aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-12-03 12:12:10 -0800
committerIan Lance Taylor <iant@golang.org>2020-12-03 12:12:10 -0800
commitf012991e2db06cc95f7aac8ecb74a1ac5f51f3d2 (patch)
tree582e5d7b377b6e973666a71960b28a7d11d72b07
parent8d703821c69062c0cd255787d793e44f1a95d463 (diff)
parent3089f5feef36810c625b5813370a97b4ecc841f8 (diff)
downloadgcc-f012991e2db06cc95f7aac8ecb74a1ac5f51f3d2.zip
gcc-f012991e2db06cc95f7aac8ecb74a1ac5f51f3d2.tar.gz
gcc-f012991e2db06cc95f7aac8ecb74a1ac5f51f3d2.tar.bz2
Merge from trunk revision 3089f5feef36810c625b5813370a97b4ecc841f8
-rw-r--r--.gitignore8
-rw-r--r--ChangeLog37
-rw-r--r--MAINTAINERS2
-rwxr-xr-xconfig.guess250
-rwxr-xr-xconfig.sub632
-rw-r--r--config/ChangeLog9
-rw-r--r--config/bootstrap-hwasan.mk12
-rwxr-xr-xconfigure5
-rw-r--r--configure.ac5
-rw-r--r--contrib/ChangeLog42
-rwxr-xr-xcontrib/gcc-changelog/git_commit.py60
-rwxr-xr-xcontrib/gcc-changelog/test_email.py15
-rw-r--r--contrib/gcc-changelog/test_patches.txt26
-rwxr-xr-xcontrib/gcc-git-customization.sh4
-rwxr-xr-xcontrib/mklog.py9
-rw-r--r--fixincludes/ChangeLog5
-rw-r--r--fixincludes/fixincl.x53
-rw-r--r--fixincludes/inclhack.def14
-rw-r--r--gcc/ChangeLog3591
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in21
-rw-r--r--gcc/ada/ChangeLog1566
-rw-r--r--gcc/ada/Makefile.rtl53
-rw-r--r--gcc/ada/adabkend.adb3
-rw-r--r--gcc/ada/adaint.c28
-rw-r--r--gcc/ada/ali-util.adb10
-rw-r--r--gcc/ada/aspects.adb28
-rw-r--r--gcc/ada/aspects.ads50
-rw-r--r--gcc/ada/checks.adb196
-rw-r--r--gcc/ada/checks.ads15
-rw-r--r--gcc/ada/contracts.adb274
-rw-r--r--gcc/ada/cstand.adb12
-rw-r--r--gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst35
-rw-r--r--gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst29
-rw-r--r--gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst23
-rw-r--r--gcc/ada/doc/gnat_rm/intrinsic_subprograms.rst4
-rw-r--r--gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst13
-rw-r--r--gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst4
-rw-r--r--gcc/ada/einfo.adb174
-rw-r--r--gcc/ada/einfo.ads46
-rw-r--r--gcc/ada/errout.adb6
-rw-r--r--gcc/ada/exp_aggr.adb43
-rw-r--r--gcc/ada/exp_attr.adb259
-rw-r--r--gcc/ada/exp_ch11.adb81
-rw-r--r--gcc/ada/exp_ch13.adb5
-rw-r--r--gcc/ada/exp_ch2.adb44
-rw-r--r--gcc/ada/exp_ch3.adb209
-rw-r--r--gcc/ada/exp_ch4.adb373
-rw-r--r--gcc/ada/exp_ch5.adb15
-rw-r--r--gcc/ada/exp_ch6.adb124
-rw-r--r--gcc/ada/exp_ch7.adb37
-rw-r--r--gcc/ada/exp_ch8.adb12
-rw-r--r--gcc/ada/exp_ch9.adb22
-rw-r--r--gcc/ada/exp_dbug.adb32
-rw-r--r--gcc/ada/exp_dist.adb2
-rw-r--r--gcc/ada/exp_fixd.adb348
-rw-r--r--gcc/ada/exp_imgv.adb312
-rw-r--r--gcc/ada/exp_intr.adb5
-rw-r--r--gcc/ada/exp_prag.adb17
-rw-r--r--gcc/ada/exp_sel.adb18
-rw-r--r--gcc/ada/exp_sel.ads9
-rw-r--r--gcc/ada/exp_spark.adb303
-rw-r--r--gcc/ada/exp_strm.adb30
-rw-r--r--gcc/ada/exp_util.adb811
-rw-r--r--gcc/ada/exp_util.ads30
-rw-r--r--gcc/ada/freeze.adb231
-rw-r--r--gcc/ada/gcc-interface/Make-lang.in6
-rw-r--r--gcc/ada/gcc-interface/Makefile.in6
-rw-r--r--gcc/ada/gcc-interface/decl.c92
-rw-r--r--gcc/ada/gcc-interface/gigi.h2
-rw-r--r--gcc/ada/gcc-interface/misc.c14
-rw-r--r--gcc/ada/gcc-interface/trans.c128
-rw-r--r--gcc/ada/gcc-interface/utils.c64
-rw-r--r--gcc/ada/gcc-interface/utils2.c32
-rw-r--r--gcc/ada/gnat_rm.texi1067
-rw-r--r--gcc/ada/gnat_ugn.texi25
-rw-r--r--gcc/ada/lib-load.adb2
-rw-r--r--gcc/ada/lib-writ.adb11
-rw-r--r--gcc/ada/lib-xref.adb2
-rw-r--r--gcc/ada/lib.adb2
-rw-r--r--gcc/ada/libgnarl/s-osinte__solaris.ads3
-rw-r--r--gcc/ada/libgnarl/s-tasren.adb14
-rw-r--r--gcc/ada/libgnarl/s-tassta.adb11
-rw-r--r--gcc/ada/libgnarl/s-tpobop.adb10
-rw-r--r--gcc/ada/libgnat/a-cbhase.adb2
-rw-r--r--gcc/ada/libgnat/a-cbmutr.ads2
-rw-r--r--gcc/ada/libgnat/a-cborse.adb2
-rw-r--r--gcc/ada/libgnat/a-decima__128.ads69
-rw-r--r--gcc/ada/libgnat/a-except.adb30
-rw-r--r--gcc/ada/libgnat/a-nbnbin.adb193
-rw-r--r--gcc/ada/libgnat/a-nbnbin.ads2
-rw-r--r--gcc/ada/libgnat/a-nbnbre.adb247
-rw-r--r--gcc/ada/libgnat/a-nbnbre.ads4
-rw-r--r--gcc/ada/libgnat/a-strmap.ads179
-rw-r--r--gcc/ada/libgnat/a-stzhas.adb14
-rw-r--r--gcc/ada/libgnat/a-stzhas.ads6
-rw-r--r--gcc/ada/libgnat/a-tideau.adb187
-rw-r--r--gcc/ada/libgnat/a-tideau.ads74
-rw-r--r--gcc/ada/libgnat/a-tideio.adb58
-rw-r--r--gcc/ada/libgnat/a-tideio__128.adb177
-rw-r--r--gcc/ada/libgnat/a-tifiau.adb160
-rw-r--r--gcc/ada/libgnat/a-tifiau.ads97
-rw-r--r--gcc/ada/libgnat/a-tifiio.adb647
-rw-r--r--gcc/ada/libgnat/a-tifiio__128.adb418
-rw-r--r--gcc/ada/libgnat/a-tiflau.adb7
-rw-r--r--gcc/ada/libgnat/a-wtdeau.adb191
-rw-r--r--gcc/ada/libgnat/a-wtdeau.ads75
-rw-r--r--gcc/ada/libgnat/a-wtdeio.adb69
-rw-r--r--gcc/ada/libgnat/a-wtdeio__128.adb190
-rw-r--r--gcc/ada/libgnat/a-wtenau.adb15
-rw-r--r--gcc/ada/libgnat/a-wtfiau.adb160
-rw-r--r--gcc/ada/libgnat/a-wtfiau.ads97
-rw-r--r--gcc/ada/libgnat/a-wtfiio.adb162
-rw-r--r--gcc/ada/libgnat/a-wtfiio__128.adb321
-rw-r--r--gcc/ada/libgnat/a-wtflio.adb7
-rw-r--r--gcc/ada/libgnat/a-wtinio.adb11
-rw-r--r--gcc/ada/libgnat/a-wtinio__128.adb15
-rw-r--r--gcc/ada/libgnat/a-wtmoio.adb11
-rw-r--r--gcc/ada/libgnat/a-wtmoio__128.adb11
-rw-r--r--gcc/ada/libgnat/a-ztdeau.adb189
-rw-r--r--gcc/ada/libgnat/a-ztdeau.ads75
-rw-r--r--gcc/ada/libgnat/a-ztdeio.adb78
-rw-r--r--gcc/ada/libgnat/a-ztdeio__128.adb190
-rw-r--r--gcc/ada/libgnat/a-ztenau.adb15
-rw-r--r--gcc/ada/libgnat/a-ztfiau.adb160
-rw-r--r--gcc/ada/libgnat/a-ztfiau.ads97
-rw-r--r--gcc/ada/libgnat/a-ztfiio.adb162
-rw-r--r--gcc/ada/libgnat/a-ztfiio__128.adb322
-rw-r--r--gcc/ada/libgnat/a-ztflio.adb7
-rw-r--r--gcc/ada/libgnat/a-ztinio.adb11
-rw-r--r--gcc/ada/libgnat/a-ztinio__128.adb15
-rw-r--r--gcc/ada/libgnat/a-ztmoio.adb11
-rw-r--r--gcc/ada/libgnat/a-ztmoio__128.adb11
-rw-r--r--gcc/ada/libgnat/g-rannum.adb86
-rw-r--r--gcc/ada/libgnat/g-rannum.ads2
-rw-r--r--gcc/ada/libgnat/g-sercom__linux.adb36
-rw-r--r--gcc/ada/libgnat/s-arit32.adb182
-rw-r--r--gcc/ada/libgnat/s-arit32.ads55
-rw-r--r--gcc/ada/libgnat/s-bitfie.ads6
-rw-r--r--gcc/ada/libgnat/s-bituti.adb1
-rw-r--r--gcc/ada/libgnat/s-fode128.ads48
-rw-r--r--gcc/ada/libgnat/s-fode32.ads48
-rw-r--r--gcc/ada/libgnat/s-fode64.ads48
-rw-r--r--gcc/ada/libgnat/s-fofi128.ads50
-rw-r--r--gcc/ada/libgnat/s-fofi32.ads50
-rw-r--r--gcc/ada/libgnat/s-fofi64.ads50
-rw-r--r--gcc/ada/libgnat/s-fore_d.adb62
-rw-r--r--gcc/ada/libgnat/s-fore_d.ads47
-rw-r--r--gcc/ada/libgnat/s-fore_f.adb136
-rw-r--r--gcc/ada/libgnat/s-fore_f.ads54
-rw-r--r--gcc/ada/libgnat/s-forrea.adb (renamed from gcc/ada/libgnat/s-fore.adb)25
-rw-r--r--gcc/ada/libgnat/s-forrea.ads (renamed from gcc/ada/libgnat/s-fore.ads)15
-rw-r--r--gcc/ada/libgnat/s-genbig.adb26
-rw-r--r--gcc/ada/libgnat/s-genbig.ads4
-rw-r--r--gcc/ada/libgnat/s-imaged.adb (renamed from gcc/ada/libgnat/s-imglld.adb)39
-rw-r--r--gcc/ada/libgnat/s-imaged.ads (renamed from gcc/ada/libgnat/s-imglld.ads)41
-rw-r--r--gcc/ada/libgnat/s-imagef.adb362
-rw-r--r--gcc/ada/libgnat/s-imagef.ads (renamed from gcc/ada/libgnat/s-imgdec.ads)99
-rw-r--r--gcc/ada/libgnat/s-imagei.adb47
-rw-r--r--gcc/ada/libgnat/s-imageu.adb39
-rw-r--r--gcc/ada/libgnat/s-imde128.ads63
-rw-r--r--gcc/ada/libgnat/s-imde32.ads63
-rw-r--r--gcc/ada/libgnat/s-imde64.ads63
-rw-r--r--gcc/ada/libgnat/s-imfi128.ads69
-rw-r--r--gcc/ada/libgnat/s-imfi32.ads69
-rw-r--r--gcc/ada/libgnat/s-imfi64.ads69
-rw-r--r--gcc/ada/libgnat/s-imgrea.adb38
-rw-r--r--gcc/ada/libgnat/s-imgrea.ads3
-rw-r--r--gcc/ada/libgnat/s-imguti.adb (renamed from gcc/ada/libgnat/s-imgdec.adb)75
-rw-r--r--gcc/ada/libgnat/s-imguti.ads58
-rw-r--r--gcc/ada/libgnat/s-os_lib.adb25
-rw-r--r--gcc/ada/libgnat/s-rannum.adb35
-rw-r--r--gcc/ada/libgnat/s-rident.ads2
-rw-r--r--gcc/ada/libgnat/s-secsta.adb15
-rw-r--r--gcc/ada/libgnat/s-stratt.adb210
-rw-r--r--gcc/ada/libgnat/s-stratt.ads107
-rw-r--r--gcc/ada/libgnat/s-trasym.ads3
-rw-r--r--gcc/ada/libgnat/s-vade128.ads (renamed from gcc/ada/libgnat/s-valdec.adb)54
-rw-r--r--gcc/ada/libgnat/s-vade32.ads58
-rw-r--r--gcc/ada/libgnat/s-vade64.ads (renamed from gcc/ada/libgnat/s-vallld.adb)54
-rw-r--r--gcc/ada/libgnat/s-vafi128.ads60
-rw-r--r--gcc/ada/libgnat/s-vafi32.ads60
-rw-r--r--gcc/ada/libgnat/s-vafi64.ads60
-rw-r--r--gcc/ada/libgnat/s-valrea.adb522
-rw-r--r--gcc/ada/libgnat/s-valued.adb257
-rw-r--r--gcc/ada/libgnat/s-valued.ads (renamed from gcc/ada/libgnat/s-valdec.ads)44
-rw-r--r--gcc/ada/libgnat/s-valuef.adb364
-rw-r--r--gcc/ada/libgnat/s-valuef.ads (renamed from gcc/ada/libgnat/s-vallld.ads)59
-rw-r--r--gcc/ada/libgnat/s-valuei.adb2
-rw-r--r--gcc/ada/libgnat/s-valuer.adb620
-rw-r--r--gcc/ada/libgnat/s-valuer.ads99
-rw-r--r--gcc/ada/libgnat/system-aix.ads2
-rw-r--r--gcc/ada/libgnat/system-darwin-arm.ads2
-rw-r--r--gcc/ada/libgnat/system-darwin-ppc.ads2
-rw-r--r--gcc/ada/libgnat/system-darwin-x86.ads2
-rw-r--r--gcc/ada/libgnat/system-djgpp.ads2
-rw-r--r--gcc/ada/libgnat/system-dragonfly-x86_64.ads2
-rw-r--r--gcc/ada/libgnat/system-freebsd.ads2
-rw-r--r--gcc/ada/libgnat/system-hpux-ia64.ads2
-rw-r--r--gcc/ada/libgnat/system-hpux.ads2
-rw-r--r--gcc/ada/libgnat/system-linux-alpha.ads2
-rw-r--r--gcc/ada/libgnat/system-linux-arm.ads2
-rw-r--r--gcc/ada/libgnat/system-linux-hppa.ads2
-rw-r--r--gcc/ada/libgnat/system-linux-ia64.ads2
-rw-r--r--gcc/ada/libgnat/system-linux-m68k.ads2
-rw-r--r--gcc/ada/libgnat/system-linux-mips.ads2
-rw-r--r--gcc/ada/libgnat/system-linux-ppc.ads2
-rw-r--r--gcc/ada/libgnat/system-linux-riscv.ads2
-rw-r--r--gcc/ada/libgnat/system-linux-s390.ads2
-rw-r--r--gcc/ada/libgnat/system-linux-sh4.ads2
-rw-r--r--gcc/ada/libgnat/system-linux-sparc.ads2
-rw-r--r--gcc/ada/libgnat/system-linux-x86.ads2
-rw-r--r--gcc/ada/libgnat/system-lynxos178-ppc.ads2
-rw-r--r--gcc/ada/libgnat/system-lynxos178-x86.ads2
-rw-r--r--gcc/ada/libgnat/system-mingw.ads2
-rw-r--r--gcc/ada/libgnat/system-qnx-aarch64.ads2
-rw-r--r--gcc/ada/libgnat/system-rtems.ads2
-rw-r--r--gcc/ada/libgnat/system-solaris-sparc.ads2
-rw-r--r--gcc/ada/libgnat/system-solaris-x86.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks-arm-rtp-smp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks-arm-rtp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks-arm.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks-e500-kernel.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks-e500-rtp-smp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks-e500-rtp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks-e500-vthread.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks-ppc-kernel.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks-ppc-ravenscar.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks-ppc-rtp-smp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks-ppc-rtp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks-ppc-vthread.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks-ppc.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks-x86-kernel.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks-x86-rtp-smp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks-x86-rtp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks-x86-vthread.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks-x86.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-aarch64-rtp-smp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-aarch64.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-arm-rtp-smp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-arm.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-e500-kernel.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-e500-rtp-smp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-e500-rtp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-ppc-kernel.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-ppc-rtp-smp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-ppc-rtp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-ppc64-kernel.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-ppc64-rtp-smp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-x86-kernel.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-x86-rtp-smp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-x86-rtp.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-x86_64-kernel.ads2
-rw-r--r--gcc/ada/libgnat/system-vxworks7-x86_64-rtp-smp.ads2
-rw-r--r--gcc/ada/make.adb20
-rw-r--r--gcc/ada/opt.ads9
-rw-r--r--gcc/ada/osint-c.adb8
-rw-r--r--gcc/ada/par-ch13.adb36
-rw-r--r--gcc/ada/par-ch6.adb1
-rw-r--r--gcc/ada/par-load.adb2
-rw-r--r--gcc/ada/par-prag.adb9
-rw-r--r--gcc/ada/par-tchk.adb1
-rw-r--r--gcc/ada/par.adb4
-rw-r--r--gcc/ada/rtsfind.adb2
-rw-r--r--gcc/ada/rtsfind.ads116
-rw-r--r--gcc/ada/sem_aggr.adb94
-rw-r--r--gcc/ada/sem_attr.adb74
-rw-r--r--gcc/ada/sem_ch10.adb3
-rw-r--r--gcc/ada/sem_ch12.adb68
-rw-r--r--gcc/ada/sem_ch13.adb750
-rw-r--r--gcc/ada/sem_ch13.ads6
-rw-r--r--gcc/ada/sem_ch3.adb113
-rw-r--r--gcc/ada/sem_ch4.adb2
-rw-r--r--gcc/ada/sem_ch5.adb65
-rw-r--r--gcc/ada/sem_ch6.adb246
-rw-r--r--gcc/ada/sem_ch8.adb37
-rw-r--r--gcc/ada/sem_eval.adb196
-rw-r--r--gcc/ada/sem_prag.adb229
-rw-r--r--gcc/ada/sem_res.adb254
-rw-r--r--gcc/ada/sem_type.adb118
-rw-r--r--gcc/ada/sem_util.adb97
-rw-r--r--gcc/ada/sem_util.ads19
-rw-r--r--gcc/ada/sinfo.adb16
-rw-r--r--gcc/ada/sinfo.ads18
-rw-r--r--gcc/ada/snames.ads-tmpl186
-rw-r--r--gcc/ada/spark_xrefs.ads3
-rw-r--r--gcc/ada/stand.ads9
-rw-r--r--gcc/ada/switch-c.adb6
-rw-r--r--gcc/ada/terminals.c2
-rw-r--r--gcc/ada/uintp.ads12
-rw-r--r--gcc/ada/urealp.adb168
-rw-r--r--gcc/ada/urealp.ads32
-rw-r--r--gcc/ada/xsnamest.adb9
-rw-r--r--gcc/analyzer/ChangeLog84
-rw-r--r--gcc/analyzer/analyzer-pass.cc21
-rw-r--r--gcc/analyzer/analyzer.h13
-rw-r--r--gcc/analyzer/analyzer.opt8
-rw-r--r--gcc/analyzer/checker-path.cc9
-rw-r--r--gcc/analyzer/checker-path.h10
-rw-r--r--gcc/analyzer/constraint-manager.cc11
-rw-r--r--gcc/analyzer/constraint-manager.h3
-rw-r--r--gcc/analyzer/diagnostic-manager.cc27
-rw-r--r--gcc/analyzer/engine.cc86
-rw-r--r--gcc/analyzer/pending-diagnostic.h23
-rw-r--r--gcc/analyzer/program-state.cc22
-rw-r--r--gcc/analyzer/program-state.h3
-rw-r--r--gcc/analyzer/region-model-reachability.cc5
-rw-r--r--gcc/analyzer/region-model-reachability.h3
-rw-r--r--gcc/analyzer/region-model.cc109
-rw-r--r--gcc/analyzer/sm-malloc.cc8
-rw-r--r--gcc/asan.c1034
-rw-r--r--gcc/asan.h45
-rw-r--r--gcc/attr-fnspec.h30
-rw-r--r--gcc/bitmap.c5
-rw-r--r--gcc/brig/ChangeLog13
-rw-r--r--gcc/brig/Make-lang.in10
-rw-r--r--gcc/builtin-types.def5
-rw-r--r--gcc/builtins.c1279
-rw-r--r--gcc/builtins.def2
-rw-r--r--gcc/builtins.h123
-rw-r--r--gcc/c-family/ChangeLog215
-rw-r--r--gcc/c-family/c-ada-spec.c23
-rw-r--r--gcc/c-family/c-attribs.c250
-rw-r--r--gcc/c-family/c-common.c57
-rw-r--r--gcc/c-family/c-common.h24
-rw-r--r--gcc/c-family/c-cppbuiltin.c43
-rw-r--r--gcc/c-family/c-lex.c80
-rw-r--r--gcc/c-family/c-objc.h7
-rw-r--r--gcc/c-family/c-opts.c34
-rw-r--r--gcc/c-family/c-pch.c44
-rw-r--r--gcc/c-family/c-ppoutput.c158
-rw-r--r--gcc/c-family/c-pretty-print.c2
-rw-r--r--gcc/c-family/c-warn.c20
-rw-r--r--gcc/c-family/c.opt77
-rw-r--r--gcc/c-family/stub-objc.c6
-rw-r--r--gcc/c/ChangeLog89
-rw-r--r--gcc/c/Make-lang.in3
-rw-r--r--gcc/c/c-aux-info.c1
-rw-r--r--gcc/c/c-decl.c7
-rw-r--r--gcc/c/c-parser.c27
-rw-r--r--gcc/c/c-typeck.c14
-rw-r--r--gcc/cfg.c45
-rw-r--r--gcc/cfg.h2
-rw-r--r--gcc/cfgexpand.c213
-rw-r--r--gcc/cfgloop.h2
-rw-r--r--gcc/cfgrtl.c10
-rw-r--r--gcc/cgraph.c4
-rw-r--r--gcc/cgraph.h14
-rw-r--r--gcc/cgraphclones.c8
-rw-r--r--gcc/common.opt24
-rw-r--r--gcc/common/config/i386/cpuinfo.h2
-rw-r--r--gcc/common/config/i386/i386-common.c20
-rw-r--r--gcc/common/config/i386/i386-cpuinfo.h1
-rw-r--r--gcc/common/config/i386/i386-isas.h1
-rw-r--r--gcc/common/config/riscv/riscv-common.c458
-rw-r--r--gcc/config.gcc96
-rw-r--r--gcc/config.in65
-rw-r--r--gcc/config/aarch64/aarch64-option-extensions.def3
-rw-r--r--gcc/config/aarch64/aarch64-protos.h1
-rw-r--r--gcc/config/aarch64/aarch64-simd-builtins.def44
-rw-r--r--gcc/config/aarch64/aarch64-simd.md113
-rw-r--r--gcc/config/aarch64/aarch64-sve-builtins-base.cc11
-rw-r--r--gcc/config/aarch64/aarch64-sve.md275
-rw-r--r--gcc/config/aarch64/aarch64-sve2.md68
-rw-r--r--gcc/config/aarch64/aarch64.c408
-rw-r--r--gcc/config/aarch64/aarch64.h22
-rw-r--r--gcc/config/aarch64/aarch64.md18
-rw-r--r--gcc/config/aarch64/aarch64.opt2
-rw-r--r--gcc/config/arc/arc.c8
-rw-r--r--gcc/config/arm/aarch-common.c2
-rw-r--r--gcc/config/arm/aarch-cost-tables.h103
-rw-r--r--gcc/config/arm/arm.c103
-rw-r--r--gcc/config/arm/t-rtems5
-rw-r--r--gcc/config/c6x/c6x.c7
-rw-r--r--gcc/config/csky/csky.c7
-rw-r--r--gcc/config/darwin-c.c15
-rw-r--r--gcc/config/darwin-d.c49
-rw-r--r--gcc/config/darwin-protos.h1
-rw-r--r--gcc/config/darwin.c11
-rw-r--r--gcc/config/darwin.h7
-rw-r--r--gcc/config/dragonfly-d.c37
-rw-r--r--gcc/config/elfos.h6
-rw-r--r--gcc/config/freebsd-d.c42
-rw-r--r--gcc/config/ft32/ft32.md6
-rw-r--r--gcc/config/gcn/mkoffload.c15
-rw-r--r--gcc/config/gnu-user.h8
-rw-r--r--gcc/config/h8300/addsub.md188
-rw-r--r--gcc/config/h8300/bitfield.md564
-rw-r--r--gcc/config/h8300/combiner.md901
-rw-r--r--gcc/config/h8300/constraints.md6
-rw-r--r--gcc/config/h8300/divmod.md127
-rw-r--r--gcc/config/h8300/extensions.md136
-rw-r--r--gcc/config/h8300/genmova.sh18
-rw-r--r--gcc/config/h8300/h8300-modes.def21
-rw-r--r--gcc/config/h8300/h8300-protos.h12
-rw-r--r--gcc/config/h8300/h8300.c370
-rw-r--r--gcc/config/h8300/h8300.h14
-rw-r--r--gcc/config/h8300/h8300.md40
-rw-r--r--gcc/config/h8300/jumpcall.md132
-rw-r--r--gcc/config/h8300/logical.md240
-rw-r--r--gcc/config/h8300/mova.md249
-rw-r--r--gcc/config/h8300/movepush.md180
-rw-r--r--gcc/config/h8300/multiply.md131
-rw-r--r--gcc/config/h8300/other.md15
-rw-r--r--gcc/config/h8300/peepholes.md104
-rw-r--r--gcc/config/h8300/predicates.md9
-rw-r--r--gcc/config/h8300/proepi.md12
-rw-r--r--gcc/config/h8300/shiftrotate.md262
-rw-r--r--gcc/config/h8300/testcompare.md275
-rw-r--r--gcc/config/i386/avx512vnnivlintrin.h88
-rw-r--r--gcc/config/i386/avxvnniintrin.h113
-rw-r--r--gcc/config/i386/cet.c76
-rw-r--r--gcc/config/i386/cpuid.h1
-rw-r--r--gcc/config/i386/gnu-property.c124
-rw-r--r--gcc/config/i386/i386-builtin.def18
-rw-r--r--gcc/config/i386/i386-builtins.c4
-rw-r--r--gcc/config/i386/i386-c.c2
-rw-r--r--gcc/config/i386/i386-expand.c324
-rw-r--r--gcc/config/i386/i386-features.c24
-rw-r--r--gcc/config/i386/i386-options.c12
-rw-r--r--gcc/config/i386/i386-protos.h2
-rw-r--r--gcc/config/i386/i386.c54
-rw-r--r--gcc/config/i386/i386.h22
-rw-r--r--gcc/config/i386/i386.md346
-rw-r--r--gcc/config/i386/i386.opt9
-rw-r--r--gcc/config/i386/immintrin.h2
-rw-r--r--gcc/config/i386/linux-common.h4
-rw-r--r--gcc/config/i386/msformat-c.c53
-rw-r--r--gcc/config/i386/predicates.md6
-rw-r--r--gcc/config/i386/sse.md385
-rw-r--r--gcc/config/i386/t-gnu-property (renamed from gcc/config/i386/t-cet)2
-rw-r--r--gcc/config/m68k/linux.h8
-rw-r--r--gcc/config/mcore/t-mcore2
-rw-r--r--gcc/config/mips/mips.c4
-rw-r--r--gcc/config/msp430/msp430-protos.h5
-rw-r--r--gcc/config/msp430/msp430.c981
-rw-r--r--gcc/config/msp430/msp430.h18
-rw-r--r--gcc/config/msp430/msp430.md498
-rw-r--r--gcc/config/msp430/predicates.md13
-rw-r--r--gcc/config/pru/alu-zext.md51
-rw-r--r--gcc/config/pru/pru.c62
-rw-r--r--gcc/config/pru/pru.h3
-rw-r--r--gcc/config/pru/pru.md40
-rwxr-xr-xgcc/config/riscv/arch-canonicalize102
-rwxr-xr-xgcc/config/riscv/multilib-generator83
-rw-r--r--gcc/config/riscv/riscv-opts.h16
-rw-r--r--gcc/config/riscv/riscv.c39
-rw-r--r--gcc/config/riscv/riscv.h24
-rw-r--r--gcc/config/riscv/riscv.md5
-rw-r--r--gcc/config/riscv/riscv.opt20
-rw-r--r--gcc/config/riscv/withmultilib.h51
-rw-r--r--gcc/config/rs6000/mma.md421
-rw-r--r--gcc/config/rs6000/predicates.md12
-rw-r--r--gcc/config/rs6000/rs6000-builtin.def14
-rw-r--r--gcc/config/rs6000/rs6000-call.c178
-rw-r--r--gcc/config/rs6000/rs6000-cpus.def10
-rw-r--r--gcc/config/rs6000/rs6000-modes.def10
-rw-r--r--gcc/config/rs6000/rs6000-protos.h3
-rw-r--r--gcc/config/rs6000/rs6000-string.c6
-rw-r--r--gcc/config/rs6000/rs6000.c257
-rw-r--r--gcc/config/rs6000/rs6000.h18
-rw-r--r--gcc/config/rs6000/rs6000.md49
-rw-r--r--gcc/config/rs6000/rs6000.opt3
-rw-r--r--gcc/config/rs6000/vector.md4
-rw-r--r--gcc/config/s390/s390-protos.h1
-rw-r--r--gcc/config/s390/s390.c60
-rw-r--r--gcc/config/s390/s390.h5
-rw-r--r--gcc/config/s390/s390.md31
-rw-r--r--gcc/config/s390/vector.md164
-rw-r--r--gcc/config/s390/vx-builtins.md50
-rw-r--r--gcc/config/sol2.h3
-rw-r--r--gcc/config/sparc/predicates.md2
-rw-r--r--gcc/config/sparc/sparc-protos.h1
-rw-r--r--gcc/config/sparc/sparc.c85
-rw-r--r--gcc/config/sparc/sparc.md183
-rw-r--r--gcc/config/t-darwin3
-rw-r--r--gcc/config/t-dragonfly21
-rw-r--r--gcc/config/t-freebsd21
-rw-r--r--gcc/config/tilegx/tilegx.c4
-rw-r--r--gcc/config/tilepro/tilepro.c4
-rw-r--r--gcc/config/vax/vax.c6
-rw-r--r--gcc/config/vxworks.c24
-rw-r--r--gcc/config/vxworks.h11
-rwxr-xr-xgcc/configure539
-rw-r--r--gcc/configure.ac314
-rw-r--r--gcc/coverage.c28
-rw-r--r--gcc/cp/ChangeLog470
-rw-r--r--gcc/cp/Make-lang.in10
-rw-r--r--gcc/cp/call.c94
-rw-r--r--gcc/cp/class.c17
-rw-r--r--gcc/cp/constexpr.c416
-rw-r--r--gcc/cp/constraint.cc4
-rw-r--r--gcc/cp/coroutines.cc2
-rw-r--r--gcc/cp/cp-gimplify.c13
-rw-r--r--gcc/cp/cp-objcp-common.c2
-rw-r--r--gcc/cp/cp-tree.def6
-rw-r--r--gcc/cp/cp-tree.h170
-rw-r--r--gcc/cp/cxx-pretty-print.c15
-rw-r--r--gcc/cp/decl.c110
-rw-r--r--gcc/cp/error.c19
-rw-r--r--gcc/cp/g++spec.c33
-rw-r--r--gcc/cp/init.c6
-rw-r--r--gcc/cp/lang-specs.h57
-rw-r--r--gcc/cp/lex.c15
-rw-r--r--gcc/cp/logic.cc5
-rw-r--r--gcc/cp/mangle.c27
-rw-r--r--gcc/cp/method.c2
-rw-r--r--gcc/cp/module.cc21
-rw-r--r--gcc/cp/name-lookup.c264
-rw-r--r--gcc/cp/name-lookup.h119
-rw-r--r--gcc/cp/optimize.c2
-rw-r--r--gcc/cp/parser.c375
-rw-r--r--gcc/cp/pt.c184
-rw-r--r--gcc/cp/ptree.c38
-rw-r--r--gcc/cp/rtti.c34
-rw-r--r--gcc/cp/semantics.c165
-rw-r--r--gcc/cp/tree.c85
-rw-r--r--gcc/cp/typeck.c38
-rw-r--r--gcc/cp/typeck2.c168
-rw-r--r--gcc/cppbuiltin.c3
-rw-r--r--gcc/d/ChangeLog81
-rw-r--r--gcc/d/Make-lang.in5
-rw-r--r--gcc/d/d-codegen.cc5
-rw-r--r--gcc/d/d-target.cc9
-rw-r--r--gcc/d/d-target.def25
-rw-r--r--gcc/d/decl.cc58
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/cond.c4
-rw-r--r--gcc/d/dmd/cppmangle.c20
-rw-r--r--gcc/d/dmd/dmangle.c2
-rw-r--r--gcc/d/dmd/expression.c2
-rw-r--r--gcc/d/dmd/expression.h2
-rw-r--r--gcc/d/dmd/globals.h1
-rw-r--r--gcc/d/dmd/hdrgen.c2
-rw-r--r--gcc/d/dmd/idgen.c1
-rw-r--r--gcc/d/dmd/json.c3
-rw-r--r--gcc/d/dmd/mangle.h1
-rw-r--r--gcc/d/dmd/mtype.c6
-rw-r--r--gcc/d/dmd/mtype.h3
-rw-r--r--gcc/d/dmd/parse.c4
-rw-r--r--gcc/d/dmd/root/array.h28
-rw-r--r--gcc/d/dmd/root/bitarray.h4
-rw-r--r--gcc/d/dmd/root/dcompat.h12
-rw-r--r--gcc/d/dmd/root/outbuffer.h4
-rw-r--r--gcc/d/dmd/root/rmem.h10
-rw-r--r--gcc/d/dmd/root/stringtable.h9
-rw-r--r--gcc/d/dmd/target.h2
-rw-r--r--gcc/d/expr.cc64
-rw-r--r--gcc/d/intrinsics.cc23
-rw-r--r--gcc/d/intrinsics.def20
-rw-r--r--gcc/d/modules.cc14
-rw-r--r--gcc/d/types.cc1
-rw-r--r--gcc/dbgcnt.def1
-rw-r--r--gcc/dbxout.c1
-rw-r--r--gcc/diagnostic.c23
-rw-r--r--gcc/digraph.cc2
-rw-r--r--gcc/doc/cpp.texi30
-rw-r--r--gcc/doc/extend.texi186
-rw-r--r--gcc/doc/generic.texi39
-rw-r--r--gcc/doc/install.texi41
-rw-r--r--gcc/doc/invoke.texi422
-rw-r--r--gcc/doc/md.texi22
-rw-r--r--gcc/doc/plugins.texi4
-rw-r--r--gcc/doc/rtl.texi6
-rw-r--r--gcc/doc/sourcebuild.texi18
-rw-r--r--gcc/doc/tm.texi121
-rw-r--r--gcc/doc/tm.texi.in28
-rw-r--r--gcc/dse.c5
-rw-r--r--gcc/dumpfile.c18
-rw-r--r--gcc/dwarf2out.c78
-rw-r--r--gcc/dwarf2out.h17
-rw-r--r--gcc/edit-context.c14
-rw-r--r--gcc/explow.c12
-rw-r--r--gcc/explow.h2
-rw-r--r--gcc/expmed.c75
-rw-r--r--gcc/expmed.h4
-rw-r--r--gcc/expr.c9
-rw-r--r--gcc/final.c22
-rw-r--r--gcc/flag-types.h20
-rw-r--r--gcc/fold-const.c835
-rw-r--r--gcc/fold-const.h11
-rw-r--r--gcc/fortran/ChangeLog135
-rw-r--r--gcc/fortran/Make-lang.in6
-rw-r--r--gcc/fortran/decl.c2
-rw-r--r--gcc/fortran/dump-parse-tree.c12
-rw-r--r--gcc/fortran/expr.c3
-rw-r--r--gcc/fortran/f95-lang.c11
-rw-r--r--gcc/fortran/gfortran.h4
-rw-r--r--gcc/fortran/gfortran.texi4
-rw-r--r--gcc/fortran/lang.opt4
-rw-r--r--gcc/fortran/misc.c28
-rw-r--r--gcc/fortran/openmp.c377
-rw-r--r--gcc/fortran/options.c16
-rw-r--r--gcc/fortran/resolve.c11
-rw-r--r--gcc/fortran/scanner.c32
-rw-r--r--gcc/fortran/trans-decl.c9
-rw-r--r--gcc/fortran/trans-intrinsic.c108
-rw-r--r--gcc/fortran/trans-openmp.c121
-rw-r--r--gcc/fortran/trans-types.c17
-rw-r--r--gcc/fortran/trans-types.h3
-rw-r--r--gcc/fortran/trans.h3
-rw-r--r--gcc/fortran/types.def5
-rw-r--r--gcc/function.c10
-rw-r--r--gcc/gcc.c60
-rw-r--r--gcc/gdbinit.in38
-rw-r--r--gcc/genmodes.c22
-rw-r--r--gcc/gimple-fold.c903
-rw-r--r--gcc/gimple-fold.h16
-rw-r--r--gcc/gimple-if-to-switch.cc569
-rw-r--r--gcc/gimple-isel.cc29
-rw-r--r--gcc/gimple-loop-interchange.cc9
-rw-r--r--gcc/gimple-pretty-print.c10
-rw-r--r--gcc/gimple-range.cc99
-rw-r--r--gcc/gimple-range.h10
-rw-r--r--gcc/gimple-ssa-evrp-analyze.c6
-rw-r--r--gcc/gimple-ssa-sprintf.c30
-rw-r--r--gcc/gimple-ssa-store-merging.c18
-rw-r--r--gcc/gimple.c57
-rw-r--r--gcc/gimple.h60
-rw-r--r--gcc/gimplify-me.c12
-rw-r--r--gcc/gimplify.c127
-rw-r--r--gcc/ginclude/float.h86
-rw-r--r--gcc/ginclude/stdatomic.h14
-rw-r--r--gcc/go/ChangeLog18
-rw-r--r--gcc/go/Make-lang.in5
-rw-r--r--gcc/go/go-gcc.cc2
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/ast-dump.cc6
-rw-r--r--gcc/go/gofrontend/export.cc8
-rw-r--r--gcc/go/gofrontend/expressions.cc216
-rw-r--r--gcc/go/gofrontend/expressions.h11
-rw-r--r--gcc/go/gofrontend/go-encode-id.cc289
-rw-r--r--gcc/go/gofrontend/go-encode-id.h13
-rw-r--r--gcc/go/gofrontend/gogo.cc254
-rw-r--r--gcc/go/gofrontend/gogo.h173
-rw-r--r--gcc/go/gofrontend/names.cc759
-rw-r--r--gcc/go/gofrontend/parse.cc27
-rw-r--r--gcc/go/gofrontend/runtime.def45
-rw-r--r--gcc/go/gofrontend/statements.cc28
-rw-r--r--gcc/go/gofrontend/types.cc159
-rw-r--r--gcc/go/gofrontend/types.h24
-rw-r--r--gcc/internal-fn.c267
-rw-r--r--gcc/internal-fn.def7
-rw-r--r--gcc/internal-fn.h2
-rw-r--r--gcc/ipa-cp.c202
-rw-r--r--gcc/ipa-devirt.c3
-rw-r--r--gcc/ipa-icf-gimple.c225
-rw-r--r--gcc/ipa-icf-gimple.h25
-rw-r--r--gcc/ipa-icf.c124
-rw-r--r--gcc/ipa-icf.h10
-rw-r--r--gcc/ipa-modref.c1492
-rw-r--r--gcc/ipa-modref.h5
-rw-r--r--gcc/ipa-prop.c155
-rw-r--r--gcc/ipa-prop.h16
-rw-r--r--gcc/ipa-pure-const.c3
-rw-r--r--gcc/ipa-utils.h14
-rw-r--r--gcc/ira.c61
-rw-r--r--gcc/ira.h1
-rw-r--r--gcc/jit/ChangeLog154
-rw-r--r--gcc/jit/Make-lang.in6
-rw-r--r--gcc/jit/docs/_build/texinfo/Makefile11
-rw-r--r--gcc/jit/docs/_build/texinfo/libgccjit.texi1837
-rw-r--r--gcc/jit/docs/cp/topics/asm.rst308
-rw-r--r--gcc/jit/docs/cp/topics/index.rst1
-rw-r--r--gcc/jit/docs/topics/asm.rst311
-rw-r--r--gcc/jit/docs/topics/compatibility.rst17
-rw-r--r--gcc/jit/docs/topics/functions.rst3
-rw-r--r--gcc/jit/docs/topics/index.rst1
-rw-r--r--gcc/jit/docs/topics/objects.rst1
-rw-r--r--gcc/jit/jit-common.h2
-rw-r--r--gcc/jit/jit-playback.c125
-rw-r--r--gcc/jit/jit-playback.h27
-rw-r--r--gcc/jit/jit-recording.c573
-rw-r--r--gcc/jit/jit-recording.h224
-rw-r--r--gcc/jit/libgccjit++.h170
-rw-r--r--gcc/jit/libgccjit.c188
-rw-r--r--gcc/jit/libgccjit.h105
-rw-r--r--gcc/jit/libgccjit.map13
-rw-r--r--gcc/json.cc5
-rw-r--r--gcc/langhooks-def.h8
-rw-r--r--gcc/langhooks.h18
-rw-r--r--gcc/loop-init.c9
-rw-r--r--gcc/loop-invariant.c4
-rw-r--r--gcc/loop-iv.c2
-rw-r--r--gcc/lra-assigns.c17
-rw-r--r--gcc/lra-constraints.c23
-rw-r--r--gcc/lra-spills.c8
-rw-r--r--gcc/lra.c75
-rw-r--r--gcc/lto-streamer-in.c8
-rw-r--r--gcc/lto-wrapper.c3
-rw-r--r--gcc/lto/ChangeLog28
-rw-r--r--gcc/lto/Make-lang.in18
-rw-r--r--gcc/lto/lto-common.c5
-rw-r--r--gcc/lto/lto-symtab.c2
-rw-r--r--gcc/machmode.def3
-rw-r--r--gcc/machmode.h4
-rw-r--r--gcc/match.pd84
-rw-r--r--gcc/mode-classes.def3
-rw-r--r--gcc/objc/ChangeLog31
-rw-r--r--gcc/objc/Make-lang.in6
-rw-r--r--gcc/objc/objc-act.c63
-rw-r--r--gcc/objc/objc-act.h10
-rw-r--r--gcc/objcp/ChangeLog14
-rw-r--r--gcc/objcp/Make-lang.in6
-rw-r--r--gcc/omp-builtins.def9
-rw-r--r--gcc/omp-expand.c99
-rw-r--r--gcc/omp-low.c424
-rw-r--r--gcc/omp-oacc-kernels-decompose.cc1545
-rw-r--r--gcc/omp-offload.c70
-rw-r--r--gcc/optabs-tree.c66
-rw-r--r--gcc/optabs.c413
-rw-r--r--gcc/optabs.def8
-rw-r--r--gcc/optabs.h14
-rw-r--r--gcc/optc-gen.awk24
-rw-r--r--gcc/optc-save-gen.awk36
-rw-r--r--gcc/opts.c196
-rw-r--r--gcc/opts.h11
-rw-r--r--gcc/output.h11
-rw-r--r--gcc/params.opt48
-rw-r--r--gcc/passes.c3
-rw-r--r--gcc/passes.def2
-rw-r--r--gcc/plugin.c2
-rw-r--r--gcc/plugin.def4
-rw-r--r--gcc/po/ChangeLog4
-rw-r--r--gcc/po/zh_TW.po8
-rw-r--r--gcc/predict.c2
-rw-r--r--gcc/range-op.cc144
-rw-r--r--gcc/reg-stack.c3
-rw-r--r--gcc/reload.c16
-rw-r--r--gcc/sanitizer.def61
-rw-r--r--gcc/sanopt.c21
-rw-r--r--gcc/stor-layout.c3
-rw-r--r--gcc/symtab-thunks.h2
-rw-r--r--gcc/symtab.c106
-rw-r--r--gcc/system.h6
-rw-r--r--gcc/target.def125
-rw-r--r--gcc/targhooks.c120
-rw-r--r--gcc/targhooks.h10
-rw-r--r--gcc/testsuite/ChangeLog2441
-rw-r--r--gcc/testsuite/ada/acats/support/acats26.lst (renamed from gcc/testsuite/ada/acats/support/acats25.lst)30
-rw-r--r--gcc/testsuite/ada/acats/support/fcndecl.ada18
-rw-r--r--gcc/testsuite/ada/acats/support/impdef.a15
-rw-r--r--gcc/testsuite/ada/acats/support/impdefg.a27
-rw-r--r--gcc/testsuite/ada/acats/support/macro.dfs5
-rw-r--r--gcc/testsuite/ada/acats/support/repbody.ada5
-rw-r--r--gcc/testsuite/ada/acats/support/tctouch.ada3
-rw-r--r--gcc/testsuite/ada/acats/tests/c3/c352001.a270
-rw-r--r--gcc/testsuite/ada/acats/tests/c4/c433001.a9
-rw-r--r--gcc/testsuite/ada/acats/tests/c4/c453001.a236
-rw-r--r--gcc/testsuite/ada/acats/tests/c4/c45622a.ada83
-rw-r--r--gcc/testsuite/ada/acats/tests/c4/c45624a.ada86
-rw-r--r--gcc/testsuite/ada/acats/tests/c4/c45624b.ada81
-rw-r--r--gcc/testsuite/ada/acats/tests/c4/c460013.a188
-rw-r--r--gcc/testsuite/ada/acats/tests/c4/c460014.a289
-rw-r--r--gcc/testsuite/ada/acats/tests/c6/c620001.a340
-rw-r--r--gcc/testsuite/ada/acats/tests/c6/c620002.a509
-rw-r--r--gcc/testsuite/ada/acats/tests/c7/c761006.a47
-rw-r--r--gcc/testsuite/ada/acats/tests/c9/c96004a.ada48
-rw-r--r--gcc/testsuite/ada/acats/tests/c9/c96007a.ada28
-rw-r--r--gcc/testsuite/ada/acats/tests/cb/cb41004.a73
-rw-r--r--gcc/testsuite/ada/acats/tests/cc/cc3016f.ada19
-rw-r--r--gcc/testsuite/ada/acats/tests/cd/cd30011.a155
-rw-r--r--gcc/testsuite/ada/acats/tests/cd/cd30012.a173
-rw-r--r--gcc/testsuite/ada/acats/tests/cd/cd90001.a31
-rw-r--r--gcc/testsuite/ada/acats/tests/cxa/cxa3004.a235
-rw-r--r--gcc/testsuite/ada/acats/tests/cxa/cxa5013.a326
-rw-r--r--gcc/testsuite/ada/acats/tests/cxa/cxac005.a24
-rw-r--r--gcc/testsuite/ada/acats/tests/cxb/cxb30061.am404
-rw-r--r--gcc/testsuite/ada/acats/tests/cxf/cxf2001.a202
-rw-r--r--gcc/testsuite/c-c++-common/Wstringop-overflow-2.c10
-rw-r--r--gcc/testsuite/c-c++-common/asan/pointer-compare-1.c7
-rw-r--r--gcc/testsuite/c-c++-common/asmgoto-2.c2
-rw-r--r--gcc/testsuite/c-c++-common/attr-used-2.c1
-rw-r--r--gcc/testsuite/c-c++-common/attr-used-3.c7
-rw-r--r--gcc/testsuite/c-c++-common/attr-used-4.c7
-rw-r--r--gcc/testsuite/c-c++-common/attr-used.c1
-rw-r--r--gcc/testsuite/c-c++-common/builtin-clear-padding-1.c19
-rw-r--r--gcc/testsuite/c-c++-common/builtin-clear-padding-2.c17
-rw-r--r--gcc/testsuite/c-c++-common/builtin-clear-padding-3.c15
-rw-r--r--gcc/testsuite/c-c++-common/cpp/wide-narrow-predef-macros.c13
-rw-r--r--gcc/testsuite/c-c++-common/goacc/cache-1.c18
-rw-r--r--gcc/testsuite/c-c++-common/goacc/cache-2.c10
-rw-r--r--gcc/testsuite/c-c++-common/goacc/cache-3-1.c116
-rw-r--r--gcc/testsuite/c-c++-common/goacc/cache-3-2.c50
-rw-r--r--gcc/testsuite/c-c++-common/goacc/classify-parallel.c4
-rw-r--r--gcc/testsuite/c-c++-common/goacc/classify-serial.c29
-rw-r--r--gcc/testsuite/c-c++-common/goacc/data-clause-1.c115
-rw-r--r--gcc/testsuite/c-c++-common/goacc/data-clause-2.c49
-rw-r--r--gcc/testsuite/c-c++-common/goacc/if-clause-2.c24
-rw-r--r--gcc/testsuite/c-c++-common/goacc/kernels-decompose-1.c91
-rw-r--r--gcc/testsuite/c-c++-common/goacc/kernels-decompose-2.c149
-rw-r--r--gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-1.c109
-rw-r--r--gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-2.c16
-rw-r--r--gcc/testsuite/c-c++-common/gomp/depobj-2.c11
-rw-r--r--gcc/testsuite/c-c++-common/gomp/map-1.c7
-rw-r--r--gcc/testsuite/c-c++-common/gomp/map-2.c7
-rw-r--r--gcc/testsuite/c-c++-common/gomp/pr97862.c15
-rw-r--r--gcc/testsuite/c-c++-common/gomp/pr97958.c17
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/aligned-alloc.c16
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/alloca-array-accessible.c33
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/alloca-base-init.c66
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/alloca-gets-different-tag.c65
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/alloca-outside-caught.c25
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/arguments-1.c3
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/arguments-2.c3
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/arguments-3.c3
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/arguments.c3
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/asan-pr63316.c24
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/asan-pr70541.c36
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/asan-pr78106.c31
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/asan-pr79944.c19
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/asan-rlimit-mmap-test-1.c24
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/bitfield-1.c31
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/bitfield-2.c30
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/builtin-special-handling.c31
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/check-interface.c26
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/halt_on_error-1.c24
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/handles-poly_int-marked-vars.c37
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/heap-overflow.c29
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/hwasan-poison-optimisation.c29
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/hwasan-thread-access-parent.c51
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/hwasan-thread-basic-failure.c48
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/hwasan-thread-clears-stack.c56
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/hwasan-thread-success.c35
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/kernel-defaults.c37
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/large-aligned-0.c33
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/large-aligned-1.c14
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-0.c75
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-1.c15
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-2.c15
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-3.c15
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-4.c16
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-5.c16
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-6.c16
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-7.c16
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/macro-definition.c11
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/no-sanitize-attribute.c12
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/param-instrument-mem-intrinsics.c10
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/param-instrument-reads-and-writes.c7
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/param-instrument-reads.c21
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/param-instrument-writes.c7
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/random-frame-tag.c7
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/sanity-check-pure-c.c25
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/setjmp-longjmp-0.c54
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/setjmp-longjmp-1.c19
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/stack-tagging-basic-0.c37
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/stack-tagging-basic-1.c18
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/stack-tagging-disable.c33
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/unprotected-allocas-0.c46
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/unprotected-allocas-1.c16
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/use-after-free.c28
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/vararray-outside-caught.c22
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/vararray-stack-restore-correct.c43
-rw-r--r--gcc/testsuite/c-c++-common/hwasan/very-large-objects.c68
-rw-r--r--gcc/testsuite/c-c++-common/patchable_function_entry-error-3.c6
-rw-r--r--gcc/testsuite/c-c++-common/torture/attr-noinit-1.c7
-rw-r--r--gcc/testsuite/c-c++-common/torture/attr-noinit-2.c8
-rw-r--r--gcc/testsuite/c-c++-common/torture/attr-noinit-3.c11
-rw-r--r--gcc/testsuite/c-c++-common/torture/attr-noinit-invalid.c12
-rw-r--r--gcc/testsuite/c-c++-common/torture/attr-noinit-main.inc (renamed from gcc/testsuite/gcc.c-torture/execute/noinit-attribute.c)37
-rw-r--r--gcc/testsuite/c-c++-common/torture/attr-persistent-1.c8
-rw-r--r--gcc/testsuite/c-c++-common/torture/attr-persistent-2.c8
-rw-r--r--gcc/testsuite/c-c++-common/torture/attr-persistent-3.c10
-rw-r--r--gcc/testsuite/c-c++-common/torture/attr-persistent-invalid.c11
-rw-r--r--gcc/testsuite/c-c++-common/torture/attr-persistent-main.inc58
-rw-r--r--gcc/testsuite/c-c++-common/torture/builtin-clear-padding-1.c47
-rw-r--r--gcc/testsuite/c-c++-common/torture/builtin-clear-padding-2.c24
-rw-r--r--gcc/testsuite/c-c++-common/torture/builtin-clear-padding-3.c65
-rw-r--r--gcc/testsuite/c-c++-common/torture/builtin-clear-padding-4.c59
-rw-r--r--gcc/testsuite/c-c++-common/torture/builtin-clear-padding-5.c49
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/sanitize-recover-7.c2
-rw-r--r--gcc/testsuite/c-c++-common/zero-scratch-regs-10.c2
-rw-r--r--gcc/testsuite/c-c++-common/zero-scratch-regs-11.c2
-rw-r--r--gcc/testsuite/c-c++-common/zero-scratch-regs-5.c1
-rw-r--r--gcc/testsuite/c-c++-common/zero-scratch-regs-8.c2
-rw-r--r--gcc/testsuite/c-c++-common/zero-scratch-regs-9.c2
-rw-r--r--gcc/testsuite/g++.dg/abi/macro0.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alignof6.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alignof7.C22
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alignof8.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/auto54.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C37
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor28.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor33.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist-template3.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/using-enum-1.C3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/using-enum-2.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/using-enum-3.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/vt-88982.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-label.C9
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/class-deduction69.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/class-deduction76.C25
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/constexpr-lambda26.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/inline-var8.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/bit-cast1.C47
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/bit-cast2.C57
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/bit-cast3.C229
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/bit-cast4.C44
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/bit-cast5.C69
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/class-deduction-abbrev1.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-decltype3.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-nodiscard1.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/consteval-defarg1.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/consteval-defarg2.C29
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constexpr-dtor10.C16
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constexpr-dtor9.C31
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C6
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/lambda-generic8.C9
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/nontype-class39.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/pr98082.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/srcloc15.C119
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/srcloc16.C97
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/srcloc17.C122
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/srcloc18.C100
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/using-enum-1.C62
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/using-enum-2.C48
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/using-enum-3.C6
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/using-enum-4.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/using-enum-5.C132
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/using-enum-6.C5
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp17.C7
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp20.C7
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/using-enum.C21
-rw-r--r--gcc/testsuite/g++.dg/debug/localclass2.C24
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/pr87386.C2
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/static_assert1.C30
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/static_assert2.C68
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/static_assert3.C36
-rw-r--r--gcc/testsuite/g++.dg/eh/crash2.C20
-rw-r--r--gcc/testsuite/g++.dg/expr/anew5.C26
-rw-r--r--gcc/testsuite/g++.dg/expr/anew6.C33
-rw-r--r--gcc/testsuite/g++.dg/ext/builtin-clear-padding-1.C15
-rw-r--r--gcc/testsuite/g++.dg/ext/sve-sizeless-1.C33
-rw-r--r--gcc/testsuite/g++.dg/ext/sve-sizeless-2.C33
-rw-r--r--gcc/testsuite/g++.dg/goacc/cache-1.C15
-rw-r--r--gcc/testsuite/g++.dg/goacc/cache-2.C64
-rw-r--r--gcc/testsuite/g++.dg/goacc/cache-3-1.C123
-rw-r--r--gcc/testsuite/g++.dg/goacc/cache-3-2.C57
-rw-r--r--gcc/testsuite/g++.dg/goacc/data-clause-1.C122
-rw-r--r--gcc/testsuite/g++.dg/goacc/data-clause-2.C56
-rw-r--r--gcc/testsuite/g++.dg/gomp/map-1.C119
-rw-r--r--gcc/testsuite/g++.dg/gomp/map-2.C54
-rw-r--r--gcc/testsuite/g++.dg/gomp/tls-5.C2
-rw-r--r--gcc/testsuite/g++.dg/guality/redeclaration1.C8
-rw-r--r--gcc/testsuite/g++.dg/hwasan/hwasan.exp34
-rw-r--r--gcc/testsuite/g++.dg/hwasan/rvo-handled.C46
-rw-r--r--gcc/testsuite/g++.dg/inherit/using5.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr98057.C18
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr98075.C30
-rw-r--r--gcc/testsuite/g++.dg/lookup/pr97877.C8
-rw-r--r--gcc/testsuite/g++.dg/lookup/pr97905.C7
-rw-r--r--gcc/testsuite/g++.dg/opt/const4.C3
-rw-r--r--gcc/testsuite/g++.dg/other/abstract1.C29
-rw-r--r--gcc/testsuite/g++.dg/other/abstract2.C57
-rw-r--r--gcc/testsuite/g++.dg/other/abstract4.C4
-rw-r--r--gcc/testsuite/g++.dg/other/abstract5.C2
-rw-r--r--gcc/testsuite/g++.dg/other/abstract8.C40
-rw-r--r--gcc/testsuite/g++.dg/other/i386-2.C2
-rw-r--r--gcc/testsuite/g++.dg/other/i386-3.C2
-rw-r--r--gcc/testsuite/g++.dg/other/pr88187.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/defarg17.C11
-rw-r--r--gcc/testsuite/g++.dg/pr93195a.C27
-rw-r--r--gcc/testsuite/g++.dg/pr93195b.C14
-rw-r--r--gcc/testsuite/g++.dg/template/crash132.C6
-rw-r--r--gcc/testsuite/g++.dg/template/pr98115.C4
-rw-r--r--gcc/testsuite/g++.dg/template/pr98116.C29
-rw-r--r--gcc/testsuite/g++.dg/template/sfinae-dr657.C9
-rw-r--r--gcc/testsuite/g++.dg/torture/builtin-clear-padding-1.C31
-rw-r--r--gcc/testsuite/g++.dg/torture/builtin-clear-padding-2.C34
-rw-r--r--gcc/testsuite/g++.dg/torture/builtin-clear-padding-3.C24
-rw-r--r--gcc/testsuite/g++.dg/torture/pr93347.C320
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/if-to-switch-1.C25
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr90883.C4
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr97736.C12
-rw-r--r--gcc/testsuite/g++.dg/ubsan/pr61272.C4
-rw-r--r--gcc/testsuite/g++.dg/vect/pr98064.cc25
-rw-r--r--gcc/testsuite/g++.dg/vect/simd-12.cc36
-rw-r--r--gcc/testsuite/g++.dg/warn/Warray-bounds-14.C25
-rw-r--r--gcc/testsuite/g++.dg/warn/Warray-bounds-8.C2
-rw-r--r--gcc/testsuite/g++.dg/warn/Wnonnull5.C16
-rw-r--r--gcc/testsuite/g++.dg/warn/Wplacement-new-size-8.C2
-rw-r--r--gcc/testsuite/g++.dg/warn/Wplacement-new-size.C10
-rw-r--r--gcc/testsuite/g++.dg/warn/Wrange-loop-construct2.C212
-rw-r--r--gcc/testsuite/g++.dg/warn/Wstringop-overflow-3.C18
-rw-r--r--gcc/testsuite/g++.dg/warn/Wstringop-overflow-6.C8
-rw-r--r--gcc/testsuite/g++.dg/warn/Wvexing-parse9.C8
-rw-r--r--gcc/testsuite/g++.dg/warn/pr98104.C20
-rw-r--r--gcc/testsuite/g++.dg/warn/uninit-1.C29
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/decl3.C2
-rw-r--r--gcc/testsuite/g++.target/msp430/data-attributes.C55
-rw-r--r--gcc/testsuite/g++.target/msp430/msp430.exp44
-rw-r--r--gcc/testsuite/g++.target/powerpc/pr97947.C12
-rw-r--r--gcc/testsuite/g++.target/riscv/pr97682.C160
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/asmgoto-2.c65
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/asmgoto-3.c89
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/asmgoto-4.c14
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/asmgoto-5.c56
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/attr-used-retain-1.c35
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/attr-used-retain-2.c16
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr97979.c7
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr98087.c14
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/index-1.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr97836.c17
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr97888-1.c24
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr97888-2.c19
-rw-r--r--gcc/testsuite/gcc.dg/20021029-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-43.c27
-rw-r--r--gcc/testsuite/gcc.dg/Wstring-compare-3.c106
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-11.c8
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-12.c7
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-17.c2
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-27.c10
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-28.c33
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-29.c10
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-37.c26
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-46.c10
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-47.c2
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-54.c10
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-58.c260
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-59.c267
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-60.c72
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-61.c88
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-62.c363
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-63.c33
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-64.c74
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-7.c124
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/invalid-shift-1.c34
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-1.c30
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/setjmp-5.c13
-rw-r--r--gcc/testsuite/gcc.dg/array-quals-1.c20
-rw-r--r--gcc/testsuite/gcc.dg/attr-access-3.c21
-rw-r--r--gcc/testsuite/gcc.dg/attr-access-4.c8
-rw-r--r--gcc/testsuite/gcc.dg/attr-access-5.c16
-rw-r--r--gcc/testsuite/gcc.dg/binary-constants-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/binary-constants-3.c4
-rw-r--r--gcc/testsuite/gcc.dg/builtin-arith-overflow-4.c43
-rw-r--r--gcc/testsuite/gcc.dg/builtin-arith-overflow-5.c87
-rw-r--r--gcc/testsuite/gcc.dg/builtin-clear-padding-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/builtin-clear-padding-2.c15
-rw-r--r--gcc/testsuite/gcc.dg/c11-binary-constants-1.c11
-rw-r--r--gcc/testsuite/gcc.dg/c11-binary-constants-2.c11
-rw-r--r--gcc/testsuite/gcc.dg/c11-compare-incomplete-1.c52
-rw-r--r--gcc/testsuite/gcc.dg/c11-compare-incomplete-2.c52
-rw-r--r--gcc/testsuite/gcc.dg/c11-float-4.c25
-rw-r--r--gcc/testsuite/gcc.dg/c11-float-5.c35
-rw-r--r--gcc/testsuite/gcc.dg/c11-float-6.c17
-rw-r--r--gcc/testsuite/gcc.dg/c11-float-dfp-2.c6
-rw-r--r--gcc/testsuite/gcc.dg/c2x-binary-constants-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/c2x-binary-constants-2.c11
-rw-r--r--gcc/testsuite/gcc.dg/c2x-binary-constants-3.c9
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-10.c33
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-2.c23
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-3.c27
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-4.c33
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-5.c32
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-6.c49
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-7.c49
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-8.c7
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-9.c7
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-no-dfp-3.c26
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-no-dfp-4.c10
-rw-r--r--gcc/testsuite/gcc.dg/c2x-has-c-attribute-1.c28
-rw-r--r--gcc/testsuite/gcc.dg/c2x-has-c-attribute-2.c41
-rw-r--r--gcc/testsuite/gcc.dg/c2x-has-c-attribute-3.c25
-rw-r--r--gcc/testsuite/gcc.dg/c2x-has-c-attribute-4.c18
-rw-r--r--gcc/testsuite/gcc.dg/c99-compare-incomplete-1.c52
-rw-r--r--gcc/testsuite/gcc.dg/c99-compare-incomplete-2.c52
-rw-r--r--gcc/testsuite/gcc.dg/cond-constqual-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/line10.c5
-rw-r--r--gcc/testsuite/gcc.dg/cpp/line9.c5
-rw-r--r--gcc/testsuite/gcc.dg/cpp/pr97989-1.c8
-rw-r--r--gcc/testsuite/gcc.dg/cpp/pr97989-2.c8
-rw-r--r--gcc/testsuite/gcc.dg/cr-decimal-dig-3.c14
-rw-r--r--gcc/testsuite/gcc.dg/darwin-sections.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr97060.c13
-rw-r--r--gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-4.c25
-rw-r--r--gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-5.c25
-rw-r--r--gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-6.c28
-rw-r--r--gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-7.c45
-rw-r--r--gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-8.c45
-rw-r--r--gcc/testsuite/gcc.dg/fold-isfinite-1.c21
-rw-r--r--gcc/testsuite/gcc.dg/fold-isfinite-2.c21
-rw-r--r--gcc/testsuite/gcc.dg/fold-isinf-1.c21
-rw-r--r--gcc/testsuite/gcc.dg/fold-isinf-2.c21
-rw-r--r--gcc/testsuite/gcc.dg/fold-isnan-1.c21
-rw-r--r--gcc/testsuite/gcc.dg/fold-isnan-2.c21
-rw-r--r--gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c22
-rw-r--r--gcc/testsuite/gcc.dg/goacc/tile-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/guality/pr59776.c2
-rw-r--r--gcc/testsuite/gcc.dg/hwasan/hwasan.exp36
-rw-r--r--gcc/testsuite/gcc.dg/hwasan/nested-functions-0.c53
-rw-r--r--gcc/testsuite/gcc.dg/hwasan/nested-functions-1.c27
-rw-r--r--gcc/testsuite/gcc.dg/hwasan/nested-functions-2.c28
-rw-r--r--gcc/testsuite/gcc.dg/ipa/modref-2.c5
-rw-r--r--gcc/testsuite/gcc.dg/lto/modref-3_0.c17
-rw-r--r--gcc/testsuite/gcc.dg/lto/modref-3_1.c13
-rw-r--r--gcc/testsuite/gcc.dg/lto/modref-4_0.c17
-rw-r--r--gcc/testsuite/gcc.dg/lto/modref-4_1.c13
-rw-r--r--gcc/testsuite/gcc.dg/lvalue-11.c40
-rw-r--r--gcc/testsuite/gcc.dg/memchr-3.c25
-rw-r--r--gcc/testsuite/gcc.dg/nextafter-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/nextafter-2.c15
-rw-r--r--gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c436
-rw-r--r--gcc/testsuite/gcc.dg/plugin/gil-1.c90
-rw-r--r--gcc/testsuite/gcc.dg/plugin/gil.h32
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin.exp2
-rw-r--r--gcc/testsuite/gcc.dg/pr25376.c1
-rw-r--r--gcc/testsuite/gcc.dg/pr46309-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr60195.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr83072.c14
-rw-r--r--gcc/testsuite/gcc.dg/pr85811.c15
-rw-r--r--gcc/testsuite/gcc.dg/pr91029.c48
-rw-r--r--gcc/testsuite/gcc.dg/pr95853.c59
-rw-r--r--gcc/testsuite/gcc.dg/pr96708-negative.c48
-rw-r--r--gcc/testsuite/gcc.dg/pr96708-positive.c48
-rw-r--r--gcc/testsuite/gcc.dg/pr97459-1.c54
-rw-r--r--gcc/testsuite/gcc.dg/pr97459-2.c57
-rw-r--r--gcc/testsuite/gcc.dg/pr97459-3.c54
-rw-r--r--gcc/testsuite/gcc.dg/pr97459-4.c57
-rw-r--r--gcc/testsuite/gcc.dg/pr97459-5.c56
-rw-r--r--gcc/testsuite/gcc.dg/pr97459-6.c62
-rw-r--r--gcc/testsuite/gcc.dg/pr97515.c8
-rw-r--r--gcc/testsuite/gcc.dg/pr97534.c9
-rw-r--r--gcc/testsuite/gcc.dg/pr97579.c31
-rw-r--r--gcc/testsuite/gcc.dg/pr97806.c16
-rw-r--r--gcc/testsuite/gcc.dg/pr97830.c24
-rw-r--r--gcc/testsuite/gcc.dg/pr97860.c11
-rw-r--r--gcc/testsuite/gcc.dg/pr97897.c14
-rw-r--r--gcc/testsuite/gcc.dg/pr97953.c24
-rw-r--r--gcc/testsuite/gcc.dg/pr97954.c12
-rw-r--r--gcc/testsuite/gcc.dg/pr97955.c7
-rw-r--r--gcc/testsuite/gcc.dg/pr97979.c13
-rw-r--r--gcc/testsuite/gcc.dg/pr98099.c12
-rw-r--r--gcc/testsuite/gcc.dg/profile-info-section.c22
-rw-r--r--gcc/testsuite/gcc.dg/strncmp-2.c1
-rw-r--r--gcc/testsuite/gcc.dg/system-binary-constants-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/float128-nan-floath.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/float128x-nan-floath.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/float16-nan-floath.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/float32-nan-floath.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/float32x-nan-floath.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/float64-nan-floath.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/float64x-nan-floath.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/floatn-nan-floath.h36
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr97812.c15
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr97901.c15
-rw-r--r--gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/torture/ssa-fre-5.c8
-rw-r--r--gcc/testsuite/gcc.dg/torture/ssa-fre-6.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/stringop-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c23
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-11.c12
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-18.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-25.c76
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/evrp20.c19
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/evrp21.c28
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/evrp22.c43
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-1.c35
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-2.c11
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-3.c11
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-4.c36
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-5.c12
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-6.c42
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-7.c25
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-8.c27
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-9.c11
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loopclosedphi.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/modref-5.c27
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr23401.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr27810.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr78655.c37
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr91029-1.c68
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr91029-2.c98
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr93781-1.c18
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr93781-2.c17
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr93781-3.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr96480.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr96789.c5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr96929.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr97849.c16
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr97964.c18
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr97997-1.c52
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr97997-2.c41
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr98084.c26
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr98094.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/reassoc-32.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/slsr-8.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-7.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/switch-1.c6
-rw-r--r--gcc/testsuite/gcc.dg/typeof-2.c20
-rw-r--r--gcc/testsuite/gcc.dg/vect/aligned-section-anchors-nest-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-43.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pr68892.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-3.c5
-rw-r--r--gcc/testsuite/gcc.dg/vect/fast-math-vect-call-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr65947-8.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr91750.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr97678.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr97693.c15
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr97730.c12
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr97835.c22
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr97838.c11
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr98048.c14
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-21.c12
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-46.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-49.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-perm-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-perm-5.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-perm-6.c11
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-perm-7.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-reduc-4.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-reduc-7.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-35-big-array.c7
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-35.c7
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-cost-model-1.c11
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-cost-model-2.c11
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-cost-model-3.c11
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-cost-model-4.c13
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-cost-model-5.c11
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-cost-model-6.c12
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-epilogues.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-outer-slp-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-outer-slp-2.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-outer-slp-3.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-sdiv-pow2-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c8
-rw-r--r--gcc/testsuite/gcc.target/aarch64/aapcs64/abitest-2.h2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/aapcs64/abitest.h2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bf16_vstN_lane_2.c10
-rw-r--r--gcc/testsuite/gcc.target/aarch64/memset-corner-cases.c88
-rw-r--r--gcc/testsuite/gcc.target/aarch64/memset-q-reg.c81
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_f16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_f32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_f64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s8.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s8.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s8.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u8.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s8.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u8.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_bf16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_f16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_f32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_f64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s8.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u8.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_bf16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_f16.c8
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_f32.c6
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_f64.c6
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_s16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_s32.c3
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_s64.c3
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_u16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_u32.c3
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_u64.c3
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extb_s16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extb_s32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extb_s64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/exth_s32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/exth_s64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extw_s64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_f16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_f32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_f64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s8.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s8.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u8.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s8.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u8.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/recpx_f16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/recpx_f32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/recpx_f64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_s16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_s32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_s64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_u16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_u32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_u64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_s32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_s64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_u32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_u64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revw_s64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revw_u64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinta_f16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinta_f32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinta_f64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinti_f16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinti_f32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinti_f64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintm_f16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintm_f32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintm_f64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintn_f16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintn_f32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintn_f64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintp_f16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintp_f32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintp_f64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintx_f16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintx_f32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintx_f64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintz_f16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintz_f32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintz_f64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sqrt_f16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sqrt_f32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sqrt_f64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr98037.c6
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/general/undef_1.c12
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cmp_1.c57
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cmp_2.c72
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_arith_1.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_arith_1_run.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_arith_3.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_arith_3_run.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_1.c3
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_unary_1.c4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/mask_gather_load_7.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/mask_load_slp_1.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/vcond_11.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/vcond_11_run.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/cvtlt_f32.c8
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/cvtlt_f64.c8
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/cvtx_f32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/logb_f16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/logb_f32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/logb_f64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s8.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s16.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s64.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s8.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/recpe_u32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/rsqrte_u32.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve2/bcax_1.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/vect-widen-add.c92
-rw-r--r--gcc/testsuite/gcc.target/aarch64/vect-widen-lshift.c62
-rw-r--r--gcc/testsuite/gcc.target/aarch64/vect-widen-sub.c92
-rw-r--r--gcc/testsuite/gcc.target/arm/cortex-m55-nodsp-flag-hard.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/cortex-m55-nodsp-flag-softfp.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/cortex-m55-nodsp-nofp-flag-softfp.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/cortex-m55-nofp-flag-hard.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/cortex-m55-nofp-flag-softfp.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/cortex-m55-nofp-nomve-flag-softfp.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/cortex-m55-nomve-flag-hard.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/cortex-m55-nomve-flag-softfp.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/cortex-m55-nomve.fp-flag-hard.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/cortex-m55-nomve.fp-flag-softfp.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/mve/intrinsics/pr97327.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/pr91816.c64
-rw-r--r--gcc/testsuite/gcc.target/arm/pr97528.c28
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/bf16_vldn_1.c48
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vldn_lane_bf16_1.c30
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vmmla_1.c2
-rw-r--r--gcc/testsuite/gcc.target/h8300/add-2.c5
-rw-r--r--gcc/testsuite/gcc.target/h8300/add-3.c5
-rw-r--r--gcc/testsuite/gcc.target/h8300/add.c118
-rw-r--r--gcc/testsuite/gcc.target/h8300/sub-2.c5
-rw-r--r--gcc/testsuite/gcc.target/h8300/sub-3.c5
-rw-r--r--gcc/testsuite/gcc.target/h8300/sub.c118
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vnni-1.c29
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vnni-2.c30
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vnni-3.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vnni-4.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vnni-5.c29
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vnni-6.c29
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vpdpbusd-2.c74
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vpdpbusds-2.c74
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vpdpwssd-2.c70
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vpdpwssds-2.c70
-rw-r--r--gcc/testsuite/gcc.target/i386/avx2-vec-set-1.c49
-rw-r--r--gcc/testsuite/gcc.target/i386/avx2-vec-set-2.c50
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bitalg-pr97770-1.c60
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-pr96906-1.c68
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-vec-set-1.c20
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-vec-set-2.c44
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu16-1.c6
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu8-1.c6
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vec-set-2.c42
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vmovapd-1.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vmovaps-1.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vmovdqa32-1.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vmovdqa64-1.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vec-set-2.c55
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vmovapd-1.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vmovaps-1.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vmovdqa32-1.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vmovdqa64-1.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vnni-1a.c (renamed from gcc/testsuite/gcc.target/i386/avx512vl-vnni-1.c)0
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vnni-1b.c69
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vnni-2.c30
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vnni-3.c47
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vnnivl-builtin.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vpopcntdq-pr97770-1.c63
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vpopcntdq-pr97770-2.c39
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vpopcntdqvl-pr97770-1.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/avxvnni-builtin.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/fma4-256-maccXX.c5
-rw-r--r--gcc/testsuite/gcc.target/i386/fma4-256-msubXX.c5
-rw-r--r--gcc/testsuite/gcc.target/i386/fma4-256-nmaccXX.c5
-rw-r--r--gcc/testsuite/gcc.target/i386/fma4-256-nmsubXX.c5
-rw-r--r--gcc/testsuite/gcc.target/i386/fma4-maccXX.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/fma4-msubXX.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/fma4-nmaccXX.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/fma4-nmsubXX.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/funcspec-56.inc2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr31799.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/pr92180.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/pr96906-1.c62
-rw-r--r--gcc/testsuite/gcc.target/i386/pr97282.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/pr97642-1.c41
-rw-r--r--gcc/testsuite/gcc.target/i386/pr97642-2.c77
-rw-r--r--gcc/testsuite/gcc.target/i386/pr97777.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/pr97873-1.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/pr97873-2.c23
-rw-r--r--gcc/testsuite/gcc.target/i386/pr97873-3.c27
-rw-r--r--gcc/testsuite/gcc.target/i386/pr97873.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/pr97887.c15
-rw-r--r--gcc/testsuite/gcc.target/i386/pr97950.c153
-rw-r--r--gcc/testsuite/gcc.target/i386/pr98063.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/pr98079.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/pr98086.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-12.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-13.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-14.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-22.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-23.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/vnni_inline_error.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/x86-needed-1.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/x86-needed-2.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/x86-needed-3.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/xop-haddX.c27
-rw-r--r--gcc/testsuite/gcc.target/i386/xop-hadduX.c22
-rw-r--r--gcc/testsuite/gcc.target/i386/xop-hsubX.c16
-rw-r--r--gcc/testsuite/gcc.target/microblaze/others/strings1.c5
-rw-r--r--gcc/testsuite/gcc.target/msp430/data-attributes-2.c13
-rw-r--r--gcc/testsuite/gcc.target/msp430/pr78818-auto-warn.c4
-rw-r--r--gcc/testsuite/gcc.target/msp430/rtx-cost-O3-default.c42
-rw-r--r--gcc/testsuite/gcc.target/msp430/rtx-cost-O3-f5series.c38
-rw-r--r--gcc/testsuite/gcc.target/msp430/rtx-cost-Os-default.c43
-rw-r--r--gcc/testsuite/gcc.target/msp430/rtx-cost-Os-f5series.c38
-rwxr-xr-xgcc/testsuite/gcc.target/powerpc/mma-double-test.c3
-rwxr-xr-xgcc/testsuite/gcc.target/powerpc/mma-single-test.c3
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr96506-1.c (renamed from gcc/testsuite/gcc.target/powerpc/pr96506.c)24
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr96506-2.c38
-rw-r--r--gcc/testsuite/gcc.target/pru/halt.c9
-rw-r--r--gcc/testsuite/gcc.target/pru/lmbd.c14
-rw-r--r--gcc/testsuite/gcc.target/riscv/arch-10.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/arch-11.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/arch-8.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/arch-9.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-11.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-12.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-13.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-14.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-15.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-16.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-17.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-6.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-8.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-9.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/interrupt-3.c4
-rw-r--r--gcc/testsuite/gcc.target/riscv/interrupt-4.c4
-rw-r--r--gcc/testsuite/gcc.target/s390/builtin-constant-p-threading.c46
-rw-r--r--gcc/testsuite/gcc.target/s390/float_t-1.c15
-rw-r--r--gcc/testsuite/gcc.target/s390/float_t-2.c13
-rw-r--r--gcc/testsuite/gcc.target/s390/load-imm64-1.c14
-rw-r--r--gcc/testsuite/gcc.target/s390/load-imm64-2.c14
-rw-r--r--gcc/testsuite/gcc.target/s390/s390.exp10
-rw-r--r--gcc/testsuite/gcc.target/s390/stack-clash-4.c10
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-caller-abi-run.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-copysign.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-from-double.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-from-float.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-from-i16.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-from-i32.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-from-i64.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-from-i8.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-from-u16.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-from-u32.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-from-u64.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-from-u8.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-to-double.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-to-float.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-to-i16.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-to-i32.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-to-i64.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-to-i8.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-to-u16.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-to-u32.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-to-u64.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-to-u8.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-wfaxb.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-wfdxb.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-wfsxb-1.c3
-rw-r--r--gcc/testsuite/gcc.target/s390/zvector/autovec-double-quiet-uneq.c5
-rw-r--r--gcc/testsuite/gcc.target/s390/zvector/autovec-float-quiet-uneq.c5
-rw-r--r--gcc/testsuite/gcc.target/sparc/overflow-6.c20
-rw-r--r--gcc/testsuite/gcc.target/vax/bswapdi-1.c2
-rw-r--r--gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-1-exp-F.S13
-rw-r--r--gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-2-exp-F.S9
-rw-r--r--gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-3-exp-F.S10
-rw-r--r--gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-exp-P.S50
-rw-r--r--gcc/testsuite/gcc.test-framework/test-framework.exp3
-rw-r--r--gcc/testsuite/gdc.dg/intrinsics.d92
-rw-r--r--gcc/testsuite/gdc.dg/pr92216.d4
-rw-r--r--gcc/testsuite/gdc.dg/torture/pr97843.d37
-rw-r--r--gcc/testsuite/gdc.dg/torture/pr97889.d29
-rw-r--r--gcc/testsuite/gdc.test/compilable/callconv.d20
-rw-r--r--gcc/testsuite/gdc.test/compilable/test17419.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail18970.d37
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/imports/test21164a.d9
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/imports/test21164b.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/imports/test21164c.d10
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/imports/test21164d.d9
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test21164.d13
-rw-r--r--gcc/testsuite/gdc.test/runnable/dhry.d927
-rw-r--r--gcc/testsuite/gdc.test/runnable/nested.d9
-rw-r--r--gcc/testsuite/gdc.test/runnable/test4.d12
-rw-r--r--gcc/testsuite/gfortran.dg/entry_23.f57
-rw-r--r--gcc/testsuite/gfortran.dg/goacc-gomp/fixed-1.f81
-rw-r--r--gcc/testsuite/gfortran.dg/goacc-gomp/free-1.f9034
-rw-r--r--gcc/testsuite/gfortran.dg/goacc/classify-kernels-unparallelized.f954
-rw-r--r--gcc/testsuite/gfortran.dg/goacc/classify-kernels.f954
-rw-r--r--gcc/testsuite/gfortran.dg/goacc/classify-parallel.f954
-rw-r--r--gcc/testsuite/gfortran.dg/goacc/classify-serial.f9531
-rw-r--r--gcc/testsuite/gfortran.dg/goacc/fixed-5.f30
-rw-r--r--gcc/testsuite/gfortran.dg/goacc/kernels-decompose-1.f9589
-rw-r--r--gcc/testsuite/gfortran.dg/goacc/kernels-decompose-2.f95150
-rw-r--r--gcc/testsuite/gfortran.dg/goacc/kernels-tree.f955
-rw-r--r--gcc/testsuite/gfortran.dg/goacc/sentinel-free-form.f957
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/declare-target-4.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/reduction4.f90171
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/reduction5.f9041
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/requires-4.f906
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/schedule-modifiers-2.f908
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-1.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-10.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-11.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-12.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-13.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-14.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-15.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-16.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-17.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-18.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-19.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-2.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-20.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-21.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-22.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-23.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-24.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-25.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-29.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-30.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-31.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-32.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-33.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-34.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-35.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-4.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-48.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-49.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-5.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-50.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-51.f9035
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-52.f9035
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-53.f9035
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-54.f9035
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-55.f9035
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f9035
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f9035
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-58.f9035
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-6.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-7.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-8.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/workshare-reduction-9.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/ipcp-array-2.f9045
-rw-r--r--gcc/testsuite/gfortran.dg/pr48958.f9025
-rw-r--r--gcc/testsuite/gfortran.dg/pr85796.f908
-rw-r--r--gcc/testsuite/gfortran.dg/pr95342.f9020
-rw-r--r--gcc/testsuite/gfortran.dg/pr97768_1.f9025
-rw-r--r--gcc/testsuite/gfortran.dg/pr97768_2.f9053
-rw-r--r--gcc/testsuite/gfortran.dg/pr98017.f9014
-rw-r--r--gcc/testsuite/gnat.dg/bias2.adb33
-rw-r--r--gcc/testsuite/gnat.dg/multfixed.adb3
-rw-r--r--gcc/testsuite/gnat.dg/opt89.adb18
-rw-r--r--gcc/testsuite/gnat.dg/opt90a.adb16
-rw-r--r--gcc/testsuite/gnat.dg/opt90a_pkg.ads15
-rw-r--r--gcc/testsuite/gnat.dg/opt90b.adb16
-rw-r--r--gcc/testsuite/gnat.dg/opt90b_pkg.ads16
-rw-r--r--gcc/testsuite/gnat.dg/opt90c.adb16
-rw-r--r--gcc/testsuite/gnat.dg/opt90c_pkg.ads16
-rw-r--r--gcc/testsuite/gnat.dg/opt90d.adb16
-rw-r--r--gcc/testsuite/gnat.dg/opt90d_pkg.ads16
-rw-r--r--gcc/testsuite/gnat.dg/opt90e.adb16
-rw-r--r--gcc/testsuite/gnat.dg/opt90e_pkg.ads16
-rw-r--r--gcc/testsuite/gnat.dg/shift1.adb15
-rw-r--r--gcc/testsuite/go.test/go-test.exp12
-rw-r--r--gcc/testsuite/go.test/test/alias.go2
-rw-r--r--gcc/testsuite/go.test/test/alias1.go2
-rw-r--r--gcc/testsuite/go.test/test/alias2.go104
-rw-r--r--gcc/testsuite/go.test/test/alias3.dir/a.go42
-rw-r--r--gcc/testsuite/go.test/test/alias3.dir/b.go26
-rw-r--r--gcc/testsuite/go.test/test/alias3.dir/c.go25
-rw-r--r--gcc/testsuite/go.test/test/alias3.go7
-rw-r--r--gcc/testsuite/go.test/test/append.go25
-rw-r--r--gcc/testsuite/go.test/test/assign.go12
-rw-r--r--gcc/testsuite/go.test/test/bench/garbage/Makefile2
-rw-r--r--gcc/testsuite/go.test/test/bench/garbage/parser.go4
-rw-r--r--gcc/testsuite/go.test/test/bench/garbage/stats.go2
-rw-r--r--gcc/testsuite/go.test/test/bench/garbage/tree.go2
-rw-r--r--gcc/testsuite/go.test/test/bench/garbage/tree2.go2
-rw-r--r--gcc/testsuite/go.test/test/bench/go1/binarytree_test.go2
-rw-r--r--gcc/testsuite/go.test/test/bench/go1/fannkuch_test.go2
-rw-r--r--gcc/testsuite/go.test/test/bench/go1/fasta_test.go10
-rw-r--r--gcc/testsuite/go.test/test/bench/go1/gob_test.go2
-rw-r--r--gcc/testsuite/go.test/test/bench/go1/gzip_test.go2
-rw-r--r--gcc/testsuite/go.test/test/bench/go1/http_test.go2
-rw-r--r--gcc/testsuite/go.test/test/bench/go1/json_test.go2
-rw-r--r--gcc/testsuite/go.test/test/bench/go1/jsondata_test.go4
-rw-r--r--gcc/testsuite/go.test/test/bench/go1/mandel_test.go2
-rw-r--r--gcc/testsuite/go.test/test/bench/go1/parserdata_test.go6
-rw-r--r--gcc/testsuite/go.test/test/bench/go1/revcomp_test.go2
-rw-r--r--gcc/testsuite/go.test/test/bench/go1/template_test.go2
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/binary-tree-freelist.go129
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/binary-tree-freelist.txt8
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/binary-tree.c164
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/binary-tree.go92
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/binary-tree.txt8
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/chameneosredux.c330
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/chameneosredux.go180
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/chameneosredux.txt29
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/fannkuch-parallel.go224
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/fannkuch-parallel.txt31
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/fannkuch.c134
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/fannkuch.go122
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/fannkuch.txt31
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/fasta-1000.out171
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/fasta.c219
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/fasta.go205
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/fasta.txt171
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/k-nucleotide-parallel.go157
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/k-nucleotide-parallel.txt27
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/k-nucleotide.c228
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/k-nucleotide.go140
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/k-nucleotide.txt27
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/mandelbrot.c91
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/mandelbrot.go95
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/mandelbrot.txtbin5011 -> 0 bytes
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/meteor-contest.c626
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/meteor-contest.go656
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/meteor-contest.txt24
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/nbody.c170
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/nbody.go177
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/nbody.txt2
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/pidigits.c123
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/pidigits.go135
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/pidigits.txt3
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/regex-dna-parallel.go124
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/regex-dna-parallel.txt13
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/regex-dna.c154
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/regex-dna.go106
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/regex-dna.txt13
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/reverse-complement.c100
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/reverse-complement.go105
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/reverse-complement.txt171
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/spectral-norm-parallel.go111
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/spectral-norm.c82
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/spectral-norm.go93
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/spectral-norm.txt1
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/threadring.c103
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/threadring.go71
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/threadring.txt1
-rw-r--r--gcc/testsuite/go.test/test/bench/shootout/timing.log1254
-rwxr-xr-xgcc/testsuite/go.test/test/bench/shootout/timing.sh219
-rw-r--r--gcc/testsuite/go.test/test/blank1.go6
-rw-r--r--gcc/testsuite/go.test/test/bombad.go2
-rw-r--r--gcc/testsuite/go.test/test/bounds.go108
-rw-r--r--gcc/testsuite/go.test/test/bugs/bug395.go25
-rw-r--r--gcc/testsuite/go.test/test/bugs/placeholder2
-rw-r--r--gcc/testsuite/go.test/test/chan/doubleselect.go1
-rw-r--r--gcc/testsuite/go.test/test/chan/fifo.go1
-rw-r--r--gcc/testsuite/go.test/test/chan/perm.go30
-rw-r--r--gcc/testsuite/go.test/test/chan/powser1.go326
-rw-r--r--gcc/testsuite/go.test/test/chan/powser2.go412
-rw-r--r--gcc/testsuite/go.test/test/chan/select2.go2
-rw-r--r--gcc/testsuite/go.test/test/chan/select3.go18
-rw-r--r--gcc/testsuite/go.test/test/chan/select5.go10
-rw-r--r--gcc/testsuite/go.test/test/chan/select6.go2
-rw-r--r--gcc/testsuite/go.test/test/chan/select7.go2
-rw-r--r--gcc/testsuite/go.test/test/chan/select8.go55
-rw-r--r--gcc/testsuite/go.test/test/chan/sendstmt.go6
-rw-r--r--gcc/testsuite/go.test/test/chancap.go44
-rw-r--r--gcc/testsuite/go.test/test/cmp.go61
-rw-r--r--gcc/testsuite/go.test/test/cmp6.go13
-rw-r--r--gcc/testsuite/go.test/test/cmplx.go14
-rw-r--r--gcc/testsuite/go.test/test/cmplxdivide.c87
-rw-r--r--gcc/testsuite/go.test/test/cmplxdivide.go27
-rw-r--r--gcc/testsuite/go.test/test/cmplxdivide1.go6511
-rw-r--r--gcc/testsuite/go.test/test/complit1.go25
-rw-r--r--gcc/testsuite/go.test/test/compos.go2
-rw-r--r--gcc/testsuite/go.test/test/const.go83
-rw-r--r--gcc/testsuite/go.test/test/const1.go6
-rw-r--r--gcc/testsuite/go.test/test/const4.go2
-rw-r--r--gcc/testsuite/go.test/test/const5.go6
-rw-r--r--gcc/testsuite/go.test/test/const6.go2
-rw-r--r--gcc/testsuite/go.test/test/convert1.go2
-rw-r--r--gcc/testsuite/go.test/test/convlit.go11
-rw-r--r--gcc/testsuite/go.test/test/ddd.go2
-rw-r--r--gcc/testsuite/go.test/test/ddd1.go18
-rw-r--r--gcc/testsuite/go.test/test/ddd2.dir/ddd2.go2
-rw-r--r--gcc/testsuite/go.test/test/ddd2.dir/ddd3.go2
-rw-r--r--gcc/testsuite/go.test/test/ddd2.go2
-rw-r--r--gcc/testsuite/go.test/test/deferprint.go4
-rw-r--r--gcc/testsuite/go.test/test/divide.go2
-rw-r--r--gcc/testsuite/go.test/test/divmod.go4
-rw-r--r--gcc/testsuite/go.test/test/eof.go2
-rw-r--r--gcc/testsuite/go.test/test/eof1.go2
-rwxr-xr-xgcc/testsuite/go.test/test/errchk147
-rw-r--r--gcc/testsuite/go.test/test/escape2.go1139
-rw-r--r--gcc/testsuite/go.test/test/escape3.go2
-rw-r--r--gcc/testsuite/go.test/test/escape4.go28
-rw-r--r--gcc/testsuite/go.test/test/escape5.go160
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug083.dir/bug0.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug083.dir/bug1.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug088.dir/bug0.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug088.dir/bug1.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug106.dir/bug0.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug106.dir/bug1.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug108.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug121.go1
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug133.dir/bug0.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug133.dir/bug1.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug133.dir/bug2.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug1515.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug160.dir/x.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug160.dir/y.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug169.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug173.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug176.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug195.go16
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug203.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug206.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug214.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug215.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug216.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug217.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug218.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug221.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug227.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug228.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug229.go10
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug230.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug231.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug232.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug233.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug234.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug235.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug236.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug237.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug243.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug245.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug247.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug248.dir/bug1.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug248.dir/bug2.go106
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug248.dir/bug3.go102
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug248.go17
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug249.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug250.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug252.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug253.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug254.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug255.go21
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug256.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug257.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug258.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug259.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug261.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug264.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug265.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug266.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug269.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug271.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug272.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug273.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug274.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug275.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug278.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug279.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug280.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug281.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug282.dir/p1.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug282.dir/p2.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug283.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug285.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug286.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug287.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug288.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug289.go6
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug290.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug291.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug292.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug293.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug294.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug295.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug296.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug297.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug298.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug299.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug300.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug301.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug302.dir/main.go6
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug302.dir/p.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug302.go46
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug303.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug304.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug305.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug306.dir/p1.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug306.dir/p2.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug308.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug309.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug311.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug312.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug313.dir/a.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug313.dir/b.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug313.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug317.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug319.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug320.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug321.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug323.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug325.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug326.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug327.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug328.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug329.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug330.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug331.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug332.go6
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug333.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug334.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug335.dir/a.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug335.dir/b.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug335.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug336.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug337.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug338.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug339.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug340.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug341.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug342.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug343.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug344.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug345.dir/io.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug345.dir/main.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug345.go10
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug346.go27
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug347.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug348.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug349.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug350.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug351.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug352.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug353.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug354.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug355.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug356.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug357.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug358.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug361.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug362.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug363.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug365.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug366.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug368.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug369.dir/pkg.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug369.go73
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug370.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug371.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug372.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug373.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug374.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug375.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug376.go5
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug378.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug379.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug380.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug381.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug382.dir/pkg.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug383.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug384.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug385_32.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug385_64.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug386.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug387.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug388.go6
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug389.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug391.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug392.dir/one.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug392.dir/pkg2.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug392.dir/pkg3.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug393.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug394.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug396.dir/one.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug396.dir/two.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug397.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug398.go28
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug399.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug401.go5
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug402.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug403.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug404.dir/one.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug404.dir/two.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug406.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug407.dir/one.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug407.dir/two.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug409.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug410.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug411.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug412.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug413.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug414.dir/p1.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug414.dir/prog.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug414.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug415.dir/p.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug415.dir/prog.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug415.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug416.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug424.dir/lib.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug424.dir/main.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug424.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug425.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug427.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug428.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug429.go8
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug435.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug437.dir/one.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug437.dir/two.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug437.dir/x.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug437.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug441.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug442.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug443.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug444.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug445.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug447.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug448.dir/pkg1.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug448.dir/pkg2.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug448.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug450.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug452.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug453.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug454.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug455.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug456.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug457.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug458.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug459.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug460.dir/a.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug460.dir/b.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug460.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug461.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug462.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug463.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug464.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug465.dir/a.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug465.dir/b.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug465.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug466.dir/a.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug466.dir/b.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug466.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug467.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug468.dir/p1.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug468.dir/p2.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug468.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug470.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug471.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug472.dir/p1.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug472.dir/p2.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug472.dir/z.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug472.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug473.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug474.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug475.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug476.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug477.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug478.dir/a.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug478.dir/b.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug478.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug479.dir/a.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug479.dir/b.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug479.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug480.dir/a.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug480.dir/b.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug480.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug481.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug482.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug487.go24
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug488.dir/a.go7
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug488.dir/b.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug488.go12
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug489.go22
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug492.dir/a.go16
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug492.dir/b.go11
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug492.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug493.go15
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug494.go51
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug496.go29
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug497.go28
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug499.go15
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug500.go41
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug501.go24
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug502.go28
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug503.go16
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug504.dir/a.go7
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug504.dir/b.go11
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug504.dir/c.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug504.dir/main.go11
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug504.go10
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug505.go20
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug506.dir/a.go16
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug506.dir/main.go20
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug506.go10
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug507.dir/a.go13
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug507.dir/b.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug507.dir/c.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug507.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug508.go14
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug509.go30
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/gcc67968.dir/a.go12
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/gcc67968.dir/b.go12
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/gcc67968.go14
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/gcc78763.go19
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/gcc80226.go17
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/gcc89321.go17
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue12621.go20
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue14540.go20
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue15002.go132
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue16949.go30
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue19113.go108
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue20923.go19
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue21253.go27
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue22305.go15
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue23188.go32
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue23489.go20
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue23912.go30
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue2615.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue26335.go32
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue26340.go21
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue28601.go15
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue30116.go112
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue30116.out558
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue30116u.go112
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue30116u.out340
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue30659.dir/a.go19
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue30659.dir/b.go13
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue30659.go7
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue32901.dir/a.go15
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue32901.dir/b.go15
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue32901.dir/c.go17
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue32901.dir/main.go18
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue32901.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue32922.dir/a.go18
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue32922.dir/b.go11
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue32922.go11
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33013.dir/a.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33013.dir/b.go24
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33013.dir/c.go19
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33013.dir/d.go16
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33013.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33020.dir/a.go16
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33020.dir/b.go22
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33020.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33062.go33
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33158.dir/a.go25
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33158.dir/b.go11
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33158.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33219.dir/a.go17
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33219.dir/b.go25
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33219.dir/c.go20
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33219.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33739.dir/a.go11
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33739.dir/b.go11
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue33739.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue34503.dir/a.go15
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue34503.dir/b.go11
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue34503.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue34577.dir/a.go27
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue34577.dir/b.go23
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue34577.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue3552.dir/one.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue3552.dir/two.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue35739.dir/a.go15
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue35739.dir/b.go11
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue35739.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue3705.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue3783.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue38125.go22
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue3924.go13
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue3925.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue40152.go21
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue40252.dir/a.go14
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue40252.dir/main.go16
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue40252.go8
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4085a.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4085b.go37
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4097.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4099.go6
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4162.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4167.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4232.go31
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4251.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4252.dir/a.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4252.dir/main.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4252.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue42790.go9
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4283.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4313.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4316.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4323.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4326.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4348.go6
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4353.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4359.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4370.dir/p1.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4370.dir/p2.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4370.dir/p3.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4370.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4396a.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4396b.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4399.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4405.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4429.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4448.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4452.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4458.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4463.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4468.go10
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4470.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4495.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4517a.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4517b.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4517c.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4517d.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4518.go8
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4529.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4545.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4562.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4585.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4590.dir/pkg1.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4590.dir/pkg2.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4590.dir/prog.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4614.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4618.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4620.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4654.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4663.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4667.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4734.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4748.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4752.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4776.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4785.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4909a.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue4964.dir/a.go6
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue5002.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue5056.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue5172.go11
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue5231.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue5358.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue5581.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue5698.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue5704.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue5809.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue5820.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue5841.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue5856.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue5963.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue6004.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue6036.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue6055.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue6131.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue6140.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue6247.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue6269.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue6298.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue6513.dir/a.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue6513.dir/b.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue6513.dir/main.go2
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue6899.go4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue6977.go40
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue8042.go66
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/issue887.go2
-rw-r--r--gcc/testsuite/go.test/test/func6.go4
-rw-r--r--gcc/testsuite/go.test/test/func7.go4
-rw-r--r--gcc/testsuite/go.test/test/func8.go8
-rw-r--r--gcc/testsuite/go.test/test/funcdup.go2
-rw-r--r--gcc/testsuite/go.test/test/funcdup2.go2
-rw-r--r--gcc/testsuite/go.test/test/gc2.go5
-rw-r--r--gcc/testsuite/go.test/test/golden.out24
-rw-r--r--gcc/testsuite/go.test/test/goprint.go24
-rw-r--r--gcc/testsuite/go.test/test/goto.go90
-rw-r--r--gcc/testsuite/go.test/test/helloworld.go2
-rw-r--r--gcc/testsuite/go.test/test/import2.dir/import2.go2
-rw-r--r--gcc/testsuite/go.test/test/import2.dir/import3.go2
-rw-r--r--gcc/testsuite/go.test/test/import2.go2
-rw-r--r--gcc/testsuite/go.test/test/import5.go36
-rw-r--r--gcc/testsuite/go.test/test/index.go6
-rw-r--r--gcc/testsuite/go.test/test/index0.go2
-rw-r--r--gcc/testsuite/go.test/test/index1.go2
-rw-r--r--gcc/testsuite/go.test/test/index2.go2
-rw-r--r--gcc/testsuite/go.test/test/init.go4
-rw-r--r--gcc/testsuite/go.test/test/init1.go28
-rw-r--r--gcc/testsuite/go.test/test/initializerr.go1
-rw-r--r--gcc/testsuite/go.test/test/interface/embed2.go23
-rw-r--r--gcc/testsuite/go.test/test/interface/explicit.go8
-rw-r--r--gcc/testsuite/go.test/test/interface/noeq.go2
-rw-r--r--gcc/testsuite/go.test/test/interface/recursive1.dir/recursive1.go2
-rw-r--r--gcc/testsuite/go.test/test/interface/recursive1.dir/recursive2.go2
-rw-r--r--gcc/testsuite/go.test/test/interface/recursive1.go2
-rw-r--r--gcc/testsuite/go.test/test/ken/cplx0.go2
-rw-r--r--gcc/testsuite/go.test/test/ken/embed.go2
-rw-r--r--gcc/testsuite/go.test/test/ken/modconst.go2
-rw-r--r--gcc/testsuite/go.test/test/ken/string.go2
-rw-r--r--gcc/testsuite/go.test/test/label.go9
-rw-r--r--gcc/testsuite/go.test/test/label1.go50
-rw-r--r--gcc/testsuite/go.test/test/linkx.go32
-rw-r--r--gcc/testsuite/go.test/test/map.go2
-rw-r--r--gcc/testsuite/go.test/test/map1.go12
-rw-r--r--gcc/testsuite/go.test/test/mapnan.go56
-rw-r--r--gcc/testsuite/go.test/test/method1.go18
-rw-r--r--gcc/testsuite/go.test/test/method2.go8
-rw-r--r--gcc/testsuite/go.test/test/method4.dir/prog.go9
-rw-r--r--gcc/testsuite/go.test/test/method5.go2
-rw-r--r--gcc/testsuite/go.test/test/named.go2
-rw-r--r--gcc/testsuite/go.test/test/named1.go10
-rw-r--r--gcc/testsuite/go.test/test/nilcheck.go105
-rw-r--r--gcc/testsuite/go.test/test/nilptr.go6
-rw-r--r--gcc/testsuite/go.test/test/nilptr2.go2
-rw-r--r--gcc/testsuite/go.test/test/nilptr3.go200
-rw-r--r--gcc/testsuite/go.test/test/nul1.go7
-rw-r--r--gcc/testsuite/go.test/test/peano.go8
-rw-r--r--gcc/testsuite/go.test/test/printbig.go2
-rw-r--r--gcc/testsuite/go.test/test/range.go186
-rw-r--r--gcc/testsuite/go.test/test/recover.go94
-rw-r--r--gcc/testsuite/go.test/test/recover1.go2
-rw-r--r--gcc/testsuite/go.test/test/recover2.go4
-rw-r--r--gcc/testsuite/go.test/test/recover3.go2
-rw-r--r--gcc/testsuite/go.test/test/rename.go2
-rw-r--r--gcc/testsuite/go.test/test/rename1.go6
-rw-r--r--gcc/testsuite/go.test/test/reorder.go39
-rw-r--r--gcc/testsuite/go.test/test/reorder2.go177
-rw-r--r--gcc/testsuite/go.test/test/return.go2
-rw-r--r--gcc/testsuite/go.test/test/rotate.go2
-rw-r--r--gcc/testsuite/go.test/test/rotate0.go2
-rw-r--r--gcc/testsuite/go.test/test/rotate1.go2
-rw-r--r--gcc/testsuite/go.test/test/rotate2.go2
-rw-r--r--gcc/testsuite/go.test/test/rotate3.go2
-rwxr-xr-xgcc/testsuite/go.test/test/run138
-rw-r--r--gcc/testsuite/go.test/test/run.go1322
-rw-r--r--gcc/testsuite/go.test/test/rune.go2
-rw-r--r--gcc/testsuite/go.test/test/runtime.go2
-rw-r--r--gcc/testsuite/go.test/test/safe/main.go14
-rw-r--r--gcc/testsuite/go.test/test/safe/nousesafe.go8
-rw-r--r--gcc/testsuite/go.test/test/safe/pkg.go16
-rw-r--r--gcc/testsuite/go.test/test/safe/usesafe.go8
-rw-r--r--gcc/testsuite/go.test/test/shift1.go18
-rw-r--r--gcc/testsuite/go.test/test/shift2.go2
-rw-r--r--gcc/testsuite/go.test/test/sigchld.go4
-rw-r--r--gcc/testsuite/go.test/test/sinit.go90
-rw-r--r--gcc/testsuite/go.test/test/sizeof.go2
-rw-r--r--gcc/testsuite/go.test/test/slice3err.go2
-rw-r--r--gcc/testsuite/go.test/test/stress/maps.go4
-rw-r--r--gcc/testsuite/go.test/test/stress/parsego.go4
-rw-r--r--gcc/testsuite/go.test/test/stress/runstress.go2
-rw-r--r--gcc/testsuite/go.test/test/struct0.go2
-rw-r--r--gcc/testsuite/go.test/test/syntax/chan.go8
-rw-r--r--gcc/testsuite/go.test/test/syntax/chan1.go6
-rw-r--r--gcc/testsuite/go.test/test/syntax/composite.go4
-rw-r--r--gcc/testsuite/go.test/test/syntax/else.go2
-rw-r--r--gcc/testsuite/go.test/test/syntax/forvar.go10
-rw-r--r--gcc/testsuite/go.test/test/syntax/if.go2
-rw-r--r--gcc/testsuite/go.test/test/syntax/import.go2
-rw-r--r--gcc/testsuite/go.test/test/syntax/interface.go2
-rw-r--r--gcc/testsuite/go.test/test/syntax/semi1.go4
-rw-r--r--gcc/testsuite/go.test/test/syntax/semi2.go2
-rw-r--r--gcc/testsuite/go.test/test/syntax/semi3.go4
-rw-r--r--gcc/testsuite/go.test/test/syntax/semi4.go6
-rw-r--r--gcc/testsuite/go.test/test/syntax/semi5.go2
-rw-r--r--gcc/testsuite/go.test/test/syntax/semi6.go8
-rw-r--r--gcc/testsuite/go.test/test/syntax/semi7.go4
-rw-r--r--gcc/testsuite/go.test/test/syntax/topexpr.go2
-rw-r--r--gcc/testsuite/go.test/test/syntax/typesw.go4
-rw-r--r--gcc/testsuite/go.test/test/syntax/vareq.go2
-rw-r--r--gcc/testsuite/go.test/test/syntax/vareq1.go4
-rw-r--r--gcc/testsuite/go.test/test/testlib170
-rw-r--r--gcc/testsuite/go.test/test/torture.go7
-rw-r--r--gcc/testsuite/go.test/test/typecheck.go12
-rw-r--r--gcc/testsuite/go.test/test/typeswitch2.go16
-rw-r--r--gcc/testsuite/go.test/test/typeswitch3.go31
-rw-r--r--gcc/testsuite/go.test/test/undef.go2
-rw-r--r--gcc/testsuite/go.test/test/varerr.go2
-rw-r--r--gcc/testsuite/go.test/test/zerodivide.go9
-rw-r--r--gcc/testsuite/jit.dg/jit.exp31
-rw-r--r--gcc/testsuite/jit.dg/test-asm.c492
-rw-r--r--gcc/testsuite/jit.dg/test-asm.cc453
-rw-r--r--gcc/testsuite/jit.dg/test-debug-strings.c20
-rw-r--r--gcc/testsuite/lib/asan-dg.exp31
-rw-r--r--gcc/testsuite/lib/gcc-dg.exp4
-rw-r--r--gcc/testsuite/lib/hwasan-dg.exp167
-rw-r--r--gcc/testsuite/lib/options.exp5
-rw-r--r--gcc/testsuite/lib/profopt.exp1
-rw-r--r--gcc/testsuite/lib/prune.exp10
-rw-r--r--gcc/testsuite/lib/scanasm.exp184
-rw-r--r--gcc/testsuite/lib/target-supports.exp113
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/class-attribute-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/class-attribute-2.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/class-attribute-3.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/method-deprecated-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/method-deprecated-2.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/method-deprecated-3.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/method-format-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/method-nonnull-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/method-noreturn-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/method-sentinel-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/nsobject-01.mm2
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/nullability-00.mm20
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/parameter-attribute-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/parameter-attribute-2.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/proto-attribute-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/proto-attribute-3.mm2
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/proto-attribute-4.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/root-class-01.mm11
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/unused-parameter-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/bad-receiver-type.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/bitfield-3.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/bitfield-5.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/class-extension-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/class-extension-2.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/class-extension-3.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/class-extension-4.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/class-protocol-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/comp-types-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/comp-types-10.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/comp-types-2.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/comp-types-3.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/comp-types-5.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/comp-types-6.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/comp-types-7.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/comp-types-8.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/demangle-2.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/demangle-3.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/duplicate-class-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/encode-1-next.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/encode-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/enhanced-proto-2.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/exceptions-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/exceptions-3.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/exceptions-4.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/exceptions-5.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/extern-c-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/fobjc-std-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/gnu-api-2-class-meta.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/gnu-api-2-class.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/gnu-api-2-ivar.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/gnu-api-2-method.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/gnu-api-2-objc.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/gnu-api-2-objc_msg_lookup.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/gnu-api-2-object.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/gnu-api-2-property.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/gnu-api-2-protocol.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/gnu-api-2-resolve-method.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/gnu-api-2-sel.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/invalid-method-2.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/ivar-invalid-type-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/ivar-problem-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/lto/lto.exp16
-rw-r--r--gcc/testsuite/obj-c++.dg/lto/trivial-1_0.mm2
-rw-r--r--gcc/testsuite/obj-c++.dg/method-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/method-12.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/method-18.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/method-19.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/method-20.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/method-3.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/method-4.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/method-5.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/method-8.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/method-9.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/method-namespace-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/plugin/diagnostic-test-expressions-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/pr23709.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/pragma-2.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/private-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/private-2.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/property/at-property-4.mm20
-rw-r--r--gcc/testsuite/obj-c++.dg/property/nullability-00.mm21
-rw-r--r--gcc/testsuite/obj-c++.dg/property/property.exp4
-rw-r--r--gcc/testsuite/obj-c++.dg/proto-lossage-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/proto-lossage-5.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/proto-qual-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/protocol-inheritance-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/protocol-inheritance-2.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/protocol-optional-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/root-class-00.mm10
-rw-r--r--gcc/testsuite/obj-c++.dg/selector-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/selector-2.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/selector-3.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/selector-4.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/strings/strings.exp4
-rw-r--r--gcc/testsuite/obj-c++.dg/stubify-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/stubify-2.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/super-dealloc-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/super-dealloc-2.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/sync-3.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/syntax-error-2.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/syntax-error-4.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/syntax-error-7.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/syntax-error-9.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/template-4.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/template-7.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/template-8.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/threedotthree-abi-1.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/torture/dg-torture.exp4
-rw-r--r--gcc/testsuite/obj-c++.dg/torture/strings/strings.exp4
-rw-r--r--gcc/testsuite/obj-c++.dg/try-catch-12.mm1
-rw-r--r--gcc/testsuite/obj-c++.dg/try-catch-13.mm1
-rw-r--r--gcc/testsuite/objc.dg/anon-1.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/class-attribute-1.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/class-attribute-2.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/class-attribute-3.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/method-deprecated-1.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/method-deprecated-2.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/method-deprecated-3.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/method-format-1.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/method-nonnull-1.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/method-noreturn-1.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/method-sentinel-1.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/nsobject-01.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/nullability-00.m20
-rw-r--r--gcc/testsuite/objc.dg/attributes/objc-exception-1.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/parameter-attribute-1.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/parameter-attribute-2.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/proto-attribute-1.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/proto-attribute-2.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/proto-attribute-3.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/proto-attribute-4.m1
-rw-r--r--gcc/testsuite/objc.dg/attributes/root-class-01.m11
-rw-r--r--gcc/testsuite/objc.dg/bitfield-2.m1
-rw-r--r--gcc/testsuite/objc.dg/break-in-ifstmt.m1
-rw-r--r--gcc/testsuite/objc.dg/class-1.m4
-rw-r--r--gcc/testsuite/objc.dg/class-extension-1.m1
-rw-r--r--gcc/testsuite/objc.dg/class-extension-2.m1
-rw-r--r--gcc/testsuite/objc.dg/class-extension-3.m1
-rw-r--r--gcc/testsuite/objc.dg/class-extension-4.m1
-rw-r--r--gcc/testsuite/objc.dg/class-protocol-1.m1
-rw-r--r--gcc/testsuite/objc.dg/comp-types-7.m1
-rw-r--r--gcc/testsuite/objc.dg/demangle-1.m1
-rw-r--r--gcc/testsuite/objc.dg/duplicate-class-1.m1
-rw-r--r--gcc/testsuite/objc.dg/encode-6-next.m1
-rw-r--r--gcc/testsuite/objc.dg/encode-6.m1
-rw-r--r--gcc/testsuite/objc.dg/enhanced-proto-2.m1
-rw-r--r--gcc/testsuite/objc.dg/exceptions-1.m1
-rw-r--r--gcc/testsuite/objc.dg/exceptions-3.m1
-rw-r--r--gcc/testsuite/objc.dg/exceptions-4.m1
-rw-r--r--gcc/testsuite/objc.dg/exceptions-5.m1
-rw-r--r--gcc/testsuite/objc.dg/fobjc-std-1.m5
-rw-r--r--gcc/testsuite/objc.dg/foreach-2.m1
-rw-r--r--gcc/testsuite/objc.dg/foreach-4.m1
-rw-r--r--gcc/testsuite/objc.dg/foreach-5.m1
-rw-r--r--gcc/testsuite/objc.dg/fsyntax-only.m3
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-class-meta.m4
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-class.m1
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-ivar.m1
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-method.m1
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-objc.m1
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-objc_msg_lookup.m1
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-object.m1
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-property.m1
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-protocol.m1
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-resolve-method.m1
-rw-r--r--gcc/testsuite/objc.dg/gnu-api-2-sel.m1
-rw-r--r--gcc/testsuite/objc.dg/incomplete-type-1.m3
-rw-r--r--gcc/testsuite/objc.dg/instancetype-0.m3
-rw-r--r--gcc/testsuite/objc.dg/invalid-method-2.m3
-rw-r--r--gcc/testsuite/objc.dg/ivar-invalid-type-1.m3
-rw-r--r--gcc/testsuite/objc.dg/ivar-problem-1.m6
-rw-r--r--gcc/testsuite/objc.dg/ivar-scope-1.m3
-rw-r--r--gcc/testsuite/objc.dg/ivar-scope-2.m3
-rw-r--r--gcc/testsuite/objc.dg/ivar-scope-4.m3
-rw-r--r--gcc/testsuite/objc.dg/ivar-visibility-1.m1
-rw-r--r--gcc/testsuite/objc.dg/ivar-visibility-2.m2
-rw-r--r--gcc/testsuite/objc.dg/ivar-visibility-3.m2
-rw-r--r--gcc/testsuite/objc.dg/ivar-visibility-4.m2
-rw-r--r--gcc/testsuite/objc.dg/local-decl-1.m1
-rw-r--r--gcc/testsuite/objc.dg/lto/lto.exp16
-rw-r--r--gcc/testsuite/objc.dg/lto/trivial-1_0.m4
-rw-r--r--gcc/testsuite/objc.dg/method-1.m1
-rw-r--r--gcc/testsuite/objc.dg/method-12.m1
-rw-r--r--gcc/testsuite/objc.dg/method-13.m1
-rw-r--r--gcc/testsuite/objc.dg/method-14.m1
-rw-r--r--gcc/testsuite/objc.dg/missing-proto-3.m3
-rw-r--r--gcc/testsuite/objc.dg/next-runtime-1.m1
-rw-r--r--gcc/testsuite/objc.dg/objc-foreach-1.m1
-rw-r--r--gcc/testsuite/objc.dg/objc-foreach-2.m1
-rw-r--r--gcc/testsuite/objc.dg/objc-foreach-3.m1
-rw-r--r--gcc/testsuite/objc.dg/objc-nofilename-1.m1
-rw-r--r--gcc/testsuite/objc.dg/param-1.m1
-rw-r--r--gcc/testsuite/objc.dg/pch/pch.exp4
-rw-r--r--gcc/testsuite/objc.dg/plugin/diagnostic-test-expressions-1.m2
-rw-r--r--gcc/testsuite/objc.dg/pr23214.m2
-rw-r--r--gcc/testsuite/objc.dg/pr23709.m1
-rw-r--r--gcc/testsuite/objc.dg/private-1.m1
-rw-r--r--gcc/testsuite/objc.dg/private-2.m1
-rw-r--r--gcc/testsuite/objc.dg/property/at-property-4.m18
-rw-r--r--gcc/testsuite/objc.dg/property/nullability-00.m21
-rw-r--r--gcc/testsuite/objc.dg/property/property.exp4
-rw-r--r--gcc/testsuite/objc.dg/proto-hier-1.m1
-rw-r--r--gcc/testsuite/objc.dg/proto-hier-2.m1
-rw-r--r--gcc/testsuite/objc.dg/proto-lossage-1.m1
-rw-r--r--gcc/testsuite/objc.dg/proto-lossage-5.m1
-rw-r--r--gcc/testsuite/objc.dg/proto-qual-1.m1
-rw-r--r--gcc/testsuite/objc.dg/protocol-inheritance-1.m1
-rw-r--r--gcc/testsuite/objc.dg/protocol-inheritance-2.m1
-rw-r--r--gcc/testsuite/objc.dg/protocol-optional-1.m1
-rw-r--r--gcc/testsuite/objc.dg/root-class-00.m10
-rw-r--r--gcc/testsuite/objc.dg/selector-1.m1
-rw-r--r--gcc/testsuite/objc.dg/selector-2.m1
-rw-r--r--gcc/testsuite/objc.dg/selector-3.m1
-rw-r--r--gcc/testsuite/objc.dg/selector-4.m1
-rw-r--r--gcc/testsuite/objc.dg/shadow-1.m1
-rw-r--r--gcc/testsuite/objc.dg/shadow-2.m1
-rw-r--r--gcc/testsuite/objc.dg/special/load-category-1.m1
-rw-r--r--gcc/testsuite/objc.dg/special/load-category-2.m1
-rw-r--r--gcc/testsuite/objc.dg/special/load-category-3.m1
-rw-r--r--gcc/testsuite/objc.dg/special/special.exp8
-rw-r--r--gcc/testsuite/objc.dg/special/unclaimed-category-1.h1
-rw-r--r--gcc/testsuite/objc.dg/special/unclaimed-category-1.m1
-rw-r--r--gcc/testsuite/objc.dg/stabs-1.m1
-rw-r--r--gcc/testsuite/objc.dg/strings/strings.exp4
-rw-r--r--gcc/testsuite/objc.dg/stubify-1.m1
-rw-r--r--gcc/testsuite/objc.dg/stubify-2.m1
-rw-r--r--gcc/testsuite/objc.dg/super-class-2.m1
-rw-r--r--gcc/testsuite/objc.dg/super-dealloc-1.m1
-rw-r--r--gcc/testsuite/objc.dg/super-dealloc-2.m1
-rw-r--r--gcc/testsuite/objc.dg/sync-3.m1
-rw-r--r--gcc/testsuite/objc.dg/threedotthree-abi-1.m1
-rw-r--r--gcc/testsuite/objc.dg/torture/dg-torture.exp4
-rw-r--r--gcc/testsuite/objc.dg/torture/strings/strings.exp4
-rw-r--r--gcc/testsuite/objc.dg/try-catch-11.m1
-rw-r--r--gcc/testsuite/objc.dg/try-catch-12.m1
-rw-r--r--gcc/testsuite/objc.dg/type-size-2.m1
-rw-r--r--gcc/testsuite/objc.dg/type-size-3.m1
-rw-r--r--gcc/testsuite/objc.dg/type-size-4.m1
-rw-r--r--gcc/testsuite/objc.dg/type-size-5.m1
-rw-r--r--gcc/testsuite/objc.dg/undeclared-selector.m1
-rw-r--r--gcc/testsuite/objc.dg/volatile-1.m3
-rw-r--r--gcc/timevar.def4
-rw-r--r--gcc/toplev.c15
-rw-r--r--gcc/trans-mem.c2
-rw-r--r--gcc/tree-cfg.c23
-rw-r--r--gcc/tree-cfgcleanup.h1
-rw-r--r--gcc/tree-complex.c5
-rw-r--r--gcc/tree-core.h9
-rw-r--r--gcc/tree-diagnostic-path.cc13
-rw-r--r--gcc/tree-emutls.c2
-rw-r--r--gcc/tree-if-conv.c13
-rw-r--r--gcc/tree-inline.c6
-rw-r--r--gcc/tree-into-ssa.c4
-rw-r--r--gcc/tree-pass.h2
-rw-r--r--gcc/tree-pretty-print.c1
-rw-r--r--gcc/tree-scalar-evolution.c18
-rw-r--r--gcc/tree-ssa-alias-compare.h43
-rw-r--r--gcc/tree-ssa-alias.c406
-rw-r--r--gcc/tree-ssa-alias.h2
-rw-r--r--gcc/tree-ssa-ccp.c9
-rw-r--r--gcc/tree-ssa-dce.c41
-rw-r--r--gcc/tree-ssa-loop-im.c36
-rw-r--r--gcc/tree-ssa-loop-manip.h2
-rw-r--r--gcc/tree-ssa-loop.c2
-rw-r--r--gcc/tree-ssa-math-opts.c262
-rw-r--r--gcc/tree-ssa-pre.c266
-rw-r--r--gcc/tree-ssa-propagate.c60
-rw-r--r--gcc/tree-ssa-reassoc.c73
-rw-r--r--gcc/tree-ssa-reassoc.h48
-rw-r--r--gcc/tree-ssa-sccvn.c32
-rw-r--r--gcc/tree-ssa-strlen.c554
-rw-r--r--gcc/tree-ssa-strlen.h7
-rw-r--r--gcc/tree-ssa-structalias.c30
-rw-r--r--gcc/tree-ssa-tail-merge.c4
-rw-r--r--gcc/tree-ssa-threadbackward.c7
-rw-r--r--gcc/tree-ssa-threadedge.c6
-rw-r--r--gcc/tree-ssa-uninit.c19
-rw-r--r--gcc/tree-ssa.c13
-rw-r--r--gcc/tree-ssa.h2
-rw-r--r--gcc/tree-ssanames.c27
-rw-r--r--gcc/tree-streamer-out.c6
-rw-r--r--gcc/tree-streamer.c1
-rw-r--r--gcc/tree-switch-conversion.c10
-rw-r--r--gcc/tree-switch-conversion.h24
-rw-r--r--gcc/tree-vect-data-refs.c8
-rw-r--r--gcc/tree-vect-generic.c6
-rw-r--r--gcc/tree-vect-loop.c85
-rw-r--r--gcc/tree-vect-patterns.c31
-rw-r--r--gcc/tree-vect-slp.c170
-rw-r--r--gcc/tree-vect-stmts.c23
-rw-r--r--gcc/tree-vectorizer.c10
-rw-r--r--gcc/tree-vectorizer.h10
-rw-r--r--gcc/tree-vrp.c1831
-rw-r--r--gcc/tree.c112
-rw-r--r--gcc/tree.def12
-rw-r--r--gcc/tree.h40
-rw-r--r--gcc/typeclass.h2
-rw-r--r--gcc/ubsan.c13
-rw-r--r--gcc/value-range.cc10
-rw-r--r--gcc/varasm.c125
-rw-r--r--gcc/vec.h2
-rw-r--r--gcc/vr-values.c246
-rw-r--r--gcc/vr-values.h2
-rw-r--r--libatomic/ChangeLog4
-rwxr-xr-xlibatomic/configure4
-rw-r--r--libbacktrace/ChangeLog10
-rwxr-xr-xlibbacktrace/configure4
-rw-r--r--libbacktrace/dwarf.c4
-rw-r--r--libcc1/ChangeLog16
-rwxr-xr-xlibcc1/configure8
-rw-r--r--libcc1/libcp1plugin.cc4
-rw-r--r--libcpp/ChangeLog170
-rw-r--r--libcpp/charset.c3
-rw-r--r--libcpp/directives.c64
-rw-r--r--libcpp/expr.c32
-rw-r--r--libcpp/files.c215
-rw-r--r--libcpp/include/cpplib.h81
-rw-r--r--libcpp/include/line-map.h51
-rw-r--r--libcpp/include/mkdeps.h7
-rw-r--r--libcpp/init.c50
-rw-r--r--libcpp/internal.h65
-rw-r--r--libcpp/lex.c414
-rw-r--r--libcpp/line-map.c116
-rw-r--r--libcpp/macro.c186
-rw-r--r--libcpp/mkdeps.c107
-rw-r--r--libcpp/traditional.c1
-rw-r--r--libffi/ChangeLog4
-rwxr-xr-xlibffi/configure8
-rw-r--r--libgcc/ChangeLog48
-rw-r--r--libgcc/config/msp430/lib2hw_mul.S89
-rw-r--r--libgcc/config/msp430/lib2mul.c52
-rw-r--r--libgcc/config/msp430/t-msp4305
-rw-r--r--libgcc/config/rs6000/ppc64-fp.c237
-rw-r--r--libgcc/config/rs6000/t-linux22
-rw-r--r--libgcc/config/rs6000/t-ppc64-fp3
-rw-r--r--libgcc/config/t-vxworks1
-rw-r--r--libgcc/config/t-vxworks71
-rw-r--r--libgcc/config/vxcache.c35
-rw-r--r--libgcc/libgcc2.c132
-rw-r--r--libgcc/libgcc2.h2
-rw-r--r--libgcc/unwind-dw2-fde-dip.c1
-rw-r--r--libgfortran/ChangeLog31
-rwxr-xr-xlibgfortran/configure8
-rw-r--r--libgfortran/intrinsics/execute_command_line.c5
-rw-r--r--libgfortran/io/io.h10
-rw-r--r--libgfortran/io/transfer.c4
-rw-r--r--libgfortran/io/unit.c6
-rw-r--r--libgfortran/libgfortran.h12
-rw-r--r--libgfortran/runtime/error.c2
-rw-r--r--libgo/MERGE2
-rw-r--r--libgo/Makefile.am1
-rw-r--r--libgo/Makefile.in15
-rw-r--r--libgo/VERSION2
-rw-r--r--libgo/check-packages.txt1
-rwxr-xr-xlibgo/configure2
-rw-r--r--libgo/configure.ac2
-rw-r--r--libgo/go/cmd/cgo/main.go3
-rw-r--r--libgo/go/cmd/cgo/out.go160
-rw-r--r--libgo/go/cmd/go/internal/work/exec.go60
-rw-r--r--libgo/go/cmd/go/internal/work/gccgo.go47
-rw-r--r--libgo/go/cmd/go/internal/work/security.go8
-rw-r--r--libgo/go/cmd/go/internal/work/security_test.go5
-rw-r--r--libgo/go/cmd/internal/pkgpath/pkgpath.go174
-rw-r--r--libgo/go/cmd/internal/pkgpath/pkgpath_test.go141
-rw-r--r--libgo/go/go/internal/srcimporter/srcimporter.go2
-rw-r--r--libgo/go/internal/bytealg/bytealg.c10
-rw-r--r--libgo/go/internal/cpu/cpu_gccgo.c20
-rw-r--r--libgo/go/internal/cpu/cpu_mips64x.go2
-rw-r--r--libgo/go/log/syslog/syslog_c.c2
-rw-r--r--libgo/go/math/big/nat.go2
-rw-r--r--libgo/go/runtime/atomic_pointer.go12
-rw-r--r--libgo/go/runtime/chan.go2
-rw-r--r--libgo/go/runtime/cpuprof.go4
-rw-r--r--libgo/go/runtime/debug.go2
-rw-r--r--libgo/go/runtime/heapdump.go2
-rw-r--r--libgo/go/runtime/iface.go2
-rw-r--r--libgo/go/runtime/internal/atomic/atomic.c56
-rw-r--r--libgo/go/runtime/malloc.go6
-rw-r--r--libgo/go/runtime/map.go2
-rw-r--r--libgo/go/runtime/mbarrier.go2
-rw-r--r--libgo/go/runtime/mgc.go4
-rw-r--r--libgo/go/runtime/mheap.go2
-rw-r--r--libgo/go/runtime/mprof.go2
-rw-r--r--libgo/go/runtime/mstats.go2
-rw-r--r--libgo/go/runtime/net_plan9.go4
-rw-r--r--libgo/go/runtime/netpoll.go18
-rw-r--r--libgo/go/runtime/pprof/mprof_test.go20
-rw-r--r--libgo/go/runtime/pprof/pprof_test.go4
-rw-r--r--libgo/go/runtime/preempt.go2
-rw-r--r--libgo/go/runtime/proc.go26
-rw-r--r--libgo/go/runtime/proflabel.go4
-rw-r--r--libgo/go/runtime/rdebug.go4
-rw-r--r--libgo/go/runtime/runtime.go4
-rw-r--r--libgo/go/runtime/runtime1.go2
-rw-r--r--libgo/go/runtime/sema.go22
-rw-r--r--libgo/go/runtime/sigqueue.go12
-rw-r--r--libgo/go/runtime/slice.go11
-rw-r--r--libgo/go/runtime/symtab.go88
-rw-r--r--libgo/go/runtime/trace.go8
-rw-r--r--libgo/go/runtime/traceback_gccgo.go4
-rw-r--r--libgo/go/sync/atomic/atomic.c52
-rw-r--r--libgo/gotool-packages.txt1
-rw-r--r--libgo/misc/cgo/errors/badsym_test.go216
-rwxr-xr-xlibgo/mksysinfo.sh9
-rw-r--r--libgo/runtime/go-cdiv.c49
-rw-r--r--libgo/runtime/go-ffi.c30
-rw-r--r--libgo/runtime/go-setenv.c2
-rw-r--r--libgo/runtime/go-unsafe-pointer.c4
-rw-r--r--libgo/runtime/go-unsetenv.c2
-rw-r--r--libgo/runtime/runtime.h2
-rw-r--r--libgo/sysinfo.c3
-rwxr-xr-xlibgo/testsuite/gotest7
-rw-r--r--libgomp/ChangeLog132
-rw-r--r--libgomp/allocator.c42
-rwxr-xr-xlibgomp/configure8
-rw-r--r--libgomp/env.c44
-rw-r--r--libgomp/icv.c17
-rw-r--r--libgomp/libgomp.h5
-rw-r--r--libgomp/libgomp.map6
-rw-r--r--libgomp/libgomp.texi60
-rw-r--r--libgomp/libgomp_g.h5
-rw-r--r--libgomp/omp.h.in2
-rw-r--r--libgomp/parallel.c4
-rw-r--r--libgomp/plugin/plugin-gcn.c3
-rw-r--r--libgomp/testsuite/libgomp.c++/allocate-1.C207
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/allocate-1.c375
-rw-r--r--libgomp/testsuite/libgomp.c/usleep.h7
-rw-r--r--libgomp/testsuite/libgomp.oacc-c++/cache-1.C13
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/cache-1.c12
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla-kernels-decompose-ice-1.c8
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla-kernels-decompose.c6
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla.c6
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/kernels-decompose-1.c46
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/atomic_capture-1.f9038
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/attach-descriptor-1.f903
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/pr94358-1.f9047
-rw-r--r--libhsail-rt/ChangeLog4
-rwxr-xr-xlibhsail-rt/configure8
-rw-r--r--libiberty/ChangeLog47
-rwxr-xr-xlibiberty/configure1
-rw-r--r--libiberty/configure.ac1
-rw-r--r--libiberty/cp-demangle.c25
-rw-r--r--libiberty/rust-demangle.c1010
-rw-r--r--libiberty/strstr.c16
-rw-r--r--libiberty/testsuite/demangle-expected7
-rw-r--r--libiberty/testsuite/rust-demangle-expected134
-rw-r--r--libitm/ChangeLog4
-rwxr-xr-xlibitm/configure8
-rw-r--r--libobjc/ChangeLog4
-rwxr-xr-xlibobjc/configure4
-rw-r--r--liboffloadmic/ChangeLog5
-rw-r--r--liboffloadmic/configure8
-rw-r--r--liboffloadmic/plugin/configure8
-rw-r--r--libphobos/ChangeLog51
-rw-r--r--libphobos/Makefile.in1
-rwxr-xr-xlibphobos/configure20
-rw-r--r--libphobos/configure.ac13
-rw-r--r--libphobos/configure.tgt6
-rw-r--r--libphobos/libdruntime/MERGE2
-rw-r--r--libphobos/libdruntime/Makefile.am20
-rw-r--r--libphobos/libdruntime/Makefile.in24
-rw-r--r--libphobos/libdruntime/core/demangle.d15
-rw-r--r--libphobos/libdruntime/core/internal/convert.d11
-rw-r--r--libphobos/libdruntime/core/math.d113
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/config.d24
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/sys/event.d35
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/sys/mount.d14
-rw-r--r--libphobos/libdruntime/core/sys/posix/dirent.d33
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/stat.d94
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/types.d19
-rw-r--r--libphobos/libdruntime/core/sys/posix/ucontext.d6
-rw-r--r--libphobos/libdruntime/core/thread.d10
-rw-r--r--libphobos/libdruntime/gcc/config.d.in3
-rw-r--r--libphobos/libdruntime/rt/critical_.d2
-rw-r--r--libphobos/libdruntime/rt/dmain2.d21
-rw-r--r--libphobos/m4/druntime/os.m42
-rw-r--r--libphobos/src/MERGE2
-rw-r--r--libphobos/src/Makefile.in1
-rw-r--r--libphobos/src/std/complex.d20
-rw-r--r--libphobos/src/std/conv.d26
-rw-r--r--libphobos/src/std/internal/math/gammafunction.d7
-rw-r--r--libphobos/src/std/math.d72
-rw-r--r--libphobos/src/std/string.d267
-rw-r--r--libphobos/src/std/traits.d6
-rw-r--r--libphobos/testsuite/Makefile.in1
-rw-r--r--libquadmath/ChangeLog4
-rwxr-xr-xlibquadmath/configure4
-rw-r--r--libsanitizer/ChangeLog43
-rw-r--r--libsanitizer/LOCAL_PATCHES4
-rw-r--r--libsanitizer/MERGE2
-rw-r--r--libsanitizer/Makefile.am6
-rw-r--r--libsanitizer/Makefile.in9
-rw-r--r--libsanitizer/README.gcc1
-rw-r--r--libsanitizer/asan/Makefile.in1
-rw-r--r--libsanitizer/asan/asan_fuchsia.cpp31
-rw-r--r--libsanitizer/asan/asan_report.cpp3
-rw-r--r--libsanitizer/asan/asan_rtl.cpp3
-rw-r--r--libsanitizer/asan/asan_thread.cpp15
-rw-r--r--libsanitizer/asan/asan_thread.h2
-rwxr-xr-xlibsanitizer/configure51
-rw-r--r--libsanitizer/configure.ac21
-rw-r--r--libsanitizer/configure.tgt3
-rw-r--r--libsanitizer/hwasan/Makefile.am89
-rw-r--r--libsanitizer/hwasan/Makefile.in803
-rw-r--r--libsanitizer/hwasan/hwasan.cpp522
-rw-r--r--libsanitizer/hwasan/hwasan.h165
-rw-r--r--libsanitizer/hwasan/hwasan_allocator.cpp408
-rw-r--r--libsanitizer/hwasan/hwasan_allocator.h107
-rw-r--r--libsanitizer/hwasan/hwasan_checks.h124
-rw-r--r--libsanitizer/hwasan/hwasan_dynamic_shadow.cpp126
-rw-r--r--libsanitizer/hwasan/hwasan_dynamic_shadow.h27
-rw-r--r--libsanitizer/hwasan/hwasan_exceptions.cpp67
-rw-r--r--libsanitizer/hwasan/hwasan_flags.h29
-rw-r--r--libsanitizer/hwasan/hwasan_flags.inc74
-rw-r--r--libsanitizer/hwasan/hwasan_globals.cpp91
-rw-r--r--libsanitizer/hwasan/hwasan_globals.h49
-rw-r--r--libsanitizer/hwasan/hwasan_interceptors.cpp349
-rw-r--r--libsanitizer/hwasan/hwasan_interceptors_vfork.S11
-rw-r--r--libsanitizer/hwasan/hwasan_interface_internal.h227
-rw-r--r--libsanitizer/hwasan/hwasan_linux.cpp455
-rw-r--r--libsanitizer/hwasan/hwasan_malloc_bisect.h50
-rw-r--r--libsanitizer/hwasan/hwasan_mapping.h66
-rw-r--r--libsanitizer/hwasan/hwasan_memintrinsics.cpp44
-rw-r--r--libsanitizer/hwasan/hwasan_new_delete.cpp81
-rw-r--r--libsanitizer/hwasan/hwasan_poisoning.cpp52
-rw-r--r--libsanitizer/hwasan/hwasan_poisoning.h24
-rw-r--r--libsanitizer/hwasan/hwasan_report.cpp652
-rw-r--r--libsanitizer/hwasan/hwasan_report.h35
-rw-r--r--libsanitizer/hwasan/hwasan_setjmp.S100
-rw-r--r--libsanitizer/hwasan/hwasan_tag_mismatch_aarch64.S152
-rw-r--r--libsanitizer/hwasan/hwasan_thread.cpp133
-rw-r--r--libsanitizer/hwasan/hwasan_thread.h98
-rw-r--r--libsanitizer/hwasan/hwasan_thread_list.cpp15
-rw-r--r--libsanitizer/hwasan/hwasan_thread_list.h215
-rw-r--r--libsanitizer/hwasan/hwasan_type_test.cpp25
-rw-r--r--libsanitizer/hwasan/libtool-version6
-rw-r--r--libsanitizer/include/sanitizer/memprof_interface.h60
-rw-r--r--libsanitizer/interception/Makefile.in1
-rw-r--r--libsanitizer/interception/interception.h4
-rw-r--r--libsanitizer/interception/interception_linux.cpp6
-rw-r--r--libsanitizer/interception/interception_linux.h8
-rw-r--r--libsanitizer/libbacktrace/Makefile.in1
-rw-r--r--libsanitizer/libsanitizer.spec.in2
-rw-r--r--libsanitizer/lsan/Makefile.in1
-rw-r--r--libsanitizer/lsan/lsan.cpp2
-rw-r--r--libsanitizer/lsan/lsan_common.cpp39
-rw-r--r--libsanitizer/lsan/lsan_common.h15
-rw-r--r--libsanitizer/lsan/lsan_common_fuchsia.cpp3
-rw-r--r--libsanitizer/lsan/lsan_common_linux.cpp5
-rw-r--r--libsanitizer/lsan/lsan_interceptors.cpp7
-rw-r--r--libsanitizer/lsan/lsan_posix.h2
-rw-r--r--libsanitizer/lsan/lsan_thread.h1
-rwxr-xr-xlibsanitizer/merge.sh1
-rw-r--r--libsanitizer/sanitizer_common/Makefile.in1
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator_report.cpp8
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator_report.h1
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_atomic_clang_other.h18
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common.h1
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc4
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common_nolibc.cpp4
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_deadlock_detector1.cpp2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cpp2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_deadlock_detector_interface.h6
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_errno.h2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_file.cpp27
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_flag_parser.h2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_flags.cpp7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_flags.h4
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_flags.inc9
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_fuchsia.cpp17
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_internal_defs.h12
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_libignore.cpp2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_linux.cpp122
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_linux.h3
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp64
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_mac.cpp4
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_openbsd.cpp119
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform.h16
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h282
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cpp279
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.h382
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_posix.cpp2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_posix.h1
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp1
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_procmaps.h2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cpp31
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_procmaps_common.cpp2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_rtems.cpp2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stacktrace.h4
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stoptheworld.h7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stoptheworld_fuchsia.cpp3
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stoptheworld_fuchsia.h20
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stoptheworld_mac.cpp2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_internal.h7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.h2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cpp2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.h4
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp8
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cpp2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_thread_registry.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cpp7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_unwind_win.cpp4
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_win.cpp4
-rw-r--r--libsanitizer/tsan/Makefile.in1
-rw-r--r--libsanitizer/tsan/tsan_platform.h26
-rw-r--r--libsanitizer/tsan/tsan_platform_linux.cpp7
-rw-r--r--libsanitizer/tsan/tsan_platform_mac.cpp2
-rw-r--r--libsanitizer/tsan/tsan_report.cpp3
-rw-r--r--libsanitizer/tsan/tsan_rtl.cpp3
-rw-r--r--libsanitizer/tsan/tsan_rtl.h2
-rw-r--r--libsanitizer/tsan/tsan_rtl_mutex.cpp2
-rw-r--r--libsanitizer/ubsan/Makefile.in1
-rw-r--r--libsanitizer/ubsan/ubsan_platform.h2
-rw-r--r--libsanitizer/ubsan/ubsan_type_hash_itanium.cpp2
-rw-r--r--libsanitizer/ubsan/ubsan_type_hash_win.cpp2
-rw-r--r--libssp/ChangeLog4
-rwxr-xr-xlibssp/configure4
-rw-r--r--libstdc++-v3/ChangeLog876
-rw-r--r--libstdc++-v3/acinclude.m4107
-rw-r--r--libstdc++-v3/config.h.in4
-rw-r--r--libstdc++-v3/config/abi/post/powerpc-linux-gnu/baseline_symbols.txt17
-rw-r--r--libstdc++-v3/config/abi/post/powerpc64-linux-gnu/32/baseline_symbols.txt17
-rw-r--r--libstdc++-v3/config/abi/pre/gnu.ver21
-rw-r--r--libstdc++-v3/config/locale/generic/c_locale.cc49
-rw-r--r--libstdc++-v3/config/os/gnu-linux/os_defines.h12
-rwxr-xr-xlibstdc++-v3/configure556
-rw-r--r--libstdc++-v3/doc/doxygen/user.cfg.in3
-rw-r--r--libstdc++-v3/doc/html/manual/configure.html3
-rw-r--r--libstdc++-v3/doc/html/manual/status.html18
-rw-r--r--libstdc++-v3/doc/xml/manual/configure.xml3
-rw-r--r--libstdc++-v3/doc/xml/manual/status_cxx2020.xml15
-rw-r--r--libstdc++-v3/include/Makefile.am7
-rw-r--r--libstdc++-v3/include/Makefile.in7
-rw-r--r--libstdc++-v3/include/bits/alloc_traits.h8
-rw-r--r--libstdc++-v3/include/bits/atomic_base.h207
-rw-r--r--libstdc++-v3/include/bits/atomic_timed_wait.h297
-rw-r--r--libstdc++-v3/include/bits/atomic_wait.h299
-rw-r--r--libstdc++-v3/include/bits/c++config51
-rw-r--r--libstdc++-v3/include/bits/iterator_concepts.h17
-rw-r--r--libstdc++-v3/include/bits/move.h2
-rw-r--r--libstdc++-v3/include/bits/ranges_algo.h4
-rw-r--r--libstdc++-v3/include/bits/semaphore_base.h301
-rw-r--r--libstdc++-v3/include/bits/std_mutex.h70
-rw-r--r--libstdc++-v3/include/bits/std_thread.h323
-rw-r--r--libstdc++-v3/include/bits/stl_algo.h16
-rw-r--r--libstdc++-v3/include/bits/stl_tempbuf.h2
-rw-r--r--libstdc++-v3/include/bits/stl_tree.h76
-rw-r--r--libstdc++-v3/include/ext/numeric_traits.h133
-rw-r--r--libstdc++-v3/include/ext/rope39
-rw-r--r--libstdc++-v3/include/ext/ropeimpl.h23
-rw-r--r--libstdc++-v3/include/precompiled/stdc++.h5
-rw-r--r--libstdc++-v3/include/std/array6
-rw-r--r--libstdc++-v3/include/std/atomic84
-rw-r--r--libstdc++-v3/include/std/bit12
-rw-r--r--libstdc++-v3/include/std/condition_variable18
-rw-r--r--libstdc++-v3/include/std/future16
-rw-r--r--libstdc++-v3/include/std/latch94
-rw-r--r--libstdc++-v3/include/std/ostream67
-rw-r--r--libstdc++-v3/include/std/ranges14
-rw-r--r--libstdc++-v3/include/std/regex14
-rw-r--r--libstdc++-v3/include/std/semaphore95
-rw-r--r--libstdc++-v3/include/std/source_location92
-rw-r--r--libstdc++-v3/include/std/sstream432
-rw-r--r--libstdc++-v3/include/std/stop_token33
-rw-r--r--libstdc++-v3/include/std/syncstream149
-rw-r--r--libstdc++-v3/include/std/thread272
-rw-r--r--libstdc++-v3/include/std/version19
-rw-r--r--libstdc++-v3/python/libstdcxx/v6/printers.py70
-rw-r--r--libstdc++-v3/src/Makefile.am4
-rw-r--r--libstdc++-v3/src/Makefile.in4
-rw-r--r--libstdc++-v3/src/c++11/condition_variable.cc33
-rw-r--r--libstdc++-v3/src/c++11/futex.cc118
-rw-r--r--libstdc++-v3/src/c++11/thread.cc11
-rw-r--r--libstdc++-v3/src/c++20/sstream-inst.cc48
-rw-r--r--libstdc++-v3/src/c++98/locale.cc2
-rw-r--r--libstdc++-v3/testsuite/17_intro/names.cc2
-rw-r--r--libstdc++-v3/testsuite/18_support/96817.cc13
-rw-r--r--libstdc++-v3/testsuite/18_support/source_location/1.cc155
-rw-r--r--libstdc++-v3/testsuite/18_support/source_location/consteval.cc149
-rw-r--r--libstdc++-v3/testsuite/18_support/source_location/srcloc.h25
-rw-r--r--libstdc++-v3/testsuite/18_support/source_location/version.cc27
-rw-r--r--libstdc++-v3/testsuite/20_util/result_of/sfinae_friendly_1.cc10
-rw-r--r--libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_construct.cc1
-rw-r--r--libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_copy_move.cc1
-rw-r--r--libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_fill_destroy.cc1
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/debug/constexpr_c++11.cc32
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/element_access/constexpr_element_access.cc15
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc6
-rw-r--r--libstdc++-v3/testsuite/23_containers/map/allocator/move_cons.cc53
-rw-r--r--libstdc++-v3/testsuite/23_containers/multimap/allocator/move_cons.cc53
-rw-r--r--libstdc++-v3/testsuite/23_containers/multiset/allocator/move_cons.cc53
-rw-r--r--libstdc++-v3/testsuite/23_containers/set/allocator/move_cons.cc53
-rw-r--r--libstdc++-v3/testsuite/24_iterators/associated_types/iterator.traits.cc56
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/inplace_merge/1.cc37
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_merge/inplace_merge.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_merge/merge.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_if.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_move.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/fill.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/generate.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/is_partitioned.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/partition.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/partition_copy.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/remove.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/remove_copy.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/replace.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/replace_copy.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate_copy.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/swap_ranges.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_binary.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_unary.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/unique.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/unique_copy_equal.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/adjacent_find.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/all_of.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/any_of.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/count.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/equal.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_end.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_first_of.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_if.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/for_each.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/mismatch.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/none_of.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/nth_element.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse_copy.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/search_n.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/includes.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/is_heap.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/is_sorted.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/lexicographical_compare.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/minmax_element.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/partial_sort.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/partial_sort_copy.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/set.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/sort.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/search_n/97828.cc58
-rw-r--r--libstdc++-v3/testsuite/26_numerics/bit/bit.cast/bit_cast.cc81
-rw-r--r--libstdc++-v3/testsuite/26_numerics/bit/bit.cast/version.cc27
-rw-r--r--libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/adjacent_difference.cc1
-rw-r--r--libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/reduce.cc1
-rw-r--r--libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/scan.cc1
-rw-r--r--libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/transform_reduce.cc1
-rw-r--r--libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/transform_scan.cc1
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_istream/get/char/lwg3464.cc1
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_istream/get/wchar_t/lwg3464.cc1
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/94749.cc1
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_istream/ignore/wchar_t/94749.cc1
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_istringstream/str/char/2.cc94
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_istringstream/str/wchar_t/2.cc94
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_istringstream/view/char/1.cc16
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_istringstream/view/wchar_t/1.cc14
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_ostream/emit/1.cc44
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_ostringstream/str/char/3.cc94
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_ostringstream/str/wchar_t/3.cc94
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_ostringstream/view/char/1.cc12
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_ostringstream/view/wchar_t/1.cc12
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringbuf/str/char/4.cc94
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringbuf/str/wchar_t/4.cc94
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringstream/str/char/5.cc94
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringstream/str/wchar_t/5.cc.cc94
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringstream/view/char/1.cc16
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringstream/view/wchar_t/1.cc14
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_syncbuf/sync_ops/1.cc5
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_syncstream/basic_ops/1.cc31
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/operations/absolute.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/append/source.cc4
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/assign/copy.cc4
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/compare/path.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/construct/copy.cc4
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/decompose/extension.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/decompose/filename.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/decompose/parent_path.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/decompose/relative_path.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/decompose/root_directory.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/decompose/root_path.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/itr/traversal.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/remove_filename.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/replace_extension.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/replace_filename.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/append.cc4
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/cmp.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/cmp_c++20.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/hash_value.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/query/has_extension.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/query/has_filename.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/query/has_parent_path.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/query/has_relative_path.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/query/has_root_directory.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/query/has_root_name.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/query/has_root_path.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/query/has_stem.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/filesystem/path/query/is_relative.cc2
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/awk/cstring_01.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/empty_range.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_01.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_00_03.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_01_03.cc3
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/cstring_bracket_01.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/dr2329_neg.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/53622.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/57173.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/58576.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/61601.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/68863.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/anymatcher.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/backref.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/empty_range.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/emptygroup.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/hex.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/ungreedy.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/63199.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/anymatcher.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/cjk_match.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/hex.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_any.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_01_03.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/51711.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/basic_replace.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/dr2213.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/pr83601.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/wchar_t/51711.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/wchar_t/pr83601.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_search/61424.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_search/61720.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_search/basic/string_01.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_search/dr2332_neg.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/flags.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/greedy.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/85098.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/cstring.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/cstring_op.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/lwg3296.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/moveable.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/pstring.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/range.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/string.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/string_op.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/cstring.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/cstring_op.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/lwg3296.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/pstring.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/range.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/string.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/string_op.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/47724.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/83598.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/cstring.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/default.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/iter.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/pstring_char.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/pstring_wchar_t.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/raw_string.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/string_range_01_02_03.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_awk.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_ecma.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_egrep.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_grep.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/default.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/range.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/copy_char.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/deduction.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/extended/cstring.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/extended/string_range_01_02_03.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/move_char.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/string_char.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/string_wchar_t.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/cstring.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/default.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/range.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/imbue/string.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/multiple_quantifiers.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/requirements/constexpr_data.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/constants/constexpr.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/constants/error_type.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/constants/match_flag_type.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/constants/syntax_option_type.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/headers/regex/std_c++0x_neg.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/init-list.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/64140.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_01.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_position_01.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/ctors/char/default.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/ctors/char/dr2332_neg.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/ctors/wchar_t/default.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/typedefs.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_01.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_02.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/64303.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/char/string_01.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/ctors/char/default.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/ctors/char/dr2332_neg.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/ctors/wchar_t/default.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/typedefs.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/wchar_t/string_01.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/wchar_t/wstring_02.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/match_results/94627.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/match_results/ctors/char/default.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/match_results/ctors/wchar_t/default.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/match_results/format.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/match_results/out_of_range_submatches.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/match_results/pmr_typedefs.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/match_results/swap.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/match_results/typedefs.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/range_access.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/regex_error/base.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/regex_error/regex_error.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/regression.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/requirements/typedefs.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/simple_c++11.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/sub_match/cast_char.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/sub_match/cast_wchar_t.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/sub_match/compare.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/sub_match/compare_c++20.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/sub_match/embedded_zeros_cmp.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/sub_match/length.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/sub_match/typedefs.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/char/ctor.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/char/icase.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/char/isctype.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/char/length.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/char/lookup_classname.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/char/lookup_collatename.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/char/transform.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/char/transform_primary.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/char/translate.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/char/translate_nocase.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/char/user_defined.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/char/value.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/wchar_t/ctor.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/wchar_t/isctype.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/wchar_t/length.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_classname.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_collatename.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/wchar_t/transform.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/wchar_t/transform_primary.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/wchar_t/translate.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/wchar_t/translate_nocase.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/wchar_t/user_defined.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/traits/wchar_t/value.cc1
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/1.cc29
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/2.cc30
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/bool.cc63
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/generic.cc31
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/pointers.cc63
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc65
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic_float/wait_notify.cc32
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic_integral/wait_notify.cc66
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc95
-rw-r--r--libstdc++-v3/testsuite/30_threads/async/async.cc1
-rw-r--r--libstdc++-v3/testsuite/30_threads/call_once/66146.cc4
-rw-r--r--libstdc++-v3/testsuite/30_threads/future/members/93456.cc49
-rw-r--r--libstdc++-v3/testsuite/30_threads/future/members/poll.cc105
-rw-r--r--libstdc++-v3/testsuite/30_threads/jthread/95989.cc56
-rw-r--r--libstdc++-v3/testsuite/30_threads/jthread/jthread.cc20
-rw-r--r--libstdc++-v3/testsuite/30_threads/latch/1.cc27
-rw-r--r--libstdc++-v3/testsuite/30_threads/latch/2.cc27
-rw-r--r--libstdc++-v3/testsuite/30_threads/latch/3.cc69
-rw-r--r--libstdc++-v3/testsuite/30_threads/semaphore/1.cc27
-rw-r--r--libstdc++-v3/testsuite/30_threads/semaphore/2.cc27
-rw-r--r--libstdc++-v3/testsuite/30_threads/semaphore/least_max_value_neg.cc30
-rw-r--r--libstdc++-v3/testsuite/30_threads/semaphore/try_acquire.cc55
-rw-r--r--libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_for.cc85
-rw-r--r--libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_posix.cc153
-rw-r--r--libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc94
-rw-r--r--libstdc++-v3/testsuite/30_threads/this_thread/95989.cc51
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/operations/absolute.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/assign/copy.cc4
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/compare/path.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/construct/copy.cc4
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/decompose/extension.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/decompose/filename.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/decompose/parent_path.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/decompose/relative_path.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/decompose/root_directory.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/decompose/root_path.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/itr/traversal.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/modifiers/remove_filename.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/modifiers/replace_extension.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/modifiers/replace_filename.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/nonmember/hash_value.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/query/has_extension.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/query/has_filename.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/query/has_parent_path.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/query/has_relative_path.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/query/has_root_directory.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/query/has_root_name.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/query/has_root_path.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/query/has_stem.cc2
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/query/is_relative.cc2
-rw-r--r--libstdc++-v3/testsuite/ext/stdio_filebuf/char/79820.cc3
-rw-r--r--libstdc++-v3/testsuite/lib/dg-options.exp9
-rw-r--r--libstdc++-v3/testsuite/lib/libstdc++.exp605
-rw-r--r--libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc39
-rw-r--r--libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc31
-rw-r--r--libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc31
-rw-r--r--libstdc++-v3/testsuite/performance/25_algorithms/inplace_merge.cc290
-rw-r--r--libstdc++-v3/testsuite/performance/25_algorithms/stable_sort.cc90
-rw-r--r--libstdc++-v3/testsuite/std/ranges/adaptors/join.cc12
-rw-r--r--libstdc++-v3/testsuite/util/atomic/wait_notify_util.h176
-rw-r--r--libtool.m48
-rw-r--r--libvtv/ChangeLog4
-rwxr-xr-xlibvtv/configure8
-rw-r--r--lto-plugin/ChangeLog9
-rw-r--r--lto-plugin/Makefile.am4
-rw-r--r--lto-plugin/Makefile.in4
-rwxr-xr-xlto-plugin/configure4
-rw-r--r--zlib/ChangeLog4
-rwxr-xr-xzlib/configure4
3408 files changed, 112510 insertions, 35474 deletions
diff --git a/.gitignore b/.gitignore
index d9eeaf2..382e2de 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@
*.o
*.pyc
*.tmp
+*.a
.deps
.libs
@@ -38,11 +39,15 @@ TAGS.sub
.clang-format
.clang-tidy
.clangd
+.cache
compile_commands.json
.gdbinit
.gdb_history
+perf.data
+perf.data.old
+
# ignore core files, but not java/net/protocol/core/
core
!core/
@@ -53,6 +58,9 @@ lost+found
LAST_UPDATED
REVISION
+stamp-*
+*.stamp
+
# ignore in-tree prerequisites
/mpfr*
/mpc*
diff --git a/ChangeLog b/ChangeLog
index b6e6275..b512943 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,40 @@
+2020-12-02 Simon Marchi <simon.marchi@polymtl.ca>
+
+ * .gitignore: Sync with binutils-gdb
+
+2020-12-02 Claudiu Zissulescu <claziss@gmail.com>
+
+ * MAINTAINERS: Add myself as arc port maintainer.
+
+2020-11-29 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/87788
+ * configure.ac: Don't disable D for *-*-darwin*.
+ * configure: Regenerate.
+
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ * libtool.m4 (archive_cmds): Add +nodefaultrpath ld option on
+ hppa64-*-hpux11*.
+
+2020-11-25 Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * configure: Regenerate.
+ * configure.ac: Add --bootstrap-hwasan option.
+
+2020-11-23 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config.guess: Import latest upstream.
+ * config.sub: Import latest upstream.
+
+2020-11-16 Martin Liska <mliska@suse.cz>
+
+ * .gitignore: Add cache as clangd uses it now.
+
+2020-11-13 Haochen Gui <guihaoc@gcc.gnu.org>
+
+ * MAINTAINERS (Write After Approval): add myself
+
2020-11-09 Pat Bernardi <bernardi@adacore.com>
* MAINTAINERS (Write After Approval): Add myself.
diff --git a/MAINTAINERS b/MAINTAINERS
index a021618..32f8a2b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -51,6 +51,7 @@ alpha port Richard Henderson <rth@twiddle.net>
amdgcn port Julian Brown <julian@codesourcery.com>
amdgcn port Andrew Stubbs <ams@codesourcery.com>
arc port Joern Rennecke <gnu@amylaar.uk>
+arc port Claudiu Zissulescu <claziss@synopsys.com>
arm port Nick Clifton <nickc@redhat.com>
arm port Richard Earnshaw <richard.earnshaw@arm.com>
arm port Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
@@ -409,6 +410,7 @@ Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
Yury Gribov <tetra2005@gmail.com>
Jon Grimm <jgrimm2@us.ibm.com>
Laurent Guerby <laurent@guerby.net>
+Haochen Gui <guihaoc@gcc.gnu.org>
Jiufu Guo <guojiufu@linux.ibm.com>
Xuepeng Guo <terry.xpguo@gmail.com>
Wei Guozhi <carrot@google.com>
diff --git a/config.guess b/config.guess
index 97ad073..0fc11ed 100755
--- a/config.guess
+++ b/config.guess
@@ -1,8 +1,8 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2019 Free Software Foundation, Inc.
+# Copyright 1992-2020 Free Software Foundation, Inc.
-timestamp='2019-07-24'
+timestamp='2020-11-07'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -32,7 +32,7 @@ timestamp='2019-07-24'
# Please send patches to <config-patches@gnu.org>.
-me=`echo "$0" | sed -e 's,.*/,,'`
+me=$(echo "$0" | sed -e 's,.*/,,')
usage="\
Usage: $0 [OPTION]
@@ -50,7 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2019 Free Software Foundation, Inc.
+Copyright 1992-2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -99,9 +99,11 @@ tmp=
trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15
set_cc_for_build() {
+ # prevent multiple calls if $tmp is already set
+ test "$tmp" && return 0
: "${TMPDIR=/tmp}"
# shellcheck disable=SC2039
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { tmp=$( (umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null) && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
@@ -129,10 +131,10 @@ if test -f /.attbin/uname ; then
PATH=$PATH:/.attbin ; export PATH
fi
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+UNAME_MACHINE=$( (uname -m) 2>/dev/null) || UNAME_MACHINE=unknown
+UNAME_RELEASE=$( (uname -r) 2>/dev/null) || UNAME_RELEASE=unknown
+UNAME_SYSTEM=$( (uname -s) 2>/dev/null) || UNAME_SYSTEM=unknown
+UNAME_VERSION=$( (uname -v) 2>/dev/null) || UNAME_VERSION=unknown
case "$UNAME_SYSTEM" in
Linux|GNU|GNU/*)
@@ -148,17 +150,15 @@ Linux|GNU|GNU/*)
#elif defined(__dietlibc__)
LIBC=dietlibc
#else
+ #include <stdarg.h>
+ #ifdef __DEFINED_va_list
+ LIBC=musl
+ #else
LIBC=gnu
#endif
+ #endif
EOF
- eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`"
-
- # If ldd exists, use it to detect musl libc.
- if command -v ldd >/dev/null && \
- ldd --version 2>&1 | grep -q ^musl
- then
- LIBC=musl
- fi
+ eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g')"
;;
esac
@@ -177,19 +177,20 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch"
- UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+ UNAME_MACHINE_ARCH=$( (uname -p 2>/dev/null || \
"/sbin/$sysctl" 2>/dev/null || \
"/usr/sbin/$sysctl" 2>/dev/null || \
- echo unknown)`
+ echo unknown))
case "$UNAME_MACHINE_ARCH" in
+ aarch64eb) machine=aarch64_be-unknown ;;
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
earmv*)
- arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
- endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
+ arch=$(echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,')
+ endian=$(echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p')
machine="${arch}${endian}"-unknown
;;
*) machine="$UNAME_MACHINE_ARCH"-unknown ;;
@@ -220,7 +221,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
case "$UNAME_MACHINE_ARCH" in
earm*)
expr='s/^earmv[0-9]/-eabi/;s/eb$//'
- abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
+ abi=$(echo "$UNAME_MACHINE_ARCH" | sed -e "$expr")
;;
esac
# The OS release
@@ -233,7 +234,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
release='-gnu'
;;
*)
- release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
+ release=$(echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2)
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
@@ -242,15 +243,15 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
echo "$machine-${os}${release}${abi-}"
exit ;;
*:Bitrig:*:*)
- UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ UNAME_MACHINE_ARCH=$(arch | sed 's/Bitrig.//')
echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
exit ;;
*:OpenBSD:*:*)
- UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ UNAME_MACHINE_ARCH=$(arch | sed 's/OpenBSD.//')
echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
exit ;;
*:LibertyBSD:*:*)
- UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+ UNAME_MACHINE_ARCH=$(arch | sed 's/^.*BSD\.//')
echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
exit ;;
*:MidnightBSD:*:*)
@@ -274,6 +275,9 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
*:Sortix:*:*)
echo "$UNAME_MACHINE"-unknown-sortix
exit ;;
+ *:Twizzler:*:*)
+ echo "$UNAME_MACHINE"-unknown-twizzler
+ exit ;;
*:Redox:*:*)
echo "$UNAME_MACHINE"-unknown-redox
exit ;;
@@ -283,17 +287,17 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
alpha:OSF1:*:*)
case $UNAME_RELEASE in
*4.0)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $3}')
;;
*5.*)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $4}')
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
# OSF/1 and Tru64 systems produced since 1995. I hope that
# covers most systems running today. This code pipes the CPU
# types through head -n 1, so we only detect the type of CPU 0.
- ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ ALPHA_CPU_TYPE=$(/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1)
case "$ALPHA_CPU_TYPE" in
"EV4 (21064)")
UNAME_MACHINE=alpha ;;
@@ -331,7 +335,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`"
+ echo "$UNAME_MACHINE"-dec-osf"$(echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)"
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$?
trap '' 0
@@ -365,7 +369,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
exit ;;
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
- if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ if test "$( (/bin/universe) 2>/dev/null)" = att ; then
echo pyramid-pyramid-sysv3
else
echo pyramid-pyramid-bsd
@@ -378,17 +382,17 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
echo sparc-icl-nx6
exit ;;
DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
- case `/usr/bin/uname -p` in
+ case $(/usr/bin/uname -p) in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
s390x:SunOS:*:*)
- echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
+ echo "$UNAME_MACHINE"-ibm-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')"
exit ;;
sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+ echo sparc-hal-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
+ echo sparc-sun-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')"
exit ;;
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
echo i386-pc-auroraux"$UNAME_RELEASE"
@@ -399,7 +403,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
# If there is a compiler, see if it is configured for 64-bit objects.
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
# This test works for both compilers.
- if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+ if test "$CC_FOR_BUILD" != no_compiler_found; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
@@ -407,30 +411,30 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
SUN_ARCH=x86_64
fi
fi
- echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+ echo "$SUN_ARCH"-pc-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+ echo sparc-sun-solaris3"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
exit ;;
sun4*:SunOS:*:*)
- case "`/usr/bin/arch -k`" in
+ case "$(/usr/bin/arch -k)" in
Series*|S4*)
- UNAME_RELEASE=`uname -v`
+ UNAME_RELEASE=$(uname -v)
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`"
+ echo sparc-sun-sunos"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/')"
exit ;;
sun3*:SunOS:*:*)
echo m68k-sun-sunos"$UNAME_RELEASE"
exit ;;
sun*:*:4.2BSD:*)
- UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ UNAME_RELEASE=$( (sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null)
test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
- case "`/bin/arch`" in
+ case "$(/bin/arch)" in
sun3)
echo m68k-sun-sunos"$UNAME_RELEASE"
;;
@@ -510,8 +514,8 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
}
EOF
$CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
- dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
- SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
+ dummyarg=$(echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p') &&
+ SYSTEM_NAME=$("$dummy" "$dummyarg") &&
{ echo "$SYSTEM_NAME"; exit; }
echo mips-mips-riscos"$UNAME_RELEASE"
exit ;;
@@ -538,11 +542,11 @@ EOF
exit ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ]
+ UNAME_PROCESSOR=$(/usr/bin/uname -p)
+ if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110
then
- if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \
- [ "$TARGET_BINARY_INTERFACE"x = x ]
+ if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \
+ test "$TARGET_BINARY_INTERFACE"x = x
then
echo m88k-dg-dgux"$UNAME_RELEASE"
else
@@ -566,17 +570,17 @@ EOF
echo m68k-tektronix-bsd
exit ;;
*:IRIX*:*:*)
- echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`"
+ echo mips-sgi-irix"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/g')"
exit ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ exit ;; # Note that: echo "'$(uname -s)'" gives 'AIX '
i*86:AIX:*:*)
echo i386-ibm-aix
exit ;;
ia64:AIX:*:*)
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
+ if test -x /usr/bin/oslevel ; then
+ IBM_REV=$(/usr/bin/oslevel)
else
IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
fi
@@ -596,7 +600,7 @@ EOF
exit(0);
}
EOF
- if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
+ if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy")
then
echo "$SYSTEM_NAME"
else
@@ -609,15 +613,15 @@ EOF
fi
exit ;;
*:AIX:*:[4567])
- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ IBM_CPU_ID=$(/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }')
if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
- if [ -x /usr/bin/lslpp ] ; then
- IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
- awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+ if test -x /usr/bin/lslpp ; then
+ IBM_REV=$(/usr/bin/lslpp -Lqc bos.rte.libc |
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/)
else
IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
fi
@@ -645,14 +649,14 @@ EOF
echo m68k-hp-bsd4.4
exit ;;
9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+ HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//')
case "$UNAME_MACHINE" in
9000/31?) HP_ARCH=m68000 ;;
9000/[34]??) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ if test -x /usr/bin/getconf; then
+ sc_cpu_version=$(/usr/bin/getconf SC_CPU_VERSION 2>/dev/null)
+ sc_kernel_bits=$(/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null)
case "$sc_cpu_version" in
523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
@@ -664,7 +668,7 @@ EOF
esac ;;
esac
fi
- if [ "$HP_ARCH" = "" ]; then
+ if test "$HP_ARCH" = ""; then
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
@@ -699,11 +703,11 @@ EOF
exit (0);
}
EOF
- (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
+ (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=$("$dummy")
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
- if [ "$HP_ARCH" = hppa2.0w ]
+ if test "$HP_ARCH" = hppa2.0w
then
set_cc_for_build
@@ -727,7 +731,7 @@ EOF
echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
exit ;;
ia64:HP-UX:*:*)
- HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+ HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//')
echo ia64-hp-hpux"$HPUX_REV"
exit ;;
3050*:HI-UX:*:*)
@@ -757,7 +761,7 @@ EOF
exit (0);
}
EOF
- $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
+ $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") &&
{ echo "$SYSTEM_NAME"; exit; }
echo unknown-hitachi-hiuxwe2
exit ;;
@@ -777,7 +781,7 @@ EOF
echo hppa1.0-hp-osf
exit ;;
i*86:OSF1:*:*)
- if [ -x /usr/sbin/sysversion ] ; then
+ if test -x /usr/sbin/sysversion ; then
echo "$UNAME_MACHINE"-unknown-osf1mk
else
echo "$UNAME_MACHINE"-unknown-osf1
@@ -826,14 +830,14 @@ EOF
echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
- FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
- FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
+ FUJITSU_PROC=$(uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)
+ FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///')
+ FUJITSU_REL=$(echo "$UNAME_RELEASE" | sed -e 's/ /_/')
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
- FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
+ FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///')
+ FUJITSU_REL=$(echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/')
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
@@ -846,25 +850,25 @@ EOF
echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
exit ;;
arm:FreeBSD:*:*)
- UNAME_PROCESSOR=`uname -p`
+ UNAME_PROCESSOR=$(uname -p)
set_cc_for_build
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
- echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi
+ echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabi
else
- echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf
+ echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabihf
fi
exit ;;
*:FreeBSD:*:*)
- UNAME_PROCESSOR=`/usr/bin/uname -p`
+ UNAME_PROCESSOR=$(/usr/bin/uname -p)
case "$UNAME_PROCESSOR" in
amd64)
UNAME_PROCESSOR=x86_64 ;;
i386)
UNAME_PROCESSOR=i586 ;;
esac
- echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
+ echo "$UNAME_PROCESSOR"-unknown-freebsd"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')"
exit ;;
i*:CYGWIN*:*)
echo "$UNAME_MACHINE"-pc-cygwin
@@ -900,15 +904,15 @@ EOF
echo x86_64-pc-cygwin
exit ;;
prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+ echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
exit ;;
*:GNU:*:*)
# the GNU system
- echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`"
+ echo "$(echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,')-unknown-$LIBC$(echo "$UNAME_RELEASE"|sed -e 's,/.*$,,')"
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC"
+ echo "$UNAME_MACHINE-unknown-$(echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]")$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')-$LIBC"
exit ;;
*:Minix:*:*)
echo "$UNAME_MACHINE"-unknown-minix
@@ -921,7 +925,7 @@ EOF
echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ case $(sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null) in
EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;;
@@ -1030,7 +1034,7 @@ EOF
#endif
#endif
EOF
- eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`"
+ eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI')"
test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
;;
mips64el:Linux:*:*)
@@ -1050,7 +1054,7 @@ EOF
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
- case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ case $(grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2) in
PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
*) echo hppa-unknown-linux-"$LIBC" ;;
@@ -1090,7 +1094,17 @@ EOF
echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
exit ;;
x86_64:Linux:*:*)
- echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
+ set_cc_for_build
+ LIBCABI=$LIBC
+ if test "$CC_FOR_BUILD" != no_compiler_found; then
+ if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_X32 >/dev/null
+ then
+ LIBCABI="$LIBC"x32
+ fi
+ fi
+ echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI"
exit ;;
xtensa*:Linux:*:*)
echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
@@ -1130,7 +1144,7 @@ EOF
echo "$UNAME_MACHINE"-pc-msdosdjgpp
exit ;;
i*86:*:4.*:*)
- UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
+ UNAME_REL=$(echo "$UNAME_RELEASE" | sed 's/\/MP$//')
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
else
@@ -1139,7 +1153,7 @@ EOF
exit ;;
i*86:*:5:[678]*)
# UnixWare 7.x, OpenUNIX and OpenServer 6.
- case `/bin/uname -X | grep "^Machine"` in
+ case $(/bin/uname -X | grep "^Machine") in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
@@ -1148,10 +1162,10 @@ EOF
exit ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
- UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ UNAME_REL=$(sed -n 's/.*Version //p' </usr/options/cb.name)
echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ UNAME_REL=$( (/bin/uname -X|grep Release|sed -e 's/.*= //'))
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
@@ -1201,7 +1215,7 @@ EOF
3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
@@ -1212,7 +1226,7 @@ EOF
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
OS_REL='.3'
test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
@@ -1245,7 +1259,7 @@ EOF
exit ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ UNAME_MACHINE=$( (uname -p) 2>/dev/null)
echo "$UNAME_MACHINE"-sni-sysv4
else
echo ns32k-sni-sysv
@@ -1279,7 +1293,7 @@ EOF
echo mips-sony-newsos6
exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
- if [ -d /usr/nec ]; then
+ if test -d /usr/nec; then
echo mips-nec-sysv"$UNAME_RELEASE"
else
echo mips-unknown-sysv"$UNAME_RELEASE"
@@ -1327,8 +1341,11 @@ EOF
*:Rhapsody:*:*)
echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
exit ;;
+ arm64:Darwin:*:*)
+ echo aarch64-apple-darwin"$UNAME_RELEASE"
+ exit ;;
*:Darwin:*:*)
- UNAME_PROCESSOR=`uname -p`
+ UNAME_PROCESSOR=$(uname -p)
case $UNAME_PROCESSOR in
unknown) UNAME_PROCESSOR=powerpc ;;
esac
@@ -1341,7 +1358,7 @@ EOF
else
set_cc_for_build
fi
- if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+ if test "$CC_FOR_BUILD" != no_compiler_found; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
@@ -1365,7 +1382,7 @@ EOF
echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
- UNAME_PROCESSOR=`uname -p`
+ UNAME_PROCESSOR=$(uname -p)
if test "$UNAME_PROCESSOR" = x86; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
@@ -1433,10 +1450,10 @@ EOF
echo mips-sei-seiux"$UNAME_RELEASE"
exit ;;
*:DragonFly:*:*)
- echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
+ echo "$UNAME_MACHINE"-unknown-dragonfly"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')"
exit ;;
*:*VMS:*:*)
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ UNAME_MACHINE=$( (uname -p) 2>/dev/null)
case "$UNAME_MACHINE" in
A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;;
@@ -1446,7 +1463,7 @@ EOF
echo i386-pc-xenix
exit ;;
i*86:skyos:*:*)
- echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`"
+ echo "$UNAME_MACHINE"-pc-skyos"$(echo "$UNAME_RELEASE" | sed -e 's/ .*$//')"
exit ;;
i*86:rdos:*:*)
echo "$UNAME_MACHINE"-pc-rdos
@@ -1504,7 +1521,7 @@ main ()
#define __ARCHITECTURE__ "m68k"
#endif
int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ version=$( (hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null);
if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else
@@ -1596,7 +1613,7 @@ main ()
}
EOF
-$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=$($dummy) &&
{ echo "$SYSTEM_NAME"; exit; }
# Apollos put the system type in the environment.
@@ -1624,6 +1641,12 @@ copies of config.guess and config.sub with the latest versions from:
https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
and
https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+EOF
+
+year=$(echo $timestamp | sed 's,-.*,,')
+# shellcheck disable=SC2003
+if test "$(expr "$(date +%Y)" - "$year")" -lt 3 ; then
+ cat >&2 <<EOF
If $0 has already been updated, send the following data and any
information you think might be pertinent to config-patches@gnu.org to
@@ -1631,26 +1654,27 @@ provide the necessary information to handle your system.
config.guess timestamp = $timestamp
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
+uname -m = $( (uname -m) 2>/dev/null || echo unknown)
+uname -r = $( (uname -r) 2>/dev/null || echo unknown)
+uname -s = $( (uname -s) 2>/dev/null || echo unknown)
+uname -v = $( (uname -v) 2>/dev/null || echo unknown)
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+/usr/bin/uname -p = $( (/usr/bin/uname -p) 2>/dev/null)
+/bin/uname -X = $( (/bin/uname -X) 2>/dev/null)
-hostinfo = `(hostinfo) 2>/dev/null`
-/bin/universe = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+hostinfo = $( (hostinfo) 2>/dev/null)
+/bin/universe = $( (/bin/universe) 2>/dev/null)
+/usr/bin/arch -k = $( (/usr/bin/arch -k) 2>/dev/null)
+/bin/arch = $( (/bin/arch) 2>/dev/null)
+/usr/bin/oslevel = $( (/usr/bin/oslevel) 2>/dev/null)
+/usr/convex/getsysinfo = $( (/usr/convex/getsysinfo) 2>/dev/null)
UNAME_MACHINE = "$UNAME_MACHINE"
UNAME_RELEASE = "$UNAME_RELEASE"
UNAME_SYSTEM = "$UNAME_SYSTEM"
UNAME_VERSION = "$UNAME_VERSION"
EOF
+fi
exit 1
diff --git a/config.sub b/config.sub
index a318a46..c874b7a 100755
--- a/config.sub
+++ b/config.sub
@@ -1,8 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2019 Free Software Foundation, Inc.
+# Copyright 1992-2020 Free Software Foundation, Inc.
-timestamp='2019-06-30'
+timestamp='2020-11-07'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -50,7 +50,7 @@ timestamp='2019-06-30'
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
-me=`echo "$0" | sed -e 's,.*/,,'`
+me=$(echo "$0" | sed -e 's,.*/,,')
usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
@@ -67,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2019 Free Software Foundation, Inc.
+Copyright 1992-2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -124,28 +124,27 @@ case $1 in
;;
*-*-*-*)
basic_machine=$field1-$field2
- os=$field3-$field4
+ basic_os=$field3-$field4
;;
*-*-*)
# Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two
# parts
maybe_os=$field2-$field3
case $maybe_os in
- nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \
- | linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \
+ nto-qnx* | linux-* | uclinux-uclibc* \
| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
| storm-chaos* | os2-emx* | rtmk-nova*)
basic_machine=$field1
- os=$maybe_os
+ basic_os=$maybe_os
;;
android-linux)
basic_machine=$field1-unknown
- os=linux-android
+ basic_os=linux-android
;;
*)
basic_machine=$field1-$field2
- os=$field3
+ basic_os=$field3
;;
esac
;;
@@ -154,7 +153,7 @@ case $1 in
case $field1-$field2 in
decstation-3100)
basic_machine=mips-dec
- os=
+ basic_os=
;;
*-*)
# Second component is usually, but not always the OS
@@ -162,7 +161,7 @@ case $1 in
# Prevent following clause from handling this valid os
sun*os*)
basic_machine=$field1
- os=$field2
+ basic_os=$field2
;;
# Manufacturers
dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \
@@ -175,11 +174,11 @@ case $1 in
| microblaze* | sim | cisco \
| oki | wec | wrs | winbond)
basic_machine=$field1-$field2
- os=
+ basic_os=
;;
*)
basic_machine=$field1
- os=$field2
+ basic_os=$field2
;;
esac
;;
@@ -191,447 +190,451 @@ case $1 in
case $field1 in
386bsd)
basic_machine=i386-pc
- os=bsd
+ basic_os=bsd
;;
a29khif)
basic_machine=a29k-amd
- os=udi
+ basic_os=udi
;;
adobe68k)
basic_machine=m68010-adobe
- os=scout
+ basic_os=scout
;;
alliant)
basic_machine=fx80-alliant
- os=
+ basic_os=
;;
altos | altos3068)
basic_machine=m68k-altos
- os=
+ basic_os=
;;
am29k)
basic_machine=a29k-none
- os=bsd
+ basic_os=bsd
;;
amdahl)
basic_machine=580-amdahl
- os=sysv
+ basic_os=sysv
;;
amiga)
basic_machine=m68k-unknown
- os=
+ basic_os=
;;
amigaos | amigados)
basic_machine=m68k-unknown
- os=amigaos
+ basic_os=amigaos
;;
amigaunix | amix)
basic_machine=m68k-unknown
- os=sysv4
+ basic_os=sysv4
;;
apollo68)
basic_machine=m68k-apollo
- os=sysv
+ basic_os=sysv
;;
apollo68bsd)
basic_machine=m68k-apollo
- os=bsd
+ basic_os=bsd
;;
aros)
basic_machine=i386-pc
- os=aros
+ basic_os=aros
;;
aux)
basic_machine=m68k-apple
- os=aux
+ basic_os=aux
;;
balance)
basic_machine=ns32k-sequent
- os=dynix
+ basic_os=dynix
;;
blackfin)
basic_machine=bfin-unknown
- os=linux
+ basic_os=linux
;;
cegcc)
basic_machine=arm-unknown
- os=cegcc
+ basic_os=cegcc
;;
convex-c1)
basic_machine=c1-convex
- os=bsd
+ basic_os=bsd
;;
convex-c2)
basic_machine=c2-convex
- os=bsd
+ basic_os=bsd
;;
convex-c32)
basic_machine=c32-convex
- os=bsd
+ basic_os=bsd
;;
convex-c34)
basic_machine=c34-convex
- os=bsd
+ basic_os=bsd
;;
convex-c38)
basic_machine=c38-convex
- os=bsd
+ basic_os=bsd
;;
cray)
basic_machine=j90-cray
- os=unicos
+ basic_os=unicos
;;
crds | unos)
basic_machine=m68k-crds
- os=
+ basic_os=
;;
da30)
basic_machine=m68k-da30
- os=
+ basic_os=
;;
decstation | pmax | pmin | dec3100 | decstatn)
basic_machine=mips-dec
- os=
+ basic_os=
;;
delta88)
basic_machine=m88k-motorola
- os=sysv3
+ basic_os=sysv3
;;
dicos)
basic_machine=i686-pc
- os=dicos
+ basic_os=dicos
;;
djgpp)
basic_machine=i586-pc
- os=msdosdjgpp
+ basic_os=msdosdjgpp
;;
ebmon29k)
basic_machine=a29k-amd
- os=ebmon
+ basic_os=ebmon
;;
es1800 | OSE68k | ose68k | ose | OSE)
basic_machine=m68k-ericsson
- os=ose
+ basic_os=ose
;;
gmicro)
basic_machine=tron-gmicro
- os=sysv
+ basic_os=sysv
;;
go32)
basic_machine=i386-pc
- os=go32
+ basic_os=go32
;;
h8300hms)
basic_machine=h8300-hitachi
- os=hms
+ basic_os=hms
;;
h8300xray)
basic_machine=h8300-hitachi
- os=xray
+ basic_os=xray
;;
h8500hms)
basic_machine=h8500-hitachi
- os=hms
+ basic_os=hms
;;
harris)
basic_machine=m88k-harris
- os=sysv3
+ basic_os=sysv3
;;
hp300 | hp300hpux)
basic_machine=m68k-hp
- os=hpux
+ basic_os=hpux
;;
hp300bsd)
basic_machine=m68k-hp
- os=bsd
+ basic_os=bsd
;;
hppaosf)
basic_machine=hppa1.1-hp
- os=osf
+ basic_os=osf
;;
hppro)
basic_machine=hppa1.1-hp
- os=proelf
+ basic_os=proelf
;;
i386mach)
basic_machine=i386-mach
- os=mach
+ basic_os=mach
;;
isi68 | isi)
basic_machine=m68k-isi
- os=sysv
+ basic_os=sysv
;;
m68knommu)
basic_machine=m68k-unknown
- os=linux
+ basic_os=linux
;;
magnum | m3230)
basic_machine=mips-mips
- os=sysv
+ basic_os=sysv
;;
merlin)
basic_machine=ns32k-utek
- os=sysv
+ basic_os=sysv
;;
mingw64)
basic_machine=x86_64-pc
- os=mingw64
+ basic_os=mingw64
;;
mingw32)
basic_machine=i686-pc
- os=mingw32
+ basic_os=mingw32
;;
mingw32ce)
basic_machine=arm-unknown
- os=mingw32ce
+ basic_os=mingw32ce
;;
monitor)
basic_machine=m68k-rom68k
- os=coff
+ basic_os=coff
;;
morphos)
basic_machine=powerpc-unknown
- os=morphos
+ basic_os=morphos
;;
moxiebox)
basic_machine=moxie-unknown
- os=moxiebox
+ basic_os=moxiebox
;;
msdos)
basic_machine=i386-pc
- os=msdos
+ basic_os=msdos
;;
msys)
basic_machine=i686-pc
- os=msys
+ basic_os=msys
;;
mvs)
basic_machine=i370-ibm
- os=mvs
+ basic_os=mvs
;;
nacl)
basic_machine=le32-unknown
- os=nacl
+ basic_os=nacl
;;
ncr3000)
basic_machine=i486-ncr
- os=sysv4
+ basic_os=sysv4
;;
netbsd386)
basic_machine=i386-pc
- os=netbsd
+ basic_os=netbsd
;;
netwinder)
basic_machine=armv4l-rebel
- os=linux
+ basic_os=linux
;;
news | news700 | news800 | news900)
basic_machine=m68k-sony
- os=newsos
+ basic_os=newsos
;;
news1000)
basic_machine=m68030-sony
- os=newsos
+ basic_os=newsos
;;
necv70)
basic_machine=v70-nec
- os=sysv
+ basic_os=sysv
;;
nh3000)
basic_machine=m68k-harris
- os=cxux
+ basic_os=cxux
;;
nh[45]000)
basic_machine=m88k-harris
- os=cxux
+ basic_os=cxux
;;
nindy960)
basic_machine=i960-intel
- os=nindy
+ basic_os=nindy
;;
mon960)
basic_machine=i960-intel
- os=mon960
+ basic_os=mon960
;;
nonstopux)
basic_machine=mips-compaq
- os=nonstopux
+ basic_os=nonstopux
;;
os400)
basic_machine=powerpc-ibm
- os=os400
+ basic_os=os400
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
- os=ose
+ basic_os=ose
;;
os68k)
basic_machine=m68k-none
- os=os68k
+ basic_os=os68k
;;
paragon)
basic_machine=i860-intel
- os=osf
+ basic_os=osf
;;
parisc)
basic_machine=hppa-unknown
- os=linux
+ basic_os=linux
+ ;;
+ psp)
+ basic_machine=mipsallegrexel-sony
+ basic_os=psp
;;
pw32)
basic_machine=i586-unknown
- os=pw32
+ basic_os=pw32
;;
rdos | rdos64)
basic_machine=x86_64-pc
- os=rdos
+ basic_os=rdos
;;
rdos32)
basic_machine=i386-pc
- os=rdos
+ basic_os=rdos
;;
rom68k)
basic_machine=m68k-rom68k
- os=coff
+ basic_os=coff
;;
sa29200)
basic_machine=a29k-amd
- os=udi
+ basic_os=udi
;;
sei)
basic_machine=mips-sei
- os=seiux
+ basic_os=seiux
;;
sequent)
basic_machine=i386-sequent
- os=
+ basic_os=
;;
sps7)
basic_machine=m68k-bull
- os=sysv2
+ basic_os=sysv2
;;
st2000)
basic_machine=m68k-tandem
- os=
+ basic_os=
;;
stratus)
basic_machine=i860-stratus
- os=sysv4
+ basic_os=sysv4
;;
sun2)
basic_machine=m68000-sun
- os=
+ basic_os=
;;
sun2os3)
basic_machine=m68000-sun
- os=sunos3
+ basic_os=sunos3
;;
sun2os4)
basic_machine=m68000-sun
- os=sunos4
+ basic_os=sunos4
;;
sun3)
basic_machine=m68k-sun
- os=
+ basic_os=
;;
sun3os3)
basic_machine=m68k-sun
- os=sunos3
+ basic_os=sunos3
;;
sun3os4)
basic_machine=m68k-sun
- os=sunos4
+ basic_os=sunos4
;;
sun4)
basic_machine=sparc-sun
- os=
+ basic_os=
;;
sun4os3)
basic_machine=sparc-sun
- os=sunos3
+ basic_os=sunos3
;;
sun4os4)
basic_machine=sparc-sun
- os=sunos4
+ basic_os=sunos4
;;
sun4sol2)
basic_machine=sparc-sun
- os=solaris2
+ basic_os=solaris2
;;
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
- os=
+ basic_os=
;;
sv1)
basic_machine=sv1-cray
- os=unicos
+ basic_os=unicos
;;
symmetry)
basic_machine=i386-sequent
- os=dynix
+ basic_os=dynix
;;
t3e)
basic_machine=alphaev5-cray
- os=unicos
+ basic_os=unicos
;;
t90)
basic_machine=t90-cray
- os=unicos
+ basic_os=unicos
;;
toad1)
basic_machine=pdp10-xkl
- os=tops20
+ basic_os=tops20
;;
tpf)
basic_machine=s390x-ibm
- os=tpf
+ basic_os=tpf
;;
udi29k)
basic_machine=a29k-amd
- os=udi
+ basic_os=udi
;;
ultra3)
basic_machine=a29k-nyu
- os=sym1
+ basic_os=sym1
;;
v810 | necv810)
basic_machine=v810-nec
- os=none
+ basic_os=none
;;
vaxv)
basic_machine=vax-dec
- os=sysv
+ basic_os=sysv
;;
vms)
basic_machine=vax-dec
- os=vms
+ basic_os=vms
;;
vsta)
basic_machine=i386-pc
- os=vsta
+ basic_os=vsta
;;
vxworks960)
basic_machine=i960-wrs
- os=vxworks
+ basic_os=vxworks
;;
vxworks68)
basic_machine=m68k-wrs
- os=vxworks
+ basic_os=vxworks
;;
vxworks29k)
basic_machine=a29k-wrs
- os=vxworks
+ basic_os=vxworks
;;
xbox)
basic_machine=i686-pc
- os=mingw32
+ basic_os=mingw32
;;
ymp)
basic_machine=ymp-cray
- os=unicos
+ basic_os=unicos
;;
*)
basic_machine=$1
- os=
+ basic_os=
;;
esac
;;
@@ -683,17 +686,17 @@ case $basic_machine in
bluegene*)
cpu=powerpc
vendor=ibm
- os=cnk
+ basic_os=cnk
;;
decsystem10* | dec10*)
cpu=pdp10
vendor=dec
- os=tops10
+ basic_os=tops10
;;
decsystem20* | dec20*)
cpu=pdp10
vendor=dec
- os=tops20
+ basic_os=tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
@@ -703,7 +706,7 @@ case $basic_machine in
dpx2*)
cpu=m68k
vendor=bull
- os=sysv3
+ basic_os=sysv3
;;
encore | umax | mmax)
cpu=ns32k
@@ -712,7 +715,7 @@ case $basic_machine in
elxsi)
cpu=elxsi
vendor=elxsi
- os=${os:-bsd}
+ basic_os=${basic_os:-bsd}
;;
fx2800)
cpu=i860
@@ -725,7 +728,7 @@ case $basic_machine in
h3050r* | hiux*)
cpu=hppa1.1
vendor=hitachi
- os=hiuxwe2
+ basic_os=hiuxwe2
;;
hp3k9[0-9][0-9] | hp9[0-9][0-9])
cpu=hppa1.0
@@ -766,38 +769,38 @@ case $basic_machine in
vendor=hp
;;
i*86v32)
- cpu=`echo "$1" | sed -e 's/86.*/86/'`
+ cpu=$(echo "$1" | sed -e 's/86.*/86/')
vendor=pc
- os=sysv32
+ basic_os=sysv32
;;
i*86v4*)
- cpu=`echo "$1" | sed -e 's/86.*/86/'`
+ cpu=$(echo "$1" | sed -e 's/86.*/86/')
vendor=pc
- os=sysv4
+ basic_os=sysv4
;;
i*86v)
- cpu=`echo "$1" | sed -e 's/86.*/86/'`
+ cpu=$(echo "$1" | sed -e 's/86.*/86/')
vendor=pc
- os=sysv
+ basic_os=sysv
;;
i*86sol2)
- cpu=`echo "$1" | sed -e 's/86.*/86/'`
+ cpu=$(echo "$1" | sed -e 's/86.*/86/')
vendor=pc
- os=solaris2
+ basic_os=solaris2
;;
j90 | j90-cray)
cpu=j90
vendor=cray
- os=${os:-unicos}
+ basic_os=${basic_os:-unicos}
;;
iris | iris4d)
cpu=mips
vendor=sgi
- case $os in
+ case $basic_os in
irix*)
;;
*)
- os=irix4
+ basic_os=irix4
;;
esac
;;
@@ -808,26 +811,26 @@ case $basic_machine in
*mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
cpu=m68k
vendor=atari
- os=mint
+ basic_os=mint
;;
news-3600 | risc-news)
cpu=mips
vendor=sony
- os=newsos
+ basic_os=newsos
;;
next | m*-next)
cpu=m68k
vendor=next
- case $os in
+ case $basic_os in
openstep*)
;;
nextstep*)
;;
ns2*)
- os=nextstep2
+ basic_os=nextstep2
;;
*)
- os=nextstep3
+ basic_os=nextstep3
;;
esac
;;
@@ -838,12 +841,12 @@ case $basic_machine in
op50n-* | op60c-*)
cpu=hppa1.1
vendor=oki
- os=proelf
+ basic_os=proelf
;;
pa-hitachi)
cpu=hppa1.1
vendor=hitachi
- os=hiuxwe2
+ basic_os=hiuxwe2
;;
pbd)
cpu=sparc
@@ -880,12 +883,12 @@ case $basic_machine in
sde)
cpu=mipsisa32
vendor=sde
- os=${os:-elf}
+ basic_os=${basic_os:-elf}
;;
simso-wrs)
cpu=sparclite
vendor=wrs
- os=vxworks
+ basic_os=vxworks
;;
tower | tower-32)
cpu=m68k
@@ -902,7 +905,7 @@ case $basic_machine in
w89k-*)
cpu=hppa1.1
vendor=winbond
- os=proelf
+ basic_os=proelf
;;
none)
cpu=none
@@ -914,7 +917,7 @@ case $basic_machine in
;;
leon-*|leon[3-9]-*)
cpu=sparc
- vendor=`echo "$basic_machine" | sed 's/-.*//'`
+ vendor=$(echo "$basic_machine" | sed 's/-.*//')
;;
*-*)
@@ -955,11 +958,11 @@ case $cpu-$vendor in
# some cases the only manufacturer, in others, it is the most popular.
craynv-unknown)
vendor=cray
- os=${os:-unicosmp}
+ basic_os=${basic_os:-unicosmp}
;;
c90-unknown | c90-cray)
vendor=cray
- os=${os:-unicos}
+ basic_os=${Basic_os:-unicos}
;;
fx80-unknown)
vendor=alliant
@@ -1003,7 +1006,7 @@ case $cpu-$vendor in
dpx20-unknown | dpx20-bull)
cpu=rs6000
vendor=bull
- os=${os:-bosx}
+ basic_os=${basic_os:-bosx}
;;
# Here we normalize CPU types irrespective of the vendor
@@ -1012,7 +1015,7 @@ case $cpu-$vendor in
;;
blackfin-*)
cpu=bfin
- os=linux
+ basic_os=linux
;;
c54x-*)
cpu=tic54x
@@ -1025,7 +1028,7 @@ case $cpu-$vendor in
;;
e500v[12]-*)
cpu=powerpc
- os=$os"spe"
+ basic_os=${basic_os}"spe"
;;
mips3*-*)
cpu=mips64
@@ -1035,7 +1038,7 @@ case $cpu-$vendor in
;;
m68knommu-*)
cpu=m68k
- os=linux
+ basic_os=linux
;;
m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
cpu=s12z
@@ -1045,7 +1048,7 @@ case $cpu-$vendor in
;;
parisc-*)
cpu=hppa
- os=linux
+ basic_os=linux
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
cpu=i586
@@ -1081,7 +1084,7 @@ case $cpu-$vendor in
cpu=mipsisa64sb1el
;;
sh5e[lb]-*)
- cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'`
+ cpu=$(echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/')
;;
spur-*)
cpu=spur
@@ -1099,13 +1102,16 @@ case $cpu-$vendor in
cpu=x86_64
;;
xscale-* | xscalee[bl]-*)
- cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
+ cpu=$(echo "$cpu" | sed 's/^xscale/arm/')
+ ;;
+ arm64-*)
+ cpu=aarch64
;;
# Recognize the canonical CPU Types that limit and/or modify the
# company names they are paired with.
cr16-*)
- os=${os:-elf}
+ basic_os=${basic_os:-elf}
;;
crisv32-* | etraxfs*-*)
cpu=crisv32
@@ -1116,7 +1122,7 @@ case $cpu-$vendor in
vendor=axis
;;
crx-*)
- os=${os:-elf}
+ basic_os=${basic_os:-elf}
;;
neo-tandem)
cpu=neo
@@ -1138,16 +1144,12 @@ case $cpu-$vendor in
cpu=nsx
vendor=tandem
;;
- s390-*)
- cpu=s390
- vendor=ibm
- ;;
- s390x-*)
- cpu=s390x
- vendor=ibm
+ mipsallegrexel-sony)
+ cpu=mipsallegrexel
+ vendor=sony
;;
tile*-*)
- os=${os:-linux-gnu}
+ basic_os=${basic_os:-linux-gnu}
;;
*)
@@ -1164,7 +1166,7 @@ case $cpu-$vendor in
| am33_2.0 \
| amdgcn \
| arc | arceb \
- | arm | arm[lb]e | arme[lb] | armv* \
+ | arm | arm[lb]e | arme[lb] | armv* \
| avr | avr32 \
| asmjs \
| ba \
@@ -1229,6 +1231,7 @@ case $cpu-$vendor in
| pyramid \
| riscv | riscv32 | riscv64 \
| rl78 | romp | rs6000 | rx \
+ | s390 | s390x \
| score \
| sh | shl \
| sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \
@@ -1275,8 +1278,47 @@ esac
# Decode manufacturer-specific aliases for certain operating systems.
-if [ x$os != x ]
+if test x$basic_os != x
then
+
+# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just
+# set os.
+case $basic_os in
+ gnu/linux*)
+ kernel=linux
+ os=$(echo $basic_os | sed -e 's|gnu/linux|gnu|')
+ ;;
+ os2-emx)
+ kernel=os2
+ os=$(echo $basic_os | sed -e 's|os2-emx|emx|')
+ ;;
+ nto-qnx*)
+ kernel=nto
+ os=$(echo $basic_os | sed -e 's|nto-qnx|qnx|')
+ ;;
+ *-*)
+ # shellcheck disable=SC2162
+ IFS="-" read kernel os <<EOF
+$basic_os
+EOF
+ ;;
+ # Default OS when just kernel was specified
+ nto*)
+ kernel=nto
+ os=$(echo $basic_os | sed -e 's|nto|qnx|')
+ ;;
+ linux*)
+ kernel=linux
+ os=$(echo $basic_os | sed -e 's|linux|gnu|')
+ ;;
+ *)
+ kernel=
+ os=$basic_os
+ ;;
+esac
+
+# Now, normalize the OS (knowing we just have one component, it's not a kernel,
+# etc.)
case $os in
# First match some system type aliases that might get confused
# with valid system types.
@@ -1288,7 +1330,7 @@ case $os in
os=cnk
;;
solaris1 | solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ os=$(echo $os | sed -e 's|solaris1|sunos4|')
;;
solaris)
os=solaris2
@@ -1296,9 +1338,6 @@ case $os in
unixware*)
os=sysv4.2uw
;;
- gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
- ;;
# es1800 is here to avoid being matched by es* (a different OS)
es1800*)
os=ose
@@ -1320,12 +1359,9 @@ case $os in
os=sco3.2v4
;;
sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ os=$(echo $os | sed -e 's/sco3.2./sco3.2v/')
;;
- sco3.2v[4-9]* | sco5v6*)
- # Don't forget version if it is 3.2v4 or newer.
- ;;
- scout)
+ sco*v* | scout)
# Don't match below
;;
sco*)
@@ -1334,79 +1370,26 @@ case $os in
psos*)
os=psos
;;
- # Now accept the basic system types.
- # The portable systems comes first.
- # Each alternative MUST end in a * to match a version number.
- # sysv* is not here because it comes later, after sysvr4.
- gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \
- | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\
- | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
- | sym* | kopensolaris* | plan9* \
- | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
- | aos* | aros* | cloudabi* | sortix* \
- | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
- | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
- | knetbsd* | mirbsd* | netbsd* \
- | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \
- | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \
- | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
- | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
- | udi* | eabi* | lites* | ieee* | go32* | aux* | hcos* \
- | chorusrdb* | cegcc* | glidix* \
- | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
- | midipix* | mingw32* | mingw64* | linux-gnu* | linux-android* \
- | linux-newlib* | linux-musl* | linux-uclibc* \
- | uxpv* | beos* | mpeix* | udk* | moxiebox* \
- | interix* | uwin* | mks* | rhapsody* | darwin* \
- | openstep* | oskit* | conix* | pw32* | nonstopux* \
- | storm-chaos* | tops10* | tenex* | tops20* | its* \
- | os2* | vos* | palmos* | uclinux* | nucleus* \
- | morphos* | superux* | rtmk* | windiss* \
- | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
- | skyos* | haiku* | rdos* | toppers* | drops* | es* \
- | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
- | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
- | nsk* | powerunix)
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
qnx*)
- case $cpu in
- x86 | i*86)
- ;;
- *)
- os=nto-$os
- ;;
- esac
+ os=qnx
;;
hiux*)
os=hiuxwe2
;;
- nto-qnx*)
- ;;
- nto*)
- os=`echo $os | sed -e 's|nto|nto-qnx|'`
- ;;
- sim | xray | os68k* | v88r* \
- | windows* | osx | abug | netware* | os9* \
- | macos* | mpw* | magic* | mmixware* | mon960* | lnews*)
- ;;
- linux-dietlibc)
- os=linux-dietlibc
- ;;
- linux*)
- os=`echo $os | sed -e 's|linux|linux-gnu|'`
- ;;
lynx*178)
os=lynxos178
;;
lynx*5)
os=lynxos5
;;
+ lynxos*)
+ # don't get caught up in next wildcard
+ ;;
lynx*)
os=lynxos
;;
- mac*)
- os=`echo "$os" | sed -e 's|mac|macos|'`
+ mac[0-9]*)
+ os=$(echo "$os" | sed -e 's|mac|macos|')
;;
opened*)
os=openedition
@@ -1415,10 +1398,10 @@ case $os in
os=os400
;;
sunos5*)
- os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
+ os=$(echo "$os" | sed -e 's|sunos5|solaris2|')
;;
sunos6*)
- os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
+ os=$(echo "$os" | sed -e 's|sunos6|solaris3|')
;;
wince*)
os=wince
@@ -1452,7 +1435,7 @@ case $os in
;;
# Preserve the version number of sinix5.
sinix5.*)
- os=`echo $os | sed -e 's|sinix|sysv|'`
+ os=$(echo $os | sed -e 's|sinix|sysv|')
;;
sinix*)
os=sysv4
@@ -1475,18 +1458,12 @@ case $os in
sysvr4)
os=sysv4
;;
- # This must come after sysvr4.
- sysv*)
- ;;
ose*)
os=ose
;;
*mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
os=mint
;;
- zvmoe)
- os=zvmoe
- ;;
dicos*)
os=dicos
;;
@@ -1503,19 +1480,11 @@ case $os in
;;
esac
;;
- nacl*)
- ;;
- ios)
- ;;
- none)
- ;;
- *-eabi)
- ;;
*)
- echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
- exit 1
+ # No normalization, but not necessarily accepted, that comes below.
;;
esac
+
else
# Here we handle the default operating systems that come with various machines.
@@ -1528,6 +1497,7 @@ else
# will signal an error saying that MANUFACTURER isn't an operating
# system, and we'll never get to this point.
+kernel=
case $cpu-$vendor in
score-*)
os=elf
@@ -1539,7 +1509,8 @@ case $cpu-$vendor in
os=riscix1.2
;;
arm*-rebel)
- os=linux
+ kernel=linux
+ os=gnu
;;
arm*-semi)
os=aout
@@ -1705,84 +1676,173 @@ case $cpu-$vendor in
os=none
;;
esac
+
fi
+# Now, validate our (potentially fixed-up) OS.
+case $os in
+ # Sometimes we do "kernel-abi", so those need to count as OSes.
+ musl* | newlib* | uclibc*)
+ ;;
+ # Likewise for "kernel-libc"
+ eabi | eabihf | gnueabi | gnueabihf)
+ ;;
+ # Now accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST end in a * to match a version number.
+ gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \
+ | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \
+ | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
+ | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \
+ | hiux* | abug | nacl* | netware* | windows* \
+ | os9* | macos* | osx* | ios* \
+ | mpw* | magic* | mmixware* | mon960* | lnews* \
+ | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
+ | aos* | aros* | cloudabi* | sortix* | twizzler* \
+ | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
+ | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
+ | mirbsd* | netbsd* | dicos* | openedition* | ose* \
+ | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \
+ | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \
+ | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
+ | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
+ | udi* | lites* | ieee* | go32* | aux* | hcos* \
+ | chorusrdb* | cegcc* | glidix* \
+ | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
+ | midipix* | mingw32* | mingw64* | mint* \
+ | uxpv* | beos* | mpeix* | udk* | moxiebox* \
+ | interix* | uwin* | mks* | rhapsody* | darwin* \
+ | openstep* | oskit* | conix* | pw32* | nonstopux* \
+ | storm-chaos* | tops10* | tenex* | tops20* | its* \
+ | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \
+ | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \
+ | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
+ | skyos* | haiku* | rdos* | toppers* | drops* | es* \
+ | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
+ | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
+ | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx*)
+ ;;
+ # This one is extra strict with allowed versions
+ sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ ;;
+ none)
+ ;;
+ *)
+ echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# As a final step for OS-related things, validate the OS-kernel combination
+# (given a valid OS), if there is a kernel.
+case $kernel-$os in
+ linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* | linux-musl* | linux-uclibc* )
+ ;;
+ uclinux-uclibc* )
+ ;;
+ -dietlibc* | -newlib* | -musl* | -uclibc* )
+ # These are just libc implementations, not actual OSes, and thus
+ # require a kernel.
+ echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2
+ exit 1
+ ;;
+ kfreebsd*-gnu* | kopensolaris*-gnu*)
+ ;;
+ nto-qnx*)
+ ;;
+ os2-emx)
+ ;;
+ *-eabi* | *-gnueabi*)
+ ;;
+ -*)
+ # Blank kernel with real OS is always fine.
+ ;;
+ *-*)
+ echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2
+ exit 1
+ ;;
+esac
+
# Here we handle the case where we know the os, and the CPU type, but not the
# manufacturer. We pick the logical manufacturer.
case $vendor in
unknown)
- case $os in
- riscix*)
+ case $cpu-$os in
+ *-riscix*)
vendor=acorn
;;
- sunos*)
+ *-sunos*)
vendor=sun
;;
- cnk*|-aix*)
+ *-cnk* | *-aix*)
vendor=ibm
;;
- beos*)
+ *-beos*)
vendor=be
;;
- hpux*)
+ *-hpux*)
vendor=hp
;;
- mpeix*)
+ *-mpeix*)
vendor=hp
;;
- hiux*)
+ *-hiux*)
vendor=hitachi
;;
- unos*)
+ *-unos*)
vendor=crds
;;
- dgux*)
+ *-dgux*)
vendor=dg
;;
- luna*)
+ *-luna*)
vendor=omron
;;
- genix*)
+ *-genix*)
vendor=ns
;;
- clix*)
+ *-clix*)
vendor=intergraph
;;
- mvs* | opened*)
+ *-mvs* | *-opened*)
+ vendor=ibm
+ ;;
+ *-os400*)
vendor=ibm
;;
- os400*)
+ s390-* | s390x-*)
vendor=ibm
;;
- ptx*)
+ *-ptx*)
vendor=sequent
;;
- tpf*)
+ *-tpf*)
vendor=ibm
;;
- vxsim* | vxworks* | windiss*)
+ *-vxsim* | *-vxworks* | *-windiss*)
vendor=wrs
;;
- aux*)
+ *-aux*)
vendor=apple
;;
- hms*)
+ *-hms*)
vendor=hitachi
;;
- mpw* | macos*)
+ *-mpw* | *-macos*)
vendor=apple
;;
- *mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
+ *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*)
vendor=atari
;;
- vos*)
+ *-vos*)
vendor=stratus
;;
esac
;;
esac
-echo "$cpu-$vendor-$os"
+echo "$cpu-$vendor-${kernel:+$kernel-}$os"
exit
# Local variables:
diff --git a/config/ChangeLog b/config/ChangeLog
index 650e8e6..6a15db4 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,12 @@
+2020-11-25 Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * bootstrap-hwasan.mk: Disable random frame tags for stack-tagging
+ during bootstrap.
+
+2020-11-25 Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * bootstrap-hwasan.mk: New file.
+
2020-09-09 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
Sync from binutils-gdb.
diff --git a/config/bootstrap-hwasan.mk b/config/bootstrap-hwasan.mk
new file mode 100644
index 0000000..91989f4
--- /dev/null
+++ b/config/bootstrap-hwasan.mk
@@ -0,0 +1,12 @@
+# This option enables -fsanitize=hwaddress for stage2 and stage3.
+# We need to disable random frame tags for bootstrap since the autoconf check
+# for which direction the stack is growing has UB that a random frame tag
+# breaks. Running with a random frame tag gives approx. 50% chance of
+# bootstrap comparison diff in libiberty/alloca.c.
+
+STAGE2_CFLAGS += -fsanitize=hwaddress --param hwasan-random-frame-tag=0
+STAGE3_CFLAGS += -fsanitize=hwaddress --param hwasan-random-frame-tag=0
+POSTSTAGE1_LDFLAGS += -fsanitize=hwaddress -static-libhwasan \
+ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ \
+ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/hwasan/ \
+ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/hwasan/.libs
diff --git a/configure b/configure
index a2ea1a3..d079883 100755
--- a/configure
+++ b/configure
@@ -3444,9 +3444,6 @@ case ,${enable_languages}, in
;;
*)
case "${target}" in
- *-*-darwin*)
- unsupported_languages="$unsupported_languages d"
- ;;
bpf-*-*)
unsupported_languages="$unsupported_languages d"
;;
@@ -9305,7 +9302,7 @@ fi
# or bootstrap-ubsan, bootstrap it.
if echo " ${target_configdirs} " | grep " libsanitizer " > /dev/null 2>&1; then
case "$BUILD_CONFIG" in
- *bootstrap-asan* | *bootstrap-ubsan* )
+ *bootstrap-hwasan* | *bootstrap-asan* | *bootstrap-ubsan* )
bootstrap_target_libs=${bootstrap_target_libs}target-libsanitizer,
bootstrap_fixincludes=yes
;;
diff --git a/configure.ac b/configure.ac
index 44fa75f..12f85cc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -724,9 +724,6 @@ case ,${enable_languages}, in
;;
*)
case "${target}" in
- *-*-darwin*)
- unsupported_languages="$unsupported_languages d"
- ;;
bpf-*-*)
unsupported_languages="$unsupported_languages d"
;;
@@ -2814,7 +2811,7 @@ fi
# or bootstrap-ubsan, bootstrap it.
if echo " ${target_configdirs} " | grep " libsanitizer " > /dev/null 2>&1; then
case "$BUILD_CONFIG" in
- *bootstrap-asan* | *bootstrap-ubsan* )
+ *bootstrap-hwasan* | *bootstrap-asan* | *bootstrap-ubsan* )
bootstrap_target_libs=${bootstrap_target_libs}target-libsanitizer,
bootstrap_fixincludes=yes
;;
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index c269e7c..2baa7f9 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,45 @@
+2020-12-02 Jason Merrill <jason@redhat.com>
+
+ * gcc-git-customization.sh: Configure sendemail.to.
+
+2020-11-30 Martin Liska <mliska@suse.cz>
+
+ * gcc-changelog/git_commit.py: Suggest close file for
+ 'unchanged file mentioned in a ChangeLog' error.
+ * gcc-changelog/test_email.py: Test it.
+
+2020-11-30 Martin Liska <mliska@suse.cz>
+
+ * gcc-changelog/git_commit.py: Allow sub-directory wildcard
+ changelog entry. Fix a typo caused by apostrophe escaping.
+ * gcc-changelog/test_email.py: Test it.
+ * gcc-changelog/test_patches.txt: Likewise.
+
+2020-11-30 Jonathan Wakely <jwakely@redhat.com>
+
+ * gcc-changelog/git_commit.py (wildcard_prefixes): Add libstdc++
+ testsuite directory.
+
+2020-11-30 Martin Liska <mliska@suse.cz>
+
+ * gcc-changelog/git_commit.py: Allow wildcard pattern only.
+
+2020-11-27 Martin Liska <mliska@suse.cz>
+
+ * gcc-changelog/git_commit.py: Use regex for cherry pick prefix.
+ * gcc-changelog/test_email.py: Test it.
+ * gcc-changelog/test_patches.txt: Likewise.
+
+2020-11-25 Martin Liska <mliska@suse.cz>
+
+ * gcc-changelog/git_commit.py: Use revert_regex instead
+ of string prefix. Convert sets to literals.
+
+2020-11-16 Martin Liska <mliska@suse.cz>
+
+ * mklog.py: Do not call read on an input stream.
+ Fix some flake8 issues.
+
2020-11-07 Lewis Hyatt <lhyatt@gmail.com>
* unicode/EastAsianWidth.txt: Update to Unicode 13.0.0.
diff --git a/contrib/gcc-changelog/git_commit.py b/contrib/gcc-changelog/git_commit.py
index 80ae0b2..0c43816 100755
--- a/contrib/gcc-changelog/git_commit.py
+++ b/contrib/gcc-changelog/git_commit.py
@@ -16,10 +16,11 @@
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>. */
+import difflib
import os
import re
-changelog_locations = set([
+changelog_locations = {
'config',
'contrib',
'contrib/header-tools',
@@ -72,9 +73,9 @@ changelog_locations = set([
'libvtv',
'lto-plugin',
'maintainer-scripts',
- 'zlib'])
+ 'zlib'}
-bug_components = set([
+bug_components = {
'ada',
'analyzer',
'boehm-gc',
@@ -123,9 +124,9 @@ bug_components = set([
'testsuite',
'translation',
'tree-optimization',
- 'web'])
+ 'web'}
-ignored_prefixes = [
+ignored_prefixes = {
'gcc/d/dmd/',
'gcc/go/gofrontend/',
'gcc/testsuite/gdc.test/',
@@ -134,18 +135,19 @@ ignored_prefixes = [
'libphobos/libdruntime/',
'libphobos/src/',
'libsanitizer/',
- ]
+ }
-wildcard_prefixes = [
+wildcard_prefixes = {
'gcc/testsuite/',
- 'libstdc++-v3/doc/html/'
- ]
+ 'libstdc++-v3/doc/html/',
+ 'libstdc++-v3/testsuite/'
+ }
-misc_files = [
+misc_files = {
'gcc/DATESTAMP',
'gcc/BASE-VER',
'gcc/DEV-PHASE'
- ]
+ }
author_line_regex = \
re.compile(r'^(?P<datetime>\d{4}-\d{2}-\d{2})\ {2}(?P<name>.* <.*>)')
@@ -157,12 +159,12 @@ star_prefix_regex = re.compile(r'\t\*(?P<spaces>\ *)(?P<content>.*)')
end_of_location_regex = re.compile(r'[\[<(:]')
item_empty_regex = re.compile(r'\t(\* \S+ )?\(\S+\):\s*$')
item_parenthesis_regex = re.compile(r'\t(\*|\(\S+\):)')
+revert_regex = re.compile(r'This reverts commit (?P<hash>\w+).$')
+cherry_pick_regex = re.compile(r'cherry picked from commit (?P<hash>\w+)')
LINE_LIMIT = 100
TAB_WIDTH = 8
CO_AUTHORED_BY_PREFIX = 'co-authored-by: '
-CHERRY_PICK_PREFIX = '(cherry picked from commit '
-REVERT_PREFIX = 'This reverts commit '
REVIEW_PREFIXES = ('reviewed-by: ', 'reviewed-on: ', 'signed-off-by: ',
'acked-by: ', 'tested-by: ', 'reported-by: ',
@@ -274,8 +276,9 @@ class GitCommit:
# Identify first if the commit is a Revert commit
for line in self.info.lines:
- if line.startswith(REVERT_PREFIX):
- self.revert_commit = line[len(REVERT_PREFIX):].rstrip('.')
+ m = revert_regex.match(line)
+ if m:
+ self.revert_commit = m.group('hash')
break
if self.revert_commit:
self.info = self.commit_to_info_hook(self.revert_commit)
@@ -421,14 +424,16 @@ class GitCommit:
continue
elif lowered_line.startswith(REVIEW_PREFIXES):
continue
- elif line.startswith(CHERRY_PICK_PREFIX):
- commit = line[len(CHERRY_PICK_PREFIX):].rstrip(')')
- if self.cherry_pick_commit:
- self.errors.append(Error('multiple cherry pick lines',
- line))
- else:
- self.cherry_pick_commit = commit
- continue
+ else:
+ m = cherry_pick_regex.search(line)
+ if m:
+ commit = m.group('hash')
+ if self.cherry_pick_commit:
+ msg = 'multiple cherry pick lines'
+ self.errors.append(Error(msg, line))
+ else:
+ self.cherry_pick_commit = commit
+ continue
# ChangeLog name will be deduced later
if not last_entry:
@@ -489,7 +494,7 @@ class GitCommit:
for entry in self.changelog_entries:
for pattern in entry.file_patterns:
name = os.path.join(entry.folder, pattern)
- if name not in wildcard_prefixes:
+ if not [name.startswith(pr) for pr in wildcard_prefixes]:
msg = 'unsupported wildcard prefix'
self.errors.append(Error(msg, name))
@@ -557,7 +562,7 @@ class GitCommit:
mentioned_patterns = []
used_patterns = set()
for entry in self.changelog_entries:
- if not entry.files:
+ if not entry.files and not entry.file_patterns:
msg = 'no files mentioned for ChangeLog in directory'
self.errors.append(Error(msg, entry.folder))
assert not entry.folder.endswith('/')
@@ -572,6 +577,9 @@ class GitCommit:
changed_files = set(cand)
for file in sorted(mentioned_files - changed_files):
msg = 'unchanged file mentioned in a ChangeLog'
+ candidates = difflib.get_close_matches(file, changed_files, 1)
+ if candidates:
+ msg += f' (did you mean "{candidates[0]}"?)'
self.errors.append(Error(msg, file))
for file in sorted(changed_files - mentioned_files):
if not self.in_ignored_location(file):
@@ -613,7 +621,7 @@ class GitCommit:
for pattern in mentioned_patterns:
if pattern not in used_patterns:
- error = 'pattern doesn''t match any changed files'
+ error = "pattern doesn't match any changed files"
self.errors.append(Error(error, pattern))
def check_for_correct_changelog(self):
diff --git a/contrib/gcc-changelog/test_email.py b/contrib/gcc-changelog/test_email.py
index e38c3e5..8f5129e 100755
--- a/contrib/gcc-changelog/test_email.py
+++ b/contrib/gcc-changelog/test_email.py
@@ -113,7 +113,9 @@ class TestGccChangelog(unittest.TestCase):
email = self.from_patch_glob('0096')
assert email.errors
err = email.errors[0]
- assert err.message == 'unchanged file mentioned in a ChangeLog'
+ assert err.message == 'unchanged file mentioned in a ChangeLog (did ' \
+ 'you mean "gcc/testsuite/gcc.target/aarch64/' \
+ 'advsimd-intrinsics/vdot-3-1.c"?)'
assert err.line == 'gcc/testsuite/gcc.target/aarch64/' \
'advsimd-intrinsics/vdot-compile-3-1.c'
@@ -333,7 +335,7 @@ class TestGccChangelog(unittest.TestCase):
assert not email.errors
email = self.from_patch_glob('0002-libstdc-Fake-test-change-1.patch')
assert len(email.errors) == 1
- msg = 'pattern doesn''t match any changed files'
+ msg = "pattern doesn't match any changed files"
assert email.errors[0].message == msg
assert email.errors[0].line == 'libstdc++-v3/doc/html/'
email = self.from_patch_glob('0003-libstdc-Fake-test-change-2.patch')
@@ -355,6 +357,8 @@ class TestGccChangelog(unittest.TestCase):
def test_backport(self):
email = self.from_patch_glob('0001-asan-fix-RTX-emission.patch')
assert not email.errors
+ expected_hash = '8cff672cb9a132d3d3158c2edfc9a64b55292b80'
+ assert email.cherry_pick_commit == expected_hash
assert len(email.changelog_entries) == 1
entry = list(email.to_changelog_entries())[0][1]
assert entry.startswith('2020-06-11 Martin Liska <mliska@suse.cz>')
@@ -384,3 +388,10 @@ class TestGccChangelog(unittest.TestCase):
email = self.from_patch_glob('0001-lto-fix-LTO-debug')
assert not email.errors
assert len(email.changelog_entries) == 1
+
+ def test_wildcard_in_subdir(self):
+ email = self.from_patch_glob('0001-Wildcard-subdirs.patch')
+ assert len(email.changelog_entries) == 1
+ err = email.errors[0]
+ assert err.message == "pattern doesn't match any changed files"
+ assert err.line == 'libstdc++-v3/testsuite/28_regex_not-existing/'
diff --git a/contrib/gcc-changelog/test_patches.txt b/contrib/gcc-changelog/test_patches.txt
index 37f49c8..02ce28d 100644
--- a/contrib/gcc-changelog/test_patches.txt
+++ b/contrib/gcc-changelog/test_patches.txt
@@ -3145,7 +3145,7 @@ gcc/ChangeLog:
by using Pmode instead of ptr_mode.
Co-Authored-By: Jakub Jelinek <jakub@redhat.com>
-(cherry picked from commit 8cff672cb9a132d3d3158c2edfc9a64b55292b80)
+(cherry picked from commit 8cff672cb9a132d3d3158c2edfc9a64b55292b80 (only part))
---
gcc/asan.c | 1 +
1 file changed, 1 insertion(+)
@@ -3320,3 +3320,27 @@ index 7c9d492f6a4..37e73348cb7 100644
--
2.25.1
+=== 0001-Wildcard-subdirs.patch ===
+From b798205595426c53eb362065f6ed6c320dcc161d Mon Sep 17 00:00:00 2001
+From: Martin Liska <mliska@suse.cz>
+Date: Mon, 30 Nov 2020 13:27:51 +0100
+Subject: [PATCH] Fix it.
+
+libstdc++-v3/ChangeLog:
+
+ * testsuite/28_regex/*: Fix them all.
+ * testsuite/28_regex_not-existing/*: Fix them all.
+---
+ contrib/gcc-changelog/git_commit.py | 1 +
+ libstdc++-v3/testsuite/28_regex/init-list.cc | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/libstdc++-v3/testsuite/28_regex/init-list.cc b/libstdc++-v3/testsuite/28_regex/init-list.cc
+index f51453f019a..d10ecf483f4 100644
+--- a/libstdc++-v3/testsuite/28_regex/init-list.cc
++++ b/libstdc++-v3/testsuite/28_regex/init-list.cc
+@@ -1 +1,2 @@
+
++
+--
+2.29.2
diff --git a/contrib/gcc-git-customization.sh b/contrib/gcc-git-customization.sh
index 200b81e..e7e6662 100755
--- a/contrib/gcc-git-customization.sh
+++ b/contrib/gcc-git-customization.sh
@@ -35,6 +35,10 @@ git config alias.gcc-commit-mklog '!f() { GCC_FORCE_MKLOG=1 git commit "$@"; };
# *.md diff=md
git config diff.md.xfuncname '^\(define.*$'
+# Tell git send-email where patches go.
+# ??? Maybe also set sendemail.tocmd to guess from MAINTAINERS?
+git config sendemail.to 'gcc-patches@gcc.gnu.org'
+
set_user=$(git config --get "user.name")
set_email=$(git config --get "user.email")
diff --git a/contrib/mklog.py b/contrib/mklog.py
index 1e85dfe..57be299 100755
--- a/contrib/mklog.py
+++ b/contrib/mklog.py
@@ -50,7 +50,7 @@ template_and_param_regex = re.compile(r'<[^<>]*>')
bugzilla_url = 'https://gcc.gnu.org/bugzilla/rest.cgi/bug?id=%s&' \
'include_fields=summary'
-function_extensions = set(['.c', '.cpp', '.C', '.cc', '.h', '.inc', '.def'])
+function_extensions = {'.c', '.cpp', '.C', '.cc', '.h', '.inc', '.def'}
help_message = """\
Generate ChangeLog template for PATCH.
@@ -111,8 +111,8 @@ def sort_changelog_files(changed_file):
def get_pr_titles(prs):
output = ''
for pr in prs:
- id = pr.split('/')[-1]
- r = requests.get(bugzilla_url % id)
+ pr_id = pr.split('/')[-1]
+ r = requests.get(bugzilla_url % pr_id)
bugs = r.json()['bugs']
if len(bugs) == 1:
output += '%s - %s\n' % (pr, bugs[0]['summary'])
@@ -242,8 +242,7 @@ if __name__ == '__main__':
if args.input == '-':
args.input = None
- input = open(args.input) if args.input else sys.stdin
- data = input.read()
+ data = open(args.input) if args.input else sys.stdin
output = generate_changelog(data, args.no_functions,
args.fill_up_bug_titles)
if args.changelog:
diff --git a/fixincludes/ChangeLog b/fixincludes/ChangeLog
index 1428c68..104aa42 100644
--- a/fixincludes/ChangeLog
+++ b/fixincludes/ChangeLog
@@ -1,3 +1,8 @@
+2020-11-18 Nathan Sidwell <nathan@acm.org>
+
+ * inclhack.def (aix_physaddr_t): New.
+ * fixincl.x: Regenerated.
+
2020-10-03 Clément Chigot <clement.chigot@atos.net>
* inclhack.def (aix_malloc): Add more context to select.
diff --git a/fixincludes/fixincl.x b/fixincludes/fixincl.x
index 758d562..2143965 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 October 3, 2020 at 11:40:52 PM by AutoGen 5.18
+ * It has been AutoGen-ed October 21, 2020 at 10:43:22 AM by AutoGen 5.18.16
* From the definitions inclhack.def
* and the template file fixincl
*/
-/* DO NOT SVN-MERGE THIS FILE, EITHER Sat Oct 3 23:40:52 UTC 2020
+/* DO NOT SVN-MERGE THIS FILE, EITHER Wed Oct 21 10:43:22 EDT 2020
*
* 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 259 fixup descriptions.
+ * This file contains 260 fixup descriptions.
*
* See README for more information.
*
@@ -1249,6 +1249,43 @@ static const char* apzAix_Rwlock_Initializer_1Patch[] = {
/* * * * * * * * * * * * * * * * * * * * * * * * * *
*
+ * Description of Aix_Physadr_T fix
+ */
+tSCC zAix_Physadr_TName[] =
+ "aix_physadr_t";
+
+/*
+ * File name selection pattern
+ */
+tSCC zAix_Physadr_TList[] =
+ "sys/types.h\0";
+/*
+ * Machine/OS name selection pattern
+ */
+tSCC* apzAix_Physadr_TMachs[] = {
+ "*-*-aix*",
+ (const char*)NULL };
+
+/*
+ * content selection pattern - do fix if pattern found
+ */
+tSCC zAix_Physadr_TSelect0[] =
+ "typedef[ \t]*struct[ \t]*([{][^}]*[}][ \t]*\\*[ \t]*physadr_t;)";
+
+#define AIX_PHYSADR_T_TEST_CT 1
+static tTestDesc aAix_Physadr_TTests[] = {
+ { TT_EGREP, zAix_Physadr_TSelect0, (regex_t*)NULL }, };
+
+/*
+ * Fix Command Arguments for Aix_Physadr_T
+ */
+static const char* apzAix_Physadr_TPatch[] = {
+ "format",
+ "typedef struct __physadr_s %1",
+ (char*)NULL };
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
* Description of Aix_Pthread fix
*/
tSCC zAix_PthreadName[] =
@@ -10521,9 +10558,9 @@ static const char* apzX11_SprintfPatch[] = {
*
* List of all fixes
*/
-#define REGEX_COUNT 297
+#define REGEX_COUNT 298
#define MACH_LIST_SIZE_LIMIT 187
-#define FIX_COUNT 259
+#define FIX_COUNT 260
/*
* Enumerate the fixes
@@ -10555,6 +10592,7 @@ typedef enum {
AIX_MUTEX_INITIALIZER_1_FIXIDX,
AIX_COND_INITIALIZER_1_FIXIDX,
AIX_RWLOCK_INITIALIZER_1_FIXIDX,
+ AIX_PHYSADR_T_FIXIDX,
AIX_PTHREAD_FIXIDX,
AIX_STDINT_1_FIXIDX,
AIX_STDINT_2_FIXIDX,
@@ -10921,6 +10959,11 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
AIX_RWLOCK_INITIALIZER_1_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
aAix_Rwlock_Initializer_1Tests, apzAix_Rwlock_Initializer_1Patch, 0 },
+ { zAix_Physadr_TName, zAix_Physadr_TList,
+ apzAix_Physadr_TMachs,
+ AIX_PHYSADR_T_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+ aAix_Physadr_TTests, apzAix_Physadr_TPatch, 0 },
+
{ zAix_PthreadName, zAix_PthreadList,
apzAix_PthreadMachs,
AIX_PTHREAD_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
diff --git a/fixincludes/inclhack.def b/fixincludes/inclhack.def
index 47eb236..80c9adf 100644
--- a/fixincludes/inclhack.def
+++ b/fixincludes/inclhack.def
@@ -720,6 +720,20 @@ fix = {
"{ \\\\\n";
};
+
+/* On AIX 'typedef struct {<stuff>} * physadr_t;' needs to give the struct a
+ name for linkage purposes. Fortunately it is on exactly one
+ line. */
+fix = {
+ hackname = aix_physadr_t;
+ mach = "*-*-aix*";
+ files = sys/types.h;
+ select = "typedef[ \t]*struct[ \t]*([{][^}]*[}][ \t]*\\*[ \t]*physadr_t;)";
+ c_fix = format;
+ c_fix_arg = "typedef struct __physadr_s %1";
+ test_text = "typedef struct __physadr_s {";
+};
+
/*
* pthread.h on AIX 4.3.3 tries to define a macro without whitspace
* which violates a requirement of ISO C.
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7509245..7e76b2f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,3594 @@
+2020-12-02 Jakub Jelinek <jakub@redhat.com>
+
+ * dwarf2out.c (add_scalar_info): Only use add_AT_wide for 128-bit
+ constants and only in dwarf-5 or later, where DW_FORM_data16 is
+ available. Otherwise use DW_FORM_block*/DW_FORM_exprloc with
+ DW_OP_implicit_value to describe the constant.
+
+2020-12-02 qing zhao <qinzhao@gcc.gnu.org>
+
+ PR rtl-optimization/97777
+ * reg-stack.c (rest_of_handle_stack_regs): call
+ df_insn_rescan_all if reg_to_stack return true.
+
+2020-12-02 Ilya Leoshkevich <iii@linux.ibm.com>
+
+ * config/s390/s390-protos.h (s390_const_int_pool_entry_p): New
+ function.
+ * config/s390/s390.c (s390_const_int_pool_entry_p): New
+ function.
+ * config/s390/s390.md: Add define_peephole2 that produces llihf
+ and oilf.
+
+2020-12-02 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97630
+ * tree-vectorizer.h (_slp_tree::next_node,
+ _slp_tree::prev_node): New.
+ (vect_slp_init): Declare.
+ (vect_slp_fini): Likewise.
+ * tree-vectorizer.c (vectorize_loops): Call vect_slp_init/fini.
+ (pass_slp_vectorize::execute): Likewise.
+ * tree-vect-slp.c (vect_slp_init): New.
+ (vect_slp_fini): Likewise.
+ (slp_first_node): New global.
+ (_slp_tree::_slp_tree): Link node into the SLP tree list.
+ (_slp_tree::~_slp_tree): Delink node from the SLP tree list.
+
+2020-12-02 Scott Snyder <sss@li-snyder.org>
+
+ PR plugins/98059
+ * vec.h (auto_delete_vec): Use
+ DISABLE_COPY_AND_ASSIGN(auto_delete_vec) instead of
+ DISABLE_COPY_AND_ASSIGN(auto_delete_vec<T>) to make it valid C++20
+ after DR2237.
+
+2020-12-02 Martin Liska <mliska@suse.cz>
+
+ PR ipa/98075
+ * cgraph.c (cgraph_node::dump): Dump decl_is_malloc flag.
+ * ipa-pure-const.c (propagate_malloc): Do not set malloc
+ attribute for void functions.
+
+2020-12-02 H.J. Lu <hjl.tools@gmail.com>
+
+ PR middle-end/93195
+ PR middle-end/93197
+ * configure.ac (HAVE_GAS_SECTION_LINK_ORDER): New. Define 1 if
+ the assembler supports the section flag 'o' for specifying
+ section with link-order.
+ * output.h (SECTION_LINK_ORDER): New. Defined to 0x8000000.
+ (SECTION_MACH_DEP): Changed from 0x8000000 to 0x10000000.
+ * targhooks.c (default_print_patchable_function_entry): Pass
+ SECTION_LINK_ORDER to switch_to_section if the section flag 'o'
+ works. Pass current_function_decl to switch_to_section.
+ * varasm.c (default_elf_asm_named_section): Use 'o' flag for
+ SECTION_LINK_ORDER if assembler supports it.
+ * config.in: Regenerated.
+ * configure: Likewise.
+ * doc/sourcebuild.texi: Document o_flag_in_section.
+
+2020-12-02 H.J. Lu <hjl.tools@gmail.com>
+
+ * config/i386/i386.opt: Add the missing '.' for -mneeded.
+
+2020-12-02 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-loop.c (vect_transform_loop_stmt): Return whether
+ we vectorized a stmt.
+ (vect_transform_loop): Only call maybe_set_vectorized_backedge_value
+ when we vectorized the stmt.
+
+2020-12-02 Jakub Jelinek <jakub@redhat.com>
+
+ * expmed.h (expand_divmod): Only declare if GCC_OPTABS_H is defined.
+ Add enum optabs_method argument defaulted to OPTAB_LIB_WIDEN.
+ * expmed.c: Include expmed.h after optabs.h.
+ (expand_divmod): Add methods argument, if it is not OPTAB_{,LIB_}WIDEN,
+ don't choose a wider mode, and pass it to other calls instead of
+ hardcoded OPTAB_LIB_WIDEN. Avoid emitting libcalls if not
+ OPTAB_LIB or OPTAB_LIB_WIDEN.
+ * optabs.c: Include expmed.h after optabs.h.
+ (expand_doubleword_mod, expand_doubleword_divmod): Pass OPTAB_DIRECT
+ as last argument to expand_divmod.
+ (expand_binop): Punt if {s,u}divmod_optab has handler for double-word
+ int_mode.
+ * expr.c: Include expmed.h after optabs.h.
+ * explow.c: Include expmed.h after optabs.h.
+
+2020-12-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/97459
+ * optabs.h (expand_doubleword_divmod): Declare.
+ * optabs.c (expand_doubleword_divmod): New function.
+ (expand_binop): Use it.
+ * internal-fn.c (expand_DIVMOD): Likewise.
+
+2020-12-02 Martin Liska <mliska@suse.cz>
+
+ PR c/98087
+ * gimple-fold.c (clear_padding_type): Do not divide by zero.
+
+2020-12-02 Martin Liska <mliska@suse.cz>
+
+ * gdbinit.in: Write what each command calls
+ for a debugging function.
+
+2020-12-02 Kewen Lin <linkw@linux.ibm.com>
+
+ * config/rs6000/rs6000.c (rs6000_option_override_internal):
+ Use OPTION_MASK_DIRECT_MOVE for Power8 target_enable instead
+ of OPTION_MASK_HTM.
+ * config/rs6000/rs6000-cpus.def (ISA_2_7_MASKS_SERVER):
+ Remove OPTION_MASK_HTM.
+ (RS6000_CPU): Add OPTION_MASK_HTM to power8, power9 and
+ powerpc64le entries.
+
+2020-12-02 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/98079
+ * config/i386/i386.md (abs<mode>2): Enable QImode
+ only for !TARGET_PARTIAL_REG_STALL.
+ (*abs<mode>2_1): Ditto.
+ (<maxmin:code><mode>3): Ditto.
+ (*<maxmin:code><mode>3_1): Ditto.
+
+2020-12-02 Martin Liska <mliska@suse.cz>
+
+ * diagnostic.c (diagnostic_report_diagnostic): ICE causes to
+ terminate compiler immediately, so I guess it should be printed
+ always.
+
+2020-12-02 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/88702
+ * gimple-if-to-switch.cc (pass_if_to_switch::execute):
+ Require at least 2 BBs.
+ * gimple-if-to-switch.cc (find_conditions): Require
+ equal precision for low and high of a range.
+
+2020-12-02 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/98084
+ * gimple-if-to-switch.cc (find_conditions): Consider only
+ integral types.
+
+2020-12-02 Jeff Law <law@redhat.com>
+
+ * config/h8300/addsub.md (addqi3_clobber_flags): Rename to
+ addqi3_flags and annotate with a <cczn> for define_subst.
+ (addhi3_h8sx_clobber_flags): Likewise.
+ (subqi3_clobber_flags, sub<mode>3_clobber_flags): Likewise.
+ (neg<mode2>_clobber_flags): Similarly.
+ (addsi3_clobber_flags): Similarly. Update last argument to
+ output_plussi to distinguish when we need flags or do not need
+ flags.
+ (addhi3_clobber_flags): Similarly. Twiddle code for cases
+ +-1, +-2 and +-4.
+ * config/h8300/h8300.md: Define iterators, mode attributes and
+ substitutions for use in compare/test elimination.
+ * config/h8300/jumpcall.md (branch, branch_1): Use H8cc mode
+ iterator to cover the different modes for the CC register.
+ (branch_1_false): Likewise.
+
+2020-12-02 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * loop-iv.c: Fix a typo, s/bu/by/, in the `iv_analyze_expr'
+ description in the introduction.
+
+2020-12-02 H.J. Lu <hjl.tools@gmail.com>
+
+ * configure.ac (HAVE_GAS_SHF_GNU_RETAIN): New. Define 1 if
+ the assembler supports marking sections with SHF_GNU_RETAIN flag.
+ * output.h (SECTION_RETAIN): New. Defined as 0x4000000.
+ (SECTION_MACH_DEP): Changed from 0x4000000 to 0x8000000.
+ (default_unique_section): Add a bool argument.
+ * varasm.c (get_section): Set SECTION_RETAIN for the preserved
+ symbol with HAVE_GAS_SHF_GNU_RETAIN.
+ (resolve_unique_section): Used named section for the preserved
+ symbol if assembler supports SHF_GNU_RETAIN.
+ (get_variable_section): Handle the preserved common symbol with
+ HAVE_GAS_SHF_GNU_RETAIN.
+ (default_elf_asm_named_section): Require the full declaration and
+ use the 'R' flag for SECTION_RETAIN.
+ * config.in: Regenerated.
+ * configure: Likewise.
+ * doc/sourcebuild.texi: Document R_flag_in_section.
+
+2020-12-02 H.J. Lu <hjl.tools@gmail.com>
+
+ * config.gcc: Replace cet.o with gnu-property.o. Replace
+ i386/t-cet with i386/t-gnu-property.
+ * config/i386/cet.c: Renamed to ...
+ * config/i386/gnu-property.c: This.
+ (emit_gnu_property): New function.
+ (file_end_indicate_exec_stack_and_cet): Renamed to ...
+ (file_end_indicate_exec_stack_and_gnu_property): This. Call
+ emit_gnu_property to generate GNU_PROPERTY_X86_FEATURE_1_AND and
+ GNU_PROPERTY_X86_ISA_1_NEEDED properties.
+ * config/i386/i386.opt (mneeded): New.
+ * config/i386/linux-common.h (file_end_indicate_exec_stack_and_cet):
+ Renamed to ...
+ (file_end_indicate_exec_stack_and_gnu_property): This.
+ (TARGET_ASM_FILE_END): Updated.
+ * config/i386/t-cet: Renamed to ...
+ * config/i386/t-gnu-property: This.
+ (cet.o): Renamed to ...
+ (gnu-property.o): This.
+ * doc/invoke.texi: Document -mneeded.
+
+2020-12-01 Eugene Rozenfeld <Eugene.Rozenfeld@microsoft.com>
+
+ PR tree-optimization/96708
+ * match.pd: New pattern for comparing X with MAX (X, Y)
+ or MIN (X, y).
+
+2020-12-01 Jeff Law <law@redhat.com>
+
+ * config/mcore/t-mcore (MULTILIB_EXCEPTIONS): Define.
+
+2020-12-01 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/97595
+ * tree.c (component_ref_size): Fail when DECL_SIZE != TYPE_SIZE.
+ * tree.h (DECL_SIZE, TYPE_SIZE): Update comment.
+
+2020-12-01 JeanHeyd Meneide <phdofthehouse@gmail.com>
+
+ * doc/cpp.texi: Document new macros.
+
+2020-12-01 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/97373
+ * builtins.c (compute_objsize): Rename...
+ (compute_objsize_r): to this. Change order and types of arguments.
+ Use new argument. Adjust calls to self.
+ (access_ref::get_ref): New member function.
+ (pointer_query::pointer_query): New member function.
+ (pointer_query::get_ref): Same.
+ (pointer_query::put_ref): Same.
+ (handle_min_max_size): Change order and types of arguments.
+ (maybe_emit_free_warning): Add a test.
+ * builtins.h (class pointer_query): New class.
+ (compute_objsize): Declare an overload.
+ * gimple-ssa-sprintf.c (get_destination_size): Add argument.
+ (handle_printf_call): Change argument type.
+ * tree-ssa-strlen.c (adjust_last_stmt): Add an argument and use it.
+ (maybe_warn_overflow): Same.
+ (handle_builtin_strcpy): Same.
+ (maybe_diag_stxncpy_trunc): Same.
+ (handle_builtin_memcpy): Change argument type. Adjust calls.
+ (handle_builtin_strcat): Same.
+ (handle_builtin_memset): Same.
+ (handle_store): Same.
+ (strlen_check_and_optimize_call): Same.
+ (check_and_optimize_stmt): Same.
+ (strlen_dom_walker): Add new data members.
+ (strlen_dom_walker::before_dom_children): Use new member.
+ (printf_strlen_execute): Dump cache performance counters. Remove
+ objsize pass cleanup.
+ * tree-ssa-strlen.h (maybe_diag_stxncpy_trunc): Add argument.
+ (handle_printf_call): Change argument type.
+
+2020-12-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * function.c (gen_call_used_regs_seq): In a function subject to the
+ leaf register optimization, skip registers that are not present.
+ * config/sparc/sparc.c (TARGET_ZERO_CALL_USED_REGS): Define to...
+ (sparc_zero_call_used_regs): ...this. New function.
+
+2020-12-01 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config/darwin.h: Remove unused 'X' specs in the link spec
+ rather than driver self-specs.
+
+2020-12-01 Nathan Sidwell <nathan@acm.org>
+
+ * params.opt (lazy-modules): New.
+ * timevar.def (TV_MODULE_IMPORT, TV_MODULE_EXPORT)
+ (TV_MODULE_MAPPER): New.
+
+2020-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/97459
+ * optabs.c (expand_doubleword_mod): Punt early for even op1.
+ (expand_binop): Don't require lshr_optab double-word handler.
+
+2020-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/97954
+ * loop-invariant.c (find_invariant_insn): Punt on JUMP_P insns.
+
+2020-12-01 Iain Sandoe <iain@sandoe.co.uk>
+
+ * configure.ac (check leb128 support): Check that assemblers both
+ accept the LEB128 directives and also give the expected output.
+ Add a test for uleb128 with the MSB set for a 64 bit value.
+ * configure: Regenerated.
+
+2020-12-01 Iain Sandoe <iain@sandoe.co.uk>
+
+ * configure: Regnerated.
+
+2020-12-01 Ilya Leoshkevich <iii@linux.ibm.com>
+
+ * optabs-tree.c (vec_cmp_icode_p): New function.
+ (vec_cmp_eq_icode_p): New function.
+ (expand_vec_cmp_expr_p): Use vec_cmp_icode_p and
+ vec_cmp_eq_icode_p.
+ (vcond_icode_p): Use get_rtx_code_1, just to be uniform with
+ vec_cmp_icode_p.
+ * optabs.c (unsigned_optab_p): New function.
+ (insn_predicate_matches_p): New function.
+ (can_vec_cmp_compare_p): New function.
+ (can_vcond_compare_p): Use unsigned_optab_p and
+ insn_predicate_matches_p.
+ (get_rtx_code): Use get_rtx_code_1.
+ (get_rtx_code_1): Version of get_rtx_code that returns UNKNOWN
+ instead of asserting.
+ * optabs.h (can_vec_cmp_compare_p): New function.
+ (get_rtx_code_1): New function.
+
+2020-12-01 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/14799
+ PR ipa/88702
+ * Makefile.in: Add gimple-if-to-switch.o.
+ * dbgcnt.def (DEBUG_COUNTER): Add new debug counter.
+ * passes.def: Include new pass_if_to_switch pass.
+ * timevar.def (TV_TREE_IF_TO_SWITCH): New timevar.
+ * tree-pass.h (make_pass_if_to_switch): New.
+ * tree-ssa-reassoc.c (struct operand_entry): Move to the header.
+ (dump_range_entry): Move to header file.
+ (debug_range_entry): Likewise.
+ (no_side_effect_bb): Make it global.
+ * tree-switch-conversion.h (simple_cluster::simple_cluster):
+ Add inline for couple of functions in order to prevent error
+ about multiple defined symbols.
+ * gimple-if-to-switch.cc: New file.
+ * tree-ssa-reassoc.h: New file.
+
+2020-12-01 Marius Hillenbrand <mhillen@linux.ibm.com>
+
+ * configure.ac: Add configure option
+ --enable-s390-excess-float-precision and check to derive default
+ from glibc.
+ * config/s390/s390.c: Guard s390_excess_precision with an ifdef
+ for ENABLE_S390_EXCESS_FLOAT_PRECISION.
+ * doc/install.texi: Document --enable-s390-excess-float-precision.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+
+2020-12-01 Martin Liska <mliska@suse.cz>
+
+ PR ipa/98057
+ * symtab.c (symtab_node::set_section_for_node): Drop
+ implicit_section if x_section is NULL.
+
+2020-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/98063
+ * config/i386/i386-expand.c (ix86_expand_call): Handle non-plt
+ CM_LARGE_PIC calls.
+
+2020-12-01 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/98070
+ * builtins.c (builtin_fnspec): realloc is ".Cw ".
+
+2020-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ * dwarf2out.c (gen_compile_unit_die): Treat GNU C++20
+ like C++14 for -gdwarf-5.
+
+2020-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/97989
+ * gcc.c (cpp_unique_options): Add -dD if %:debug-level-gt(2)
+ rather than g3|ggdb3|gstabs3|gxcoff3|gvms3.
+
+2020-12-01 Kito Cheng <kito.cheng@sifive.com>
+
+ * config.gcc (riscv*-*-*): Drop some commited accidentally code.
+
+2020-11-30 Jeff Law <law@redhat.com>
+
+ * symtab.c (set_section_for_node): Add function comment.
+ (set_section_from_node): Likewise.
+
+2020-11-30 David Malcolm <dmalcolm@redhat.com>
+
+ * doc/plugins.texi (Plugin callbacks): Add PLUGIN_ANALYZER_INIT.
+ * plugin.c (register_callback): Likewise.
+ (invoke_plugin_callbacks_full): Likewise.
+ * plugin.def (PLUGIN_ANALYZER_INIT): New event.
+
+2020-11-30 Jeff Law <law@redhat.com>
+
+ * config/h8300/bitfield.md: Remove "cc" attribute on any
+ insns where it remained.
+ * config/h8300/combiner.md: Likewise.
+ * config/h8300/jumpcall.md: Likewise.
+ * config/h8300/logical.md: Likewise.
+ * config/h8300/testcompare.md: Likewise.
+ * config/h8300/h8300.md (old_cc attr): Renamed from cc attr.
+ * config/h8300/h8300.c (notice_update_cc): Remove.
+ (compute_plussi_cc): Change references to CC_* to OLD_CC_.
+ (compute_logical_op_cc): Likewise.
+ (shift_one, shift_two): Likewise.
+ (compute_a_shift_cc): Likewise.
+ (get_shift_alg): Likewise.
+ (struct shift_insn): Change type of cc_valid field.
+ (struct shift_info): Likewise.
+ * config/h8300/save.md: Remove accidentially created file.
+
+2020-11-30 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR rtl-optimization/98037
+ * dse.c (find_shift_sequence): Iterate over all integers and
+ skip modes that are too small.
+
+2020-11-30 Eugene Rozenfeld <Eugene.Rozenfeld@microsoft.com>
+
+ PR tree-optimization/96679
+ * match.pd (((b | c) & a) | b -> (a & c) | b): New pattern.
+
+2020-11-30 Martin Liska <mliska@suse.cz>
+
+ * passes.c (emergency_dump_function): Dump symtab when
+ we are in an IPA pass.
+
+2020-11-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/98064
+ * tree-vect-loop.c (vectorizable_live_operation): Avoid
+ breaking LC SSA for BB vectorization.
+
+2020-11-30 Jonathan Wakely <jwakely@redhat.com>
+
+ * doc/sourcebuild.texi (Directives): Fix description of
+ dg-require-effective-target to include "target" in selector.
+
+2020-11-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/98048
+ * tree-vect-generic.c (expand_vector_operations_1): Use the
+ correct type for the scalar LHS replacement.
+
+2020-11-30 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/98066
+ * gimple-isel.cc (gimple_expand_vec_exprs): Return when
+ gimple_expand_vec_exprs replaces last stmt.
+
+2020-11-30 Ilya Leoshkevich <iii@linux.ibm.com>
+
+ * cfgrtl.c (rtl_bb_info_initialized_p): New function.
+ (rtl_dump_bb): Use rtl_bb_info_initialized_p before accessing bb
+ insns.
+
+2020-11-30 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/87818
+ * config.gcc (*-*-freebsd*): Add freebsd-d.o and t-freebsd.
+ * config/freebsd-d.c: New file.
+ * config/t-freebsd: New file.
+
+2020-11-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/97459
+ * internal-fn.h (expand_addsub_overflow): Declare.
+ * internal-fn.c (expand_addsub_overflow): No longer static.
+ * optabs.c (expand_doubleword_mod): New function.
+ (expand_binop): Optimize double-word mod with constant divisor.
+
+2020-11-30 Kito Cheng <kito.cheng@sifive.com>
+
+ * config.gcc (riscv*-*-*): Add TARGET_RISCV_DEFAULT_ABI and
+ TARGET_RISCV_DEFAULT_ARCH to tm_defines.
+ Remove including riscv/withmultilib.h for --with-multilib-list.
+ * config/riscv/riscv.h (STRINGIZING): New.
+ (__STRINGIZING): Ditto.
+ (MULTILIB_DEFAULTS): Ditto.
+ * config/riscv/withmultilib.h: Remove.
+
+2020-11-30 Kito Cheng <kito.cheng@sifive.com>
+
+ * gcc.c (print_multilib_info): Check default arguments not
+ appeared in multi-lib option list with '!'
+
+2020-11-30 Jeff Law <law@redhat.com>
+
+ * config/ft32/ft32.md (umulsidi3): Do not allow constants as
+ arguments.
+
+2020-11-29 Jan Hubicka <jh@suse.cz>
+
+ * ipa-modref.c (ipa_merge_modref_summary_after_inlining): Fix
+ handling of ignore_stores.
+
+2020-11-29 Jan Hubicka <jh@suse.cz>
+
+ PR jit/97867
+ * symtab-thunks.h (thunk_info::release): Use ggc_delete.
+
+2020-11-29 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/92936
+ PR middle-end/92940
+ PR middle-end/89428
+ * builtins.c (access_ref::access_ref): Initialize member.
+ (access_ref::phi): New function.
+ (access_ref::get_ref): New function.
+ (access_ref::add_offset): Remove duplicate assignment.
+ (maybe_warn_for_bound): Add "maybe" kind of warning messages.
+ (warn_for_access): Same.
+ (inform_access): Rename...
+ (access_ref::inform_access): ...to this. Print PHI arguments. Format
+ offset the same as size and simplify. Improve printing of allocation
+ functions and VLAs.
+ (check_access): Adjust to the above.
+ (gimple_parm_array_size): Change argument.
+ (handle_min_max_size): New function.
+ * builtins.h (class ssa_name_limit_t): Move class here from
+ tree-ssa-strlen.c.
+ (struct access_ref): Declare new members.
+ (gimple_parm_array_size): Change argument.
+ * tree-ssa-strlen.c (maybe_warn_overflow): Use access_ref and simplify.
+ (handle_builtin_memcpy): Correct argument passed to maybe_warn_overflow.
+ (handle_builtin_memset): Same.
+ (class ssa_name_limit_t): Move class to builtins.{h,c}.
+
+2020-11-29 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * config.gcc (*-*-darwin*): Set d_target_objs and target_has_targetdm.
+ * config/elfos.h (TARGET_D_MINFO_SECTION): New macro.
+ (TARGET_D_MINFO_START_NAME): New macro.
+ (TARGET_D_MINFO_END_NAME): New macro.
+ * config/t-darwin: Add darwin-d.o.
+ * doc/tm.texi: Regenerate.
+ * doc/tm.texi.in (D language and ABI): Add @hook for
+ TARGET_D_MINFO_SECTION, TARGET_D_MINFO_START_NAME, and
+ TARGET_D_MINFO_END_NAME.
+ * config/darwin-d.c: New file.
+
+2020-11-29 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa-structalias.c (handle_pure_call): Skip EAF_UNUSED
+ parameters.
+
+2020-11-29 Jan Hubicka <jh@suse.cz>
+
+ * ipa-modref.c (modref_lattice::merge): Do nothing if F is EAF_UNUSED.
+ (analyze_parms): Detect unused params.
+ (modref_merge_call_site_flags): Merge correct EAF_UNUSED.
+
+2020-11-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR target/97939
+ * config/sparc/predicates.md (arith_double_add_operand): Comment.
+ * config/sparc/sparc.md (uaddvdi4): Use arith_double_operand.
+ (addvdi4): Use arith_double_add_operand.
+ (addsi3): Remove useless attributes.
+ (addvsi4): Use arith_add_operand.
+ (*cmp_ccv_plus): Likewise and add second alternative accordingly.
+ (*cmp_ccxv_plus): Likewise.
+ (*cmp_ccv_plus_set): Likewise.
+ (*cmp_ccxv_plus_set): Likewise.
+ (*cmp_ccv_plus_sltu_set): Likewise.
+ (usubvdi4): Use arith_double_operand.
+ (subvdi4): Use arith_double_add_operand.
+ (subsi3): Remove useless attributes.
+ (subvsi4): Use arith_add_operand.
+ (*cmp_ccv_minus): Likewise and add second alternative accordingly.
+ (*cmp_ccxv_minus): Likewise.
+ (*cmp_ccv_minus_set): Likewise.
+ (*cmp_ccxv_minus_set): Likewise.
+ (*cmp_ccv_minus_sltu_set): Likewise.
+ (negsi2): Use register_operand.
+ (unegvsi3): Likewise.
+ (negvsi3) Likewise.
+ (*cmp_ccnz_neg): Likewise.
+ (*cmp_ccxnz_neg): Likewise.
+ (*cmp_ccnz_neg_set): Likewise.
+ (*cmp_ccxnz_neg_set): Likewise.
+ (*cmp_ccc_neg_set): Likewise.
+ (*cmp_ccxc_neg_set): Likewise.
+ (*cmp_ccc_neg_sltu_set): Likewise.
+ (*cmp_ccv_neg): Likewise.
+ (*cmp_ccxv_neg): Likewise.
+ (*cmp_ccv_neg_set): Likewise.
+ (*cmp_ccxv_neg_set): Likewise.
+ (*cmp_ccv_neg_sltu_set): Likewise.
+
+2020-11-27 H.J. Lu <hjl.tools@gmail.com>
+
+ PR other/98027
+ * doc/install.texi: Default to --enable-cet=auto.
+
+2020-11-27 Thomas Schwinge <thomas@codesourcery.com>
+
+ * omp-oacc-kernels-decompose.cc (flatten_binds): Don't choke on
+ empty GIMPLE sequence, and examine all statements contained in
+ inner 'GIMPLE_BIND'.
+
+2020-11-27 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/98024
+ * tree-ssa-pre.c (insert): Fix successor RPO order check.
+ (do_pre_regular_insertion): When inserting an assignment
+ in place of an all-same-value PHI still record that into
+ PHI_GEN.
+
+2020-11-27 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-ssanames.c (get_range_info): Handle INTEGER_CST by returning
+ VR_RANGE with both *min and *max set to the wide_int value of the
+ INTEGER_CST. Return VR_VARYING for non-SSA_NAMEs.
+ * match.pd ((t * 2) / 2) -> t): Handle also @0 being INTEGER_CST.
+ Simplify by calling get_range_info on everything.
+ * tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Simplify by calling
+ get_range_info on everything.
+ * tree-scalar-evolution.c (iv_can_overflow_p): Likewise.
+
+2020-11-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR libstdc++/88101
+ * gimple-fold.c (clear_padding_type): Ignore fields with is_empty_type
+ types.
+
+2020-11-27 Tobias Burnus <tobias@codesourcery.com>
+
+ PR c/97880
+ * omp-expand.c (expand_oacc_collapse_init, expand_oacc_collapse_vars):
+ Use now passed diff_type.
+ (expand_oacc_for): Take largest type for diff_type, taking tiling
+ and collapsing into account.
+
+2020-11-27 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/aarch64.opt
+ (-param=aarch64-autovec-preference): Define.
+ * config/aarch64/aarch64.c (aarch64_override_options_internal):
+ Set aarch64_sve_compare_costs to 0 when preferring only Advanced
+ SIMD.
+ (aarch64_cmp_autovec_modes): Define.
+ (aarch64_preferred_simd_mode): Adjust to use the above.
+ (aarch64_autovectorize_vector_modes): Likewise.
+ * doc/invoke.texi: Document aarch64-autovec-preference param.
+
+2020-11-27 Xionghu Luo <luoxhu@linux.ibm.com>
+
+ * config/rs6000/rs6000-call.c (altivec_expand_vec_set_builtin):
+ Change call param 2 from type int to rtx.
+ * config/rs6000/rs6000-protos.h (rs6000_expand_vector_set):
+ Likewise.
+ * config/rs6000/rs6000.c (rs6000_expand_vector_init):
+ Change call param 2 from type int to rtx.
+ (rs6000_expand_vector_set): Likewise.
+ * config/rs6000/vector.md (vec_set<mode>): Support both constant
+ and variable index vec_set.
+
+2020-11-27 Haochen Gui <guihaoc@gcc.gnu.org>
+
+ * config/rs6000/rs6000-protos.h (rs6000_output_addr_vec_elt): Declare.
+ * config/rs6000/rs6000.c (TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC):
+ Define.
+ (rs6000_gen_pic_addr_diff_vec, rs6000_output_addr_vec_elt): Implement.
+ * config/rs6000/rs6000.h (CASE_VECTOR_PC_RELATIVE,
+ CASE_VECTOR_MODE, ASM_OUTPUT_ADDR_VEC_ELT): Define.
+ * config/rs6000/rs6000.md (tablejump<mode>_absolute,
+ tablejump<mode>_absolute_nospec): New expanders.
+ * config/rs6000/rs6000.opt (mrelative-jumptables): New.
+
+2020-11-26 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR target/96607
+ * config/sparc/sparc-protos.h (eligible_for_call_delay): Delete.
+ * config/sparc/sparc.c (eligible_for_call_delay): Likewise.
+ * config/sparc/sparc.md (in_call_delay): Likewise.
+ (tls_delay_slot): New attribute.
+ (define_delay [call]): Use in_branch_delay.
+ (tgd_call<P:mode>): Set type to call_no_delay_slot when
+ tls_delay_slot is false.
+ (tldm_call<P:mode>): Likewise.
+
+2020-11-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/97997
+ * match.pd ((t * 2) / 2) -> t): Optimize even for defined
+ overflow if ranges prove there is no overflow.
+
+2020-11-26 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97953
+ * gimple-ssa-evrp-analyze.c
+ (evrp_range_analyzer::record_ranges_from_incoming_edge): Make
+ sure the condition post-dominates the SSA definition before
+ recording into SSA_NAME_RANGE_INFO.
+
+2020-11-26 Richard Biener <rguenther@suse.de>
+
+ * gimple-isel.cc (gimple_expand_vec_cond_expr): Only
+ lower VECTOR_BOOLEAN_TYPE_P VEC_COND_EXPRs.
+
+2020-11-26 Andrew Stubbs <ams@codesourcery.com>
+
+ * config/gcn/mkoffload.c (copy_early_debug_info): Don't wipe
+ relocation symbols.
+
+2020-11-26 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386-expand.c (ix86_expand_multi_arg_builtin):
+ Remove args array of structs, declare rtx xops array instead.
+ Update all uses.
+ (ix86_expand_args_builtin): Ditto.
+ (ix86_expand_round_builtin): Ditto.
+ (ix86_expand_special_args_builtin): Ditto.
+
+2020-11-26 Martin Liska <mliska@suse.cz>
+
+ * dwarf2out.c (gen_compile_unit_die): Fix missing == 0 in a
+ strcmp.
+
+2020-11-26 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * config/sol2.h (TIME_LIBRARY): Remove.
+
+2020-11-26 Kewen Lin <linkw@linux.ibm.com>
+
+ * config/rs6000/rs6000.c (rs6000_option_override_internal):
+ Set param_vect_partial_vector_usage as 1 for Power10 and up
+ by default.
+
+2020-11-26 Jakub Jelinek <jakub@redhat.com>
+
+ * gimple-fold.c (clear_padding_union): Ignore DECL_PADDING_P
+ fields.
+ (clear_padding_type): Ignore DECL_PADDING_P fields, rather than
+ DECL_BIT_FIELD with NULL DECL_NAME.
+
+2020-11-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/97979
+ * match.pd ((X {&,^,|} C2) << C1 into (X << C1) {&,^,|} (C2 << C1)):
+ Only optimize if int_const_binop returned non-NULL.
+
+2020-11-26 liuhongt <hongtao.liu@intel.com>
+
+ * config/i386/i386-expand.c
+ (ix86_expand_special_args_builtin): Delete last_arg_constant
+ and match.
+
+2020-11-26 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/97873
+ * config/i386/i386.md (abs<mode>2): Use SDWIM mode iterator.
+ (*abs<mode>2_1): Use SWI mode iterator.
+ (<maxmin:code><mode>3): Use SDWIM mode iterator.
+ (*<maxmin:code><mode>3_1): Use SWI mode iterator.
+
+2020-11-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/96906
+ * config/i386/sse.md (VI12_AVX2): Remove V64QI/V32HI modes.
+ (VI12_AVX2_AVX512BW): New mode iterator.
+ (<sse2_avx2>_<plusminus_insn><mode>3<mask_name>,
+ uavg<mode>3_ceil, <sse2_avx2>_uavg<mode>3<mask_name>): Use
+ VI12_AVX2_AVX512BW iterator instead of VI12_AVX2.
+ (*<sse2_avx2>_<plusminus_insn><mode>3<mask_name>): Likewise.
+ (*<sse2_avx2>_uavg<mode>3<mask_name>): Likewise.
+ (*<sse2_avx2>_<plusminus_insn><mode>3<mask_name>): Add a new
+ define_split after this insn.
+
+2020-11-26 Martin Uecker <muecker@gwdg.de>
+
+ PR c/65455
+ PR c/92935
+ * ginclude/stdatomic.h: Use comma operator to drop qualifiers.
+
+2020-11-26 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR bootstrap/97983
+ * lra.c (lra_process_new_insns): Use emit_insn_before_noloc or
+ emit_insn_after_noloc with the destination BB.
+
+2020-11-25 Martin Sebor <msebor@redhat.com>
+
+ PR bootstrap/97622
+ PR bootstrap/94982
+ * config/i386/i386-options.c (ix86_valid_target_attribute_inner_p):
+ Avoid -Wformat-diag.
+ * digraph.cc (struct test_edge): Same.
+ * dumpfile.c (dump_loc): Same.
+ (dump_context::begin_scope): Same.
+ * edit-context.c (edited_file::print_diff): Same.
+ (edited_file::print_diff_hunk): Same.
+ * json.cc (object::print): Same.
+ * lto-wrapper.c (merge_and_complain): Same.
+ * reload.c (find_reloads): Same.
+ * tree-diagnostic-path.cc (print_path_summary_as_text): Same.
+ * ubsan.c (ubsan_type_descriptor): Same.
+
+2020-11-25 Jan Hubicka <jh@suse.cz>
+
+ * gimple.c (gimple_call_arg_flags): Also imply EAF_NODIRECTESCAPE.
+ * tree-core.h (EAF_NODRECTESCAPE): New flag.
+ * tree-ssa-structalias.c (make_indirect_escape_constraint): New
+ function.
+ (handle_rhs_call): Hanlde EAF_NODIRECTESCAPE.
+ * ipa-modref.c (dump_eaf_flags): Print EAF_NODIRECTESCAPE.
+ (deref_flags): Dereference is always EAF_NODIRECTESCAPE.
+ (modref_lattice::init): Also set EAF_NODIRECTESCAPE.
+ (analyze_ssa_name_flags): Pure functions do not affect
+ EAF_NODIRECTESCAPE.
+ (analyze_params): Likewise.
+ (ipa_merge_modref_summary_after_inlining): Likewise.
+ (modref_merge_call_site_flags): Likewise.
+
+2020-11-25 Jan Hubicka <jh@suse.cz>
+
+ * ipa-modref.c (modref_summaries::duplicate,
+ modref_summaries_lto::duplicate): Copy arg_flags.
+ (remap_arg_flags): Fix remapping of arg_flags.
+
+2020-11-25 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/97956
+ * gimple-fold.c (gimple_fold_builtin_memchr): Use sizetype for pointer
+ offsets.
+
+2020-11-25 Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * asan.c (asan_instrument_reads): New.
+ (asan_instrument_writes): New.
+ (asan_memintrin): New.
+ (handle_builtin_stack_restore): Account for HWASAN.
+ (handle_builtin_alloca): Account for HWASAN.
+ (get_mem_refs_of_builtin_call): Special case strlen for HWASAN.
+ (hwasan_instrument_reads): New.
+ (hwasan_instrument_writes): New.
+ (hwasan_memintrin): New.
+ (report_error_func): Assert not HWASAN.
+ (build_check_stmt): Make HWASAN_CHECK instead of ASAN_CHECK.
+ (instrument_derefs): HWASAN does not tag globals.
+ (instrument_builtin_call): Use new helper functions.
+ (maybe_instrument_call): Don't instrument `noreturn` functions.
+ (initialize_sanitizer_builtins): Add new type.
+ (asan_expand_mark_ifn): Account for HWASAN.
+ (asan_expand_check_ifn): Assert never called by HWASAN.
+ (asan_expand_poison_ifn): Account for HWASAN.
+ (asan_instrument): Branch based on whether using HWASAN or ASAN.
+ (pass_asan::gate): Return true if sanitizing HWASAN.
+ (pass_asan_O0::gate): Return true if sanitizing HWASAN.
+ (hwasan_check_func): New.
+ (hwasan_expand_check_ifn): New.
+ (hwasan_expand_mark_ifn): New.
+ (gate_hwasan): New.
+ * asan.h (hwasan_expand_check_ifn): New decl.
+ (hwasan_expand_mark_ifn): New decl.
+ (gate_hwasan): New decl.
+ (asan_intercepted_p): Always false for hwasan.
+ (asan_sanitize_use_after_scope): Account for HWASAN.
+ * builtin-types.def (BT_FN_PTR_CONST_PTR_UINT8): New.
+ * gimple-fold.c (gimple_build): New overload for building function
+ calls without arguments.
+ (gimple_build_round_up): New.
+ * gimple-fold.h (gimple_build): New decl.
+ (gimple_build): New inline function.
+ (gimple_build_round_up): New decl.
+ (gimple_build_round_up): New inline function.
+ * gimple-pretty-print.c (dump_gimple_call_args): Account for
+ HWASAN.
+ * gimplify.c (asan_poison_variable): Account for HWASAN.
+ (gimplify_function_tree): Remove requirement of
+ SANITIZE_ADDRESS, requiring asan or hwasan is accounted for in
+ `asan_sanitize_use_after_scope`.
+ * internal-fn.c (expand_HWASAN_CHECK): New.
+ (expand_HWASAN_ALLOCA_UNPOISON): New.
+ (expand_HWASAN_CHOOSE_TAG): New.
+ (expand_HWASAN_MARK): New.
+ (expand_HWASAN_SET_TAG): New.
+ * internal-fn.def (HWASAN_ALLOCA_UNPOISON): New.
+ (HWASAN_CHOOSE_TAG): New.
+ (HWASAN_CHECK): New.
+ (HWASAN_MARK): New.
+ (HWASAN_SET_TAG): New.
+ * sanitizer.def (BUILT_IN_HWASAN_LOAD1): New.
+ (BUILT_IN_HWASAN_LOAD2): New.
+ (BUILT_IN_HWASAN_LOAD4): New.
+ (BUILT_IN_HWASAN_LOAD8): New.
+ (BUILT_IN_HWASAN_LOAD16): New.
+ (BUILT_IN_HWASAN_LOADN): New.
+ (BUILT_IN_HWASAN_STORE1): New.
+ (BUILT_IN_HWASAN_STORE2): New.
+ (BUILT_IN_HWASAN_STORE4): New.
+ (BUILT_IN_HWASAN_STORE8): New.
+ (BUILT_IN_HWASAN_STORE16): New.
+ (BUILT_IN_HWASAN_STOREN): New.
+ (BUILT_IN_HWASAN_LOAD1_NOABORT): New.
+ (BUILT_IN_HWASAN_LOAD2_NOABORT): New.
+ (BUILT_IN_HWASAN_LOAD4_NOABORT): New.
+ (BUILT_IN_HWASAN_LOAD8_NOABORT): New.
+ (BUILT_IN_HWASAN_LOAD16_NOABORT): New.
+ (BUILT_IN_HWASAN_LOADN_NOABORT): New.
+ (BUILT_IN_HWASAN_STORE1_NOABORT): New.
+ (BUILT_IN_HWASAN_STORE2_NOABORT): New.
+ (BUILT_IN_HWASAN_STORE4_NOABORT): New.
+ (BUILT_IN_HWASAN_STORE8_NOABORT): New.
+ (BUILT_IN_HWASAN_STORE16_NOABORT): New.
+ (BUILT_IN_HWASAN_STOREN_NOABORT): New.
+ (BUILT_IN_HWASAN_TAG_MISMATCH4): New.
+ (BUILT_IN_HWASAN_HANDLE_LONGJMP): New.
+ (BUILT_IN_HWASAN_TAG_PTR): New.
+ * sanopt.c (sanopt_optimize_walker): Act for hwasan.
+ (pass_sanopt::execute): Act for hwasan.
+ * toplev.c (compile_file): Use `gate_hwasan` function.
+
+2020-11-25 Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * asan.c (struct hwasan_stack_var): New.
+ (hwasan_sanitize_p): New.
+ (hwasan_sanitize_stack_p): New.
+ (hwasan_sanitize_allocas_p): New.
+ (initialize_sanitizer_builtins): Define new builtins.
+ (ATTR_NOTHROW_LIST): New macro.
+ (hwasan_current_frame_tag): New.
+ (hwasan_frame_base): New.
+ (stack_vars_base_reg_p): New.
+ (hwasan_maybe_init_frame_base_init): New.
+ (hwasan_record_stack_var): New.
+ (hwasan_get_frame_extent): New.
+ (hwasan_increment_frame_tag): New.
+ (hwasan_record_frame_init): New.
+ (hwasan_emit_prologue): New.
+ (hwasan_emit_untag_frame): New.
+ (hwasan_finish_file): New.
+ (hwasan_truncate_to_tag_size): New.
+ * asan.h (hwasan_record_frame_init): New declaration.
+ (hwasan_record_stack_var): New declaration.
+ (hwasan_emit_prologue): New declaration.
+ (hwasan_emit_untag_frame): New declaration.
+ (hwasan_get_frame_extent): New declaration.
+ (hwasan_maybe_enit_frame_base_init): New declaration.
+ (hwasan_frame_base): New declaration.
+ (stack_vars_base_reg_p): New declaration.
+ (hwasan_current_frame_tag): New declaration.
+ (hwasan_increment_frame_tag): New declaration.
+ (hwasan_truncate_to_tag_size): New declaration.
+ (hwasan_finish_file): New declaration.
+ (hwasan_sanitize_p): New declaration.
+ (hwasan_sanitize_stack_p): New declaration.
+ (hwasan_sanitize_allocas_p): New declaration.
+ (HWASAN_TAG_SIZE): New macro.
+ (HWASAN_TAG_GRANULE_SIZE): New macro.
+ (HWASAN_STACK_BACKGROUND): New macro.
+ * builtin-types.def (BT_FN_VOID_PTR_UINT8_PTRMODE): New.
+ * builtins.def (DEF_SANITIZER_BUILTIN): Enable for HWASAN.
+ * cfgexpand.c (align_local_variable): When using hwasan ensure
+ alignment to tag granule.
+ (align_frame_offset): New.
+ (expand_one_stack_var_at): For hwasan use tag offset.
+ (expand_stack_vars): Record stack objects for hwasan.
+ (expand_one_stack_var_1): Record stack objects for hwasan.
+ (init_vars_expansion): Initialise hwasan state.
+ (expand_used_vars): Emit hwasan prologue and generate hwasan epilogue.
+ (pass_expand::execute): Emit hwasan base initialization if needed.
+ * doc/tm.texi (TARGET_MEMTAG_TAG_SIZE,TARGET_MEMTAG_GRANULE_SIZE,
+ TARGET_MEMTAG_INSERT_RANDOM_TAG,TARGET_MEMTAG_ADD_TAG,
+ TARGET_MEMTAG_SET_TAG,TARGET_MEMTAG_EXTRACT_TAG,
+ TARGET_MEMTAG_UNTAGGED_POINTER): Document new hooks.
+ * doc/tm.texi.in (TARGET_MEMTAG_TAG_SIZE,TARGET_MEMTAG_GRANULE_SIZE,
+ TARGET_MEMTAG_INSERT_RANDOM_TAG,TARGET_MEMTAG_ADD_TAG,
+ TARGET_MEMTAG_SET_TAG,TARGET_MEMTAG_EXTRACT_TAG,
+ TARGET_MEMTAG_UNTAGGED_POINTER): Document new hooks.
+ * explow.c (get_dynamic_stack_base): Take new `base` argument.
+ * explow.h (get_dynamic_stack_base): Take new `base` argument.
+ * sanitizer.def (BUILT_IN_HWASAN_INIT): New.
+ (BUILT_IN_HWASAN_TAG_MEM): New.
+ * target.def (target_memtag_tag_size,target_memtag_granule_size,
+ target_memtag_insert_random_tag,target_memtag_add_tag,
+ target_memtag_set_tag,target_memtag_extract_tag,
+ target_memtag_untagged_pointer): New hooks.
+ * targhooks.c (HWASAN_SHIFT): New.
+ (HWASAN_SHIFT_RTX): New.
+ (default_memtag_tag_size): New default hook.
+ (default_memtag_granule_size): New default hook.
+ (default_memtag_insert_random_tag): New default hook.
+ (default_memtag_add_tag): New default hook.
+ (default_memtag_set_tag): New default hook.
+ (default_memtag_extract_tag): New default hook.
+ (default_memtag_untagged_pointer): New default hook.
+ * targhooks.h (default_memtag_tag_size): New default hook.
+ (default_memtag_granule_size): New default hook.
+ (default_memtag_insert_random_tag): New default hook.
+ (default_memtag_add_tag): New default hook.
+ (default_memtag_set_tag): New default hook.
+ (default_memtag_extract_tag): New default hook.
+ (default_memtag_untagged_pointer): New default hook.
+ * toplev.c (compile_file): Call hwasan_finish_file when finished.
+
+2020-11-25 Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * common.opt (flag_sanitize_recover): Default for kernel
+ hwaddress.
+ (static-libhwasan): New cli option.
+ * config/aarch64/aarch64.c (aarch64_can_tag_addresses): New.
+ (TARGET_MEMTAG_CAN_TAG_ADDRESSES): New.
+ * config/gnu-user.h (LIBHWASAN_EARLY_SPEC): hwasan equivalent of
+ asan command line flags.
+ * cppbuiltin.c (define_builtin_macros_for_compilation_flags):
+ Add hwasan equivalent of __SANITIZE_ADDRESS__.
+ * doc/invoke.texi: Document hwasan command line flags.
+ * doc/tm.texi: Document new hook.
+ * doc/tm.texi.in: Document new hook.
+ * flag-types.h (enum sanitize_code): New sanitizer values.
+ * gcc.c (STATIC_LIBHWASAN_LIBS): New macro.
+ (LIBHWASAN_SPEC): New macro.
+ (LIBHWASAN_EARLY_SPEC): New macro.
+ (SANITIZER_EARLY_SPEC): Update to include hwasan.
+ (SANITIZER_SPEC): Update to include hwasan.
+ (sanitize_spec_function): Use hwasan options.
+ * opts.c (finish_options): Describe conflicts between address
+ sanitizers.
+ (find_sanitizer_argument): New.
+ (report_conflicting_sanitizer_options): New.
+ (sanitizer_opts): Introduce new sanitizer flags.
+ (common_handle_option): Add defaults for kernel sanitizer.
+ * params.opt (hwasan--instrument-stack): New
+ (hwasan-random-frame-tag): New
+ (hwasan-instrument-allocas): New
+ (hwasan-instrument-reads): New
+ (hwasan-instrument-writes): New
+ (hwasan-instrument-mem-intrinsics): New
+ * target.def (HOOK_PREFIX): Add new hook.
+ (can_tag_addresses): Add new hook under memtag prefix.
+ * targhooks.c (default_memtag_can_tag_addresses): New.
+ * targhooks.h (default_memtag_can_tag_addresses): New decl.
+ * toplev.c (process_options): Ensure hwasan only on
+ architectures that advertise the possibility.
+
+2020-11-25 Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * doc/install.texi: Document new option.
+
+2020-11-25 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_maybe_expand_sve_subreg_move):
+ Do not optimize LRA subregs.
+ * config/aarch64/aarch64-sve.md
+ (@aarch64_pred_<SVE_INT_UNARY:optab><mode>): Tie the input to the
+ output.
+ (@aarch64_sve_revbhw_<SVE_ALL:mode><PRED_HSD:mode>): Likewise.
+ (*<ANY_EXTEND:optab><SVE_PARTIAL_I:mode><SVE_HSDI:mode>2): Likewise.
+ (@aarch64_pred_sxt<SVE_FULL_HSDI:mode><SVE_PARTIAL_I:mode>): Likewise.
+ (*cnot<mode>): Likewise.
+ (@aarch64_pred_<SVE_COND_FP_UNARY:optab><mode>): Likewise.
+ (@aarch64_sve_<optab>_nontrunc<SVE_FULL_F:mode><SVE_FULL_HSDI:mode>):
+ Likewise.
+ (@aarch64_sve_<optab>_trunc<VNx2DF_ONLY:mode><VNx4SI_ONLY:mode>):
+ Likewise.
+ (@aarch64_sve_<optab>_nonextend<SVE_FULL_HSDI:mode><SVE_FULL_F:mode>):
+ Likewise.
+ (@aarch64_sve_<optab>_extend<VNx4SI_ONLY:mode><VNx2DF_ONLY:mode>):
+ Likewise.
+ (@aarch64_sve_<optab>_trunc<SVE_FULL_SDF:mode><SVE_FULL_HSF:mode>):
+ Likewise.
+ (@aarch64_sve_<optab>_trunc<VNx4SF_ONLY:mode><VNx8BF_ONLY:mode>):
+ Likewise.
+ (@aarch64_sve_<optab>_nontrunc<SVE_FULL_HSF:mode><SVE_FULL_SDF:mode>):
+ Likewise.
+ * config/aarch64/aarch64-sve2.md
+ (@aarch64_pred_<SVE2_COND_FP_UNARY_LONG:sve_fp_op><mode>): Likewise.
+ (@aarch64_pred_<SVE2_COND_FP_UNARY_NARROWB:sve_fp_op><mode>): Likewise.
+ (@aarch64_pred_<SVE2_U32_UNARY:sve_int_op><mode>): Likewise.
+ (@aarch64_pred_<SVE2_COND_INT_UNARY_FP:sve_fp_op><mode>): Likewise.
+
+2020-11-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/95862
+ * internal-fn.c (get_min_precision): For narrowing conversion, recurse
+ on the operand and if the operand precision is smaller than the
+ current one, return that smaller precision.
+ (expand_mul_overflow): For s1 * u2 -> ur and s1 * s2 -> ur cases
+ if the sum of minimum precisions of both operands is smaller or equal
+ to the result precision, just perform normal multiplication and
+ set overflow to the sign bit of the multiplication result. For
+ u1 * u2 -> sr if both arguments have the MSB known zero, use
+ normal s1 * s2 -> sr expansion.
+
+2020-11-25 Jan Hubicka <jh@suse.cz>
+
+ * cfg.c (free_block): New function.
+ (clear_edges): Rename to ....
+ (free_cfg): ... this one; also free BBs and vectors.
+ (expunge_block): Update comment.
+ * cfg.h (clear_edges): Rename to ...
+ (free_cfg): ... this one.
+ * cgraph.c (release_function_body): Use free_cfg.
+
+2020-11-25 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/97579
+ * gimple-isel.cc (gimple_expand_vec_cond_expr): Lower
+ VECTOR_BOOLEAN_TYPE_P, non-vector mode VEC_COND_EXPRs.
+
+2020-11-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/97943
+ * gimple-fold.c (clear_padding_union, clear_padding_type): Error on and
+ ignore flexible array member fields. Ignore fields with
+ error_mark_node type.
+
+2020-11-24 Ulrich Weigand <ulrich.weigand@de.ibm.com>
+
+ Revert:
+ 2020-11-24 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * doc/invoke.texi (-ffast-math): Remove mention of -fno-signaling-nans.
+ Clarify conditions when __FAST_MATH__ preprocessor macro is defined.
+ * opts.c (common_handle_option): Pass OPTS_SET to set_fast_math_flags
+ and set_unsafe_math_optimizations_flags.
+ (set_fast_math_flags): Add OPTS_SET argument, and use it to avoid
+ setting flags already explicitly set on the command line. In the !set
+ case, also reset x_flag_cx_limited_range and x_flag_excess_precision.
+ Never reset x_flag_signaling_nans or x_flag_rounding_math.
+ (set_unsafe_math_optimizations_flags): Add OPTS_SET argument, and use
+ it to avoid setting flags already explicitly set on the command line.
+ (fast_math_flags_set_p): Also test x_flag_cx_limited_range,
+ x_flag_associative_math, x_flag_reciprocal_math, and
+ x_flag_rounding_math.
+
+2020-11-24 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR bootstrap/97933
+ * lra.c (lra_process_new_insns): Stop on the first real insn after
+ head of e->dest.
+
+2020-11-24 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/97534
+ * config/arm/arm.c (arm_split_atomic_op): Use gen_int_mode when
+ negating a const_int.
+
+2020-11-24 Ilya Leoshkevich <iii@linux.ibm.com>
+
+ * config/s390/vector.md: Use vcond_comparison_operator
+ predicate.
+
+2020-11-24 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * doc/invoke.texi (-ffast-math): Remove mention of -fno-signaling-nans.
+ Clarify conditions when __FAST_MATH__ preprocessor macro is defined.
+ * opts.c (common_handle_option): Pass OPTS_SET to set_fast_math_flags
+ and set_unsafe_math_optimizations_flags.
+ (set_fast_math_flags): Add OPTS_SET argument, and use it to avoid
+ setting flags already explicitly set on the command line. In the !set
+ case, also reset x_flag_cx_limited_range and x_flag_excess_precision.
+ Never reset x_flag_signaling_nans or x_flag_rounding_math.
+ (set_unsafe_math_optimizations_flags): Add OPTS_SET argument, and use
+ it to avoid setting flags already explicitly set on the command line.
+ (fast_math_flags_set_p): Also test x_flag_cx_limited_range,
+ x_flag_associative_math, x_flag_reciprocal_math, and
+ x_flag_rounding_math.
+
+2020-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/97950
+ * config/i386/i386.md (*setcc_si_1_and): Macroize into...
+ (*setcc_<mode>_1_and): New define_insn_and_split with SWI24 iterator.
+ (*setcc_si_1_movzbl): Macroize into...
+ (*setcc_<mode>_1_movzbl): New define_insn_and_split with SWI24
+ iterator.
+
+2020-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ * gimple-fold.c (clear_padding_flush): If a word contains only 0
+ or 0xff bytes of padding other than all set, all clear, all set
+ followed by all clear or all clear followed by all set, don't emit
+ a RMW operation on the whole word or parts of it, but instead
+ clear the individual bytes of padding. For paddings of one byte
+ size, don't use char[1] and {}, but instead just char and 0.
+
+2020-11-24 Thomas Schwinge <thomas@codesourcery.com>
+
+ * omp-expand.c (expand_oacc_for): More explicit checking of which
+ OMP constructs we're expecting.
+
+2020-11-24 Thomas Schwinge <thomas@codesourcery.com>
+
+ * doc/install.texi (Prerequisites) <Tcl>: Add comment.
+
+2020-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/96929
+ * fold-const.c (wide_int_binop) <case LSHIFT_EXPR, case RSHIFT_EXPR>:
+ Return false on negative second argument rather than trying to handle
+ it as shift in the other direction.
+ * tree-ssa-ccp.c (bit_value_binop) <case LSHIFT_EXPR,
+ case RSHIFT_EXPR>: Punt on negative shift count rather than trying
+ to handle it as shift in the other direction.
+ * match.pd (-1 >> x to -1): Remove tree_expr_nonnegative_p check.
+
+2020-11-24 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ PR tree-optimization/97849
+ * tree-if-conv.c (tree_if_conversion): Move ssa_name
+ replacement code from ifcvt_local_dce to this function
+ before calling do_rpo_vn.
+
+2020-11-24 Martin Sebor <msebor@redhat.com>
+
+ * tree-cfg.c (dump_function_to_file): Print type attributes
+ and return type.
+
+2020-11-23 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-prop.h (ipa_pass_through_data): Expand comment describing
+ operation.
+ * ipa-prop.c (analyze_agg_content_value): Detect new special case and
+ encode it as ASSERT_EXPR.
+ * ipa-cp.c (values_equal_for_ipcp_p): Move before
+ ipa_get_jf_arith_result.
+ (ipa_get_jf_arith_result): Special case ASSERT_EXPR.
+
+2020-11-23 Jeff Law <law@redhat.com>
+
+ * config/h8300/h8300.c (h8300_rtx_costs): Handle the various
+ comparison rtx codes too.
+
+2020-11-23 Jan Hubicka <jh@suse.cz>
+
+ * ipa-prop.c (build_agg_jump_func_from_list,
+ ipa_read_jump_function): Reserve agg.items precisely.
+ * ipa-prop.h (ipa_node_params::~ipa_node_params): Release descriptors
+ (ipa_edge_args::~ipa_edge_args): Release agg.items.
+
+2020-11-23 Jan Hubicka <jh@suse.cz>
+
+ * lto-streamer-in.c (input_cfg): Do not init ssa operands.
+ (input_function): Do not init tree_ssa and set in_ssa_p.
+ (input_ssa_names): Do it here.
+ * tree-ssa.c (init_tree_ssa): Add additional SIZE parameter, default
+ to 0
+ * tree-ssanames.c (init_ssanames): Do not round size up to 50, allocate
+ precisely.
+ * tree-ssa.h (init_tree_ssa): Update prototype.
+
+2020-11-23 Nathan Sidwell <nathan@acm.org>
+
+ * diagnostic.c (diagnostic_report_current_module): Adjust for C++
+ module importation.
+
+2020-11-23 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * config/msp430/msp430.c (msp430_section_attr): Don't warn for "lower"
+ attribute used with "noinit" or "persistent" attributes.
+ (msp430_persist_attr): Remove.
+ (attr_lower_exclusions): Remove ATTR_PERSIST exclusion.
+ (attr_upper_exclusions): Likewise.
+ (attr_either_exclusions): Likewise.
+ (attr_persist_exclusions): Remove.
+ (msp430_attribute_table): Remove ATTR_PERSIST handling.
+ (msp430_handle_generic_attribute): Remove ATTR_PERSIST section conflict
+ handling.
+ (TARGET_ASM_INIT_SECTIONS): Remove.
+ (msp430_init_sections): Remove.
+ (msp430_select_section): Use default_elf_select_section for decls with
+ the "persistent" attribute.
+ (msp430_section_type_flags): Remove ".persistent" section handling.
+ * doc/extend.texi (MSP430 Variable Attributes): Remove "noinit" and
+ "persistent" documentation.
+
+2020-11-23 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-slp.c (maybe_push_to_hybrid_worklist): Skip
+ debug stmts.
+
+2020-11-23 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * doc/extend.texi (Common Variable Attributes): Document the
+ "persistent" variable attribute.
+ * doc/sourcebuild.texi (Effective-Target Keywords): Document
+ the "persistent" effective target keyword.
+ * tree.h (DECL_PERSISTENT_P): Define.
+ * varasm.c (bss_initializer_p): Return false for a
+ DECL_PERSISTENT_P decl initialized to zero.
+ (default_section_type_flags): Handle the ".persistent" section.
+ (default_elf_select_section): Likewise.
+ (default_unique_section): Likewise.
+
+2020-11-23 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * tree.h (DECL_NOINIT_P): Define.
+ * varasm.c (DECL_NOINIT_P): Check DECL_NOINIT_P before using
+ unnamed bss/lcomm sections for bss_initializer variables.
+ (default_elf_select_section): Use DECL_NOINIT_P instead of
+ looking up attribute for .noinit section selection.
+ (default_unique_section): Check DECL_NOINIT_P for .noinit
+ section selection.
+
+2020-11-23 Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * doc/install.texi: Document bootstrap-asan option.
+
+2020-11-22 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/97873
+ * config/i386/i386.md (abs<mode>2): Use SWI48DWI mode iterator.
+ (*abs<dwi>2_doubleword): Use DWIH mode iterator.
+ (<maxmin:code><mode>3): Use SWI48DWI mode iterator.
+ (*<maxmin:code><dwi>3_doubleword): Use DWIH mode iterator.
+
+2020-11-22 Austin Law <austinklaw@gmail.com>
+
+ * config/h8300/addsub.md: Turn existing patterns into
+ define_insn_and_split style patterns where the splitter
+ adds a clobber of the condition code register. Drop "cc"
+ attribute. Add _clobber_flags patterns to match output of
+ the splitters.
+ (add<mod>3_incdec): Remove pattern
+ (adds/subs splitter): Only run before reload.
+ * config/h8300/bitfield.md: Turn existing patterns into
+ define_insn_and_split style patterns where the splitter
+ adds a clobber of the condition code register. Drop "cc"
+ attribute. Add _clobber_flags patterns to match output
+ of the splitters.
+ (cstoreqi4, cstorehi4, cstoresi4): Comment out
+ (*bstzhireg, *cmpstz, *bstz, *bistz, *cmpcondset): Likewise
+ (*condbset, *cmpcondbclr, *condbclr): Likewise.
+ (*cmpcondbsetreg, *condbsetreg, *cmpcondbclrreg): Likewise.
+ (*condbclrreg): Likewise.
+ * config/h8300/combiner.md: Turn existing patterns into
+ define_insn_and_split style patterns where the splitter
+ adds a clobber of the condition code register. Drop "cc"
+ attribute. Add _clobber_flags patterns to match output of
+ the splitters. Add appropriate CC register clobbers to
+ existing splitters.
+ (*addsi3_and_r_1): Disable for now.
+ (*addsi3_and_not_r_1, bit-test branches): Likewise.
+ * config/h8300/divmod.md: Turn existing patterns into
+ define_insn_and_split style patterns where the splitter
+ adds a clobber of the condition code register. Drop "cc"
+ attribute. Add _clobber_flags patterns to match output of
+ the splitters.
+ * config/h8300/extensions.md: Turn existing patterns into
+ define_insn_and_split style patterns where the splitter
+ adds a clobber of the condition code register. Drop "cc"
+ attribute. Add _clobber_flags patterns to match output of
+ the splitters.
+ * config/h8300/genmova.sh: Drop "cc" attribute from patterns.
+ * config/h8300/mova.md: Drop "cc" attribute from patterns.
+ * config/h8300/h8300-modes.def: Add CCZN and CCZNV modes.
+ * config/h8300/h8300-protos.h (output_plussi): Update prototype.
+ (compute_plussi_length): Likewise.
+ (h8300_select_cc_mode): Add prototype.
+ (compute_a_shift_cc): Remove prototype
+ (cmpute_logical_op_cc): Likewise.
+ * config/h8300/h8300.c (names_big): Add "cc" register.
+ (names_extended, names_upper_extended): Likewise.
+ (h8300_emit_stack_adjustment): Be more selective about setting
+ RTX_FRAME_RELATED_P.
+ (h8300_print_operand): Handle CCZN mode
+ (h8300_select_cc_mode): New function.
+ (notice_update_cc): if-0 out. Only kept for reference purposes.
+ (h8300_expand_store): Likewise.
+ (h8300_binary_length): Handle new insn forms.
+ (output_plussi): Add argument for NEED_FLAGS and handle that case.
+ (compute_plussi_length): Likewise.
+ (compute_logical_op_cc): Return integer.
+ (TARGET_FLAGS_REGNUM): Define.
+ * config/h8300/h8300.h (FIRST_PSEUDO_REGISTER): Bump for cc register.
+ (FIXED_REGISTERS, CALL_USED_REGISTERS): Handle cc register.
+ (REG_ALLOC_ORDER, REGISTER_NAMES): Likewise.
+ (SELECT_CC_MODE): Define.
+ * config/h8300/h8300.md: Add CC_REG.
+ Do not include peepholes.md for now.
+ * config/h8300/jumpcall.md (cbranchqi4): Consolidate into
+ cbranch<mode>4.
+ (cbranchhi4, cbranchsi4): Likewise.
+ (cbranch<mode>4): New expander.
+ (branch): New define_insn_and_split for use before reload.
+ (branch_1, branch_1_false): New patterns to match splitter output.
+ Remove code to manage cc_status.flags.
+ * config/h8300/logical.md: Turn existing patterns into
+ define_insn_and_split style patterns where the splitter
+ adds a clobber of the condition code register. Drop "cc"
+ attribute. Add _clobber_flags patterns to match output of
+ the splitters. Move various peepholes into this file.
+ * config/h8300/movepush.md: Turn existing patterns into
+ define_insn_and_split style patterns where the splitter
+ adds a clobber of the condition code register. Drop "cc"
+ attribute. Add _clobber_flags patterns to match output of
+ the splitters.
+ * config/h8300/multiply.md: Turn existing patterns into
+ define_insn_and_split style patterns where the splitter
+ adds a clobber of the condition code register. Drop "cc"
+ attribute. Add _clobber_flags patterns to match output of
+ the splitters.
+ * config/h8300/other.md: Turn existing patterns into
+ define_insn_and_split style patterns where the splitter
+ adds a clobber of the condition code register. Drop "cc"
+ attribute. Add _clobber_flags patterns to match output of
+ the splitters.
+ * config/h8300/peepholes.md: Remove peepholes that were moved
+ elsewhere.
+ * config/h8300/predicates.md (simple_memory_operand): New.
+ * config/h8300/proepi.md: Drop "cc" attribute setting.
+ * config/h8300/shiftrotate.md: Turn existing patterns into
+ define_insn_and_split style patterns where the splitter
+ adds a clobber of the condition code register. Drop "cc"
+ attribute. Add _clobber_flags patterns to match output of
+ the splitters.
+ * config/h8300/testcompare.md: Turn existing patterns into
+ define_insn_and_split style patterns where the splitter
+ adds a clobber of the condition code register. Drop "cc"
+ attribute. Add _clobber_flags patterns to match output of
+ the splitters. Disable various patterns for now.
+ Move some peepholes that were previously in peepholes.md here.
+ * config/h8300/save.md: New file.
+
+2020-11-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/95853
+ * tree-ssa-math-opts.c (uaddsub_overflow_check_p): Add maxval
+ argument, if non-NULL, instead look for r > maxval or r <= maxval
+ comparisons.
+ (match_uaddsub_overflow): Pattern recognize even other forms of
+ __builtin_add_overflow, in particular when addition is performed
+ in a wider type and result compared to maximum of the narrower
+ type.
+
+2020-11-22 Jeff Law <law@redhat.com>
+
+ * config/h8300/jumpcall.md (branch_true, branch_false): Revert
+ recent change. Ensure operand[0] is always the target label.
+
+2020-11-22 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config/darwin-c.c (struct f_align_stack): Rename
+ to type from align_stack to f_align_stack.
+ (push_field_alignment): Likewise.
+ (pop_field_alignment): Likewise.
+
+2020-11-21 Marek Polacek <polacek@redhat.com>
+
+ PR c++/94695
+ * doc/invoke.texi: Update the -Wrange-loop-construct description.
+
+2020-11-21 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa-alias.c (ao_compare::compare_ao_refs,
+ ao_compare::hash_ao_ref): Use OEP_MATCH_SIDE_EFFECTS.
+
+2020-11-21 Jan Hubicka <jh@suse.cz>
+
+ * ipa-icf.c (sem_function::equals_wpa): Do not compare ODR type with
+ -fno-devirtualize.
+ (sem_item_optimizer::update_hash_by_addr_refs): Hash anonymous ODR
+ types by TYPE_UID of their main variant.
+
+2020-11-21 Aaron Sawdey <acsawdey@linux.ibm.com>
+
+ * config/rs6000/rs6000.c (rs6000_option_override_internal):
+ Enable vector pair memcpy/memmove expansion.
+
+2020-11-21 Aaron Sawdey <acsawdey@linux.ibm.com>
+
+ * config/rs6000/mma.md (unspec): Add assemble/extract UNSPECs.
+ (movoi): Change to movoo.
+ (*movpoi): Change to *movoo.
+ (movxi): Change to movxo.
+ (*movpxi): Change to *movxo.
+ (mma_assemble_pair): Change to OO mode.
+ (*mma_assemble_pair): New define_insn_and_split.
+ (mma_disassemble_pair): New define_expand.
+ (*mma_disassemble_pair): New define_insn_and_split.
+ (mma_assemble_acc): Change to XO mode.
+ (*mma_assemble_acc): Change to XO mode.
+ (mma_disassemble_acc): New define_expand.
+ (*mma_disassemble_acc): New define_insn_and_split.
+ (mma_<acc>): Change to XO mode.
+ (mma_<vv>): Change to XO mode.
+ (mma_<avv>): Change to XO mode.
+ (mma_<pv>): Change to OO mode.
+ (mma_<apv>): Change to XO/OO mode.
+ (mma_<vvi4i4i8>): Change to XO mode.
+ (mma_<avvi4i4i8>): Change to XO mode.
+ (mma_<vvi4i4i2>): Change to XO mode.
+ (mma_<avvi4i4i2>): Change to XO mode.
+ (mma_<vvi4i4>): Change to XO mode.
+ (mma_<avvi4i4>): Change to XO mode.
+ (mma_<pvi4i2>): Change to XO/OO mode.
+ (mma_<apvi4i2>): Change to XO/OO mode.
+ (mma_<vvi4i4i4>): Change to XO mode.
+ (mma_<avvi4i4i4>): Change to XO mode.
+ * config/rs6000/predicates.md (input_operand): Allow opaque.
+ (mma_disassemble_output_operand): New predicate.
+ * config/rs6000/rs6000-builtin.def:
+ Changes to disassemble builtins.
+ * config/rs6000/rs6000-call.c (rs6000_return_in_memory):
+ Disallow __vector_pair/__vector_quad as return types.
+ (rs6000_promote_function_mode): Remove function return type
+ check because we can't test it here any more.
+ (rs6000_function_arg): Do not allow __vector_pair/__vector_quad
+ as as function arguments.
+ (rs6000_gimple_fold_mma_builtin):
+ Handle mma_disassemble_* builtins.
+ (rs6000_init_builtins): Create types for XO/OO modes.
+ * config/rs6000/rs6000-modes.def: DElete OI, XI,
+ POI, and PXI modes, and create XO and OO modes.
+ * config/rs6000/rs6000-string.c (expand_block_move):
+ Update to OO mode.
+ * config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok_uncached):
+ Update for XO/OO modes.
+ (rs6000_rtx_costs): Make UNSPEC_MMA_XXSETACCZ cost 0.
+ (rs6000_modes_tieable_p): Update for XO/OO modes.
+ (rs6000_debug_reg_global): Update for XO/OO modes.
+ (rs6000_setup_reg_addr_masks): Update for XO/OO modes.
+ (rs6000_init_hard_regno_mode_ok): Update for XO/OO modes.
+ (reg_offset_addressing_ok_p): Update for XO/OO modes.
+ (rs6000_emit_move): Update for XO/OO modes.
+ (rs6000_preferred_reload_class): Update for XO/OO modes.
+ (rs6000_split_multireg_move): Update for XO/OO modes.
+ (rs6000_mangle_type): Update for opaque types.
+ (rs6000_invalid_conversion): Update for XO/OO modes.
+ * config/rs6000/rs6000.h (VECTOR_ALIGNMENT_P):
+ Update for XO/OO modes.
+ * config/rs6000/rs6000.md (RELOAD): Update for XO/OO modes.
+
+2020-11-21 Aaron Sawdey <acsawdey@linux.ibm.com>
+
+ * typeclass.h: Add opaque_type_class.
+ * builtins.c (type_to_class): Identify opaque type class.
+ * dwarf2out.c (is_base_type): Handle opaque types.
+ (gen_type_die_with_usage): Handle opaque types.
+ * expr.c (count_type_elements): Opaque types should
+ never have initializers.
+ * ipa-devirt.c (odr_types_equivalent_p): No type-specific handling
+ for opaque types is needed as it eventually checks the underlying
+ mode which is what is important.
+ * tree-streamer.c (record_common_node): Handle opaque types.
+ * tree.c (type_contains_placeholder_1): Handle opaque types.
+ (type_cache_hasher::equal): No additional comparison needed for
+ opaque types.
+
+2020-11-20 Michael Meissner <meissner@linux.ibm.com>
+
+ * config/rs6000/rs6000-call.c (rs6000_expand_builtin): Add missing
+ XSCMP* cases for IEEE 128-bit long double.
+
+2020-11-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/97918
+ * dwarf2out.c (dwarf2out_early_finish): flush_limbo_die_list
+ after gen_scheduled_generic_parms_dies.
+
+2020-11-20 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/97879
+ * tree-core.h (enum attribute_flags): Add ATTR_FLAG_INTERNAL.
+
+2020-11-20 Jan Hubicka <jh@suse.cz>
+
+ * ipa-icf-gimple.c (func_checker::hash_operand): Improve hashing of
+ decls.
+
+2020-11-20 Jan Hubicka <jh@suse.cz>
+
+ * ipa-icf-gimple.c (func_checker::compare_decl): Do not compare types
+ of local variables.
+
+2020-11-20 Nathan Sidwell <nathan@acm.org>
+
+ * doc/invoke.texi: Replace a couple of @code with @command
+
+2020-11-20 Tamar Christina <tamar.christina@arm.com>
+
+ * tree-vect-slp.c (vectorizable_slp_permutation): Update types on nodes
+ when needed.
+
+2020-11-20 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-slp.c (maybe_push_to_hybrid_worklist): New function.
+ (vect_detect_hybrid_slp): Use it. Perform a backward walk
+ over the IL.
+
+2020-11-20 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-slp.c (vect_print_slp_tree): Also dump
+ SLP_TREE_REPRESENTATIVE.
+
+2020-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR libstdc++/88101
+ * builtins.def (BUILT_IN_CLEAR_PADDING): New built-in function.
+ * gimplify.c (gimplify_call_expr): Rewrite single argument
+ BUILT_IN_CLEAR_PADDING into two-argument variant.
+ * gimple-fold.c (clear_padding_unit, clear_padding_buf_size): New
+ const variables.
+ (struct clear_padding_struct): New type.
+ (clear_padding_flush, clear_padding_add_padding,
+ clear_padding_emit_loop, clear_padding_type,
+ clear_padding_union, clear_padding_real_needs_padding_p,
+ clear_padding_type_may_have_padding_p,
+ gimple_fold_builtin_clear_padding): New functions.
+ (gimple_fold_builtin): Handle BUILT_IN_CLEAR_PADDING.
+ * doc/extend.texi (__builtin_clear_padding): Document.
+
+2020-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/97528
+ * config/arm/arm.c (neon_vector_mem_operand): For POST_MODIFY, require
+ first POST_MODIFY operand is a REG and is equal to the first operand
+ of PLUS.
+
+2020-11-20 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gimple-ssa-store-merging.c (struct merged_store_group): Add
+ new 'consecutive' field.
+ (merged_store_group): Set it to true.
+ (do_merge): Set it to false if the store is not consecutive and
+ set string_concatenation to false in this case.
+ (merge_into): Call do_merge on entry.
+ (merge_overlapping): Likewise.
+
+2020-11-20 Jan Hubicka <jh@suse.cz>
+
+ * ipa-icf-gimple.c (func_checker::operand_equal_p): Fix comment.
+
+2020-11-20 Jan Hubicka <jh@suse.cz>
+
+ * ipa-icf-gimple.c (func_checker::hash_operand): Hash gimple clobber.
+ (func_checker::operand_equal_p): Special case gimple clobber.
+
+2020-11-20 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/97873
+ * config/i386/i386.md (*neg<mode>2_2): Rename from
+ "*neg<mode>2_cmpz". Use CCGOCmode instead of CCZmode.
+ (*negsi2_zext): Rename from *negsi2_cmpz_zext.
+ Use CCGOCmode instead of CCZmode.
+ (*neg<mode>_ccc_1): New insn pattern.
+ (*neg<dwi>2_doubleword): Use *neg<mode>_ccc_1.
+ (abs<mode>2): Add FLAGS_REG clobber.
+ Use TARGET_CMOVE insn predicate.
+ (*abs<mode>2_1): New insn_and_split pattern.
+ (*absdi2_doubleword): Ditto.
+ (<maxmin:code><mode>3): Use SWI48x mode iterator.
+ (*<maxmin:code><mode>3): Use SWI48 mode iterator.
+ * config/i386/i386-features.c
+ (general_scalar_chain::compute_convert_gain): Handle ABS code.
+ (general_scalar_chain::convert_insn): Ditto.
+ (general_scalar_to_vector_candidate_p): Ditto.
+
+2020-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/97911
+ * configure.ac: In SERIAL_LIST use lang words without .serial
+ suffix. Change $lang.prev from a target to variable and instead
+ of depending on *.serial expand to the *.serial variable if
+ the word is in the SERIAL_LIST at all, otherwise to nothing.
+ * configure: Regenerated.
+
+2020-11-20 Kewen Lin <linkw@linux.ibm.com>
+
+ * config/rs6000/rs6000.md (p8_mtvsrd_df): Fix insn type.
+
+2020-11-20 Martin Uecker <muecker@gwdg.de>
+
+ * gimplify.c (gimplify_modify_expr_rhs): Optimizie
+ NOP_EXPRs that contain compound literals.
+
+2020-11-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/91029
+ * range-op.cc (operator_trunc_mod::op1_range): Don't require signed
+ types, nor require that op2 >= 0. Implement (a % b) >= x && x > 0
+ implies a >= x and (a % b) <= x && x < 0 implies a <= x.
+ (operator_trunc_mod::op2_range): New method.
+
+2020-11-19 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/93781
+ * range-op.cc (get_shift_range): Rename from
+ undefined_shift_range_check and now return valid shift ranges.
+ (operator_lshift::fold_range): Use result from get_shift_range.
+ (operator_rshift::fold_range): Ditto.
+
+2020-11-19 Jan Hubicka <jh@suse.cz>
+
+ * fold-const.c (operand_compare::operand_equal_p): Fix thinko in
+ COMPONENT_REF handling and guard types_same_for_odr by
+ virtual_method_call_p.
+ (operand_compare::hash_operand): Likewise.
+
+2020-11-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/97860
+ * tree.c (array_type_nelts): For complete arrays with zero min
+ and NULL max and zero size return -1.
+
+2020-11-19 Nathan Sidwell <nathan@acm.org>
+
+ * configure.ac: Add tests for fstatat, sighandler_t, O_CLOEXEC,
+ unix-domain and ipv6 sockets.
+ * config.in: Rebuilt.
+ * configure: Rebuilt.
+
+2020-11-19 Dimitar Dimitrov <dimitar@dinux.eu>
+
+ * config/pru/alu-zext.md: Add lmbd patterns for zero_extend
+ variants.
+ * config/pru/pru.c (enum pru_builtin): Add HALT and LMBD.
+ (pru_init_builtins): Ditto.
+ (pru_builtin_decl): Ditto.
+ (pru_expand_builtin): Ditto.
+ * config/pru/pru.h (CLZ_DEFINED_VALUE_AT_ZERO): Define PRU
+ value for CLZ with zero value parameter.
+ * config/pru/pru.md: Add halt, lmbd and clz patterns.
+ * doc/extend.texi: Document PRU builtins.
+
+2020-11-19 Richard Sandiford <richard.sandiford@arm.com>
+
+ * doc/invoke.texi (-fvect-cost-model): Add a very-cheap model.
+ * common.opt (fvect-cost-model=): Add very-cheap as a possible option.
+ (fsimd-cost-model=): Likewise.
+ (vect_cost_model): Add very-cheap.
+ * flag-types.h (vect_cost_model): Add VECT_COST_MODEL_VERY_CHEAP.
+ Put the values in order of increasing aggressiveness.
+ * tree-vect-data-refs.c (vect_enhance_data_refs_alignment): Use
+ range checks when comparing against VECT_COST_MODEL_CHEAP.
+ (vect_prune_runtime_alias_test_list): Do not allow any alias
+ checks for the very-cheap cost model.
+ * tree-vect-loop.c (vect_analyze_loop_costing): Do not allow
+ any peeling for the very-cheap cost model. Also require one
+ iteration of the vector loop to pay for itself.
+
+2020-11-19 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * config/aarch64/aarch64.c (neoversen1_tunings): Use new
+ cortexa76_extra_costs.
+ (neoversev1_tunings): Likewise.
+ (neoversen2_tunines): Likewise.
+ * config/arm/aarch-cost-tables.h (cortexa76_extra_costs):
+ add new costs.
+
+2020-11-19 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_expand_cpymem): Cleanup code and
+ comments, tweak expansion decisions and improve tail expansion.
+
+2020-11-19 Richard Biener <rguenther@suse.de>
+
+ * fold-const.c (operand_compare::hash_operand): Fix typo.
+
+2020-11-19 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-reassoc.c (get_rank): Refactor to consistently
+ use the cache and dump ranks assigned.
+
+2020-11-19 Jan Hubicka <jh@suse.cz>
+
+ * fold-const.c (operand_compare::operand_equal_p): More OBJ_TYPE_REF
+ matching to correct place; drop OEP_ADDRESS_OF for TOKEN, OBJECT and
+ class.
+ (operand_compare::hash_operand): Hash ODR type for OBJ_TYPE_REF.
+
+2020-11-19 Joel Hutton <joel.hutton@arm.com>
+
+ * config/aarch64/aarch64-simd.md: Add vec_widen_lshift_hi/lo<mode>
+ patterns.
+ * tree-vect-stmts.c (vectorizable_conversion): Fix for widen_lshift
+ case.
+
+2020-11-19 Joel Hutton <joel.hutton@arm.com>
+
+ * doc/generic.texi: Document new widen_plus/minus_lo/hi tree codes.
+ * doc/md.texi: Document new widenening add/subtract hi/lo optabs.
+ * expr.c (expand_expr_real_2): Add widen_add, widen_subtract cases.
+ * optabs-tree.c (optab_for_tree_code): Add case for widening optabs.
+ * optabs.def (OPTAB_D): Define vectorized widen add, subtracts.
+ * tree-cfg.c (verify_gimple_assign_binary): Add case for widening adds,
+ subtracts.
+ * tree-inline.c (estimate_operator_cost): Add case for widening adds,
+ subtracts.
+ * tree-vect-generic.c (expand_vector_operations_1): Add case for
+ widening adds, subtracts
+ * tree-vect-patterns.c (vect_recog_widen_add_pattern): New recog
+ pattern.
+ (vect_recog_widen_sub_pattern): New recog pattern.
+ (vect_recog_average_pattern): Update widened add code.
+ (vect_recog_average_pattern): Update widened add code.
+ * tree-vect-stmts.c (vectorizable_conversion): Add case for widened add,
+ subtract.
+ (supportable_widening_operation): Add case for widened add, subtract.
+ * tree.def
+ (WIDEN_PLUS_EXPR): New tree code.
+ (WIDEN_MINUS_EXPR): New tree code.
+ (VEC_WIDEN_ADD_HI_EXPR): New tree code.
+ (VEC_WIDEN_PLUS_LO_EXPR): New tree code.
+ (VEC_WIDEN_MINUS_HI_EXPR): New tree code.
+ (VEC_WIDEN_MINUS_LO_EXPR): New tree code.
+
+2020-11-19 Joel Hutton <joel.hutton@arm.com>
+
+ * config/aarch64/aarch64-simd.md: New patterns
+ vec_widen_saddl_lo/hi_<mode>.
+
+2020-11-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97901
+ * tree-ssa-propagate.c (clean_up_loop_closed_phi): Compute
+ dominators and use replace_uses_by.
+
+2020-11-19 Eric Botcazou <ebotcazou@adacore.com>
+
+ * dwarf2out.h (struct fixed_point_type_info) <scale_factor>: Turn
+ numerator and denominator into a tree.
+ * dwarf2out.c (base_type_die): In the case of a fixed-point type
+ with arbitrary scale factor, call add_scalar_info on numerator and
+ denominator to emit the appropriate attributes.
+
+2020-11-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97897
+ * tree-complex.c (complex_propagate::visit_stmt): Make sure
+ abnormally used SSA names are VARYING.
+ (complex_propagate::visit_phi): Likewise.
+ * tree-ssa.c (verify_phi_args): Verify PHI arguments on abnormal
+ edges are SSA names.
+
+2020-11-19 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (*<absneg:code><mode>2_i387_1):
+ Disable for TARGET_SSE_MATH modes.
+
+2020-11-19 Jeff Law <law@redhat.com>
+
+ * config/h8300/constraints.md (R constraint): Add argument to call
+ to h8300_shift_needs_scratch_p.
+ (S and T constraints): Similary.
+ * config/h8300/h8300-protos.h: Update h8300_shift_needs_scratch_p
+ prototype.
+ * config/h8300/h8300.c (expand_a_shift): Emit a different pattern
+ if the shift does not require a scratch register.
+ (h8300_shift_needs_scratch_p): Refine to be more accurate.
+ * config/h8300/shiftrotate.md (shiftqi_noscratch): New pattern.
+ (shifthi_noscratch, shiftsi_noscratch): Similarly.
+
+2020-11-18 Roger Sayle <roger@nextmovesoftware.com>
+
+ PR middle-end/85811
+ * fold-const.c (tree_expr_finite_p): New function to test whether
+ a tree expression must be finite, i.e. not a FP NaN or infinity.
+ (tree_expr_infinite_p): New function to test whether a tree
+ expression must be infinite, i.e. a FP infinity.
+ (tree_expr_maybe_infinite_p): New function to test whether a tree
+ expression may be infinite, i.e. a FP infinity.
+ (tree_expr_signaling_nan_p): New function to test whether a tree
+ expression must evaluate to a signaling NaN (sNaN).
+ (tree_expr_maybe_signaling_nan_p): New function to test whether a
+ tree expression may be a signaling NaN (sNaN).
+ (tree_expr_nan_p): New function to test whether a tree expression
+ must evaluate to a (quiet or signaling) NaN.
+ (tree_expr_maybe_nan_p): New function to test whether a tree
+ expression me be a (quiet or signaling) NaN.
+ (tree_binary_nonnegative_warnv_p) [MAX_EXPR]: In the presence
+ of NaNs, MAX_EXPR is only guaranteed to be non-negative, if both
+ operands are non-negative.
+ (tree_call_nonnegative_warnv_p) [CASE_CFN_FMAX,CASE_CFN_FMAX_FN]:
+ In the presence of signaling NaNs, fmax is only guaranteed to be
+ non-negative if both operands are negative. In the presence of
+ quiet NaNs, fmax is non-negative if either operand is non-negative
+ and not a qNaN, or both operands are non-negative.
+ * fold-const.h (tree_expr_finite_p, tree_expr_infinite_p,
+ tree_expr_maybe_infinite_p, tree_expr_signaling_nan_p,
+ tree_expr_maybe_signaling_nan_p, tree_expr_nan_p,
+ tree_expr_maybe_nan_p): Prototype new functions here.
+ * builtins.c (fold_builtin_classify) [BUILT_IN_ISINF]: Fold to
+ a constant if argument is known to be (or not to be) an Infinity.
+ [BUILT_IN_ISFINITE]: Fold to a constant if argument is known to
+ be (or not to be) finite.
+ [BUILT_IN_ISNAN]: Fold to a constant if argument is known to be
+ (or not to be) a NaN.
+ (fold_builtin_fpclassify): Check tree_expr_maybe_infinite_p and
+ tree_expr_maybe_nan_p instead of HONOR_INFINITIES and HONOR_NANS
+ respectively.
+ (fold_builtin_unordered_cmp): Fold UNORDERED_EXPR to a constant
+ when its arguments are known to be (or not be) NaNs. Check
+ tree_expr_maybe_nan_p instead of HONOR_NANS when choosing between
+ unordered and regular forms of comparison operators.
+ * match.pd (ordered(x,y)->true/false): Constant fold ORDERED_EXPR
+ if its operands are known to be (or not to be) NaNs.
+ (unordered(x,y)->true/false): Constant fold UNORDERED_EXPR if its
+ operands are known to be (or not to be) NaNs.
+ (sqrt(x)*sqrt(x)->x): Check tree_expr_maybe_signaling_nan_p instead
+ of HONOR_SNANS.
+
+2020-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/91029
+ PR tree-optimization/97888
+ * range-op.cc (operator_trunc_mod::op1_range): Only set op1
+ range to >= 0 if lhs is > 0, rather than >= 0. Fix up comments.
+
+2020-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ * opts.h (struct cl_var): New type.
+ (cl_vars): Declare.
+ * optc-gen.awk: Generate cl_vars array.
+
+2020-11-18 Eugene Rozenfeld <Eugene.Rozenfeld@microsoft.com>
+
+ PR tree-optimization/96671
+ * match.pd (three xor patterns): New patterns.
+
+2020-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ * optc-save-gen.awk: Initialize var_opt_init. In
+ cl_optimization_stream_out for params with default values larger than
+ 10, xor the default value with the actual parameter value. In
+ cl_optimization_stream_in repeat the above xor.
+
+2020-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ * configure.ac: Add $lang.prev rules, INDEX.$lang and SERIAL_LIST and
+ SERIAL_COUNT variables to Make-hooks.
+ (--enable-link-serialization): New configure option.
+ * Makefile.in (DO_LINK_SERIALIZATION, LINK_PROGRESS): New variables.
+ * doc/install.texi (--enable-link-serialization): Document.
+ * configure: Regenerated.
+
+2020-11-18 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR target/97870
+ * lra-constraints.c (curr_insn_transform): Do not delete asm goto
+ with wrong constraints. Nullify it saving CFG.
+
+2020-11-18 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * config/msp430/msp430.md (mulhi3): New.
+ (mulsi3): New.
+ (mulsidi3): Rename to *mulsidi3_inline.
+ (umulsidi3): Rename to *umulsidi3_inline.
+ (mulsidi3): New define_expand.
+ (umulsidi3): New define_expand.
+
+2020-11-18 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97886
+ * tree-vect-loop.c (vectorizable_lc_phi): Properly assign
+ vector types to invariants for SLP.
+
+2020-11-18 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * config.gcc (*-*-dragonfly*): Add dragonfly-d.o and t-dragonfly.
+ * config/dragonfly-d.c: New file.
+ * config/t-dragonfly: New file.
+
+2020-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/97862
+ * omp-expand.c (expand_omp_for_init_vars): Don't use the sqrt path
+ if number of iterations is constant 0.
+
+2020-11-18 Kito Cheng <kito.cheng@sifive.com>
+
+ * common/config/riscv/riscv-common.c (riscv_ext_version): New.
+ (riscv_ext_version_table): Ditto.
+ (get_default_version): Ditto.
+ (riscv_subset_t::implied_p): New field.
+ (riscv_subset_t::riscv_subset_t): Init implied_p.
+ (riscv_subset_list::add): New.
+ (riscv_subset_list::handle_implied_ext): Pass riscv_subset_t
+ instead of separated argument.
+ (riscv_subset_list::to_string): Handle zifencei and zicsr, and
+ omit version if version is unknown.
+ (riscv_subset_list::parsing_subset_version): New argument `ext`,
+ remove default_major_version and default_minor_version, get
+ default version info via get_default_version.
+ (riscv_subset_list::parse_std_ext): Update argument for
+ parsing_subset_version calls.
+ Handle 2.2 ISA spec, always enable zicsr and zifencei, they are
+ included in baseline ISA in that time.
+ (riscv_subset_list::parse_multiletter_ext): Update argument for
+ `parsing_subset_version` and `add` calls.
+ (riscv_subset_list::parse): Adjust argument for
+ riscv_subset_list::handle_implied_ext call.
+ * config.gcc (riscv*-*-*): Handle --with-isa-spec=.
+ * config.in (HAVE_AS_MISA_SPEC): New.
+ (HAVE_AS_MARCH_ZIFENCEI): Ditto.
+ * config/riscv/riscv-opts.h (riscv_isa_spec_class): New.
+ (riscv_isa_spec): Ditto.
+ * config/riscv/riscv.h (HAVE_AS_MISA_SPEC): New.
+ (ASM_SPEC): Pass -misa-spec if gas supported.
+ * config/riscv/riscv.opt (riscv_isa_spec_class) New.
+ * configure.ac (HAVE_AS_MARCH_ZIFENCEI): New test.
+ (HAVE_AS_MISA_SPEC): Ditto.
+ * configure: Regen.
+
+2020-11-18 Kito Cheng <kito.cheng@sifive.com>
+
+ * common/config/riscv/riscv-common.c (riscv_implied_info):
+ d and f implied zicsr.
+ (riscv_ext_flag_table): Handle zicsr and zifencei.
+ * config/riscv/riscv-opts.h (MASK_ZICSR): New.
+ (MASK_ZIFENCEI): Ditto.
+ (TARGET_ZICSR): Ditto.
+ (TARGET_ZIFENCEI): Ditto.
+ * config/riscv/riscv.md (clear_cache): Check TARGET_ZIFENCEI.
+ (fence_i): Ditto.
+ * config/riscv/riscv.opt (riscv_zi_subext): New.
+
+2020-11-18 Kito Cheng <kito.cheng@sifive.com>
+
+ * common/config/riscv/riscv-common.c (single_letter_subset_rank): New.
+ (multi_letter_subset_rank): Ditto.
+ (subset_cmp): Ditto.
+ (riscv_subset_list::add): Insert subext in canonical ordering.
+ (riscv_subset_list::parse_std_ext): Move handle_implied_ext to ...
+ (riscv_subset_list::parse): ... here.
+
+2020-11-18 Jiufu Guo <guojiufu@linux.ibm.com>
+
+ * cfgloop.h (loop_optimizer_finalize): Add flag argument.
+ * loop-init.c (loop_optimizer_finalize): Call clean_up_loop_closed_phi.
+ * tree-cfgcleanup.h (clean_up_loop_closed_phi): New declare.
+ * tree-ssa-loop.c (tree_ssa_loop_done): Call loop_optimizer_finalize
+ with flag argument.
+ * tree-ssa-propagate.c (clean_up_loop_closed_phi): New function.
+
+2020-11-17 Sebastian Pop <spop@amazon.com>
+
+ * config.gcc: add configure flags --with-{cpu,arch,tune}-{32,64}
+ as alias flags for --with-{cpu,arch,tune} on AArch64.
+ * doc/install.texi: Document new flags for aarch64.
+
+2020-11-17 Sebastian Pop <spop@amazon.com>
+
+ * config.gcc: Add --with-tune to AArch64 configure flags.
+
+2020-11-17 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/91029
+ * range-op.cc (operator_trunc_mod::op1_range): New.
+
+2020-11-17 Jan Hubicka <jh@suse.cz>
+
+ * ipa-icf.c (sem_function::hash_stmt): Fix conditional on
+ variably_modified_type_p.
+
+2020-11-17 Nathan Sidwell <nathan@acm.org>
+
+ * tree.h (cache_integer_cst): Add defaulted might_duplicate parm.
+ * tree.c (cache_integer_cst): Return the integer cst, add
+ might_duplicate parm to permit finding a small duplicate.
+
+2020-11-17 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/83072
+ * range-op.cc (wi_optimize_and_or): Remove zero from IOR range when
+ mask is non-zero.
+
+2020-11-17 Joseph Myers <joseph@codesourcery.com>
+
+ * ginclude/float.h (CR_DECIMAL_DIG): Also define for
+ [__STDC_WANT_IEC_60559_EXT__].
+
+2020-11-17 Joseph Myers <joseph@codesourcery.com>
+
+ * ginclude/float.h [__STDC_VERSION__ > 201710L] (FLT_IS_IEC_60559,
+ DBL_IS_IEC_60559, LDBL_IS_IEC_60559): New macros.
+
+2020-11-17 Aaron Sawdey <acsawdey@linux.ibm.com>
+
+ PR target/96791
+ * mode-classes.def: Add MODE_OPAQUE.
+ * machmode.def: Add OPAQUE_MODE.
+ * tree.def: Add OPAQUE_TYPE for types that will use
+ MODE_OPAQUE.
+ * doc/generic.texi: Document OPAQUE_TYPE.
+ * doc/rtl.texi: Document MODE_OPAQUE.
+ * machmode.h: Add OPAQUE_MODE_P().
+ * genmodes.c (complete_mode): Add MODE_OPAQUE.
+ (opaque_mode): New function.
+ * tree.c (tree_code_size): Add OPAQUE_TYPE.
+ * tree.h: Add OPAQUE_TYPE_P().
+ * stor-layout.c (int_mode_for_mode): Treat MODE_OPAQUE modes
+ like BLKmode.
+ * ira.c (find_moveable_pseudos): Treat MODE_OPAQUE modes more
+ like integer/float modes here.
+ * dbxout.c (dbxout_type): Treat OPAQUE_TYPE like VOID_TYPE.
+ * tree-pretty-print.c (dump_generic_node): Treat OPAQUE_TYPE
+ like like other types.
+
+2020-11-17 Jan Hubicka <hubicka@ucw.cz>
+ Martin Liska <mliska@suse.cz>
+
+ * ipa-icf.c: Include data-streamer.h and alias.h.
+ (sem_function::sem_function): Initialize memory_access_types
+ and m_alias_sets_hash.
+ (sem_function::hash_stmt): For memory accesses and when going to
+ do lto streaming add base and ref types into memory_access_types.
+ (sem_item_optimizer::write_summary): Stream memory access types.
+ (sem_item_optimizer::read_section): Likewise and also iniitalize
+ m_alias_sets_hash.
+ (sem_item_optimizer::execute): Call
+ sem_item_optimizer::update_hash_by_memory_access_type.
+ (sem_item_optimizer::update_hash_by_memory_access_type): Updat.
+ * ipa-icf.h (sem_function): Add memory_access_types and
+ m_alias_sets_hash.
+
+2020-11-17 Jan Hubicka <jh@suse.cz>
+
+ PR bootstrap/97857
+ * ipa-devirt.c (odr_based_tbaa_p): Do not ICE when
+ odr_hash is not initialized
+ * ipa-utils.h (type_with_linkage_p): Do not sanity check
+ CXX_ODR_P.
+ * tree-streamer-out.c (pack_ts_type_common_value_fields): Set
+ CXX_ODR_P according to the canonical type.
+
+2020-11-17 Nathan Sidwell <nathan@acm.org>
+
+ * langhooks-def.h (LANG_HOOKS_PREPROCESS_MAIN_FILE)
+ (LANG_HOOKS_PREPROCESS_OPTIONS, LANG_HOOKS_PREPROCESS_UNDEF)
+ (LANG_HOOKS_PREPROCESS_TOKEN): New.
+ (LANG_HOOKS_INITIALIZER): Add them.
+ * langhooks.h (struct lang_hooks): Add preprocess_main_file,
+ preprocess_options, preprocess_undef, preprocess_token hooks. Add
+ enum PT_flags.
+
+2020-11-17 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR tree-optimization/97693
+ * tree-vect-stmts.c (vectorizable_call): Pass the required vectype
+ to vect_get_vec_defs_for_operand.
+
+2020-11-17 Liu Hao <lh_mouse@126.com>
+
+ * config/i386/msformat-c.c: Add more length modifiers.
+
+2020-11-17 Tamar Christina <tamar.christina@arm.com>
+
+ PR driver/97574
+ * gcc.c (convert_filename): Don't add suffix to things that are
+ not files.
+ (not_actual_file_p): Use supplied argument.
+
+2020-11-17 Haochen Gui <guihaoc@gcc.gnu.org>
+
+ * final.c (final_scan_insn_1): Set jump table relocatable as the
+ second argument of targetm.asm_out.function_rodata_section.
+ * output.h (default_function_rodata_section,
+ default_no_function_rodata_section): Add the second argument to the
+ declarations.
+ * target.def (function_rodata_section): Change the doc and add
+ the second argument.
+ * doc/tm.texi: Regenerate.
+ * varasm.c (jumptable_relocatable): Implement.
+ (default_function_rodata_section): Add the second argument
+ and the support for relocatable read only sections.
+ (default_no_function_rodata_section): Add the second argument.
+ (function_mergeable_rodata_prefix): Set the second argument to false.
+ * config/mips/mips.c (mips_function_rodata_section): Add the second
+ arugment and set it to false.
+ * config/s390/s390.c (targetm.asm_out.function_rodata_section): Set
+ the second argument to false.
+ * config/s390/s390.md: Likewise.
+
+2020-11-17 liuhongt <hongtao.liu@intel.com>
+
+ PR target/97194
+ * config/i386/i386-expand.c (ix86_expand_vector_set_var): New function.
+ * config/i386/i386-protos.h (ix86_expand_vector_set_var): New Decl.
+ * config/i386/predicates.md (vec_setm_operand): New predicate,
+ true for const_int_operand or register_operand under TARGET_AVX2.
+ * config/i386/sse.md (vec_set<mode>): Support both constant
+ and variable index vec_set.
+
+2020-11-17 Martin Sebor <msebor@redhat.com>
+
+ * tree-ssa-uninit.c (maybe_warn_operand): Call is_empty_type.
+ * tree.c (default_is_empty_type): Rename...
+ (is_empty_type): ...to this.
+ * tree.h (is_empty_type): Declare.
+
+2020-11-17 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/95673
+ * tree-ssa-strlen.c (used_only_for_zero_equality): Rename...
+ (use_in_zero_equality): ...to this. Add a default argument.
+ (handle_builtin_memcmp): Adjust to the name change above.
+ (handle_builtin_string_cmp): Same.
+ (maybe_warn_pointless_strcmp): Same. Pass in an explicit argument.
+
+2020-11-17 Joseph Myers <joseph@codesourcery.com>
+
+ * ginclude/float.h (DEC32_SNAN, DEC64_SNAN, DEC128_SNAN): New C2x
+ macros.
+
+2020-11-17 Joseph Myers <joseph@codesourcery.com>
+
+ * ginclude/float.h (INFINITY, NAN, FLT_SNAN, DBL_SNAN, LDBL_SNAN)
+ (FLT16_SNAN, FLT32_SNAN, FLT64_SNAN, FLT128_SNAN, FLT32X_SNAN)
+ (FLT64X_SNAN, FLT128X_SNAN, DEC_INFINITY, DEC_NAN): New C2x
+ macros.
+ * doc/sourcebuild.texi (Effective-Target Keywords): Document inff.
+
+2020-11-17 Armin Brauns via Gcc-patches <gcc-patches@gcc.gnu.org>
+
+ * gcc.c: Document %T spec file directive.
+ * doc/invoke.texi: Remove %p, %P spec file directives.
+ Add %M, %R, %V, %nSTR, %>S, %<S*, %{%:function(args):X}, %@{...} spec
+ file directives add sanitize, version-compare, include, gt and
+ debug-level-gt spec functions.
+
+2020-11-16 Roger Sayle <roger@nextmovesoftware.com>
+
+ PR rtl-optimization/92180
+ * config/i386/i386.c (ix86_hardreg_mov_ok): New function to
+ determine whether (set DST SRC) should be allowed at this point.
+ * config/i386/i386-protos.h (ix86_hardreg_mov_ok): Prototype here.
+ * config/i386/i386-expand.c (ix86_expand_move): Check whether
+ this is a complex set of a likely spilled hard register, and if
+ so place the value in a pseudo, and load the hard reg from it.
+ * config/i386/i386.md (*movdi_internal, *movsi_internal)
+ (*movhi_internal, *movqi_internal): Make these instructions
+ conditional on ix86_hardreg_mov_ok.
+ (*lea<mode>): Make this define_insn_and_split conditional on
+ ix86_hardreg_mov_ok.
+
+2020-11-16 Martin Liska <mliska@suse.cz>
+
+ * params.opt: Add missing dot.
+
+2020-11-16 Jan Hubicka <jh@suse.cz>
+
+ * ipa-modref.c (escape_point): New type.
+ (modref_lattice): New type.
+ (escape_entry): New type.
+ (escape_summary): New type.
+ (escape_summaries_t): New type.
+ (escape_summaries): New static variable.
+ (eaf_flags_useful_p): New function.
+ (modref_summary::useful_p): Add new check_flags
+ attribute; check eaf_flags for usefulness.
+ (modref_summary_lto): Add arg_flags.
+ (modref_summary_lto::useful_p): Add new check_flags
+ attribute; check eaf_flags for usefulness.
+ (dump_modref_edge_summaries): New function.
+ (remove_modref_edge_summaries): New function.
+ (ignore_retval_p): New predicate.
+ (ignore_stores_p): Also ignore for const.
+ (remove_summary): Call remove_modref_edge_summaries.
+ (modref_lattice::init): New member function.
+ (modref_lattice::release): New member unction.
+ (modref_lattice::dump): New member function.
+ (modref_lattice::add_escape_point): New member function.
+ (modref_lattice::merge): Two new member functions.
+ (modref_lattice::merge_deref): New member functions.
+ (modref_lattice::merge_direct_load): New member function.
+ (modref_lattice::merge_direct_store): New member function.
+ (call_lhs_flags): Rename to ...
+ (merge_call_lhs_flags): ... this one; reimplement using
+ modreflattice.
+ (analyze_ssa_name_flags): Replace KNOWN_FLAGS param by LATTICE;
+ add IPA parametr; use modref_lattice.
+ (analyze_parms): New parameter IPA and SUMMARY_LTO; update for
+ modref_lattice; initialize escape_summary.
+ (analyze_function): Allocate escape_summaries; update uses of useful_p.
+ (modref_write_escape_summary): New function.
+ (modref_read_escape_summary): New function.
+ (modref_write): Write escape summary.
+ (read_section): Read escape summary.
+ (modref_read): Initialie escape_summaries.
+ (remap_arg_flags): New function.
+ (update_signature): Use it.
+ (escape_map): New structure.
+ (update_escape_summary_1, update_escape_summary): New functions.
+ (ipa_merge_modref_summary_after_inlining): Merge escape summaries.
+ (propagate_unknown_call): Do not remove useless summaries.
+ (remove_useless_summaries): Remove them here.
+ (modref_propagate_in_scc): Update; do not dump scc.
+ (modref_propagate_dump_scc): New function.
+ (modref_merge_call_site_flags): New function.
+ (modref_propagate_flags_in_scc): New function.
+ (pass_ipa_modref::execute): Use modref_propagate_flags_in_scc
+ and modref_propagate_dump_scc; delete escape_summaries.
+ (ipa_modref_c_finalize): Remove escape_summaries.
+ * ipa-modref.h (modref_summary): Update prototype of useful_p.
+ * params.opt (param=modref-max-escape-points): New param.
+ * doc/invoke.texi (modref-max-escape-points): Document.
+
+2020-11-16 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/97840
+ * ipa-modref.c (analyze_ssa_name_flags): Skip clobbers if inlining
+ is done.
+ * tree-ssa-uninit.c (maybe_warn_pass_by_reference): Make stmt gcall;
+ skip const calls and unused arguments.
+ (warn_uninitialized_vars): Update prototype.
+
+2020-11-16 Richard Biener <rguenther@suse.de>
+
+ * tree-vectorizer.h (vect_gather_slp_loads): Declare.
+ * tree-vect-loop.c (vect_analyze_loop_2): Call
+ vect_gather_slp_loads.
+ * tree-vect-slp.c (vect_build_slp_instance): Do not gather
+ SLP loads here.
+ (vect_gather_slp_loads): Remove wrapper, new function.
+ (vect_slp_analyze_bb_1): Call it.
+
+2020-11-16 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-loop-im.c (analyze_memory_references): Add
+ store_motion parameter and elide unnecessary work.
+ (tree_ssa_lim_initialize): Likewise.
+ (loop_invariant_motion_in_fun): Pass down store_motion.
+
+2020-11-16 Martin Liska <mliska@suse.cz>
+
+ * params.opt: All modref parameters miss Optimization and Param
+ keyword as seen in testsuite failure.
+
+2020-11-16 Jan Hubicka <jh@suse.cz>
+
+ * params.opt (-param=modref-max-depth=): Add missing full stop.
+
+2020-11-16 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+ * common.opt (fprofile-info-section): New.
+ * coverage.c (build_gcov_info_var_registration): New.
+ (coverage_obj_init): Evaluate profile_info_section and use
+ build_gcov_info_var_registration().
+ * doc/invoke.texi (fprofile-info-section): Document.
+ * opts.c (common_handle_option): Process fprofile-info-section
+ option.
+
+2020-11-16 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97838
+ * tree-vect-slp.c (vect_slp_build_vertices): Properly handle
+ not backwards reachable cycles.
+ (vect_optimize_slp): Check a node is leaf before marking it
+ visited.
+
+2020-11-16 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/97736
+ * tree-switch-conversion.c (switch_decision_tree::analyze_switch_statement):
+ Prefer bit tests.
+
+2020-11-16 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97835
+ * tree-vect-loop.c (vectorizable_induction): Convert step
+ scalars rather than step vector.
+
+2020-11-16 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97830
+ * tree-ssa-sccvn.c (vn_reference_eq): Check for incomplete
+ types before comparing TYPE_SIZE.
+
+2020-11-16 Cui,Lili <lili.cui@intel.com>
+
+ * config/i386/i386.h: Add PREFETCHW to march=broadwell.
+ * doc/invoke.texi: Put PREFETCHW back to relation arch.
+
+2020-11-15 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * config/msp430/msp430.c (msp430_output_labelref): Don't process mspabi
+ hwmult library function names into GCC-style names.
+
+2020-11-15 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * config/msp430/msp430.c (msp430_use_16bit_hwmult): New.
+ (use_32bit_hwmult): Rename to..
+ (msp430_use_32bit_hwmult): ..this.
+ (msp430_muldiv_costs): Use msp430_use_16bit_hwmult and
+ msp430_use_32bit_hwmult.
+ (msp430_expand_helper): Use msp430_use_16bit_hwmult and
+ msp430_use_32bit_hwmult.
+ (msp430_output_labelref): Use msp430_use_32bit_hwmult.
+
+2020-11-15 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * config/vax/vax.c (vax_rtx_costs): Use `rtx_code' rather than
+ `int' for `code'.
+
+2020-11-15 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * config/vax/vax.c (vax_output_int_add) <E_DImode>: Fix a typo
+ in NO_EXTERNAL_INDIRECT_ADDRESS.
+
+2020-11-15 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * config/vax/vax.c (vax_output_int_add) <E_SImode>: Also check
+ `operands[2]' for being symbolic with PIC rather than checking
+ `operands[1]' twice.
+
+2020-11-15 Aldy Hernandez <aldyh@redhat.com>
+
+ * vr-values.c (vr_values::extract_range_builtin): Rename to...
+ (vr_values::extract_range_from_ubsan_builtin): ...this.
+ Remove everything but UBSAN code.
+ (vr_values::extract_range_basic): Call ranger version for
+ everything except UBSAN built-ins.
+ * vr-values.h (class vr_values): Rename extract_range_builtin to
+ extract_range_from_ubsan_builtin.
+
+2020-11-15 Vladimir N. Makarov <vmakarov@redhat.com>
+
+ * lra.c (lra_process_new_insns): Don't put reload insns in the
+ last empty BB.
+
+2020-11-15 Jan Hubicka <jh@suse.cz>
+
+ * ipa-modref.c (analyze_ssa_name_flags): Make return to clear
+ EAF_UNUSED flag.
+
+2020-11-14 Jan Hubicka <jh@suse.cz>
+
+ * gimple.c: Include ipa-modref-tree.h and ipa-modref.h.
+ (gimple_call_arg_flags): Use modref to determine flags.
+ * ipa-modref.c: Include gimple-ssa.h, tree-phinodes.h,
+ tree-ssa-operands.h, stringpool.h and tree-ssanames.h.
+ (analyze_ssa_name_flags): Declare.
+ (modref_summary::useful_p): Summary is also useful if arg flags are
+ known.
+ (dump_eaf_flags): New function.
+ (modref_summary::dump): Use it.
+ (get_modref_function_summary): Be read for current_function_decl
+ being NULL.
+ (memory_access_to): New function.
+ (deref_flags): New function.
+ (call_lhs_flags): New function.
+ (analyze_parms): New function.
+ (analyze_function): Use it.
+ * ipa-modref.h (struct modref_summary): Add arg_flags.
+ * doc/invoke.texi (ipa-modref-max-depth): Document.
+ * params.opt (ipa-modref-max-depth): New param.
+
+2020-11-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/97599
+ * dwarf2out.c (gen_subprogram_die): Call
+ gen_unspecified_parameters_die even if not early dwarf, but only
+ if subr_die is a newly created DIE.
+
+2020-11-14 Monk Chiang <monk.chiang@sifive.com>
+
+ PR target/97682
+ * config/riscv/riscv.h (RISCV_PROLOGUE_TEMP_REGNUM): Change register
+ to t0.
+ (RISCV_CALL_ADDRESS_TEMP_REGNUM): New Marco, define t1 register.
+ (RISCV_CALL_ADDRESS_TEMP): Use it for call instructions.
+ * config/riscv/riscv.c (riscv_legitimize_call_address): Use
+ RISCV_CALL_ADDRESS_TEMP.
+ (riscv_compute_frame_info): Change temporary register to t0 form t1.
+ (riscv_trampoline_init): Adjust comment.
+
+2020-11-14 Jim Wilson <jimw@sifive.com>
+ cooper.joshua <cooper.joshua@linux.alibaba.com>
+
+ * config/riscv/riscv.c (riscv_asan_shadow_offset): New.
+ (TARGET_ASAN_SHADOW_OFFSET): New.
+ * doc/tm.texi: Regenerated.
+ * target.def (asan_shadow_offset); Mention that it can return zero.
+ * toplev.c (process_options): Check for and handle zero return from
+ targetm.asan_shadow_offset call.
+
+2020-11-14 Jakub Jelinek <jakub@redhat.com>
+
+ * gimplify.c (gimplify_omp_for): Add OMP_CLAUSE_ALLOCATE_ALLOCATOR
+ decls as firstprivate on task clauses even when allocate clause
+ decl is not lastprivate.
+ * omp-low.c (install_var_field): Don't dereference omp_is_reference
+ types if mask is 33 rather than 1.
+ (scan_sharing_clauses): Populate allocate_map even for task
+ constructs. For now remove it back for variables mentioned in
+ reduction and in_reduction clauses on task/taskloop constructs
+ or on VLA task firstprivates. For firstprivate on task construct,
+ install the var field into field_map with by_ref and 33 instead
+ of false and 1 if mentioned in allocate clause.
+ (lower_private_allocate): Set TREE_THIS_NOTRAP on the created
+ MEM_REF.
+ (lower_rec_input_clauses): Handle allocate for task firstprivatized
+ non-VLA variables.
+ (create_task_copyfn): Likewise.
+
+2020-11-13 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa-alias.c (ao_ref_base_alias_ptr_type): Remove accidental
+ commit.
+ (ao_ref_alias_ptr_type): Remove accidental commit.
+
+2020-11-13 Kwok Cheung Yeung <kcy@codesourcery.com>
+
+ * omp-oacc-kernels-decompose.cc (maybe_build_inner_data_region):
+ Use langhook instead of accessing language-specific decl
+ information.
+
+2020-11-13 Gergö Barany <gergo@codesourcery.com>
+ Thomas Schwinge <thomas@codesourcery.com>
+
+ * omp-oacc-kernels-decompose.cc: New.
+ * Makefile.in (OBJS): Add it.
+ * passes.def: Instantiate it.
+ * tree-pass.h (make_pass_omp_oacc_kernels_decompose): Declare.
+ * flag-types.h (enum openacc_kernels): Add.
+ * doc/invoke.texi (-fopenacc-kernels): Document.
+ * gimple.h (enum gf_mask): Add
+ 'GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED',
+ 'GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE',
+ 'GF_OMP_TARGET_KIND_OACC_DATA_KERNELS'.
+ (is_gimple_omp_oacc, is_gimple_omp_offloaded): Handle these.
+ * gimple-pretty-print.c (dump_gimple_omp_target): Likewise.
+ * omp-expand.c (expand_omp_target, build_omp_regions_1)
+ (omp_make_gimple_edges): Likewise.
+ * omp-low.c (scan_sharing_clauses, scan_omp_for)
+ (check_omp_nesting_restrictions, lower_oacc_reductions)
+ (lower_oacc_head_mark, lower_omp_target): Likewise.
+ * omp-offload.c (execute_oacc_device_lower): Likewise.
+
+2020-11-13 Thomas Schwinge <thomas@codesourcery.com>
+
+ * omp-low.c (scan_sharing_clauses, scan_omp_for)
+ (lower_oacc_reductions, lower_omp_target): More explicit checking
+ of which OMP constructs we're expecting.
+
+2020-11-13 Thomas Schwinge <thomas@codesourcery.com>
+
+ * omp-expand.c (expand_omp_target): Attach an attribute to all
+ outlined OpenACC compute regions.
+ * omp-offload.c (execute_oacc_device_lower): Adjust.
+
+2020-11-13 Jan Hubicka <jh@suse.cz>
+
+ * ipa-modref.c (modref_summaries::insert,
+ modref_summaries_lto::insert): Remove summary if ipa-modref is disabled.
+
+2020-11-13 Jan Hubicka <jh@suse.cz>
+
+ * attr-fnspec.h (attr_fnspec::arg_readonly_p): Accept '1'...'9'.
+
+2020-11-13 Peter Jones <pjones@redhat.com>
+
+ * doc/extend.texi: Clarify the documentation for the ms_abi
+ function attribute.
+
+2020-11-13 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range.h (gimple_range_handler): Cast to gimple stmt
+ kinds before asking for code and type.
+ * gimple.h (gimple_expr_code): Call gassign and gcond routines
+ to get their expr_code.
+
+2020-11-13 Jason Merrill <jason@redhat.com>
+
+ * dwarf2out.c (gen_enumeration_type_die): Call
+ equate_decl_number_to_die for enumerators.
+ (gen_member_die): Don't move enumerators to their
+ enclosing class.
+ (dwarf2out_imported_module_or_decl_1): Allow importing
+ individual enumerators.
+ (force_decl_die): Handle CONST_DECL.
+
+2020-11-13 Vladimir N. Makarov <vmakarov@redhat.com>
+
+ * cfgexpand.c (expand_asm_stmt): Output asm goto with outputs too.
+ Place insns after asm goto on edges.
+ * doc/extend.texi: Reflect the changes in asm goto documentation.
+ * gimple.c (gimple_build_asm_1): Remove an assert checking output
+ absence for asm goto.
+ * gimple.h (gimple_asm_label_op, gimple_asm_set_label_op): Take
+ possible asm goto outputs into account.
+ * ira.c (ira): Remove critical edges for potential asm goto output
+ reloads.
+ (ira_nullify_asm_goto): New function.
+ * ira.h (ira_nullify_asm_goto): New prototype.
+ * lra-assigns.c (lra_split_hard_reg_for): Use ira_nullify_asm_goto.
+ Check that splitting is done inside a basic block.
+ * lra-constraints.c (curr_insn_transform): Permit output reloads
+ for any jump insn.
+ * lra-spills.c (lra_final_code_change): Remove USEs added in ira
+ for asm gotos.
+ * lra.c (lra_process_new_insns): Place output reload insns after
+ jumps in the beginning of destination BBs.
+ * reload.c (find_reloads): Report error for asm gotos with
+ outputs. Modify them to keep CFG consistency to avoid crashes.
+ * tree-into-ssa.c (rewrite_stmt): Don't put debug stmt after asm
+ goto.
+
+2020-11-13 Jakub Jelinek <jakub@redhat.com>
+
+ * omp-low.c (scan_sharing_clauses): For now remove for reduction
+ clauses with inscan or task modifiers decl from allocate_map.
+ (lower_private_allocate): Handle TYPE_P (new_var).
+ (lower_rec_input_clauses): Handle allocate clause for C/C++ array
+ reductions.
+
+2020-11-13 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/97816
+ * ipa-cp.c (value_topo_info<valtype>::propagate_effects): Use
+ safe_add instead of a simple addition.
+
+2020-11-13 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * config/msp430/msp430.c (TARGET_INSN_COST): Define.
+ (msp430_insn_cost): New function.
+ * config/msp430/msp430.h (BRANCH_COST): Define.
+ (LOGICAL_OP_NON_SHORT_CIRCUIT): Define.
+
+2020-11-13 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * config/msp430/msp430-protos.h (msp430x_extendhisi): Return int
+ instead of char *.
+ (msp430_output_asm_shift_insns): Likewise.
+ Add new return_length argument.
+ (msp430x_insn_required): Add prototype.
+ * config/msp430/msp430.c (msp430_output_asm_shift_insns): Return the
+ total length, in bytes, of the emitted instructions.
+ (msp430x_insn_required): New function.
+ (msp430x_extendhisi): Return the total length, in bytes, of the
+ emitted instructions.
+ * config/msp430/msp430.h (ADJUST_INSN_LENGTH): Define.
+ * config/msp430/msp430.md: New define_attr "type".
+ New define_attr "extension".
+ New define_attr "length_multiplier".
+ New define_attr "extra_length".
+ Rewrite define_attr "length".
+ Set type, extension, length, length_multiplier or extra_length insn
+ attributes on all insns, as appropriate.
+ (andneghi3): Rewrite using constraints instead of C code to decide
+ output insns.
+ * config/msp430/predicates.md (msp430_cheap_operand): New predicate.
+ (msp430_high_memory_operand): New predicate.
+
+2020-11-13 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * config/msp430/msp430.c (use_helper_for_const_shift): Add forward
+ declaration.
+ Remove unused argument.
+ (struct msp430_multlib_costs): New struct.
+ (msp430_is_mem_indirect): New function.
+ (msp430_costs): Likewise.
+ (msp430_shift_costs): Likewise.
+ (msp430_muldiv_costs): Likewise.
+ (msp430_get_inner_dest_code): Likewise.
+ (msp430_single_op_cost): Likewise.
+ (msp430_rtx_costs): Rewrite from scratch.
+ (msp430_expand_shift): Adjust use_helper_for_const_shift call.
+
+2020-11-13 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * config/msp430/msp430.c (struct single_op_cost): New struct.
+ (struct double_op_cost): Likewise.
+ (TARGET_REGISTER_MOVE_COST): Don't define but add comment.
+ (TARGET_MEMORY_MOVE_COST): Define to...
+ (msp430_memory_move_cost): New function.
+ (BRANCH_COST): Don't define but add comment.
+
+2020-11-13 Jan Hubicka <jh@suse.cz>
+
+ * ipa-icf-gimple.c: Include tree-ssa-alias-compare.h.
+ (find_checker::func_checker): Initialize m_tbaa.
+ (func_checker::hash_operand): Use hash_ao_ref for memory accesses.
+ (func_checker::compare_operand): Use compare_ao_refs for memory
+ accesses.
+ (func_checker::cmopare_gimple_assign): Do not check LHS types
+ of memory stores.
+ * ipa-icf-gimple.h (func_checker): Derive from ao_compare;
+ add m_tbaa.
+ * ipa-icf.c: Include tree-ssa-alias-compare.h.
+ (sem_function::equals_private): Update call of
+ func_checker::func_checker.
+ * ipa-utils.h (lto_streaming_expected_p): New inline
+ predicate.
+ * tree-ssa-alias-compare.h: New file.
+ * tree-ssa-alias.c: Include tree-ssa-alias-compare.h
+ and bultins.h
+ (view_converted_memref_p): New function.
+ (types_equal_for_same_type_for_tbaa_p): New function.
+ (ao_ref_alias_ptr_type, ao_ref_base_alias_ptr_type): New functions.
+ (ao_compare::compare_ao_refs): New member function.
+ (ao_compare::hash_ao_ref): New function
+ * tree-ssa-alias.h (ao_ref_base_alias_ptr_type,
+ ao_ref_alias_ptr_type): Declare.
+
+2020-11-13 Jan Hubicka <jh@suse.cz>
+
+ * ipa-icf-gimple.c: Include gimple-walk.h.
+ (func_checker::compare_ssa_name): Update call of compare_operand.
+ (func_checker::hash_operand): Fix comment and add variant taking
+ operand_access_type parameter.
+ (func_checker::compare_operand): Add operand_access_type parameter.
+ (func_checker::compare_asm_inputs_outputs): Add
+ operand_access_type_map parameter; update use of
+ func_checker::compare_operand.
+ (func_checker::compare_gimple_call): Update use of
+ func_checker::compare_operand.
+ (func_checker::compare_gimple_assign): Likewise.
+ (func_checker::compare_gimple_cond): Likewise.
+ (func_checker::compare_gimple_switch): Likewise.
+ (func_checker::compare_gimple_return): Likewise.
+ (func_checker::compare_gimple_goto): Likewise.
+ (func_checker::compare_gimple_asm): Likewise.
+ (visit_load_store): New static functio.
+ (func_checker::classify_operands): New member function.
+ (func_checker::get_operand_access_type): New member function.
+ * ipa-icf-gimple.h (func_checker::operand_access_type): New enum
+ (func_checker::operand_access_type_map): New typedef.
+ (func_checker::compare_operand): Update prototype.
+ (func_checker::compare_asm_inputs_outputs): Likewise.
+ (func_checker::cleassify_operands): Declare.
+ (func_checker::get_operand_access_type): Declare.
+ (func_checker::hash_operand): New variant with operand_access_type.
+ * ipa-icf.c (sem_function::hash_stmt): Update uses of hash_operand.
+ (sem_function::compare_phi_node): Update use of compare_operand.
+
+2020-11-13 Andrea Corallo <andrea.corallo@arm.com>
+
+ * config/arm/aarch-common.c (aarch_accumulator_forwarding): Use
+ RTL predicates where possible.
+ * config/arm/arm.c (legitimate_pic_operand_p)
+ (legitimize_pic_address, arm_is_segment_info_known)
+ (can_avoid_literal_pool_for_label_p)
+ (thumb1_legitimate_address_p, arm_legitimize_address)
+ (arm_tls_referenced_p, thumb_legitimate_constant_p)
+ (REG_OR_SUBREG_REG, thumb1_rtx_costs, thumb1_size_rtx_costs)
+ (arm_adjust_cost, arm_coproc_mem_operand_wb)
+ (neon_vector_mem_operand, neon_struct_mem_operand)
+ (symbol_mentioned_p, label_mentioned_p, )
+ (load_multiple_sequence, store_multiple_sequence)
+ (arm_select_cc_mode, arm_reload_in_hi, arm_reload_out_hi)
+ (mem_ok_for_ldrd_strd, arm_emit_call_insn, output_move_neon)
+ (arm_attr_length_move_neon, arm_assemble_integer)
+ (arm_emit_coreregs_64bit_shift, arm_valid_symbolic_address_p)
+ (extract_base_offset_in_addr, fusion_load_store): Likewise.
+
+2020-11-13 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range.cc: (gimple_ranger::range_of_range_op): Check for
+ ADDR_EXPR and call range_of_address.
+ (gimple_ranger::range_of_address): Rename from
+ range_of_non_trivial_assignment and match vrp_stmt_computes_nonzero.
+ * gimple-range.h: (range_of_address): Renamed.
+ * range-op.cc: (pointer_table): Add INTEGER_CST handler.
+
+2020-11-13 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/94406
+ * tree-ssa-loop-im.c (tree_ssa_lim): Renamed to
+ loop_invariant_motion_in_fun, added a parameter to control store
+ motion.
+ (pass_lim::execute): Adjust call to tree_ssa_lim, now
+ loop_invariant_motion_in_fun.
+ * tree-ssa-loop-manip.h (loop_invariant_motion_in_fun): Declare.
+ * gimple-loop-interchange.cc (pass_linterchange::execute): Call
+ loop_invariant_motion_in_fun if any interchange has been done.
+
+2020-11-13 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-sccvn.c (vn_phi_compute_hash): Always hash the
+ number of predecessors. Hash the block number also for
+ loop header PHIs.
+ (expressions_equal_p): Short-cut SSA name compares, remove
+ test for NULL operands.
+ (vn_phi_eq): Cache number of predecessors, change inlined
+ test from expressions_equal_p.
+
+2020-11-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ * doc/extend.texi: Don't try to line-wrap an @r command.
+
+2020-11-13 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97812
+ * tree-vrp.c (register_edge_assert_for_2): Extend the range
+ according to its sign before seeing whether it fits.
+
+2020-11-13 Andrea Corallo <andrea.corallo@arm.com>
+
+ * config/aarch64/aarch64.c (tls_symbolic_operand_type)
+ (aarch64_load_symref_appropriately, aarch64_mov128_immediate)
+ (aarch64_expand_mov_immediate)
+ (aarch64_maybe_expand_sve_subreg_move)
+ (aarch64_tls_referenced_p, aarch64_cannot_force_const_mem)
+ (aarch64_base_register_rtx_p, aarch64_classify_index)
+ (aarch64_classify_address, aarch64_symbolic_address_p)
+ (aarch64_reinterpret_float_as_int, aarch64_float_const_rtx_p)
+ (aarch64_can_const_movi_rtx_p, aarch64_select_cc_mode)
+ (aarch64_print_operand, aarch64_label_mentioned_p)
+ (aarch64_secondary_reload, aarch64_preferred_reload_class)
+ (aarch64_address_cost, aarch64_tls_symbol_p)
+ (aarch64_classify_symbol, aarch64_legitimate_pic_operand_p)
+ (aarch64_legitimate_constant_p)
+ (aarch64_sve_float_arith_immediate_p)
+ (aarch64_sve_float_mul_immediate_p, aarch64_mov_operand_p)
+ (fusion_load_store): Use RTL operands where possible.
+
+2020-11-13 Sudakshina Das <sudi.das@arm.com>
+
+ * config/aarch64/aarch64-protos.h (aarch64_expand_setmem): New
+ declaration.
+ * config/aarch64/aarch64.c (aarch64_gen_store_pair): Add case for
+ E_V16QImode.
+ (aarch64_set_one_block_and_progress_pointer): New helper for
+ aarch64_expand_setmem.
+ (aarch64_expand_setmem): Define the expansion for memset.
+ * config/aarch64/aarch64.h (CLEAR_RATIO): Tweak to favor
+ aarch64_expand_setmem when allowed and profitable.
+ (SET_RATIO): Likewise.
+ * config/aarch64/aarch64.md: Define pattern for setmemdi.
+
+2020-11-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR objc/90707
+ * doc/extend.texi: Document the objc_nullability attribute.
+
+2020-11-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR objc/77404
+ * doc/extend.texi: Document the objc_root_class attribute.
+ * doc/invoke.texi: Document -Wobjc-root-class.
+
+2020-11-13 Richard Biener <rguenther@suse.de>
+
+ * cfgexpand.c (gimple_assign_rhs_to_tree): Use
+ gimple_assign_rhs_class.
+ (expand_gimple_stmt_1): Likewise.
+ * gimplify-me.c (gimple_regimplify_operands): Use
+ gimple_assign_single_p.
+ * ipa-icf-gimple.c (func_checker::compare_gimple_assign):
+ Remove redundant compare.
+ (func_checker::compare_gimple_cond): Use gimple_cond_code.
+ * tree-ssa-tail-merge.c (gimple_equal_p): Likewise.
+ * predict.c (predict_loops): Use gimple_assign_rhs_code.
+
+2020-11-13 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-vrp.c (class vrp_folder): Make visit_stmt, visit_phi,
+ and m_vr_values private.
+ (vrp_folder::vrp_evaluate_conditional): Remove.
+ (vrp_folder::vrp_simplify_stmt_using_ranges): Remove.
+ (vrp_folder::fold_predicate_in): Inline
+ vrp_evaluate_conditional and vrp_simplify_stmt_using_ranges.
+ (vrp_folder::fold_stmt): Same.
+
+2020-11-13 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-vrp.c (class vrp_prop): Rename vr_values to m_vr_values.
+ (vrp_prop::vrp_prop): New.
+ (vrp_prop::initialize): Rename vr_values to m_vr_values.
+ (vrp_prop::visit_stmt): Same.
+ (vrp_prop::visit_phi): Same.
+ (vrp_prop::finalize): Same.
+ (execute_vrp): Instantiate vrp_vr_values and pass it to folder
+ and propagator.
+
+2020-11-13 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-vrp.c (class vrp_prop): Move entire class...
+ (class vrp_folder): ...before here.
+
+2020-11-13 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-vrp.c (identify_jump_threads): Refactor to..
+ (vrp_jump_threader::vrp_jump_threader): ...here
+ (vrp_jump_threader::~vrp_jump_threader): ...and here.
+ (vrp_jump_threader::after_dom_children): Rename vr_values to
+ m_vr_values.
+ (execute_vrp): Use vrp_jump_threader.
+
+2020-11-13 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-vrp.c (struct assert_locus): Move.
+ (class vrp_insert): Rename to vrp_asserts.
+ (vrp_insert::build_assert_expr_for): Move to vrp_asserts.
+ (fp_predicate): Same.
+ (vrp_insert::dump): Same.
+ (vrp_insert::register_new_assert_for): Same.
+ (extract_code_and_val_from_cond_with_ops): Move.
+ (vrp_insert::finish_register_edge_assert_for): Move to vrp_asserts.
+ (maybe_set_nonzero_bits): Move.
+ (vrp_insert::find_conditional_asserts): Move to vrp_asserts.
+ (stmt_interesting_for_vrp): Move.
+ (struct case_info): Move.
+ (compare_case_labels): Move.
+ (lhs_of_dominating_assert): Move.
+ (find_case_label_index): Move.
+ (find_case_label_range): Move.
+ (class vrp_asserts): New.
+ (vrp_asserts::build_assert_expr_for): Rename from vrp_insert.
+ (vrp_asserts::dump): Same.
+ (vrp_asserts::register_new_assert_for): Same.
+ (vrp_asserts::finish_register_edge_assert_for): Same.
+ (vrp_asserts::find_conditional_asserts): Same.
+ (vrp_asserts::compare_case_labels): Same.
+ (vrp_asserts::find_switch_asserts): Same.
+ (vrp_asserts::find_assert_locations_in_bb): Same.
+ (vrp_asserts::find_assert_locations): Same.
+ (vrp_asserts::process_assert_insertions_for): Same.
+ (vrp_asserts::compare_assert_loc): Same.
+ (vrp_asserts::process_assert_insertions): Same.
+ (vrp_asserts::insert_range_assertions): Same.
+ (vrp_asserts::all_imm_uses_in_stmt_or_feed_cond): Same.
+ (vrp_asserts::remove_range_assertions): Same.
+ (class vrp_prop): Move.
+ (all_imm_uses_in_stmt_or_feed_cond): Move.
+ (vrp_prop::vrp_initialize): Move.
+ (class vrp_folder): Move.
+ (vrp_folder::fold_predicate_in): Move.
+ (vrp_folder::fold_stmt): Move.
+ (vrp_prop::initialize): Move.
+ (vrp_prop::visit_stmt): Move.
+ (enum ssa_prop_result): Move.
+ (vrp_prop::visit_phi): Move.
+ (vrp_prop::finalize): Move.
+ (class vrp_dom_walker): Rename to...
+ (class vrp_jump_threader): ...this.
+ (vrp_jump_threader::before_dom_children): Rename from
+ vrp_dom_walker.
+ (simplify_stmt_for_jump_threading): Rename to...
+ (vrp_jump_threader::simplify_stmt): ...here.
+ (vrp_jump_threader::after_dom_children): Same.
+ (identify_jump_threads): Move.
+ (vrp_prop::vrp_finalize): Move array bounds setup code to...
+ (execute_vrp): ...here.
+
+2020-11-13 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range.h (gimple_range_handler): Use gimple_assign and
+ gimple_cond routines to get type and code.
+ * range-op.cc (range_op_handler): Check for integral types.
+
+2020-11-12 Nelson Chu <nelson.chu@sifive.com>
+
+ * configure: Regenerated.
+ * configure.ac: If ifunc was supported in the binutils for
+ linux toolchain, then set enable_gnu_indirect_function to yes.
+
+2020-11-12 Joseph Myers <joseph@codesourcery.com>
+
+ * doc/cpp.texi (__has_attribute): Document when scopes are allowed
+ for C.
+ (__has_c_attribute): New.
+
+2020-11-12 Jakub Jelinek <jakub@redhat.com>
+
+ * builtin-types.def (BT_FN_PTR_SIZE_SIZE_PTRMODE): New function type.
+ * omp-builtins.def (BUILT_IN_GOACC_DECLARE): Move earlier.
+ (BUILT_IN_GOMP_ALLOC, BUILT_IN_GOMP_FREE): New builtins.
+ * gimplify.c (gimplify_scan_omp_clauses): Force allocator into a
+ decl if it is not NULL, INTEGER_CST or decl.
+ (gimplify_adjust_omp_clauses): Clear GOVD_EXPLICIT on explicit clauses
+ which are being removed. Remove allocate clauses for variables not seen
+ if they are private, firstprivate or linear too. Call
+ omp_notice_variable on the allocator otherwise.
+ (gimplify_omp_for): Handle iterator vars mentioned in allocate clauses
+ similarly to non-is_gimple_reg iterators.
+ * omp-low.c (struct omp_context): Add allocate_map field.
+ (delete_omp_context): Delete it.
+ (scan_sharing_clauses): Fill it from allocate clauses. Remove it
+ if mentioned also in shared clause.
+ (lower_private_allocate): New function.
+ (lower_rec_input_clauses): Handle allocate clause for privatized
+ variables, except for task/taskloop, C/C++ array reductions for now
+ and task/inscan variables.
+ (lower_send_shared_vars): Don't consider variables in allocate_map
+ as shared.
+ * omp-expand.c (expand_omp_for_generic, expand_omp_for_static_nochunk,
+ expand_omp_for_static_chunk): Use expand_omp_build_assign instead of
+ gimple_build_assign + gsi_insert_after.
+ * builtins.c (builtin_fnspec): Handle BUILTIN_GOMP_ALLOC and
+ BUILTIN_GOMP_FREE.
+ * tree-ssa-ccp.c (evaluate_stmt): Handle BUILTIN_GOMP_ALLOC.
+ * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Handle
+ BUILTIN_GOMP_ALLOC.
+ (mark_all_reaching_defs_necessary_1): Handle BUILTIN_GOMP_ALLOC
+ and BUILTIN_GOMP_FREE.
+ (propagate_necessity): Likewise.
+
+2020-11-12 Martin Jambor <mjambor@suse.cz>
+
+ * cgraphclones.c (cgraph_node::materialize_clone): Check that clone
+ info is not NULL before attempting to dump it.
+
+2020-11-12 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-cp.c (class ipcp_value_base): Change the type of
+ local_time_benefit and prop_time_benefit to sreal. Adjust the
+ constructor initializer.
+ (ipcp_lattice::print): Dump sreals.
+ (struct caller_statistics): Change the type of freq_sum to sreal.
+ (gather_caller_stats): Work with sreal freq_sum.
+ (incorporate_penalties): Work with sreal evaluation.
+ (good_cloning_opportunity_p): Adjusted for sreal sreal time_benefit
+ and freq_sum. Bail out if size_cost is INT_MAX.
+ (perform_estimation_of_a_value): Work with sreal time_benefit. Avoid
+ unnecessary capping.
+ (estimate_local_effects): Pass sreal time benefit to
+ good_cloning_opportunity_p without capping it. Adjust dumping.
+ (safe_add): If there can be overflow, return INT_MAX.
+ (propagate_effects): Work with sreal times.
+ (get_info_about_necessary_edges): Work with sreal frequencies.
+ (decide_about_value): Likewise and with sreal time benefits.
+
+2020-11-12 Marek Polacek <polacek@redhat.com>
+
+ * system.h (WARN_UNUSED_RESULT): Define for GCC >= 3.4.
+ * tree.h (maybe_wrap_with_location): Add WARN_UNUSED_RESULT.
+
+2020-11-12 Jan Hubicka <jh@suse.cz>
+
+ * fold-const.c (operand_compare::operand_equal_p): Compare field
+ offsets in operand_equal_p and OEP_ADDRESS_OF.
+ (operand_compare::hash_operand): Update.
+
+2020-11-12 Richard Biener <rguenther@suse.de>
+
+ * bitmap.c (bitmap_list_view): Restore head->current.
+ * tree-ssa-pre.c (pre_expr_DFS): Elide expr_visited bitmap.
+ Special-case value expression bitmaps with one element.
+ (bitmap_find_leader): Likewise.
+ (sorted_array_from_bitmap_set): Elide expr_visited bitmap.
+
+2020-11-12 Jan Hubicka <jh@suse.cz>
+
+ * attr-fnspec.h: Update topleve comment.
+ (attr_fnspec::arg_direct_p): Accept 1...9.
+ (attr_fnspec::arg_maybe_written_p): Reject 1...9.
+ (attr_fnspec::arg_copied_to_arg_p): New member function.
+ * builtins.c (builtin_fnspec): Update fnspec of block copy.
+ * tree-ssa-alias.c (attr_fnspec::verify): Update.
+
+2020-11-12 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-pre.c (bitmap_value_replace_in_set): Return
+ whether we have changed anything.
+ (do_pre_regular_insertion): Get topologically sorted array
+ of expressions from caller.
+ (do_pre_partial_partial_insertion): Likewise.
+ (insert): Compute topologically sorted arrays of expressions
+ here and locally iterate actual insertion. Iterate only
+ when AVAIL_OUT of an already visited block source changed.
+
+2020-11-12 Alex Coplan <alex.coplan@arm.com>
+
+ PR target/97730
+ * config/aarch64/aarch64-sve2.md (@aarch64_sve2_bcax<mode>):
+ Change to define_expand, add missing (trivially-predicated) not
+ rtx to fix wrong code bug.
+ (*aarch64_sve2_bcax<mode>): New.
+
+2020-11-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97806
+ * tree-ssa-pre.c (pre_expr_DFS): New overload for visiting
+ values, visiting all leaders for a value. Use a bitmap
+ for visited values.
+ (sorted_array_from_bitmap_set): Walk over values and adjust.
+
+2020-11-12 Andreas Krebbel <krebbel@linux.ibm.com>
+
+ PR target/97326
+ * config/s390/vector.md: Support vector floating point modes in
+ vec_cmp.
+
+2020-11-12 Andreas Krebbel <krebbel@linux.ibm.com>
+
+ * config/s390/vector.md: Rename tointvec to TOINTVEC.
+ * config/s390/vx-builtins.md: Likewise.
+
+2020-11-12 Jason Merrill <jason@redhat.com>
+
+ PR debug/97060
+ * dwarf2out.c (gen_subprogram_die): It's a declaration
+ if DECL_INITIAL isn't set.
+
+2020-11-12 David Malcolm <dmalcolm@redhat.com>
+
+ PR tree-optimization/97424
+ * doc/invoke.texi (Static Analyzer Options): Add
+ -Wno-analyzer-shift-count-negative and
+ -Wno-analyzer-shift-count-overflow.
+ (-Wno-analyzer-shift-count-negative): New.
+ (-Wno-analyzer-shift-count-overflow): New.
+
+2020-11-11 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config/darwin-protos.h (darwin_make_eh_symbol_indirect): New.
+ * config/darwin.c (darwin_make_eh_symbol_indirect): New. Use
+ Mach-O semantics for personality and ldsa indirections.
+ * config/darwin.h (TARGET_ASM_MAKE_EH_SYMBOL_INDIRECT): New.
+ * doc/tm.texi: Regenerate.
+ * doc/tm.texi.in: Add TARGET_ASM_MAKE_EH_SYMBOL_INDIRECT hook.
+ * dwarf2out.c (dwarf2out_do_cfi_startproc): If the target defines
+ a hook for indirecting personality and ldsa references, use that
+ otherwise default to ELF semantics.
+ * target.def (make_eh_symbol_indirect): New target hook.
+
+2020-11-11 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/88115
+ * common.opt (-fabi-version): Document =15.
+ * doc/invoke.texi (C++ Dialect Options): Likewise.
+
+2020-11-11 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97518
+ * tree.c (maybe_wrap_with_location): Don't add a location
+ wrapper around an artificial and ignored decl.
+
+2020-11-11 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97623
+ * tree-ssa-pre.c (create_expression_by_pieces): Guard
+ NEW_SETS access.
+ (insert_into_preds_of_block): Likewise.
+
+2020-11-11 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-pre.c (pre_expr_DFS): New function.
+ (sorted_array_from_bitmap_set): Use it to properly
+ topologically sort the expression set.
+ (clean): Verify we've cleaned everything we should.
+
+2020-11-11 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97623
+ * params.opt (-param=max-pre-hoist-insert-iterations): Remove
+ again.
+ * doc/invoke.texi (max-pre-hoist-insert-iterations): Likewise.
+ * tree-ssa-pre.c (insert): Move hoist insertion after PRE
+ insertion iteration and do not iterate it.
+
+2020-11-11 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve.md (@vcond_mask_<mode><vpred>): Extend
+ from SVE_FULL to SVE_ALL.
+ (*vcond_mask_<mode><vpred>): Likewise.
+ (@aarch64_sel_dup<mode>): Likewise.
+ (vcond<SVE_FULL:mode><v_int_equiv>): Extend to...
+ (vcond<SVE_ALL:mode><SVE_I:mode>): ...this, but requiring the
+ sizes of the container modes to match.
+ (vcondu<SVE_FULL:mode><v_int_equiv>): Extend to...
+ (vcondu<SVE_ALL:mode><SVE_I:mode>): ...this.
+ (vec_cmp<SVE_FULL_I:mode><vpred>): Extend to...
+ (vec_cmp<SVE_I:mode><vpred>): ...this.
+ (vec_cmpu<SVE_FULL_I:mode><vpred>): Extend to...
+ (vec_cmpu<SVE_I:mode><vpred>): ...this.
+ (@aarch64_pred_cmp<cmp_op><SVE_FULL_I:mode>): Extend to...
+ (@aarch64_pred_cmp<cmp_op><SVE_I:mode>): ...this.
+ (*cmp<cmp_op><SVE_FULL_I:mode>_cc): Extend to...
+ (*cmp<cmp_op><SVE_I:mode>_cc): ...this.
+ (*cmp<cmp_op><SVE_FULL_I:mode>_ptest): Extend to...
+ (*cmp<cmp_op><SVE_I:mode>_ptest): ...this.
+ (*cmp<cmp_op><SVE_FULL_I:mode>_and): Extend to...
+ (*cmp<cmp_op><SVE_I:mode>_and): ...this.
+
+2020-11-11 Richard Sandiford <richard.sandiford@arm.com>
+
+ * optabs-tree.c (expand_vec_cond_expr_p): Allow the compared values
+ and the selected values to have different mode sizes.
+ * gimple-isel.cc (gimple_expand_vec_cond_expr): Likewise.
+
+2020-11-11 Hongtao Liu <hongtao.liu@intel.com>
+ Hongyu Wang <hongyu.wang@intel.com>
+
+ * common/config/i386/cpuinfo.h (get_available_features):
+ Detect AVXVNNI.
+ * common/config/i386/i386-common.c
+ (OPTION_MASK_ISA2_AVXVNNI_SET,
+ OPTION_MASK_ISA2_AVXVNNI_UNSET): New.
+ (OPTION_MASK_ISA2_AVX2_UNSET): Add AVXVNNI.
+ (ix86_hanlde_option): Handle -mavxvnni, unset avxvnni when
+ avx2 is disabled.
+ * common/config/i386/i386-cpuinfo.h (enum processor_features):
+ Add FEATURE_AVXVNNI.
+ * common/config/i386/i386-isas.h: Add ISA_NAMES_TABLE_ENTRY
+ for avxvnni.
+ * config.gcc: Add avxvnniintrin.h.
+ * config/i386/avx512vnnivlintrin.h: Reimplement 128/256 bit non-mask
+ intrinsics with macros to support unified interface.
+ * config/i386/avxvnniintrin.h: New header file.
+ * config/i386/cpuid.h (bit_AVXVNNI): New.
+ * config/i386/i386-builtins.c (def_builtin): Handle AVXVNNI mask
+ for unified builtin.
+ * config/i386/i386-builtin.def (BDESC): Adjust AVX512VNNI
+ builtins for AVXVNNI.
+ * config/i386/i386-c.c (ix86_target_macros_internal): Define
+ __AVXVNNI__.
+ * config/i386/i386-expand.c (ix86_expand_builtin): Handle bisa
+ for AVXVNNI to support unified intrinsic name, since there is no
+ dependency between AVX512VNNI and AVXVNNI.
+ * config/i386/i386-options.c (isa2_opts): Add -mavxvnni.
+ (ix86_valid_target_attribute_inner_p): Handle avxnnni.
+ (ix86_option_override_internal): Ditto.
+ * config/i386/i386.h (TARGET_AVXVNNI, TARGET_AVXVNNI_P,
+ TARGET_AVXVNNI_P, PTA_AVXVNNI): New.
+ (PTA_SAPPHIRERAPIDS): Add AVX_VNNI.
+ (PTA_ALDERLAKE): Likewise.
+ * config/i386/i386.md ("isa"): Add avxvnni, avx512vnnivl.
+ ("enabled"): Adjust for avxvnni and avx512vnnivl.
+ * config/i386/i386.opt: Add option -mavxvnni.
+ * config/i386/immintrin.h: Include avxvnniintrin.h.
+ * config/i386/sse.md (vpdpbusd_<mode>): Adjust for AVXVNNI.
+ (vpdpbusds_<mode>): Likewise.
+ (vpdpwssd_<mode>): Likewise.
+ (vpdpwssds_<mode>): Likewise.
+ (vpdpbusd_v16si): New.
+ (vpdpbusds_v16si): Likewise.
+ (vpdpwssd_v16si): Likewise.
+ (vpdpwssds_v16si): Likewise.
+ * doc/invoke.texi: Document -mavxvnni.
+ * doc/extend.texi: Document avxvnni.
+ * doc/sourcebuild.texi: Document target avxvnni.
+
+2020-11-11 Martin Liska <mliska@suse.cz>
+
+ * tree.c (copy_node): Fix spelling.
+
+2020-11-11 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-pre.c (phi_translate_set): Do not sort the
+ expression set topologically.
+
+2020-11-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * value-range.cc (irange::set): Early exit on VR_VARYING.
+
+2020-11-11 Zhiheng Xie <xiezhiheng@huawei.com>
+ Nannan Zheng <zhengnannan@huawei.com>
+
+ * config/aarch64/aarch64-simd-builtins.def: Add proper FLAG
+ for arithmetic operation intrinsics.
+
+2020-11-11 Strager Neds <strager.nds@gmail.com>
+
+ * cgraph.h (symtab_node::set_section_for_node): Declare new
+ overload.
+ (symtab_node::set_section_from_string): Rename from set_section.
+ (symtab_node::set_section_from_node): Declare.
+ * symtab.c (symtab_node::set_section_for_node): Define new
+ overload.
+ (symtab_node::set_section_from_string): Rename from set_section.
+ (symtab_node::set_section_from_node): Define.
+ (symtab_node::set_section): Call renamed set_section_from_string.
+ (symtab_node::set_section): Call new set_section_from_node.
+
+2020-11-11 Strager Neds <strager.nds@gmail.com>
+
+ * symtab.c (symtab_node::set_section_for_node): Extract reference
+ counting logic into ...
+ (retain_section_hash_entry): ... here (new function) and ...
+ (release_section_hash_entry): ... here (new function).
+
+2020-11-11 liuhongt <hongtao.liu@intel.com>
+
+ * config/i386/i386.h (PTA_MOVDIRI, PTA_MOVDIR64B,
+ PTA_AMX_TILE, PTA_AMX_INT8, PTA_AMX_BF16, PTA_HRESET):
+ Formatting.
+
+2020-11-11 Ilya Leoshkevich <iii@linux.ibm.com>
+
+ * config/s390/s390.h (HAVE_TF): Use opaque value when
+ GENERATOR_FILE is defined.
+
+2020-11-10 Strager Neds <strager.nds@gmail.com>
+
+ * cgraph.h (symtab_node::get_section): Constify.
+ (symtab_node::set_section): Declare new overload.
+ * symtab.c (symtab_node::set_section): Define new overload.
+ (symtab_node::copy_visibility_from): Use new overload of
+ symtab_node::set_section.
+ (symtab_node::resolve_alias): Same.
+ * tree.h (set_decl_section_name): Declare new overload.
+ * tree.c (set_decl_section_name): Define new overload.
+ * tree-emutls.c (get_emutls_init_templ_addr): Same.
+ * cgraphclones.c (cgraph_node::create_virtual_clone): Use new
+ overload of symtab_node::set_section.
+ (cgraph_node::create_version_clone_with_body): Same.
+ * trans-mem.c (ipa_tm_create_version): Same.
+
+2020-11-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * value-range.cc (irange::set): Early exit for poly ints.
+
+2020-11-10 Tobias Burnus <tobias@codesourcery.com>
+
+ * gimplify.c (gimplify_scan_omp_clauses, gimplify_omp_loop): Use 'do'
+ instead of 'for' in error messages for Fortran.
+ * omp-low.c (check_omp_nesting_restrictions): Likewise
+
+2020-11-10 Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * opts.c (control_options_for_live_patching): Reform 'is incompatible
+ with' error messages to use a standard message with differing format
+ arguments.
+ (finish_options): Likewise.
+
+2020-11-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97769
+ * tree-vect-data-refs.c (vect_update_misalignment_for_peel):
+ Remove assert.
+
+2020-11-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97780
+ * tree-ssa-pre.c (fini_pre): Deal with added basic blocks
+ when freeing PHI_TRANS_TABLE.
+
+2020-11-10 Zhiheng Xie <xiezhiheng@huawei.com>
+ Nannan Zheng <zhengnannan@huawei.com>
+
+ * config/aarch64/aarch64-simd-builtins.def: Add proper FLAG
+ for tbl/tbx intrinsics.
+
+2020-11-10 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * gimplify.c (is_or_contains_p): New static helper function.
+ (omp_target_reorder_clauses): New function.
+ (gimplify_scan_omp_clauses): Add use of omp_target_reorder_clauses to
+ reorder clause list according to OpenMP 5.0 rules. Add handling of
+ GOMP_MAP_ATTACH_DETACH for OpenMP cases.
+ * omp-low.c (is_omp_target): New static helper function.
+ (scan_sharing_clauses): Add scan phase handling of GOMP_MAP_ATTACH/DETACH
+ for OpenMP cases.
+ (lower_omp_target): Add lowering handling of GOMP_MAP_ATTACH/DETACH for
+ OpenMP cases.
+
+2020-11-10 Ilya Leoshkevich <iii@linux.ibm.com>
+
+ * config/s390/s390-modes.def (FPRX2): New mode.
+ * config/s390/s390-protos.h (s390_fma_allowed_p): New function.
+ * config/s390/s390.c (s390_fma_allowed_p): Likewise.
+ (s390_build_signbit_mask): Support 128-bit masks.
+ (print_operand): Support printing the second word of a TFmode
+ operand as vector register.
+ (constant_modes): Add FPRX2mode.
+ (s390_class_max_nregs): Return 1 for TFmode on z14+.
+ (s390_is_fpr128): New function.
+ (s390_is_vr128): Likewise.
+ (s390_can_change_mode_class): Use s390_is_fpr128 and
+ s390_is_vr128 in order to determine whether mode refers to a FPR
+ pair or to a VR.
+ (s390_emit_compare): Force TFmode operands into registers on
+ z14+.
+ * config/s390/s390.h (HAVE_TF): New macro.
+ (EXPAND_MOVTF): New macro.
+ (EXPAND_TF): Likewise.
+ * config/s390/s390.md (PFPO_OP_TYPE_FPRX2): PFPO_OP_TYPE_TF
+ alias.
+ (ALL): Add FPRX2.
+ (FP_ALL): Add FPRX2 for z14+, restrict TFmode to z13-.
+ (FP): Likewise.
+ (FP_ANYTF): New mode iterator.
+ (BFP): Add FPRX2 for z14+, restrict TFmode to z13-.
+ (TD_TF): Likewise.
+ (xde): Add FPRX2.
+ (nBFP): Likewise.
+ (nDFP): Likewise.
+ (DSF): Likewise.
+ (DFDI): Likewise.
+ (SFSI): Likewise.
+ (DF): Likewise.
+ (SF): Likewise.
+ (fT0): Likewise.
+ (bt): Likewise.
+ (_d): Likewise.
+ (HALF_TMODE): Likewise.
+ (tf_fpr): New mode_attr.
+ (type): New mode_attr.
+ (*cmp<mode>_ccz_0): Use type instead of mode with fsimp.
+ (*cmp<mode>_ccs_0_fastmath): Likewise.
+ (*cmptf_ccs): New pattern for wfcxb.
+ (*cmptf_ccsfps): New pattern for wfkxb.
+ (mov<mode>): Rename to mov<mode><tf_fpr>.
+ (signbit<mode>2): Rename to signbit<mode>2<tf_fpr>.
+ (isinf<mode>2): Renamed to isinf<mode>2<tf_fpr>.
+ (*TDC_insn_<mode>): Use type instead of mode with fsimp.
+ (fixuns_trunc<FP:mode><GPR:mode>2): Rename to
+ fixuns_trunc<FP:mode><GPR:mode>2<FP:tf_fpr>.
+ (fix_trunctf<mode>2): Rename to fix_trunctf<mode>2_fpr.
+ (floatdi<mode>2): Rename to floatdi<mode>2<tf_fpr>, use type
+ instead of mode with itof.
+ (floatsi<mode>2): Rename to floatsi<mode>2<tf_fpr>, use type
+ instead of mode with itof.
+ (*floatuns<GPR:mode><FP:mode>2): Use type instead of mode for
+ itof.
+ (floatuns<GPR:mode><FP:mode>2): Rename to
+ floatuns<GPR:mode><FP:mode>2<tf_fpr>.
+ (trunctf<mode>2): Rename to trunctf<mode>2_fpr, use type instead
+ of mode with fsimp.
+ (extend<DSF:mode><BFP:mode>2): Rename to
+ extend<DSF:mode><BFP:mode>2<BFP:tf_fpr>.
+ (<FPINT:fpint_name><BFP:mode>2): Rename to
+ <FPINT:fpint_name><BFP:mode>2<BFP:tf_fpr>, use type instead of
+ mode with fsimp.
+ (rint<BFP:mode>2): Rename to rint<BFP:mode>2<BFP:tf_fpr>, use
+ type instead of mode with fsimp.
+ (<FPINT:fpint_name><DFP:mode>2): Use type instead of mode for
+ fsimp.
+ (rint<DFP:mode>2): Likewise.
+ (trunc<BFP:mode><DFP_ALL:mode>2): Rename to
+ trunc<BFP:mode><DFP_ALL:mode>2<BFP:tf_fpr>.
+ (trunc<DFP_ALL:mode><BFP:mode>2): Rename to
+ trunc<DFP_ALL:mode><BFP:mode>2<BFP:tf_fpr>.
+ (extend<BFP:mode><DFP_ALL:mode>2): Rename to
+ extend<BFP:mode><DFP_ALL:mode>2<BFP:tf_fpr>.
+ (extend<DFP_ALL:mode><BFP:mode>2): Rename to
+ extend<DFP_ALL:mode><BFP:mode>2<BFP:tf_fpr>.
+ (add<mode>3): Rename to add<mode>3<tf_fpr>, use type instead of
+ mode with fsimp.
+ (*add<mode>3_cc): Use type instead of mode with fsimp.
+ (*add<mode>3_cconly): Likewise.
+ (sub<mode>3): Rename to sub<mode>3<tf_fpr>, use type instead of
+ mode with fsimp.
+ (*sub<mode>3_cc): Use type instead of mode with fsimp.
+ (*sub<mode>3_cconly): Likewise.
+ (mul<mode>3): Rename to mul<mode>3<tf_fpr>, use type instead of
+ mode with fsimp.
+ (fma<mode>4): Restrict using s390_fma_allowed_p.
+ (fms<mode>4): Restrict using s390_fma_allowed_p.
+ (div<mode>3): Rename to div<mode>3<tf_fpr>, use type instead of
+ mode with fdiv.
+ (neg<mode>2): Rename to neg<mode>2<tf_fpr>.
+ (*neg<mode>2_cc): Use type instead of mode with fsimp.
+ (*neg<mode>2_cconly): Likewise.
+ (*neg<mode>2_nocc): Likewise.
+ (*neg<mode>2): Likeiwse.
+ (abs<mode>2): Rename to abs<mode>2<tf_fpr>, use type instead of
+ mode with fdiv.
+ (*abs<mode>2_cc): Use type instead of mode with fsimp.
+ (*abs<mode>2_cconly): Likewise.
+ (*abs<mode>2_nocc): Likewise.
+ (*abs<mode>2): Likewise.
+ (*negabs<mode>2_cc): Likewise.
+ (*negabs<mode>2_cconly): Likewise.
+ (*negabs<mode>2_nocc): Likewise.
+ (*negabs<mode>2): Likewise.
+ (sqrt<mode>2): Rename to sqrt<mode>2<tf_fpr>, use type instead
+ of mode with fsqrt.
+ (cbranch<mode>4): Use FP_ANYTF instead of FP.
+ (copysign<mode>3): Rename to copysign<mode>3<tf_fpr>, use type
+ instead of mode with fsimp.
+ * config/s390/s390.opt (flag_vx_long_double_fma): New
+ undocumented option.
+ * config/s390/vector.md (V_HW): Add TF for z14+.
+ (V_HW2): Likewise.
+ (VFT): Likewise.
+ (VF_HW): Likewise.
+ (V_128): Likewise.
+ (tf_vr): New mode_attr.
+ (tointvec): Add TF.
+ (mov<mode>): Rename to mov<mode><tf_vr>.
+ (movetf): New dispatcher.
+ (*vec_tf_to_v1tf): Rename to *vec_tf_to_v1tf_fpr, restrict to
+ z13-.
+ (*vec_tf_to_v1tf_vr): New pattern for z14+.
+ (*fprx2_to_tf): Likewise.
+ (*mov_tf_to_fprx2_0): Likewise.
+ (*mov_tf_to_fprx2_1): Likewise.
+ (add<mode>3): Rename to add<mode>3<tf_vr>.
+ (addtf3): New dispatcher.
+ (sub<mode>3): Rename to sub<mode>3<tf_vr>.
+ (subtf3): New dispatcher.
+ (mul<mode>3): Rename to mul<mode>3<tf_vr>.
+ (multf3): New dispatcher.
+ (div<mode>3): Rename to div<mode>3<tf_vr>.
+ (divtf3): New dispatcher.
+ (sqrt<mode>2): Rename to sqrt<mode>2<tf_vr>.
+ (sqrttf2): New dispatcher.
+ (fma<mode>4): Restrict using s390_fma_allowed_p.
+ (fms<mode>4): Likewise.
+ (neg_fma<mode>4): Likewise.
+ (neg_fms<mode>4): Likewise.
+ (neg<mode>2): Rename to neg<mode>2<tf_vr>.
+ (negtf2): New dispatcher.
+ (abs<mode>2): Rename to abs<mode>2<tf_vr>.
+ (abstf2): New dispatcher.
+ (float<mode>tf2_vr): New forwarder.
+ (float<mode>tf2): New dispatcher.
+ (floatuns<mode>tf2_vr): New forwarder.
+ (floatuns<mode>tf2): New dispatcher.
+ (fix_trunctf<mode>2_vr): New forwarder.
+ (fix_trunctf<mode>2): New dispatcher.
+ (fixuns_trunctf<mode>2_vr): New forwarder.
+ (fixuns_trunctf<mode>2): New dispatcher.
+ (<FPINT:fpint_name><VF_HW:mode>2<VF_HW:tf_vr>): New pattern.
+ (<FPINT:fpint_name>tf2): New forwarder.
+ (rint<mode>2<tf_vr>): New pattern.
+ (rinttf2): New forwarder.
+ (*trunctfdf2_vr): New pattern.
+ (trunctfdf2_vr): New forwarder.
+ (trunctfdf2): New dispatcher.
+ (trunctfsf2_vr): New forwarder.
+ (trunctfsf2): New dispatcher.
+ (extenddftf2_vr): New pattern.
+ (extenddftf2): New dispatcher.
+ (extendsftf2_vr): New forwarder.
+ (extendsftf2): New dispatcher.
+ (signbittf2_vr): New forwarder.
+ (signbittf2): New dispatchers.
+ (isinftf2_vr): New forwarder.
+ (isinftf2): New dispatcher.
+ * config/s390/vx-builtins.md (*vftci<mode>_cconly): Use VF_HW
+ instead of VECF_HW, add missing constraint, add vw support.
+ (vftci<mode>_intcconly): Use VF_HW instead of VECF_HW.
+ (*vftci<mode>): Rename to vftci<mode>, use VF_HW instead of
+ VECF_HW, and vw support.
+ (vftci<mode>_intcc): Use VF_HW instead of VECF_HW.
+
+2020-11-10 Eric Botcazou <ebotcazou@adacore.com>
+
+ * range-op.cc (operator_logical_not::fold_range): Tidy up.
+ (operator_logical_not::op1_range): Call above method.
+ (operator_bitwise_not::fold_range): If the type is compatible
+ with boolean, call op_logical_not.fold_range.
+ (operator_bitwise_not::op1_range): If the type is compatible
+ with boolean, call op_logical_not.op1_range.
+
+2020-11-10 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-pre.c (pre_expr_d::value_id): Add.
+ (constant_value_expressions): Turn into an array of pre_expr.
+ (get_or_alloc_expr_for_nary): New function.
+ (get_or_alloc_expr_for_reference): Likewise.
+ (add_to_value): For constant values only ever add a single
+ CONSTANT.
+ (get_expr_value_id): Return the new value_id member.
+ (vn_valnum_from_value_id): Split out and simplify constant
+ value id handling.
+ (get_or_alloc_expr_for_constant): Set the value_id member.
+ (phi_translate_1): Use get_or_alloc_expr_for_*.
+ (compute_avail): Likewise.
+ (bitmap_find_leader): Simplify constant value id handling.
+
+2020-11-10 Alex Coplan <alex.coplan@arm.com>
+
+ * doc/md.texi (Modifiers): Fix grammar in description of
+ earlyclobber constraint modifier.
+
+2020-11-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/97764
+ * tree-ssa-sccvn.c (vn_walk_cb_data::push_partial_def): For
+ little-endian stores with negative pd.offset, subtract
+ BITS_PER_UNIT - amnt from size if amnt is non-zero.
+
+2020-11-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97760
+ * tree-vect-loop.c (check_reduction_path): Reject
+ reduction paths we do not handle in epilogue generation.
+
+2020-11-10 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/97767
+ * value-range.cc (dump_bound_with_infinite_markers): Use
+ wi::min_value and wi::max_value.
+ (range_tests_strict_enum): New.
+ (range_tests): Call range_tests_strict_enum.
+ * value-range.h (irange::varying_p): Use wi::min_value
+ and wi::max_value.
+ (irange::set_varying): Same.
+ (irange::normalize_min_max): Remove comment.
+
+2020-11-10 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/97567
+ * gimple-range-gori.cc: (gori_compute::logical_combine): False
+ OR operations should intersect the 2 results.
+ (gori_compute::compute_logical_operands_in_chain): If def chains
+ are outside the current basic block, don't follow them.
+
2020-11-09 Claudiu Zissulescu <claziss@synopsys.com>
* config/arc/arc.c (arc_split_move): Recognize vadd2 instructions.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 2cca29c..81e21c8 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20201110
+20201203
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 978a08f..16be66f 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1364,6 +1364,7 @@ OBJS = \
gimple-array-bounds.o \
gimple-builder.o \
gimple-expr.o \
+ gimple-if-to-switch.o \
gimple-iterator.o \
gimple-fold.o \
gimple-laddress.o \
@@ -1480,6 +1481,7 @@ OBJS = \
omp-expand.o \
omp-general.o \
omp-low.o \
+ omp-oacc-kernels-decompose.o \
omp-simd-clone.o \
opt-problem.o \
optabs.o \
@@ -1749,6 +1751,8 @@ $(FULL_DRIVER_NAME): ./xgcc$(exeext)
# Otherwise $(SELFTEST_DEPS) is empty when used from <LANG>/Make-lang.in.
SELFTEST_DEPS = $(GCC_PASSES) stmp-int-hdrs $(srcdir)/testsuite/selftests
+DO_LINK_SERIALIZATION = @DO_LINK_SERIALIZATION@
+
# Language makefile fragments.
# The following targets define the interface between us and the languages.
@@ -1766,6 +1770,23 @@ SELFTEST_DEPS = $(GCC_PASSES) stmp-int-hdrs $(srcdir)/testsuite/selftests
# language hooks, generated by configure
@language_hooks@
+ifeq ($(DO_LINK_SERIALIZATION),)
+LINK_PROGRESS = :
+else
+LINK_PROGRESS = msg="Linking |"; cnt=0; if test "$(2)" = start; then \
+ idx=0; cnt2=$(DO_LINK_SERIALIZATION); \
+ while test $$cnt2 -le $(1); do msg="$${msg}=="; cnt2=`expr $$cnt2 + 1`; idx=`expr $$idx + 1`; done; \
+ cnt=$$idx; \
+ while test $$cnt -lt $(1); do msg="$${msg}>>"; cnt=`expr $$cnt + 1`; done; \
+ msg="$${msg}--"; cnt=`expr $$cnt + 1`; \
+ else \
+ idx=`expr $(1) + 1`; \
+ while test $$cnt -le $(1); do msg="$${msg}=="; cnt=`expr $$cnt + 1`; done; \
+ fi; \
+ while test $$cnt -lt $(SERIAL_COUNT); do msg="$${msg} "; cnt=`expr $$cnt + 1`; done; \
+ msg="$${msg}| `expr 100 \* $$idx / $(SERIAL_COUNT)`%"; echo "$$msg"
+endif
+
# Wire in install-gnatlib invocation with `make install' for a configuration
# with top-level libada disabled.
gnat_install_lib = @gnat_install_lib@
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index e00b1a1..5631a01 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,1569 @@
+2020-11-30 Pierre-Marie de Rodat <derodat@adacore.com>
+
+ * libgnat/s-trasym.ads: Update the list of supported platforms.
+
+2020-11-30 Arnaud Charlet <charlet@adacore.com>
+
+ * gcc-interface/Makefile.in, gcc-interface/trans.c: Remove ^L
+ characters.
+
+2020-11-30 Arnaud Charlet <charlet@adacore.com>
+
+ * gcc-interface/Makefile.in (GNATLIBFLAGS): Enable checks by
+ default.
+ * libgnat/s-bitfie.ads: Suppress alignment checks.
+ * libgnat/s-bituti.adb: Minor reformatting.
+ * libgnat/s-secsta.adb (SS_Allocate): Support Size = 0.
+
+2020-11-30 Arnaud Charlet <charlet@adacore.com>
+
+ * exp_ch3.adb (Replace_Discr_Ref): Removed, no longer needed.
+
+2020-11-30 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch5.adb (Process_Statements): Replace low-level membership
+ test with a high-level wrapper.
+
+2020-11-30 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch5.adb (Set_Assignment_Type): Combine calls to Ekind
+ using membership test.
+ (Should_Transform_BIP_Assignment): Replace assignment to a
+ "Result" variable with simple return statements; avoid repeated
+ calls to Unqual_Conv by declaring a local constant.
+
+2020-11-30 Piotr Trojanek <trojanek@adacore.com>
+
+ * lib-xref.adb (Generate_Reference): Fix reference to
+ Analyze_Assignment.
+ * sem_ch5.adb (Diagnose_Non_Variable_Lhs): Reuse existing
+ utility function.
+
+2020-11-30 Eric Botcazou <ebotcazou@adacore.com>
+
+ * contracts.adb (Check_Type_Or_Object_External_Properties): Make
+ sure to exclude all return objects from the SPARK legality rule
+ on effectively volatile variables.
+ * exp_ch6.adb (Expand_N_Extended_Return_Statement): Use the fast
+ track only when the declaration of the return object can be
+ dropped.
+
+2020-11-30 Gary Dismukes <dismukes@adacore.com>
+
+ * einfo.ads (Is_Partial_DIC_Procedure): New function.
+ (Partial_DIC_Procedure): New procedure.
+ * einfo.adb (Is_Partial_DIC_Procedure): New function to return
+ whether a subprogram is a partial Default_Initial_Condition
+ procedure by checking the name (to avoid adding a new field).
+ (DIC_Procedure): Add a test that excludes partial DIC procedures
+ from being returned.
+ (Partial_DIC_Procedure): New procedure to return the partial DIC
+ procedure of a type, if it has one (otherwise returns Empty).
+ (Set_DIC_Procedure): Remove check for duplicate DIC procedures.
+ * exp_aggr.adb (Gen_Assign): Generate a call to the type's DIC
+ procedure in the case where an array component is default
+ initialized (due to an association with a box).
+ (Build_Record_Aggr_Code): For an extension aggregate, generate a
+ call to the ancestor type's DIC procedure (if any) when the
+ ancestor part is a subtype mark. For a record component
+ association that was specified with a box (tested for by
+ checking the new flag Was_Default_Init_Box_Association),
+ generate a call to the component type's DIC procedure (if it has
+ one).
+ * exp_ch4.adb (Expand_N_Allocator): When the allocated object is
+ default initialized and the designated type has a DIC aspect,
+ generate a call to the DIC procedure.
+ * exp_util.ads (Build_DIC_Call): Change the formal Obj_Id to
+ name Obj_Name, and change its type from Entity_Id to Node_Id
+ (and update comment).
+ (Build_DIC_Procedure_Body): Add formal Partial_DIC, remove
+ formal For_Freeze, and update comment accordingly.
+ (Build_DIC_Procedure_Declaration): Add formal Partial_DIC and
+ update comment.
+ * exp_util.adb
+ (Build_DIC_Call): Revised to use its Obj_Name (formerly Obj_Id)
+ formal directly rather than calling New_Occurrence_Of on it, to
+ allow arbitrary names to be passed rather than being limited to
+ Entity_Ids.
+ (Build_DIC_Procedure_Body): Call Add_Parent_DICs to generate
+ checks for DICs associated with any parent types, implementing
+ the required "additive" semantics for DICs. When building a DIC
+ procedure body for a partial view (when Partial_DIC is True),
+ call Add_Own_DIC when the type has its own DIC. In the case of
+ "full" DIC procedures, a call is generated to any partial DIC
+ procedure of the type (unless the procedure has a null body),
+ along with checks for any DICs inherited by the full view.
+ (Build_DIC_Procedure_Declaration): Add handling for partial DIC
+ procedures. For the suffix of a regular DIC procedure's name,
+ use "DIC" (instead of "Default_Initial_Condition"), and for the
+ suffix of a partial DIC procedure's name, use "Partial_DIC".
+ (Add_DIC_Check): Add the DIC pragma to the list of seen pragmas
+ (Pragmas_Seen).
+ (Add_Inherited_Tagged_DIC): Remove the formals Par_Typ,
+ Deriv_Typ, and Obj_Id, and add formal Expr, which denotes DIC's
+ expression. Remove the call to Replace_References (which is now
+ done in Add_Inherited_DICs).
+ (Add_Inherited_DICs): New procedure to locate a DIC pragma
+ associated with a parent type, replace its references
+ appropriately (such as any current instance references), and add
+ a check for the DIC.
+ (Add_Own_DIC): Add an Obj_Id formal to allow caller to pass the
+ _init formal of the generated DIC procedure.
+ (Add_Parent_DICs): New procedure to traverse a type's parents,
+ looking for DICs associated with those and calling
+ Add_Inherited_DICs to apply the appropriate DIC checks.
+ (Is_Verifiable_DIC_Pragma): Treat pragmas that have an Empty
+ first argument the same as a pragma without any arguments
+ (returning False for that case).
+ * exp_ch3.adb (Init_One_Dimension): Generate calls to the
+ component's DIC procedure when needed.
+ (Possible_DIC_Call): New function nested in Init_One_Dimension
+ to build a call to the array component type's DIC-checking
+ function when appropriate.
+ (Build_Array_Init_Proc): The presence of a DIC on the component
+ type is an additional condition for generating an init proc for
+ an array type.
+ (Build_Init_Statements): When the record component's type has a
+ DIC, and the component declaration does not have an
+ initialization expression, generate a call to the component
+ type's DIC procedure.
+ (Expand_N_Object_Declaration): Modify the call to Build_DIC_Call
+ to pass a new occurrence of the object's defining id rather than
+ the id itself.
+ (Freeze_Type): Only build a type's DIC procedure (if it has one)
+ for types that are not interfaces.
+ * exp_spark.adb (Expand_SPARK_N_Freeze_Type): Remove From_Freeze
+ actual and add a ??? comment.
+ (Expand_SPARK_N_Object_Declaration): Modify call to
+ Build_DIC_Call to pass a new occurrence of the object id rather
+ than the object id itself.
+ * sem_aggr.adb (Resolve_Record_Aggregate): Declare local flag
+ Is_Box_Init_By_Default and set it in cases where the component
+ association has a box and the component is being initialized by
+ default (as opposed to initialized by an initialization
+ expression associated with the component's declaration).
+ (Add_Association): If the association has a box for a component
+ initialized by default, the flag
+ Was_Default_Init_Box_Association is set on the new component
+ association (for later testing during expansion).
+ (Get_Value): Reset Is_Box_Init_By_Default to False.
+ * sem_ch3.adb (Build_Assertion_Bodies_For_Type): Rearrange code
+ to build DIC procedure bodies for a (noninterface) type that
+ Has_Own_DIC (for partial type views) or Has_DIC (for full type
+ views) as appropriate.
+ * sem_ch13.adb (Analyze_Aspect_Specifications,
+ Aspect_Default_Initial_Condition): Add an extra argument to the
+ DIC pragma to denote the type associated with the pragma (for
+ use in Build_DIC_Procedure_Body).
+ * sem_prag.adb (Analyze_Pragma): Allow two arguments for pragma
+ Default_Initial_Condition. If not already present, add an extra
+ argument denoting the type that the pragma is associated with.
+ * sem_util.adb (Propagate_DIC_Attributes): Retrieve any partial
+ DIC procedure associated with the type and add it to the type's
+ list of subprograms (Subprograms_For_Type).
+ * sinfo.ads (Was_Default_Init_Box_Association): New flag on
+ N_Component_Association nodes. Add subprograms to get and set
+ flag, as well as updating the documentation.
+ * sinfo.adb (Was_Default_Init_Box_Association): New function to
+ retrieve the corresponding flag (Flag14).
+ (Set_Was_Default_Init_Box_Association): New procedure to set the
+ corresponding flag (Flag14).
+
+2020-11-30 Arnaud Charlet <charlet@adacore.com>
+
+ * par-ch6.adb (P_Formal_Part): Remove extra call to Scan.
+ * par-tchk.adb: Minor reformatting.
+
+2020-11-30 Eric Botcazou <ebotcazou@adacore.com>
+
+ * libgnat/a-nbnbre.adb (Float_Conversions): Instantiate Conv
+ package only once in the body.
+ (Fixed_Conversions.Float_Aux): New instance.
+ (Fixed_Conversions.Conv_I): Likewise.
+ (Fixed_Conversions.Conv_U): Likewise.
+ (Fixed_Conversions.LLLI): New subtype.
+ (Fixed_Conversions.LLLU): Likewise.
+ (Fixed_Conversions.Too_Large): New constant.
+ (Fixed_Conversions.To_Big_Real): Reimplement.
+ (Fixed_Conversions.From_Big_Real): Likewise.
+
+2020-11-30 Bob Duff <duff@adacore.com>
+
+ * exp_ch3.adb (Expand_N_Object_Declaration): Avoid crash in case
+ of conditional expression.
+
+2020-11-30 Eric Botcazou <ebotcazou@adacore.com>
+
+ * doc/gnat_rm/implementation_defined_attributes.rst (Pool_Address):
+ Fix pasto.
+ (Small_Denominator): New entry.
+ (Small_Numerator): Likewise.
+ * doc/gnat_rm/implementation_defined_characteristics.rst (3.5.9):
+ Relax conditions on 128-bit smalls and integer-only implementation.
+ * gnat_rm.texi: Regenerate.
+ * exp_attr.adb (Expand_N_Attribute_Reference) <Attribute_Fore>:
+ Relax conditions on integer implementation for ordinary fixed-point
+ types and pass a third parameter to the routine.
+ <Attribute_Small_Denominator>: Raise Program_Error.
+ <Attribute_Small_Numerator>: Likewise.
+ * exp_fixd.adb (Expand_Convert_Fixed_To_Fixed): Use a scaled divide
+ if the numerator and denominator of the small ratio are sufficiently
+ small integers.
+ (Expand_Convert_Fixed_To_Integer): Use a scaled divide if numerator
+ and denominator of the small value are sufficiently small integers.
+ (Expand_Convert_Integer_To_Fixed): Likewise.
+ * exp_imgv.adb (Expand_Image_Attribute): Relax the conditions on the
+ integer implementation for ordinary fixed-point types.
+ (Expand_Value_Attribute): Likewise.
+ * freeze.adb (Freeze_Fixed_Point_Type): Relax conditions on 128-bit
+ smalls.
+ * sem_attr.adb (Analyze_Attribute) <Attribute_Small_Denominator>:
+ Check no arguments, fixed-point and set type to Universal_Integer.
+ <Attribute_Small_Numerator>: Likewise.
+ (Eval_Attribute) <Attribute_Small_Denominator>: Fold statically.
+ <Attribute_Small_Numerator>: Likewise.
+ * snames.ads-tmpl (Name_Small_Denominator): New attribute name.
+ (Name_Small_Numerator): Likewise.
+ (Attribute_Id): Add Attribute_Small_{Denominator,Numerator}.
+ * libgnat/a-tifiio.adb (Exact): Delete.
+ (Need_64): Likewise.
+ (OK_Get_32): New boolean constant.
+ (OK_Put_32): Likewise.
+ (OK_Get_64): Likewise.
+ (OK_Put_64): Likewise.
+ (E): Adjust.
+ (Get procedures): Likewise.
+ (Put procedures): Likewise.
+ * libgnat/a-tifiio__128.adb (Exact): Delete.
+ (Need_64): Likewise.
+ (Need_128): Likewise.
+ (OK_Get_32): New boolean constant.
+ (OK_Put_32): Likewise.
+ (OK_Get_64): Likewise.
+ (OK_Put_64): Likewise.
+ (OK_Get_128): Likewise.
+ (OK_Put_128): Likewise.
+ (E): Adjust.
+ (Get procedures): Likewise.
+ (Put procedures): Likewise.
+ * libgnat/a-wtfiio.adb (Exact): Delete.
+ (Need_64): Likewise.
+ (OK_Get_32): New boolean constant.
+ (OK_Put_32): Likewise.
+ (OK_Get_64): Likewise.
+ (OK_Put_64): Likewise.
+ (E): Adjust.
+ (Get procedures): Likewise.
+ (Put procedures): Likewise.
+ * libgnat/a-wtfiio__128.adb (Exact): Delete.
+ (Need_64): Likewise.
+ (Need_128): Likewise.
+ (OK_Get_32): New boolean constant.
+ (OK_Put_32): Likewise.
+ (OK_Get_64): Likewise.
+ (OK_Put_64): Likewise.
+ (OK_Get_128): Likewise.
+ (OK_Put_128): Likewise.
+ (E): Adjust.
+ (Get procedures): Likewise.
+ (Put procedures): Likewise.
+ * libgnat/a-ztfiio.adb (Exact): Delete.
+ (Need_64): Likewise.
+ (OK_Get_32): New boolean constant.
+ (OK_Put_32): Likewise.
+ (OK_Get_64): Likewise.
+ (OK_Put_64): Likewise.
+ (E): Adjust.
+ (Get procedures): Likewise.
+ (Put procedures): Likewise.
+ * libgnat/a-ztfiio__128.adb (Exact): Delete.
+ (Need_64): Likewise.
+ (Need_128): Likewise.
+ (OK_Get_32): New boolean constant.
+ (OK_Put_32): Likewise.
+ (OK_Get_64): Likewise.
+ (OK_Put_64): Likewise.
+ (OK_Get_128): Likewise.
+ (OK_Put_128): Likewise.
+ (E): Adjust.
+ (Get procedures): Likewise.
+ (Put procedures): Likewise.
+ * libgnat/s-fore_f.ads (Fore_Fixed): Adjust signature.
+ * libgnat/s-fore_f.adb (Fore_Fixed): Reimplement.
+ * libgnat/s-fofi32.ads (Fore_Fixed32): Adjust signature.
+ * libgnat/s-fofi64.ads (Fore_Fixed64): Likewise.
+ * libgnat/s-fofi128.ads (Fore_Fixed128): Likewise.
+ * libgnat/s-imagef.ads: Adjust description.
+ * libgnat/s-imagef.adb (Maxdigs): Move around.
+ (Set_Image_Integer): Remove assertion.
+ * libgnat/s-valuef.ads: Adjust description.
+ * libgnat/s-valuef.adb (Integer_To_Fixed): Minor tweak.
+
+2020-11-30 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * doc/gnat_ugn/building_executable_programs_with_gnat.rst:
+ Describe -gnateb switch.
+ * doc/gnat_ugn/the_gnat_compilation_model.rst: Mention -gnateb
+ switch in configuration pragma files section.
+ * gnat_ugn.texi: Regenerate.
+ * lib-writ.adb (Write_ALI): Strip directories from configuration
+ files path if needed.
+ * opt.ads: Declare Config_Files_Store_Basename option.
+ * par.adb (Par): Save configuration file checksum.
+ * switch-c.adb (Scan_Front_End_Switches): Set
+ Config_Files_Store_Basename true if -gnateb is present.
+
+2020-11-30 Arnaud Charlet <charlet@adacore.com>
+
+ * exp_dist.adb (RCI_Cache): Initialize.
+
+2020-11-30 Arnaud Charlet <charlet@adacore.com>
+
+ * terminals.c (allocate_pty_desc): Copy one less byte since the
+ last byte will always be set to 0.
+
+2020-11-30 Eric Botcazou <ebotcazou@adacore.com>
+
+ * doc/gnat_ugn/building_executable_programs_with_gnat.rst (-xdr):
+ Document that XDR is not supported for 128-bit integer types.
+ * gnat_ugn.texi: Regenerate.
+ * exp_strm.adb (Build_Elementary_Input_Call): Deal with types
+ larger than Long_Long_Integer.
+ (Build_Elementary_Write_Call): Likewise.
+ * rtsfind.ads (RE_Id): Add RE_I_LLL{I,U] and RE_W_LLL{I,U}.
+ (RE_Unit_Table): Add entries for them.
+ * libgnat/s-stratt.ads (I_LLLI): New inline function.
+ (I_LLLU): Likewise.
+ (W_LLLI): New inline procedure.
+ (W_LLLU): Likewise.
+ * libgnat/s-stratt.adb (S_LLLI): New subtype of SEA.
+ (S_LLLU): Likewise.
+ (From_LLLI): New instance of Unchecked_Conversion.
+ (From_LLLU): Likewise.
+ (To_LLLI): Likewise.
+ (To_LLLU): Likewise.
+ (I_LLLI): Implement.
+ (I_LLLU): Likewise.
+ (W_LLLI): Likewise.
+ (W_LLLU): Likewise.
+
+2020-11-30 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch5.adb (Expand_Iterator_Loop_Over_Container): Check the
+ signature of the private operation Get_Element_Access to prevent
+ accidental use of a user-defined homonym subprogram.
+
+2020-11-30 Yannick Moy <moy@adacore.com>
+
+ * spark_xrefs.ads: Add comment for Heap that it may remain
+ Empty.
+
+2020-11-30 Pascal Obry <obry@adacore.com>
+
+ * libgnat/g-sercom__linux.adb (Set): Fix control flags of the
+ serial port setting.
+
+2020-11-30 Pascal Obry <obry@adacore.com>
+
+ * libgnat/g-sercom__linux.adb: Minor style fixes.
+
+2020-11-30 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_util.adb (Get_Current_Value_Condition): Don't use current
+ value tracking in GNATprove mode.
+ * sem_res.adb (Resolve_Comparison_Op): Remove incomplete
+ special-casing for folding in GNATprove mode.
+
+2020-11-30 Bob Duff <duff@adacore.com>
+
+ * errout.adb (Error_Msg_NEL): Do not call Set_Posted if errors
+ are being ignored.
+ (Error_Msg): Change Errors_Must_Be_Ignored to use the getter.
+ * sem_ch8.adb (Find_Direct_Name): Do not skip all the error
+ checks when ignoring errors, but instead do not add an entry to
+ the Urefs table if errors are being ignored.
+ * exp_ch5.adb: Minor comment fix.
+
+2020-11-30 Yannick Moy <moy@adacore.com>
+
+ * sem_aggr.adb (Resolve_Array_Aggregate): Improve error message.
+
+2020-11-30 Eric Botcazou <ebotcazou@adacore.com>
+
+ * libgnat/s-valuef.adb (Integer_To_Fixed): Do not modify numerator
+ or denominator in order to reduce the exponent.
+
+2020-11-30 Arnaud Charlet <charlet@adacore.com>
+
+ * ali-util.adb (Get_File_Checksum): Remove dead code.
+ * exp_ch4.adb (Expand_Boolean_Operator, Expand_N_Op_Not,
+ Make_Boolean_Array_Op): Take Transform_Function_Array into
+ account.
+ * exp_ch6.adb (Expand_Call_Helper): Update comment. Code
+ cleanup.
+ * exp_util.adb (Build_Procedure_Form): Use new predefined name
+ Name_UP_RESULT.
+ * snames.ads-tmpl (Name_UP_RESULT): New predefined name. Code
+ cleanup: remove unused names from the project parser, moved to
+ gprbuild sources.
+ * xsnamest.adb: Add support for uppercase names.
+
+2020-11-30 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_util.adb (Enter_Name): When an inherited operation for a
+ local derived type is hidden by an explicit declaration of a
+ non-overloadable entity in the same scope, make the inherited
+ operation non-visible to prevent its accidental use elsewhere.
+
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ PR ada/97504
+ * Makefile.rtl (LIBGNAT_TARGET_PAIRS) <hppa*-*-hpux*>: Use wraplf
+ version of Aux_Long_Long_Float.
+
+2020-11-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * libgnat/s-valuef.adb (Integer_To_Fixed): Take into account the
+ extra digit when scaling up the input.
+ * libgnat/s-valuer.adb (Scan_Decimal_Digits): Restrict previous
+ change to fixed-point types.
+ (Scan_Integral_Digits): Likewise.
+
+2020-11-27 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_res.adb (Parent_Is_Boolean): Simplify.
+ (Resolve_Op_Not): Reduce scope of a local variable.
+
+2020-11-27 Piotr Trojanek <trojanek@adacore.com>
+
+ * cstand.adb: Simplify with Append_New_Elmt.
+ * sem_util.adb: Likewise.
+
+2020-11-27 Arnaud Charlet <charlet@adacore.com>
+
+ * sem_eval.adb (Fold_Shift): Fix evaluation of Shift_Right on
+ negative values.
+
+2020-11-27 Arnaud Charlet <charlet@adacore.com>
+
+ * exp_ch6.adb (Expand_Call): Properly split
+ Transform_Function_Array and Modify_Tree_For_C.
+
+2020-11-27 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_eval.ads (Compile_Time_Compare): Restore parameter Diff to
+ be of an access type.
+ * sem_eval.adb (Compile_Time_Compare): Adapt body and callers.
+ * sem_attr.adb (Eval_Attribute): Adapt callers.
+
+2020-11-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * libgnat/s-valuer.adb (Scan_Decimal_Digits): Round Extra.
+ (Scan_Integral_Digits): Likewise.
+
+2020-11-27 Yannick Moy <moy@adacore.com>
+
+ * checks.adb (Selected_Range_Checks): Adapt the condition for
+ applying range checks so that it is not done inside generics.
+
+2020-11-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_fixd.adb (Build_Double_Divide): Only use a 128-bit
+ division if one of the operands is larger than 64 bits.
+ (Build_Double_Divide_Code): Likewise.
+ (Build_Scaled_Divide): Likewise.
+ (Build_Scaled_Divide_Code): Likewise.
+
+2020-11-27 Arnaud Charlet <charlet@adacore.com>
+
+ * libgnat/s-os_lib.adb (To_GM_Time): Return valid and consistent
+ values for Invalid_Time.
+
+2020-11-27 Steve Baird <baird@adacore.com>
+
+ * snames.ads-tmpl: Define new Name_Stable_Properties Name_Id
+ value.
+ * aspects.ads, aspects.adb: Add new Aspect_Stable_Properties
+ enumeration literal to Aspect_Id type. Add Class_Present
+ parameter to Find_Aspect and related
+ functions (Find_Value_Of_Aspect and Has_Aspect).
+ * sem_util.adb (Has_Nontrivial_Precondition): Fix
+ previously-latent bug uncovered by adding Class_Present
+ parameter to Aspect.Find_Aspect. The code was wrong before, but
+ with the change the bug was more likely to make a user-visible
+ difference.
+ * sem_ch6.adb (Analyze_Operator_Symbol): If a string literal
+ like "abs" or "-" occurs in a Stable_Properties aspect
+ specification, then it is to be interpreted as an operator
+ symbol and not as a string literal.
+ * sem_ch13.ads: Export new Parse_Aspect_Stable_Properties
+ function, analogous to the existing Parse_Aspect_Aggregate
+ exported procedure.
+ * sem_ch13.adb: (Parse_Aspect_Stable_Properties): New function;
+ analogous to existing Parse_Aspect_Aggregate.
+ (Validate_Aspect_Stable_Properties): New procedure; analogous to
+ existing Validate_Aspect_Aggregate. Called from the same case
+ statement (casing on an Aspect_Id value) where
+ Validate_Aspect_Aggregate is called.
+ (Resolve_Aspect_Stable_Properties): New procedure; analogous to
+ existing Resolve_Aspect_Aggregate. Called from the same two case
+ statements (each casing on an Aspect_Id value) where
+ Resolve_Aspect_Aggregate is called.
+ (Analyze_Aspect_Specifications): Set Has_Delayed_Aspects and
+ Is_Delayed_Aspect attributes for Aspect_Stable_Properties aspect
+ specifications.
+ (Check_Aspect_At_End_Of_Declarations): The syntactic
+ "expression" for a Stable_Properties aspect specification is not
+ semantically an expression; it doesn't have a type. Thus, force
+ T to be empty in this case.
+ * contracts.adb (Expand_Subprogram_Contract): Add call to new
+ local procedure,
+ Expand_Subprogram_Contract.Add_Stable_Property_Contracts, which
+ generates Postcondition pragmas corresponding to stable property
+ checks.
+
+2020-11-27 Piotr Trojanek <trojanek@adacore.com>
+
+ * doc/gnat_rm/implementation_defined_pragmas.rst:
+ (Assertion_Policy): Move "Default_Initial_Condition" from
+ ID_ASSERTION_KIND to RM_ASSERTION_KIND section.
+ * gnat_rm.texi: Regenerate.
+
+2020-11-27 Piotr Trojanek <trojanek@adacore.com>
+
+ * doc/gnat_rm/implementation_defined_pragmas.rst
+ (Assertion_Policy): Add "Default_Initial_Condition",
+ "Initial_Condition" and "Subprogram_Variant".
+ * gnat_rm.texi: Regenerate.
+
+2020-11-27 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_prag.adb (Is_Valid_Assertion_Kind): Return False on
+ "Assertion_Policy"
+
+2020-11-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * make.adb (GNAT_Flag): Change to "-gnatg".
+ (Compile): Adjust comments accordingly.
+
+2020-11-27 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_ch4.adb (Rewrite_Comparison): Add assertion to confirm
+ that evaluation folds comparisons with static operands; when
+ folding comparison with non-static operands, the resulting
+ literal is non-static.
+ * sem_eval.adb (Eval_Relational_Op): Refactor nested IF
+ statement for the special case in the THEN branch; move code for
+ the "general case" out of the ELSE branch.
+ * sem_res.adb (Resolve_Comparison_Op): Only apply a dubious
+ special-case for GNATprove in the GNATprove_Mode.
+
+2020-11-27 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_eval.ads (Compile_Time_Compare): Change parameter Diff
+ from access to mode out.
+ * sem_eval.adb (Compile_Time_Compare): Adapt body and callers.
+ * sem_attr.adb (Eval_Attribute): Adapt callers.
+
+2020-11-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Op_Multiply): Move down block calling
+ Narrow_Large_Operation if the type is Universal_Integer.
+
+2020-11-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * libgnat/a-nbnbre.adb: Remove clauses for System.Img_Real and
+ add them for System.Unsigned_Types.
+ (Float_Conversions.To_Big_Real): Reimplement.
+ (Float_Conversions.From_Big_Real): Likewise.
+
+2020-11-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * checks.ads (Determine_Range_To_Discrete): New procedure.
+ * checks.adb (Apply_Scalar_Range_Check): Call it to determine
+ a range for the expression when the target type is discrete.
+ And also apply the tests for discrete types to fixed-point
+ types when they are treated as integers.
+ (Apply_Type_Conversion_Checks): Apply checks to conversions
+ involving fixed-point types when they are treated as integers.
+ (Determine_Range) <N_Type_Conversion>: Factor out code into...
+ (Determine_Range_To_Discrete): ...this new procedure and add
+ support for fixed-point types when they are treated as integers.
+ * einfo.ads (Type_High_Bound): Remove obsolete sentence.
+ (Type_Low_Bound): Likewise.
+ * exp_ch4.adb (Discrete_Range_Check): Remove obsolete code.
+ (Real_Range_Check): Likewise.
+ (Expand_N_Type_Conversion): In case of a no-op conversion, clear
+ the Do_Range_Check flag on the operand before substituting it.
+ Remove calls to Real_Range_Check and Discrete_Range_Check that
+ are not guarded by the Do_Range_Check flag, and an assertion.
+ * sem_res.adb (Resolve_Type_Conversion): Always apply range
+ checks in GNATprove mode; in normal mode, use the updated type
+ of the operand in the test against Universal_Fixed. Remove
+ obsolete code setting the Do_Range_Check flag at the end.
+
+2020-11-27 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_prag.adb (Analyze_Pragma): Change "Ref Manual" to RM;
+ replace uses of an unnecessary "Ok" variable with RETURN
+ statements; replace nested IF with ELSIF.
+
+2020-11-27 Arnaud Charlet <charlet@adacore.com>
+
+ * libgnarl/s-tasren.adb (Local_Complete_Rendezvous): Always call
+ Defer_Abort.
+ * libgnat/a-except.adb: Abort does not need to be deferred.
+ * libgnarl/s-tpobop.adb (Exceptional_Complete_Entry_Body): Abort
+ never needs to be undeferred here.
+ * exp_ch11.adb (Expand_Exception_Handlers): Remove difference
+ between ZCX and SJLJ.
+ * exp_ch9.adb (Expand_N_Asynchronous_Select): Remove different
+ handling for sjlj.
+ * exp_sel.ads, exp_sel.adb (Build_Abort_Block,
+ Build_Abort_Block_Handler): Ditto.
+
+2020-11-27 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * sem_prag.adb (Analyze_Pragma): declare new Check_No_Return
+ function and call it.
+
+2020-11-27 Arnaud Charlet <charlet@adacore.com>
+
+ * sem_ch12.adb (Instantiate_Object): Consistently use
+ New_Copy_Tree instead of New_Copy.
+
+2020-11-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_fixd.adb (Build_Conversion): Adjust head comment.
+ (Build_Divide): Likewise.
+ (Build_Double_Divide): Likewise.
+ (Build_Multiply): Likewise.
+ (Build_Rem): Likewise.
+ (Build_Scaled_Divide): Likewise.
+
+2020-11-27 Arnaud Charlet <charlet@adacore.com>
+
+ * libgnat/s-genbig.ads, libgnat/s-genbig.adb (To_Bignum): New
+ variant taking an Unsigned_128.
+ * libgnat/a-nbnbin.adb (To_Big_Integer): Add support for 128
+ bits signed and unsigned types.
+
+2020-11-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * libgnat/s-imagef.adb (Set_Image_Fixed): Pass the full value
+ of the quotient to Set_Image_Integer during the first round and
+ adjust the handling of the minus sign.
+
+2020-11-27 Arnaud Charlet <charlet@adacore.com>
+
+ * libgnat/a-nbnbre.adb ("=", "<"): Fix.
+
+2020-11-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * libgnat/s-valuer.adb (Scan_Raw_Real): Move pragma Annotate around
+ and adjust its parameters.
+
+2020-11-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_fixd.adb (Build_Double_Divide): Use the RM size of types and
+ a more precise estimate for the size of the denominator.
+ (Build_Double_Divide_Code): Likewise.
+ (Build_Multiply): Use a more precise estimate for the size of the
+ result.
+ (Build_Scaled_Divide): Use the RM size of types and a more precise
+ estimate for the size of the numerator.
+ (Build_Scaled_Divide_Code): Likewise.
+
+2020-11-26 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * Makefile.rtl <sparc*-sun-solaris*> (THREADSLIB): Remove.
+ (MISCLIB): Remove -lposix4.
+ <*86-*-solaris2*>: Likewise.
+ * libgnarl/s-osinte__solaris.ads (System.OS_Interface): Remove
+ -lposix4 -lthread.
+
+2020-11-26 Arnaud Charlet <charlet@adacore.com>
+
+ * libgnat/a-nbnbre.adb (To_Big_Real): Do not loose precision.
+
+2020-11-26 Arnaud Charlet <charlet@adacore.com>
+
+ * sem_ch8.adb (Analyze_Object_Renaming): Check for AI12-0401.
+
+2020-11-26 Eric Botcazou <ebotcazou@adacore.com>
+
+ * Makefile.rtl (GNATRTL_NONTASKING_OBJS): Likewise.
+ (GNATRTL_128BIT_OBJS): Likewise.
+ (GNATRTL_128BIT_PAIRS): Add new 128-bit variants.
+ * cstand.adb (Create_Standard): Create Standard_Integer_128.
+ * doc/gnat_rm/implementation_defined_characteristics.rst: Document
+ new limits on 64-bit platforms in entry for 3.5.9(10).
+ * gnat_rm.texi: Regenerate.
+ * exp_attr.adb: Add with and use clauses for Urealp.
+ (Expand_N_Attribute_Reference) <Attribute_Fore>: Call new routines
+ for decimal fixed-point types and common ordinary fixed-point types.
+ * exp_ch4.adb (Real_Range_Check): Extend conversion trick to all
+ ordinary fixed-point types and use Small_Integer_Type_For.
+ * exp_fixd.adb: Add with and use clauses for Ttypes.
+ (Build_Divide): Add special case for 32-bit values and deal with
+ 128-bit types.
+ (Build_Double_Divide): Deal with 128-bit types.
+ (Build_Double_Divide_Code): Likewise. Do not apply conversions
+ before calling Build_Multiply.
+ (Build_Multiply): Likewise. Add special case for 32-bit values.
+ (Build_Scaled_Divide): Deal with 128-bit types.
+ (Build_Scaled_Divide_Code): Likewise. Fix size computation. Do not
+ apply conversions before calling Build_Multiply.
+ (Do_Multiply_Fixed_Fixed): Minor tweak.
+ (Integer_Literal): Deal with 128-bit values.
+ * exp_imgv.adb (Has_Decimal_Small): Delete.
+ (Expand_Image_Attribute): Call new routines for common ordinary
+ fixed-point types.
+ (Expand_Value_Attribute): Likewise.
+ (Expand_Width_Attribute): Add new expansion for fixed-point types.
+ * freeze.adb (Freeze_Entity): Move error checks for ordinary
+ fixed-point types to...
+ (Freeze_Fixed_Point_Type): ...here. Deal with 128-bit types and
+ adjust limitations for 32-bnt and 64-bit types.
+ * rtsfind.ads (RTU_Id): Add entries for new System_Fore, System_Img,
+ and System_Val units and remove them for obsolete units.
+ (RE_Id): Add entries for Double_Divide128, Scaled_Divide128, the new
+ Fore, Image, Value routines and remove them for obsolete units.
+ (RE_Unit_Table): Likewise.
+ * sem_ch3.adb (Decimal_Fixed_Point_Type_Declaration): Deal with
+ 128-bit types.
+ * stand.ads (Standard_Entity_Type): Add Standard_Integer_128.
+ * uintp.ads (Uint_31): New deferred constant.
+ (Uint_Minus_18): Likewise.
+ (Uint_Minus_31): Likewise.
+ (Uint_Minus_76): Likewise.
+ (Uint_Minus_127): Likewise.
+ * urealp.ads (Ureal_2_31): New function.
+ (Ureal_2_63): Likewise.
+ (Ureal_2_127): Likewise.
+ (Ureal_2_M_127): Likewise.
+ (Ureal_2_10_18): Likewise.
+ (Ureal_M_2_10_18): Likewise.
+ (Ureal_9_10_36): Likewise.
+ (Ureal_M_9_10_36): Likewise.
+ (Ureal_10_76): Likewise.
+ (Ureal_M_10_76): Likewise.
+ (Ureal_10_36): Delete.
+ (Ureal_M_10_36): Likewise.
+ * urealp.adb (UR_2_10_18): New variable.
+ (UR_9_10_36): Likewise.
+ (UR_10_76): Likewise.
+ (UR_M_2_10_18): Likewise.
+ (UR_M_9_10_36): Likewise.
+ (UR_M_10_76): Likewise.
+ (UR_2_31): Likewise.
+ (UR_2_63): Likewise.
+ (UR_2_127): Likewise.
+ (UR_2_M_127): Likewise.
+ (UR_10_36): Delete.
+ (UR_M_10_36): Likewise.
+ (Initialize): Initialize them.
+ (UR_Write): Do not use awkward Ada literal style.
+ (Ureal_2_10_18): New function.
+ (Ureal_9_10_36): Likewise.
+ (Ureal_10_76): Likewise.
+ (Ureal_2_31): Likewise.
+ (Ureal_2_63): Likewise.
+ (Ureal_2_127): Likewise.
+ (Ureal_2_M_127): Likewise.
+ (Ureal_M_2_10_18): Likewise.
+ (Ureal_M_9_10_36): Likewise.
+ (Ureal_10_76): Likewise.
+ (Ureal_M_10_76): Likewise.
+ (Ureal_10_36): Delete.
+ (Ureal_M_10_36): Likewise.
+ * libgnat/a-decima__128.ads: New file.
+ * libgnat/a-tideau.ads, libgnat/a-tideau.adb: Reimplement as
+ generic unit.
+ * libgnat/a-tideio.adb: Reimplement.
+ * libgnat/a-tideio__128.adb: New file.
+ * libgnat/a-tifiau.ads, libgnat/a-tifiau.adb: New generic unit.
+ * libgnat/a-tifiio.adb: Move bulk of implementation to s-imagef
+ and reimplement.
+ * libgnat/a-tifiio__128.adb: New file.
+ * libgnat/a-tiflau.adb (Get): Minor consistency fix.
+ (Gets): Likewise.
+ * libgnat/a-wtdeau.ads, libgnat/a-wtdeau.adb: Reimplement as
+ generic unit.
+ * libgnat/a-wtdeio.adb: Reimplement.
+ * libgnat/a-wtdeio__128.adb: New file.
+ * libgnat/a-wtfiau.ads, libgnat/a-wtfiau.adb: New generic unit.
+ * libgnat/a-wtfiio.adb: Reimplement.
+ * libgnat/a-wtfiio__128.adb: New file.
+ * libgnat/a-ztdeau.ads, libgnat/a-ztdeau.adb: Reimplement as
+ generic unit.
+ * libgnat/a-ztdeio.adb: Reimplement.
+ * libgnat/a-ztdeio__128.adb: New file.
+ * libgnat/a-ztfiau.ads, libgnat/a-ztfiau.adb: New generic unit.
+ * libgnat/a-ztfiio.adb: Reimplement.
+ * libgnat/a-ztfiio__128.adb: New file.
+ * libgnat/g-rannum.adb (Random_Decimal_Fixed): Use a subtype of the
+ appropiate size for the instantiation.
+ (Random_Ordinary_Fixed): Likewise.
+ * libgnat/s-arit32.ads, libgnat/s-arit32.adb: New support unit.
+ * libgnat/s-fode128.ads: New instantiation.
+ * libgnat/s-fode32.ads: Likewise.
+ * libgnat/s-fode64.ads: Likewise.
+ * libgnat/s-fofi128.ads: Likewise.
+ * libgnat/s-fofi32.ads: Likewise.
+ * libgnat/s-fofi64.ads: Likewise.
+ * libgnat/s-fore_d.ads, libgnat/s-fore_d.adb: New generic unit.
+ * libgnat/s-fore_f.ads, libgnat/s-fore_f.adb: Likewise.
+ * libgnat/s-fore.ads, libgnat/s-fore.adb: Rename into...
+ * libgnat/s-forrea.ads, libgnat/s-forrea.adb: ...this.
+ * libgnat/s-imaged.ads, libgnat/s-imaged.adb: New generic unit.
+ * libgnat/s-imagef.ads, libgnat/s-imagef.adb: Likewise, taken
+ from a-tifiio.adb.
+ * libgnat/s-imde128.ads: New instantiation.
+ * libgnat/s-imde32.ads: Likewise.
+ * libgnat/s-imde64.ads: Likewise.
+ * libgnat/s-imfi128.ads: Likewise.
+ * libgnat/s-imfi32.ads: Likewise.
+ * libgnat/s-imfi64.ads: Likewise.
+ * libgnat/s-imgdec.ads, libgnat/s-imgdec.adb: Delete.
+ * libgnat/s-imglld.ads, libgnat/s-imglld.adb: Likewise.
+ * libgnat/s-imgrea.adb (Set_Image_Real): Replace Sign local variable
+ with Minus local variable for the sake of consistency.
+ * libgnat/s-imguti.ads, libgnat/s-imguti.adb: New support unit.
+ * libgnat/s-vade128.ads: New instantiation.
+ * libgnat/s-vade32.ads: Likewise.
+ * libgnat/s-vade64.ads: Likewise.
+ * libgnat/s-vafi128.ads: Likewise.
+ * libgnat/s-vafi32.ads: Likewise.
+ * libgnat/s-vafi64.ads: Likewise.
+ * libgnat/s-valdec.ads, libgnat/s-valdec.adb: Delete.
+ * libgnat/s-vallld.ads, libgnat/s-vallld.adb: Likewise.
+ * libgnat/s-valued.ads, libgnat/s-valued.adb: New generic unit.
+ * libgnat/s-valuef.ads, libgnat/s-valuef.adb: Likewise.
+ * libgnat/s-valuei.adb: Minor rewording.
+ * libgnat/s-valrea.adb: Move bulk of implementation to...
+ * libgnat/s-valuer.ads, libgnat/s-valuer.adb: ...here. New
+ generic unit.
+ * libgnat/system-aix.ads (Max_Mantissa): Adjust.
+ * libgnat/system-darwin-arm.ads (Max_Mantissa): Likewise.
+ * libgnat/system-darwin-ppc.ads (Max_Mantissa): Likewise.
+ * libgnat/system-darwin-x86.ads (Max_Mantissa): Likewise.
+ * libgnat/system-djgpp.ads (Max_Mantissa): Likewise.
+ * libgnat/system-dragonfly-x86_64.ads (Max_Mantissa): Likewise.
+ * libgnat/system-freebsd.ads (Max_Mantissa): Likewise.
+ * libgnat/system-hpux-ia64.ads (Max_Mantissa): Likewise.
+ * libgnat/system-hpux.ads (Max_Mantissa): Likewise.
+ * libgnat/system-linux-alpha.ads (Max_Mantissa): Likewise.
+ * libgnat/system-linux-arm.ads (Max_Mantissa): Likewise.
+ * libgnat/system-linux-hppa.ads (Max_Mantissa): Likewise.
+ * libgnat/system-linux-ia64.ads (Max_Mantissa): Likewise.
+ * libgnat/system-linux-m68k.ads (Max_Mantissa): Likewise.
+ * libgnat/system-linux-mips.ads (Max_Mantissa): Likewise.
+ * libgnat/system-linux-ppc.ads (Max_Mantissa): Likewise.
+ * libgnat/system-linux-riscv.ads (Max_Mantissa): Likewise.
+ * libgnat/system-linux-s390.ads (Max_Mantissa): Likewise.
+ * libgnat/system-linux-sh4.ads (Max_Mantissa): Likewise.
+ * libgnat/system-linux-sparc.ads (Max_Mantissa): Likewise.
+ * libgnat/system-linux-x86.ads (Max_Mantissa): Likewise.
+ * libgnat/system-lynxos178-ppc.ads (Max_Mantissa): Likewise.
+ * libgnat/system-lynxos178-x86.ads (Max_Mantissa): Likewise.
+ * libgnat/system-mingw.ads (Max_Mantissa): Likewise.
+ * libgnat/system-qnx-aarch64.ads (Max_Mantissa): Likewise.
+ * libgnat/system-rtems.ads (Max_Mantissa): Likewise.
+ * libgnat/system-solaris-sparc.ads (Max_Mantissa): Likewise.
+ * libgnat/system-solaris-x86.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks-arm-rtp-smp.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks-arm-rtp.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks-arm.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks-e500-kernel.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks-e500-rtp-smp.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks-e500-rtp.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks-e500-vthread.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks-ppc-kernel.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks-ppc-ravenscar.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks-ppc-rtp-smp.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks-ppc-rtp.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks-ppc-vthread.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks-ppc.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks-x86-kernel.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks-x86-rtp-smp.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks-x86-rtp.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks-x86-vthread.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks-x86.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks7-aarch64-rtp-smp.ads (Max_Mantissa):
+ Likewise.
+ * libgnat/system-vxworks7-aarch64.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks7-arm-rtp-smp.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks7-arm.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks7-e500-kernel.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks7-e500-rtp-smp.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks7-e500-rtp.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks7-ppc-kernel.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks7-ppc-rtp-smp.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks7-ppc-rtp.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks7-ppc64-kernel.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks7-ppc64-rtp-smp.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks7-x86-kernel.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks7-x86-rtp-smp.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks7-x86-rtp.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks7-x86_64-kernel.ads (Max_Mantissa): Likewise.
+ * libgnat/system-vxworks7-x86_64-rtp-smp.ads (Max_Mantissa): Likewise.
+
+2020-11-26 Liaiss Merzougue <merzougue@adacore.com>
+
+ * libgnat/s-imgrea.ads (Image_Ordinary_Fixed_Point): Add a
+ remark concerning the irrelevant use of Inf and -0.0
+
+2020-11-26 Arnaud Charlet <charlet@adacore.com>
+
+ * osint-c.adb (Set_Output_Object_File_Name): Add support for
+ .c output file.
+
+2020-11-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * lib-writ.adb, sem_ch8.adb, sem_prag.adb: Use
+ Is_Generic_Subprogram instead of low-level membership tests.
+
+2020-11-26 Gary Dismukes <dismukes@adacore.com>
+
+ * sem_ch6.adb (Analyze_Call_And_Resolve): Reformatted a comment.
+ * sem_prag.adb (Process_Restrictions_Or_Restriction_Warnings):
+ Fixed a typo.
+
+2020-11-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_res.adb (Resolve_Membership_Op): Replace pragma Warnings
+ with pragma Assert.
+
+2020-11-26 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch6.adb (Analyze_Call_And_Resolve): Add information to the
+ error message on an illegal procedure call, when the illegality
+ is due to the presence of a component of the full view of the
+ target object, as well as a procedure with the same name (See RM
+ 4.1.3 (9.2/3)).
+
+2020-11-26 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_prag.adb (Process_Restrictions_Or_Restriction_Warnings):
+ when the restriction is a configuration pragma and specifies
+ No_Tasking, a global flag is set to reject task declarations,
+ and to prevent the construction of Master entities. The flag
+ must not be set if the pragma is a Restriction_Warning, in which
+ case task declarationns are allowed.
+
+2020-11-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * libgnat/a-stzhas.adb (Wide_Wide_Hash): Instantiate inside a
+ wrapper function.
+ * libgnat/a-stzhas.ads (Wide_Wide_Hash): Likewise; remove wrong
+ comment, because this is indeed a RM unit, as described in Ada
+ RM A.4.8 (1/3).
+
+2020-11-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_eval.adb (Eval_Slice): Refactor repeated calls to Prefix
+ with a local constant (named just like in Resolve_Slice).
+
+2020-11-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_eval.adb (Eval_Slice): Emit warning not just for
+ constants, but for any objects.
+
+2020-11-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch4.adb (Indicate_Name_And_Type): Fix whitespace in
+ comment.
+ * sem_res.adb (Resolve_Call): Remove redundant parens.
+ * sem_util.adb (Set_Entity_With_Checks): Remove extra call to
+ Set_Entity.
+
+2020-11-26 Bob Duff <duff@adacore.com>
+
+ * exp_ch4.adb (Expand_Concatenate): Call Set_No_Initialization
+ on the N_Allocator node that is supposed to allocate on the
+ secondary stack.
+
+2020-11-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_ch13.adb, exp_ch9.adb, sem_ch8.adb, sem_util.adb: Replace
+ a combination of Is_Protected_Type and Is_Task_Type by
+ Is_Concurrent_Type.
+
+2020-11-26 Arnaud Charlet <charlet@adacore.com>
+
+ * libgnarl/s-tassta.adb (Task_Wrapper): Fix computation of
+ Pattern_Size.
+
+2020-11-26 Bob Duff <duff@adacore.com>
+
+ * freeze.adb (Freeze_Array_Type): Remove propagation of
+ Has_Own_Invariants to the first subtype. This is a no-op,
+ because the current (incorrect) version of Has_Own_Invariants
+ calls Base_Type.
+ * sem_prag.adb, sem_util.adb: Pass the base type to
+ Set_Has_Own_Invariants.
+
+2020-11-26 Eric Botcazou <ebotcazou@adacore.com>
+
+ * einfo.ads (Aft_Value): Adjust documentation.
+ (Scale_Value): Likewise.
+
+2020-11-26 Justin Squirek <squirek@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Type_Conversion): Use the unexpanded
+ operand when generating accessibility checks.
+
+2020-11-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * libgnat/a-cbhase.adb (Read): Remove extra whitespace.
+ * libgnat/a-cbmutr.ads (Read): Likewise.
+ * libgnat/a-cborse.adb (Read): Likewise.
+
+2020-11-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_ch7.adb, exp_util.adb, freeze.adb: Rewrite with
+ Is_Access_Object_Type.
+
+2020-11-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_prag.adb (Check_Valid_Library_Unit_Pragma): Raise
+ exception.
+ (Analyze_Pragma): Remove detection of rewritten pragmas.
+
+2020-11-26 Joffrey Huguet <huguet@adacore.com>
+
+ * libgnat/a-strmap.ads: Add preconditions and postconditions to
+ all subprograms.
+
+2020-11-26 Yannick Moy <moy@adacore.com>
+
+ * sem_res.adb (Resolve_Equality_Op): Warn when -gnatwq is used
+ (the default) and the problematic case is encountered.
+
+2020-11-26 Yannick Moy <moy@adacore.com>
+
+ * sem_attr.adb (Analyze_Attribute): Issue a continuation message
+ to give proper recommendation here.
+
+2020-11-26 Gary Dismukes <dismukes@adacore.com>
+
+ * exp_util.adb (Expand_Subtype_From_Expr): A typo correction,
+ plus other minor reformatting.
+
+2020-11-26 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch12.adb (Instantiate_Formal_Package): If previous matched
+ entity is overloadable, advance in the list of actuals of the
+ actual package, to prevent an erroneous match of two adjacent
+ overloadable homonyms with the same entity.
+
+2020-11-26 Justin Squirek <squirek@adacore.com>
+
+ * sem_ch6.adb (First_Selector): Utility routine to return the
+ first selector or choice in an association.
+ (Check_Return_Construct_Accessibility): Modify loop to handle
+ named associations when iterating through discriminants.
+
+2020-11-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch12.adb: Fix casing from "Instantiation" to
+ "instantiation".
+
+2020-11-25 Ed Schonberg <schonberg@adacore.com>
+
+ * freeze.adb (Is_Uninitialized_Aggregate): Move...
+ * exp_util.adb (Is_Uninitialized_Aggregate): ... here.
+ (Expand_Subtype_From_Expr): If the expression is an
+ uninitialized aggregate, capture subtype for declared object and
+ remove expression to suppress further superfluous expansion.
+
+2020-11-25 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_eval.adb (Subtypes_Statically_Compatible): Scalar types
+ with compatible static bounds are statically compatible if
+ predicates are compatible, even if they are not static subtypes.
+ Same for private types without discriminants.
+
+2020-11-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch11.adb (Expand_N_Raise_Statement): Use Is_Entity_Name
+ consistently in tests on the name of the statement.
+ * exp_prag.adb (Expand_Pragma_Check): In the local propagation
+ case, wrap the raise statement in a block statement.
+
+2020-11-25 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_ch8.adb (Expand_N_Exception_Renaming_Declaration): Move
+ "Nam" constant after the body of a nested subprogram; change "T"
+ from variable to constant.
+
+2020-11-25 Piotr Trojanek <trojanek@adacore.com>
+
+ * make.adb (Scan_Make_Arg): Merge ELSIF branches for -u and -U.
+
+2020-11-25 Piotr Trojanek <trojanek@adacore.com>
+
+ * doc/gnat_rm/implementation_defined_attributes.rst
+ (Has_Tagged_Values): Document based on the existing description
+ of Has_Access_Type and the comment for Has_Tagged_Component,
+ which is where frontend evaluates this attribute.
+ * gnat_rm.texi: Regenerate.
+ * sem_attr.adb (Analyze_Attribute): Merge processing of
+ Has_Access_Type and Has_Tagged_Component attributes.
+ * sem_util.adb (Has_Access_Type): Fix casing in comment.
+ * sem_util.ads (Has_Tagged_Component): Remove wrong (or
+ outdated) comment about the use of this routine to implement the
+ equality operator.
+
+2020-11-25 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_attr.adb (Expand_Size_Attribute): Remove whitespace;
+ simplify with a membership test, which are now allowed in the
+ frontend code.
+
+2020-11-25 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch13.adb (Analyze_One_Aspect): Fix inconsistent calls to
+ Make_Aitem_Pragma.
+
+2020-11-25 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch13.adb (Check_Expr_Constants): Simplify with
+ Is_Named_Number.
+ * sem_prag.adb (Process_Convention): Likewise.
+
+2020-11-25 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch13.adb (Analyze_One_Aspect): Detect aspect identifiers
+ with membership tests.
+ (Check_Aspect_At_End_Of_Declarations): Likewise.
+ (Freeze_Entity_Checks): Likewise; a local constant is no longer
+ needed.
+ (Is_Operational_Item): Similar simplification for attribute
+ identifiers.
+ (Is_Type_Related_Rep_Item): Likewise.
+ (Resolve_Iterable_Operation): Detect names with a membership
+ test.
+ (Validate_Independence): Replace repeated Ekind with a
+ membership test.
+
+2020-11-25 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch13.adb (Analyze_One_Aspect): Replace duplicate of
+ Effective_Reads.
+
+2020-11-25 Piotr Trojanek <trojanek@adacore.com>
+
+ * einfo.adb: Use composite wrappers (e.g.
+ Is_Subprogram_Or_Entry) and membership tests where it appears to
+ improve clarity.
+
+2020-11-25 Piotr Trojanek <trojanek@adacore.com>
+
+ * einfo.adb (Is_Standard_Character_Type,
+ Is_Standard_String_Type): Simplify.
+ (Last_Formal): Use procedural variant of Next_Formal.
+
+2020-11-25 Piotr Trojanek <trojanek@adacore.com>
+
+ * einfo.adb: Replace "E" with Entity_Id in local object
+ declarations.
+
+2020-11-25 Steve Baird <baird@adacore.com>
+
+ * exp_ch2.adb (Expand_Entity_Reference): A new local predicate
+ Is_Object_Renaming_Name indicates whether a given expression
+ occurs (after looking through qualified expressions and type
+ conversions) as the name of an object renaming declaration. If
+ Current_Value is available but this new predicate is True, then
+ ignore the availability of Current_Value.
+
+2020-11-25 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch12.adb (Instantiate_Type): Remove extra whitespace.
+ (Validate_Access_Type_Instance): Remove dead (and duplicated)
+ code.
+
+2020-11-25 Gary Dismukes <dismukes@adacore.com>
+
+ * exp_util.adb (Possible_Side_Effect_In_SPARK): Replace hyphen
+ with a space in "side-effect" (two instances).
+
+2020-11-25 Justin Squirek <squirek@adacore.com>
+
+ * doc/gnat_rm/intrinsic_subprograms.rst (Shifts and Rotates):
+ Document behavior on negative numbers
+ * gnat_rm.texi: Regenerate.
+ * sem_eval.adb (Fold_Shift): Set modulus to be based on the RM
+ size for non-modular integer types.
+
+2020-11-25 Olivier Hainque <hainque@adacore.com>
+
+ * adaint.c (__gnat_copy_attribs): Reinstate code based on utime
+ for timestamp processing on VxWorks 6.
+
+2020-11-25 Yannick Moy <moy@adacore.com>
+
+ * exp_util.adb (Remove_Side_Effects): Only remove side-effects
+ in GNATprove mode when this is useful.
+ * sem_res.adb (Set_Slice_Subtype): Make sure in GNATprove mode
+ to define the Itype when needed, so that run-time errors can be
+ analyzed.
+ * sem_util.adb (Enclosing_Declaration): Correctly take into
+ account renaming declarations.
+
+2020-11-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ * libgnat/s-rannum.adb (Random_Discrete): Specifically deal with
+ the case where the size of the base type is larger than 64 bits.
+
+2020-11-25 Yannick Moy <moy@adacore.com>
+
+ * sem_ch3.adb (Access_Type_Declaration): Set Etype before
+ checking for volatility compatibility.
+
+2020-11-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ * libgnat/g-rannum.ads (Random): New functions returning 128-bit.
+ * libgnat/g-rannum.adb (Random): Implement them and alphabetize.
+ (To_Signed): New unchecked conversion function for 128-bit.
+
+2020-11-25 Arnaud Charlet <charlet@adacore.com>
+
+ * exp_ch7.adb (Build_Finalization_Master, Build_Finalizer,
+ Build_Object_Declarations, Make_Deep_Array_Body,
+ Wrap_Transient_Expression): Call Set_Debug_Info_Needed on
+ temporaries when Debug_Generated_Code is True.
+
+2020-11-25 Liaiss Merzougue <merzougue@adacore.com>
+
+ * libgnat/s-imagei.adb
+ (Set_Digits): Rewrite the procedure to remove recursion.
+ (Image_Integer, Set_Image_Integer): Update assertions and remove
+ redundant ones.
+ * libgnat/s-imageu.adb
+ (Set_Image_Unsigned): Rewrite the procedure to remove recursion.
+
+2020-11-25 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_util.adb (Attribute_Constrained_Static_Value): Fix body
+ box.
+ * sem_attr.adb (Eval_Attribute): Replace repeated calls to
+ Attribute_Name with a captured value of the Attribute_Id; also,
+ remove extra parens around Is_Generic_Type.
+
+2020-11-25 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * sem_prag.adb (Analyze_Pragma): Emit error on wrong argument
+ nkind.
+
+2020-11-25 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_attr.adb, sem_prag.adb: Use Is_Named_Number.
+
+2020-11-25 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_attr.adb, exp_util.adb: Fix style and typos in comments.
+
+2020-11-25 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_attr.adb (Expand_N_Attribute_Reference): A variable that
+ is only incremented in the code has now type Nat; conversion is
+ now unnecessary.
+
+2020-11-24 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_prag.adb (Analyze_Global_Item): Call SPARK_Msg_NE with the
+ entity, not with its identifier.
+
+2020-11-24 Arnaud Charlet <charlet@adacore.com>
+
+ * opt.ads (Generate_Asm): New flag.
+ * osint-c.adb (Set_Output_Object_File_Name): Accept any
+ extension when generating assembly.
+ * adabkend.adb (Scan_Compiler_Args): Recognize -S.
+
+2020-11-24 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_attr.adb, exp_ch4.adb, exp_intr.adb, sem_ch8.adb,
+ sem_res.adb, sem_type.adb, sem_util.adb: Reuse Is_Packed_Array.
+
+2020-11-24 Piotr Trojanek <trojanek@adacore.com>
+
+ * checks.adb (Apply_Access_Check): Remove unbalanced paren.
+ * exp_attr.adb (Expand_N_Attribute_Reference): Fix typo in
+ comment.
+
+2020-11-24 Justin Squirek <squirek@adacore.com>
+
+ * sem_prag.adb (Analyze_Pragma): Mark relevant pragmas as ghost
+ when they are within a ghost region.
+
+2020-11-24 Piotr Trojanek <trojanek@adacore.com>
+
+ * contracts.adb, freeze.adb, sem_ch12.adb, sem_prag.adb: Reuse
+ In_Same_List.
+
+2020-11-24 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_prag.adb (Is_Loop_Pragma): Avoid repeated calls to
+ Original_Node; remove unnecessary IF statement.
+
+2020-11-24 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_spark.adb (Expand_SPARK_N_Attribute_Reference): Rewrite
+ with a CASE statement.
+
+2020-11-24 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_attr.adb (Expand_N_Attribute_Reference): Replace calls to
+ Sloc with a local constant Loc; remove call to
+ Analyze_And_Resolve and return, which is exactly what happens
+ anyway (and other branches in the Constrained declare block
+ appear to rely on analysis, resolution and returning happening
+ in all cases).
+ * sem_util.adb: Remove useless parens.
+
+2020-11-24 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_util.adb (Is_Object_Reference): Delta and extension
+ aggregates are objects.
+
+2020-11-24 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * libgnat/s-rident.ads (System.Rident): Register new restriction
+ IDs.
+ * par-ch13.adb (Get_Aspect_Specifications): Add restriction check.
+ * par-prag.adb (Process_Restrictions_Or_Restriction_Warnings):
+ Register No_Unrecognized_Aspects restriction.
+ * sem_prag.adb (Analyze_Pragma): Add restriction check.
+ * snames.ads-tmpl: Create restriction names.
+
+2020-11-24 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_attr.adb (Declared_Within): Return True for objects
+ declared within the attribute Loop_Entry prefix itself.
+
+2020-11-24 Yannick Moy <moy@adacore.com>
+
+ * sem_ch3.adb (Process_Discriminants): Correctly set right
+ context for analyzing default value of discriminant.
+
+2020-11-24 Arnaud Charlet <charlet@adacore.com>
+
+ * sem_type.adb (Add_One_Interp.Is_Universal_Operation): Account
+ for universal_access = operator.
+ (Disambiguate): Take into account preference on universal_access
+ = operator when relevant.
+ (Disambiguate.Is_User_Defined_Anonymous_Access_Equality): New.
+
+2020-11-24 Arnaud Charlet <charlet@adacore.com>
+
+ * exp_util.adb (Is_Finalizable_Transient): Take into account return
+ statements containing N_Expression_With_Actions. Also clean up a
+ condition to make it more readable.
+ * exp_ch6.adb: Fix typo.
+
+2020-11-24 Eric Botcazou <ebotcazou@adacore.com>
+
+ * libgnat/a-wtdeio.adb (TFT): Delete and adjust throughout.
+ * libgnat/a-wtenau.adb (TFT): Likewise.
+ * libgnat/a-wtfiio.adb (TFT): Likewise.
+ * libgnat/a-wtflio.adb (TFT): Likewise.
+ * libgnat/a-wtinio.adb (TFT): Likewise.
+ * libgnat/a-wtinio__128.adb (TFT): Likewise.
+ * libgnat/a-wtmoio.adb (TFT): Likewise.
+ * libgnat/a-wtmoio__128.adb (TFT): Likewise.
+ * libgnat/a-ztdeio.adb (TFT): Likewise.
+ * libgnat/a-ztenau.adb (TFT): Likewise.
+ * libgnat/a-ztfiio.adb (TFT): Likewise.
+ * libgnat/a-ztflio.adb (TFT): Likewise.
+ * libgnat/a-ztinio.adb (TFT): Likewise.
+ * libgnat/a-ztinio__128.adb (TFT): Likewise.
+ * libgnat/a-ztmoio.adb (TFT): Likewise.
+ * libgnat/a-ztmoio__128.adb (TFT): Likewise.
+
+2020-11-24 Arnaud Charlet <charlet@adacore.com>
+
+ * sem_ch13.adb (Validate_Literal_Aspect): Add support for named
+ numbers and in particular overload of the Real_Literal function.
+ * sem_res.adb (Resolve): Add support for named numbers in
+ Real_Literal and Integer_Literal resolution.
+ * einfo.adb, einfo.ads (Related_Expression,
+ Set_Related_Expression): Allow E_Function.
+ * uintp.ads (UI_Image_Max): Bump size of buffer to avoid loosing
+ precision.
+ * sem_eval.adb: Fix typo in comment.
+ * libgnat/a-nbnbin.adb, libgnat/a-nbnbin.ads (From_String):
+ Return a Valid_Big_Integer.
+ * libgnat/a-nbnbre.adb, libgnat/a-nbnbre.ads (From_String): New
+ variant taking two strings. Return a Valid_Big_Real.
+
+2020-11-24 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch12.adb (Analyze_Associations) <Explicit_Freeze_Check>: Test
+ that the instance is in a statement sequence instead of local scope.
+ (Freeze_Subprogram_Body): Use the special delayed placement with
+ regard to the parent instance only if its Sloc is strictly greater.
+ (Install_Body): Likewise.
+
+2020-11-24 Steve Baird <baird@adacore.com>
+
+ * sem_ch13.adb (Validate_Literal_Aspect): Call to Base_Type
+ needed in order to correctly check result type of String_Literal
+ function when the first named subtype differs from the base
+ type (e.g.:
+ type T is range 1 .. 10 with String_Literal => ... ;
+ ).
+
+2020-11-24 Yannick Moy <moy@adacore.com>
+
+ * sem_prag.adb (Analyze_Global_Item): Handle specially the
+ current instance of a PO.
+ * sem_util.ads (Is_Effectively_Volatile,
+ Is_Effectively_Volatile_For_Reading): Add parameter
+ Ignore_Protected.
+ * sem_util.adb (Is_Effectively_Volatile,
+ Is_Effectively_Volatile_For_Reading): Add parameter
+ Ignore_Protected to compute the query results ignoring protected
+ objects/types.
+ (Is_Effectively_Volatile_Object,
+ Is_Effectively_Volatile_Object_For_Reading): Adapt to new
+ signature.
+
+2020-11-24 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * doc/gnat_ugn/building_executable_programs_with_gnat.rst:
+ Update documentation on -gnatyk.
+ * gnat_ugn.texi: Regenerate.
+
+2020-11-24 Yannick Moy <moy@adacore.com>
+
+ * sem_ch10.adb (Analyze_Compilation_Unit): Move aspects from
+ body to the newly created spec.
+
+2020-11-24 Arnaud Charlet <charlet@adacore.com>
+
+ * exp_ch6.adb (Add_Cond_Expression_Extra_Actual): Simplify
+ handling of function calls and remove bug in handling of
+ transient objects. Minor reformatting along the way.
+
+2020-11-24 Arnaud Charlet <charlet@adacore.com>
+
+ * libgnat/a-nbnbin.adb (From_String): Implement fully.
+
+2020-11-24 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_aggr.adb (Resolve_Delta_Array_Aggregate): If the choice is
+ a subtype_indication then call
+ Resolve_Discrete_Subtype_Indication; both for choices
+ immediately inside array delta aggregates and inside
+ iterated_component_association within array delta aggregates.
+
+2020-11-24 Piotr Trojanek <trojanek@adacore.com>
+
+ * lib-load.adb, lib-writ.adb, lib.adb, par-load.adb,
+ rtsfind.adb, sem_ch10.adb: Use Present where possible.
+
+2020-11-24 Yannick Moy <moy@adacore.com>
+
+ * sem_prag.adb (Analyze_Depends_Global): Reject Global and
+ Depends on null procedure.
+
+2020-11-24 Arnaud Charlet <charlet@adacore.com>
+
+ * libgnat/a-nbnbre.adb (From_String): Handle properly '_'
+ characters.
+
+2020-11-24 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_spark.adb (Expand_SPARK_Array_Aggregate,
+ Expand_SPARK_N_Aggregate): Remove, no longer needed.
+ * sem_aggr.adb (Resolve_Iterated_Component_Association): Only
+ remove references in the analyzed expression when generating
+ code and the expression needs to be analyzed anew after being
+ rewritten into a loop.
+
+2020-11-24 Eric Botcazou <ebotcazou@adacore.com>
+
+ * doc/gnat_rm/implementation_defined_characteristics.rst: Complete
+ entry of 3.5.9(10).
+ * gnat_rm.texi: Regenerate.
+
+2020-11-20 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * adaint.c (__gnat_number_of_cpus): Check for the presence of
+ _SC_NPROCESSORS_ONLN rather than a list of OS-specific macros
+ to decide whether to use `sysconf'.
+
+2020-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/97911
+ * gcc-interface/Make-lang.in (ada.serial): Change from goal to a
+ variable.
+ (.PHONY): Drop ada.serial and ada.prev.
+ (gnat1$(exeext)): Depend on $(ada.serial) rather than ada.serial.
+
+2020-11-19 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/97805
+ * adaint.c: Include climits in C++ and limits.h otherwise.
+
+2020-11-19 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_dbug.adb (Is_Handled_Scale_Factor): Delete.
+ (Get_Encoded_Name): Do not call it.
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <Fixed_Point_Type>:
+ Tidy up and always use a meaningful description for arbitrary
+ scale factors.
+ * gcc-interface/misc.c (gnat_get_fixed_point_type_info): Remove
+ obsolete block and adjust the description of the scale factor.
+
+2020-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc-interface/Make-lang.in (ada.serial): New goal.
+ (.PHONY): Add ada.serial ada.prev.
+ (gnat1$(exeext)): Depend on ada.prev. Call LINK_PROGRESS.
+
+2020-11-18 Matthias Klose <doko@ubuntu.com>
+
+ PR ada/97859
+ * Makefile.rtl (powerpc% linux%): Also match powerpc64le cpu.
+
+2020-11-11 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/gigi.h: Remove ^L characters throughout.
+ * gcc-interface/decl.c: Likewise.
+ * gcc-interface/utils.c: Likewise.
+ * gcc-interface/utils2.c: Likewise.
+ * gcc-interface/trans.c (gnat_to_gnu) <N_Allocator>: Do not explicitly
+ go to the base type for the Has_Constrained_Partial_View flag.
+
+2020-11-11 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/trans.c (build_binary_op_trapv): Convert operands
+ to the result type before doing generic overflow checking.
+
+2020-11-11 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/trans.c (can_be_lower_p): Remove.
+ (Regular_Loop_to_gnu): Add ENTRY_COND unconditionally if
+ BOTTOM_COND is non-zero.
+
+2020-11-11 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Constant>: In case
+ the constant is not being defined, get the expression in type
+ annotation mode only if its type is elementary.
+
+2020-11-11 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/trans.c (gnat_to_gnu) <N_Op_Shift>: Also convert
+ GNU_MAX_SHIFT if the type of the operation has been changed.
+ * gcc-interface/utils.c (can_materialize_object_renaming_p): Add
+ pair of missing parentheses.
+
2020-11-07 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/Makefile.in: Force target_cpu to powerpc if the
diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
index 6d9efc4..544d0cf 100644
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -344,6 +344,7 @@ GNATRTL_NONTASKING_OBJS= \
a-tideio$(objext) \
a-tienau$(objext) \
a-tienio$(objext) \
+ a-tifiau$(objext) \
a-tifiio$(objext) \
a-tiflau$(objext) \
a-tiflio$(objext) \
@@ -371,6 +372,7 @@ GNATRTL_NONTASKING_OBJS= \
a-wtedit$(objext) \
a-wtenau$(objext) \
a-wtenio$(objext) \
+ a-wtfiau$(objext) \
a-wtfiio$(objext) \
a-wtflau$(objext) \
a-wtflio$(objext) \
@@ -394,6 +396,7 @@ GNATRTL_NONTASKING_OBJS= \
a-ztenau$(objext) \
a-ztenio$(objext) \
a-ztexio$(objext) \
+ a-ztfiau$(objext) \
a-ztfiio$(objext) \
a-ztflau$(objext) \
a-ztflio$(objext) \
@@ -520,6 +523,7 @@ GNATRTL_NONTASKING_OBJS= \
s-aomoar$(objext) \
s-aotase$(objext) \
s-aridou$(objext) \
+ s-arit32$(objext) \
s-arit64$(objext) \
s-assert$(objext) \
s-atacco$(objext) \
@@ -599,30 +603,41 @@ GNATRTL_NONTASKING_OBJS= \
s-finmas$(objext) \
s-finroo$(objext) \
s-flocon$(objext) \
- s-fore$(objext) \
+ s-fode32$(objext) \
+ s-fode64$(objext) \
+ s-fofi32$(objext) \
+ s-fofi64$(objext) \
+ s-fore_d$(objext) \
+ s-fore_f$(objext) \
+ s-forrea$(objext) \
s-gearop$(objext) \
s-genbig$(objext) \
s-geveop$(objext) \
s-gloloc$(objext) \
s-htable$(objext) \
s-imageb$(objext) \
+ s-imaged$(objext) \
+ s-imagef$(objext) \
s-imagei$(objext) \
s-imageu$(objext) \
s-imagew$(objext) \
+ s-imde32$(objext) \
+ s-imde64$(objext) \
s-imenne$(objext) \
+ s-imfi32$(objext) \
+ s-imfi64$(objext) \
s-imgbiu$(objext) \
s-imgboo$(objext) \
s-imgcha$(objext) \
- s-imgdec$(objext) \
s-imgenu$(objext) \
s-imgint$(objext) \
s-imgllb$(objext) \
- s-imglld$(objext) \
s-imglli$(objext) \
s-imgllu$(objext) \
s-imgllw$(objext) \
s-imgrea$(objext) \
s-imguns$(objext) \
+ s-imguti$(objext) \
s-imgwch$(objext) \
s-imgwiu$(objext) \
s-io$(objext) \
@@ -736,14 +751,19 @@ GNATRTL_NONTASKING_OBJS= \
s-utf_32$(objext) \
s-valboo$(objext) \
s-valcha$(objext) \
- s-valdec$(objext) \
+ s-vade32$(objext) \
+ s-vade64$(objext) \
+ s-vafi32$(objext) \
+ s-vafi64$(objext) \
s-valenu$(objext) \
s-valint$(objext) \
- s-vallld$(objext) \
s-vallli$(objext) \
s-valllu$(objext) \
s-valrea$(objext) \
+ s-valued$(objext) \
+ s-valuef$(objext) \
s-valuei$(objext) \
+ s-valuer$(objext) \
s-valueu$(objext) \
s-valuns$(objext) \
s-valuti$(objext) \
@@ -885,10 +905,17 @@ TRASYM_DWARF_UNIX_OBJS = $(TRASYM_DWARF_COMMON_OBJS) s-mmauni$(objext)
TRASYM_DWARF_MINGW_OBJS = $(TRASYM_DWARF_COMMON_OBJS)
GNATRTL_128BIT_PAIRS = \
+ a-decima.ads<libgnat/a-decima__128.ads \
+ a-tideio.adb<libgnat/a-tideio__128.adb \
+ a-tifiio.adb<libgnat/a-tifiio__128.adb \
a-tiinio.adb<libgnat/a-tiinio__128.adb \
a-timoio.adb<libgnat/a-timoio__128.adb \
+ a-wtdeio.adb<libgnat/a-wtdeio__128.adb \
+ a-wtfiio.adb<libgnat/a-wtfiio__128.adb \
a-wtinio.adb<libgnat/a-wtinio__128.adb \
a-wtmoio.adb<libgnat/a-wtmoio__128.adb \
+ a-ztdeio.adb<libgnat/a-ztdeio__128.adb \
+ a-ztfiio.adb<libgnat/a-ztfiio__128.adb \
a-ztinio.adb<libgnat/a-ztinio__128.adb \
a-ztmoio.adb<libgnat/a-ztmoio__128.adb \
i-cexten.ads<libgnat/i-cexten__128.ads \
@@ -903,6 +930,10 @@ GNATRTL_128BIT_OBJS = \
s-exnllli$(objext) \
s-expllli$(objext) \
s-explllu$(objext) \
+ s-fode128$(objext) \
+ s-fofi128$(objext) \
+ s-imde128$(objext) \
+ s-imfi128$(objext) \
s-imglllb$(objext) \
s-imgllli$(objext) \
s-imglllu$(objext) \
@@ -970,6 +1001,8 @@ GNATRTL_128BIT_OBJS = \
s-pack125$(objext) \
s-pack126$(objext) \
s-pack127$(objext) \
+ s-vade128$(objext) \
+ s-vafi128$(objext) \
s-valllli$(objext) \
s-vallllu$(objext) \
s-widllli$(objext) \
@@ -1641,8 +1674,7 @@ ifeq ($(strip $(filter-out sparc% sun solaris%,$(target_cpu) $(target_vendor) $(
endif
EH_MECHANISM=-gcc
- THREADSLIB = -lposix4 -lthread
- MISCLIB = -lposix4 -lnsl -lsocket
+ MISCLIB = -lnsl -lsocket
SO_OPTS = -Wl,-h,
GNATLIB_SHARED = gnatlib-shared-dual
GMEM_LIB = gmemlib
@@ -1695,8 +1727,7 @@ ifeq ($(strip $(filter-out %86 %x86_64 solaris2%,$(target_cpu) $(target_os))),)
EXTRA_GNATRTL_NONTASKING_OBJS += $(TRASYM_DWARF_UNIX_OBJS)
EH_MECHANISM=-gcc
- THREADSLIB = -lposix4 -lthread
- MISCLIB = -lposix4 -lnsl -lsocket
+ MISCLIB = -lnsl -lsocket
SO_OPTS = -Wl,-h,
GNATLIB_SHARED = gnatlib-shared-dual
GMEM_LIB = gmemlib
@@ -2006,6 +2037,7 @@ ifeq ($(strip $(filter-out hppa% hp hpux10%,$(target_cpu) $(target_vendor) $(tar
s-inmaop.adb<libgnarl/s-inmaop__posix.adb \
s-interr.adb<libgnarl/s-interr__sigaction.adb \
s-intman.adb<libgnarl/s-intman__posix.adb \
+ a-nallfl.ads<libgnat/a-nallfl__wraplf.ads \
s-osinte.adb<libgnarl/s-osinte__hpux-dce.adb \
s-osinte.ads<libgnarl/s-osinte__hpux-dce.ads \
s-parame.ads<libgnat/s-parame__hpux.ads \
@@ -2024,6 +2056,7 @@ ifeq ($(strip $(filter-out hppa% hp hpux11%,$(target_cpu) $(target_vendor) $(tar
a-intnam.ads<libgnarl/a-intnam__hpux.ads \
s-inmaop.adb<libgnarl/s-inmaop__posix.adb \
s-intman.adb<libgnarl/s-intman__posix.adb \
+ a-nallfl.ads<libgnat/a-nallfl__wraplf.ads \
s-osinte.adb<libgnarl/s-osinte__posix.adb \
s-osinte.ads<libgnarl/s-osinte__hpux.ads \
s-parame.ads<libgnat/s-parame__hpux.ads \
@@ -2305,7 +2338,7 @@ ifeq ($(strip $(filter-out powerpc% linux%,$(target_cpu) $(target_os))),)
$(ATOMICS_BUILTINS_TARGET_PAIRS) \
system.ads<libgnat/system-linux-ppc.ads
- ifeq ($(strip $(filter-out powerpc64,$(target_cpu))),)
+ ifeq ($(strip $(filter-out powerpc64%,$(target_cpu))),)
ifneq ($(strip $(MULTISUBDIR)),/32)
LIBGNAT_TARGET_PAIRS += $(GNATRTL_128BIT_PAIRS)
EXTRA_GNATRTL_NONTASKING_OBJS += $(GNATRTL_128BIT_OBJS)
diff --git a/gcc/ada/adabkend.adb b/gcc/ada/adabkend.adb
index 6fb4a84..b10c0bd 100644
--- a/gcc/ada/adabkend.adb
+++ b/gcc/ada/adabkend.adb
@@ -218,6 +218,9 @@ package body Adabkend is
end case;
end if;
+ elsif Switch_Chars (First .. Last) = "S" then
+ Generate_Asm := True;
+
-- Ignore all other back-end switches
elsif Is_Back_End_Switch (Switch_Chars) then
diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c
index 560f352..41453d1 100644
--- a/gcc/ada/adaint.c
+++ b/gcc/ada/adaint.c
@@ -145,6 +145,13 @@
#include "version.h"
#endif
+/* limits.h is needed for LLONG_MIN. */
+#ifdef __cplusplus
+#include <climits>
+#else
+#include <limits.h>
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -2476,9 +2483,7 @@ __gnat_number_of_cpus (void)
{
int cores = 1;
-#if defined (__linux__) || defined (__sun__) || defined (_AIX) \
- || defined (__APPLE__) || defined (__FreeBSD__) || defined (__OpenBSD__) \
- || defined (__DragonFly__) || defined (__NetBSD__)
+#ifdef _SC_NPROCESSORS_ONLN
cores = (int) sysconf (_SC_NPROCESSORS_ONLN);
#elif defined (__QNX__)
@@ -3262,7 +3267,22 @@ __gnat_copy_attribs (char *from ATTRIBUTE_UNUSED, char *to ATTRIBUTE_UNUSED,
return -1;
}
-#if _POSIX_C_SOURCE >= 200809L
+#if (defined (__vxworks) && _WRS_VXWORKS_MAJOR < 7)
+
+ /* VxWorks prior to 7 only has utime. */
+
+ /* Do we need to copy the timestamp ? */
+ if (mode != 2) {
+ struct utimbuf tbuf;
+
+ tbuf.actime = fbuf.st_atime;
+ tbuf.modtime = fbuf.st_mtime;
+
+ if (utime (to, &tbuf) == -1)
+ return -1;
+ }
+
+#elif _POSIX_C_SOURCE >= 200809L
struct timespec tbuf[2];
if (mode != 2) {
diff --git a/gcc/ada/ali-util.adb b/gcc/ada/ali-util.adb
index 9dcc656..7dabbfb 100644
--- a/gcc/ada/ali-util.adb
+++ b/gcc/ada/ali-util.adb
@@ -31,7 +31,6 @@ with Osint; use Osint;
with Scans; use Scans;
with Scng;
with Sinput.C;
-with Snames; use Snames;
with Stringt;
with Styleg;
@@ -154,15 +153,6 @@ package body ALI.Util is
Scanner.Initialize_Scanner (Source_Index);
- -- Make sure that the project language reserved words are not
- -- recognized as reserved words, but as identifiers. The byte info for
- -- those names have been set if we are in gnatmake.
-
- Set_Name_Table_Byte (Name_Project, 0);
- Set_Name_Table_Byte (Name_Extends, 0);
- Set_Name_Table_Byte (Name_External, 0);
- Set_Name_Table_Byte (Name_External_As_List, 0);
-
-- Scan the complete file to compute its checksum
loop
diff --git a/gcc/ada/aspects.adb b/gcc/ada/aspects.adb
index 37bbcae..91550c8 100644
--- a/gcc/ada/aspects.adb
+++ b/gcc/ada/aspects.adb
@@ -44,6 +44,7 @@ package body Aspects is
Aspect_Discard_Names => True,
Aspect_Independent_Components => True,
Aspect_Iterator_Element => True,
+ Aspect_Stable_Properties => True,
Aspect_Type_Invariant => True,
Aspect_Unchecked_Union => True,
Aspect_Variable_Indexing => True,
@@ -185,7 +186,11 @@ package body Aspects is
-- Find_Aspect --
-----------------
- function Find_Aspect (Id : Entity_Id; A : Aspect_Id) return Node_Id is
+ function Find_Aspect
+ (Id : Entity_Id;
+ A : Aspect_Id;
+ Class_Present : Boolean := False) return Node_Id
+ is
Decl : Node_Id;
Item : Node_Id;
Owner : Entity_Id;
@@ -219,6 +224,7 @@ package body Aspects is
while Present (Item) loop
if Nkind (Item) = N_Aspect_Specification
and then Get_Aspect_Id (Item) = A
+ and then Class_Present = Sinfo.Class_Present (Item)
then
return Item;
end if;
@@ -241,7 +247,9 @@ package body Aspects is
if Permits_Aspect_Specifications (Decl) then
Spec := First (Aspect_Specifications (Decl));
while Present (Spec) loop
- if Get_Aspect_Id (Spec) = A then
+ if Get_Aspect_Id (Spec) = A
+ and then Class_Present = Sinfo.Class_Present (Spec)
+ then
return Spec;
end if;
@@ -260,10 +268,12 @@ package body Aspects is
--------------------------
function Find_Value_Of_Aspect
- (Id : Entity_Id;
- A : Aspect_Id) return Node_Id
+ (Id : Entity_Id;
+ A : Aspect_Id;
+ Class_Present : Boolean := False) return Node_Id
is
- Spec : constant Node_Id := Find_Aspect (Id, A);
+ Spec : constant Node_Id := Find_Aspect (Id, A,
+ Class_Present => Class_Present);
begin
if Present (Spec) then
@@ -296,9 +306,13 @@ package body Aspects is
-- Has_Aspect --
----------------
- function Has_Aspect (Id : Entity_Id; A : Aspect_Id) return Boolean is
+ function Has_Aspect
+ (Id : Entity_Id;
+ A : Aspect_Id;
+ Class_Present : Boolean := False) return Boolean
+ is
begin
- return Present (Find_Aspect (Id, A));
+ return Present (Find_Aspect (Id, A, Class_Present => Class_Present));
end Has_Aspect;
------------------
diff --git a/gcc/ada/aspects.ads b/gcc/ada/aspects.ads
index 1470efe..e16ceb0 100644
--- a/gcc/ada/aspects.ads
+++ b/gcc/ada/aspects.ads
@@ -142,6 +142,7 @@ package Aspects is
Aspect_Size,
Aspect_Small,
Aspect_SPARK_Mode, -- GNAT
+ Aspect_Stable_Properties,
Aspect_Static_Predicate,
Aspect_Storage_Pool,
Aspect_Storage_Size,
@@ -237,16 +238,17 @@ package Aspects is
-- The following array indicates aspects that accept 'Class
Class_Aspect_OK : constant array (Aspect_Id) of Boolean :=
- (Aspect_Input => True,
- Aspect_Invariant => True,
- Aspect_Output => True,
- Aspect_Pre => True,
- Aspect_Predicate => True,
- Aspect_Post => True,
- Aspect_Read => True,
- Aspect_Write => True,
- Aspect_Type_Invariant => True,
- others => False);
+ (Aspect_Input => True,
+ Aspect_Invariant => True,
+ Aspect_Output => True,
+ Aspect_Pre => True,
+ Aspect_Predicate => True,
+ Aspect_Post => True,
+ Aspect_Read => True,
+ Aspect_Write => True,
+ Aspect_Stable_Properties => True,
+ Aspect_Type_Invariant => True,
+ others => False);
-- The following array identifies all implementation defined aspects
@@ -427,6 +429,7 @@ package Aspects is
Aspect_Size => Expression,
Aspect_Small => Expression,
Aspect_SPARK_Mode => Optional_Name,
+ Aspect_Stable_Properties => Expression,
Aspect_Static_Predicate => Expression,
Aspect_Storage_Pool => Name,
Aspect_Storage_Size => Expression,
@@ -528,6 +531,7 @@ package Aspects is
Aspect_Size => True,
Aspect_Small => True,
Aspect_SPARK_Mode => False,
+ Aspect_Stable_Properties => False,
Aspect_Static_Predicate => False,
Aspect_Storage_Pool => True,
Aspect_Storage_Size => True,
@@ -704,6 +708,7 @@ package Aspects is
Aspect_Size => Name_Size,
Aspect_Small => Name_Small,
Aspect_SPARK_Mode => Name_SPARK_Mode,
+ Aspect_Stable_Properties => Name_Stable_Properties,
Aspect_Static => Name_Static,
Aspect_Static_Predicate => Name_Static_Predicate,
Aspect_Storage_Pool => Name_Storage_Pool,
@@ -965,6 +970,7 @@ package Aspects is
Aspect_Refined_State => Never_Delay,
Aspect_Relaxed_Initialization => Never_Delay,
Aspect_SPARK_Mode => Never_Delay,
+ Aspect_Stable_Properties => Always_Delay,
Aspect_Static => Never_Delay,
Aspect_Subprogram_Variant => Never_Delay,
Aspect_Synchronization => Never_Delay,
@@ -1094,18 +1100,24 @@ package Aspects is
-- aspect specification list, the routine has no effect. It is assumed that
-- both nodes can support aspects.
- function Find_Aspect (Id : Entity_Id; A : Aspect_Id) return Node_Id;
- -- Find the aspect specification of aspect A associated with entity I.
+ function Find_Aspect (Id : Entity_Id;
+ A : Aspect_Id;
+ Class_Present : Boolean := False) return Node_Id;
+ -- Find the aspect specification of aspect A (or A'Class if Class_Present)
+ -- associated with entity I.
-- Return Empty if Id does not have the requested aspect.
function Find_Value_Of_Aspect
- (Id : Entity_Id;
- A : Aspect_Id) return Node_Id;
- -- Find the value of aspect A associated with entity Id. Return Empty if
- -- Id does not have the requested aspect.
-
- function Has_Aspect (Id : Entity_Id; A : Aspect_Id) return Boolean;
- -- Determine whether entity Id has aspect A
+ (Id : Entity_Id;
+ A : Aspect_Id;
+ Class_Present : Boolean := False) return Node_Id;
+ -- Find the value of aspect A (or A'Class, if Class_Present) associated
+ -- with entity Id. Return Empty if Id does not have the requested aspect.
+
+ function Has_Aspect (Id : Entity_Id;
+ A : Aspect_Id;
+ Class_Present : Boolean := False) return Boolean;
+ -- Determine whether entity Id has aspect A (or A'Class, if Class_Present)
procedure Move_Aspects (From : Node_Id; To : Node_Id);
-- Relocate the aspect specifications of node From to node To. On entry it
diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
index b389da5..803bd21 100644
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -535,7 +535,7 @@ package body Checks is
-- We do not need checks if we are not generating code (i.e. the
-- expander is not active). This is not just an optimization, there
-- are cases (e.g. with pragma Debug) where generating the checks
- -- can cause real trouble).
+ -- can cause real trouble.
if not Expander_Active then
return;
@@ -3258,23 +3258,16 @@ package body Checks is
end if;
-- Return if we know expression is definitely in the range of the target
- -- type as determined by Determine_Range. Right now we only do this for
- -- discrete types, and not fixed-point or floating-point types.
-
- -- The additional less-precise tests below catch these cases
-
- -- In GNATprove_Mode, also deal with the case of a conversion from
- -- floating-point to integer. It is only possible because analysis
- -- in GNATprove rules out the possibility of a NaN or infinite value.
+ -- type as determined by Determine_Range_To_Discrete. Right now we only
+ -- do this for discrete target types, i.e. neither for fixed-point nor
+ -- for floating-point types. But the additional less precise tests below
+ -- catch these cases.
-- Note: skip this if we are given a source_typ, since the point of
-- supplying a Source_Typ is to stop us looking at the expression.
-- We could sharpen this test to be out parameters only ???
if Is_Discrete_Type (Target_Typ)
- and then (Is_Discrete_Type (Etype (Expr))
- or else (GNATprove_Mode
- and then Is_Floating_Point_Type (Etype (Expr))))
and then not Is_Unconstrained_Subscr_Ref
and then No (Source_Typ)
then
@@ -3318,35 +3311,8 @@ package body Checks is
-- Otherwise determine range of value
- if Is_Discrete_Type (Etype (Expr)) then
- Determine_Range
- (Expr, OK, Lo, Hi, Assume_Valid => True);
-
- -- When converting a float to an integer type, determine the
- -- range in real first, and then convert the bounds using
- -- UR_To_Uint which correctly rounds away from zero when
- -- half way between two integers, as required by normal
- -- Ada 95 rounding semantics. It is only possible because
- -- analysis in GNATprove rules out the possibility of a NaN
- -- or infinite value.
-
- elsif GNATprove_Mode
- and then Is_Floating_Point_Type (Etype (Expr))
- then
- declare
- Hir : Ureal;
- Lor : Ureal;
-
- begin
- Determine_Range_R
- (Expr, OK, Lor, Hir, Assume_Valid => True);
-
- if OK then
- Lo := UR_To_Uint (Lor);
- Hi := UR_To_Uint (Hir);
- end if;
- end;
- end if;
+ Determine_Range_To_Discrete
+ (Expr, OK, Lo, Hi, Fixed_Int, Assume_Valid => True);
if OK then
@@ -3389,10 +3355,12 @@ package body Checks is
-- Check if we can determine at compile time whether Expr is in the
-- range of the target type. Note that if S_Typ is within the bounds
-- of Target_Typ then this must be the case. This check is meaningful
- -- only if this is not a conversion between integer and real types.
+ -- only if this is not a conversion between integer and real types,
+ -- unless for a fixed-point type if Fixed_Int is set.
if not Is_Unconstrained_Subscr_Ref
- and then Is_Discrete_Type (S_Typ) = Is_Discrete_Type (Target_Typ)
+ and then (Is_Discrete_Type (S_Typ) = Is_Discrete_Type (Target_Typ)
+ or else (Fixed_Int and then Is_Discrete_Type (Target_Typ)))
and then
(In_Subrange_Of (S_Typ, Target_Typ, Fixed_Int)
@@ -3705,12 +3673,15 @@ package body Checks is
then
Apply_Float_Conversion_Check (Expr, Target_Type);
else
- -- Conversions involving fixed-point types are expanded
- -- separately, and do not need a Range_Check flag, except
- -- in GNATprove_Mode, where the explicit constraint check
- -- will not be generated.
+ -- Raw conversions involving fixed-point types are expanded
+ -- separately and do not need a Range_Check flag yet, except
+ -- in GNATprove_Mode where this expansion is not performed.
+ -- This does not apply to conversion where fixed-point types
+ -- are treated as integers, which are precisely generated by
+ -- this expansion.
if GNATprove_Mode
+ or else Conv_OK
or else (not Is_Fixed_Point_Type (Expr_Type)
and then not Is_Fixed_Point_Type (Target_Type))
then
@@ -5354,38 +5325,11 @@ package body Checks is
end case;
when N_Type_Conversion =>
+ -- For a type conversion, we can try to refine the range using the
+ -- converted value.
- -- For type conversion from one discrete type to another, we can
- -- refine the range using the converted value.
-
- if Is_Discrete_Type (Etype (Expression (N))) then
- Determine_Range (Expression (N), OK1, Lor, Hir, Assume_Valid);
-
- -- When converting a float to an integer type, determine the range
- -- in real first, and then convert the bounds using UR_To_Uint
- -- which correctly rounds away from zero when half way between two
- -- integers, as required by normal Ada 95 rounding semantics. It
- -- is only possible because analysis in GNATprove rules out the
- -- possibility of a NaN or infinite value.
-
- elsif GNATprove_Mode
- and then Is_Floating_Point_Type (Etype (Expression (N)))
- then
- declare
- Lor_Real, Hir_Real : Ureal;
- begin
- Determine_Range_R (Expression (N), OK1, Lor_Real, Hir_Real,
- Assume_Valid);
-
- if OK1 then
- Lor := UR_To_Uint (Lor_Real);
- Hir := UR_To_Uint (Hir_Real);
- end if;
- end;
-
- else
- OK1 := False;
- end if;
+ Determine_Range_To_Discrete
+ (Expression (N), OK1, Lor, Hir, Conversion_OK (N), Assume_Valid);
-- Nothing special to do for all other expression kinds
@@ -5905,6 +5849,96 @@ package body Checks is
end if;
end Determine_Range_R;
+ ---------------------------------
+ -- Determine_Range_To_Discrete --
+ ---------------------------------
+
+ procedure Determine_Range_To_Discrete
+ (N : Node_Id;
+ OK : out Boolean;
+ Lo : out Uint;
+ Hi : out Uint;
+ Fixed_Int : Boolean := False;
+ Assume_Valid : Boolean := False)
+ is
+ Typ : constant Entity_Id := Etype (N);
+
+ begin
+ -- For a discrete type, simply defer to Determine_Range
+
+ if Is_Discrete_Type (Typ) then
+ Determine_Range (N, OK, Lo, Hi, Assume_Valid);
+
+ -- For a fixed point type treated as an integer, we can determine the
+ -- range using the Corresponding_Integer_Value of the bounds of the
+ -- type or base type. This is done by the calls to Expr_Value below.
+
+ elsif Is_Fixed_Point_Type (Typ) and then Fixed_Int then
+ declare
+ Btyp, Ftyp : Entity_Id;
+ Bound : Node_Id;
+
+ begin
+ if Assume_Valid then
+ Ftyp := Typ;
+ else
+ Ftyp := Underlying_Type (Base_Type (Typ));
+ end if;
+
+ Btyp := Base_Type (Ftyp);
+
+ -- First the low bound
+
+ Bound := Type_Low_Bound (Ftyp);
+
+ if Compile_Time_Known_Value (Bound) then
+ Lo := Expr_Value (Bound);
+ else
+ Lo := Expr_Value (Type_Low_Bound (Btyp));
+ end if;
+
+ -- Then the high bound
+
+ Bound := Type_High_Bound (Ftyp);
+
+ if Compile_Time_Known_Value (Bound) then
+ Hi := Expr_Value (Bound);
+ else
+ Hi := Expr_Value (Type_High_Bound (Btyp));
+ end if;
+
+ OK := True;
+ end;
+
+ -- For a floating-point type, we can determine the range in real first,
+ -- and then convert the bounds using UR_To_Uint, which correctly rounds
+ -- away from zero when half way between two integers, as required by
+ -- normal Ada 95 rounding semantics. But this is only possible because
+ -- GNATprove's analysis rules out the possibility of a NaN or infinite.
+
+ elsif GNATprove_Mode and then Is_Floating_Point_Type (Typ) then
+ declare
+ Lo_Real, Hi_Real : Ureal;
+
+ begin
+ Determine_Range_R (N, OK, Lo_Real, Hi_Real, Assume_Valid);
+
+ if OK then
+ Lo := UR_To_Uint (Lo_Real);
+ Hi := UR_To_Uint (Hi_Real);
+ else
+ Lo := No_Uint;
+ Hi := No_Uint;
+ end if;
+ end;
+
+ else
+ Lo := No_Uint;
+ Hi := No_Uint;
+ OK := False;
+ end if;
+ end Determine_Range_To_Discrete;
+
------------------------------------
-- Discriminant_Checks_Suppressed --
------------------------------------
@@ -10551,10 +10585,10 @@ package body Checks is
begin
-- Checks will be applied only when generating code. In GNATprove mode,
-- we do not apply the checks, but we still call Selected_Range_Checks
- -- to possibly issue errors on SPARK code when a run-time error can be
- -- detected at compile time.
+ -- outside of generics to possibly issue errors on SPARK code when a
+ -- run-time error can be detected at compile time.
- if not Expander_Active and not GNATprove_Mode then
+ if Inside_A_Generic or (not GNATprove_Mode and not Expander_Active) then
return Ret_Result;
end if;
diff --git a/gcc/ada/checks.ads b/gcc/ada/checks.ads
index aca1b7e..d75c602 100644
--- a/gcc/ada/checks.ads
+++ b/gcc/ada/checks.ads
@@ -338,6 +338,21 @@ package Checks is
-- For that to happen, the possibility of arguments of infinite or NaN
-- value should be taken into account, which is not the case currently.
+ procedure Determine_Range_To_Discrete
+ (N : Node_Id;
+ OK : out Boolean;
+ Lo : out Uint;
+ Hi : out Uint;
+ Fixed_Int : Boolean := False;
+ Assume_Valid : Boolean := False);
+ -- Similar to Determine_Range, but attempts to return a discrete range even
+ -- if N is not of a discrete type by doing a conversion. The Fixed_Int flag
+ -- if set causes any fixed-point values to be treated as though they were
+ -- discrete values (i.e. the underlying integer value is used), in which
+ -- case no conversion is needed. At the current time, this is used only for
+ -- discrete types, for fixed-point types if Fixed_Int is set, and also for
+ -- floating-point types in GNATprove, see Determine_Range_R above.
+
procedure Install_Null_Excluding_Check (N : Node_Id);
-- Determines whether an access node requires a run-time access check and
-- if so inserts the appropriate run-time check.
diff --git a/gcc/ada/contracts.adb b/gcc/ada/contracts.adb
index 936b16e..7387ffe 100644
--- a/gcc/ada/contracts.adb
+++ b/gcc/ada/contracts.adb
@@ -47,6 +47,7 @@ with Sem_Disp; use Sem_Disp;
with Sem_Prag; use Sem_Prag;
with Sem_Util; use Sem_Util;
with Sinfo; use Sinfo;
+with Sinput; use Sinput;
with Snames; use Snames;
with Stand; use Stand;
with Stringt; use Stringt;
@@ -904,9 +905,12 @@ package body Contracts is
-- The following checks are relevant only when SPARK_Mode is on, as
-- they are not standard Ada legality rules. Internally generated
- -- temporaries are ignored.
+ -- temporaries are ignored, as well as return objects.
- if SPARK_Mode = On and then Comes_From_Source (Type_Or_Obj_Id) then
+ if SPARK_Mode = On
+ and then Comes_From_Source (Type_Or_Obj_Id)
+ and then not Is_Return_Object (Type_Or_Obj_Id)
+ then
if Is_Effectively_Volatile (Type_Or_Obj_Id) then
-- The declaration of an effectively volatile object or type must
@@ -1668,6 +1672,12 @@ package body Contracts is
-- function, Result contains the entity of parameter _Result, to be
-- used in the creation of procedure _Postconditions.
+ procedure Add_Stable_Property_Contracts
+ (Subp_Id : Entity_Id; Class_Present : Boolean);
+ -- Augment postcondition contracts to reflect Stable_Property aspect
+ -- (if Class_Present = False) or Stable_Property'Class aspect (if
+ -- Class_Present = True).
+
procedure Append_Enabled_Item (Item : Node_Id; List : in out List_Id);
-- Append a node to a list. If there is no list, create a new one. When
-- the item denotes a pragma, it is added to the list only when it is
@@ -1905,6 +1915,244 @@ package body Contracts is
end loop;
end Add_Invariant_And_Predicate_Checks;
+ -----------------------------------
+ -- Add_Stable_Property_Contracts --
+ -----------------------------------
+
+ procedure Add_Stable_Property_Contracts
+ (Subp_Id : Entity_Id; Class_Present : Boolean)
+ is
+ Loc : constant Source_Ptr := Sloc (Subp_Id);
+
+ procedure Insert_Stable_Property_Check
+ (Formal : Entity_Id; Property_Function : Entity_Id);
+ -- Build the pragma for one check and insert it in the tree.
+
+ function Make_Stable_Property_Condition
+ (Formal : Entity_Id; Property_Function : Entity_Id) return Node_Id;
+ -- Builds tree for "Func (Formal) = Func (Formal)'Old" expression.
+
+ function Stable_Properties
+ (Aspect_Bearer : Entity_Id; Negated : out Boolean)
+ return Subprogram_List;
+ -- If no aspect specified, then returns length-zero result.
+ -- Negated indicates that reserved word NOT was specified.
+
+ ----------------------------------
+ -- Insert_Stable_Property_Check --
+ ----------------------------------
+
+ procedure Insert_Stable_Property_Check
+ (Formal : Entity_Id; Property_Function : Entity_Id) is
+
+ Args : constant List_Id :=
+ New_List
+ (Make_Pragma_Argument_Association
+ (Sloc => Loc,
+ Expression =>
+ Make_Stable_Property_Condition
+ (Formal => Formal,
+ Property_Function => Property_Function)),
+ Make_Pragma_Argument_Association
+ (Sloc => Loc,
+ Expression =>
+ Make_String_Literal
+ (Sloc => Loc,
+ Strval =>
+ "failed stable property check at "
+ & Build_Location_String (Loc)
+ & " for parameter "
+ & To_String (Fully_Qualified_Name_String
+ (Formal, Append_NUL => False))
+ & " and property function "
+ & To_String (Fully_Qualified_Name_String
+ (Property_Function, Append_NUL => False))
+ )));
+
+ Prag : constant Node_Id :=
+ Make_Pragma (Loc,
+ Pragma_Identifier =>
+ Make_Identifier (Loc, Name_Postcondition),
+ Pragma_Argument_Associations => Args,
+ Class_Present => Class_Present);
+
+ Subp_Decl : Node_Id := Subp_Id;
+ begin
+ -- Enclosing_Declaration may return, for example,
+ -- a N_Procedure_Specification node. Cope with this.
+ loop
+ Subp_Decl := Enclosing_Declaration (Subp_Decl);
+ exit when Is_Declaration (Subp_Decl);
+ Subp_Decl := Parent (Subp_Decl);
+ pragma Assert (Present (Subp_Decl));
+ end loop;
+
+ Insert_After_And_Analyze (Subp_Decl, Prag);
+ end Insert_Stable_Property_Check;
+
+ ------------------------------------
+ -- Make_Stable_Property_Condition --
+ ------------------------------------
+
+ function Make_Stable_Property_Condition
+ (Formal : Entity_Id; Property_Function : Entity_Id) return Node_Id
+ is
+ function Call_Property_Function return Node_Id is
+ (Make_Function_Call
+ (Loc,
+ Name =>
+ New_Occurrence_Of (Property_Function, Loc),
+ Parameter_Associations =>
+ New_List (New_Occurrence_Of (Formal, Loc))));
+ begin
+ return Make_Op_Eq
+ (Loc,
+ Call_Property_Function,
+ Make_Attribute_Reference
+ (Loc,
+ Prefix => Call_Property_Function,
+ Attribute_Name => Name_Old));
+ end Make_Stable_Property_Condition;
+
+ -----------------------
+ -- Stable_Properties --
+ -----------------------
+
+ function Stable_Properties
+ (Aspect_Bearer : Entity_Id; Negated : out Boolean)
+ return Subprogram_List
+ is
+ Aspect_Spec : Node_Id :=
+ Find_Value_Of_Aspect
+ (Aspect_Bearer, Aspect_Stable_Properties,
+ Class_Present => Class_Present);
+ begin
+ -- ??? For a derived type, we wish Find_Value_Of_Aspect
+ -- somehow knew that this aspect is not inherited.
+ -- But it doesn't, so we cope with that here.
+ --
+ -- There are probably issues here with inheritance from
+ -- interface types, where just looking for the one parent type
+ -- isn't enough. But this is far from the only work needed for
+ -- Stable_Properties'Class for interface types.
+
+ if Is_Derived_Type (Aspect_Bearer) then
+ declare
+ Parent_Type : constant Entity_Id :=
+ Etype (Base_Type (Aspect_Bearer));
+ begin
+ if Aspect_Spec =
+ Find_Value_Of_Aspect
+ (Parent_Type, Aspect_Stable_Properties,
+ Class_Present => Class_Present)
+ then
+ -- prevent inheritance
+ Aspect_Spec := Empty;
+ end if;
+ end;
+ end if;
+
+ if No (Aspect_Spec) then
+ Negated := Aspect_Bearer = Subp_Id;
+ -- This is a little bit subtle.
+ -- We need to assign True in the Subp_Id case in order to
+ -- distinguish between no aspect spec at all vs. an
+ -- explicitly specified "with S_P => []" empty list.
+ -- In both cases Stable_Properties will return a length-0
+ -- array, but the two cases are not equivalent.
+ -- Very roughly speaking the lack of an S_P aspect spec for
+ -- a subprogram would be equivalent to something like
+ -- "with S_P => [not]", where we apply the "not" modifier to
+ -- an empty set of subprograms, if such a construct existed.
+ -- We could just assign True here, but it seems untidy to
+ -- return True in the case of an aspect spec for a type
+ -- (since negation is only allowed for subp S_P aspects).
+
+ return (1 .. 0 => <>);
+ else
+ return Parse_Aspect_Stable_Properties
+ (Aspect_Spec, Negated => Negated);
+ end if;
+ end Stable_Properties;
+
+ Formal : Entity_Id := First_Formal (Subp_Id);
+ Type_Of_Formal : Entity_Id;
+
+ Subp_Properties_Negated : Boolean;
+ Subp_Properties : constant Subprogram_List :=
+ Stable_Properties (Subp_Id, Subp_Properties_Negated);
+
+ -- start of processing for Add_Stable_Property_Contracts
+
+ begin
+ if not (Is_Primitive (Subp_Id) and then Comes_From_Source (Subp_Id))
+ then
+ return;
+ end if;
+
+ while Present (Formal) loop
+ Type_Of_Formal := Base_Type (Etype (Formal));
+
+ if not Subp_Properties_Negated then
+
+ for SPF_Id of Subp_Properties loop
+ if Type_Of_Formal = Base_Type (Etype (First_Formal (SPF_Id)))
+ and then Scope (Type_Of_Formal) = Scope (Subp_Id)
+ then
+ -- ??? Need to filter out checks for SPFs that are
+ -- mentioned explicitly in the postcondition of
+ -- Subp_Id.
+
+ Insert_Stable_Property_Check
+ (Formal => Formal, Property_Function => SPF_Id);
+ end if;
+ end loop;
+
+ elsif Scope (Type_Of_Formal) = Scope (Subp_Id) then
+ declare
+ Ignored : Boolean range False .. False;
+
+ Typ_Property_Funcs : constant Subprogram_List :=
+ Stable_Properties (Type_Of_Formal, Negated => Ignored);
+
+ function Excluded_By_Aspect_Spec_Of_Subp
+ (SPF_Id : Entity_Id) return Boolean;
+ -- Examine Subp_Properties to determine whether SPF should
+ -- be excluded.
+
+ -------------------------------------
+ -- Excluded_By_Aspect_Spec_Of_Subp --
+ -------------------------------------
+
+ function Excluded_By_Aspect_Spec_Of_Subp
+ (SPF_Id : Entity_Id) return Boolean is
+ begin
+ pragma Assert (Subp_Properties_Negated);
+ -- Look through renames for equality test here ???
+ return (for some F of Subp_Properties => F = SPF_Id);
+ end Excluded_By_Aspect_Spec_Of_Subp;
+
+ -- Look through renames for equality test here ???
+ Subp_Is_Stable_Property_Function : constant Boolean :=
+ (for some F of Typ_Property_Funcs => F = Subp_Id);
+ begin
+ if not Subp_Is_Stable_Property_Function then
+ for SPF_Id of Typ_Property_Funcs loop
+ if not Excluded_By_Aspect_Spec_Of_Subp (SPF_Id) then
+ -- ??? Need to filter out checks for SPFs that are
+ -- mentioned explicitly in the postcondition of
+ -- Subp_Id.
+ Insert_Stable_Property_Check
+ (Formal => Formal, Property_Function => SPF_Id);
+ end if;
+ end loop;
+ end if;
+ end;
+ end if;
+ Next_Formal (Formal);
+ end loop;
+ end Add_Stable_Property_Contracts;
+
-------------------------
-- Append_Enabled_Item --
-------------------------
@@ -2559,8 +2807,7 @@ package body Contracts is
Was_Expression_Function (Body_Decl)
and then Sloc (Body_Id) /= Sloc (Subp_Id)
and then In_Same_Source_Unit (Body_Id, Subp_Id)
- and then List_Containing (Body_Decl) /=
- List_Containing (Subp_Decl);
+ and then not In_Same_List (Body_Decl, Subp_Decl);
if Present (Items) then
Prag := Pre_Post_Conditions (Items);
@@ -2794,30 +3041,39 @@ package body Contracts is
-- Routine _Postconditions holds all contract assertions that must be
-- verified on exit from the related subprogram.
- -- Step 1: Handle all preconditions. This action must come before the
+ -- Step 1: augment contracts list with postconditions associated with
+ -- Stable_Properties and Stable_Properties'Class aspects. This must
+ -- precede Process_Postconditions.
+
+ for Class_Present in Boolean loop
+ Add_Stable_Property_Contracts
+ (Subp_Id, Class_Present => Class_Present);
+ end loop;
+
+ -- Step 2: Handle all preconditions. This action must come before the
-- processing of pragma Contract_Cases because the pragma prepends items
-- to the body declarations.
Process_Preconditions;
- -- Step 2: Handle all postconditions. This action must come before the
+ -- Step 3: Handle all postconditions. This action must come before the
-- processing of pragma Contract_Cases because the pragma appends items
-- to list Stmts.
Process_Postconditions (Stmts);
- -- Step 3: Handle pragma Contract_Cases. This action must come before
+ -- Step 4: Handle pragma Contract_Cases. This action must come before
-- the processing of invariants and predicates because those append
-- items to list Stmts.
Process_Contract_Cases (Stmts);
- -- Step 4: Apply invariant and predicate checks on a function result and
+ -- Step 5: Apply invariant and predicate checks on a function result and
-- all formals. The resulting checks are accumulated in list Stmts.
Add_Invariant_And_Predicate_Checks (Subp_Id, Stmts, Result);
- -- Step 5: Construct procedure _Postconditions
+ -- Step 6: Construct procedure _Postconditions
Build_Postconditions_Procedure (Subp_Id, Stmts, Result);
diff --git a/gcc/ada/cstand.adb b/gcc/ada/cstand.adb
index fa335c1..3f5389c 100644
--- a/gcc/ada/cstand.adb
+++ b/gcc/ada/cstand.adb
@@ -1326,6 +1326,12 @@ package body CStand is
Set_Scope (Standard_Integer_64, Standard_Standard);
Build_Signed_Integer_Type (Standard_Integer_64, 64);
+ Standard_Integer_128 := New_Standard_Entity ("integer_128");
+ Decl := New_Node (N_Full_Type_Declaration, Stloc);
+ Set_Defining_Identifier (Decl, Standard_Integer_128);
+ Set_Scope (Standard_Integer_128, Standard_Standard);
+ Build_Signed_Integer_Type (Standard_Integer_128, 128);
+
-- Standard_*_Unsigned subtypes are not user visible, but they are
-- used internally. They are unsigned types with the same length as
-- the correspondingly named signed integer types.
@@ -2068,11 +2074,7 @@ package body CStand is
Build_Float_Type
(Ent, Pos (Digs), Float_Rep, Int (Size), Int (Alignment / 8));
- if No (Back_End_Float_Types) then
- Back_End_Float_Types := New_Elmt_List;
- end if;
-
- Append_Elmt (Ent, Back_End_Float_Types);
+ Append_New_Elmt (Ent, Back_End_Float_Types);
end Register_Float_Type;
----------------------
diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst b/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
index f98a427..f8d41ea 100644
--- a/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
@@ -483,6 +483,19 @@ otherwise. The intended use of this attribute is in conjunction with generic
definitions. If the attribute is applied to a generic private type, it
indicates whether or not the corresponding actual type has discriminants.
+Attribute Has_Tagged_Values
+===========================
+.. index:: Tagged values, testing for
+
+.. index:: Has_Tagged_Values
+
+The prefix of the ``Has_Tagged_Values`` attribute is a type. The result is a
+Boolean value which is True if the type is a composite type (array or record)
+that is either a tagged type or has a subcomponent that is tagged, and is False
+otherwise. The intended use of this attribute is in conjunction with generic
+definitions. If the attribute is applied to a generic private type, it
+indicates whether or not the corresponding actual type has access values.
+
Attribute Img
=============
.. index:: Img
@@ -804,8 +817,6 @@ and is static. For non-scalar types, the result is nonstatic.
Attribute Pool_Address
======================
-.. index:: Parameters, when passed by reference
-
.. index:: Pool_Address
``X'Pool_Address`` for any object ``X`` returns the address
@@ -1129,6 +1140,26 @@ for compatibility with Ada 83. See
the Ada 83 reference manual for an exact description of the semantics of
this attribute when applied to floating-point types.
+Attribute Small_Denominator
+===========================
+.. index:: Small
+
+.. index:: Small_Denominator
+
+``typ'Small_Denominator`` for any fixed-point subtype `typ` yields the
+denominator in the representation of ``typ'Small`` as a rational number
+with coprime factors (i.e. as an irreducible fraction).
+
+Attribute Small_Numerator
+=========================
+.. index:: Small
+
+.. index:: Small_Numerator
+
+``typ'Small_Numerator`` for any fixed-point subtype `typ` yields the
+numerator in the representation of ``typ'Small`` as a rational number
+with coprime factors (i.e. as an irreducible fraction).
+
Attribute Storage_Unit
======================
.. index:: Storage_Unit
diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst b/gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst
index 3174825..10fcfc9 100644
--- a/gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst
@@ -153,14 +153,27 @@ The small is the largest power of two that does not exceed the delta.
"What combinations of small, range, and digits are
supported for fixed point types. See 3.5.9(10)."
-For an ordinary fixed point type, the small must lie in 2**(-80) .. 2**80
-and the range in -10.0**36 .. 10.0**36; any combination is permitted that
-does not result in a mantissa larger than 63 bits. However, if the mantissa
-is larger than 53 bits on machines where Long_Long_Float is 64 bits (true
-of all architectures except x86), then the output from Text_IO may be
-accurate to only 53 bits, rather than the full mantissa. This is because
-floating-point conversions may be used to convert fixed point.
-
+For an ordinary fixed point type, on 32-bit platforms, the small must lie in
+2.0**(-80) .. 2.0**80 and the range in -9.0E+36 .. 9.0E+36; any combination
+is permitted that does not result in a mantissa larger than 63 bits.
+
+On 64-bit platforms, the small must lie in 2.0**(-127) .. 2.0**127 and the
+range in -1.0E+76 .. 1.0E+76; any combination is permitted that does not
+result in a mantissa larger than 63 bits, and any combination is permitted
+that results in a mantissa between 64 and 127 bits if the small is the
+ratio of two integers that lie in 1 .. 2.0**127.
+
+If the small is the ratio of two integers with 64-bit magnitude on 32-bit
+platforms and 128-bit magnitude on 64-bit platforms, which is the case if
+no ``small`` clause is provided, then the operations of the fixed point
+type are entirely implemented by means of integer instructions. In the
+other cases, some operations, in particular input and output, may be
+implemented by means of floating-point instructions and may be affected
+by accuracy issues on architectures other than x86.
+
+For a decimal fixed point type, on 32-bit platforms, the small must lie in
+1.0E-18 .. 1.0E+18 and the digits in 1 .. 18. On 64-bit platforms, the
+small must lie in 1.0E-38 .. 1.0E+38 and the digits in 1 .. 38.
*
"The result of ``Tags.Expanded_Name`` for types declared
diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
index ddf60ec..f8a62a5 100644
--- a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
@@ -434,15 +434,16 @@ Syntax::
ASSERTION_KIND ::= RM_ASSERTION_KIND | ID_ASSERTION_KIND
- RM_ASSERTION_KIND ::= Assert |
- Static_Predicate |
- Dynamic_Predicate |
- Pre |
- Pre'Class |
- Post |
- Post'Class |
- Type_Invariant |
- Type_Invariant'Class
+ RM_ASSERTION_KIND ::= Assert |
+ Static_Predicate |
+ Dynamic_Predicate |
+ Pre |
+ Pre'Class |
+ Post |
+ Post'Class |
+ Type_Invariant |
+ Type_Invariant'Class |
+ Default_Initial_Condition
ID_ASSERTION_KIND ::= Assertions |
Assert_And_Cut |
@@ -450,6 +451,7 @@ Syntax::
Contract_Cases |
Debug |
Ghost |
+ Initial_Condition |
Invariant |
Invariant'Class |
Loop_Invariant |
@@ -458,7 +460,8 @@ Syntax::
Precondition |
Predicate |
Refined_Post |
- Statement_Assertions
+ Statement_Assertions |
+ Subprogram_Variant
POLICY_IDENTIFIER ::= Check | Disable | Ignore | Suppressible
diff --git a/gcc/ada/doc/gnat_rm/intrinsic_subprograms.rst b/gcc/ada/doc/gnat_rm/intrinsic_subprograms.rst
index bf9f0b9e..e448816 100644
--- a/gcc/ada/doc/gnat_rm/intrinsic_subprograms.rst
+++ b/gcc/ada/doc/gnat_rm/intrinsic_subprograms.rst
@@ -217,7 +217,9 @@ The formal parameter names can be anything.
A more convenient way of providing these shift operators is to use
the Provide_Shift_Operators pragma, which provides the function declarations
-and corresponding pragma Import's for all five shift functions.
+and corresponding pragma Import's for all five shift functions. Note that in
+using these provided shift operations, shifts performed on negative numbers
+will result in modification of the sign bit.
.. _Source_Location:
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 1dec487..9c62d6e 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
@@ -1517,6 +1517,13 @@ Alphabetical List of All Switches
an exception because ``Self(Obj)`` produces an anonymous object which does
not share the memory location of ``Obj``.
+.. index:: -gnateb (gcc)
+
+:switch:`-gnateb`
+ Store configuration files by their basename in ALI files. This switch is
+ used for instance by gprbuild for distributed builds in order to prevent
+ issues where machine-specific absolute paths could end up being stored in
+ ALI files.
.. index:: -gnatec (gcc)
@@ -4807,7 +4814,8 @@ checks to be performed. The following checks are defined:
All keywords must be in lower case (with the exception of keywords
such as ``digits`` used as attribute names to which this check
- does not apply).
+ does not apply). A single error is reported for each line breaking
+ this rule even if multiple casing issues exist on a same line.
.. index:: -gnatyl (gcc)
@@ -6703,6 +6711,9 @@ be presented in subsequent sections.
Use the target-independent XDR protocol for stream oriented attributes
instead of the default implementation which is based on direct binary
representations and is therefore target-and endianness-dependent.
+ However it does not support 128-bit integer types and the exception
+ ``Ada.IO_Exceptions.Device_Error`` is raised if any attempt is made
+ at streaming 128-bit integer types with it.
.. index:: -Xnnn (gnatbind)
diff --git a/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst b/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst
index 2f0e10c..46d589a 100644
--- a/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst
+++ b/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst
@@ -1560,6 +1560,10 @@ temporary files that are immediately deleted; it doesn't make sense to
depend on a file that no longer exists. Such tools include
``gprbuild``, ``gnatmake``, and ``gnatcheck``.
+By default, configuration pragma files are stored by their absolute paths in
+ALI files. You can use the :switch:`-gnateb` switch in order to store them by
+their basename instead.
+
If you are using project file, a separate mechanism is provided using
project attributes.
diff --git a/gcc/ada/einfo.adb b/gcc/ada/einfo.adb
index f39b3bc..8949703 100644
--- a/gcc/ada/einfo.adb
+++ b/gcc/ada/einfo.adb
@@ -2543,6 +2543,29 @@ package body Einfo is
return Flag215 (Base_Type (Id));
end Is_Param_Block_Component_Type;
+ function Is_Partial_DIC_Procedure (Id : E) return B is
+ Partial_DIC_Suffix : constant String := "Partial_DIC";
+ DIC_Nam : constant String := Get_Name_String (Chars (Id));
+
+ begin
+ pragma Assert (Ekind (Id) in E_Function | E_Procedure);
+
+ -- Instead of adding a new Entity_Id flag (which are in short supply),
+ -- we test the form of the subprogram name. When the node field and flag
+ -- situation is eased, this should be replaced with a flag. ???
+
+ if DIC_Nam'Length > Partial_DIC_Suffix'Length
+ and then
+ DIC_Nam
+ (DIC_Nam'Last - Partial_DIC_Suffix'Length + 1 .. DIC_Nam'Last) =
+ Partial_DIC_Suffix
+ then
+ return True;
+ else
+ return False;
+ end if;
+ end Is_Partial_DIC_Procedure;
+
function Is_Partial_Invariant_Procedure (Id : E) return B is
begin
pragma Assert (Ekind (Id) in E_Function | E_Procedure);
@@ -3040,7 +3063,7 @@ package body Einfo is
function Overridden_Operation (Id : E) return E is
begin
- pragma Assert (Is_Subprogram (Id) or else Is_Generic_Subprogram (Id));
+ pragma Assert (Is_Subprogram_Or_Generic_Subprogram (Id));
return Node26 (Id);
end Overridden_Operation;
@@ -3133,7 +3156,7 @@ package body Einfo is
function Protected_Body_Subprogram (Id : E) return E is
begin
- pragma Assert (Is_Subprogram (Id) or else Is_Entry (Id));
+ pragma Assert (Is_Subprogram_Or_Entry (Id));
return Node11 (Id);
end Protected_Body_Subprogram;
@@ -3202,7 +3225,8 @@ package body Einfo is
function Related_Expression (Id : E) return N is
begin
- pragma Assert (Ekind (Id) in Type_Kind | E_Constant | E_Variable);
+ pragma Assert
+ (Ekind (Id) in Type_Kind | E_Constant | E_Variable | E_Function);
return Node24 (Id);
end Related_Expression;
@@ -4914,7 +4938,7 @@ package body Einfo is
procedure Set_Has_Out_Or_In_Out_Parameter (Id : E; V : B := True) is
begin
pragma Assert
- (Ekind (Id) in E_Entry | E_Entry_Family
+ (Is_Entry (Id)
or else Is_Subprogram_Or_Generic_Subprogram (Id));
Set_Flag110 (Id, V);
end Set_Has_Out_Or_In_Out_Parameter;
@@ -6201,7 +6225,7 @@ package body Einfo is
procedure Set_No_Return (Id : E; V : B := True) is
begin
- pragma Assert (Is_Subprogram (Id) or else Is_Generic_Subprogram (Id));
+ pragma Assert (Is_Subprogram_Or_Generic_Subprogram (Id));
Set_Flag113 (Id, V);
end Set_No_Return;
@@ -6308,7 +6332,7 @@ package body Einfo is
procedure Set_Overridden_Operation (Id : E; V : E) is
begin
- pragma Assert (Is_Subprogram (Id) or else Is_Generic_Subprogram (Id));
+ pragma Assert (Is_Subprogram_Or_Generic_Subprogram (Id));
Set_Node26 (Id, V);
end Set_Overridden_Operation;
@@ -6406,7 +6430,7 @@ package body Einfo is
procedure Set_Protected_Body_Subprogram (Id : E; V : E) is
begin
- pragma Assert (Is_Subprogram (Id) or else Is_Entry (Id));
+ pragma Assert (Is_Subprogram_Or_Entry (Id));
Set_Node11 (Id, V);
end Set_Protected_Body_Subprogram;
@@ -6478,7 +6502,8 @@ package body Einfo is
procedure Set_Related_Expression (Id : E; V : N) is
begin
pragma Assert
- (Ekind (Id) in Type_Kind | E_Constant | E_Variable | E_Void);
+ (Ekind (Id) in
+ Type_Kind | E_Constant | E_Variable | E_Function | E_Void);
Set_Node24 (Id, V);
end Set_Related_Expression;
@@ -7358,7 +7383,7 @@ package body Einfo is
---------------------
function Designated_Type (Id : E) return E is
- Desig_Type : E;
+ Desig_Type : Entity_Id;
begin
Desig_Type := Directly_Designated_Type (Id);
@@ -7399,7 +7424,13 @@ package body Einfo is
while Present (Subp_Elmt) loop
Subp_Id := Node (Subp_Elmt);
- if Is_DIC_Procedure (Subp_Id) then
+ -- Currently the flag Is_DIC_Procedure is set for both normal DIC
+ -- check procedures as well as for partial DIC check procedures,
+ -- and we don't have a flag for the partial procedures.
+
+ if Is_DIC_Procedure (Subp_Id)
+ and then not Is_Partial_DIC_Procedure (Subp_Id)
+ then
return Subp_Id;
end if;
@@ -7425,7 +7456,7 @@ package body Einfo is
---------------------
function First_Component (Id : E) return E is
- Comp_Id : E;
+ Comp_Id : Entity_Id;
begin
pragma Assert
@@ -7447,7 +7478,7 @@ package body Einfo is
-------------------------------------
function First_Component_Or_Discriminant (Id : E) return E is
- Comp_Id : E;
+ Comp_Id : Entity_Id;
begin
pragma Assert
@@ -7470,7 +7501,7 @@ package body Einfo is
------------------
function First_Formal (Id : E) return E is
- Formal : E;
+ Formal : Entity_Id;
begin
pragma Assert
@@ -7511,7 +7542,7 @@ package body Einfo is
------------------------------
function First_Formal_With_Extras (Id : E) return E is
- Formal : E;
+ Formal : Entity_Id;
begin
pragma Assert
@@ -8152,9 +8183,7 @@ package body Einfo is
begin
-- Identifiers, operator symbols, expanded names are entity names
- return Kind = N_Identifier
- or else Kind = N_Operator_Symbol
- or else Kind = N_Expanded_Name
+ return Kind in N_Identifier | N_Operator_Symbol | N_Expanded_Name
-- Attribute references are entity names if they refer to an entity.
-- Note that we don't do this by testing for the presence of the
@@ -8173,10 +8202,9 @@ package body Einfo is
begin
return
Ekind (Id) in E_Constant | E_Package | E_Variable
- or else Is_Entry (Id)
- or else Is_Generic_Unit (Id)
- or else Is_Subprogram (Id)
- or else Is_Task_Type (Id);
+ or else Is_Generic_Unit (Id)
+ or else Is_Subprogram_Or_Entry (Id)
+ or else Is_Task_Type (Id);
end Is_Elaboration_Target;
-----------------------
@@ -8307,21 +8335,10 @@ package body Einfo is
function Is_Standard_Character_Type (Id : E) return B is
begin
- if Is_Type (Id) then
- declare
- R : constant Entity_Id := Root_Type (Id);
- begin
- return
- R = Standard_Character
- or else
- R = Standard_Wide_Character
- or else
- R = Standard_Wide_Wide_Character;
- end;
-
- else
- return False;
- end if;
+ return Is_Type (Id)
+ and then Root_Type (Id) in Standard_Character
+ | Standard_Wide_Character
+ | Standard_Wide_Wide_Character;
end Is_Standard_Character_Type;
-----------------------------
@@ -8330,21 +8347,10 @@ package body Einfo is
function Is_Standard_String_Type (Id : E) return B is
begin
- if Is_Type (Id) then
- declare
- R : constant Entity_Id := Root_Type (Id);
- begin
- return
- R = Standard_String
- or else
- R = Standard_Wide_String
- or else
- R = Standard_Wide_Wide_String;
- end;
-
- else
- return False;
- end if;
+ return Is_Type (Id)
+ and then Root_Type (Id) in Standard_String
+ | Standard_Wide_String
+ | Standard_Wide_Wide_String;
end Is_Standard_String_Type;
--------------------
@@ -8435,7 +8441,7 @@ package body Einfo is
-----------------
function Last_Formal (Id : E) return E is
- Formal : E;
+ Formal : Entity_Id;
begin
pragma Assert
@@ -8452,7 +8458,7 @@ package body Einfo is
if Present (Formal) then
while Present (Next_Formal (Formal)) loop
- Formal := Next_Formal (Formal);
+ Next_Formal (Formal);
end loop;
end if;
@@ -8591,7 +8597,7 @@ package body Einfo is
--------------------
function Next_Component (Id : E) return E is
- Comp_Id : E;
+ Comp_Id : Entity_Id;
begin
Comp_Id := Next_Entity (Id);
@@ -8608,7 +8614,7 @@ package body Einfo is
------------------------------------
function Next_Component_Or_Discriminant (Id : E) return E is
- Comp_Id : E;
+ Comp_Id : Entity_Id;
begin
Comp_Id := Next_Entity (Id);
@@ -8667,7 +8673,7 @@ package body Einfo is
-----------------
function Next_Formal (Id : E) return E is
- P : E;
+ P : Entity_Id;
begin
-- Follow the chain of declared entities as long as the kind of the
@@ -8815,6 +8821,36 @@ package body Einfo is
return Ekind (Id);
end Parameter_Mode;
+ ---------------------------
+ -- Partial_DIC_Procedure --
+ ---------------------------
+
+ function Partial_DIC_Procedure (Id : E) return E is
+ Subp_Elmt : Elmt_Id;
+ Subp_Id : Entity_Id;
+ Subps : Elist_Id;
+
+ begin
+ pragma Assert (Is_Type (Id));
+
+ Subps := Subprograms_For_Type (Base_Type (Id));
+
+ if Present (Subps) then
+ Subp_Elmt := First_Elmt (Subps);
+ while Present (Subp_Elmt) loop
+ Subp_Id := Node (Subp_Elmt);
+
+ if Is_Partial_DIC_Procedure (Subp_Id) then
+ return Subp_Id;
+ end if;
+
+ Next_Elmt (Subp_Elmt);
+ end loop;
+ end if;
+
+ return Empty;
+ end Partial_DIC_Procedure;
+
---------------------------------
-- Partial_Invariant_Procedure --
---------------------------------
@@ -9131,7 +9167,7 @@ package body Einfo is
---------------
function Root_Type (Id : E) return E is
- T, Etyp : E;
+ T, Etyp : Entity_Id;
begin
pragma Assert (Nkind (Id) in N_Entity);
@@ -9294,8 +9330,6 @@ package body Einfo is
procedure Set_DIC_Procedure (Id : E; V : E) is
Base_Typ : Entity_Id;
- Subp_Elmt : Elmt_Id;
- Subp_Id : Entity_Id;
Subps : Elist_Id;
begin
@@ -9309,21 +9343,17 @@ package body Einfo is
Set_Subprograms_For_Type (Base_Typ, Subps);
end if;
- Subp_Elmt := First_Elmt (Subps);
Prepend_Elmt (V, Subps);
+ end Set_DIC_Procedure;
- -- Check for a duplicate default initial condition procedure
-
- while Present (Subp_Elmt) loop
- Subp_Id := Node (Subp_Elmt);
-
- if Is_DIC_Procedure (Subp_Id) then
- raise Program_Error;
- end if;
+ -------------------------------------
+ -- Set_Partial_Invariant_Procedure --
+ -------------------------------------
- Next_Elmt (Subp_Elmt);
- end loop;
- end Set_DIC_Procedure;
+ procedure Set_Partial_DIC_Procedure (Id : E; V : E) is
+ begin
+ Set_DIC_Procedure (Id, V);
+ end Set_Partial_DIC_Procedure;
-----------------------------
-- Set_Invariant_Procedure --
@@ -10122,7 +10152,7 @@ package body Einfo is
when Array_Kind =>
declare
- Index : E;
+ Index : Entity_Id;
begin
Write_Attribute
diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads
index be195ab..360ce7c 100644
--- a/gcc/ada/einfo.ads
+++ b/gcc/ada/einfo.ads
@@ -420,8 +420,10 @@ package Einfo is
-- output of certain warnings.
-- Aft_Value (synthesized)
--- Applies to fixed and decimal types. Computes a universal integer that
--- holds value of the Aft attribute for the type.
+-- Applies to fixed-point types and subtypes. This yields the value of
+-- the Aft attribute for the type, i.e. the number of decimal digits
+-- needed after the decimal point to accommodate the delta of the type,
+-- unless the delta is greater than 0.1, in which case it is 1.
-- Alias (Node18)
-- Defined in overloadable entities (literals, subprograms, entries) and
@@ -3930,6 +3932,20 @@ package Einfo is
-- of a single protected/task type, the references are examined as they
-- must appear only within the type defintion and the corresponding body.
+-- Partial_DIC_Procedure (synthesized)
+-- Defined in type entities. Set for a private type and its full view
+-- when the type is subject to pragma Default_Initial_Condition (DIC), or
+-- when the type inherits a DIC pragma from a parent type. Points to the
+-- entity of a procedure that takes a single argument of the given type
+-- and verifies the assertion expression of the DIC pragma at run time.
+-- When present, the Partial_DIC_Procedure of a type only checks DICs
+-- associated with the partial (private) view of the type, and is invoked
+-- by the full DIC_Procedure (which may check additional DICs associated
+-- with the full view).
+
+-- Note: the reason this is marked as a synthesized attribute is that the
+-- way this is stored is as an element of the Subprograms_For_Type field.
+
-- Partial_Invariant_Procedure (synthesized)
-- Defined in types and subtypes. Set for private types when one or more
-- [class-wide] type invariants apply to them. Points to the entity for a
@@ -4115,14 +4131,16 @@ package Einfo is
-- only for type-related error messages.
-- Related_Expression (Node24)
--- Defined in variables and types. When Set for internally generated
--- entities, it may be used to denote the source expression whose
--- elaboration created the variable declaration. If set, it is used
+-- Defined in variables, types and functions. When Set for internally
+-- generated entities, it may be used to denote the source expression
+-- whose elaboration created the variable declaration. If set, it is used
-- for generating clearer messages from CodePeer. It is used on source
-- entities that are variables in iterator specifications, to provide
-- a link to the container that is the domain of iteration. This allows
-- for better cross-reference information when the loop modifies elements
-- of the container, and suppresses spurious warnings.
+-- Finally this node is used on functions specified via the Real_Literal
+-- aspect, to denote the 2-parameter overloading, if found.
--
-- Shouldn't it also be used for the same purpose in errout? It seems
-- odd to have two mechanisms here???
@@ -4261,9 +4279,10 @@ package Einfo is
-- explicit range).
-- Scale_Value (Uint16)
--- Defined in decimal fixed-point types and subtypes. Contains the scale
--- for the type (i.e. the value of type'Scale = the number of decimal
--- digits after the decimal point).
+-- Defined in decimal fixed-point types and subtypes. This holds the
+-- value of the Scale attribute for the type, i.e. the scale of the type
+-- defined as the integer N such that the delta is equal to 10.0**(-N).
+-- Note that, if Scale_Value is positive, then it is equal to Aft_Value.
-- Scope (Node3)
-- Defined in all entities. Points to the entity for the scope (block,
@@ -4591,15 +4610,13 @@ package Einfo is
-- Applies to scalar types. Returns the tree node (Node_Id) that contains
-- the high bound of a scalar type. The returned value is literal for a
-- base type, but may be an expression in the case of scalar type with
--- dynamic bounds. Note that in the case of a fixed point type, the high
--- bound is in units of small, and is an integer.
+-- dynamic bounds.
-- Type_Low_Bound (synthesized)
-- Applies to scalar types. Returns the tree node (Node_Id) that contains
-- the low bound of a scalar type. The returned value is literal for a
-- base type, but may be an expression in the case of scalar type with
--- dynamic bounds. Note that in the case of a fixed point type, the low
--- bound is in units of small, and is an integer.
+-- dynamic bounds.
-- Underlying_Full_View (Node19)
-- Defined in private subtypes that are the completion of other private
@@ -5818,6 +5835,7 @@ package Einfo is
-- Is_Full_Access (synth)
-- Is_Controlled (synth)
-- Object_Size_Clause (synth)
+ -- Partial_DIC_Procedure (synth)
-- Partial_Invariant_Procedure (synth)
-- Predicate_Function (synth)
-- Predicate_Function_M (synth)
@@ -6583,6 +6601,7 @@ package Einfo is
-- Is_Invariant_Procedure (Flag257) (non-generic case only)
-- Is_Machine_Code_Subprogram (Flag137) (non-generic case only)
-- Is_Null_Init_Proc (Flag178)
+ -- Is_Partial_DIC_Procedure (synth) (non-generic case only)
-- Is_Partial_Invariant_Procedure (Flag292) (non-generic case only)
-- Is_Predicate_Function (Flag255) (non-generic case only)
-- Is_Predicate_Function_M (Flag256) (non-generic case only)
@@ -7402,6 +7421,7 @@ package Einfo is
function Is_Packed_Array_Impl_Type (Id : E) return B;
function Is_Potentially_Use_Visible (Id : E) return B;
function Is_Param_Block_Component_Type (Id : E) return B;
+ function Is_Partial_DIC_Procedure (Id : E) return B;
function Is_Partial_Invariant_Procedure (Id : E) return B;
function Is_Predicate_Function (Id : E) return B;
function Is_Predicate_Function_M (Id : E) return B;
@@ -8306,12 +8326,14 @@ package Einfo is
---------------------------------------------------
function DIC_Procedure (Id : E) return E;
+ function Partial_DIC_Procedure (Id : E) return E;
function Invariant_Procedure (Id : E) return E;
function Partial_Invariant_Procedure (Id : E) return E;
function Predicate_Function (Id : E) return E;
function Predicate_Function_M (Id : E) return E;
procedure Set_DIC_Procedure (Id : E; V : E);
+ procedure Set_Partial_DIC_Procedure (Id : E; V : E);
procedure Set_Invariant_Procedure (Id : E; V : E);
procedure Set_Partial_Invariant_Procedure (Id : E; V : E);
procedure Set_Predicate_Function (Id : E; V : E);
diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb
index 049db89..fbbf579 100644
--- a/gcc/ada/errout.adb
+++ b/gcc/ada/errout.adb
@@ -337,7 +337,7 @@ package body Errout is
begin
-- Return if all errors are to be ignored
- if Errors_Must_Be_Ignored then
+ if Get_Ignore_Errors then
return;
end if;
@@ -1430,7 +1430,9 @@ package body Errout is
Last_Killed := True;
end if;
- Set_Posted (N);
+ if not Get_Ignore_Errors then
+ Set_Posted (N);
+ end if;
end Error_Msg_NEL;
------------------
diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 986ccc9..30f6dd9 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -1865,6 +1865,21 @@ package body Exp_Aggr is
Typ => Ctype,
With_Default_Init => True));
+ -- If Default_Initial_Condition applies to the component type,
+ -- add a DIC check after the component is default-initialized.
+ -- It will be analyzed and resolved before the code for
+ -- initialization of other components.
+
+ -- Theoretically this might also be needed for cases where
+ -- the component type doesn't have an init proc (such as for
+ -- Default_Value cases), but those should be uncommon, and for
+ -- now we only support the init proc case. ???
+
+ if Has_DIC (Ctype) and then Present (DIC_Procedure (Ctype)) then
+ Append_To (Stmts,
+ Build_DIC_Call (Loc, New_Copy_Tree (Indexed_Comp), Ctype));
+ end if;
+
-- If the component type has invariants, add an invariant
-- check after the component is default-initialized. It will
-- be analyzed and resolved before the code for initialization
@@ -3504,6 +3519,18 @@ package body Exp_Aggr is
then
Check_Ancestor_Discriminants (Entity (Ancestor));
end if;
+
+ -- If ancestor type has Default_Initialization_Condition,
+ -- add a DIC check after the ancestor object is initialized
+ -- by default.
+
+ if Has_DIC (Entity (Ancestor))
+ and then Present (DIC_Procedure (Entity (Ancestor)))
+ then
+ Append_To (L,
+ Build_DIC_Call
+ (Loc, New_Copy_Tree (Ref), Entity (Ancestor)));
+ end if;
end if;
-- Handle calls to C++ constructors
@@ -4109,6 +4136,22 @@ package body Exp_Aggr is
end;
end if;
+ -- If the component association was specified with a box and the
+ -- component type has a Default_Initial_Condition, then generate
+ -- a call to the DIC procedure.
+
+ if Has_DIC (Etype (Selector))
+ and then Was_Default_Init_Box_Association (Comp)
+ and then Present (DIC_Procedure (Etype (Selector)))
+ then
+ Append_To (L,
+ Build_DIC_Call (Loc,
+ Make_Selected_Component (Loc,
+ Prefix => New_Copy_Tree (Target),
+ Selector_Name => New_Occurrence_Of (Selector, Loc)),
+ Etype (Selector)));
+ end if;
+
Next (Comp);
end loop;
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index f95c682..251fa14 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -67,6 +67,7 @@ with Tbuild; use Tbuild;
with Ttypes; use Ttypes;
with Uintp; use Uintp;
with Uname; use Uname;
+with Urealp; use Urealp;
with Validsw; use Validsw;
package body Exp_Attr is
@@ -1209,7 +1210,7 @@ package body Exp_Attr is
-- by Expand_Fpt_Attribute
procedure Expand_Fpt_Attribute_R (N : Node_Id) is
- E1 : constant Node_Id := First (Expressions (N));
+ E1 : constant Node_Id := First (Expressions (N));
Ftp : Entity_Id;
Pkg : RE_Id;
begin
@@ -1229,10 +1230,10 @@ package body Exp_Attr is
-- by Expand_Fpt_Attribute
procedure Expand_Fpt_Attribute_RI (N : Node_Id) is
- E1 : constant Node_Id := First (Expressions (N));
+ E1 : constant Node_Id := First (Expressions (N));
+ E2 : constant Node_Id := Next (E1);
Ftp : Entity_Id;
Pkg : RE_Id;
- E2 : constant Node_Id := Next (E1);
begin
Find_Fat_Info (Etype (E1), Ftp, Pkg);
Expand_Fpt_Attribute
@@ -2822,7 +2823,7 @@ package body Exp_Attr is
Id_Kind : constant Entity_Id := RTE (RO_AT_Task_Id);
Ent : constant Entity_Id := Entity (Pref);
Conctype : constant Entity_Id := Scope (Ent);
- Nest_Depth : Integer := 0;
+ Nest_Depth : Nat := 0;
Name : Node_Id;
S : Entity_Id;
@@ -2885,7 +2886,7 @@ package body Exp_Attr is
New_Occurrence_Of (RTE (RE_Task_Entry_Caller), Loc),
Parameter_Associations => New_List (
Make_Integer_Literal (Loc,
- Intval => Int (Nest_Depth))))));
+ Intval => Nest_Depth)))));
end if;
Analyze_And_Resolve (N, Id_Kind);
@@ -2923,8 +2924,6 @@ package body Exp_Attr is
when Attribute_Constrained => Constrained : declare
Formal_Ent : constant Entity_Id := Param_Entity (Pref);
- -- Start of processing for Constrained
-
begin
-- Reference to a parameter where the value is passed as an extra
-- actual, corresponding to the extra formal referenced by the
@@ -2938,7 +2937,7 @@ package body Exp_Attr is
then
Rewrite (N,
New_Occurrence_Of
- (Extra_Constrained (Formal_Ent), Sloc (N)));
+ (Extra_Constrained (Formal_Ent), Loc));
-- If the prefix is an access to object, the attribute applies to
-- the designated object, so rewrite with an explicit dereference.
@@ -2949,8 +2948,6 @@ package body Exp_Attr is
then
Rewrite (Pref,
Make_Explicit_Dereference (Loc, Relocate_Node (Pref)));
- Analyze_And_Resolve (N, Standard_Boolean);
- return;
-- For variables with a Extra_Constrained field, we use the
-- corresponding entity.
@@ -2961,7 +2958,7 @@ package body Exp_Attr is
then
Rewrite (N,
New_Occurrence_Of
- (Extra_Constrained (Entity (Pref)), Sloc (N)));
+ (Extra_Constrained (Entity (Pref)), Loc));
-- For all other cases, we can tell at compile time
@@ -2978,8 +2975,7 @@ package body Exp_Attr is
Rewrite (N,
New_Occurrence_Of
(Boolean_Literals
- (Exp_Util.Attribute_Constrained_Static_Value
- (Pref)), Sloc (N)));
+ (Exp_Util.Attribute_Constrained_Static_Value (Pref)), Loc));
end if;
Analyze_And_Resolve (N, Standard_Boolean);
@@ -2990,7 +2986,7 @@ package body Exp_Attr is
---------------
-- Transforms 'Copy_Sign into a call to the floating-point attribute
- -- function Copy_Sign in Fat_xxx (where xxx is the root type)
+ -- function Copy_Sign in Fat_xxx (where xxx is the root type).
when Attribute_Copy_Sign =>
Expand_Fpt_Attribute_RR (N);
@@ -3389,7 +3385,7 @@ package body Exp_Attr is
Size : Entity_Id;
- -- Start of Finalization_Size
+ -- Start of processing for Finalization_Size
begin
-- An object of a class-wide type first requires a runtime check to
@@ -3620,31 +3616,145 @@ package body Exp_Attr is
-- expands into
- -- Result_Type (System.Fore (Universal_Real (Type'First)),
- -- Universal_Real (Type'Last))
+ -- System.Fore_xx (ftyp (Typ'First), ftyp (Typ'Last) [,pm])
+
+ -- For decimal fixed-point types
+ -- xx = Decimal{32,64,128}
+ -- ftyp = Integer_{32,64,128}
+ -- pm = Typ'Scale
+
+ -- For the most common ordinary fixed-point types
+ -- xx = Fixed{32,64,128}
+ -- ftyp = Integer_{32,64,128}
+ -- pm = numerator of Typ'Small
+ -- denominator of Typ'Small
+ -- min (scale of Typ'Small, 0)
+
+ -- For other ordinary fixed-point types
+ -- xx = Real
+ -- ftyp = Universal_Real
+ -- pm = none
-- Note that we know that the type is a nonstatic subtype, or Fore would
- -- have itself been computed dynamically in Eval_Attribute.
+ -- have been computed statically in Eval_Attribute.
when Attribute_Fore =>
- Rewrite (N,
- Convert_To (Typ,
- Make_Function_Call (Loc,
- Name =>
- New_Occurrence_Of (RTE (RE_Fore), Loc),
+ declare
+ Arg_List : List_Id;
+ Fid : RE_Id;
+ Ftyp : Entity_Id;
- Parameter_Associations => New_List (
- Convert_To (Universal_Real,
- Make_Attribute_Reference (Loc,
- Prefix => New_Occurrence_Of (Ptyp, Loc),
- Attribute_Name => Name_First)),
+ begin
+ if Is_Decimal_Fixed_Point_Type (Ptyp) then
+ if Esize (Ptyp) <= 32 then
+ Fid := RE_Fore_Decimal32;
+ Ftyp := RTE (RE_Integer_32);
+ elsif Esize (Ptyp) <= 64 then
+ Fid := RE_Fore_Decimal64;
+ Ftyp := RTE (RE_Integer_64);
+ else
+ Fid := RE_Fore_Decimal128;
+ Ftyp := RTE (RE_Integer_128);
+ end if;
- Convert_To (Universal_Real,
- Make_Attribute_Reference (Loc,
- Prefix => New_Occurrence_Of (Ptyp, Loc),
- Attribute_Name => Name_Last))))));
+ else
+ declare
+ Num : constant Uint := Norm_Num (Small_Value (Ptyp));
+ Den : constant Uint := Norm_Den (Small_Value (Ptyp));
+ Max : constant Uint := UI_Max (Num, Den);
+ Min : constant Uint := UI_Min (Num, Den);
+ Siz : constant Uint := Esize (Ptyp);
- Analyze_And_Resolve (N, Typ);
+ begin
+ if Siz <= 32
+ and then Max <= Uint_2 ** 31
+ and then (Min = Uint_1
+ or else Num < Den
+ or else Num < Uint_10 ** 8)
+ then
+ Fid := RE_Fore_Fixed32;
+ Ftyp := RTE (RE_Integer_32);
+ elsif Siz <= 64
+ and then Max <= Uint_2 ** 63
+ and then (Min = Uint_1
+ or else Num < Den
+ or else Num < Uint_10 ** 17)
+ then
+ Fid := RE_Fore_Fixed64;
+ Ftyp := RTE (RE_Integer_64);
+ elsif System_Max_Integer_Size = 128
+ and then Max <= Uint_2 ** 127
+ and then (Min = Uint_1
+ or else Num < Den
+ or else Num < Uint_10 ** 37)
+ then
+ Fid := RE_Fore_Fixed128;
+ Ftyp := RTE (RE_Integer_128);
+ else
+ Fid := RE_Fore_Real;
+ Ftyp := Universal_Real;
+ end if;
+ end;
+ end if;
+
+ Arg_List := New_List (
+ Convert_To (Ftyp,
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Occurrence_Of (Ptyp, Loc),
+ Attribute_Name => Name_First)));
+
+ Append_To (Arg_List,
+ Convert_To (Ftyp,
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Occurrence_Of (Ptyp, Loc),
+ Attribute_Name => Name_Last)));
+
+ -- For decimal, append Scale and also set to do literal conversion
+
+ if Is_Decimal_Fixed_Point_Type (Ptyp) then
+ Set_Conversion_OK (First (Arg_List));
+ Set_Conversion_OK (Next (First (Arg_List)));
+
+ Append_To (Arg_List,
+ Make_Integer_Literal (Loc, Scale_Value (Ptyp)));
+
+ -- For ordinary fixed-point types, append Num, Den and Scale
+ -- parameters and also set to do literal conversion
+
+ elsif Fid /= RE_Fore_Real then
+ Set_Conversion_OK (First (Arg_List));
+ Set_Conversion_OK (Next (First (Arg_List)));
+
+ Append_To (Arg_List,
+ Make_Integer_Literal (Loc, -Norm_Num (Small_Value (Ptyp))));
+
+ Append_To (Arg_List,
+ Make_Integer_Literal (Loc, -Norm_Den (Small_Value (Ptyp))));
+
+ declare
+ Val : Ureal := Small_Value (Ptyp);
+ Scale : Int := 0;
+
+ begin
+ while Val >= Ureal_10 loop
+ Val := Val / Ureal_10;
+ Scale := Scale - 1;
+ end loop;
+
+ Append_To (Arg_List,
+ Make_Integer_Literal (Loc, UI_From_Int (Scale)));
+ end;
+ end if;
+
+ Rewrite (N,
+ Convert_To (Typ,
+ Make_Function_Call (Loc,
+ Name =>
+ New_Occurrence_Of (RTE (Fid), Loc),
+ Parameter_Associations => Arg_List)));
+
+ Analyze_And_Resolve (N, Typ);
+ end;
--------------
-- Fraction --
@@ -4240,7 +4350,7 @@ package body Exp_Attr is
begin
-- Processing for packed array types
- if Is_Array_Type (Ptyp) and then Is_Packed (Ptyp) then
+ if Is_Packed_Array (Ptyp) then
Ityp := Get_Index_Subtype (N);
-- If the index type, Ityp, is an enumeration type with holes,
@@ -4338,7 +4448,7 @@ package body Exp_Attr is
Xtyp : Entity_Id;
begin
- if Is_Array_Type (Dtyp) and then Is_Packed (Dtyp) then
+ if Is_Packed_Array (Dtyp) then
Xtyp := Get_Index_Subtype (N);
Rewrite (N,
@@ -5717,14 +5827,14 @@ package body Exp_Attr is
when Attribute_Reduce =>
declare
- Loc : constant Source_Ptr := Sloc (N);
- E1 : constant Node_Id := First (Expressions (N));
- E2 : constant Node_Id := Next (E1);
- Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
- Typ : constant Entity_Id := Etype (N);
+ Loc : constant Source_Ptr := Sloc (N);
+ E1 : constant Node_Id := First (Expressions (N));
+ E2 : constant Node_Id := Next (E1);
+ Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
+ Typ : constant Entity_Id := Etype (N);
New_Loop : Node_Id;
- Stat : Node_Id;
+ Stat : Node_Id;
function Build_Stat (Comp : Node_Id) return Node_Id;
-- The reducer can be a function, a procedure whose first
@@ -5739,14 +5849,14 @@ package body Exp_Attr is
function Build_Stat (Comp : Node_Id) return Node_Id is
begin
if Nkind (E1) = N_Attribute_Reference then
- Stat := Make_Assignment_Statement (Loc,
- Name => New_Occurrence_Of (Bnn, Loc),
- Expression => Make_Attribute_Reference (Loc,
- Attribute_Name => Attribute_Name (E1),
- Prefix => New_Copy (Prefix (E1)),
- Expressions => New_List (
- New_Occurrence_Of (Bnn, Loc),
- Comp)));
+ Stat := Make_Assignment_Statement (Loc,
+ Name => New_Occurrence_Of (Bnn, Loc),
+ Expression => Make_Attribute_Reference (Loc,
+ Attribute_Name => Attribute_Name (E1),
+ Prefix => New_Copy (Prefix (E1)),
+ Expressions => New_List (
+ New_Occurrence_Of (Bnn, Loc),
+ Comp)));
elsif Ekind (Entity (E1)) = E_Procedure then
Stat := Make_Procedure_Call_Statement (Loc,
@@ -5755,13 +5865,13 @@ package body Exp_Attr is
New_Occurrence_Of (Bnn, Loc),
Comp));
else
- Stat := Make_Assignment_Statement (Loc,
- Name => New_Occurrence_Of (Bnn, Loc),
- Expression => Make_Function_Call (Loc,
- Name => New_Occurrence_Of (Entity (E1), Loc),
- Parameter_Associations => New_List (
- New_Occurrence_Of (Bnn, Loc),
- Comp)));
+ Stat := Make_Assignment_Statement (Loc,
+ Name => New_Occurrence_Of (Bnn, Loc),
+ Expression => Make_Function_Call (Loc,
+ Name => New_Occurrence_Of (Entity (E1), Loc),
+ Parameter_Associations => New_List (
+ New_Occurrence_Of (Bnn, Loc),
+ Comp)));
end if;
return Stat;
@@ -5769,9 +5879,8 @@ package body Exp_Attr is
-- If the prefix is an aggregate, its unique component is an
-- Iterated_Element, and we create a loop out of its iterator.
- -- The iterated_component_Association is parsed as a loop
- -- parameter specification with "in" or as a container
- -- iterator with "of".
+ -- The iterated_component_association is parsed as a loop parameter
+ -- specification with "in" or as a container iterator with "of".
begin
if Nkind (Prefix (N)) = N_Aggregate then
@@ -6229,7 +6338,7 @@ package body Exp_Attr is
then
Set_Attribute_Name (N, Name_Object_Size);
- -- In all other cases, Size and VADS_Size are the sane
+ -- In all other cases, Size and VADS_Size are the same
else
Set_Attribute_Name (N, Name_Size);
@@ -6293,7 +6402,7 @@ package body Exp_Attr is
------------------
when Attribute_Storage_Size => Storage_Size : declare
- Alloc_Op : Entity_Id := Empty;
+ Alloc_Op : Entity_Id := Empty;
begin
@@ -6714,7 +6823,7 @@ package body Exp_Attr is
------------
when Attribute_To_Any => To_Any : declare
- Decls : constant List_Id := New_List;
+ Decls : constant List_Id := New_List;
begin
Rewrite (N,
Build_To_Any_Call
@@ -6743,7 +6852,7 @@ package body Exp_Attr is
--------------
when Attribute_TypeCode => TypeCode : declare
- Decls : constant List_Id := New_List;
+ Decls : constant List_Id := New_List;
begin
Rewrite (N, Build_TypeCode_Call (Loc, Ptyp, Decls));
Insert_Actions (N, Decls);
@@ -7671,7 +7780,7 @@ package body Exp_Attr is
-- The following attributes should not appear at this stage, since they
-- have already been handled by the analyzer (and properly rewritten
- -- with corresponding values or entities to represent the right values)
+ -- with corresponding values or entities to represent the right values).
when Attribute_Abort_Signal
| Attribute_Address_Size
@@ -7725,6 +7834,8 @@ package body Exp_Attr is
| Attribute_Scale
| Attribute_Signed_Zeros
| Attribute_Small
+ | Attribute_Small_Denominator
+ | Attribute_Small_Numerator
| Attribute_Storage_Unit
| Attribute_Stub_Type
| Attribute_System_Allocator_Alignment
@@ -7802,17 +7913,17 @@ package body Exp_Attr is
---------------------------
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;
+ 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)
+ if Id in Attribute_Size | Attribute_Value_Size
and then Is_Entity_Name (Pref)
and then Is_Type (Entity (Pref))
and then Known_Static_RM_Size (Entity (Pref))
@@ -7874,8 +7985,7 @@ package body Exp_Attr is
if Is_Entity_Name (Pref)
and then Is_Formal (Entity (Pref))
- and then Is_Array_Type (Ptyp)
- and then Is_Packed (Ptyp)
+ and then Is_Packed_Array (Ptyp)
then
Rewrite (N,
Make_Attribute_Reference (Loc,
@@ -7889,9 +7999,8 @@ package body Exp_Attr is
-- type, but also a hint to the actual constrained type.
elsif Nkind (Pref) = N_Explicit_Dereference
- and then Is_Array_Type (Ptyp)
+ and then Is_Packed_Array (Ptyp)
and then not Is_Constrained (Ptyp)
- and then Is_Packed (Ptyp)
then
Set_Actual_Designated_Subtype (Pref, Get_Actual_Subtype (Pref));
diff --git a/gcc/ada/exp_ch11.adb b/gcc/ada/exp_ch11.adb
index abc91a2..3ab2ea2 100644
--- a/gcc/ada/exp_ch11.adb
+++ b/gcc/ada/exp_ch11.adb
@@ -189,7 +189,6 @@ package body Exp_Ch11 is
Handlrs : constant List_Id := Exception_Handlers (HSS);
Loc : constant Source_Ptr := Sloc (HSS);
Handler : Node_Id;
- Others_Choice : Boolean;
Obj_Decl : Node_Id;
Next_Handler : Node_Id;
@@ -197,12 +196,6 @@ package body Exp_Ch11 is
-- This procedure handles the expansion of exception handlers for the
-- optimization of local raise statements into goto statements.
- procedure Prepend_Call_To_Handler
- (Proc : RE_Id;
- Args : List_Id := No_List);
- -- Routine to prepend a call to the procedure referenced by Proc at
- -- the start of the handler code for the current Handler.
-
procedure Replace_Raise_By_Goto (Raise_S : Node_Id; Goto_L1 : Node_Id);
-- Raise_S is a raise statement (possibly expanded, and possibly of the
-- form of a Raise_xxx_Error node with a condition. This procedure is
@@ -850,36 +843,6 @@ package body Exp_Ch11 is
end;
end Expand_Local_Exception_Handlers;
- -----------------------------
- -- Prepend_Call_To_Handler --
- -----------------------------
-
- procedure Prepend_Call_To_Handler
- (Proc : RE_Id;
- Args : List_Id := No_List)
- is
- Ent : constant Entity_Id := RTE (Proc);
-
- begin
- -- If we have no Entity, then we are probably in no run time mode or
- -- some weird error has occurred. In either case do nothing. Note use
- -- of No_Location to hide this code from the debugger, so single
- -- stepping doesn't jump back and forth.
-
- if Present (Ent) then
- declare
- Call : constant Node_Id :=
- Make_Procedure_Call_Statement (No_Location,
- Name => New_Occurrence_Of (RTE (Proc), No_Location),
- Parameter_Associations => Args);
-
- begin
- Prepend_To (Statements (Handler), Call);
- Analyze (Call, Suppress => All_Checks);
- end;
- end if;
- end Prepend_Call_To_Handler;
-
---------------------------
-- Replace_Raise_By_Goto --
---------------------------
@@ -1089,44 +1052,6 @@ package body Exp_Ch11 is
(Statements (Handler), Suppress => All_Checks);
end;
end if;
-
- -- For the normal case, we have to worry about the state of
- -- abort deferral. Generally, we defer abort during runtime
- -- handling of exceptions. When control is passed to the
- -- handler, then in the normal case we undefer aborts. In
- -- any case this entire handling is relevant only if aborts
- -- are allowed.
-
- if Abort_Allowed
- and then not ZCX_Exceptions
- then
- -- There are some special cases in which we do not do the
- -- undefer. In particular a finalization (AT END) handler
- -- wants to operate with aborts still deferred.
-
- -- We also suppress the call if this is the special handler
- -- for Abort_Signal, since if we are aborting, we want to
- -- keep aborts deferred (one abort is enough).
-
- -- If abort really needs to be deferred the expander must
- -- add this call explicitly, see
- -- Expand_N_Asynchronous_Select.
-
- Others_Choice :=
- Nkind (First (Exception_Choices (Handler))) =
- N_Others_Choice;
-
- if (Others_Choice
- or else Entity (First (Exception_Choices (Handler))) /=
- Stand.Abort_Signal)
- and then not
- (Others_Choice
- and then
- All_Others (First (Exception_Choices (Handler))))
- then
- Prepend_Call_To_Handler (RE_Abort_Undefer);
- end if;
- end if;
end if;
end if;
@@ -1553,7 +1478,7 @@ package body Exp_Ch11 is
begin
-- Processing for locally handled exception (exclude reraise case)
- if Present (Name (N)) and then Nkind (Name (N)) = N_Identifier then
+ if Present (Name (N)) and then Is_Entity_Name (Name (N)) then
if Debug_Flag_Dot_G
or else Restriction_Active (No_Exception_Propagation)
then
@@ -1657,7 +1582,7 @@ package body Exp_Ch11 is
-- but this is also faster in all modes). Propagate Comes_From_Source
-- flag to the new node.
- if Present (Name (N)) and then Nkind (Name (N)) = N_Identifier then
+ if Present (Name (N)) and then Is_Entity_Name (Name (N)) then
Src := Comes_From_Source (N);
if Entity (Name (N)) = Standard_Constraint_Error then
@@ -1689,7 +1614,7 @@ package body Exp_Ch11 is
-- where location_string identifies the file/line of the raise
- if Present (Name (N)) then
+ if Present (Name (N)) and then Is_Entity_Name (Name (N)) then
declare
Id : Entity_Id := Entity (Name (N));
Buf : Bounded_String;
diff --git a/gcc/ada/exp_ch13.adb b/gcc/ada/exp_ch13.adb
index 30f101d..89efca9 100644
--- a/gcc/ada/exp_ch13.adb
+++ b/gcc/ada/exp_ch13.adb
@@ -582,9 +582,8 @@ package body Exp_Ch13 is
Install_Visible_Declarations (E_Scope);
end if;
- if Is_Package_Or_Generic_Package (E_Scope) or else
- Is_Protected_Type (E_Scope) or else
- Is_Task_Type (E_Scope)
+ if Is_Concurrent_Type (E_Scope)
+ or else Is_Package_Or_Generic_Package (E_Scope)
then
Install_Private_Declarations (E_Scope);
end if;
diff --git a/gcc/ada/exp_ch2.adb b/gcc/ada/exp_ch2.adb
index 5c3435b..6c41e08 100644
--- a/gcc/ada/exp_ch2.adb
+++ b/gcc/ada/exp_ch2.adb
@@ -338,8 +338,43 @@ package body Exp_Ch2 is
-----------------------------
procedure Expand_Entity_Reference (N : Node_Id) is
+
+ function Is_Object_Renaming_Name (N : Node_Id) return Boolean;
+ -- Indicates that N occurs (after accounting for qualified expressions
+ -- and type conversions) as the name of an object renaming declaration.
+ -- We don't want to fold values in that case.
+
+ -----------------------------
+ -- Is_Object_Renaming_Name --
+ -----------------------------
+
+ function Is_Object_Renaming_Name (N : Node_Id) return Boolean is
+ Trailer : Node_Id := N;
+ Rover : Node_Id;
+ begin
+ loop
+ Rover := Parent (Trailer);
+ case Nkind (Rover) is
+ when N_Qualified_Expression | N_Type_Conversion =>
+ -- Conservative for type conversions; only necessary if
+ -- conversion does not introduce a new object (as opposed
+ -- to a new view of an existing object).
+ null;
+ when N_Object_Renaming_Declaration =>
+ return Trailer = Name (Rover);
+ when others =>
+ return False; -- the usual case
+ end case;
+ Trailer := Rover;
+ end loop;
+ end Is_Object_Renaming_Name;
+
+ -- Local variables
+
E : constant Entity_Id := Entity (N);
+ -- Start of processing for Expand_Entity_Reference
+
begin
-- Defend against errors
@@ -441,10 +476,17 @@ package body Exp_Ch2 is
end;
end if;
- -- Interpret possible Current_Value for variable case
+ -- Interpret possible Current_Value for variable case. The
+ -- Is_Object_Renaming_Name test is needed for cases such as
+ -- X : Integer := 1;
+ -- Y : Integer renames Integer'(X);
+ -- where the value of Y is changed by any subsequent assignments to X.
+ -- In cases like this, we do not want to use Current_Value even though
+ -- it is available.
if Is_Assignable (E)
and then Present (Current_Value (E))
+ and then not Is_Object_Renaming_Name (N)
then
Expand_Current_Value (N);
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index f8b6ee6..bbb7d53 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -671,24 +671,85 @@ package body Exp_Ch3 is
------------------------
function Init_One_Dimension (N : Int) return List_Id is
- Index : Entity_Id;
+ Index : Entity_Id;
+ DIC_Call : Node_Id;
+ Result_List : List_Id;
+
+ function Possible_DIC_Call return Node_Id;
+ -- If the component type has Default_Initial_Conditions and a DIC
+ -- procedure that is not an empty body, then builds a call to the
+ -- DIC procedure and returns it.
+
+ -----------------------
+ -- Possible_DIC_Call --
+ -----------------------
+
+ function Possible_DIC_Call return Node_Id is
+ begin
+ -- When the component's type has a Default_Initial_Condition, then
+ -- create a call for the DIC check.
+
+ if Has_DIC (Comp_Type)
+ -- In GNATprove mode, the component DICs are checked by other
+ -- means. They should not be added to the record type DIC
+ -- procedure, so that the procedure can be used to check the
+ -- record type invariants or DICs if any.
+
+ and then not GNATprove_Mode
+
+ and then Present (DIC_Procedure (Comp_Type))
+
+ and then not Has_Null_Body (DIC_Procedure (Comp_Type))
+ then
+ return
+ Build_DIC_Call (Loc,
+ Make_Indexed_Component (Loc,
+ Prefix => Make_Identifier (Loc, Name_uInit),
+ Expressions => Index_List),
+ Comp_Type);
+ else
+ return Empty;
+ end if;
+ end Possible_DIC_Call;
+
+ -- Start of processing for Init_One_Dimension
begin
-- If the component does not need initializing, then there is nothing
-- to do here, so we return a null body. This occurs when generating
-- the dummy Init_Proc needed for Initialize_Scalars processing.
+ -- An exception is if component type has a Default_Initial_Condition,
+ -- in which case we generate a call to the type's DIC procedure.
if not Has_Non_Null_Base_Init_Proc (Comp_Type)
and then not Comp_Simple_Init
and then not Has_Task (Comp_Type)
and then not Has_Default_Aspect (A_Type)
+ and then (not Has_DIC (Comp_Type)
+ or else N > Number_Dimensions (A_Type))
then
- return New_List (Make_Null_Statement (Loc));
+ DIC_Call := Possible_DIC_Call;
+
+ if Present (DIC_Call) then
+ return New_List (DIC_Call);
+ else
+ return New_List (Make_Null_Statement (Loc));
+ end if;
-- If all dimensions dealt with, we simply initialize the component
+ -- and append a call to component type's DIC procedure when needed.
elsif N > Number_Dimensions (A_Type) then
- return Init_Component;
+ DIC_Call := Possible_DIC_Call;
+
+ if Present (DIC_Call) then
+ Result_List := Init_Component;
+ Append (DIC_Call, Result_List);
+ return Result_List;
+
+ else
+ return Init_Component;
+ end if;
-- Here we generate the required loop
@@ -753,6 +814,7 @@ package body Exp_Ch3 is
-- 3. Tasks are present
-- 4. The type is marked as a public entity
-- 5. The array type has a Default_Component_Value aspect
+ -- 6. The array component type has a Default_Initialization_Condition
-- The reason for the public entity test is to deal properly with the
-- Initialize_Scalars pragma. This pragma can be set in the client and
@@ -771,7 +833,8 @@ package body Exp_Ch3 is
Has_Default_Init := Has_Non_Null_Base_Init_Proc (Comp_Type)
or else Comp_Simple_Init
or else Has_Task (Comp_Type)
- or else Has_Default_Aspect (A_Type);
+ or else Has_Default_Aspect (A_Type)
+ or else Has_DIC (Comp_Type);
if Has_Default_Init
or else (not Restriction_Active (No_Initialize_Scalars)
@@ -1945,47 +2008,6 @@ package body Exp_Ch3 is
Lhs : Node_Id;
Res : List_Id;
- function Replace_Discr_Ref (N : Node_Id) return Traverse_Result;
- -- Analysis of the aggregate has replaced discriminants by their
- -- corresponding discriminals, but these are irrelevant when the
- -- component has a mutable type and is initialized with an aggregate.
- -- Instead, they must be replaced by the values supplied in the
- -- aggregate, that will be assigned during the expansion of the
- -- assignment.
-
- -----------------------
- -- Replace_Discr_Ref --
- -----------------------
-
- function Replace_Discr_Ref (N : Node_Id) return Traverse_Result is
- Val : Node_Id;
-
- begin
- if Is_Entity_Name (N)
- and then Present (Entity (N))
- and then Is_Formal (Entity (N))
- and then Present (Discriminal_Link (Entity (N)))
- then
- Val :=
- Make_Selected_Component (Default_Loc,
- Prefix => New_Copy_Tree (Lhs),
- Selector_Name =>
- New_Occurrence_Of
- (Discriminal_Link (Entity (N)), Default_Loc));
-
- if Present (Val) then
- Rewrite (N, New_Copy_Tree (Val));
- end if;
- end if;
-
- return OK;
- end Replace_Discr_Ref;
-
- procedure Replace_Discriminant_References is
- new Traverse_Proc (Replace_Discr_Ref);
-
- -- Start of processing for Build_Assignment
-
begin
Lhs :=
Make_Selected_Component (Default_Loc,
@@ -1993,22 +2015,6 @@ package body Exp_Ch3 is
Selector_Name => New_Occurrence_Of (Id, Default_Loc));
Set_Assignment_OK (Lhs);
- if Nkind (Exp) = N_Aggregate
- and then Has_Discriminants (Typ)
- and then not Is_Constrained (Base_Type (Typ))
- then
- -- The aggregate may provide new values for the discriminants
- -- of the component, and other components may depend on those
- -- discriminants. Previous analysis of those expressions have
- -- replaced the discriminants by the formals of the initialization
- -- procedure for the type, but these are irrelevant in the
- -- enclosing initialization procedure: those discriminant
- -- references must be replaced by the values provided in the
- -- aggregate.
-
- Replace_Discriminant_References (Exp);
- end if;
-
-- Case of an access attribute applied to the current instance.
-- Replace the reference to the type by a reference to the actual
-- object. (Note that this handles the case of the top level of
@@ -3438,6 +3444,38 @@ package body Exp_Ch3 is
Actions := No_List;
end if;
+ -- When the component's type has a Default_Initial_Condition,
+ -- and the component is default initialized, then check the
+ -- DIC here.
+
+ if Has_DIC (Typ)
+ and then not Present (Expression (Decl))
+ and then Present (DIC_Procedure (Typ))
+ and then not Has_Null_Body (DIC_Procedure (Typ))
+
+ -- The DICs of ancestors are checked as part of the type's
+ -- DIC procedure.
+
+ and then Chars (Id) /= Name_uParent
+
+ -- In GNATprove mode, the component DICs are checked by other
+ -- means. They should not be added to the record type DIC
+ -- procedure, so that the procedure can be used to check the
+ -- record type invariants or DICs if any.
+
+ and then not GNATprove_Mode
+ then
+ Append_New_To (Actions,
+ Build_DIC_Call
+ (Comp_Loc,
+ Make_Selected_Component (Comp_Loc,
+ Prefix =>
+ Make_Identifier (Comp_Loc, Name_uInit),
+ Selector_Name =>
+ New_Occurrence_Of (Id, Comp_Loc)),
+ Typ));
+ end if;
+
if Present (Checks) then
if Chars (Id) = Name_uParent then
Append_List_To (Parent_Stmts, Checks);
@@ -7403,12 +7441,12 @@ package body Exp_Ch3 is
-- If we cannot convert the expression into a renaming we must
-- consider it an internal error because the backend does not
- -- have support to handle it. Also, when a raise expression is
- -- encountered we ignore it since it doesn't return a value and
- -- thus cannot trigger a copy.
+ -- have support to handle it. But avoid crashing on a raise
+ -- expression or conditional expression.
- elsif Nkind (Original_Node (Expr_Q)) /= N_Raise_Expression then
- pragma Assert (False);
+ elsif Nkind (Original_Node (Expr_Q)) not in
+ N_Raise_Expression | N_If_Expression | N_Case_Expression
+ then
raise Program_Error;
end if;
@@ -7552,12 +7590,14 @@ package body Exp_Ch3 is
if Comes_From_Source (Def_Id)
and then Has_DIC (Typ)
and then Present (DIC_Procedure (Typ))
+ and then not Has_Null_Body (DIC_Procedure (Typ))
and then not Has_Init_Expression (N)
and then not Is_Imported (Def_Id)
then
declare
- DIC_Call : constant Node_Id := Build_DIC_Call (Loc, Def_Id, Typ);
-
+ DIC_Call : constant Node_Id :=
+ Build_DIC_Call
+ (Loc, New_Occurrence_Of (Def_Id, Loc), Typ);
begin
if Present (Next_N) then
Insert_Before_And_Analyze (Next_N, DIC_Call);
@@ -8331,13 +8371,6 @@ package body Exp_Ch3 is
Process_Pending_Access_Types (Def_Id);
Freeze_Stream_Operations (N, Def_Id);
- -- Generate the [spec and] body of the procedure tasked with the runtime
- -- verification of pragma Default_Initial_Condition's expression.
-
- if Has_DIC (Def_Id) then
- Build_DIC_Procedure_Body (Def_Id, For_Freeze => True);
- end if;
-
-- Generate the [spec and] body of the invariant procedure tasked with
-- the runtime verification of all invariants that pertain to the type.
-- This includes invariants on the partial and full view, inherited
@@ -8363,14 +8396,24 @@ package body Exp_Ch3 is
-- subprograms, which may involve local declarations of local
-- subtypes to which these checks do not apply.
- elsif Has_Invariants (Def_Id) then
- if not Predicate_Check_In_Scope (Def_Id)
- or else (Ekind (Current_Scope) = E_Function
- and then Is_Predicate_Function (Current_Scope))
- then
- null;
- else
- Build_Invariant_Procedure_Body (Def_Id);
+ else
+ if Has_Invariants (Def_Id) then
+ if not Predicate_Check_In_Scope (Def_Id)
+ or else (Ekind (Current_Scope) = E_Function
+ and then Is_Predicate_Function (Current_Scope))
+ then
+ null;
+ else
+ Build_Invariant_Procedure_Body (Def_Id);
+ end if;
+ end if;
+
+ -- Generate the [spec and] body of the procedure tasked with the
+ -- run-time verification of pragma Default_Initial_Condition's
+ -- expression.
+
+ if Has_DIC (Def_Id) then
+ Build_DIC_Procedure_Body (Def_Id);
end if;
end if;
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index 076e0de..ecaeeb2 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -1268,9 +1268,8 @@ package body Exp_Ch4 is
-- expression with a constrained subtype in order to compute the
-- proper size for the allocator.
- if Is_Array_Type (T)
+ if Is_Packed_Array (T)
and then not Is_Constrained (T)
- and then Is_Packed (T)
then
declare
ConstrT : constant Entity_Id := Make_Temporary (Loc, 'A');
@@ -2184,21 +2183,54 @@ package body Exp_Ch4 is
then
return;
else
-
Func_Body := Make_Boolean_Array_Op (Etype (L), N);
Func_Name := Defining_Unit_Name (Specification (Func_Body));
Insert_Action (N, Func_Body);
-- Now rewrite the expression with a call
- Rewrite (N,
- Make_Function_Call (Loc,
- Name => New_Occurrence_Of (Func_Name, Loc),
- Parameter_Associations =>
- New_List (
- L,
- Make_Type_Conversion
- (Loc, New_Occurrence_Of (Etype (L), Loc), R))));
+ if Transform_Function_Array then
+ declare
+ Temp_Id : constant Entity_Id := Make_Temporary (Loc, 'T');
+ Call : Node_Id;
+ Decl : Node_Id;
+
+ begin
+ -- Generate:
+ -- Temp : ...;
+
+ Decl :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Temp_Id,
+ Object_Definition =>
+ New_Occurrence_Of (Etype (L), Loc));
+
+ -- Generate:
+ -- Proc_Call (L, R, Temp);
+
+ Call :=
+ Make_Procedure_Call_Statement (Loc,
+ Name => New_Occurrence_Of (Func_Name, Loc),
+ Parameter_Associations =>
+ New_List (
+ L,
+ Make_Type_Conversion
+ (Loc, New_Occurrence_Of (Etype (L), Loc), R),
+ New_Occurrence_Of (Temp_Id, Loc)));
+
+ Insert_Actions (Parent (N), New_List (Decl, Call));
+ Rewrite (N, New_Occurrence_Of (Temp_Id, Loc));
+ end;
+ else
+ Rewrite (N,
+ Make_Function_Call (Loc,
+ Name => New_Occurrence_Of (Func_Name, Loc),
+ Parameter_Associations =>
+ New_List (
+ L,
+ Make_Type_Conversion
+ (Loc, New_Occurrence_Of (Etype (L), Loc), R))));
+ end if;
Analyze_And_Resolve (N, Typ);
end if;
@@ -3506,8 +3538,17 @@ package body Exp_Ch4 is
Alloc :=
Make_Allocator (Loc,
Expression => New_Occurrence_Of (ConstrT, Loc));
+
+ -- Allocate on the secondary stack. This is currently done
+ -- only for type String, which normally doesn't have default
+ -- initialization, but we need to Set_No_Initialization in case
+ -- of Initialize_Scalars or Normalize_Scalars; otherwise, the
+ -- allocator will get transformed and will not use the secondary
+ -- stack.
+
Set_Storage_Pool (Alloc, RTE (RE_SS_Pool));
Set_Procedure_To_Call (Alloc, RTE (RE_SS_Allocate));
+ Set_No_Initialization (Alloc);
Temp := Make_Temporary (Loc, 'R', Alloc);
Insert_Action (Cnode,
@@ -5347,6 +5388,24 @@ package body Exp_Ch4 is
Rewrite (N, New_Occurrence_Of (Temp, Loc));
Analyze_And_Resolve (N, PtrT);
+
+ -- When designated type has Default_Initial_Condition aspects,
+ -- make a call to the type's DIC procedure to perform the
+ -- checks. Theoretically this might also be needed for cases
+ -- where the type doesn't have an init proc, but those should
+ -- be very uncommon, and for now we only support the init proc
+ -- case. ???
+
+ if Has_DIC (Dtyp)
+ and then Present (DIC_Procedure (Dtyp))
+ and then not Has_Null_Body (DIC_Procedure (Dtyp))
+ then
+ Insert_Action (N,
+ Build_DIC_Call (Loc,
+ Make_Explicit_Dereference (Loc,
+ Prefix => New_Occurrence_Of (Temp, Loc)),
+ Dtyp));
+ end if;
end if;
end if;
end;
@@ -9708,16 +9767,6 @@ package body Exp_Ch4 is
end if;
end if;
- -- Try to narrow the operation
-
- if Typ = Universal_Integer then
- Narrow_Large_Operation (N);
-
- if Nkind (N) /= N_Op_Multiply then
- return;
- end if;
- end if;
-
-- Convert x * 2 ** y to Shift_Left (x, y). Note that the fact that
-- Is_Power_Of_2_For_Shift is set means that we know that our left
-- operand is an integer, as required for this to work.
@@ -9794,6 +9843,16 @@ package body Exp_Ch4 is
return;
end if;
+ -- Try to narrow the operation
+
+ if Typ = Universal_Integer then
+ Narrow_Large_Operation (N);
+
+ if Nkind (N) /= N_Op_Multiply then
+ return;
+ end if;
+ end if;
+
-- Do required fixup of universal fixed operation
if Typ = Universal_Fixed then
@@ -9990,12 +10049,21 @@ package body Exp_Ch4 is
-- return B;
-- end Nnnn;
+ -- or in the case of Transform_Function_Array:
+
+ -- procedure Nnnn (A : arr; RESULT : out arr) is
+ -- begin
+ -- for J in a'range loop
+ -- RESULT (J) := not A (J);
+ -- end loop;
+ -- end Nnnn;
+
-- Here arr is the actual subtype of the parameter (and hence always
- -- constrained). Then we replace the not with a call to this function.
+ -- constrained). Then we replace the not with a call to this subprogram.
procedure Expand_N_Op_Not (N : Node_Id) is
Loc : constant Source_Ptr := Sloc (N);
- Typ : constant Entity_Id := Etype (N);
+ Typ : constant Entity_Id := Etype (Right_Opnd (N));
Opnd : Node_Id;
Arr : Entity_Id;
A : Entity_Id;
@@ -10091,7 +10159,13 @@ package body Exp_Ch4 is
end if;
A := Make_Defining_Identifier (Loc, Name_uA);
- B := Make_Defining_Identifier (Loc, Name_uB);
+
+ if Transform_Function_Array then
+ B := Make_Defining_Identifier (Loc, Name_UP_RESULT);
+ else
+ B := Make_Defining_Identifier (Loc, Name_uB);
+ end if;
+
J := Make_Defining_Identifier (Loc, Name_uJ);
A_J :=
@@ -10126,33 +10200,82 @@ package body Exp_Ch4 is
Func_Name := Make_Temporary (Loc, 'N');
Set_Is_Inlined (Func_Name);
- Insert_Action (N,
- Make_Subprogram_Body (Loc,
- Specification =>
- Make_Function_Specification (Loc,
- Defining_Unit_Name => Func_Name,
- Parameter_Specifications => New_List (
- Make_Parameter_Specification (Loc,
- Defining_Identifier => A,
- Parameter_Type => New_Occurrence_Of (Typ, Loc))),
- Result_Definition => New_Occurrence_Of (Typ, Loc)),
+ if Transform_Function_Array then
+ Insert_Action (N,
+ Make_Subprogram_Body (Loc,
+ Specification =>
+ Make_Procedure_Specification (Loc,
+ Defining_Unit_Name => Func_Name,
+ Parameter_Specifications => New_List (
+ Make_Parameter_Specification (Loc,
+ Defining_Identifier => A,
+ Parameter_Type => New_Occurrence_Of (Typ, Loc)),
+ Make_Parameter_Specification (Loc,
+ Defining_Identifier => B,
+ Out_Present => True,
+ Parameter_Type => New_Occurrence_Of (Typ, Loc)))),
+
+ Declarations => New_List,
+
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => New_List (Loop_Statement))));
- Declarations => New_List (
- Make_Object_Declaration (Loc,
- Defining_Identifier => B,
- Object_Definition => New_Occurrence_Of (Arr, Loc))),
+ declare
+ Temp_Id : constant Entity_Id := Make_Temporary (Loc, 'T');
+ Call : Node_Id;
+ Decl : Node_Id;
- Handled_Statement_Sequence =>
- Make_Handled_Sequence_Of_Statements (Loc,
- Statements => New_List (
- Loop_Statement,
- Make_Simple_Return_Statement (Loc,
- Expression => Make_Identifier (Loc, Chars (B)))))));
+ begin
+ -- Generate:
+ -- Temp : ...;
- Rewrite (N,
- Make_Function_Call (Loc,
- Name => New_Occurrence_Of (Func_Name, Loc),
- Parameter_Associations => New_List (Opnd)));
+ Decl :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Temp_Id,
+ Object_Definition => New_Occurrence_Of (Typ, Loc));
+
+ -- Generate:
+ -- Proc_Call (Opnd, Temp);
+
+ Call :=
+ Make_Procedure_Call_Statement (Loc,
+ Name => New_Occurrence_Of (Func_Name, Loc),
+ Parameter_Associations =>
+ New_List (Opnd, New_Occurrence_Of (Temp_Id, Loc)));
+
+ Insert_Actions (Parent (N), New_List (Decl, Call));
+ Rewrite (N, New_Occurrence_Of (Temp_Id, Loc));
+ end;
+ else
+ Insert_Action (N,
+ Make_Subprogram_Body (Loc,
+ Specification =>
+ Make_Function_Specification (Loc,
+ Defining_Unit_Name => Func_Name,
+ Parameter_Specifications => New_List (
+ Make_Parameter_Specification (Loc,
+ Defining_Identifier => A,
+ Parameter_Type => New_Occurrence_Of (Typ, Loc))),
+ Result_Definition => New_Occurrence_Of (Typ, Loc)),
+
+ Declarations => New_List (
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => B,
+ Object_Definition => New_Occurrence_Of (Arr, Loc))),
+
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => New_List (
+ Loop_Statement,
+ Make_Simple_Return_Statement (Loc,
+ Expression => Make_Identifier (Loc, Chars (B)))))));
+
+ Rewrite (N,
+ Make_Function_Call (Loc,
+ Name => New_Occurrence_Of (Func_Name, Loc),
+ Parameter_Associations => New_List (Opnd)));
+ end if;
Analyze_And_Resolve (N, Typ);
end Expand_N_Op_Not;
@@ -11457,11 +11580,6 @@ package body Exp_Ch4 is
-- Start of processing for Discrete_Range_Check
begin
- -- Clear the Do_Range_Check flag on N if needed: this can occur when
- -- e.g. a trivial type conversion is rewritten by its expression.
-
- Set_Do_Range_Check (N, False);
-
-- Nothing more to do if conversion was rewritten
if Nkind (N) /= N_Type_Conversion then
@@ -11470,12 +11588,6 @@ package body Exp_Ch4 is
Expr := Expression (N);
- -- Nothing to do if no range check flag set
-
- if not Do_Range_Check (Expr) then
- return;
- end if;
-
-- Clear the Do_Range_Check flag on Expr
Set_Do_Range_Check (Expr, False);
@@ -11748,11 +11860,6 @@ package body Exp_Ch4 is
Tnn : Entity_Id;
begin
- -- Clear the Do_Range_Check flag on N if needed: this can occur when
- -- e.g. a trivial type conversion is rewritten by its expression.
-
- Set_Do_Range_Check (N, False);
-
-- Nothing more to do if conversion was rewritten
if Nkind (N) /= N_Type_Conversion then
@@ -11871,33 +11978,20 @@ package body Exp_Ch4 is
-- which used to fail when Fix_Val was a bound of the type and
-- the 'Small was not a representable number.
-- This transformation requires an integer type large enough to
- -- accommodate a fixed-point value. This will not be the case
- -- in systems where Duration is larger than Long_Integer.
+ -- accommodate a fixed-point value.
if Is_Ordinary_Fixed_Point_Type (Target_Type)
and then Is_Floating_Point_Type (Etype (Expr))
- and then RM_Size (Btyp) <= RM_Size (Standard_Long_Integer)
+ and then RM_Size (Btyp) <= System_Max_Integer_Size
and then Nkind (Lo) = N_Real_Literal
and then Nkind (Hi) = N_Real_Literal
then
declare
Expr_Id : constant Entity_Id := Make_Temporary (Loc, 'T', Conv);
- Int_Type : Entity_Id;
+ Int_Typ : constant Entity_Id :=
+ Small_Integer_Type_For (RM_Size (Btyp), False);
begin
- -- 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 (Btyp) > RM_Size (Standard_Short_Integer) then
- Int_Type := Standard_Integer;
-
- else
- Int_Type := Standard_Short_Integer;
- end if;
-
-- Generate a temporary with the integer value. Required in the
-- CCG compiler to ensure that run-time checks reference this
-- integer expression (instead of the resulting fixed-point
@@ -11907,23 +12001,23 @@ package body Exp_Ch4 is
Insert_Action (N,
Make_Object_Declaration (Loc,
Defining_Identifier => Expr_Id,
- Object_Definition => New_Occurrence_Of (Int_Type, Loc),
+ Object_Definition => New_Occurrence_Of (Int_Typ, Loc),
Constant_Present => True,
Expression =>
- Convert_To (Int_Type, Expression (Conv))));
+ Convert_To (Int_Typ, Expression (Conv))));
-- Create integer objects for range checking of result.
Lo_Arg :=
Unchecked_Convert_To
- (Int_Type, New_Occurrence_Of (Expr_Id, Loc));
+ (Int_Typ, New_Occurrence_Of (Expr_Id, Loc));
Lo_Val :=
Make_Integer_Literal (Loc, Corresponding_Integer_Value (Lo));
Hi_Arg :=
Unchecked_Convert_To
- (Int_Type, New_Occurrence_Of (Expr_Id, Loc));
+ (Int_Typ, New_Occurrence_Of (Expr_Id, Loc));
Hi_Val :=
Make_Integer_Literal (Loc, Corresponding_Integer_Value (Hi));
@@ -12037,20 +12131,16 @@ package body Exp_Ch4 is
-- Nothing at all to do if conversion is to the identical type so remove
-- the conversion completely, it is useless, except that it may carry
-- an Assignment_OK attribute, which must be propagated to the operand
- -- and the Do_Range_Check flag on Operand should be taken into account.
+ -- and the Do_Range_Check flag on the operand must be cleared, if any.
if Operand_Type = Target_Type then
if Assignment_OK (N) then
Set_Assignment_OK (Operand);
end if;
- Rewrite (N, Relocate_Node (Operand));
-
- if Do_Range_Check (Operand) then
- pragma Assert (Is_Discrete_Type (Operand_Type));
+ Set_Do_Range_Check (Operand, False);
- Discrete_Range_Check;
- end if;
+ Rewrite (N, Relocate_Node (Operand));
goto Done;
end if;
@@ -12259,7 +12349,7 @@ package body Exp_Ch4 is
else
Apply_Accessibility_Check
- (Operand_Acc, Target_Type, Insert_Node => Operand);
+ (Operand, Target_Type, Insert_Node => Operand);
end if;
-- If the level of the operand type is statically deeper than the
@@ -12473,16 +12563,11 @@ package body Exp_Ch4 is
if Is_Fixed_Point_Type (Target_Type) then
Expand_Convert_Fixed_To_Fixed (N);
- Real_Range_Check;
-
elsif Is_Integer_Type (Target_Type) then
Expand_Convert_Fixed_To_Integer (N);
- Discrete_Range_Check;
-
else
pragma Assert (Is_Floating_Point_Type (Target_Type));
Expand_Convert_Fixed_To_Float (N);
- Real_Range_Check;
end if;
-- Case of conversions to a fixed-point type
@@ -12497,11 +12582,9 @@ package body Exp_Ch4 is
then
if Is_Integer_Type (Operand_Type) then
Expand_Convert_Integer_To_Fixed (N);
- Real_Range_Check;
else
pragma Assert (Is_Floating_Point_Type (Operand_Type));
Expand_Convert_Float_To_Fixed (N);
- Real_Range_Check;
end if;
-- Case of array conversions
@@ -12661,8 +12744,6 @@ package body Exp_Ch4 is
-- Here at end of processing
<<Done>>
- pragma Assert (not Do_Range_Check (N));
-
-- Apply predicate check if required. Note that we can't just call
-- Apply_Predicate_Check here, because the type looks right after
-- the conversion and it would omit the check. The Comes_From_Source
@@ -13932,6 +14013,15 @@ package body Exp_Ch4 is
-- return C;
-- end Annn;
+ -- or in the case of Transform_Function_Array:
+
+ -- procedure Annn (A : typ; B: typ; RESULT: out typ) is
+ -- begin
+ -- for J in A'range loop
+ -- RESULT (J) := A (J) op B (J);
+ -- end loop;
+ -- end Annn;
+
-- Here typ is the boolean array type
function Make_Boolean_Array_Op
@@ -13942,9 +14032,10 @@ package body Exp_Ch4 is
A : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA);
B : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);
- C : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uC);
J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);
+ C : Entity_Id;
+
A_J : Node_Id;
B_J : Node_Id;
C_J : Node_Id;
@@ -13956,6 +14047,12 @@ package body Exp_Ch4 is
Loop_Statement : Node_Id;
begin
+ if Transform_Function_Array then
+ C := Make_Defining_Identifier (Loc, Name_UP_RESULT);
+ else
+ C := Make_Defining_Identifier (Loc, Name_uC);
+ end if;
+
A_J :=
Make_Indexed_Component (Loc,
Prefix => New_Occurrence_Of (A, Loc),
@@ -14018,28 +14115,52 @@ package body Exp_Ch4 is
Defining_Identifier => B,
Parameter_Type => New_Occurrence_Of (Typ, Loc)));
+ if Transform_Function_Array then
+ Append_To (Formals,
+ Make_Parameter_Specification (Loc,
+ Defining_Identifier => C,
+ Out_Present => True,
+ Parameter_Type => New_Occurrence_Of (Typ, Loc)));
+ end if;
+
Func_Name := Make_Temporary (Loc, 'A');
Set_Is_Inlined (Func_Name);
- Func_Body :=
- Make_Subprogram_Body (Loc,
- Specification =>
- Make_Function_Specification (Loc,
- Defining_Unit_Name => Func_Name,
- Parameter_Specifications => Formals,
- Result_Definition => New_Occurrence_Of (Typ, Loc)),
+ if Transform_Function_Array then
+ Func_Body :=
+ Make_Subprogram_Body (Loc,
+ Specification =>
+ Make_Procedure_Specification (Loc,
+ Defining_Unit_Name => Func_Name,
+ Parameter_Specifications => Formals),
- Declarations => New_List (
- Make_Object_Declaration (Loc,
- Defining_Identifier => C,
- Object_Definition => New_Occurrence_Of (Typ, Loc))),
+ Declarations => New_List,
- Handled_Statement_Sequence =>
- Make_Handled_Sequence_Of_Statements (Loc,
- Statements => New_List (
- Loop_Statement,
- Make_Simple_Return_Statement (Loc,
- Expression => New_Occurrence_Of (C, Loc)))));
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => New_List (Loop_Statement)));
+
+ else
+ Func_Body :=
+ Make_Subprogram_Body (Loc,
+ Specification =>
+ Make_Function_Specification (Loc,
+ Defining_Unit_Name => Func_Name,
+ Parameter_Specifications => Formals,
+ Result_Definition => New_Occurrence_Of (Typ, Loc)),
+
+ Declarations => New_List (
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => C,
+ Object_Definition => New_Occurrence_Of (Typ, Loc))),
+
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => New_List (
+ Loop_Statement,
+ Make_Simple_Return_Statement (Loc,
+ Expression => New_Occurrence_Of (C, Loc)))));
+ end if;
return Func_Body;
end Make_Boolean_Array_Op;
@@ -14996,6 +15117,14 @@ package body Exp_Ch4 is
return;
end if;
+ -- If both operands are static, then the comparison has been already
+ -- folded in evaluation.
+
+ pragma Assert
+ (not Is_Static_Expression (Left_Opnd (N))
+ or else
+ not Is_Static_Expression (Right_Opnd (N)));
+
-- Determine the potential outcome of the comparison assuming that the
-- operands are valid and emit a warning when the comparison evaluates
-- to True or False only in the presence of invalid values.
@@ -15011,7 +15140,8 @@ package body Exp_Ch4 is
True_Result => True_Result,
False_Result => False_Result);
- -- The outcome is a decisive False or True, rewrite the operator
+ -- The outcome is a decisive False or True, rewrite the operator into a
+ -- non-static literal.
if False_Result or True_Result then
Rewrite (N,
@@ -15019,6 +15149,7 @@ package body Exp_Ch4 is
New_Occurrence_Of (Boolean_Literals (True_Result), Sloc (N))));
Analyze_And_Resolve (N, Typ);
+ Set_Is_Static_Expression (N, False);
Warn_On_Known_Condition (N);
end if;
end Rewrite_Comparison;
diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
index 93351cf..307acaa 100644
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -1469,7 +1469,7 @@ package body Exp_Ch5 is
-- there are volatile or independent components. If the Prefix of the
-- slice is a component or slice, then it might be a part of an object
-- with some other volatile or independent components, so we disable the
- -- optimization in that case as well. We could complicate this code by
+ -- optimization in that case as well. We could complicate this code by
-- actually looking for such volatile and independent components.
if Is_Bit_Packed_Array (L_Type)
@@ -4346,10 +4346,21 @@ package body Exp_Ch5 is
Iter_Pack := Scope (Root_Type (Etype (Iter_Type)));
-- Find declarations needed for "for ... of" optimization
+ -- These declarations come from GNAT sources or sources
+ -- derived from them. User code may include additional
+ -- overloadings with similar names, and we need to perforn
+ -- some reasonable resolution to find the needed primitives.
+ -- It is unclear whether this mechanism is fragile if a user
+ -- makes arbitrary changes to the private part of a package
+ -- that supports iterators.
Ent := First_Entity (Pack);
while Present (Ent) loop
- if Chars (Ent) = Name_Get_Element_Access then
+ if Chars (Ent) = Name_Get_Element_Access
+ and then Present (First_Formal (Ent))
+ and then Chars (First_Formal (Ent)) = Name_Position
+ and then No (Next_Formal (First_Formal (Ent)))
+ then
Fast_Element_Access_Op := Ent;
elsif Chars (Ent) = Name_Step
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 4f13576..98a1ceb 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -2879,17 +2879,10 @@ package body Exp_Ch6 is
(Formal : Entity_Id)
is
Decl : Node_Id;
-
- -- Suppress warning for the final removal loop
- pragma Warnings (Off, Decl);
-
Lvl : Entity_Id;
- Res : Entity_Id;
- Temp : Node_Id;
- Typ : Node_Id;
procedure Insert_Level_Assign (Branch : Node_Id);
- -- Recursivly add assignment of the level temporary on each branch
+ -- Recursively add assignment of the level temporary on each branch
-- while moving through nested conditional expressions.
-------------------------
@@ -2917,12 +2910,10 @@ package body Exp_Ch6 is
-- There are more nested conditional expressions so we must go
-- deeper.
- if Nkind (Expression (Res_Assn)) =
- N_Expression_With_Actions
+ if Nkind (Expression (Res_Assn)) = N_Expression_With_Actions
and then
- Nkind
- (Original_Node (Expression (Res_Assn)))
- in N_Case_Expression | N_If_Expression
+ Nkind (Original_Node (Expression (Res_Assn)))
+ in N_Case_Expression | N_If_Expression
then
Insert_Level_Assign
(Expression (Res_Assn));
@@ -2932,9 +2923,7 @@ package body Exp_Ch6 is
else
Insert_Before_And_Analyze (Res_Assn,
Make_Assignment_Statement (Loc,
- Name =>
- New_Occurrence_Of
- (Lvl, Loc),
+ Name => New_Occurrence_Of (Lvl, Loc),
Expression =>
Accessibility_Level
(Expression (Res_Assn), Dynamic_Level)));
@@ -2956,9 +2945,7 @@ package body Exp_Ch6 is
Cond := First (Actions (Branch));
while Present (Cond) loop
- exit when Nkind (Cond) in
- N_Case_Statement | N_If_Statement;
-
+ exit when Nkind (Cond) in N_Case_Statement | N_If_Statement;
Next (Cond);
end loop;
@@ -2981,7 +2968,6 @@ package body Exp_Ch6 is
Alt := First (Alternatives (Cond));
while Present (Alt) loop
Expand_Branch (Last (Statements (Alt)));
-
Next (Alt);
end loop;
end if;
@@ -3000,7 +2986,7 @@ package body Exp_Ch6 is
New_Occurrence_Of (Standard_Natural, Loc));
-- Install the declaration and perform necessary expansion if we
- -- are dealing with a function call.
+ -- are dealing with a procedure call.
if Nkind (Call_Node) = N_Procedure_Call_Statement then
-- Generate:
@@ -3019,57 +3005,27 @@ package body Exp_Ch6 is
Insert_Before_And_Analyze (Call_Node, Decl);
- -- A function call must be transformed into an expression with
- -- actions.
+ -- Ditto for a function call. Note that we do not wrap the function
+ -- call into an expression with action to avoid bad interactions with
+ -- Exp_Ch4.Process_Transient_In_Expression.
else
-- Generate:
- -- do
- -- Lvl : Natural;
- -- in Call (do{
- -- If_Exp_Res : Typ
- -- if Cond then
- -- Lvl := 0; -- Access level
- -- If_Exp_Res := Exp;
- -- in If_Exp_Res end;},
- -- Lvl,
- -- ...
- -- )
- -- end;
-
- Res := Make_Temporary (Loc, 'R');
- Typ := Etype (Call_Node);
- Temp := Relocate_Node (Call_Node);
-
- -- Perform the rewrite with the dummy
-
- Rewrite (Call_Node,
-
- Make_Expression_With_Actions (Loc,
- Expression => New_Occurrence_Of (Res, Loc),
- Actions => New_List (
- Decl,
-
- Make_Object_Declaration (Loc,
- Defining_Identifier => Res,
- Object_Definition =>
- New_Occurrence_Of (Typ, Loc)))));
-
- -- Analyze the expression with the dummy
-
- Analyze_And_Resolve (Call_Node, Typ);
-
- -- Properly set the expression and move our view of the call node
-
- Set_Expression (Call_Node, Relocate_Node (Temp));
- Call_Node := Expression (Call_Node);
-
- -- Remove the declaration of the dummy and the subsequent actions
- -- its analysis has created.
+ -- Lvl : Natural; -- placed above the function call
+ -- ...
+ -- Func_Call (
+ -- {do
+ -- If_Exp_Res : Typ
+ -- if Cond then
+ -- Lvl := 0; -- Access level
+ -- If_Exp_Res := Exp;
+ -- in If_Exp_Res end;},
+ -- Lvl,
+ -- ...
+ -- )
- while Present (Remove_Next (Decl)) loop
- null;
- end loop;
+ Insert_Action (Call_Node, Decl);
+ Analyze (Call_Node);
end if;
-- Decorate the conditional expression with assignments to our level
@@ -3681,9 +3637,9 @@ package body Exp_Ch6 is
-- For internally generated calls ensure that they reference
-- the entity of the spec of the called function (needed since
-- the expander may generate calls using the entity of their
- -- body). See for example Expand_Boolean_Operator().
+ -- body).
- if not (Comes_From_Source (Call_Node))
+ if not Comes_From_Source (Call_Node)
and then Nkind (Unit_Declaration_Node (Func_Id)) =
N_Subprogram_Body
then
@@ -3700,7 +3656,8 @@ package body Exp_Ch6 is
-- are passed by pointer in the generated C code, and we cannot
-- take a pointer from a subprogram call.
- elsif Nkind (Parent (Call_Node)) in N_Subprogram_Call
+ elsif Modify_Tree_For_C
+ and then Nkind (Parent (Call_Node)) in N_Subprogram_Call
and then Is_Record_Type (Etype (Func_Id))
then
declare
@@ -5427,13 +5384,15 @@ package body Exp_Ch6 is
end if;
-- Build a simple_return_statement that returns the return object when
- -- there is a statement sequence, or no expression, or the result will
- -- be built in place. Note however that we currently do this for all
- -- composite cases, even though not all are built in place.
+ -- there is a statement sequence, or no expression, or the analysis of
+ -- the return object declaration generated extra actions, or the result
+ -- will be built in place. Note however that we currently do this for
+ -- all composite cases, even though they are not built in place.
if Present (HSS)
- or else Is_Composite_Type (Ret_Typ)
or else No (Exp)
+ or else List_Length (Return_Object_Declarations (N)) > 1
+ or else Is_Composite_Type (Ret_Typ)
then
if No (HSS) then
Stmts := New_List;
@@ -5543,7 +5502,7 @@ package body Exp_Ch6 is
(Expression (Original_Node (Ret_Obj_Decl)))
-- It is a BIP object declaration that displaces the pointer
- -- to the object to reference a convered interface type.
+ -- to the object to reference a converted interface type.
or else
Present (Unqual_BIP_Iface_Function_Call
@@ -6101,16 +6060,11 @@ package body Exp_Ch6 is
end;
end if;
- -- Case where we do not build a block
-
- else
- -- We're about to drop Return_Object_Declarations on the floor, so
- -- we need to insert it, in case it got expanded into useful code.
- -- Remove side effects from expression, which may be duplicated in
- -- subsequent checks (see Expand_Simple_Function_Return).
+ -- Case where we do not need to build a block. But we're about to drop
+ -- Return_Object_Declarations on the floor, so assert that it contains
+ -- only the return object declaration.
- Insert_List_Before (N, Return_Object_Declarations (N));
- Remove_Side_Effects (Exp);
+ else pragma Assert (List_Length (Return_Object_Declarations (N)) = 1);
-- Build simple_return_statement that returns the expression directly
diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index b58a3c1..55f714c 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -1273,6 +1273,10 @@ package body Exp_Ch7 is
Object_Definition =>
New_Occurrence_Of (RTE (RE_Finalization_Master), Loc)));
+ if Debug_Generated_Code then
+ Set_Debug_Info_Needed (Fin_Mas_Id);
+ end if;
+
-- Set the associated pool and primitive Finalize_Address of the new
-- finalization master.
@@ -1616,6 +1620,10 @@ package body Exp_Ch7 is
Set_Etype (Counter_Id, Counter_Typ);
+ if Debug_Generated_Code then
+ Set_Debug_Info_Needed (Counter_Id);
+ end if;
+
-- The counter and its type are inserted before the source
-- declarations of N.
@@ -1778,7 +1786,11 @@ package body Exp_Ch7 is
-- exactly twice (once on the normal path, and once for
-- exceptions/abort), so this won't bloat the code too much.
- Set_Is_Inlined (Fin_Id);
+ Set_Is_Inlined (Fin_Id);
+ end if;
+
+ if Debug_Generated_Code then
+ Set_Debug_Info_Needed (Fin_Id);
end if;
-- Step 2: Creation of the finalizer specification
@@ -1969,6 +1981,10 @@ package body Exp_Ch7 is
Body_Id := Make_Defining_Identifier (Loc, Chars (Fin_Id));
+ if Debug_Generated_Code then
+ Set_Debug_Info_Needed (Body_Id);
+ end if;
+
if For_Package then
Set_Has_Qualified_Name (Body_Id);
Set_Has_Fully_Qualified_Name (Body_Id);
@@ -2400,8 +2416,7 @@ package body Exp_Ch7 is
if Is_Ignored_Ghost_Entity (Typ) then
null;
- elsif (Is_Access_Type (Typ)
- and then not Is_Access_Subprogram_Type (Typ)
+ elsif (Is_Access_Object_Type (Typ)
and then Needs_Finalization
(Available_View (Designated_Type (Typ))))
or else (Is_Type (Typ) and then Needs_Finalization (Typ))
@@ -2648,6 +2663,10 @@ package body Exp_Ch7 is
Set_Finalization_Master (Ptr_Typ, Fin_Mas_Id);
Set_Associated_Storage_Pool (Ptr_Typ, Pool_Id);
+ if Debug_Generated_Code then
+ Set_Debug_Info_Needed (Pool_Id);
+ end if;
+
-- Create an explicit free statement. Note that the free uses the
-- caller's pool expressed as a renaming.
@@ -3741,6 +3760,10 @@ package body Exp_Ch7 is
Defining_Identifier => Data.Raised_Id,
Object_Definition => New_Occurrence_Of (Standard_Boolean, Loc),
Expression => New_Occurrence_Of (Standard_False, Loc)));
+
+ if Debug_Generated_Code then
+ Set_Debug_Info_Needed (Data.Raised_Id);
+ end if;
end Build_Object_Declarations;
---------------------------
@@ -6906,6 +6929,10 @@ package body Exp_Ch7 is
Make_Handled_Sequence_Of_Statements (Loc,
Statements => New_List (Init_Loop)));
+ if Debug_Generated_Code then
+ Set_Debug_Info_Needed (Counter_Id);
+ end if;
+
-- Otherwise previous errors or a missing full view may prevent the
-- proper freezing of the component type. If this is the case, there
-- is no [Deep_]Initialize primitive to call.
@@ -9681,6 +9708,10 @@ package body Exp_Ch7 is
Expression => Expr),
Par => Parent (N))));
+ if Debug_Generated_Code then
+ Set_Debug_Info_Needed (Temp);
+ end if;
+
Rewrite (N, New_Occurrence_Of (Temp, Loc));
Analyze_And_Resolve (N, Typ);
end Wrap_Transient_Expression;
diff --git a/gcc/ada/exp_ch8.adb b/gcc/ada/exp_ch8.adb
index 9f4c65c..facd12e 100644
--- a/gcc/ada/exp_ch8.adb
+++ b/gcc/ada/exp_ch8.adb
@@ -101,10 +101,6 @@ package body Exp_Ch8 is
-- More comments needed for this para ???
procedure Expand_N_Object_Renaming_Declaration (N : Node_Id) is
- Nam : constant Node_Id := Name (N);
- Decl : Node_Id;
- T : Entity_Id;
-
function Evaluation_Required (Nam : Node_Id) return Boolean;
-- Determines whether it is necessary to do static name evaluation for
-- renaming of Nam. It is considered necessary if evaluating the name
@@ -165,6 +161,12 @@ package body Exp_Ch8 is
end if;
end Evaluation_Required;
+ -- Local variables
+
+ Decl : Node_Id;
+ Nam : constant Node_Id := Name (N);
+ T : constant Entity_Id := Etype (Defining_Identifier (N));
+
-- Start of processing for Expand_N_Object_Renaming_Declaration
begin
@@ -177,8 +179,6 @@ package body Exp_Ch8 is
-- Deal with construction of subtype in class-wide case
- T := Etype (Defining_Identifier (N));
-
if Is_Class_Wide_Type (T) then
Expand_Subtype_From_Expr (N, T, Subtype_Mark (N), Name (N));
Find_Type (Subtype_Mark (N));
diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb
index 7207723..525eee9 100644
--- a/gcc/ada/exp_ch9.adb
+++ b/gcc/ada/exp_ch9.adb
@@ -7061,7 +7061,6 @@ package body Exp_Ch9 is
Enqueue_Call : Node_Id;
Formals : List_Id;
Hdle : List_Id;
- Handler_Stmt : Node_Id;
Index : Node_Id;
Lim_Typ_Stmts : List_Id;
N_Orig : Node_Id;
@@ -7737,16 +7736,6 @@ package body Exp_Ch9 is
Has_Created_Identifier => True,
Is_Asynchronous_Call_Block => True);
- -- Aborts are not deferred at beginning of exception handlers in
- -- ZCX mode.
-
- if ZCX_Exceptions then
- Handler_Stmt := Make_Null_Statement (Loc);
-
- else
- Handler_Stmt := Build_Runtime_Call (Loc, RE_Abort_Undefer);
- end if;
-
Stmts := New_List (
Make_Block_Statement (Loc,
Handled_Statement_Sequence =>
@@ -7763,11 +7752,11 @@ package body Exp_Ch9 is
Make_Implicit_Exception_Handler (Loc,
-- when Abort_Signal =>
- -- Abort_Undefer.all;
+ -- null;
Exception_Choices =>
New_List (New_Occurrence_Of (Stand.Abort_Signal, Loc)),
- Statements => New_List (Handler_Stmt))))),
+ Statements => New_List (Make_Null_Statement (Loc)))))),
-- if not Cancelled (Bnn) then
-- triggered statements
@@ -10579,13 +10568,12 @@ package body Exp_Ch9 is
Extract_Entry (N, Concval, Ename, Index);
Conc_Typ := Etype (Concval);
- -- Examine the scope stack in order to find nearest enclosing protected
- -- or task type. This will constitute our invocation source.
+ -- Examine the scope stack in order to find nearest enclosing concurrent
+ -- type. This will constitute our invocation source.
Old_Typ := Current_Scope;
while Present (Old_Typ)
- and then not Is_Protected_Type (Old_Typ)
- and then not Is_Task_Type (Old_Typ)
+ and then not Is_Concurrent_Type (Old_Typ)
loop
Old_Typ := Scope (Old_Typ);
end loop;
diff --git a/gcc/ada/exp_dbug.adb b/gcc/ada/exp_dbug.adb
index c2e7741..dc6cd26 100644
--- a/gcc/ada/exp_dbug.adb
+++ b/gcc/ada/exp_dbug.adb
@@ -133,11 +133,6 @@ package body Exp_Dbug is
-- Determine whether the bounds of E match the size of the type. This is
-- used to determine whether encoding is required for a discrete type.
- function Is_Handled_Scale_Factor (U : Ureal) return Boolean;
- -- The argument U is the Small_Value of a fixed-point type. This function
- -- determines whether the back-end can handle this scale factor. When it
- -- cannot, we have to output a GNAT encoding for the corresponding type.
-
procedure Output_Homonym_Numbers_Suffix;
-- If homonym numbers are stored, then output them into Name_Buffer
@@ -594,27 +589,6 @@ package body Exp_Dbug is
return Make_Null_Statement (Loc);
end Debug_Renaming_Declaration;
- -----------------------------
- -- Is_Handled_Scale_Factor --
- -----------------------------
-
- function Is_Handled_Scale_Factor (U : Ureal) return Boolean is
- begin
- -- Keep in sync with gigi (see E_*_Fixed_Point_Type handling in
- -- decl.c:gnat_to_gnu_entity).
-
- if UI_Eq (Numerator (U), Uint_1) then
- if Rbase (U) = 2 or else Rbase (U) = 10 then
- return True;
- end if;
- end if;
-
- return
- (UI_Is_In_Int_Range (Norm_Num (U))
- and then
- UI_Is_In_Int_Range (Norm_Den (U)));
- end Is_Handled_Scale_Factor;
-
----------------------
-- Get_Encoded_Name --
----------------------
@@ -671,12 +645,10 @@ package body Exp_Dbug is
Has_Suffix := True;
- -- Fixed-point case: generate GNAT encodings when asked to or when we
- -- know the back-end will not be able to handle the scale factor.
+ -- Fixed-point case: generate GNAT encodings when asked to
if Is_Fixed_Point_Type (E)
- and then (GNAT_Encodings /= DWARF_GNAT_Encodings_Minimal
- or else not Is_Handled_Scale_Factor (Small_Value (E)))
+ and then GNAT_Encodings /= DWARF_GNAT_Encodings_Minimal
then
Get_External_Name (E, True, "XF_");
Add_Real_To_Buffer (Delta_Value (E));
diff --git a/gcc/ada/exp_dist.adb b/gcc/ada/exp_dist.adb
index 760a412..2d3f75d 100644
--- a/gcc/ada/exp_dist.adb
+++ b/gcc/ada/exp_dist.adb
@@ -902,7 +902,7 @@ package body Exp_Dist is
-- Local variables and structures --
------------------------------------
- RCI_Cache : Node_Id;
+ RCI_Cache : Node_Id := Empty;
-- Needs comments ???
Output_From_Constrained : constant array (Boolean) of Name_Id :=
diff --git a/gcc/ada/exp_fixd.adb b/gcc/ada/exp_fixd.adb
index 42cf626..3bb7207 100644
--- a/gcc/ada/exp_fixd.adb
+++ b/gcc/ada/exp_fixd.adb
@@ -40,6 +40,7 @@ with Sinfo; use Sinfo;
with Snames; use Snames;
with Stand; use Stand;
with Tbuild; use Tbuild;
+with Ttypes; use Ttypes;
with Uintp; use Uintp;
with Urealp; use Urealp;
@@ -68,7 +69,7 @@ package body Exp_Fixd is
-- Build an expression that converts the expression Expr to type Typ,
-- taking the source location from Sloc (N). If the conversions involve
-- fixed-point types, then the Conversion_OK flag will be set so that the
- -- resulting conversions do not get re-expanded. On return the resulting
+ -- resulting conversions do not get re-expanded. On return, the resulting
-- node has its Etype set. If Rchk is set, then Do_Range_Check is set
-- in the resulting conversion node. If Trunc is set, then the
-- Float_Truncate flag is set on the conversion, which must be from
@@ -85,7 +86,7 @@ package body Exp_Fixd is
-- two operand types), and both operands are converted to this type. The
-- Etype of the result is also set to this value. The Rounded_Result flag
-- of the result in this case is set from the Rounded_Result flag of node
- -- N. On return, the resulting node is analyzed and has its Etype set.
+ -- N. On return, the resulting node has its Etype set.
function Build_Double_Divide
(N : Node_Id;
@@ -93,7 +94,7 @@ package body Exp_Fixd is
-- Returns a node corresponding to the value X/(Y*Z) using the source
-- location from Sloc (N). The division is rounded if the Rounded_Result
-- flag of N is set. The integer types of X, Y, Z may be different. On
- -- return the resulting node is analyzed, and has its Etype set.
+ -- return, the resulting node has its Etype set.
procedure Build_Double_Divide_Code
(N : Node_Id;
@@ -114,11 +115,9 @@ package body Exp_Fixd is
-- Make_Op_Multiply only in that the Etype of the resulting node is set (to
-- Universal_Real), or they can be integer or fixed-point types. In this
-- case the types need not be the same, and Build_Multiply chooses a type
- -- long enough to hold the product (i.e. twice the size of the longer of
- -- the two operand types), and both operands are converted to this type.
- -- The Etype of the result is also set to this value. However, the result
- -- can never overflow Integer_64, so this is the largest type that is ever
- -- generated. On return, the resulting node is analyzed and has Etype set.
+ -- long enough to hold the product and both operands are converted to this
+ -- type. The type of the result is also set to this value. On return, the
+ -- resulting node has its Etype set.
function Build_Rem (N : Node_Id; L, R : Node_Id) return Node_Id;
-- Builds an N_Op_Rem node from the given left and right operand
@@ -127,7 +126,7 @@ package body Exp_Fixd is
-- operand with the smaller sized type to match the type of the other
-- operand and sets this as the result type. The result is never rounded
-- (rem operations cannot be rounded in any case). On return, the resulting
- -- node is analyzed and has its Etype set.
+ -- node has its Etype set.
function Build_Scaled_Divide
(N : Node_Id;
@@ -135,7 +134,7 @@ package body Exp_Fixd is
-- Returns a node corresponding to the value X*Y/Z using the source
-- location from Sloc (N). The division is rounded if the Rounded_Result
-- flag of N is set. The integer types of X, Y, Z may be different. On
- -- return the resulting node is analyzed and has is Etype set.
+ -- return the resulting node has its Etype set.
procedure Build_Scaled_Divide_Code
(N : Node_Id;
@@ -194,12 +193,13 @@ package body Exp_Fixd is
V : Uint;
Negative : Boolean := False) return Node_Id;
-- Given a non-negative universal integer value, build a typed integer
- -- literal node, using the smallest applicable standard integer type. If
- -- and only if Negative is true a negative literal is built. If V exceeds
- -- 2**63-1, the largest value allowed for perfect result set scaling
- -- factors (see RM G.2.3(22)), then Empty is returned. The node N provides
- -- the Sloc value for the constructed literal. The Etype of the resulting
- -- literal is correctly set, and it is marked as analyzed.
+ -- literal node, using the smallest applicable standard integer type.
+ -- If Negative is true, then a negative literal is built. If V exceeds
+ -- 2**(System_Max_Integer_Size - 1) - 1, the largest value allowed for
+ -- perfect result set scaling factors (see RM G.2.3(22)), then Empty is
+ -- returned. The node N provides the Sloc value for the constructed
+ -- literal. The Etype of the resulting literal is correctly set, and it
+ -- is marked as analyzed.
function Real_Literal (N : Node_Id; V : Ureal) return Node_Id;
-- Build a real literal node from the given value, the Etype of the
@@ -347,11 +347,12 @@ package body Exp_Fixd is
return L;
end if;
+ -- Otherwise we need to figure out the correct result type size
-- First figure out the effective sizes of the operands. Normally
-- the effective size of an operand is the RM_Size of the operand.
-- But a special case arises with operands whose size is known at
-- compile time. In this case, we can use the actual value of the
- -- operand to get its size if it would fit signed in 8 or 16 bits.
+ -- operand to get its size if it would fit in signed 8/16/32 bits.
Left_Size := UI_To_Int (RM_Size (Left_Type));
@@ -359,10 +360,12 @@ package body Exp_Fixd is
declare
Val : constant Uint := Expr_Value (L);
begin
- if Val < Int'(2 ** 7) then
+ if Val < Uint_2 ** 7 then
Left_Size := 8;
- elsif Val < Int'(2 ** 15) then
+ elsif Val < Uint_2 ** 15 then
Left_Size := 16;
+ elsif Val < Uint_2 ** 31 then
+ Left_Size := 32;
end if;
end;
end if;
@@ -394,8 +397,11 @@ package body Exp_Fixd is
elsif Rsize <= 32 then
Result_Type := Standard_Integer_32;
- else
+ elsif Rsize <= 64 or else System_Max_Integer_Size < 128 then
Result_Type := Standard_Integer_64;
+
+ else
+ Result_Type := Standard_Integer_128;
end if;
Rnode :=
@@ -441,23 +447,29 @@ package body Exp_Fixd is
(N : Node_Id;
X, Y, Z : Node_Id) return Node_Id
is
- Y_Size : constant Nat := UI_To_Int (Esize (Etype (Y)));
- Z_Size : constant Nat := UI_To_Int (Esize (Etype (Z)));
+ X_Size : constant Nat := UI_To_Int (RM_Size (Etype (X)));
+ Y_Size : constant Nat := UI_To_Int (RM_Size (Etype (Y)));
+ Z_Size : constant Nat := UI_To_Int (RM_Size (Etype (Z)));
+ D_Size : constant Nat := Y_Size + Z_Size;
+ M_Size : constant Nat := Nat'Max (X_Size, Nat'Max (Y_Size, Z_Size));
Expr : Node_Id;
begin
- -- If denominator fits in 64 bits, we can build the operations directly
- -- without causing any intermediate overflow, so that's what we do.
+ -- If the denominator fits in Max_Integer_Size bits, we can build the
+ -- operations directly without causing any intermediate overflow. But
+ -- for backward compatibility reasons, we use a 128-bit divide only
+ -- if one of the operands is already larger than 64 bits.
- if Nat'Max (Y_Size, Z_Size) <= 32 then
- return
- Build_Divide (N, X, Build_Multiply (N, Y, Z));
+ if D_Size <= System_Max_Integer_Size
+ and then (D_Size <= 64 or else M_Size > 64)
+ then
+ return Build_Divide (N, X, Build_Multiply (N, Y, Z));
-- Otherwise we use the runtime routine
- -- [Qnn : Interfaces.Integer_64,
- -- Rnn : Interfaces.Integer_64;
- -- Double_Divide (X, Y, Z, Qnn, Rnn, Round);
+ -- [Qnn : Interfaces.Integer_{64|128};
+ -- Rnn : Interfaces.Integer_{64|128};
+ -- Double_Divide{64|128} (X, Y, Z, Qnn, Rnn, Round);
-- Qnn]
else
@@ -489,18 +501,18 @@ package body Exp_Fixd is
-- Build_Double_Divide_Code --
------------------------------
- -- If the denominator can be computed in 64-bits, we build
+ -- If the denominator can be computed in Max_Integer_Size bits, we build
-- [Nnn : constant typ := typ (X);
-- Dnn : constant typ := typ (Y) * typ (Z)
-- Qnn : constant typ := Nnn / Dnn;
- -- Rnn : constant typ := Nnn / Dnn;
+ -- Rnn : constant typ := Nnn rem Dnn;
- -- If the numerator cannot be computed in 64 bits, we build
+ -- If the denominator cannot be computed in Max_Integer_Size bits, we build
- -- [Qnn : typ;
- -- Rnn : typ;
- -- Double_Divide (X, Y, Z, Qnn, Rnn, Round);]
+ -- [Qnn : Interfaces.Integer_{64|128};
+ -- Rnn : Interfaces.Integer_{64|128};
+ -- Double_Divide{64|128} (X, Y, Z, Qnn, Rnn, Round);]
procedure Build_Double_Divide_Code
(N : Node_Id;
@@ -510,10 +522,12 @@ package body Exp_Fixd is
is
Loc : constant Source_Ptr := Sloc (N);
- X_Size : constant Nat := UI_To_Int (Esize (Etype (X)));
- Y_Size : constant Nat := UI_To_Int (Esize (Etype (Y)));
- Z_Size : constant Nat := UI_To_Int (Esize (Etype (Z)));
+ X_Size : constant Nat := UI_To_Int (RM_Size (Etype (X)));
+ Y_Size : constant Nat := UI_To_Int (RM_Size (Etype (Y)));
+ Z_Size : constant Nat := UI_To_Int (RM_Size (Etype (Z)));
+ M_Size : constant Nat := Nat'Max (X_Size, Nat'Max (Y_Size, Z_Size));
+ QR_Id : RE_Id;
QR_Siz : Nat;
QR_Typ : Entity_Id;
@@ -524,22 +538,36 @@ package body Exp_Fixd is
Rnd : Entity_Id;
begin
- -- Find type that will allow computation of numerator
+ -- Find type that will allow computation of denominator
- QR_Siz := Nat'Max (X_Size, 2 * Nat'Max (Y_Size, Z_Size));
+ QR_Siz := Nat'Max (X_Size, Y_Size + Z_Size);
if QR_Siz <= 16 then
QR_Typ := Standard_Integer_16;
+ QR_Id := RE_Null;
+
elsif QR_Siz <= 32 then
QR_Typ := Standard_Integer_32;
+ QR_Id := RE_Null;
+
elsif QR_Siz <= 64 then
QR_Typ := Standard_Integer_64;
+ QR_Id := RE_Null;
- -- For more than 64, bits, we use the 64-bit integer defined in
- -- Interfaces, so that it can be handled by the runtime routine.
+ -- For backward compatibility reasons, we use a 128-bit divide only
+ -- if one of the operands is already larger than 64 bits.
- else
+ elsif System_Max_Integer_Size < 128 or else M_Size <= 64 then
QR_Typ := RTE (RE_Integer_64);
+ QR_Id := RE_Double_Divide64;
+
+ elsif QR_Siz <= 128 then
+ QR_Typ := Standard_Integer_128;
+ QR_Id := RE_Null;
+
+ else
+ QR_Typ := RTE (RE_Integer_128);
+ QR_Id := RE_Double_Divide128;
end if;
-- Define quotient and remainder, and set their Etypes, so
@@ -551,9 +579,9 @@ package body Exp_Fixd is
Set_Etype (Qnn, QR_Typ);
Set_Etype (Rnn, QR_Typ);
- -- Case that we can compute the denominator in 64 bits
+ -- Case where we can compute the denominator in Max_Integer_Size bits
- if QR_Siz <= 64 then
+ if QR_Id = RE_Null then
-- Create temporaries for numerator and denominator and set Etypes,
-- so that New_Occurrence_Of picks them up for Build_xxx calls.
@@ -569,16 +597,13 @@ package body Exp_Fixd is
Defining_Identifier => Nnn,
Object_Definition => New_Occurrence_Of (QR_Typ, Loc),
Constant_Present => True,
- Expression => Build_Conversion (N, QR_Typ, X)),
+ Expression => Build_Conversion (N, QR_Typ, X)),
Make_Object_Declaration (Loc,
Defining_Identifier => Dnn,
Object_Definition => New_Occurrence_Of (QR_Typ, Loc),
Constant_Present => True,
- Expression =>
- Build_Multiply (N,
- Build_Conversion (N, QR_Typ, Y),
- Build_Conversion (N, QR_Typ, Z))));
+ Expression => Build_Multiply (N, Y, Z)));
Quo :=
Build_Divide (N,
@@ -604,8 +629,8 @@ package body Exp_Fixd is
New_Occurrence_Of (Nnn, Loc),
New_Occurrence_Of (Dnn, Loc))));
- -- Case where denominator does not fit in 64 bits, so we have to
- -- call the runtime routine to compute the quotient and remainder
+ -- Case where denominator does not fit in Max_Integer_Size bits, we have
+ -- to call the runtime routine to compute the quotient and remainder.
else
Rnd := Boolean_Literals (Rounded_Result_Set (N));
@@ -620,7 +645,7 @@ package body Exp_Fixd is
Object_Definition => New_Occurrence_Of (QR_Typ, Loc)),
Make_Procedure_Call_Statement (Loc,
- Name => New_Occurrence_Of (RTE (RE_Double_Divide64), Loc),
+ Name => New_Occurrence_Of (RTE (QR_Id), Loc),
Parameter_Associations => New_List (
Build_Conversion (N, QR_Typ, X),
Build_Conversion (N, QR_Typ, Y),
@@ -674,7 +699,7 @@ package body Exp_Fixd is
-- the effective size of an operand is the RM_Size of the operand.
-- But a special case arises with operands whose size is known at
-- compile time. In this case, we can use the actual value of the
- -- operand to get its size if it would fit signed in 8 or 16 bits.
+ -- operand to get its size if it would fit in signed 8/16/32 bits.
Left_Size := UI_To_Int (RM_Size (Left_Type));
@@ -682,10 +707,12 @@ package body Exp_Fixd is
declare
Val : constant Uint := Expr_Value (L);
begin
- if Val < Int'(2 ** 7) then
+ if Val < Uint_2 ** 7 then
Left_Size := 8;
- elsif Val < Int'(2 ** 15) then
+ elsif Val < Uint_2 ** 15 then
Left_Size := 16;
+ elsif Val < Uint_2 ** 31 then
+ Left_Size := 32;
end if;
end;
end if;
@@ -704,10 +731,10 @@ package body Exp_Fixd is
end;
end if;
- -- Now the result size must be at least twice the longer of
- -- the two sizes, to accommodate all possible results.
+ -- Now the result size must be at least the sum of the two sizes,
+ -- to accommodate all possible results.
- Rsize := 2 * Int'Max (Left_Size, Right_Size);
+ Rsize := Left_Size + Right_Size;
if Rsize <= 8 then
Result_Type := Standard_Integer_8;
@@ -718,8 +745,11 @@ package body Exp_Fixd is
elsif Rsize <= 32 then
Result_Type := Standard_Integer_32;
- else
+ elsif Rsize <= 64 or else System_Max_Integer_Size < 128 then
Result_Type := Standard_Integer_64;
+
+ else
+ Result_Type := Standard_Integer_128;
end if;
Rnode :=
@@ -805,23 +835,29 @@ package body Exp_Fixd is
(N : Node_Id;
X, Y, Z : Node_Id) return Node_Id
is
- X_Size : constant Nat := UI_To_Int (Esize (Etype (X)));
- Y_Size : constant Nat := UI_To_Int (Esize (Etype (Y)));
+ X_Size : constant Nat := UI_To_Int (RM_Size (Etype (X)));
+ Y_Size : constant Nat := UI_To_Int (RM_Size (Etype (Y)));
+ Z_Size : constant Nat := UI_To_Int (RM_Size (Etype (Z)));
+ N_Size : constant Nat := X_Size + Y_Size;
+ M_Size : constant Nat := Nat'Max (X_Size, Nat'Max (Y_Size, Z_Size));
Expr : Node_Id;
begin
- -- If numerator fits in 64 bits, we can build the operations directly
- -- without causing any intermediate overflow, so that's what we do.
+ -- If the numerator fits in Max_Integer_Size bits, we can build the
+ -- operations directly without causing any intermediate overflow. But
+ -- for backward compatibility reasons, we use a 128-bit divide only
+ -- if one of the operands is already larger than 64 bits.
- if Nat'Max (X_Size, Y_Size) <= 32 then
- return
- Build_Divide (N, Build_Multiply (N, X, Y), Z);
+ if N_Size <= System_Max_Integer_Size
+ and then (N_Size <= 64 or else M_Size > 64)
+ then
+ return Build_Divide (N, Build_Multiply (N, X, Y), Z);
-- Otherwise we use the runtime routine
- -- [Qnn : Integer_64,
- -- Rnn : Integer_64;
- -- Scaled_Divide (X, Y, Z, Qnn, Rnn, Round);
+ -- [Qnn : Integer_{64|128},
+ -- Rnn : Integer_{64|128};
+ -- Scaled_Divide{64|128} (X, Y, Z, Qnn, Rnn, Round);
-- Qnn]
else
@@ -850,18 +886,18 @@ package body Exp_Fixd is
-- Build_Scaled_Divide_Code --
------------------------------
- -- If the numerator can be computed in 64-bits, we build
+ -- If the numerator can be computed in Max_Integer_Size bits, we build
-- [Nnn : constant typ := typ (X) * typ (Y);
-- Dnn : constant typ := typ (Z)
-- Qnn : constant typ := Nnn / Dnn;
- -- Rnn : constant typ := Nnn / Dnn;
+ -- Rnn : constant typ := Nnn rem Dnn;
- -- If the numerator cannot be computed in 64 bits, we build
+ -- If the numerator cannot be computed in Max_Integer_Size bits, we build
- -- [Qnn : Interfaces.Integer_64;
- -- Rnn : Interfaces.Integer_64;
- -- Scaled_Divide (X, Y, Z, Qnn, Rnn, Round);]
+ -- [Qnn : Interfaces.Integer_{64|128};
+ -- Rnn : Interfaces.Integer_{64|128};
+ -- Scaled_Divide_{64|128} (X, Y, Z, Qnn, Rnn, Round);]
procedure Build_Scaled_Divide_Code
(N : Node_Id;
@@ -871,10 +907,12 @@ package body Exp_Fixd is
is
Loc : constant Source_Ptr := Sloc (N);
- X_Size : constant Nat := UI_To_Int (Esize (Etype (X)));
- Y_Size : constant Nat := UI_To_Int (Esize (Etype (Y)));
- Z_Size : constant Nat := UI_To_Int (Esize (Etype (Z)));
+ X_Size : constant Nat := UI_To_Int (RM_Size (Etype (X)));
+ Y_Size : constant Nat := UI_To_Int (RM_Size (Etype (Y)));
+ Z_Size : constant Nat := UI_To_Int (RM_Size (Etype (Z)));
+ M_Size : constant Nat := Nat'Max (X_Size, Nat'Max (Y_Size, Z_Size));
+ QR_Id : RE_Id;
QR_Siz : Nat;
QR_Typ : Entity_Id;
@@ -887,20 +925,34 @@ package body Exp_Fixd is
begin
-- Find type that will allow computation of numerator
- QR_Siz := Nat'Max (X_Size, 2 * Nat'Max (Y_Size, Z_Size));
+ QR_Siz := Nat'Max (X_Size + Y_Size, Z_Size);
if QR_Siz <= 16 then
QR_Typ := Standard_Integer_16;
+ QR_Id := RE_Null;
+
elsif QR_Siz <= 32 then
QR_Typ := Standard_Integer_32;
+ QR_Id := RE_Null;
+
elsif QR_Siz <= 64 then
QR_Typ := Standard_Integer_64;
+ QR_Id := RE_Null;
- -- For more than 64, bits, we use the 64-bit integer defined in
- -- Interfaces, so that it can be handled by the runtime routine.
+ -- For backward compatibility reasons, we use a 128-bit divide only
+ -- if one of the operands is already larger than 64 bits.
- else
+ elsif System_Max_Integer_Size < 128 or else M_Size <= 64 then
QR_Typ := RTE (RE_Integer_64);
+ QR_Id := RE_Scaled_Divide64;
+
+ elsif QR_Siz <= 128 then
+ QR_Typ := Standard_Integer_128;
+ QR_Id := RE_Null;
+
+ else
+ QR_Typ := RTE (RE_Integer_128);
+ QR_Id := RE_Scaled_Divide128;
end if;
-- Define quotient and remainder, and set their Etypes, so
@@ -912,9 +964,9 @@ package body Exp_Fixd is
Set_Etype (Qnn, QR_Typ);
Set_Etype (Rnn, QR_Typ);
- -- Case that we can compute the numerator in 64 bits
+ -- Case where we can compute the numerator in Max_Integer_Size bits
- if QR_Siz <= 64 then
+ if QR_Id = RE_Null then
Nnn := Make_Temporary (Loc, 'N');
Dnn := Make_Temporary (Loc, 'D');
@@ -928,16 +980,13 @@ package body Exp_Fixd is
Defining_Identifier => Nnn,
Object_Definition => New_Occurrence_Of (QR_Typ, Loc),
Constant_Present => True,
- Expression =>
- Build_Multiply (N,
- Build_Conversion (N, QR_Typ, X),
- Build_Conversion (N, QR_Typ, Y))),
+ Expression => Build_Multiply (N, X, Y)),
Make_Object_Declaration (Loc,
Defining_Identifier => Dnn,
Object_Definition => New_Occurrence_Of (QR_Typ, Loc),
Constant_Present => True,
- Expression => Build_Conversion (N, QR_Typ, Z)));
+ Expression => Build_Conversion (N, QR_Typ, Z)));
Quo :=
Build_Divide (N,
@@ -961,8 +1010,8 @@ package body Exp_Fixd is
New_Occurrence_Of (Nnn, Loc),
New_Occurrence_Of (Dnn, Loc))));
- -- Case where numerator does not fit in 64 bits, so we have to
- -- call the runtime routine to compute the quotient and remainder
+ -- Case where numerator does not fit in Max_Integer_Size bits, we have
+ -- to call the runtime routine to compute the quotient and remainder.
else
Rnd := Boolean_Literals (Rounded_Result_Set (N));
@@ -977,7 +1026,7 @@ package body Exp_Fixd is
Object_Definition => New_Occurrence_Of (QR_Typ, Loc)),
Make_Procedure_Call_Statement (Loc,
- Name => New_Occurrence_Of (RTE (RE_Scaled_Divide64), Loc),
+ Name => New_Occurrence_Of (RTE (QR_Id), Loc),
Parameter_Associations => New_List (
Build_Conversion (N, QR_Typ, X),
Build_Conversion (N, QR_Typ, Y),
@@ -1374,8 +1423,7 @@ package body Exp_Fixd is
if Present (Lit_Int) then
Set_Result (N,
- Build_Multiply (N, Build_Multiply (N, Left, Right),
- Lit_Int));
+ Build_Multiply (N, Build_Multiply (N, Left, Right), Lit_Int));
return;
end if;
@@ -1546,6 +1594,10 @@ package body Exp_Fixd is
-- If the small ratio is the reciprocal of a sufficiently small integer,
-- then the perfect result set is obtained by a single integer division.
+ -- If the numerator and denominator of the small ratio are sufficiently
+ -- small integers, then the perfect result set is obtained by a scaled
+ -- divide operation.
+
-- In other cases, we obtain the close result set by calculating the
-- result in floating-point.
@@ -1557,7 +1609,8 @@ package body Exp_Fixd is
Small_Ratio : Ureal;
Ratio_Num : Uint;
Ratio_Den : Uint;
- Lit : Node_Id;
+ Lit_Num : Node_Id;
+ Lit_Den : Node_Id;
begin
if Is_OK_Static_Expression (Expr) then
@@ -1575,26 +1628,36 @@ package body Exp_Fixd is
return;
else
- Lit := Integer_Literal (N, Ratio_Num);
+ Lit_Num := Integer_Literal (N, Ratio_Num);
- if Present (Lit) then
- Set_Result (N, Build_Multiply (N, Expr, Lit));
+ if Present (Lit_Num) then
+ Set_Result (N, Build_Multiply (N, Expr, Lit_Num));
return;
end if;
end if;
elsif Ratio_Num = 1 then
- Lit := Integer_Literal (N, Ratio_Den);
+ Lit_Den := Integer_Literal (N, Ratio_Den);
- if Present (Lit) then
- Set_Result (N, Build_Divide (N, Expr, Lit), Rng_Check);
+ if Present (Lit_Den) then
+ Set_Result (N, Build_Divide (N, Expr, Lit_Den), Rng_Check);
+ return;
+ end if;
+
+ else
+ Lit_Num := Integer_Literal (N, Ratio_Num);
+ Lit_Den := Integer_Literal (N, Ratio_Den);
+
+ if Present (Lit_Num) and then Present (Lit_Den) then
+ Set_Result
+ (N, Build_Scaled_Divide (N, Expr, Lit_Num, Lit_Den), Rng_Check);
return;
end if;
end if;
- -- Fall through to use floating-point for the close result set case
- -- either as a result of the small ratio not being an integer or the
- -- reciprocal of an integer, or if the integer is out of range.
+ -- Fall through to use floating-point for the close result set case,
+ -- as a result of the numerator or denominator of the small ratio not
+ -- being a sufficiently small integer.
Set_Result (N,
Build_Multiply (N,
@@ -1650,6 +1713,10 @@ package body Exp_Fixd is
-- If the small value is the reciprocal of a sufficiently small integer,
-- then the perfect result set is obtained by a single integer division.
+ -- If the numerator and denominator of the small value are sufficiently
+ -- small integers, then the perfect result set is obtained by a scaled
+ -- divide operation.
+
-- In other cases, we obtain the close result set by calculating the
-- result in floating-point.
@@ -1660,7 +1727,8 @@ package body Exp_Fixd is
Small : constant Ureal := Small_Value (Source_Type);
Small_Num : constant Uint := Norm_Num (Small);
Small_Den : constant Uint := Norm_Den (Small);
- Lit : Node_Id;
+ Lit_Num : Node_Id;
+ Lit_Den : Node_Id;
begin
if Is_OK_Static_Expression (Expr) then
@@ -1669,25 +1737,35 @@ package body Exp_Fixd is
end if;
if Small_Den = 1 then
- Lit := Integer_Literal (N, Small_Num);
+ Lit_Num := Integer_Literal (N, Small_Num);
- if Present (Lit) then
- Set_Result (N, Build_Multiply (N, Expr, Lit), Rng_Check);
+ if Present (Lit_Num) then
+ Set_Result (N, Build_Multiply (N, Expr, Lit_Num), Rng_Check);
return;
end if;
elsif Small_Num = 1 then
- Lit := Integer_Literal (N, Small_Den);
+ Lit_Den := Integer_Literal (N, Small_Den);
- if Present (Lit) then
- Set_Result (N, Build_Divide (N, Expr, Lit), Rng_Check);
+ if Present (Lit_Den) then
+ Set_Result (N, Build_Divide (N, Expr, Lit_Den), Rng_Check);
+ return;
+ end if;
+
+ else
+ Lit_Num := Integer_Literal (N, Small_Num);
+ Lit_Den := Integer_Literal (N, Small_Den);
+
+ if Present (Lit_Num) and then Present (Lit_Den) then
+ Set_Result
+ (N, Build_Scaled_Divide (N, Expr, Lit_Num, Lit_Den), Rng_Check);
return;
end if;
end if;
- -- Fall through to use floating-point for the close result set case
- -- either as a result of the small value not being an integer or the
- -- reciprocal of an integer, or if the integer is out of range.
+ -- Fall through to use floating-point for the close result set case,
+ -- as a result of the numerator or denominator of the small value not
+ -- being a sufficiently small integer.
Set_Result (N,
Build_Multiply (N,
@@ -1769,6 +1847,10 @@ package body Exp_Fixd is
-- If the small value is the reciprocal of a sufficiently small integer,
-- the perfect result set is obtained by a single integer multiplication.
+ -- If the numerator and denominator of the small value are sufficiently
+ -- small integers, then the perfect result set is obtained by a scaled
+ -- divide operation.
+
-- In other cases, we obtain the close result set by calculating the
-- result in floating-point using a multiplication by the reciprocal
-- of the Result_Small.
@@ -1780,29 +1862,40 @@ package body Exp_Fixd is
Small : constant Ureal := Small_Value (Result_Type);
Small_Num : constant Uint := Norm_Num (Small);
Small_Den : constant Uint := Norm_Den (Small);
- Lit : Node_Id;
+ Lit_Num : Node_Id;
+ Lit_Den : Node_Id;
begin
if Small_Den = 1 then
- Lit := Integer_Literal (N, Small_Num);
+ Lit_Num := Integer_Literal (N, Small_Num);
- if Present (Lit) then
- Set_Result (N, Build_Divide (N, Expr, Lit), Rng_Check);
+ if Present (Lit_Num) then
+ Set_Result (N, Build_Divide (N, Expr, Lit_Num), Rng_Check);
return;
end if;
elsif Small_Num = 1 then
- Lit := Integer_Literal (N, Small_Den);
+ Lit_Den := Integer_Literal (N, Small_Den);
+
+ if Present (Lit_Den) then
+ Set_Result (N, Build_Multiply (N, Expr, Lit_Den), Rng_Check);
+ return;
+ end if;
- if Present (Lit) then
- Set_Result (N, Build_Multiply (N, Expr, Lit), Rng_Check);
+ else
+ Lit_Num := Integer_Literal (N, Small_Num);
+ Lit_Den := Integer_Literal (N, Small_Den);
+
+ if Present (Lit_Num) and then Present (Lit_Den) then
+ Set_Result
+ (N, Build_Scaled_Divide (N, Expr, Lit_Den, Lit_Num), Rng_Check);
return;
end if;
end if;
- -- Fall through to use floating-point for the close result set case
- -- either as a result of the small value not being an integer or the
- -- reciprocal of an integer, or if the integer is out of range.
+ -- Fall through to use floating-point for the close result set case,
+ -- as a result of the numerator or denominator of the small value not
+ -- being a sufficiently small integer.
Set_Result (N,
Build_Multiply (N,
@@ -2380,6 +2473,9 @@ package body Exp_Fixd is
elsif V < Uint_2 ** 63 then
T := Standard_Integer_64;
+ elsif V < Uint_2 ** 127 and then System_Max_Integer_Size = 128 then
+ T := Standard_Integer_128;
+
else
return Empty;
end if;
diff --git a/gcc/ada/exp_imgv.adb b/gcc/ada/exp_imgv.adb
index 40cb514..b79d30a 100644
--- a/gcc/ada/exp_imgv.adb
+++ b/gcc/ada/exp_imgv.adb
@@ -49,11 +49,6 @@ with Urealp; use Urealp;
package body Exp_Imgv is
- function Has_Decimal_Small (E : Entity_Id) return Boolean;
- -- Applies to all entities. True for a Decimal_Fixed_Point_Type, or an
- -- Ordinary_Fixed_Point_Type with a small that is a negative power of ten.
- -- Shouldn't this be in einfo.adb or sem_aux.adb???
-
procedure Rewrite_Object_Image
(N : Node_Id;
Pref : Entity_Id;
@@ -219,21 +214,13 @@ package body Exp_Imgv is
-- xx = Boolean
-- tv = Boolean (Expr)
- -- For signed integer types with size <= Integer'Size
- -- xx = Integer
- -- tv = Integer (Expr)
-
- -- For other signed integer types
- -- xx = Long_Long_Integer
- -- tv = Long_Long_Integer (Expr)
-
- -- For modular types with modulus <= System.Unsigned_Types.Unsigned
- -- xx = Unsigned
- -- tv = System.Unsigned_Types.Unsigned (Expr)
+ -- For signed integer types
+ -- xx = [Long_Long_[Long_]]Integer
+ -- tv = [Long_Long_[Long_]]Integer (Expr)
- -- For other modular integer types
- -- xx = Long_Long_Unsigned
- -- tv = System.Unsigned_Types.Long_Long_Unsigned (Expr)
+ -- For modular types
+ -- xx = [Long_Long_[Long_]]Unsigned
+ -- tv = System.Unsigned_Types.[Long_Long_[Long_]]Unsigned (Expr)
-- For types whose root type is Wide_Character
-- xx = Wide_Character
@@ -249,21 +236,24 @@ package body Exp_Imgv is
-- tv = Long_Long_Float (Expr)
-- pm = typ'Digits (typ = subtype of expression)
- -- For ordinary fixed-point types
+ -- For decimal fixed-point types
+ -- xx = Decimal{32,64,128}
+ -- tv = Integer_{32,64,128} (Expr)? [convert with no scaling]
+ -- pm = typ'Scale (typ = subtype of expression)
+
+ -- For the most common ordinary fixed-point types
+ -- xx = Fixed{32,64,128}
+ -- tv = Integer_{32,64,128} (Expr) [convert with no scaling]
+ -- pm = numerator of typ'Small (typ = subtype of expression)
+ -- denominator of typ'Small
+ -- (Integer_{32,64,128} x typ'Small)'Fore
+ -- typ'Aft
+
+ -- For other ordinary fixed-point types
-- xx = Ordinary_Fixed_Point
-- tv = Long_Long_Float (Expr)
-- pm = typ'Aft (typ = subtype of expression)
- -- For decimal fixed-point types with size = Integer'Size
- -- xx = Decimal
- -- tv = Integer (Expr)
- -- pm = typ'Scale (typ = subtype of expression)
-
- -- For decimal fixed-point types with size > Integer'Size
- -- xx = Long_Long_Decimal
- -- tv = Long_Long_Integer?(Expr) [convert with no scaling]
- -- pm = typ'Scale (typ = subtype of expression)
-
-- For enumeration types other than those declared in package Standard
-- or System, Snn, Pnn, are expanded as above, but the call looks like:
@@ -593,18 +583,58 @@ package body Exp_Imgv is
Tent := RTE (RE_Long_Long_Long_Unsigned);
end if;
- elsif Is_Fixed_Point_Type (Rtyp) and then Has_Decimal_Small (Rtyp) then
- if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
- Imid := RE_Image_Decimal;
- Tent := Standard_Integer;
+ elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
+ if Esize (Rtyp) <= 32 then
+ Imid := RE_Image_Decimal32;
+ Tent := RTE (RE_Integer_32);
+ elsif Esize (Rtyp) <= 64 then
+ Imid := RE_Image_Decimal64;
+ Tent := RTE (RE_Integer_64);
else
- Imid := RE_Image_Long_Long_Decimal;
- Tent := Standard_Long_Long_Integer;
+ Imid := RE_Image_Decimal128;
+ Tent := RTE (RE_Integer_128);
end if;
elsif Is_Ordinary_Fixed_Point_Type (Rtyp) then
- Imid := RE_Image_Ordinary_Fixed_Point;
- Tent := Standard_Long_Long_Float;
+ declare
+ Num : constant Uint := Norm_Num (Small_Value (Rtyp));
+ Den : constant Uint := Norm_Den (Small_Value (Rtyp));
+ Max : constant Uint := UI_Max (Num, Den);
+ Min : constant Uint := UI_Min (Num, Den);
+ Siz : constant Uint := Esize (Rtyp);
+
+ begin
+ -- Note that we do not use sharp bounds to speed things up
+
+ if Siz <= 32
+ and then Max <= Uint_2 ** 31
+ and then (Min = Uint_1
+ or else (Num < Den and then Den <= Uint_2 ** 27)
+ or else (Den < Num and then Num <= Uint_2 ** 25))
+ then
+ Imid := RE_Image_Fixed32;
+ Tent := RTE (RE_Integer_32);
+ elsif Siz <= 64
+ and then Max <= Uint_2 ** 63
+ and then (Min = Uint_1
+ or else (Num < Den and then Den <= Uint_2 ** 59)
+ or else (Den < Num and then Num <= Uint_2 ** 53))
+ then
+ Imid := RE_Image_Fixed64;
+ Tent := RTE (RE_Integer_64);
+ elsif System_Max_Integer_Size = 128
+ and then Max <= Uint_2 ** 127
+ and then (Min = Uint_1
+ or else (Num < Den and then Den <= Uint_2 ** 123)
+ or else (Den < Num and then Num <= Uint_2 ** 122))
+ then
+ Imid := RE_Image_Fixed128;
+ Tent := RTE (RE_Integer_128);
+ else
+ Imid := RE_Image_Ordinary_Fixed_Point;
+ Tent := Standard_Long_Long_Float;
+ end if;
+ end;
elsif Is_Floating_Point_Type (Rtyp) then
Imid := RE_Image_Floating_Point;
@@ -746,29 +776,45 @@ package body Exp_Imgv is
Prefix => New_Occurrence_Of (Ptyp, Loc),
Attribute_Name => Name_Digits));
- -- For ordinary fixed-point types, append Aft parameter
+ -- For decimal, append Scale and also set to do literal conversion
- elsif Is_Ordinary_Fixed_Point_Type (Rtyp) then
- Append_To (Arg_List,
- Make_Attribute_Reference (Loc,
- Prefix => New_Occurrence_Of (Ptyp, Loc),
- Attribute_Name => Name_Aft));
+ elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
+ Set_Conversion_OK (First (Arg_List));
+
+ Append_To (Arg_List, Make_Integer_Literal (Loc, Scale_Value (Ptyp)));
- if Has_Decimal_Small (Rtyp) then
+ -- For ordinary fixed-point types, append Num, Den, Fore, Aft parameters
+ -- and also set to do literal conversion.
+
+ elsif Is_Ordinary_Fixed_Point_Type (Rtyp) then
+ if Imid /= RE_Image_Ordinary_Fixed_Point then
Set_Conversion_OK (First (Arg_List));
- Set_Etype (First (Arg_List), Tent);
- end if;
- -- For decimal, append Scale and also set to do literal conversion
+ Append_To (Arg_List,
+ Make_Integer_Literal (Loc, -Norm_Num (Small_Value (Ptyp))));
- elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
- Append_To (Arg_List,
- Make_Attribute_Reference (Loc,
- Prefix => New_Occurrence_Of (Ptyp, Loc),
- Attribute_Name => Name_Scale));
+ Append_To (Arg_List,
+ Make_Integer_Literal (Loc, -Norm_Den (Small_Value (Ptyp))));
- Set_Conversion_OK (First (Arg_List));
- Set_Etype (First (Arg_List), Tent);
+ -- We want to compute the Fore value for the fixed point type
+ -- whose mantissa type is Tent and whose small is typ'Small.
+
+ declare
+ T : Ureal := Uint_2 ** (Esize (Tent) - 1) * Small_Value (Ptyp);
+ F : Nat := 2;
+
+ begin
+ while T >= Ureal_10 loop
+ F := F + 1;
+ T := T / Ureal_10;
+ end loop;
+
+ Append_To (Arg_List,
+ Make_Integer_Literal (Loc, UI_From_Int (F)));
+ end;
+ end if;
+
+ Append_To (Arg_List, Make_Integer_Literal (Loc, Aft_Value (Ptyp)));
-- For Wide_Character, append Ada 2005 indication
@@ -827,35 +873,29 @@ package body Exp_Imgv is
-- For types whose root type is Boolean
-- xx = Boolean
- -- For signed integer types with size <= Integer'Size
- -- xx = Integer
-
- -- For other signed integer types
- -- xx = Long_Long_Integer
-
- -- For modular types with modulus <= System.Unsigned_Types.Unsigned
- -- xx = Unsigned
+ -- For signed integer types
+ -- xx = [Long_Long_[Long_]]Integer
- -- For other modular integer types
- -- xx = Long_Long_Unsigned
+ -- For modular types
+ -- xx = [Long_Long_[Long_]]Unsigned
- -- For floating-point types and ordinary fixed-point types
+ -- For floating-point types
-- xx = Real
- -- For Wide_[Wide_]Character types, typ'Value (X) expands into:
+ -- For decimal fixed-point types, typ'Value (X) expands into
- -- btyp (Value_xx (X, EM))
+ -- btyp?(Value_Decimal{32,64,128} (X, typ'Scale));
- -- where btyp is the base type of the prefix, and EM is the encoding method
+ -- For the most common ordinary fixed-point types
- -- For decimal types with size <= Integer'Size, typ'Value (X)
- -- expands into
+ -- btyp?(Value_Fixed{32,64,128} (X, numerator of S, denominator of S));
+ -- where S = typ'Small
- -- btyp?(Value_Decimal (X, typ'Scale));
+ -- For Wide_[Wide_]Character types, typ'Value (X) expands into:
- -- For all other decimal types, typ'Value (X) expands into
+ -- btyp (Value_xx (X, EM))
- -- btyp?(Value_Long_Long_Decimal (X, typ'Scale))
+ -- where btyp is the base type of the prefix, and EM is the encoding method
-- For enumeration types other than those derived from types Boolean,
-- Character, Wide_[Wide_]Character in Standard, typ'Value (X) expands to:
@@ -923,16 +963,15 @@ package body Exp_Imgv is
end if;
elsif Is_Decimal_Fixed_Point_Type (Rtyp) then
- if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
- Vid := RE_Value_Decimal;
+ if Esize (Rtyp) <= 32 and then abs (Scale_Value (Rtyp)) <= 9 then
+ Vid := RE_Value_Decimal32;
+ elsif Esize (Rtyp) <= 64 and then abs (Scale_Value (Rtyp)) <= 18 then
+ Vid := RE_Value_Decimal64;
else
- Vid := RE_Value_Long_Long_Decimal;
+ Vid := RE_Value_Decimal128;
end if;
- Append_To (Args,
- Make_Attribute_Reference (Loc,
- Prefix => New_Occurrence_Of (Typ, Loc),
- Attribute_Name => Name_Scale));
+ Append_To (Args, Make_Integer_Literal (Loc, Scale_Value (Rtyp)));
Rewrite (N,
OK_Convert_To (Btyp,
@@ -944,7 +983,54 @@ package body Exp_Imgv is
Analyze_And_Resolve (N, Btyp);
return;
- elsif Is_Real_Type (Rtyp) then
+ elsif Is_Ordinary_Fixed_Point_Type (Rtyp) then
+ declare
+ Num : constant Uint := Norm_Num (Small_Value (Rtyp));
+ Den : constant Uint := Norm_Den (Small_Value (Rtyp));
+ Max : constant Uint := UI_Max (Num, Den);
+ Min : constant Uint := UI_Min (Num, Den);
+ Siz : constant Uint := Esize (Rtyp);
+
+ begin
+ if Siz <= 32
+ and then Max <= Uint_2 ** 31
+ and then (Min = Uint_1 or else Max <= Uint_2 ** 27)
+ then
+ Vid := RE_Value_Fixed32;
+ elsif Siz <= 64
+ and then Max <= Uint_2 ** 63
+ and then (Min = Uint_1 or else Max <= Uint_2 ** 59)
+ then
+ Vid := RE_Value_Fixed64;
+ elsif System_Max_Integer_Size = 128
+ and then Max <= Uint_2 ** 127
+ and then (Min = Uint_1 or else Max <= Uint_2 ** 123)
+ then
+ Vid := RE_Value_Fixed128;
+ else
+ Vid := RE_Value_Real;
+ end if;
+
+ if Vid /= RE_Value_Real then
+ Append_To (Args,
+ Make_Integer_Literal (Loc, -Norm_Num (Small_Value (Rtyp))));
+
+ Append_To (Args,
+ Make_Integer_Literal (Loc, -Norm_Den (Small_Value (Rtyp))));
+
+ Rewrite (N,
+ OK_Convert_To (Btyp,
+ Make_Function_Call (Loc,
+ Name => New_Occurrence_Of (RTE (Vid), Loc),
+ Parameter_Associations => Args)));
+
+ Set_Etype (N, Btyp);
+ Analyze_And_Resolve (N, Btyp);
+ return;
+ end if;
+ end;
+
+ elsif Is_Floating_Point_Type (Rtyp) then
Vid := RE_Value_Real;
-- Only other possibility is user-defined enumeration type
@@ -1286,12 +1372,12 @@ package body Exp_Imgv is
-- yy = Boolean
-- For signed integer types
- -- xx = Width_Long_Long_Integer
- -- yy = Long_Long_Integer
+ -- xx = Width_[Long_Long_[Long_]]Integer
+ -- yy = [Long_Long_[Long_]]Integer
-- For modular integer types
- -- xx = Width_Long_Long_Unsigned
- -- yy = Long_Long_Unsigned
+ -- xx = Width_[Long_Long_[Long_]]Unsigned
+ -- yy = [Long_Long_[Long_]]Unsigned
-- For types derived from Wide_Character, typ'Width expands into
@@ -1329,7 +1415,11 @@ package body Exp_Imgv is
-- Wide_Wide_Character (typ'First),
-- Wide_Wide_Character (typ'Last));
- -- For real types, typ'Width and typ'Wide_[Wide_]Width expand into
+ -- For fixed point types, typ'Width and typ'Wide_[Wide_]Width expand into
+
+ -- if Ptyp'First > Ptyp'Last then 0 else Ptyp'Fore + 1 + Ptyp'Aft end if
+
+ -- and for floating point types, they expand into
-- if Ptyp'First > Ptyp'Last then 0 else btyp'Width end if
@@ -1451,9 +1541,41 @@ package body Exp_Imgv is
YY := RTE (RE_Long_Long_Long_Unsigned);
end if;
- -- Real types
+ -- Fixed point types
- elsif Is_Real_Type (Rtyp) then
+ elsif Is_Fixed_Point_Type (Rtyp) then
+ Rewrite (N,
+ Make_If_Expression (Loc,
+ Expressions => New_List (
+
+ Make_Op_Gt (Loc,
+ Left_Opnd =>
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Occurrence_Of (Ptyp, Loc),
+ Attribute_Name => Name_First),
+
+ Right_Opnd =>
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Occurrence_Of (Ptyp, Loc),
+ Attribute_Name => Name_Last)),
+
+ Make_Integer_Literal (Loc, 0),
+
+ Make_Op_Add (Loc,
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Occurrence_Of (Ptyp, Loc),
+ Attribute_Name => Name_Fore),
+
+ Make_Op_Add (Loc,
+ Make_Integer_Literal (Loc, 1),
+ Make_Integer_Literal (Loc, Aft_Value (Ptyp)))))));
+
+ Analyze_And_Resolve (N, Typ);
+ return;
+
+ -- Floating point types
+
+ elsif Is_Floating_Point_Type (Rtyp) then
Rewrite (N,
Make_If_Expression (Loc,
Expressions => New_List (
@@ -1680,18 +1802,6 @@ package body Exp_Imgv is
Analyze_And_Resolve (N, Typ);
end Expand_Width_Attribute;
- -----------------------
- -- Has_Decimal_Small --
- -----------------------
-
- function Has_Decimal_Small (E : Entity_Id) return Boolean is
- begin
- return Is_Decimal_Fixed_Point_Type (E)
- or else
- (Is_Ordinary_Fixed_Point_Type (E)
- and then Ureal_10**Aft_Value (E) * Small_Value (E) = Ureal_1);
- end Has_Decimal_Small;
-
--------------------------
-- Rewrite_Object_Image --
--------------------------
diff --git a/gcc/ada/exp_intr.adb b/gcc/ada/exp_intr.adb
index 78bde89..7fc00c7 100644
--- a/gcc/ada/exp_intr.adb
+++ b/gcc/ada/exp_intr.adb
@@ -1229,9 +1229,8 @@ package body Exp_Intr is
if Is_Class_Wide_Type (Desig_Typ)
or else
- (Is_Array_Type (Desig_Typ)
- and then not Is_Constrained (Desig_Typ)
- and then Is_Packed (Desig_Typ))
+ (Is_Packed_Array (Desig_Typ)
+ and then not Is_Constrained (Desig_Typ))
then
declare
Deref : constant Node_Id :=
diff --git a/gcc/ada/exp_prag.adb b/gcc/ada/exp_prag.adb
index 53e2d97..9a227c6 100644
--- a/gcc/ada/exp_prag.adb
+++ b/gcc/ada/exp_prag.adb
@@ -425,7 +425,12 @@ package body Exp_Prag is
-- Generate the appropriate if statement. Note that we consider this to
-- be an explicit conditional in the source, not an implicit if, so we
- -- do not call Make_Implicit_If_Statement.
+ -- do not call Make_Implicit_If_Statement. Note also that we wrap the
+ -- raise statement in a block statement so that, if the condition is
+ -- evaluated at compile time to False, then the rewriting of the if
+ -- statement will not involve the raise but the block statement, and
+ -- thus not leave a dangling reference to the raise statement in the
+ -- Local_Raise_Statements list of the handler.
-- Case where we generate a direct raise
@@ -438,8 +443,14 @@ package body Exp_Prag is
Make_If_Statement (Loc,
Condition => Make_Op_Not (Loc, Right_Opnd => Cond),
Then_Statements => New_List (
- Make_Raise_Statement (Loc,
- Name => New_Occurrence_Of (RTE (RE_Assert_Failure), Loc)))));
+ Make_Block_Statement (Loc,
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => New_List (
+ Make_Raise_Statement (Loc,
+ Name =>
+ New_Occurrence_Of (RTE (RE_Assert_Failure),
+ Loc))))))));
-- Case where we call the procedure
diff --git a/gcc/ada/exp_sel.adb b/gcc/ada/exp_sel.adb
index 0fe9d3b..ccf62c6 100644
--- a/gcc/ada/exp_sel.adb
+++ b/gcc/ada/exp_sel.adb
@@ -70,27 +70,11 @@ package body Exp_Sel is
-------------------------------
function Build_Abort_Block_Handler (Loc : Source_Ptr) return Node_Id is
- Stmt : Node_Id;
-
begin
-
- -- With ZCX exceptions, aborts are not defered in handlers. With SJLJ,
- -- they are deferred at the beginning of Abort_Signal handlers.
-
- if ZCX_Exceptions then
- Stmt := Make_Null_Statement (Loc);
-
- else
- Stmt :=
- Make_Procedure_Call_Statement (Loc,
- Name => New_Occurrence_Of (RTE (RE_Abort_Undefer), Loc),
- Parameter_Associations => No_List);
- end if;
-
return Make_Implicit_Exception_Handler (Loc,
Exception_Choices =>
New_List (New_Occurrence_Of (Stand.Abort_Signal, Loc)),
- Statements => New_List (Stmt));
+ Statements => New_List (Make_Null_Statement (Loc)));
end Build_Abort_Block_Handler;
-------------
diff --git a/gcc/ada/exp_sel.ads b/gcc/ada/exp_sel.ads
index 98ac647..f2f2c56 100644
--- a/gcc/ada/exp_sel.ads
+++ b/gcc/ada/exp_sel.ads
@@ -39,21 +39,18 @@ package Exp_Sel is
-- begin
-- Blk
-- exception
- -- when Abort_Signal => Abort_Undefer / null;
+ -- when Abort_Signal => null;
-- end;
-- Abr_Blk_Ent is the name of the generated block, Cln_Blk_Ent is the name
-- of the encapsulated cleanup block, Blk is the actual block name.
-- The exception handler code is built by Build_Abort_Block_Handler.
function Build_Abort_Block_Handler (Loc : Source_Ptr) return Node_Id;
- -- Generate if front-end exception:
- -- when others =>
- -- Abort_Undefer;
- -- or if back-end exception:
+ -- Generate:
-- when others =>
-- null;
-- This is an exception handler to stop propagation of aborts, without
- -- modifying the deferal level.
+ -- modifying the deferral level.
function Build_B
(Loc : Source_Ptr;
diff --git a/gcc/ada/exp_spark.adb b/gcc/ada/exp_spark.adb
index 75cdbe6..d65136b 100644
--- a/gcc/ada/exp_spark.adb
+++ b/gcc/ada/exp_spark.adb
@@ -52,16 +52,6 @@ package body Exp_SPARK is
-- Local Subprograms --
-----------------------
- procedure Expand_SPARK_Array_Aggregate (N : Node_Id; Index : Node_Id);
- -- Perform array-aggregate-specific expansion of an array sub-aggregate N
- -- corresponding to the Index of the outer-most aggregate. This routine
- -- mimics Resolve_Array_Aggregate which only checks the aggregate for being
- -- well-formed, but doesn't analyze nor apply range checks to
- -- iterated_component_associations.
-
- procedure Expand_SPARK_N_Aggregate (N : Node_Id);
- -- Perform aggregate-specific expansion
-
procedure Expand_SPARK_N_Attribute_Reference (N : Node_Id);
-- Perform attribute-reference-specific expansion
@@ -112,9 +102,6 @@ package body Exp_SPARK is
=>
Qualify_Entity_Names (N);
- when N_Aggregate =>
- Expand_SPARK_N_Aggregate (N);
-
-- Replace occurrences of System'To_Address by calls to
-- System.Storage_Elements.To_Address.
@@ -161,107 +148,6 @@ package body Exp_SPARK is
end Expand_SPARK;
----------------------------------
- -- Expand_SPARK_Array_Aggregate --
- ----------------------------------
-
- procedure Expand_SPARK_Array_Aggregate (N : Node_Id; Index : Node_Id) is
-
- procedure Expand_Aggr_Expr (Expr : Node_Id);
- -- If Expr is a subaggregate, then process it recursively; otherwise it
- -- is an expression for the array components which might not have been
- -- analyzed and where scalar range checks could be missing.
-
- ----------------------
- -- Expand_Aggr_Expr --
- ----------------------
-
- procedure Expand_Aggr_Expr (Expr : Node_Id) is
- Nxt_Ind : constant Node_Id := Next_Index (Index);
- begin
- if Present (Nxt_Ind) then
- Expand_SPARK_Array_Aggregate (Expr, Index => Nxt_Ind);
- else
- declare
- Comp_Type : constant Entity_Id := Component_Type (Etype (N));
- begin
- Analyze_And_Resolve (Expr, Comp_Type);
-
- if Is_Scalar_Type (Comp_Type) then
- Apply_Scalar_Range_Check (Expr, Comp_Type);
- end if;
- end;
- end if;
- end Expand_Aggr_Expr;
-
- -- Local variables
-
- Assoc : Node_Id := First (Component_Associations (N));
-
- -- Start of processing for Expand_SPARK_Array_Aggregate
-
- begin
- while Present (Assoc) loop
- -- For iterated_component_association we must apply range check to
- -- discrete choices and re-analyze the expression, because frontend
- -- only checks its legality and then analyzes the expanded loop code.
-
- if Nkind (Assoc) = N_Iterated_Component_Association then
- declare
- Choice : Node_Id;
- begin
- -- Analyze discrete choices
-
- Choice := First (Discrete_Choices (Assoc));
-
- while Present (Choice) loop
-
- -- The index denotes a range of elements where range checks
- -- have been already applied.
-
- if Nkind (Choice) in N_Others_Choice
- | N_Range
- | N_Subtype_Indication
- then
- null;
-
- -- Otherwise the index denotes a single element (or a
- -- subtype name which doesn't require range checks).
-
- else pragma Assert (Nkind (Choice) in N_Subexpr);
- Apply_Scalar_Range_Check (Choice, Etype (Index));
- end if;
-
- Next (Choice);
- end loop;
-
- -- Keep processing the expression with index parameter in scope
-
- Push_Scope (Scope (Defining_Identifier (Assoc)));
- Enter_Name (Defining_Identifier (Assoc));
- Expand_Aggr_Expr (Expression (Assoc));
- End_Scope;
- end;
-
- -- For ordinary component associations we recurse into subaggregates,
- -- because there could be nested iterated_component_association (and
- -- it is harmless to analyze and apply checks if there is none).
-
- else pragma Assert (Nkind (Assoc) = N_Component_Association);
- declare
- Expr : constant Node_Id := Expression (Assoc);
- pragma Assert (Present (Expr) xor Box_Present (Assoc));
- begin
- if Present (Expr) then
- Expand_Aggr_Expr (Expr);
- end if;
- end;
- end if;
-
- Next (Assoc);
- end loop;
- end Expand_SPARK_Array_Aggregate;
-
- ----------------------------------
-- Expand_SPARK_Delta_Or_Update --
----------------------------------
@@ -471,21 +357,12 @@ package body Exp_SPARK is
-- procedure for it as done during regular expansion for compilation.
if Has_DIC (E) and then Is_Tagged_Type (E) then
- Build_DIC_Procedure_Body (E, For_Freeze => True);
- end if;
- end Expand_SPARK_N_Freeze_Type;
-
- ------------------------------
- -- Expand_SPARK_N_Aggregate --
- ------------------------------
+ -- Why is this needed for DIC, but not for other aspects (such as
+ -- Type_Invariant)???
- procedure Expand_SPARK_N_Aggregate (N : Node_Id) is
- Aggr_Typ : constant Entity_Id := Etype (N);
- begin
- if Is_Array_Type (Aggr_Typ) then
- Expand_SPARK_Array_Aggregate (N, Index => First_Index (Aggr_Typ));
+ Build_DIC_Procedure_Body (E);
end if;
- end Expand_SPARK_N_Aggregate;
+ end Expand_SPARK_N_Freeze_Type;
----------------------------------------
-- Expand_SPARK_N_Attribute_Reference --
@@ -500,101 +377,105 @@ package body Exp_SPARK is
Expr : Node_Id;
begin
- if Attr_Id = Attribute_To_Address then
+ case Attr_Id is
+ when Attribute_To_Address =>
- -- Extract and convert argument to expected type for call
+ -- Extract and convert argument to expected type for call
- Expr :=
- Make_Type_Conversion (Loc,
- Subtype_Mark =>
- New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
- Expression => Relocate_Node (First (Expressions (N))));
+ Expr :=
+ Make_Type_Conversion (Loc,
+ Subtype_Mark =>
+ New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
+ Expression => Relocate_Node (First (Expressions (N))));
- -- Replace attribute reference with call
+ -- Replace attribute reference with call
- Rewrite (N,
- Make_Function_Call (Loc,
- Name =>
- New_Occurrence_Of (RTE (RE_To_Address), Loc),
- Parameter_Associations => New_List (Expr)));
- Analyze_And_Resolve (N, Typ);
-
- 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.
-
- elsif Attr_Id = Attribute_Alignment
- or else Attr_Id = Attribute_Bit
- or else Attr_Id = Attribute_Bit_Position
- or else Attr_Id = Attribute_Descriptor_Size
- or else Attr_Id = Attribute_First_Bit
- or else Attr_Id = Attribute_Last_Bit
- or else Attr_Id = Attribute_Length
- or else Attr_Id = Attribute_Max_Size_In_Storage_Elements
- or else Attr_Id = Attribute_Pos
- or else Attr_Id = Attribute_Position
- or else Attr_Id = Attribute_Range_Length
- or else Attr_Id = Attribute_Aft
- or else Attr_Id = Attribute_Max_Alignment_For_Allocation
- then
- -- If the expected type is Long_Long_Integer, there will be no check
- -- flag as the compiler assumes attributes always fit in this type.
- -- Since in SPARK_Mode we do not take Storage_Error into account, we
- -- cannot make this assumption and need to produce a check.
- -- ??? It should be enough to add this check for attributes
- -- 'Length, 'Range_Length and 'Pos when the type is as big
- -- as Long_Long_Integer.
-
- declare
- Typ : Entity_Id;
- begin
- if Attr_Id = Attribute_Range_Length
- or else Attr_Id = Attribute_Pos
- then
- Typ := Etype (Prefix (N));
+ Rewrite
+ (N,
+ Make_Function_Call (Loc,
+ Name =>
+ New_Occurrence_Of (RTE (RE_To_Address), Loc),
+ Parameter_Associations => New_List (Expr)));
+ Analyze_And_Resolve (N, Typ);
+
+ when Attribute_Object_Size
+ | Attribute_Size
+ | Attribute_Value_Size
+ | Attribute_VADS_Size
+ =>
+ 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.
+
+ when Attribute_Aft
+ | Attribute_Alignment
+ | Attribute_Bit
+ | Attribute_Bit_Position
+ | Attribute_Descriptor_Size
+ | Attribute_First_Bit
+ | Attribute_Last_Bit
+ | Attribute_Length
+ | Attribute_Max_Alignment_For_Allocation
+ | Attribute_Max_Size_In_Storage_Elements
+ | Attribute_Pos
+ | Attribute_Position
+ | Attribute_Range_Length
+ =>
+ -- If the expected type is Long_Long_Integer, there will be no
+ -- check flag as the compiler assumes attributes always fit in
+ -- this type. Since in SPARK_Mode we do not take Storage_Error
+ -- into account, we cannot make this assumption and need to
+ -- produce a check. ??? It should be enough to add this check for
+ -- attributes 'Length, 'Range_Length and 'Pos when the type is as
+ -- big as Long_Long_Integer.
- elsif Attr_Id = Attribute_Length then
- Typ := Get_Index_Subtype (N);
+ declare
+ Typ : Entity_Id;
+ begin
+ if Attr_Id in Attribute_Pos | Attribute_Range_Length then
+ Typ := Etype (Prefix (N));
- else
- Typ := Empty;
- end if;
+ elsif Attr_Id = Attribute_Length then
+ Typ := Get_Index_Subtype (N);
- Apply_Universal_Integer_Attribute_Checks (N);
+ else
+ Typ := Empty;
+ end if;
- if Present (Typ)
- and then RM_Size (Typ) = RM_Size (Standard_Long_Long_Integer)
- then
- -- ??? This should rather be a range check, but this would
- -- crash GNATprove which somehow recovers the proper kind
- -- of check anyway.
- Set_Do_Overflow_Check (N);
- end if;
- end;
+ Apply_Universal_Integer_Attribute_Checks (N);
+
+ if Present (Typ)
+ and then RM_Size (Typ) = RM_Size (Standard_Long_Long_Integer)
+ then
+ -- ??? This should rather be a range check, but this would
+ -- crash GNATprove which somehow recovers the proper kind
+ -- of check anyway.
+ Set_Do_Overflow_Check (N);
+ end if;
+ end;
- elsif Attr_Id = Attribute_Constrained then
+ when Attribute_Constrained =>
- -- If the prefix is an access to object, the attribute applies to
- -- the designated object, so rewrite with an explicit dereference.
+ -- If the prefix is an access to object, the attribute applies to
+ -- the designated object, so rewrite with an explicit dereference.
- if Is_Access_Type (Etype (Pref))
- and then
- (not Is_Entity_Name (Pref) or else Is_Object (Entity (Pref)))
- then
- Rewrite (Pref,
- Make_Explicit_Dereference (Loc, Relocate_Node (Pref)));
- Analyze_And_Resolve (N, Standard_Boolean);
- end if;
+ if Is_Access_Type (Etype (Pref))
+ and then
+ (not Is_Entity_Name (Pref) or else Is_Object (Entity (Pref)))
+ then
+ Rewrite (Pref,
+ Make_Explicit_Dereference (Loc, Relocate_Node (Pref)));
+ Analyze_And_Resolve (N, Standard_Boolean);
+ end if;
- elsif Attr_Id = Attribute_Update then
- Expand_SPARK_Delta_Or_Update (Typ, First (Expressions (N)));
- end if;
+ when Attribute_Update =>
+ Expand_SPARK_Delta_Or_Update (Typ, First (Expressions (N)));
+
+ when others =>
+ null;
+ end case;
end Expand_SPARK_N_Attribute_Reference;
------------------------------------
@@ -652,7 +533,7 @@ package body Exp_SPARK is
and then Present (DIC_Procedure (Typ))
and then not Has_Init_Expression (N)
then
- Call := Build_DIC_Call (Loc, Obj_Id, Typ);
+ Call := Build_DIC_Call (Loc, New_Occurrence_Of (Obj_Id, Loc), Typ);
-- Partially insert the call into the tree by setting its parent
-- pointer.
diff --git a/gcc/ada/exp_strm.adb b/gcc/ada/exp_strm.adb
index 6cda955..09bd872 100644
--- a/gcc/ada/exp_strm.adb
+++ b/gcc/ada/exp_strm.adb
@@ -578,8 +578,11 @@ package body Exp_Strm is
elsif P_Size <= Standard_Long_Integer_Size then
Lib_RE := RE_I_LI;
- else
+ elsif P_Size <= Standard_Long_Long_Integer_Size then
Lib_RE := RE_I_LLI;
+
+ else
+ Lib_RE := RE_I_LLLI;
end if;
-- Unsigned integer types, also includes unsigned fixed-point types
@@ -609,8 +612,11 @@ package body Exp_Strm is
elsif P_Size <= Standard_Long_Integer_Size then
Lib_RE := RE_I_LU;
- else
+ elsif P_Size <= Standard_Long_Long_Integer_Size then
Lib_RE := RE_I_LLU;
+
+ else
+ Lib_RE := RE_I_LLLU;
end if;
else pragma Assert (Is_Access_Type (U_Type));
@@ -802,16 +808,24 @@ package body Exp_Strm is
then
if P_Size <= Standard_Short_Short_Integer_Size then
Lib_RE := RE_W_SSI;
+
elsif P_Size <= Standard_Short_Integer_Size then
Lib_RE := RE_W_SI;
+
elsif P_Size = 24 then
Lib_RE := RE_W_I24;
+
elsif P_Size <= Standard_Integer_Size then
Lib_RE := RE_W_I;
+
elsif P_Size <= Standard_Long_Integer_Size then
Lib_RE := RE_W_LI;
- else
+
+ elsif P_Size <= Standard_Long_Long_Integer_Size then
Lib_RE := RE_W_LLI;
+
+ else
+ Lib_RE := RE_W_LLLI;
end if;
-- Unsigned integer types, also includes unsigned fixed-point types
@@ -828,16 +842,24 @@ package body Exp_Strm is
then
if P_Size <= Standard_Short_Short_Integer_Size then
Lib_RE := RE_W_SSU;
+
elsif P_Size <= Standard_Short_Integer_Size then
Lib_RE := RE_W_SU;
+
elsif P_Size = 24 then
Lib_RE := RE_W_U24;
+
elsif P_Size <= Standard_Integer_Size then
Lib_RE := RE_W_U;
+
elsif P_Size <= Standard_Long_Integer_Size then
Lib_RE := RE_W_LU;
- else
+
+ elsif P_Size <= Standard_Long_Long_Integer_Size then
Lib_RE := RE_W_LLU;
+
+ else
+ Lib_RE := RE_W_LLLU;
end if;
else pragma Assert (Is_Access_Type (U_Type));
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 6b474d8..9e08e9c 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -169,6 +169,16 @@ package body Exp_Util is
-- Determine whether pragma Default_Initial_Condition denoted by Prag has
-- an assertion expression that should be verified at run time.
+ function Is_Uninitialized_Aggregate
+ (Exp : Node_Id;
+ T : Entity_Id) return Boolean;
+ -- Determine whether an array aggregate used in an object declaration
+ -- is uninitialized, when the aggregate is declared with a box and
+ -- the component type has no default value. Such an aggregate can be
+ -- optimized away to prevent the copying of uninitialized data, and
+ -- the bounds of the aggregate can be propagated directly to the
+ -- object declaration.
+
function Make_CW_Equivalent_Type
(T : Entity_Id;
E : Node_Id) return Entity_Id;
@@ -471,9 +481,9 @@ package body Exp_Util is
end if;
end Append_Freeze_Actions;
- --------------------------------------
- -- Attr_Constrained_Statically_True --
- --------------------------------------
+ ----------------------------------------
+ -- Attribute_Constrained_Static_Value --
+ ----------------------------------------
function Attribute_Constrained_Static_Value (Pref : Node_Id) return Boolean
is
@@ -535,7 +545,7 @@ package body Exp_Util is
if Is_Entity_Name (Pref) then
declare
- Ent : constant Entity_Id := Entity (Pref);
+ Ent : constant Entity_Id := Entity (Pref);
Res : Boolean;
begin
@@ -1436,21 +1446,27 @@ package body Exp_Util is
--------------------
function Build_DIC_Call
- (Loc : Source_Ptr;
- Obj_Id : Entity_Id;
- Typ : Entity_Id) return Node_Id
+ (Loc : Source_Ptr;
+ Obj_Name : Node_Id;
+ Typ : Entity_Id) return Node_Id
is
Proc_Id : constant Entity_Id := DIC_Procedure (Typ);
Formal_Typ : constant Entity_Id := Etype (First_Formal (Proc_Id));
begin
+ -- The DIC procedure has a null body if assertions are disabled or
+ -- Assertion_Policy Ignore is in effect. In that case, it would be
+ -- nice to generate a null statement instead of a call to the DIC
+ -- procedure, but doing that seems to interfere with the determination
+ -- of ECRs (early call regions) in SPARK. ???
+
return
Make_Procedure_Call_Statement (Loc,
Name => New_Occurrence_Of (Proc_Id, Loc),
Parameter_Associations => New_List (
Make_Unchecked_Type_Conversion (Loc,
Subtype_Mark => New_Occurrence_Of (Formal_Typ, Loc),
- Expression => New_Occurrence_Of (Obj_Id, Loc))));
+ Expression => Obj_Name)));
end Build_DIC_Call;
------------------------------
@@ -1462,9 +1478,13 @@ package body Exp_Util is
-- Ghost mode.
procedure Build_DIC_Procedure_Body
- (Typ : Entity_Id;
- For_Freeze : Boolean := False)
+ (Typ : Entity_Id;
+ Partial_DIC : Boolean := False)
is
+ Pragmas_Seen : Elist_Id := No_Elist;
+ -- This list contains all DIC pragmas processed so far. The list is used
+ -- to avoid redundant Default_Initial_Condition checks.
+
procedure Add_DIC_Check
(DIC_Prag : Node_Id;
DIC_Expr : Node_Id;
@@ -1484,24 +1504,46 @@ package body Exp_Util is
-- pragma. All generated code is added to list Stmts.
procedure Add_Inherited_Tagged_DIC
- (DIC_Prag : Node_Id;
- Par_Typ : Entity_Id;
- Deriv_Typ : Entity_Id;
- Stmts : in out List_Id);
+ (DIC_Prag : Node_Id;
+ Expr : Node_Id;
+ Stmts : in out List_Id);
-- Add a runtime check to verify assertion expression DIC_Expr of
- -- inherited pragma DIC_Prag. This routine applies class-wide pre- and
- -- postcondition-like runtime semantics to the check. Par_Typ is the
- -- parent type whose DIC pragma is being inherited. Deriv_Typ is the
- -- derived type inheriting the DIC pragma. All generated code is added
- -- to list Stmts.
+ -- inherited pragma DIC_Prag. This routine applies class-wide pre-
+ -- and postcondition-like runtime semantics to the check. Expr is
+ -- the assertion expression after substitition has been performed
+ -- (via Replace_References). All generated code is added to list Stmts.
+
+ procedure Add_Inherited_DICs
+ (T : Entity_Id;
+ Priv_Typ : Entity_Id;
+ Full_Typ : Entity_Id;
+ Obj_Id : Entity_Id;
+ Checks : in out List_Id);
+ -- Generate a DIC check for each inherited Default_Initial_Condition
+ -- coming from all parent types of type T. Priv_Typ and Full_Typ denote
+ -- the partial and full view of the parent type. Obj_Id denotes the
+ -- entity of the _object formal parameter of the DIC procedure. All
+ -- created checks are added to list Checks.
procedure Add_Own_DIC
(DIC_Prag : Node_Id;
DIC_Typ : Entity_Id;
+ Obj_Id : Entity_Id;
Stmts : in out List_Id);
-- Add a runtime check to verify the assertion expression of pragma
- -- DIC_Prag. DIC_Typ is the owner of the DIC pragma. All generated code
- -- is added to list Stmts.
+ -- DIC_Prag. DIC_Typ is the owner of the DIC pragma. Obj_Id is the
+ -- object to substitute in the assertion expression for any references
+ -- to the current instance of the type All generated code is added to
+ -- list Stmts.
+
+ procedure Add_Parent_DICs
+ (T : Entity_Id;
+ Obj_Id : Entity_Id;
+ Checks : in out List_Id);
+ -- Generate a Default_Initial_Condition check for each inherited DIC
+ -- aspect coming from all parent types of type T. Obj_Id denotes the
+ -- entity of the _object formal parameter of the DIC procedure. All
+ -- created checks are added to list Checks.
-------------------
-- Add_DIC_Check --
@@ -1539,6 +1581,10 @@ package body Exp_Util is
Make_Pragma_Argument_Association (Loc,
Expression => DIC_Expr))));
end if;
+
+ -- Add the pragma to the list of processed pragmas
+
+ Append_New_Elmt (DIC_Prag, Pragmas_Seen);
end Add_DIC_Check;
-----------------------
@@ -1580,65 +1626,172 @@ package body Exp_Util is
------------------------------
procedure Add_Inherited_Tagged_DIC
- (DIC_Prag : Node_Id;
- Par_Typ : Entity_Id;
- Deriv_Typ : Entity_Id;
- Stmts : in out List_Id)
+ (DIC_Prag : Node_Id;
+ Expr : Node_Id;
+ Stmts : in out List_Id)
is
- Deriv_Proc : constant Entity_Id := DIC_Procedure (Deriv_Typ);
- DIC_Args : constant List_Id :=
- Pragma_Argument_Associations (DIC_Prag);
- DIC_Arg : constant Node_Id := First (DIC_Args);
- DIC_Expr : constant Node_Id := Expression_Copy (DIC_Arg);
- Par_Proc : constant Entity_Id := DIC_Procedure (Par_Typ);
+ begin
+ -- Once the DIC assertion expression is fully processed, add a check
+ -- to the statements of the DIC procedure.
- Expr : Node_Id;
+ Add_DIC_Check
+ (DIC_Prag => DIC_Prag,
+ DIC_Expr => Expr,
+ Stmts => Stmts);
+ end Add_Inherited_Tagged_DIC;
+
+ ------------------------
+ -- Add_Inherited_DICs --
+ ------------------------
+
+ procedure Add_Inherited_DICs
+ (T : Entity_Id;
+ Priv_Typ : Entity_Id;
+ Full_Typ : Entity_Id;
+ Obj_Id : Entity_Id;
+ Checks : in out List_Id)
+ is
+ Deriv_Typ : Entity_Id;
+ Expr : Node_Id;
+ Prag : Node_Id;
+ Prag_Expr : Node_Id;
+ Prag_Expr_Arg : Node_Id;
+ Prag_Typ : Node_Id;
+ Prag_Typ_Arg : Node_Id;
+
+ Par_Proc : Entity_Id;
+ -- The "partial" invariant procedure of Par_Typ
+
+ Par_Typ : Entity_Id;
+ -- The suitable view of the parent type used in the substitution of
+ -- type attributes.
begin
- -- The processing of an inherited DIC assertion expression starts off
- -- with a copy of the original parent expression where all references
- -- to the parent type have already been replaced with references to
- -- the _object formal parameter of the parent type's DIC procedure.
+ if not Present (Priv_Typ) and then not Present (Full_Typ) then
+ return;
+ end if;
- pragma Assert (Present (DIC_Expr));
- Expr := New_Copy_Tree (DIC_Expr);
+ -- When the type inheriting the class-wide invariant is a concurrent
+ -- type, use the corresponding record type because it contains all
+ -- primitive operations of the concurrent type and allows for proper
+ -- substitution.
- -- Perform the following substitutions:
+ if Is_Concurrent_Type (T) then
+ Deriv_Typ := Corresponding_Record_Type (T);
+ else
+ Deriv_Typ := T;
+ end if;
- -- * Replace a reference to the _object parameter of the parent
- -- type's DIC procedure with a reference to the _object parameter
- -- of the derived types' DIC procedure.
+ pragma Assert (Present (Deriv_Typ));
- -- * Replace a reference to a discriminant of the parent type with
- -- a suitable value from the point of view of the derived type.
+ -- Determine which rep item chain to use. Precedence is given to that
+ -- of the parent type's partial view since it usually carries all the
+ -- class-wide invariants.
- -- * Replace a call to an overridden parent primitive with a call
- -- to the overriding derived type primitive.
+ if Present (Priv_Typ) then
+ Prag := First_Rep_Item (Priv_Typ);
+ else
+ Prag := First_Rep_Item (Full_Typ);
+ end if;
- -- * Replace a call to an inherited parent primitive with a call to
- -- the internally-generated inherited derived type primitive.
+ while Present (Prag) loop
+ if Nkind (Prag) = N_Pragma
+ and then Pragma_Name (Prag) = Name_Default_Initial_Condition
+ then
+ -- Nothing to do if the pragma was already processed
- -- Note that primitives defined in the private part are automatically
- -- handled by the overriding/inheritance mechanism and do not require
- -- an extra replacement pass.
+ if Contains (Pragmas_Seen, Prag) then
+ return;
+ end if;
- pragma Assert (Present (Deriv_Proc) and then Present (Par_Proc));
+ -- Extract arguments of the Default_Initial_Condition pragma
- Replace_References
- (Expr => Expr,
- Par_Typ => Par_Typ,
- Deriv_Typ => Deriv_Typ,
- Par_Obj => First_Formal (Par_Proc),
- Deriv_Obj => First_Formal (Deriv_Proc));
+ Prag_Expr_Arg := First (Pragma_Argument_Associations (Prag));
+ Prag_Expr := Expression_Copy (Prag_Expr_Arg);
- -- Once the DIC assertion expression is fully processed, add a check
- -- to the statements of the DIC procedure.
+ -- Pick up the implicit second argument of the pragma, which
+ -- indicates the type that the pragma applies to.
- Add_DIC_Check
- (DIC_Prag => DIC_Prag,
- DIC_Expr => Expr,
- Stmts => Stmts);
- end Add_Inherited_Tagged_DIC;
+ Prag_Typ_Arg := Next (Prag_Expr_Arg);
+ if Present (Prag_Typ_Arg) then
+ Prag_Typ := Get_Pragma_Arg (Prag_Typ_Arg);
+ else
+ Prag_Typ := Empty;
+ end if;
+
+ -- The pragma applies to the partial view of the parent type
+
+ if Present (Priv_Typ)
+ and then Present (Prag_Typ)
+ and then Entity (Prag_Typ) = Priv_Typ
+ then
+ Par_Typ := Priv_Typ;
+
+ -- The pragma applies to the full view of the parent type
+
+ elsif Present (Full_Typ)
+ and then Present (Prag_Typ)
+ and then Entity (Prag_Typ) = Full_Typ
+ then
+ Par_Typ := Full_Typ;
+
+ -- Otherwise the pragma does not belong to the parent type and
+ -- should not be considered.
+
+ else
+ return;
+ end if;
+
+ -- Substitute references in the DIC expression that are related
+ -- to the partial type with corresponding references related to
+ -- the derived type (call to Replace_References below).
+
+ Expr := New_Copy_Tree (Prag_Expr);
+
+ Par_Proc := Partial_DIC_Procedure (Par_Typ);
+
+ -- If there's not a partial DIC procedure (such as when a
+ -- full type doesn't have its own DIC, but is inherited from
+ -- a type with DIC), get the full DIC procedure.
+
+ if not Present (Par_Proc) then
+ Par_Proc := DIC_Procedure (Par_Typ);
+ end if;
+
+ Replace_References
+ (Expr => Expr,
+ Par_Typ => Par_Typ,
+ Deriv_Typ => Deriv_Typ,
+ Par_Obj => First_Formal (Par_Proc),
+ Deriv_Obj => Obj_Id);
+
+ -- Why are there different actions depending on whether T is
+ -- tagged? Can these be unified? ???
+
+ if Is_Tagged_Type (T) then
+ Add_Inherited_Tagged_DIC
+ (DIC_Prag => Prag,
+ Expr => Expr,
+ Stmts => Checks);
+
+ else
+ Add_Inherited_DIC
+ (DIC_Prag => Prag,
+ Par_Typ => Par_Typ,
+ Deriv_Typ => Deriv_Typ,
+ Stmts => Checks);
+ end if;
+
+ -- Leave as soon as we get a DIC pragma, since we'll visit
+ -- the pragmas of the parents, so will get to any "inherited"
+ -- pragmas that way.
+
+ return;
+ end if;
+
+ Next_Rep_Item (Prag);
+ end loop;
+ end Add_Inherited_DICs;
-----------------
-- Add_Own_DIC --
@@ -1647,6 +1800,7 @@ package body Exp_Util is
procedure Add_Own_DIC
(DIC_Prag : Node_Id;
DIC_Typ : Entity_Id;
+ Obj_Id : Entity_Id;
Stmts : in out List_Id)
is
DIC_Args : constant List_Id :=
@@ -1654,8 +1808,6 @@ package body Exp_Util is
DIC_Arg : constant Node_Id := First (DIC_Args);
DIC_Asp : constant Node_Id := Corresponding_Aspect (DIC_Prag);
DIC_Expr : constant Node_Id := Get_Pragma_Arg (DIC_Arg);
- DIC_Proc : constant Entity_Id := DIC_Procedure (DIC_Typ);
- Obj_Id : constant Entity_Id := First_Formal (DIC_Proc);
-- Local variables
@@ -1712,6 +1864,66 @@ package body Exp_Util is
Stmts => Stmts);
end Add_Own_DIC;
+ ---------------------
+ -- Add_Parent_DICs --
+ ---------------------
+
+ procedure Add_Parent_DICs
+ (T : Entity_Id;
+ Obj_Id : Entity_Id;
+ Checks : in out List_Id)
+ is
+ Dummy_1 : Entity_Id;
+ Dummy_2 : Entity_Id;
+
+ Curr_Typ : Entity_Id;
+ -- The entity of the current type being examined
+
+ Full_Typ : Entity_Id;
+ -- The full view of Par_Typ
+
+ Par_Typ : Entity_Id;
+ -- The entity of the parent type
+
+ Priv_Typ : Entity_Id;
+ -- The partial view of Par_Typ
+
+ begin
+ -- Climb the parent type chain
+
+ Curr_Typ := T;
+ loop
+ -- Do not consider subtypes, as they inherit the DICs from their
+ -- base types.
+
+ Par_Typ := Base_Type (Etype (Base_Type (Curr_Typ)));
+
+ -- Stop the climb once the root of the parent chain is
+ -- reached.
+
+ exit when Curr_Typ = Par_Typ;
+
+ -- Process the DICs of the parent type
+
+ Get_Views (Par_Typ, Priv_Typ, Full_Typ, Dummy_1, Dummy_2);
+
+ -- Only try to inherit a DIC pragma from the parent type Par_Typ
+ -- if it Has_Own_DIC pragma. The loop will proceed up the parent
+ -- chain to find all types that have their own DIC.
+
+ if Has_Own_DIC (Par_Typ) then
+ Add_Inherited_DICs
+ (T => T,
+ Priv_Typ => Priv_Typ,
+ Full_Typ => Full_Typ,
+ Obj_Id => Obj_Id,
+ Checks => Checks);
+ end if;
+
+ Curr_Typ := Par_Typ;
+ end loop;
+ end Add_Parent_DICs;
+
-- Local variables
Loc : constant Source_Ptr := Sloc (Typ);
@@ -1730,8 +1942,20 @@ package body Exp_Util is
Proc_Id : Entity_Id;
Stmts : List_Id := No_List;
- Build_Body : Boolean := False;
- -- Flag set when the type requires a DIC procedure body to be built
+ CRec_Typ : Entity_Id := Empty;
+ -- The corresponding record type of Full_Typ
+
+ Full_Typ : Entity_Id := Empty;
+ -- The full view of the working type
+
+ Obj_Id : Entity_Id := Empty;
+ -- The _object formal parameter of the invariant procedure
+
+ Part_Proc : Entity_Id := Empty;
+ -- The entity of the "partial" invariant procedure
+
+ Priv_Typ : Entity_Id := Empty;
+ -- The partial view of the working type
Work_Typ : Entity_Id;
-- The working type
@@ -1795,25 +2019,41 @@ package body Exp_Util is
goto Leave;
end if;
- -- The working type may lack a DIC procedure declaration. This may be
- -- due to several reasons:
+ -- Obtain both views of the type
+
+ Get_Views (Work_Typ, Priv_Typ, Full_Typ, Dummy_1, CRec_Typ);
+
+ -- The caller requests a body for the partial DIC procedure
+
+ if Partial_DIC then
+ Proc_Id := Partial_DIC_Procedure (Work_Typ);
+
+ -- The "full" DIC procedure body was already created
+
+ -- Create a declaration for the "partial" DIC procedure if it
+ -- is not available.
+
+ if No (Proc_Id) then
+ Build_DIC_Procedure_Declaration
+ (Typ => Work_Typ,
+ Partial_DIC => True);
- -- * The working type's own DIC pragma does not contain a verifiable
- -- assertion expression. In this case there is no need to build a
- -- DIC procedure because there is nothing to check.
+ Proc_Id := Partial_DIC_Procedure (Work_Typ);
+ end if;
- -- * The working type derives from a parent type. In this case a DIC
- -- procedure should be built only when the inherited DIC pragma has
- -- a verifiable assertion expression.
+ -- The caller requests a body for the "full" DIC procedure
- Proc_Id := DIC_Procedure (Work_Typ);
+ else
+ Proc_Id := DIC_Procedure (Work_Typ);
+ Part_Proc := Partial_DIC_Procedure (Work_Typ);
- -- Build a DIC procedure declaration when the working type derives from
- -- a parent type.
+ -- Create a declaration for the "full" DIC procedure if it is
+ -- not available.
- if No (Proc_Id) then
- Build_DIC_Procedure_Declaration (Work_Typ);
- Proc_Id := DIC_Procedure (Work_Typ);
+ if No (Proc_Id) then
+ Build_DIC_Procedure_Declaration (Work_Typ);
+ Proc_Id := DIC_Procedure (Work_Typ);
+ end if;
end if;
-- At this point there should be a DIC procedure declaration
@@ -1833,123 +2073,146 @@ package body Exp_Util is
Push_Scope (Proc_Id);
Install_Formals (Proc_Id);
- -- The working type defines its own DIC pragma. Replace the current
- -- instance of the working type with the formal of the DIC procedure.
- -- Note that there is no need to consider inherited DIC pragmas from
- -- parent types because the working type's DIC pragma "hides" all
- -- inherited DIC pragmas.
+ Obj_Id := First_Formal (Proc_Id);
+ pragma Assert (Present (Obj_Id));
- if Has_Own_DIC (Work_Typ) then
- pragma Assert (DIC_Typ = Work_Typ);
+ -- The "partial" DIC procedure verifies the DICs of the partial view
+ -- only.
- Add_Own_DIC
- (DIC_Prag => DIC_Prag,
- DIC_Typ => DIC_Typ,
- Stmts => Stmts);
+ if Partial_DIC then
+ pragma Assert (Present (Priv_Typ));
- Build_Body := True;
+ if Has_Own_DIC (Work_Typ) then -- If we're testing this then maybe
+ Add_Own_DIC -- we shouldn't be calling Find_DIC_Typ above???
+ (DIC_Prag => DIC_Prag,
+ DIC_Typ => DIC_Typ, -- Should this just be Work_Typ???
+ Obj_Id => Obj_Id,
+ Stmts => Stmts);
+ end if;
- -- Otherwise the working type inherits a DIC pragma from a parent type.
- -- This processing is carried out when the type is frozen because the
- -- state of all parent discriminants is known at that point. Note that
- -- it is semantically sound to delay the creation of the DIC procedure
- -- body till the freeze point. If the type has a DIC pragma of its own,
- -- then the DIC procedure body would have already been constructed at
- -- the end of the visible declarations and all parent DIC pragmas are
- -- effectively "hidden" and irrelevant.
+ -- Otherwise the "full" DIC procedure verifies the DICs of the full
+ -- view, well as DICs inherited from parent types. In addition, it
+ -- indirectly verifies the DICs of the partial view by calling the
+ -- "partial" DIC procedure.
- elsif For_Freeze then
- pragma Assert (Has_Inherited_DIC (Work_Typ));
- pragma Assert (DIC_Typ /= Work_Typ);
+ else
+ pragma Assert (Present (Full_Typ));
- -- The working type is tagged. The verification of the assertion
- -- expression is subject to the same semantics as class-wide pre-
- -- and postconditions.
+ -- Check the DIC of the partial view by calling the "partial" DIC
+ -- procedure, unless the partial DIC body is empty. Generate:
- if Is_Tagged_Type (Work_Typ) then
- Add_Inherited_Tagged_DIC
- (DIC_Prag => DIC_Prag,
- Par_Typ => DIC_Typ,
- Deriv_Typ => Work_Typ,
- Stmts => Stmts);
+ -- <Work_Typ>Partial_DIC (_object);
- -- Otherwise the working type is not tagged. Verify the assertion
- -- expression of the inherited DIC pragma by directly calling the
- -- DIC procedure of the parent type.
+ if Present (Part_Proc) and then not Has_Null_Body (Part_Proc) then
+ Append_New_To (Stmts,
+ Make_Procedure_Call_Statement (Loc,
+ Name => New_Occurrence_Of (Part_Proc, Loc),
+ Parameter_Associations => New_List (
+ New_Occurrence_Of (Obj_Id, Loc))));
+ end if;
- else
- Add_Inherited_DIC
- (DIC_Prag => DIC_Prag,
- Par_Typ => DIC_Typ,
- Deriv_Typ => Work_Typ,
- Stmts => Stmts);
+ -- Derived subtypes do not have a partial view
+
+ if Present (Priv_Typ) then
+
+ -- The processing of the "full" DIC procedure intentionally
+ -- skips the partial view because a) this may result in changes of
+ -- visibility and b) lead to duplicate checks. However, when the
+ -- full view is the underlying full view of an untagged derived
+ -- type whose parent type is private, partial DICs appear on
+ -- the rep item chain of the partial view only.
+
+ -- package Pack_1 is
+ -- type Root ... is private;
+ -- private
+ -- <full view of Root>
+ -- end Pack_1;
+
+ -- with Pack_1;
+ -- package Pack_2 is
+ -- type Child is new Pack_1.Root with Type_DIC => ...;
+ -- <underlying full view of Child>
+ -- end Pack_2;
+
+ -- As a result, the processing of the full view must also consider
+ -- all DICs of the partial view.
+
+ if Is_Untagged_Private_Derivation (Priv_Typ, Full_Typ) then
+ null;
+
+ -- Otherwise the DICs of the partial view are ignored
+
+ else
+ -- Ignore the DICs of the partial view by eliminating the view
+
+ Priv_Typ := Empty;
+ end if;
end if;
- Build_Body := True;
+ -- Process inherited Default_Initial_Conditions for all parent types
+
+ Add_Parent_DICs (Work_Typ, Obj_Id, Stmts);
end if;
End_Scope;
- if Build_Body then
+ -- Produce an empty completing body in the following cases:
+ -- * Assertions are disabled
+ -- * The DIC Assertion_Policy is Ignore
- -- Produce an empty completing body in the following cases:
- -- * Assertions are disabled
- -- * The DIC Assertion_Policy is Ignore
+ if No (Stmts) then
+ Stmts := New_List (Make_Null_Statement (Loc));
+ end if;
- if No (Stmts) then
- Stmts := New_List (Make_Null_Statement (Loc));
- end if;
+ -- Generate:
+ -- procedure <Work_Typ>DIC (_object : <Work_Typ>) is
+ -- begin
+ -- <Stmts>
+ -- end <Work_Typ>DIC;
- -- Generate:
- -- procedure <Work_Typ>DIC (_object : <Work_Typ>) is
- -- begin
- -- <Stmts>
- -- end <Work_Typ>DIC;
-
- Proc_Body :=
- Make_Subprogram_Body (Loc,
- Specification =>
- Copy_Subprogram_Spec (Parent (Proc_Id)),
- Declarations => Empty_List,
- Handled_Statement_Sequence =>
- Make_Handled_Sequence_Of_Statements (Loc,
- Statements => Stmts));
- Proc_Body_Id := Defining_Entity (Proc_Body);
-
- -- Perform minor decoration in case the body is not analyzed
-
- Set_Ekind (Proc_Body_Id, E_Subprogram_Body);
- Set_Etype (Proc_Body_Id, Standard_Void_Type);
- Set_Scope (Proc_Body_Id, Current_Scope);
- Set_SPARK_Pragma (Proc_Body_Id, SPARK_Pragma (Proc_Id));
- Set_SPARK_Pragma_Inherited
- (Proc_Body_Id, SPARK_Pragma_Inherited (Proc_Id));
-
- -- Link both spec and body to avoid generating duplicates
-
- Set_Corresponding_Body (Proc_Decl, Proc_Body_Id);
- Set_Corresponding_Spec (Proc_Body, Proc_Id);
-
- -- The body should not be inserted into the tree when the context
- -- is a generic unit because it is not part of the template.
- -- Note that the body must still be generated in order to resolve the
- -- DIC assertion expression.
-
- if Inside_A_Generic then
- null;
+ Proc_Body :=
+ Make_Subprogram_Body (Loc,
+ Specification =>
+ Copy_Subprogram_Spec (Parent (Proc_Id)),
+ Declarations => Empty_List,
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => Stmts));
+ Proc_Body_Id := Defining_Entity (Proc_Body);
- -- Semi-insert the body into the tree for GNATprove by setting its
- -- Parent field. This allows for proper upstream tree traversals.
+ -- Perform minor decoration in case the body is not analyzed
- elsif GNATprove_Mode then
- Set_Parent (Proc_Body, Parent (Declaration_Node (Work_Typ)));
+ Set_Ekind (Proc_Body_Id, E_Subprogram_Body);
+ Set_Etype (Proc_Body_Id, Standard_Void_Type);
+ Set_Scope (Proc_Body_Id, Current_Scope);
+ Set_SPARK_Pragma (Proc_Body_Id, SPARK_Pragma (Proc_Id));
+ Set_SPARK_Pragma_Inherited
+ (Proc_Body_Id, SPARK_Pragma_Inherited (Proc_Id));
- -- Otherwise the body is part of the freezing actions of the working
- -- type.
+ -- Link both spec and body to avoid generating duplicates
- else
- Append_Freeze_Action (Work_Typ, Proc_Body);
- end if;
+ Set_Corresponding_Body (Proc_Decl, Proc_Body_Id);
+ Set_Corresponding_Spec (Proc_Body, Proc_Id);
+
+ -- The body should not be inserted into the tree when the context
+ -- is a generic unit because it is not part of the template.
+ -- Note that the body must still be generated in order to resolve the
+ -- DIC assertion expression.
+
+ if Inside_A_Generic then
+ null;
+
+ -- Semi-insert the body into the tree for GNATprove by setting its
+ -- Parent field. This allows for proper upstream tree traversals.
+
+ elsif GNATprove_Mode then
+ Set_Parent (Proc_Body, Parent (Declaration_Node (Work_Typ)));
+
+ -- Otherwise the body is part of the freezing actions of the working
+ -- type.
+
+ else
+ Append_Freeze_Action (Work_Typ, Proc_Body);
end if;
<<Leave>>
@@ -1964,7 +2227,10 @@ package body Exp_Util is
-- replaced by gotos which jump to the end of the routine and restore the
-- Ghost mode.
- procedure Build_DIC_Procedure_Declaration (Typ : Entity_Id) is
+ procedure Build_DIC_Procedure_Declaration
+ (Typ : Entity_Id;
+ Partial_DIC : Boolean := False)
+ is
Loc : constant Source_Ptr := Sloc (Typ);
Saved_GM : constant Ghost_Mode_Type := Ghost_Mode;
@@ -1975,6 +2241,7 @@ package body Exp_Util is
DIC_Typ : Entity_Id;
Proc_Decl : Node_Id;
Proc_Id : Entity_Id;
+ Proc_Nam : Name_Id;
Typ_Decl : Node_Id;
CRec_Typ : Entity_Id;
@@ -2050,17 +2317,35 @@ package body Exp_Util is
if not Is_Verifiable_DIC_Pragma (DIC_Prag) then
goto Leave;
+ end if;
+
+ -- Nothing to do if the type already has a "partial" DIC procedure
+
+ if Partial_DIC then
+ if Present (Partial_DIC_Procedure (Work_Typ)) then
+ goto Leave;
+ end if;
- -- Nothing to do if the type already has a DIC procedure
+ -- Nothing to do if the type already has a "full" DIC procedure
elsif Present (DIC_Procedure (Work_Typ)) then
goto Leave;
end if;
+ -- The caller requests the declaration of the "partial" DIC procedure
+
+ if Partial_DIC then
+ Proc_Nam := New_External_Name (Chars (Work_Typ), "Partial_DIC");
+
+ -- Otherwise the caller requests the declaration of the "full" DIC
+ -- procedure.
+
+ else
+ Proc_Nam := New_External_Name (Chars (Work_Typ), "DIC");
+ end if;
+
Proc_Id :=
- Make_Defining_Identifier (Loc,
- Chars =>
- New_External_Name (Chars (Work_Typ), "Default_Initial_Condition"));
+ Make_Defining_Identifier (Loc, Chars => Proc_Nam);
-- Perform minor decoration in case the declaration is not analyzed
@@ -3702,12 +3987,10 @@ package body Exp_Util is
-- Add an extra out parameter to carry the function result
- Name_Len := 6;
- Name_Buffer (1 .. Name_Len) := "RESULT";
Append_To (Proc_Formals,
Make_Parameter_Specification (Loc,
Defining_Identifier =>
- Make_Defining_Identifier (Loc, Chars => Name_Find),
+ Make_Defining_Identifier (Loc, Name_UP_RESULT),
Out_Present => True,
Parameter_Type => New_Occurrence_Of (Etype (Subp), Loc)));
@@ -5337,7 +5620,7 @@ package body Exp_Util is
then
null;
- -- For limited objects initialized with build in place function calls,
+ -- For limited objects initialized with build-in-place function calls,
-- nothing to be done; otherwise we prematurely introduce an N_Reference
-- node in the expression initializing the object, which breaks the
-- circuitry that detects and adds the additional arguments to the
@@ -5346,6 +5629,17 @@ package body Exp_Util is
elsif Is_Build_In_Place_Function_Call (Exp) then
null;
+ -- If the expression is an uninitialized aggregate, no need to build
+ -- a subtype from the expression, because this may require the use of
+ -- dynamic memory to create the object.
+
+ elsif Is_Uninitialized_Aggregate (Exp, Exp_Typ) then
+ Rewrite (Subtype_Indic, New_Occurrence_Of (Etype (Exp), Sloc (N)));
+ if Nkind (N) = N_Object_Declaration then
+ Set_Expression (N, Empty);
+ Set_No_Initialization (N);
+ end if;
+
else
Remove_Side_Effects (Exp);
Rewrite (Subtype_Indic,
@@ -6341,6 +6635,17 @@ package body Exp_Util is
return;
end if;
+ -- In GNATprove mode we don't want to use current value optimizer, in
+ -- particular for loop invariant expressions and other assertions that
+ -- act as cut points for proof. The optimizer often folds expressions
+ -- into True/False where they trivially follow from the previous
+ -- assignments, but this deprives proof from the information needed to
+ -- discharge checks that are beyond the scope of the value optimizer.
+
+ if GNATprove_Mode then
+ return;
+ end if;
+
-- Otherwise examine current value
declare
@@ -6567,7 +6872,7 @@ package body Exp_Util is
if Has_Stream_Size_Clause (E) then
return Static_Integer (Expression (Stream_Size_Clause (E)));
- -- Otherwise the Stream_Size if the size of the type
+ -- Otherwise the Stream_Size is the size of the type
else
return Esize (E);
@@ -7854,6 +8159,10 @@ package body Exp_Util is
-- is in the process of being iterated in the statement list starting
-- from First_Stmt.
+ function Is_Part_Of_BIP_Return_Statement (N : Node_Id) return Boolean;
+ -- Return True if N is directly part of a build-in-place return
+ -- statement.
+
---------------------------
-- Initialized_By_Access --
---------------------------
@@ -8183,6 +8492,35 @@ package body Exp_Util is
return False;
end Is_Iterated_Container;
+ -------------------------------------
+ -- Is_Part_Of_BIP_Return_Statement --
+ -------------------------------------
+
+ function Is_Part_Of_BIP_Return_Statement (N : Node_Id) return Boolean is
+ Subp : constant Entity_Id := Current_Subprogram;
+ Context : Node_Id;
+ begin
+ -- First check if N is part of a BIP function
+
+ if No (Subp)
+ or else not Is_Build_In_Place_Function (Subp)
+ then
+ return False;
+ end if;
+
+ -- Then check whether N is a complete part of a return statement
+ -- Should we consider other node kinds to go up the tree???
+
+ Context := N;
+ loop
+ case Nkind (Context) is
+ when N_Expression_With_Actions => Context := Parent (Context);
+ when N_Simple_Return_Statement => return True;
+ when others => return False;
+ end case;
+ end loop;
+ end Is_Part_Of_BIP_Return_Statement;
+
-- Local variables
Desig : Entity_Id := Obj_Typ;
@@ -8201,6 +8539,7 @@ package body Exp_Util is
and then Needs_Finalization (Desig)
and then Requires_Transient_Scope (Desig)
and then Nkind (Rel_Node) /= N_Simple_Return_Statement
+ and then not Is_Part_Of_BIP_Return_Statement (Rel_Node)
-- Do not consider a transient object that was already processed
@@ -8220,9 +8559,8 @@ package body Exp_Util is
-- initialized by a function that returns a pointer or acts as a
-- renaming of another pointer.
- and then
- (not Is_Access_Type (Obj_Typ)
- or else not Initialized_By_Access (Obj_Id))
+ and then not
+ (Is_Access_Type (Obj_Typ) and then Initialized_By_Access (Obj_Id))
-- Do not consider transient objects which act as indirect aliases
-- of build-in-place function results.
@@ -8761,6 +9099,47 @@ package body Exp_Util is
and then Etype (Expression (Expr)) = RTE (RE_Tag);
end Is_Tag_To_Class_Wide_Conversion;
+ --------------------------------
+ -- Is_Uninitialized_Aggregate --
+ --------------------------------
+
+ function Is_Uninitialized_Aggregate
+ (Exp : Node_Id;
+ T : Entity_Id) return Boolean
+ is
+ Comp : Node_Id;
+ Comp_Type : Entity_Id;
+ Typ : Entity_Id;
+
+ begin
+ if Nkind (Exp) /= N_Aggregate then
+ return False;
+ end if;
+
+ Preanalyze_And_Resolve (Exp, T);
+ Typ := Etype (Exp);
+
+ if No (Typ)
+ or else Ekind (Typ) /= E_Array_Subtype
+ or else Present (Expressions (Exp))
+ or else No (Component_Associations (Exp))
+ then
+ return False;
+ else
+ Comp_Type := Component_Type (Typ);
+ Comp := First (Component_Associations (Exp));
+
+ if not Box_Present (Comp)
+ or else Present (Next (Comp))
+ then
+ return False;
+ end if;
+
+ return Is_Scalar_Type (Comp_Type)
+ and then No (Default_Aspect_Component_Value (Typ));
+ end if;
+ end Is_Uninitialized_Aggregate;
+
----------------------------
-- Is_Untagged_Derivation --
----------------------------
@@ -8804,6 +9183,13 @@ package body Exp_Util is
return
Present (Args)
+
+ -- If there are args, but the first arg is Empty, then treat the
+ -- pragma the same as having no args (there may be a second arg that
+ -- is an implicitly added type arg, and Empty is a placeholder).
+
+ and then Present (Get_Pragma_Arg (First (Args)))
+
and then Nkind (Get_Pragma_Arg (First (Args))) /= N_Null;
end Is_Verifiable_DIC_Pragma;
@@ -11091,6 +11477,12 @@ package body Exp_Util is
-- otherwise it generates an internal temporary. The created temporary
-- entity is marked as internal.
+ function Possible_Side_Effect_In_SPARK (Exp : Node_Id) return Boolean;
+ -- Computes whether a side effect is possible in SPARK, which should
+ -- be handled by removing it from the expression for GNATprove. Note
+ -- that other side effects related to volatile variables are handled
+ -- separately.
+
---------------------
-- Build_Temporary --
---------------------
@@ -11126,6 +11518,26 @@ package body Exp_Util is
return Temp_Id;
end Build_Temporary;
+ -----------------------------------
+ -- Possible_Side_Effect_In_SPARK --
+ -----------------------------------
+
+ function Possible_Side_Effect_In_SPARK (Exp : Node_Id) return Boolean is
+ begin
+ -- Side-effect removal in SPARK should only occur when not inside a
+ -- generic and not doing a preanalysis, inside an object renaming or
+ -- a type declaration or a for-loop iteration scheme.
+
+ return not Inside_A_Generic
+ and then Full_Analysis
+ and then Nkind (Enclosing_Declaration (Exp)) in
+ N_Full_Type_Declaration
+ | N_Iterator_Specification
+ | N_Loop_Parameter_Specification
+ | N_Object_Renaming_Declaration
+ | N_Subtype_Declaration;
+ end Possible_Side_Effect_In_SPARK;
+
-- Local variables
Loc : constant Source_Ptr := Sloc (Exp);
@@ -11143,11 +11555,11 @@ package body Exp_Util is
begin
-- Handle cases in which there is nothing to do. In GNATprove mode,
-- removal of side effects is useful for the light expansion of
- -- renamings. This removal should only occur when not inside a
- -- generic and not doing a preanalysis.
+ -- renamings.
if not Expander_Active
- and (Inside_A_Generic or not Full_Analysis or not GNATprove_Mode)
+ and then not
+ (GNATprove_Mode and then Possible_Side_Effect_In_SPARK (Exp))
then
return;
@@ -11185,14 +11597,6 @@ package body Exp_Util is
and then Is_Class_Wide_Type (Etype (Exp))
then
return;
-
- -- An expression which is in SPARK mode is considered side effect free
- -- if the resulting value is captured by a variable or a constant.
-
- elsif GNATprove_Mode
- and then Nkind (Parent (Exp)) = N_Object_Declaration
- then
- return;
end if;
-- The remaining processing is done with all checks suppressed
@@ -12288,8 +12692,7 @@ package body Exp_Util is
if Is_Ignored_Ghost_Entity (Typ) then
null;
- elsif ((Is_Access_Type (Typ)
- and then not Is_Access_Subprogram_Type (Typ)
+ elsif ((Is_Access_Object_Type (Typ)
and then Needs_Finalization
(Available_View (Designated_Type (Typ))))
or else (Is_Type (Typ) and then Needs_Finalization (Typ)))
diff --git a/gcc/ada/exp_util.ads b/gcc/ada/exp_util.ads
index 37eb86f..202ac3c 100644
--- a/gcc/ada/exp_util.ads
+++ b/gcc/ada/exp_util.ads
@@ -293,23 +293,29 @@ package Exp_Util is
-- type is frozen.
function Build_DIC_Call
- (Loc : Source_Ptr;
- Obj_Id : Entity_Id;
- Typ : Entity_Id) return Node_Id;
- -- Build a call to the DIC procedure of type Typ with Obj_Id as the actual
+ (Loc : Source_Ptr;
+ Obj_Name : Node_Id;
+ Typ : Entity_Id) return Node_Id;
+ -- Build a call to the DIC procedure for Typ with Obj_Name as the actual
-- parameter.
procedure Build_DIC_Procedure_Body
- (Typ : Entity_Id;
- For_Freeze : Boolean := False);
+ (Typ : Entity_Id;
+ Partial_DIC : Boolean := False);
-- Create the body of the procedure which verifies the assertion expression
- -- of pragma Default_Initial_Condition at run time. Flag For_Freeze should
- -- be set when the body is constructed as part of the freezing actions for
- -- Typ.
-
- procedure Build_DIC_Procedure_Declaration (Typ : Entity_Id);
+ -- of pragma Default_Initial_Condition at run time. Partial_DIC indicates
+ -- that a partial DIC-checking procedure body should be built, for checking
+ -- a DIC associated with the type's partial view, and which will be called
+ -- by the main DIC procedure.
+
+ procedure Build_DIC_Procedure_Declaration
+ (Typ : Entity_Id;
+ Partial_DIC : Boolean := False);
-- Create the declaration of the procedure which verifies the assertion
- -- expression of pragma Default_Initial_Condition at run time.
+ -- expression of pragma Default_Initial_Condition at run time. Partial_DIC
+ -- indicates that a partial DIC-checking procedure should be declared,
+ -- for checking a DIC associated with the type's partial view, and which
+ -- will be called by the main DIC procedure.
procedure Build_Invariant_Procedure_Body
(Typ : Entity_Id;
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index 0779165..098b117 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -182,12 +182,6 @@ package body Freeze is
-- the designated type. Otherwise freezing the access type does not freeze
-- the designated type.
- function Is_Uninitialized_Aggregate (N : Node_Id) return Boolean;
- -- Determine whether an array aggregate used in an object declaration
- -- is uninitialized, when the aggregate is declared with a box and
- -- the component type has no default value. Such an aggregate can be
- -- optimized away and prevent the copying of uninitialized data.
-
procedure Process_Default_Expressions
(E : Entity_Id;
After : in out Node_Id);
@@ -727,12 +721,6 @@ package body Freeze is
if Present (Init)
and then not Is_Limited_View (Typ)
then
- if Is_Uninitialized_Aggregate (Init) then
- Init := Empty;
- Set_No_Initialization (Decl);
- return;
- end if;
-
-- Capture initialization value at point of declaration, and make
-- explicit assignment legal, because object may be a constant.
@@ -2007,7 +1995,7 @@ package body Freeze is
| N_Task_Body
| N_Body_Stub
and then
- List_Containing (After) = List_Containing (Parent (E))
+ In_Same_List (After, Parent (E))
then
Error_Msg_Sloc := Sloc (Next (After));
Error_Msg_NE
@@ -2606,13 +2594,6 @@ package body Freeze is
and then not GNATprove_Mode
then
Set_Has_Own_Invariants (Arr);
-
- -- The array type is an implementation base type. Propagate the
- -- same property to the first subtype.
-
- if Is_Itype (Arr) then
- Set_Has_Own_Invariants (First_Subtype (Arr));
- end if;
end if;
-- Warn for pragma Pack overriding foreign convention
@@ -6358,35 +6339,6 @@ package body Freeze is
if Is_Fixed_Point_Type (E) then
Freeze_Fixed_Point_Type (E);
- -- Some error checks required for ordinary fixed-point type. Defer
- -- these till the freeze-point since we need the small and range
- -- values. We only do these checks for base types
-
- if Is_Ordinary_Fixed_Point_Type (E) and then Is_Base_Type (E) then
- if Small_Value (E) < Ureal_2_M_80 then
- Error_Msg_Name_1 := Name_Small;
- Error_Msg_N
- ("`&''%` too small, minimum allowed is 2.0'*'*(-80)", E);
-
- elsif Small_Value (E) > Ureal_2_80 then
- Error_Msg_Name_1 := Name_Small;
- Error_Msg_N
- ("`&''%` too large, maximum allowed is 2.0'*'*80", E);
- end if;
-
- if Expr_Value_R (Type_Low_Bound (E)) < Ureal_M_10_36 then
- Error_Msg_Name_1 := Name_First;
- Error_Msg_N
- ("`&''%` too small, minimum allowed is -10.0'*'*36", E);
- end if;
-
- if Expr_Value_R (Type_High_Bound (E)) > Ureal_10_36 then
- Error_Msg_Name_1 := Name_Last;
- Error_Msg_N
- ("`&''%` too large, maximum allowed is 10.0'*'*36", E);
- end if;
- end if;
-
elsif Is_Enumeration_Type (E) then
Freeze_Enumeration_Type (E);
@@ -6403,8 +6355,7 @@ package body Freeze is
-- to subprogram and to internal types generated for 'Access
-- references.
- elsif Is_Access_Type (E)
- and then not Is_Access_Subprogram_Type (E)
+ elsif Is_Access_Object_Type (E)
and then Ekind (E) /= E_Access_Attribute_Type
then
-- If a pragma Default_Storage_Pool applies, and this type has no
@@ -8143,6 +8094,12 @@ package body Freeze is
-- Returns size of type with given bounds. Also leaves these
-- bounds set as the current bounds of the Typ.
+ function Larger (A, B : Ureal) return Boolean;
+ -- Returns true if A > B with a margin of Typ'Small
+
+ function Smaller (A, B : Ureal) return Boolean;
+ -- Returns true if A < B with a margin of Typ'Small
+
-----------
-- Fsize --
-----------
@@ -8154,6 +8111,24 @@ package body Freeze is
return Minimum_Size (Typ);
end Fsize;
+ ------------
+ -- Larger --
+ ------------
+
+ function Larger (A, B : Ureal) return Boolean is
+ begin
+ return A > B and then A - Small > B;
+ end Larger;
+
+ -------------
+ -- Smaller --
+ -------------
+
+ function Smaller (A, B : Ureal) return Boolean is
+ begin
+ return A < B and then A + Small < B;
+ end Smaller;
+
-- Start of processing for Freeze_Fixed_Point_Type
begin
@@ -8175,7 +8150,7 @@ package body Freeze is
if Present (Atype) then
Set_Esize (Typ, Esize (Atype));
else
- Set_Esize (Typ, Esize (Base_Type (Typ)));
+ Set_Esize (Typ, Esize (Btyp));
end if;
end if;
@@ -8455,6 +8430,111 @@ package body Freeze is
Set_Realval (Hi, Actual_Hi);
end Fudge;
+ -- Enforce some limitations for ordinary fixed-point types. They come
+ -- from an exact algorithm used to implement Text_IO.Fixed_IO and the
+ -- Fore, Image and Value attributes. The requirement on the Small is
+ -- to lie in the range 2**(-(Siz - 1)) .. 2**(Siz - 1) for a type of
+ -- Siz bits (Siz=32,64,128) and the requirement on the bounds is to
+ -- be smaller in magnitude than 10.0**N * 2**(Siz - 1), where N is
+ -- given by the formula N = floor ((Siz - 1) * log 2 / log 10).
+
+ -- If the bounds of a 32-bit type are too large, force 64-bit type
+
+ if Actual_Size <= 32
+ and then Small <= Ureal_2_31
+ and then (Smaller (Expr_Value_R (Lo), Ureal_M_2_10_18)
+ or else Larger (Expr_Value_R (Hi), Ureal_2_10_18))
+ then
+ Actual_Size := 33;
+ end if;
+
+ -- If the bounds of a 64-bit type are too large, force 128-bit type
+
+ if System_Max_Integer_Size = 128
+ and then Actual_Size <= 64
+ and then Small <= Ureal_2_63
+ and then (Smaller (Expr_Value_R (Lo), Ureal_M_9_10_36)
+ or else Larger (Expr_Value_R (Hi), Ureal_9_10_36))
+ then
+ Actual_Size := 65;
+ end if;
+
+ -- Give error messages for first subtypes and not base types, as the
+ -- bounds of base types are always maximum for their size, see below.
+
+ if System_Max_Integer_Size < 128 and then Typ /= Btyp then
+
+ -- See the 128-bit case below for the reason why we cannot test
+ -- against the 2**(-63) .. 2**63 range. This quirk should have
+ -- been kludged around as in the 128-bit case below, but it was
+ -- not and we end up with a ludicrous range as a result???
+
+ if Small < Ureal_2_M_80 then
+ Error_Msg_Name_1 := Name_Small;
+ Error_Msg_N
+ ("`&''%` too small, minimum allowed is 2.0'*'*(-80)", Typ);
+
+ elsif Small > Ureal_2_80 then
+ Error_Msg_Name_1 := Name_Small;
+ Error_Msg_N
+ ("`&''%` too large, maximum allowed is 2.0'*'*80", Typ);
+ end if;
+
+ if Smaller (Expr_Value_R (Lo), Ureal_M_9_10_36) then
+ Error_Msg_Name_1 := Name_First;
+ Error_Msg_N
+ ("`&''%` too small, minimum allowed is -9.0E+36", Typ);
+ end if;
+
+ if Larger (Expr_Value_R (Hi), Ureal_9_10_36) then
+ Error_Msg_Name_1 := Name_Last;
+ Error_Msg_N
+ ("`&''%` too large, maximum allowed is 9.0E+36", Typ);
+ end if;
+
+ elsif System_Max_Integer_Size = 128 and then Typ /= Btyp then
+
+ -- ACATS c35902d tests a delta equal to 2**(-(Max_Mantissa + 1))
+ -- but we cannot really support anything smaller than Fine_Delta
+ -- because of the way we implement I/O for fixed point types???
+
+ if Small = Ureal_2_M_128 then
+ null;
+
+ elsif Small < Ureal_2_M_127 then
+ Error_Msg_Name_1 := Name_Small;
+ Error_Msg_N
+ ("`&''%` too small, minimum allowed is 2.0'*'*(-127)", Typ);
+
+ elsif Small > Ureal_2_127 then
+ Error_Msg_Name_1 := Name_Small;
+ Error_Msg_N
+ ("`&''%` too large, maximum allowed is 2.0'*'*127", Typ);
+ end if;
+
+ if Actual_Size > 64
+ and then (Norm_Num (Small) > Uint_2 ** 127
+ or else Norm_Den (Small) > Uint_2 ** 127)
+ and then Small /= Ureal_2_M_128
+ then
+ Error_Msg_Name_1 := Name_Small;
+ Error_Msg_N
+ ("`&''%` not the ratio of two 128-bit integers", Typ);
+ end if;
+
+ if Smaller (Expr_Value_R (Lo), Ureal_M_10_76) then
+ Error_Msg_Name_1 := Name_First;
+ Error_Msg_N
+ ("`&''%` too small, minimum allowed is -1.0E+76", Typ);
+ end if;
+
+ if Larger (Expr_Value_R (Hi), Ureal_10_76) then
+ Error_Msg_Name_1 := Name_Last;
+ Error_Msg_N
+ ("`&''%` too large, maximum allowed is 1.0E+76", Typ);
+ end if;
+ end if;
+
-- For the decimal case, none of this fudging is required, since there
-- are no end-point problems in the decimal case (the end-points are
-- always included).
@@ -8466,12 +8546,13 @@ package body Freeze is
-- At this stage, the actual size has been calculated and the proper
-- required bounds are stored in the low and high bounds.
- if Actual_Size > 64 then
+ if Actual_Size > System_Max_Integer_Size then
Error_Msg_Uint_1 := UI_From_Int (Actual_Size);
+ Error_Msg_Uint_2 := UI_From_Int (System_Max_Integer_Size);
Error_Msg_N
- ("size required (^) for type& too large, maximum allowed is 64",
+ ("size required (^) for type& too large, maximum allowed is ^",
Typ);
- Actual_Size := 64;
+ Actual_Size := System_Max_Integer_Size;
end if;
-- Check size against explicit given size
@@ -8497,8 +8578,10 @@ package body Freeze is
Actual_Size := 16;
elsif Actual_Size <= 32 then
Actual_Size := 32;
- else
+ elsif Actual_Size <= 64 then
Actual_Size := 64;
+ else
+ Actual_Size := 128;
end if;
Init_Esize (Typ, Actual_Size);
@@ -8509,7 +8592,7 @@ package body Freeze is
-- the full width of the allocated size in bits, to avoid junk range
-- checks on intermediate computations.
- if Base_Type (Typ) = Typ then
+ if Typ = Btyp then
Set_Realval (Lo, -(Small * (Uint_2 ** (Actual_Size - 1))));
Set_Realval (Hi, (Small * (Uint_2 ** (Actual_Size - 1) - 1)));
end if;
@@ -9153,40 +9236,6 @@ package body Freeze is
end if;
end Freeze_Subprogram;
- --------------------------------
- -- Is_Uninitialized_Aggregate --
- --------------------------------
-
- function Is_Uninitialized_Aggregate (N : Node_Id) return Boolean is
- Aggr : constant Node_Id := Original_Node (N);
- Typ : constant Entity_Id := Etype (Aggr);
-
- Comp : Node_Id;
- Comp_Type : Entity_Id;
- begin
- if Nkind (Aggr) /= N_Aggregate
- or else No (Typ)
- or else Ekind (Typ) /= E_Array_Type
- or else Present (Expressions (Aggr))
- or else No (Component_Associations (Aggr))
- then
- return False;
- else
- Comp_Type := Component_Type (Typ);
- Comp := First (Component_Associations (Aggr));
-
- if not Box_Present (Comp)
- or else Present (Next (Comp))
- then
- return False;
- end if;
-
- return Is_Scalar_Type (Comp_Type)
- and then No (Default_Aspect_Component_Value (Typ))
- and then No (Default_Aspect_Value (Comp_Type));
- end if;
- end Is_Uninitialized_Aggregate;
-
----------------------
-- Is_Fully_Defined --
----------------------
diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in
index 78fe602..89b5750 100644
--- a/gcc/ada/gcc-interface/Make-lang.in
+++ b/gcc/ada/gcc-interface/Make-lang.in
@@ -146,6 +146,7 @@ endif
# Define the names for selecting Ada in LANGUAGES.
ada: gnat1$(exeext) gnatbind$(exeext)
+ada.serial = gnat1$(exeext)
# Tell GNU Make to ignore these, if they exist.
.PHONY: ada
@@ -667,10 +668,13 @@ ada/libgnat/s-excmac.adb: $(srcdir)/ada/libgnat/s-excmac__$(EH_MECHANISM).adb
# Needs to be built with CC=gcc
# Since the RTL should be built with the latest compiler, remove the
# stamp target in the parent directory whenever gnat1 is rebuilt
-gnat1$(exeext): $(TARGET_ADA_SRCS) $(GNAT1_OBJS) $(ADA_BACKEND) libcommon-target.a $(LIBDEPS)
+gnat1$(exeext): $(TARGET_ADA_SRCS) $(GNAT1_OBJS) $(ADA_BACKEND) libcommon-target.a \
+ $(LIBDEPS) $(ada.prev)
+ @$(call LINK_PROGRESS,$(INDEX.ada),start)
+$(GCC_LLINK) -o $@ $(GNAT1_OBJS) $(ADA_BACKEND) \
libcommon-target.a $(LIBS) $(SYSLIBS) $(BACKENDLIBS) $(CFLAGS)
$(RM) stamp-gnatlib2-rts stamp-tools
+ @$(call LINK_PROGRESS,$(INDEX.ada),end)
gnatbind$(exeext): ada/b_gnatb.o $(CONFIG_H) $(GNATBIND_OBJS) ggc-none.o libcommon-target.a $(LIBDEPS)
+$(GCC_LINK) -o $@ ada/b_gnatb.o $(GNATBIND_OBJS) ggc-none.o libcommon-target.a $(LIBS) $(SYSLIBS) $(CFLAGS)
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index bdf6ae2..836fcbe 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -110,7 +110,7 @@ NO_INLINE_ADAFLAGS = -fno-inline
NO_OMIT_ADAFLAGS = -fno-omit-frame-pointer
NO_SIBLING_ADAFLAGS = -fno-optimize-sibling-calls
NO_REORDER_ADAFLAGS = -fno-toplevel-reorder
-GNATLIBFLAGS = -W -Wall -gnatpg -nostdinc
+GNATLIBFLAGS = -W -Wall -gnatg -nostdinc
GNATLIBCFLAGS = -g -O2
# Pretend that _Unwind_GetIPInfo is available for the target by default. This
# should be autodetected during the configuration of libada and passed down to
@@ -216,7 +216,7 @@ endif
ifneq ($(xmake_file),)
include $(xmake_file)
endif
-
+
# Now figure out from those variables how to compile and link.
all.indirect: Makefile ../gnat1$(exeext)
@@ -311,7 +311,7 @@ Makefile: ../config.status $(srcdir)/ada/gcc-interface/Makefile.in $(srcdir)/ada
# This tells GNU make version 3 not to export all the variables
# defined in this file into the environment.
.NOEXPORT:
-
+
# Lists of files for various purposes.
GNATLINK_OBJS = gnatlink.o \
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 4e6dc84..a0f17b1 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -261,7 +261,7 @@ typedef struct {
} intrin_binding_t;
static bool intrin_profiles_compatible_p (intrin_binding_t *);
-
+
/* Given GNAT_ENTITY, a GNAT defining identifier node, which denotes some Ada
entity, return the equivalent GCC tree for that entity (a ..._DECL node)
and associate the ..._DECL node with the input GNAT defining identifier.
@@ -667,21 +667,24 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
/* If we have a constant that we are not defining, get the expression it
was defined to represent. This is necessary to avoid generating dumb
- elaboration code in simple cases, but we may throw it away later if it
+ elaboration code in simple cases, and we may throw it away later if it
is not a constant. But do not do it for dispatch tables because they
are only referenced indirectly and we need to have a consistent view
of the exported and of the imported declarations of the tables from
external units for them to be properly merged in LTO mode. Moreover
- simply do not retrieve the expression it if it is an allocator since
+ simply do not retrieve the expression if it is an allocator because
the designated type might still be dummy at this point. Note that we
invoke gnat_to_gnu_external and not gnat_to_gnu because the expression
may contain N_Expression_With_Actions nodes and thus declarations of
- objects from other units that we need to discard. */
+ objects from other units that we need to discard. Note also that we
+ need to do it even if we are only annotating types, so as to be able
+ to validate representation clauses using constants. */
if (!definition
&& !No_Initialization (gnat_decl)
&& !Is_Dispatch_Table_Entity (gnat_entity)
&& Present (gnat_temp = Expression (gnat_decl))
- && Nkind (gnat_temp) != N_Allocator)
+ && Nkind (gnat_temp) != N_Allocator
+ && (Is_Elementary_Type (Etype (gnat_entity)) || !type_annotate_only))
gnu_expr = gnat_to_gnu_external (gnat_temp);
/* ... fall through ... */
@@ -1740,24 +1743,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
gnu_type = make_signed_type (esize);
- /* Try to decode the scale factor and to save it for the fixed-point
- types debug hook. */
-
- /* There are various ways to describe the scale factor, however there
- are cases where back-end internals cannot hold it. In such cases,
- we output invalid scale factor for such cases (i.e. the 0/0
- rational constant) but we expect GNAT to output GNAT encodings,
- then. Thus, keep this in sync with
- Exp_Dbug.Is_Handled_Scale_Factor. */
-
/* When encoded as 1/2**N or 1/10**N, describe the scale factor as a
binary or decimal scale: it is easier to read for humans. */
if (UI_Eq (Numerator (gnat_small_value), Uint_1)
&& (Rbase (gnat_small_value) == 2
|| Rbase (gnat_small_value) == 10))
{
- /* Given RM restrictions on 'Small values, we assume here that
- the denominator fits in an int. */
tree base
= build_int_cst (integer_type_node, Rbase (gnat_small_value));
tree exponent
@@ -1770,29 +1761,18 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
base, exponent));
}
- /* Default to arbitrary scale factors descriptions. */
- else
+ /* Use the arbitrary scale factor description. Note that we support
+ a Small_Value whose magnitude is larger than 64-bit even on 32-bit
+ platforms, so we unconditionally use a (dummy) 128-bit type. */
{
- const Uint num = Norm_Num (gnat_small_value);
- const Uint den = Norm_Den (gnat_small_value);
+ const Uint gnat_num = Norm_Num (gnat_small_value);
+ const Uint gnat_den = Norm_Den (gnat_small_value);
+ tree gnu_small_type = make_unsigned_type (128);
+ tree gnu_num = UI_To_gnu (gnat_num, gnu_small_type);
+ tree gnu_den = UI_To_gnu (gnat_den, gnu_small_type);
- if (UI_Is_In_Int_Range (num) && UI_Is_In_Int_Range (den))
- {
- tree gnu_num
- = build_int_cst (integer_type_node,
- UI_To_Int (Norm_Num (gnat_small_value)));
- tree gnu_den
- = build_int_cst (integer_type_node,
- UI_To_Int (Norm_Den (gnat_small_value)));
- scale_factor = build2 (RDIV_EXPR, integer_type_node,
- gnu_num, gnu_den);
- }
- else
- /* If compiler internals cannot represent arbitrary scale
- factors, output an invalid scale factor so that debugger
- don't try to handle them but so that we still have a type
- in the output. Note that GNAT */
- scale_factor = integer_zero_node;
+ scale_factor
+ = build2 (RDIV_EXPR, gnu_small_type, gnu_num, gnu_den);
}
TYPE_FIXED_POINT_P (gnu_type) = 1;
@@ -6575,7 +6555,7 @@ update_n_elem (tree n_elem, tree min, tree max)
return n_elem;
}
-
+
/* Given GNAT_ENTITY, elaborate all expressions that are required to
be elaborated at the point of its definition, but do nothing else. */
@@ -6632,7 +6612,7 @@ elaborate_entity (Entity_Id gnat_entity)
}
}
-
+
/* Prepend to ATTR_LIST an entry for an attribute with provided TYPE,
NAME, ARGS and ERROR_POINT. */
@@ -6747,7 +6727,7 @@ prepend_attributes (struct attrib **attr_list, Entity_Id gnat_entity)
if (Nkind (gnat_temp) == N_Pragma)
prepend_one_attribute_pragma (attr_list, gnat_temp);
}
-
+
/* Given a GNAT tree GNAT_EXPR, for an expression which is a value within a
type definition (either a bound or a discriminant value) for GNAT_ENTITY,
return the GCC tree to use for that expression. S is the suffix to use
@@ -6954,7 +6934,7 @@ elaborate_reference (tree ref, Entity_Id gnat_entity, bool definition,
struct er_data er = { gnat_entity, definition, 0 };
return gnat_rewrite_reference (ref, elaborate_reference_1, &er, init);
}
-
+
/* Given a GNU tree and a GNAT list of choices, generate an expression to test
the value passed against the list of choices. */
@@ -7051,7 +7031,7 @@ choices_to_gnu (tree gnu_operand, Node_Id gnat_choices)
return gnu_result;
}
-
+
/* Adjust PACKED setting as passed to gnat_to_gnu_field for a field of
type FIELD_TYPE to be placed in RECORD_TYPE. Return the result. */
@@ -7464,7 +7444,7 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
return gnu_field;
}
-
+
/* Return true if at least one member of COMPONENT_LIST needs strict
alignment. */
@@ -8430,7 +8410,7 @@ components_to_record (Node_Id gnat_component_list, Entity_Id gnat_record_type,
return (gnu_rep_list && !p_gnu_rep_list) || variants_have_rep;
}
-
+
/* Given GNU_SIZE, a GCC tree representing a size, return a Uint to be
placed into an Esize, Component_Bit_Offset, or Component_Size value
in the GNAT tree. */
@@ -8798,7 +8778,7 @@ annotate_rep (Entity_Id gnat_entity, tree gnu_type)
}
}
}
-
+
/* Scan all fields in GNU_TYPE and return a TREE_LIST where TREE_PURPOSE is
the FIELD_DECL and TREE_VALUE a TREE_VEC containing the byte position, the
value to be placed into DECL_OFFSET_ALIGN and the bit position. The list
@@ -8956,7 +8936,7 @@ build_variant_list (tree gnu_qual_union_type, Node_Id gnat_variant_part,
return gnu_list;
}
-
+
/* If SIZE has overflowed, return the maximum valid size, which is the upper
bound of the signed sizetype in bits, rounded down to ALIGN. Otherwise
return SIZE unmodified. */
@@ -9100,7 +9080,7 @@ validate_size (Uint uint_size, tree gnu_type, Entity_Id gnat_object,
return size;
}
-
+
/* Similarly, but both validate and process a value of RM size. This routine
is only called for types. */
@@ -9177,7 +9157,7 @@ set_rm_size (Uint uint_size, tree gnu_type, Entity_Id gnat_entity)
&& !TYPE_FAT_POINTER_P (gnu_type))
SET_TYPE_ADA_SIZE (gnu_type, size);
}
-
+
/* ALIGNMENT is a Uint giving the alignment specified for GNAT_ENTITY,
a type or object whose present alignment is ALIGN. If this alignment is
valid, return it. Otherwise, give an error and return ALIGN. */
@@ -9270,7 +9250,7 @@ validate_alignment (Uint alignment, Entity_Id gnat_entity, unsigned int align)
return align;
}
-
+
/* Promote the alignment of GNU_TYPE corresponding to GNAT_ENTITY. Return
a positive value on success or zero on failure. */
@@ -9317,7 +9297,7 @@ promote_object_alignment (tree gnu_type, Entity_Id gnat_entity)
return align;
}
-
+
/* Verify that TYPE is something we can implement atomically. If not, issue
an error for GNAT_ENTITY. COMPONENT_P is true if we are being called to
process a component type. */
@@ -9385,7 +9365,7 @@ check_ok_for_atomic_type (tree type, Entity_Id gnat_entity, bool component_p)
post_error_ne ("atomic access to & cannot be guaranteed",
gnat_error_point, gnat_entity);
}
-
+
/* Helper for the intrin compatibility checks family. Evaluate whether
two types are definitely incompatible. */
@@ -9540,7 +9520,7 @@ intrin_profiles_compatible_p (intrin_binding_t * inb)
return return_compatible_p && arglists_compatible_p;
}
-
+
/* Return a FIELD_DECL node modeled on OLD_FIELD. FIELD_TYPE is its type
and RECORD_TYPE is the type of the parent. If SIZE is nonzero, it is the
specified size for this field. POS_LIST is a position list describing
@@ -10154,7 +10134,7 @@ associate_original_type_to_packed_array (tree gnu_type, Entity_Id gnat_entity)
return NULL_TREE;
}
}
-
+
/* Given a type T, a FIELD_DECL F, and a replacement value R, return an
equivalent type with adjusted size expressions where all occurrences
of references to F in a PLACEHOLDER_EXPR have been replaced by R.
@@ -10315,7 +10295,7 @@ substitute_in_type (tree t, tree f, tree r)
return t;
}
}
-
+
/* Return the RM size of GNU_TYPE. This is the actual number of bits
needed to represent the object. */
@@ -10344,7 +10324,7 @@ rm_size (tree gnu_type)
/* For other types, this is just the size. */
return TYPE_SIZE (gnu_type);
}
-
+
/* Return the name to be used for GNAT_ENTITY. If a type, create a
fully-qualified name, possibly with type information encoding.
Otherwise, return the name. */
diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h
index 355178e..328e5f3 100644
--- a/gcc/ada/gcc-interface/gigi.h
+++ b/gcc/ada/gcc-interface/gigi.h
@@ -325,7 +325,7 @@ extern int double_scalar_alignment;
/* True if floating-point arithmetics may use wider intermediate results. */
extern bool fp_arith_may_widen;
-
+
/* Data structures used to represent attributes. */
enum attrib_type
diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index 87724af..d0867e0 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -628,16 +628,6 @@ gnat_get_fixed_point_type_info (const_tree type,
/* We expect here only a finite set of pattern. See fixed-point types
handling in gnat_to_gnu_entity. */
- /* Put invalid values when compiler internals cannot represent the scale
- factor. */
- if (scale_factor == integer_zero_node)
- {
- info->scale_factor_kind = fixed_point_scale_factor_arbitrary;
- info->scale_factor.arbitrary.numerator = 0;
- info->scale_factor.arbitrary.denominator = 0;
- return true;
- }
-
if (TREE_CODE (scale_factor) == RDIV_EXPR)
{
tree num = TREE_OPERAND (scale_factor, 0);
@@ -677,8 +667,8 @@ gnat_get_fixed_point_type_info (const_tree type,
&& TREE_CODE (den) == INTEGER_CST);
info->scale_factor_kind = fixed_point_scale_factor_arbitrary;
- info->scale_factor.arbitrary.numerator = tree_to_uhwi (num);
- info->scale_factor.arbitrary.denominator = tree_to_shwi (den);
+ info->scale_factor.arbitrary.numerator = num;
+ info->scale_factor.arbitrary.denominator = den;
return true;
}
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 059e1a4..0eec178 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -255,7 +255,7 @@ static bool maybe_make_gnu_thunk (Entity_Id gnat_thunk, tree gnu_thunk);
of configurations. */
static const char *extract_encoding (const char *) ATTRIBUTE_UNUSED;
static const char *decode_name (const char *) ATTRIBUTE_UNUSED;
-
+
/* This makes gigi's file_info_ptr visible in this translation unit,
so that Sloc_to_locus can look it up when deciding whether to map
decls to instances. */
@@ -735,7 +735,7 @@ gigi (Node_Id gnat_root,
/* We cannot track the location of errors past this point. */
Current_Error_Node = Empty;
}
-
+
/* Return a subprogram decl corresponding to __gnat_rcheck_xx for the given
CHECK if KIND is EXCEPTION_SIMPLE, or else to __gnat_rcheck_xx_ext. */
@@ -779,7 +779,7 @@ build_raise_check (int check, enum exception_info_kind kind)
return result;
}
-
+
/* Return a positive value if an lvalue is required for GNAT_NODE, which is
an N_Attribute_Reference. */
@@ -1333,7 +1333,7 @@ Identifier_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p)
return gnu_result;
}
-
+
/* Subroutine of gnat_to_gnu to process gnat_node, an N_Pragma. Return
any statements we generate. */
@@ -1599,7 +1599,7 @@ Pragma_to_gnu (Node_Id gnat_node)
return gnu_result;
}
-
+
/* Check the inline status of nested function FNDECL wrt its parent function.
If a non-inline nested function is referenced from an inline external
@@ -1645,7 +1645,7 @@ check_inlining_for_nested_subprog (tree fndecl)
DECL_UNINLINABLE (parent_decl) = 1;
}
}
-
+
/* Return an expression for the length of TYPE, an integral type, computed in
RESULT_TYPE, another integral type.
@@ -2590,7 +2590,7 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
*gnu_result_type_p = gnu_result_type;
return gnu_result;
}
-
+
/* Subroutine of gnat_to_gnu to translate gnat_node, an N_Case_Statement,
to a GCC tree, which is returned. */
@@ -2715,7 +2715,7 @@ Case_Statement_to_gnu (Node_Id gnat_node)
return gnu_result;
}
-
+
/* Return true if we are in the body of a loop. */
static inline bool
@@ -2814,38 +2814,6 @@ can_equal_max_val_p (tree val, tree type, bool reverse)
return can_equal_min_or_max_val_p (val, type, !reverse);
}
-/* Return true if VAL1 can be lower than VAL2. */
-
-static bool
-can_be_lower_p (tree val1, tree val2)
-{
- if (TREE_CODE (val1) == NOP_EXPR)
- {
- tree type = TREE_TYPE (TREE_OPERAND (val1, 0));
- if (can_be_lower_p (TYPE_MAX_VALUE (type), TYPE_MIN_VALUE (type)))
- return true;
-
- val1 = TYPE_MIN_VALUE (type);
- }
-
- if (TREE_CODE (val1) != INTEGER_CST)
- return true;
-
- if (TREE_CODE (val2) == NOP_EXPR)
- {
- tree type = TREE_TYPE (TREE_OPERAND (val2, 0));
- if (can_be_lower_p (TYPE_MAX_VALUE (type), TYPE_MIN_VALUE (type)))
- return true;
-
- val2 = TYPE_MAX_VALUE (type);
- }
-
- if (TREE_CODE (val2) != INTEGER_CST)
- return true;
-
- return tree_int_cst_lt (val1, val2);
-}
-
/* Replace EXPR1 and EXPR2 by invariant expressions if possible. Return
true if both expressions have been replaced and false otherwise. */
@@ -3126,19 +3094,16 @@ Regular_Loop_to_gnu (Node_Id gnat_node, tree *gnu_cond_expr_p)
}
/* If we use the BOTTOM_COND, we can turn the test into an inequality
- test but we may have to add ENTRY_COND to protect the empty loop. */
+ test but we have to add ENTRY_COND to protect the empty loop. */
if (LOOP_STMT_BOTTOM_COND_P (gnu_loop_stmt))
{
test_code = NE_EXPR;
- if (can_be_lower_p (gnu_high, gnu_low))
- {
- gnu_cond_expr
- = build3 (COND_EXPR, void_type_node,
- build_binary_op (LE_EXPR, boolean_type_node,
- gnu_low, gnu_high),
- NULL_TREE, alloc_stmt_list ());
- set_expr_location_from_node (gnu_cond_expr, gnat_iter_scheme);
- }
+ gnu_cond_expr
+ = build3 (COND_EXPR, void_type_node,
+ build_binary_op (LE_EXPR, boolean_type_node,
+ gnu_low, gnu_high),
+ NULL_TREE, alloc_stmt_list ());
+ set_expr_location_from_node (gnu_cond_expr, gnat_iter_scheme);
}
/* Open a new nesting level that will surround the loop to declare the
@@ -3363,7 +3328,7 @@ Loop_Statement_to_gnu (Node_Id gnat_node)
return gnu_result;
}
-
+
/* This page implements a form of Named Return Value optimization modeled
on the C++ optimization of the same name. The main difference is that
we disregard any semantical considerations when applying it here, the
@@ -3855,7 +3820,7 @@ build_return_expr (tree ret_obj, tree ret_val)
return build1 (RETURN_EXPR, void_type_node, result_expr);
}
-
+
/* Subroutine of gnat_to_gnu to process gnat_node, an N_Subprogram_Body. We
don't return anything. */
@@ -4179,7 +4144,7 @@ Subprogram_Body_to_gnu (Node_Id gnat_node)
else
rest_of_subprog_body_compilation (gnu_subprog_decl);
}
-
+
/* The type of an atomic access. */
typedef enum { NOT_ATOMIC, SIMPLE_ATOMIC, OUTER_ATOMIC } atomic_acces_t;
@@ -4369,8 +4334,8 @@ not_atomic:
*type = NOT_ATOMIC;
*sync = false;
}
-
- /* Return true if GNAT_NODE requires simple atomic access and, if so, set SYNC
+
+/* Return true if GNAT_NODE requires simple atomic access and, if so, set SYNC
according to the associated synchronization setting. */
static inline bool
@@ -5240,7 +5205,7 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target,
return gnu_result;
}
-
+
/* Subroutine of gnat_to_gnu to translate gnat_node, an
N_Handled_Sequence_Of_Statements, to a GCC tree, which is returned. */
@@ -5479,7 +5444,7 @@ Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node)
return gnu_result;
}
-
+
/* Subroutine of gnat_to_gnu to translate gnat_node, an N_Exception_Handler,
to a GCC tree, which is returned. This is the variant for front-end sjlj
exception handling. */
@@ -5548,7 +5513,7 @@ Exception_Handler_to_gnu_fe_sjlj (Node_Id gnat_node)
return build3 (COND_EXPR, void_type_node, gnu_choice, gnu_body, NULL_TREE);
}
-
+
/* Return true if no statement in GNAT_LIST can alter the control flow. */
static bool
@@ -5755,7 +5720,7 @@ Exception_Handler_to_gnu_gcc (Node_Id gnat_node)
return
build2 (CATCH_EXPR, void_type_node, gnu_etypes_list, end_stmt_group ());
}
-
+
/* Subroutine of gnat_to_gnu to generate code for an N_Compilation unit. */
static void
@@ -5885,7 +5850,7 @@ Compilation_Unit_to_gnu (Node_Id gnat_node)
/* Force the processing for all nodes that remain in the queue. */
process_deferred_decl_context (true);
}
-
+
/* Mark COND, a boolean expression, as predicating a call to a noreturn
function, i.e. predict that it is very likely false, and return it.
@@ -6099,7 +6064,7 @@ Raise_Error_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p)
return gnu_result;
}
-
+
/* Return true if GNAT_NODE is on the LHS of an assignment or an actual
parameter of a call. */
@@ -7085,6 +7050,8 @@ gnat_to_gnu (Node_Id gnat_node)
if (TREE_CODE (gnu_lhs) == INTEGER_CST && ignore_lhs_overflow)
TREE_OVERFLOW (gnu_lhs) = TREE_OVERFLOW (gnu_old_lhs);
gnu_rhs = convert (gnu_type, gnu_rhs);
+ if (gnu_max_shift)
+ gnu_max_shift = convert (gnu_type, gnu_max_shift);
}
/* For signed integer addition, subtraction and multiplication, do an
@@ -7192,9 +7159,7 @@ gnat_to_gnu (Node_Id gnat_node)
const Entity_Id gnat_desig_type
= Designated_Type (Underlying_Type (Etype (gnat_node)));
- /* The flag is effectively only set on the base types. */
- ignore_init_type
- = Has_Constrained_Partial_View (Base_Type (gnat_desig_type));
+ ignore_init_type = Has_Constrained_Partial_View (gnat_desig_type);
gnu_init = gnat_to_gnu (Expression (gnat_temp));
gnu_init = maybe_unconstrained_array (gnu_init);
@@ -8364,7 +8329,7 @@ gnat_to_gnu_external (Node_Id gnat_node)
return gnu_result;
}
-
+
/* Return true if the statement list STMT_LIST is empty. */
static bool
@@ -8408,7 +8373,7 @@ insert_code_for (Node_Id gnat_node)
save_gnu_tree (gnat_node, NULL_TREE, true);
}
-
+
/* Start a new statement group chained to the previous group. */
void
@@ -8680,7 +8645,7 @@ build_stmt_group (List_Id gnat_list, bool binding_p)
return end_stmt_group ();
}
-
+
/* Generate GIMPLE in place for the expression at *EXPR_P. */
int
@@ -8929,7 +8894,7 @@ gnat_gimplify_stmt (tree *stmt_p)
gcc_unreachable ();
}
}
-
+
/* Force a reference to each of the entities in GNAT_PACKAGE recursively.
This routine is exclusively called in type_annotate mode, to compute DDA
@@ -9055,7 +9020,7 @@ elaborate_all_entities (Node_Id gnat_node)
if (Nkind (Unit (gnat_node)) == N_Package_Body)
elaborate_all_entities (Library_Unit (gnat_node));
}
-
+
/* Do the processing of GNAT_NODE, an N_Freeze_Entity. */
static void
@@ -9195,7 +9160,7 @@ process_freeze_entity (Node_Id gnat_node)
used_types_insert (TREE_TYPE (gnu_new));
}
}
-
+
/* Elaborate decls in the lists GNAT_DECLS and GNAT_DECLS2, if present.
We make two passes, one to elaborate anything other than bodies (but
we declare a function if there was no spec). The second pass
@@ -9330,7 +9295,7 @@ process_decls (List_Id gnat_decls, List_Id gnat_decls2,
add_stmt (gnat_to_gnu (gnat_decl));
}
}
-
+
/* Make a unary operation of kind CODE using build_unary_op, but guard
the operation by an overflow check. CODE can be one of NEGATE_EXPR
or ABS_EXPR. GNU_TYPE is the type desired for the result. Usually
@@ -9394,6 +9359,11 @@ build_binary_op_trapv (enum tree_code code, tree gnu_type, tree left,
/* If no operand is a constant, we use the generic implementation. */
if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (rhs) != INTEGER_CST)
{
+ /* First convert the operands to the result type like build_binary_op.
+ This is where the bias is made explicit for biased types. */
+ lhs = convert (gnu_type, lhs);
+ rhs = convert (gnu_type, rhs);
+
/* Never inline a 64-bit mult for a 32-bit target, it's way too long. */
if (code == MULT_EXPR && precision == 64 && BITS_PER_WORD < 64)
{
@@ -9573,7 +9543,7 @@ emit_check (tree gnu_cond, tree gnu_expr, int reason, Node_Id gnat_node)
: build_int_cst (TREE_TYPE (gnu_expr), 0)),
gnu_expr);
}
-
+
/* Return an expression that converts GNU_EXPR to GNAT_TYPE, doing overflow
checks if OVERFLOW_P is true. If TRUNCATE_P is true, do a fp-to-integer
conversion with truncation, otherwise round. GNAT_NODE is the GNAT node
@@ -9758,7 +9728,7 @@ convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflow_p,
return convert (gnu_type, gnu_result);
}
-
+
/* Return true if GNU_EXPR can be directly addressed. This is the case
unless it is an expression involving computation or if it involves a
reference to a bitfield or to an object not sufficiently aligned for
@@ -9936,7 +9906,7 @@ addressable_p (tree gnu_expr, tree gnu_type)
return false;
}
}
-
+
/* Do the processing for the declaration of a GNAT_ENTITY, a type or subtype.
If a Freeze node exists for the entity, delay the bulk of the processing.
Otherwise make a GCC type for GNAT_ENTITY and set up the correspondence. */
@@ -10020,7 +9990,7 @@ process_type (Entity_Id gnat_entity)
TREE_TYPE (gnu_new));
}
}
-
+
/* Subroutine of assoc_to_constructor: VALUES is a list of field associations,
some of which are from RECORD_TYPE. Return a CONSTRUCTOR consisting of the
associations that are from RECORD_TYPE. If we see an internal record, make
@@ -10174,7 +10144,7 @@ pos_to_constructor (Node_Id gnat_expr, tree gnu_array_type)
return gnat_build_constructor (gnu_array_type, gnu_expr_vec);
}
-
+
/* Process a N_Validate_Unchecked_Conversion node. */
static void
@@ -10233,7 +10203,7 @@ validate_unchecked_conversion (Node_Id gnat_node)
}
}
}
-
+
/* Convert SLOC into LOCUS. Return true if SLOC corresponds to a
source code location and false if it doesn't. If CLEAR_COLUMN is
true, set the column information to 0. If DECL is given and SLOC
@@ -10415,7 +10385,7 @@ set_end_locus_from_node (tree gnu_node, Node_Id gnat_node)
return false;
}
}
-
+
/* Return a colon-separated list of encodings contained in encoded Ada
name. */
@@ -10436,7 +10406,7 @@ decode_name (const char *name)
__gnat_decode (name, decoded, 0);
return decoded;
}
-
+
/* Post an error message. MSG is the error message, properly annotated.
NODE is the node at which to post the error and the node to use for the
'&' substitution. */
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index d50872f..013fccd 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -357,7 +357,7 @@ add_deferred_decl_context (tree decl, Entity_Id gnat_scope, int force_global);
computed. */
static void add_deferred_type_context (struct deferred_decl_context_node *n,
tree type);
-
+
/* Initialize data structures of the utils.c module. */
void
@@ -397,7 +397,7 @@ destroy_gnat_utils (void)
pad_type_hash_table->empty ();
pad_type_hash_table = NULL;
}
-
+
/* GNAT_ENTITY is a GNAT tree node for an entity. Associate GNU_DECL, a GCC
tree node, with GNAT_ENTITY. If GNU_DECL is not a ..._DECL node, abort.
If NO_CHECK is true, the latter check is suppressed.
@@ -438,7 +438,7 @@ present_gnu_tree (Entity_Id gnat_entity)
{
return PRESENT_GNU_TREE (gnat_entity);
}
-
+
/* Make a dummy type corresponding to GNAT_TYPE. */
tree
@@ -533,7 +533,7 @@ build_dummy_unc_pointer_types (Entity_Id gnat_desig_type, tree gnu_desig_type)
TYPE_REFERENCE_TO (gnu_desig_type) = gnu_fat_type;
TYPE_OBJECT_RECORD_TYPE (gnu_desig_type) = gnu_object_type;
}
-
+
/* Return true if we are in the global binding level. */
bool
@@ -663,7 +663,7 @@ gnat_zaplevel (void)
level->chain = free_binding_level;
free_binding_level = level;
}
-
+
/* Set the context of TYPE and its parallel types (if any) to CONTEXT. */
static void
@@ -935,7 +935,7 @@ gnat_pushdecl (tree decl, Node_Id gnat_node)
}
}
}
-
+
/* Create a record type that contains a SIZE bytes long field of TYPE with a
starting bit position so that it is aligned to ALIGN bits, and leaving at
least ROOM bytes free before the field. BASE_ALIGN is the alignment the
@@ -1772,7 +1772,7 @@ set_reverse_storage_order_on_pad_type (tree type)
TYPE_REVERSE_STORAGE_ORDER (type) = 1;
return canonicalize_pad_type (type);
}
-
+
/* Relate the alias sets of GNU_NEW_TYPE and GNU_OLD_TYPE according to OP.
If this is a multi-dimensional array type, do this recursively.
@@ -1847,7 +1847,7 @@ relate_alias_sets (tree gnu_new_type, tree gnu_old_type, enum alias_set_op op)
record_component_aliases (gnu_new_type);
}
-
+
/* Record TYPE as a builtin type for Ada. NAME is the name of the type.
ARTIFICIAL_P is true if the type was generated by the compiler. */
@@ -1863,7 +1863,7 @@ record_builtin_type (const char *name, tree type, bool artificial_p)
if (debug_hooks->type_decl)
debug_hooks->type_decl (type_decl, false);
}
-
+
/* Finish constructing the character type CHAR_TYPE.
In Ada character types are enumeration types and, as a consequence, are
@@ -2558,7 +2558,7 @@ split_plus (tree in, tree *pvar)
else
return bitsize_zero_node;
}
-
+
/* Return a copy of TYPE but safe to modify in any way. */
tree
@@ -2595,7 +2595,7 @@ copy_type (tree type)
return new_type;
}
-
+
/* Return a subtype of sizetype with range MIN to MAX and whose
TYPE_INDEX_TYPE is INDEX. GNAT_NODE is used for the position
of the associated TYPE_DECL. */
@@ -2634,8 +2634,8 @@ create_range_type (tree type, tree min, tree max)
return range_type;
}
-
- /* Return an extra subtype of TYPE with range MIN to MAX. */
+
+/* Return an extra subtype of TYPE with range MIN to MAX. */
tree
create_extra_subtype (tree type, tree min, tree max)
@@ -2652,7 +2652,7 @@ create_extra_subtype (tree type, tree min, tree max)
return subtype;
}
-
+
/* Return a TYPE_DECL node suitable for the TYPE_STUB_DECL field of TYPE.
NAME gives the name of the type to be used in the declaration. */
@@ -2718,7 +2718,7 @@ create_type_decl (tree name, tree type, bool artificial_p, bool debug_info_p,
return type_decl;
}
-
+
/* Return a VAR_DECL or CONST_DECL node.
NAME gives the name of the variable. ASM_NAME is its assembler name
@@ -2886,7 +2886,7 @@ create_var_decl (tree name, tree asm_name, tree type, tree init,
return var_decl;
}
-
+
/* Return true if TYPE, an aggregate type, contains (or is) an array.
If SELF_REFERENTIAL is true, then an additional requirement on the
array is that it be self-referential. */
@@ -3097,7 +3097,7 @@ create_field_decl (tree name, tree type, tree record_type, tree size, tree pos,
return field_decl;
}
-
+
/* Return a PARM_DECL node with NAME and TYPE. */
tree
@@ -3131,7 +3131,7 @@ create_param_decl (tree name, tree type)
DECL_ARG_TYPE (param_decl) = type;
return param_decl;
}
-
+
/* Process the attributes in ATTR_LIST for NODE, which is either a DECL or
a TYPE. If IN_PLACE is true, the tree pointed to by NODE should not be
changed. GNAT_NODE is used for the position of error messages. */
@@ -3420,7 +3420,7 @@ create_label_decl (tree name, Node_Id gnat_node)
return label_decl;
}
-
+
/* Return a FUNCTION_DECL node. NAME is the name of the subprogram, ASM_NAME
its assembler name, TYPE its type (a FUNCTION_TYPE or METHOD_TYPE node),
PARAM_DECL_LIST the list of its parameters (a list of PARM_DECL nodes
@@ -3558,7 +3558,7 @@ finish_subprog_decl (tree decl, tree asm_name, tree type)
DECL_NAME (decl) = main_identifier_node;
}
}
-
+
/* Set up the framework for generating code for SUBPROG_DECL, a subprogram
body. This routine needs to be invoked before processing the declarations
appearing in the subprogram. */
@@ -3830,7 +3830,7 @@ fntype_same_flags_p (const_tree t, tree cico_list, bool return_unconstrained_p,
&& TYPE_RETURN_BY_DIRECT_REF_P (t) == return_by_direct_ref_p
&& TREE_ADDRESSABLE (t) == return_by_invisi_ref_p;
}
-
+
/* EXP is an expression for the size of an object. If this size contains
discriminant references, replace them with the maximum (if MAX_P) or
minimum (if !MAX_P) possible value of the discriminant.
@@ -4042,7 +4042,7 @@ max_size (tree exp, bool max_p)
gcc_unreachable ();
}
-
+
/* Build a template of type TEMPLATE_TYPE from the array bounds of ARRAY_TYPE.
EXPR is an expression that we can use to locate any PLACEHOLDER_EXPRs.
Return a constructor for the template. */
@@ -4108,7 +4108,7 @@ build_template (tree template_type, tree array_type, tree expr)
return gnat_build_constructor (template_type, template_elts);
}
-
+
/* Return true if TYPE is suitable for the element type of a vector. */
static bool
@@ -4198,7 +4198,7 @@ build_vector_type_for_array (tree array_type, tree attribute)
TYPE_REPRESENTATIVE_ARRAY (vector_type) = array_type;
return vector_type;
}
-
+
/* Build a type to be used to represent an aliased object whose nominal type
is an unconstrained array. This consists of a RECORD_TYPE containing a
field of TEMPLATE_TYPE and a field of OBJECT_TYPE, which is an ARRAY_TYPE.
@@ -4248,7 +4248,7 @@ build_unc_object_type_from_ptr (tree thin_fat_ptr_type, tree object_type,
return
build_unc_object_type (template_type, object_type, name, debug_info_p);
}
-
+
/* Update anything previously pointing to OLD_TYPE to point to NEW_TYPE.
In the normal case this is just two adjustments, but we have more to
do if NEW_TYPE is an UNCONSTRAINED_ARRAY_TYPE. */
@@ -4379,7 +4379,7 @@ update_pointer_to (tree old_type, tree new_type)
TYPE_REFERENCE_TO (old_type) = NULL_TREE;
}
}
-
+
/* Convert EXPR, a pointer to a constrained array, into a pointer to an
unconstrained one. This involves making or finding a template. */
@@ -4483,7 +4483,7 @@ convert_to_fat_pointer (tree type, tree expr)
CONSTRUCTOR_APPEND_ELT (v, DECL_CHAIN (TYPE_FIELDS (type)), template_addr);
return gnat_build_constructor (type, v);
}
-
+
/* Create an expression whose value is that of EXPR,
converted to type TYPE. The TREE_TYPE of the value
is always TYPE. This function implements all reasonable
@@ -5170,7 +5170,7 @@ convert_to_index_type (tree expr)
return convert (sizetype, expr);
}
-
+
/* Remove all conversions that are done in EXP. This includes converting
from a padded type or to a justified modular type. If TRUE_ADDRESS
is true, always return the address of the containing object even if
@@ -5205,7 +5205,7 @@ remove_conversions (tree exp, bool true_address)
return exp;
}
-
+
/* If EXP's type is an UNCONSTRAINED_ARRAY_TYPE, return an expression that
refers to the underlying array. If it has TYPE_CONTAINS_TEMPLATE_P,
likewise return an expression pointing to the underlying array. */
@@ -5293,7 +5293,7 @@ maybe_unconstrained_array (tree exp)
return exp;
}
-
+
/* Return true if EXPR is an expression that can be folded as an operand
of a VIEW_CONVERT_EXPR. See ada-tree.h for a complete rationale. */
@@ -5687,7 +5687,7 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
return expr;
}
-
+
/* Return the appropriate GCC tree code for the specified GNAT_TYPE,
the latter being a record type as predicated by Is_Record_Type. */
@@ -5837,7 +5837,7 @@ can_materialize_object_renaming_p (Node_Id expr)
{
expr = Original_Node (expr);
- switch Nkind (expr)
+ switch (Nkind (expr))
{
case N_Identifier:
case N_Expanded_Name:
diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c
index c8a2d7c..316033b 100644
--- a/gcc/ada/gcc-interface/utils2.c
+++ b/gcc/ada/gcc-interface/utils2.c
@@ -73,7 +73,7 @@ get_base_type (tree type)
return type;
}
-
+
/* EXP is a GCC tree representing an address. See if we can find how strictly
the object at this address is aligned and, if so, return the alignment of
the object in bits. Otherwise return 0. */
@@ -203,7 +203,7 @@ known_alignment (tree exp)
return this_alignment;
}
-
+
/* We have a comparison or assignment operation on two types, T1 and T2, which
are either both array types or both record types. T1 is assumed to be for
the left hand side operand, and T2 for the right hand side. Return the
@@ -271,7 +271,7 @@ find_common_type (tree t1, tree t2)
could cause a bad self-referential reference. */
return NULL_TREE;
}
-
+
/* Return an expression tree representing an equality comparison of A1 and A2,
two objects of type ARRAY_TYPE. The result should be of type RESULT_TYPE.
@@ -533,7 +533,7 @@ compare_fat_pointers (location_t loc, tree result_type, tree p1, tree p2)
build_binary_op (TRUTH_ORIF_EXPR, result_type,
p1_array_is_null, same_bounds));
}
-
+
/* Compute the result of applying OP_CODE to LHS and RHS, where both are of
type TYPE. We know that TYPE is a modular type with a nonbinary
modulus. */
@@ -629,7 +629,7 @@ nonbinary_modular_operation (enum tree_code op_code, tree type, tree lhs,
return convert (type, result);
}
-
+
/* This page contains routines that implement the Ada semantics with regard
to atomic objects. They are fully piggybacked on the middle-end support
for atomic loads and stores.
@@ -828,7 +828,7 @@ build_load_modify_store (tree dest, tree src, Node_Id gnat_node)
/* Something went wrong earlier if we have not found the atomic load. */
gcc_unreachable ();
}
-
+
/* Make a binary operation of kind OP_CODE. RESULT_TYPE is the type
desired for the result. Usually the operation is to be performed
in that type. For INIT_EXPR and MODIFY_EXPR, RESULT_TYPE must be
@@ -1323,7 +1323,7 @@ build_binary_op (enum tree_code op_code, tree result_type,
return result;
}
-
+
/* Similar, but for unary operations. */
tree
@@ -1683,7 +1683,7 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand)
return result;
}
-
+
/* Similar, but for COND_EXPR. */
tree
@@ -1758,7 +1758,7 @@ build_compound_expr (tree result_type, tree stmt_operand, tree expr_operand)
return result;
}
-
+
/* Conveniently construct a function call expression. FNDECL names the
function to be called, N is the number of arguments, and the "..."
parameters are the argument expressions. Unlike build_call_expr
@@ -1776,7 +1776,7 @@ build_call_n_expr (tree fndecl, int n, ...)
va_end (ap);
return fn;
}
-
+
/* Build a goto to LABEL for a raise, with an optional call to Local_Raise.
MSG gives the exception's identity for the call to Local_Raise, if any. */
@@ -1924,7 +1924,7 @@ build_call_raise_range (int msg, Node_Id gnat_node, char kind,
convert (integer_type_node, first),
convert (integer_type_node, last));
}
-
+
/* qsort comparer for the bit positions of two constructor elements
for record components. */
@@ -1987,7 +1987,7 @@ gnat_build_constructor (tree type, vec<constructor_elt, va_gc> *v)
TREE_READONLY (result) = TYPE_READONLY (type) || read_only || allconstant;
return result;
}
-
+
/* Return a COMPONENT_REF to access FIELD in RECORD, or NULL_TREE if the field
is not found in the record. Don't fold the result if NO_FOLD is true. */
@@ -2113,7 +2113,7 @@ build_component_ref (tree record, tree field, bool no_fold)
build_call_raise (CE_Discriminant_Check_Failed, Empty,
N_Raise_Constraint_Error));
}
-
+
/* Helper for build_call_alloc_dealloc, with arguments to be interpreted
identically. Process the case where a GNAT_PROC to call is provided. */
@@ -2326,7 +2326,7 @@ build_call_alloc_dealloc (tree gnu_obj, tree gnu_size, tree gnu_type,
return maybe_wrap_malloc (gnu_size, gnu_type, gnat_node);
}
}
-
+
/* Build a GCC tree that corresponds to allocating an object of TYPE whose
initial value is INIT, if INIT is nonzero. Convert the expression to
RESULT_TYPE, which must be some pointer type, and return the result.
@@ -2457,7 +2457,7 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc,
return storage;
}
-
+
/* Indicate that we need to take the address of T and that it therefore
should not be allocated in a register. Return true if successful. */
@@ -2505,7 +2505,7 @@ gnat_mark_addressable (tree t)
return true;
}
}
-
+
/* Return true if EXP is a stable expression for the purpose of the functions
below and, therefore, can be returned unmodified by them. We accept things
that are actual constants or that have already been handled. */
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index c28518f..401d625 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -21,7 +21,7 @@
@copying
@quotation
-GNAT Reference Manual , Sep 29, 2020
+GNAT Reference Manual , Nov 20, 2020
AdaCore
@@ -394,6 +394,7 @@ Implementation Defined Attributes
* Attribute From_Any::
* Attribute Has_Access_Values::
* Attribute Has_Discriminants::
+* Attribute Has_Tagged_Values::
* Attribute Img::
* Attribute Initialized::
* Attribute Integer_Value::
@@ -422,6 +423,8 @@ Implementation Defined Attributes
* Attribute Scalar_Storage_Order::
* Attribute Simple_Storage_Pool::
* Attribute Small::
+* Attribute Small_Denominator::
+* Attribute Small_Numerator::
* Attribute Storage_Unit::
* Attribute Stub_Type::
* Attribute System_Allocator_Alignment::
@@ -1806,15 +1809,16 @@ pragma Assertion_Policy (
ASSERTION_KIND ::= RM_ASSERTION_KIND | ID_ASSERTION_KIND
-RM_ASSERTION_KIND ::= Assert |
- Static_Predicate |
- Dynamic_Predicate |
- Pre |
- Pre'Class |
- Post |
- Post'Class |
- Type_Invariant |
- Type_Invariant'Class
+RM_ASSERTION_KIND ::= Assert |
+ Static_Predicate |
+ Dynamic_Predicate |
+ Pre |
+ Pre'Class |
+ Post |
+ Post'Class |
+ Type_Invariant |
+ Type_Invariant'Class |
+ Default_Initial_Condition
ID_ASSERTION_KIND ::= Assertions |
Assert_And_Cut |
@@ -1822,6 +1826,7 @@ ID_ASSERTION_KIND ::= Assertions |
Contract_Cases |
Debug |
Ghost |
+ Initial_Condition |
Invariant |
Invariant'Class |
Loop_Invariant |
@@ -1830,7 +1835,8 @@ ID_ASSERTION_KIND ::= Assertions |
Precondition |
Predicate |
Refined_Post |
- Statement_Assertions
+ Statement_Assertions |
+ Subprogram_Variant
POLICY_IDENTIFIER ::= Check | Disable | Ignore | Suppressible
@end example
@@ -10043,6 +10049,7 @@ consideration, you should minimize the use of these attributes.
* Attribute From_Any::
* Attribute Has_Access_Values::
* Attribute Has_Discriminants::
+* Attribute Has_Tagged_Values::
* Attribute Img::
* Attribute Initialized::
* Attribute Integer_Value::
@@ -10071,6 +10078,8 @@ consideration, you should minimize the use of these attributes.
* Attribute Scalar_Storage_Order::
* Attribute Simple_Storage_Pool::
* Attribute Small::
+* Attribute Small_Denominator::
+* Attribute Small_Numerator::
* Attribute Storage_Unit::
* Attribute Stub_Type::
* Attribute System_Allocator_Alignment::
@@ -10622,7 +10631,7 @@ The intended use of this attribute is in conjunction with generic
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
+@node Attribute Has_Discriminants,Attribute Has_Tagged_Values,Attribute Has_Access_Values,Implementation Defined Attributes
@anchor{gnat_rm/implementation_defined_attributes attribute-has-discriminants}@anchor{183}
@section Attribute Has_Discriminants
@@ -10638,8 +10647,25 @@ otherwise. The intended use of this attribute is in conjunction with generic
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 Initialized,Attribute Has_Discriminants,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-img}@anchor{184}
+@node Attribute Has_Tagged_Values,Attribute Img,Attribute Has_Discriminants,Implementation Defined Attributes
+@anchor{gnat_rm/implementation_defined_attributes attribute-has-tagged-values}@anchor{184}
+@section Attribute Has_Tagged_Values
+
+
+@geindex Tagged values
+@geindex testing for
+
+@geindex Has_Tagged_Values
+
+The prefix of the @code{Has_Tagged_Values} attribute is a type. The result is a
+Boolean value which is True if the type is a composite type (array or record)
+that is either a tagged type or has a subcomponent that is tagged, and is False
+otherwise. The intended use of this attribute is in conjunction with generic
+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 Img,Attribute Initialized,Attribute Has_Tagged_Values,Implementation Defined Attributes
+@anchor{gnat_rm/implementation_defined_attributes attribute-img}@anchor{185}
@section Attribute Img
@@ -10669,7 +10695,7 @@ that returns the appropriate string when called. This means that
in an instantiation as a function parameter.
@node Attribute Initialized,Attribute Integer_Value,Attribute Img,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-initialized}@anchor{185}
+@anchor{gnat_rm/implementation_defined_attributes attribute-initialized}@anchor{186}
@section Attribute Initialized
@@ -10679,7 +10705,7 @@ For the syntax and semantics of this attribute, see the SPARK 2014 Reference
Manual, section 6.10.
@node Attribute Integer_Value,Attribute Invalid_Value,Attribute Initialized,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-integer-value}@anchor{186}
+@anchor{gnat_rm/implementation_defined_attributes attribute-integer-value}@anchor{187}
@section Attribute Integer_Value
@@ -10707,7 +10733,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{187}
+@anchor{gnat_rm/implementation_defined_attributes attribute-invalid-value}@anchor{188}
@section Attribute Invalid_Value
@@ -10721,7 +10747,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{188}
+@anchor{gnat_rm/implementation_defined_attributes attribute-iterable}@anchor{189}
@section Attribute Iterable
@@ -10730,7 +10756,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{189}
+@anchor{gnat_rm/implementation_defined_attributes attribute-large}@anchor{18a}
@section Attribute Large
@@ -10743,7 +10769,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{18a}
+@anchor{gnat_rm/implementation_defined_attributes attribute-library-level}@anchor{18b}
@section Attribute Library_Level
@@ -10769,7 +10795,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{18b}
+@anchor{gnat_rm/implementation_defined_attributes attribute-lock-free}@anchor{18c}
@section Attribute Lock_Free
@@ -10779,7 +10805,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{18c}
+@anchor{gnat_rm/implementation_defined_attributes attribute-loop-entry}@anchor{18d}
@section Attribute Loop_Entry
@@ -10809,7 +10835,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{18d}
+@anchor{gnat_rm/implementation_defined_attributes attribute-machine-size}@anchor{18e}
@section Attribute Machine_Size
@@ -10819,7 +10845,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{18e}
+@anchor{gnat_rm/implementation_defined_attributes attribute-mantissa}@anchor{18f}
@section Attribute Mantissa
@@ -10832,7 +10858,7 @@ the Ada 83 reference manual for an exact description of the semantics of
this attribute.
@node Attribute Maximum_Alignment,Attribute Max_Integer_Size,Attribute Mantissa,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-maximum-alignment}@anchor{18f}@anchor{gnat_rm/implementation_defined_attributes id2}@anchor{190}
+@anchor{gnat_rm/implementation_defined_attributes attribute-maximum-alignment}@anchor{190}@anchor{gnat_rm/implementation_defined_attributes id2}@anchor{191}
@section Attribute Maximum_Alignment
@@ -10848,7 +10874,7 @@ for an object, guaranteeing that it is properly aligned in all
cases.
@node Attribute Max_Integer_Size,Attribute Mechanism_Code,Attribute Maximum_Alignment,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-max-integer-size}@anchor{191}
+@anchor{gnat_rm/implementation_defined_attributes attribute-max-integer-size}@anchor{192}
@section Attribute Max_Integer_Size
@@ -10859,7 +10885,7 @@ prefix) provides the size of the largest supported integer type for
the target. The result is a static constant.
@node Attribute Mechanism_Code,Attribute Null_Parameter,Attribute Max_Integer_Size,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-mechanism-code}@anchor{192}
+@anchor{gnat_rm/implementation_defined_attributes attribute-mechanism-code}@anchor{193}
@section Attribute Mechanism_Code
@@ -10890,7 +10916,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{193}
+@anchor{gnat_rm/implementation_defined_attributes attribute-null-parameter}@anchor{194}
@section Attribute Null_Parameter
@@ -10915,7 +10941,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{194}
+@anchor{gnat_rm/implementation_defined_attributes attribute-object-size}@anchor{143}@anchor{gnat_rm/implementation_defined_attributes id3}@anchor{195}
@section Attribute Object_Size
@@ -10985,7 +11011,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{195}
+@anchor{gnat_rm/implementation_defined_attributes attribute-old}@anchor{196}
@section Attribute Old
@@ -11000,7 +11026,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{196}
+@anchor{gnat_rm/implementation_defined_attributes attribute-passed-by-reference}@anchor{197}
@section Attribute Passed_By_Reference
@@ -11016,13 +11042,10 @@ 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{197}
+@anchor{gnat_rm/implementation_defined_attributes attribute-pool-address}@anchor{198}
@section Attribute Pool_Address
-@geindex Parameters
-@geindex when passed by reference
-
@geindex Pool_Address
@code{X'Pool_Address} for any object @code{X} returns the address
@@ -11041,7 +11064,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{198}
+@anchor{gnat_rm/implementation_defined_attributes attribute-range-length}@anchor{199}
@section Attribute Range_Length
@@ -11054,7 +11077,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{199}
+@anchor{gnat_rm/implementation_defined_attributes attribute-restriction-set}@anchor{19a}
@section Attribute Restriction_Set
@@ -11124,7 +11147,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{19a}
+@anchor{gnat_rm/implementation_defined_attributes attribute-result}@anchor{19b}
@section Attribute Result
@@ -11137,7 +11160,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{19b}
+@anchor{gnat_rm/implementation_defined_attributes attribute-safe-emax}@anchor{19c}
@section Attribute Safe_Emax
@@ -11150,7 +11173,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{19c}
+@anchor{gnat_rm/implementation_defined_attributes attribute-safe-large}@anchor{19d}
@section Attribute Safe_Large
@@ -11163,7 +11186,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{19d}
+@anchor{gnat_rm/implementation_defined_attributes attribute-safe-small}@anchor{19e}
@section Attribute Safe_Small
@@ -11176,7 +11199,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{19e}@anchor{gnat_rm/implementation_defined_attributes attribute-scalar-storage-order}@anchor{151}
+@anchor{gnat_rm/implementation_defined_attributes id4}@anchor{19f}@anchor{gnat_rm/implementation_defined_attributes attribute-scalar-storage-order}@anchor{151}
@section Attribute Scalar_Storage_Order
@@ -11299,7 +11322,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{e5}@anchor{gnat_rm/implementation_defined_attributes id5}@anchor{19f}
+@anchor{gnat_rm/implementation_defined_attributes attribute-simple-storage-pool}@anchor{e5}@anchor{gnat_rm/implementation_defined_attributes id5}@anchor{1a0}
@section Attribute Simple_Storage_Pool
@@ -11361,8 +11384,8 @@ parameter. The detailed semantics of such unchecked deallocations is the same
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{1a0}
+@node Attribute Small,Attribute Small_Denominator,Attribute Simple_Storage_Pool,Implementation Defined Attributes
+@anchor{gnat_rm/implementation_defined_attributes attribute-small}@anchor{1a1}
@section Attribute Small
@@ -11377,8 +11400,34 @@ for compatibility with Ada 83. See
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{1a1}
+@node Attribute Small_Denominator,Attribute Small_Numerator,Attribute Small,Implementation Defined Attributes
+@anchor{gnat_rm/implementation_defined_attributes attribute-small-denominator}@anchor{1a2}
+@section Attribute Small_Denominator
+
+
+@geindex Small
+
+@geindex Small_Denominator
+
+@code{typ'Small_Denominator} for any fixed-point subtype @cite{typ} yields the
+denominator in the representation of @code{typ'Small} as a rational number
+with coprime factors (i.e. as an irreducible fraction).
+
+@node Attribute Small_Numerator,Attribute Storage_Unit,Attribute Small_Denominator,Implementation Defined Attributes
+@anchor{gnat_rm/implementation_defined_attributes attribute-small-numerator}@anchor{1a3}
+@section Attribute Small_Numerator
+
+
+@geindex Small
+
+@geindex Small_Numerator
+
+@code{typ'Small_Numerator} for any fixed-point subtype @cite{typ} yields the
+numerator in the representation of @code{typ'Small} as a rational number
+with coprime factors (i.e. as an irreducible fraction).
+
+@node Attribute Storage_Unit,Attribute Stub_Type,Attribute Small_Numerator,Implementation Defined Attributes
+@anchor{gnat_rm/implementation_defined_attributes attribute-storage-unit}@anchor{1a4}
@section Attribute Storage_Unit
@@ -11388,7 +11437,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{1a2}
+@anchor{gnat_rm/implementation_defined_attributes attribute-stub-type}@anchor{1a5}
@section Attribute Stub_Type
@@ -11412,7 +11461,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{1a3}
+@anchor{gnat_rm/implementation_defined_attributes attribute-system-allocator-alignment}@anchor{1a6}
@section Attribute System_Allocator_Alignment
@@ -11429,7 +11478,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{1a4}
+@anchor{gnat_rm/implementation_defined_attributes attribute-target-name}@anchor{1a7}
@section Attribute Target_Name
@@ -11442,7 +11491,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{1a5}
+@anchor{gnat_rm/implementation_defined_attributes attribute-to-address}@anchor{1a8}
@section Attribute To_Address
@@ -11465,7 +11514,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{1a6}
+@anchor{gnat_rm/implementation_defined_attributes attribute-to-any}@anchor{1a9}
@section Attribute To_Any
@@ -11475,7 +11524,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{1a7}
+@anchor{gnat_rm/implementation_defined_attributes attribute-type-class}@anchor{1aa}
@section Attribute Type_Class
@@ -11505,7 +11554,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{1a8}
+@anchor{gnat_rm/implementation_defined_attributes attribute-type-key}@anchor{1ab}
@section Attribute Type_Key
@@ -11517,7 +11566,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{1a9}
+@anchor{gnat_rm/implementation_defined_attributes attribute-typecode}@anchor{1ac}
@section Attribute TypeCode
@@ -11527,7 +11576,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{1aa}
+@anchor{gnat_rm/implementation_defined_attributes attribute-unconstrained-array}@anchor{1ad}
@section Attribute Unconstrained_Array
@@ -11541,7 +11590,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{1ab}
+@anchor{gnat_rm/implementation_defined_attributes attribute-universal-literal-string}@anchor{1ae}
@section Attribute Universal_Literal_String
@@ -11569,7 +11618,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{1ac}
+@anchor{gnat_rm/implementation_defined_attributes attribute-unrestricted-access}@anchor{1af}
@section Attribute Unrestricted_Access
@@ -11756,7 +11805,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{1ad}
+@anchor{gnat_rm/implementation_defined_attributes attribute-update}@anchor{1b0}
@section Attribute Update
@@ -11837,7 +11886,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{1ae}
+@anchor{gnat_rm/implementation_defined_attributes attribute-valid-scalars}@anchor{1b1}
@section Attribute Valid_Scalars
@@ -11871,7 +11920,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{1af}
+@anchor{gnat_rm/implementation_defined_attributes attribute-vads-size}@anchor{1b2}
@section Attribute VADS_Size
@@ -11891,7 +11940,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{1b0}@anchor{gnat_rm/implementation_defined_attributes attribute-value-size}@anchor{160}
+@anchor{gnat_rm/implementation_defined_attributes id6}@anchor{1b3}@anchor{gnat_rm/implementation_defined_attributes attribute-value-size}@anchor{160}
@section Attribute Value_Size
@@ -11905,7 +11954,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{1b1}
+@anchor{gnat_rm/implementation_defined_attributes attribute-wchar-t-size}@anchor{1b4}
@section Attribute Wchar_T_Size
@@ -11917,7 +11966,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{1b2}
+@anchor{gnat_rm/implementation_defined_attributes attribute-word-size}@anchor{1b5}
@section Attribute Word_Size
@@ -11928,7 +11977,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{1b3}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id1}@anchor{1b4}
+@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{1b6}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id1}@anchor{1b7}
@chapter Standard and Implementation Defined Restrictions
@@ -11957,7 +12006,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{1b5}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id2}@anchor{1b6}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions partition-wide-restrictions}@anchor{1b8}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id2}@anchor{1b9}
@section Partition-Wide Restrictions
@@ -12046,7 +12095,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{1b7}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions immediate-reclamation}@anchor{1ba}
@subsection Immediate_Reclamation
@@ -12058,7 +12107,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{1b8}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-asynchronous-select-nesting}@anchor{1bb}
@subsection Max_Asynchronous_Select_Nesting
@@ -12070,7 +12119,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{1b9}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-entry-queue-length}@anchor{1bc}
@subsection Max_Entry_Queue_Length
@@ -12091,7 +12140,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{1ba}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-protected-entries}@anchor{1bd}
@subsection Max_Protected_Entries
@@ -12102,7 +12151,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{1bb}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-select-alternatives}@anchor{1be}
@subsection Max_Select_Alternatives
@@ -12111,7 +12160,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{1bc}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-storage-at-blocking}@anchor{1bf}
@subsection Max_Storage_At_Blocking
@@ -12122,7 +12171,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{1bd}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-task-entries}@anchor{1c0}
@subsection Max_Task_Entries
@@ -12135,7 +12184,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{1be}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-tasks}@anchor{1c1}
@subsection Max_Tasks
@@ -12148,7 +12197,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{1bf}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-abort-statements}@anchor{1c2}
@subsection No_Abort_Statements
@@ -12158,7 +12207,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{1c0}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-access-parameter-allocators}@anchor{1c3}
@subsection No_Access_Parameter_Allocators
@@ -12169,7 +12218,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{1c1}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-access-subprograms}@anchor{1c4}
@subsection No_Access_Subprograms
@@ -12179,7 +12228,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{1c2}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-allocators}@anchor{1c5}
@subsection No_Allocators
@@ -12189,7 +12238,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{1c3}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-anonymous-allocators}@anchor{1c6}
@subsection No_Anonymous_Allocators
@@ -12199,7 +12248,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{1c4}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-asynchronous-control}@anchor{1c7}
@subsection No_Asynchronous_Control
@@ -12209,7 +12258,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{1c5}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-calendar}@anchor{1c8}
@subsection No_Calendar
@@ -12219,7 +12268,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{1c6}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-coextensions}@anchor{1c9}
@subsection No_Coextensions
@@ -12229,7 +12278,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{1c7}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-default-initialization}@anchor{1ca}
@subsection No_Default_Initialization
@@ -12246,7 +12295,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{1c8}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-delay}@anchor{1cb}
@subsection No_Delay
@@ -12256,7 +12305,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{1c9}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dependence}@anchor{1cc}
@subsection No_Dependence
@@ -12266,7 +12315,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{1ca}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-direct-boolean-operators}@anchor{1cd}
@subsection No_Direct_Boolean_Operators
@@ -12279,7 +12328,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{1cb}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dispatch}@anchor{1ce}
@subsection No_Dispatch
@@ -12289,7 +12338,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{1cc}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dispatching-calls}@anchor{1cf}
@subsection No_Dispatching_Calls
@@ -12350,7 +12399,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{1cd}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-attachment}@anchor{1d0}
@subsection No_Dynamic_Attachment
@@ -12369,7 +12418,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{1ce}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-priorities}@anchor{1d1}
@subsection No_Dynamic_Priorities
@@ -12378,7 +12427,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{1cf}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-entry-calls-in-elaboration-code}@anchor{1d2}
@subsection No_Entry_Calls_In_Elaboration_Code
@@ -12390,7 +12439,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{1d0}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-enumeration-maps}@anchor{1d3}
@subsection No_Enumeration_Maps
@@ -12401,7 +12450,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{1d1}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-handlers}@anchor{1d4}
@subsection No_Exception_Handlers
@@ -12426,7 +12475,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{1d2}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-propagation}@anchor{1d5}
@subsection No_Exception_Propagation
@@ -12443,7 +12492,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{1d3}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-registration}@anchor{1d6}
@subsection No_Exception_Registration
@@ -12457,7 +12506,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{1d4}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exceptions}@anchor{1d7}
@subsection No_Exceptions
@@ -12468,7 +12517,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{1d5}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-finalization}@anchor{1d8}
@subsection No_Finalization
@@ -12509,7 +12558,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{1d6}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-fixed-point}@anchor{1d9}
@subsection No_Fixed_Point
@@ -12519,7 +12568,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{1d7}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-floating-point}@anchor{1da}
@subsection No_Floating_Point
@@ -12529,7 +12578,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{1d8}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-conditionals}@anchor{1db}
@subsection No_Implicit_Conditionals
@@ -12545,7 +12594,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{1d9}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-dynamic-code}@anchor{1dc}
@subsection No_Implicit_Dynamic_Code
@@ -12575,7 +12624,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{1da}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-heap-allocations}@anchor{1dd}
@subsection No_Implicit_Heap_Allocations
@@ -12584,7 +12633,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{1db}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-protected-object-allocations}@anchor{1de}
@subsection No_Implicit_Protected_Object_Allocations
@@ -12594,7 +12643,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{1dc}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-task-allocations}@anchor{1df}
@subsection No_Implicit_Task_Allocations
@@ -12603,7 +12652,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{1dd}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-initialize-scalars}@anchor{1e0}
@subsection No_Initialize_Scalars
@@ -12615,7 +12664,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{1de}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-io}@anchor{1e1}
@subsection No_IO
@@ -12626,7 +12675,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{1df}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-allocators}@anchor{1e2}
@subsection No_Local_Allocators
@@ -12637,7 +12686,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{1e0}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-protected-objects}@anchor{1e3}
@subsection No_Local_Protected_Objects
@@ -12647,7 +12696,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{1e1}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-timing-events}@anchor{1e4}
@subsection No_Local_Timing_Events
@@ -12657,7 +12706,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{1e2}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-long-long-integers}@anchor{1e5}
@subsection No_Long_Long_Integers
@@ -12669,7 +12718,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{1e3}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-multiple-elaboration}@anchor{1e6}
@subsection No_Multiple_Elaboration
@@ -12685,7 +12734,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{1e4}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-nested-finalization}@anchor{1e7}
@subsection No_Nested_Finalization
@@ -12694,7 +12743,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{1e5}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-protected-type-allocators}@anchor{1e8}
@subsection No_Protected_Type_Allocators
@@ -12704,7 +12753,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{1e6}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-protected-types}@anchor{1e9}
@subsection No_Protected_Types
@@ -12714,7 +12763,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{1e7}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-recursion}@anchor{1ea}
@subsection No_Recursion
@@ -12724,7 +12773,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{1e8}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-reentrancy}@anchor{1eb}
@subsection No_Reentrancy
@@ -12734,7 +12783,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{1e9}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-relative-delay}@anchor{1ec}
@subsection No_Relative_Delay
@@ -12745,7 +12794,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{1ea}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-requeue-statements}@anchor{1ed}
@subsection No_Requeue_Statements
@@ -12763,7 +12812,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{1eb}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-secondary-stack}@anchor{1ee}
@subsection No_Secondary_Stack
@@ -12776,7 +12825,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{1ec}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-select-statements}@anchor{1ef}
@subsection No_Select_Statements
@@ -12786,7 +12835,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{1ed}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-specific-termination-handlers}@anchor{1f0}
@subsection No_Specific_Termination_Handlers
@@ -12796,7 +12845,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{1ee}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-specification-of-aspect}@anchor{1f1}
@subsection No_Specification_of_Aspect
@@ -12807,7 +12856,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{1ef}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-standard-allocators-after-elaboration}@anchor{1f2}
@subsection No_Standard_Allocators_After_Elaboration
@@ -12819,7 +12868,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{1f0}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-standard-storage-pools}@anchor{1f3}
@subsection No_Standard_Storage_Pools
@@ -12831,7 +12880,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{1f1}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-stream-optimizations}@anchor{1f4}
@subsection No_Stream_Optimizations
@@ -12844,7 +12893,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{1f2}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-streams}@anchor{1f5}
@subsection No_Streams
@@ -12865,7 +12914,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{1f3}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-allocators}@anchor{1f6}
@subsection No_Task_Allocators
@@ -12875,7 +12924,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{1f4}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-at-interrupt-priority}@anchor{1f7}
@subsection No_Task_At_Interrupt_Priority
@@ -12887,7 +12936,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{1f5}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-attributes-package}@anchor{1f8}
@subsection No_Task_Attributes_Package
@@ -12904,7 +12953,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{1f6}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-hierarchy}@anchor{1f9}
@subsection No_Task_Hierarchy
@@ -12914,7 +12963,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{1f7}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-termination}@anchor{1fa}
@subsection No_Task_Termination
@@ -12923,7 +12972,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{1f8}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-tasking}@anchor{1fb}
@subsection No_Tasking
@@ -12936,7 +12985,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{1f9}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-terminate-alternatives}@anchor{1fc}
@subsection No_Terminate_Alternatives
@@ -12945,7 +12994,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{1fa}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-access}@anchor{1fd}
@subsection No_Unchecked_Access
@@ -12955,7 +13004,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{1fb}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-conversion}@anchor{1fe}
@subsection No_Unchecked_Conversion
@@ -12965,7 +13014,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{1fc}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-deallocation}@anchor{1ff}
@subsection No_Unchecked_Deallocation
@@ -12975,7 +13024,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{1fd}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-use-of-entity}@anchor{200}
@subsection No_Use_Of_Entity
@@ -12995,7 +13044,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{1fe}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions pure-barriers}@anchor{201}
@subsection Pure_Barriers
@@ -13046,7 +13095,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{1ff}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions simple-barriers}@anchor{202}
@subsection Simple_Barriers
@@ -13065,7 +13114,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{200}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-priorities}@anchor{203}
@subsection Static_Priorities
@@ -13076,7 +13125,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{201}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-storage-size}@anchor{204}
@subsection Static_Storage_Size
@@ -13086,7 +13135,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{202}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id3}@anchor{203}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions program-unit-level-restrictions}@anchor{205}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id3}@anchor{206}
@section Program Unit Level Restrictions
@@ -13116,7 +13165,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{204}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-elaboration-code}@anchor{207}
@subsection No_Elaboration_Code
@@ -13172,7 +13221,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{205}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-sized-objects}@anchor{208}
@subsection No_Dynamic_Sized_Objects
@@ -13190,7 +13239,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{206}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-entry-queue}@anchor{209}
@subsection No_Entry_Queue
@@ -13203,7 +13252,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{207}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-aspect-specifications}@anchor{20a}
@subsection No_Implementation_Aspect_Specifications
@@ -13214,7 +13263,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{208}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-attributes}@anchor{20b}
@subsection No_Implementation_Attributes
@@ -13226,7 +13275,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{209}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-identifiers}@anchor{20c}
@subsection No_Implementation_Identifiers
@@ -13237,7 +13286,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{20a}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-pragmas}@anchor{20d}
@subsection No_Implementation_Pragmas
@@ -13248,7 +13297,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{20b}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-restrictions}@anchor{20e}
@subsection No_Implementation_Restrictions
@@ -13260,7 +13309,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{20c}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-units}@anchor{20f}
@subsection No_Implementation_Units
@@ -13271,7 +13320,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{20d}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-aliasing}@anchor{210}
@subsection No_Implicit_Aliasing
@@ -13286,7 +13335,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{20e}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-loops}@anchor{211}
@subsection No_Implicit_Loops
@@ -13303,7 +13352,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{20f}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-obsolescent-features}@anchor{212}
@subsection No_Obsolescent_Features
@@ -13313,7 +13362,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{210}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-wide-characters}@anchor{213}
@subsection No_Wide_Characters
@@ -13327,7 +13376,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{211}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-dispatch-tables}@anchor{214}
@subsection Static_Dispatch_Tables
@@ -13337,7 +13386,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{212}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions spark-05}@anchor{215}
@subsection SPARK_05
@@ -13360,7 +13409,7 @@ gnatprove -P project.gpr --mode=check_all
@end example
@node Implementation Advice,Implementation Defined Characteristics,Standard and Implementation Defined Restrictions,Top
-@anchor{gnat_rm/implementation_advice doc}@anchor{213}@anchor{gnat_rm/implementation_advice implementation-advice}@anchor{a}@anchor{gnat_rm/implementation_advice id1}@anchor{214}
+@anchor{gnat_rm/implementation_advice doc}@anchor{216}@anchor{gnat_rm/implementation_advice implementation-advice}@anchor{a}@anchor{gnat_rm/implementation_advice id1}@anchor{217}
@chapter Implementation Advice
@@ -13457,7 +13506,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{215}
+@anchor{gnat_rm/implementation_advice rm-1-1-3-20-error-detection}@anchor{218}
@section RM 1.1.3(20): Error Detection
@@ -13474,7 +13523,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{216}
+@anchor{gnat_rm/implementation_advice rm-1-1-3-31-child-units}@anchor{219}
@section RM 1.1.3(31): Child Units
@@ -13490,7 +13539,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{217}
+@anchor{gnat_rm/implementation_advice rm-1-1-5-12-bounded-errors}@anchor{21a}
@section RM 1.1.5(12): Bounded Errors
@@ -13507,7 +13556,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{218}@anchor{gnat_rm/implementation_advice rm-2-8-16-pragmas}@anchor{219}
+@anchor{gnat_rm/implementation_advice id2}@anchor{21b}@anchor{gnat_rm/implementation_advice rm-2-8-16-pragmas}@anchor{21c}
@section RM 2.8(16): Pragmas
@@ -13620,7 +13669,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{21a}
+@anchor{gnat_rm/implementation_advice rm-2-8-17-19-pragmas}@anchor{21d}
@section RM 2.8(17-19): Pragmas
@@ -13641,14 +13690,14 @@ replacing @code{library_items}."
@end itemize
@end quotation
-See @ref{219,,RM 2.8(16); Pragmas}.
+See @ref{21c,,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{21b}
+@anchor{gnat_rm/implementation_advice rm-3-5-2-5-alternative-character-sets}@anchor{21e}
@section RM 3.5.2(5): Alternative Character Sets
@@ -13676,7 +13725,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{21c}
+@anchor{gnat_rm/implementation_advice rm-3-5-4-28-integer-types}@anchor{21f}
@section RM 3.5.4(28): Integer Types
@@ -13695,7 +13744,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{21d}
+@anchor{gnat_rm/implementation_advice rm-3-5-4-29-integer-types}@anchor{220}
@section RM 3.5.4(29): Integer Types
@@ -13711,7 +13760,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{21e}
+@anchor{gnat_rm/implementation_advice rm-3-5-5-8-enumeration-values}@anchor{221}
@section RM 3.5.5(8): Enumeration Values
@@ -13731,7 +13780,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{21f}
+@anchor{gnat_rm/implementation_advice rm-3-5-7-17-float-types}@anchor{222}
@section RM 3.5.7(17): Float Types
@@ -13761,7 +13810,7 @@ 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{220}
+@anchor{gnat_rm/implementation_advice rm-3-6-2-11-multidimensional-arrays}@anchor{223}
@section RM 3.6.2(11): Multidimensional Arrays
@@ -13779,7 +13828,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{221}
+@anchor{gnat_rm/implementation_advice rm-9-6-30-31-duration-small}@anchor{224}
@section RM 9.6(30-31): Duration'Small
@@ -13800,7 +13849,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{222}
+@anchor{gnat_rm/implementation_advice rm-10-2-1-12-consistent-representation}@anchor{225}
@section RM 10.2.1(12): Consistent Representation
@@ -13822,7 +13871,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{223}
+@anchor{gnat_rm/implementation_advice rm-11-4-1-19-exception-information}@anchor{226}
@section RM 11.4.1(19): Exception Information
@@ -13853,7 +13902,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{224}
+@anchor{gnat_rm/implementation_advice rm-11-5-28-suppression-of-checks}@anchor{227}
@section RM 11.5(28): Suppression of Checks
@@ -13868,7 +13917,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{225}
+@anchor{gnat_rm/implementation_advice rm-13-1-21-24-representation-clauses}@anchor{228}
@section RM 13.1 (21-24): Representation Clauses
@@ -13917,7 +13966,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{226}
+@anchor{gnat_rm/implementation_advice rm-13-2-6-8-packed-types}@anchor{229}
@section RM 13.2(6-8): Packed Types
@@ -13956,7 +14005,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{227}
+@anchor{gnat_rm/implementation_advice rm-13-3-14-19-address-clauses}@anchor{22a}
@section RM 13.3(14-19): Address Clauses
@@ -14009,7 +14058,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{228}
+@anchor{gnat_rm/implementation_advice rm-13-3-29-35-alignment-clauses}@anchor{22b}
@section RM 13.3(29-35): Alignment Clauses
@@ -14066,7 +14115,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{229}
+@anchor{gnat_rm/implementation_advice rm-13-3-42-43-size-clauses}@anchor{22c}
@section RM 13.3(42-43): Size Clauses
@@ -14084,7 +14133,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{22a}
+@anchor{gnat_rm/implementation_advice rm-13-3-50-56-size-clauses}@anchor{22d}
@section RM 13.3(50-56): Size Clauses
@@ -14135,7 +14184,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{22b}
+@anchor{gnat_rm/implementation_advice rm-13-3-71-73-component-size-clauses}@anchor{22e}
@section RM 13.3(71-73): Component Size Clauses
@@ -14169,7 +14218,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{22c}
+@anchor{gnat_rm/implementation_advice rm-13-4-9-10-enumeration-representation-clauses}@anchor{22f}
@section RM 13.4(9-10): Enumeration Representation Clauses
@@ -14191,7 +14240,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{22d}
+@anchor{gnat_rm/implementation_advice rm-13-5-1-17-22-record-representation-clauses}@anchor{230}
@section RM 13.5.1(17-22): Record Representation Clauses
@@ -14251,7 +14300,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{22e}
+@anchor{gnat_rm/implementation_advice rm-13-5-2-5-storage-place-attributes}@anchor{231}
@section RM 13.5.2(5): Storage Place Attributes
@@ -14271,7 +14320,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{22f}
+@anchor{gnat_rm/implementation_advice rm-13-5-3-7-8-bit-ordering}@anchor{232}
@section RM 13.5.3(7-8): Bit Ordering
@@ -14291,7 +14340,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{230}
+@anchor{gnat_rm/implementation_advice rm-13-7-37-address-as-private}@anchor{233}
@section RM 13.7(37): Address as Private
@@ -14309,7 +14358,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{231}
+@anchor{gnat_rm/implementation_advice rm-13-7-1-16-address-operations}@anchor{234}
@section RM 13.7.1(16): Address Operations
@@ -14327,7 +14376,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{232}
+@anchor{gnat_rm/implementation_advice rm-13-9-14-17-unchecked-conversion}@anchor{235}
@section RM 13.9(14-17): Unchecked Conversion
@@ -14371,7 +14420,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{233}
+@anchor{gnat_rm/implementation_advice rm-13-11-23-25-implicit-heap-usage}@anchor{236}
@section RM 13.11(23-25): Implicit Heap Usage
@@ -14422,7 +14471,7 @@ Followed.
@geindex Unchecked deallocation
@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{234}
+@anchor{gnat_rm/implementation_advice rm-13-11-2-17-unchecked-deallocation}@anchor{237}
@section RM 13.11.2(17): Unchecked Deallocation
@@ -14437,7 +14486,7 @@ Followed.
@geindex 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{235}
+@anchor{gnat_rm/implementation_advice rm-13-13-2-1-6-stream-oriented-attributes}@anchor{238}
@section RM 13.13.2(1.6): Stream Oriented Attributes
@@ -14468,7 +14517,7 @@ scalar types. This XDR alternative can be enabled via the binder switch -xdr.
@geindex Stream oriented attributes
@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{236}
+@anchor{gnat_rm/implementation_advice rm-a-1-52-names-of-predefined-numeric-types}@anchor{239}
@section RM A.1(52): Names of Predefined Numeric Types
@@ -14486,7 +14535,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{237}
+@anchor{gnat_rm/implementation_advice rm-a-3-2-49-ada-characters-handling}@anchor{23a}
@section RM A.3.2(49): @code{Ada.Characters.Handling}
@@ -14503,7 +14552,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{238}
+@anchor{gnat_rm/implementation_advice rm-a-4-4-106-bounded-length-string-handling}@anchor{23b}
@section RM A.4.4(106): Bounded-Length String Handling
@@ -14518,7 +14567,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{239}
+@anchor{gnat_rm/implementation_advice rm-a-5-2-46-47-random-number-generation}@anchor{23c}
@section RM A.5.2(46-47): Random Number Generation
@@ -14547,7 +14596,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{23a}
+@anchor{gnat_rm/implementation_advice rm-a-10-7-23-get-immediate}@anchor{23d}
@section RM A.10.7(23): @code{Get_Immediate}
@@ -14571,7 +14620,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{23b}
+@anchor{gnat_rm/implementation_advice rm-b-1-39-41-pragma-export}@anchor{23e}
@section RM B.1(39-41): Pragma @code{Export}
@@ -14619,7 +14668,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{23c}
+@anchor{gnat_rm/implementation_advice rm-b-2-12-13-package-interfaces}@anchor{23f}
@section RM B.2(12-13): Package @code{Interfaces}
@@ -14649,7 +14698,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{23d}
+@anchor{gnat_rm/implementation_advice rm-b-3-63-71-interfacing-with-c}@anchor{240}
@section RM B.3(63-71): Interfacing with C
@@ -14737,7 +14786,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{23e}
+@anchor{gnat_rm/implementation_advice rm-b-4-95-98-interfacing-with-cobol}@anchor{241}
@section RM B.4(95-98): Interfacing with COBOL
@@ -14778,7 +14827,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{23f}
+@anchor{gnat_rm/implementation_advice rm-b-5-22-26-interfacing-with-fortran}@anchor{242}
@section RM B.5(22-26): Interfacing with Fortran
@@ -14829,7 +14878,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{240}
+@anchor{gnat_rm/implementation_advice rm-c-1-3-5-access-to-machine-operations}@anchor{243}
@section RM C.1(3-5): Access to Machine Operations
@@ -14864,7 +14913,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{241}
+@anchor{gnat_rm/implementation_advice rm-c-1-10-16-access-to-machine-operations}@anchor{244}
@section RM C.1(10-16): Access to Machine Operations
@@ -14925,7 +14974,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{242}
+@anchor{gnat_rm/implementation_advice rm-c-3-28-interrupt-support}@anchor{245}
@section RM C.3(28): Interrupt Support
@@ -14943,7 +14992,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{243}
+@anchor{gnat_rm/implementation_advice rm-c-3-1-20-21-protected-procedure-handlers}@anchor{246}
@section RM C.3.1(20-21): Protected Procedure Handlers
@@ -14969,7 +15018,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{244}
+@anchor{gnat_rm/implementation_advice rm-c-3-2-25-package-interrupts}@anchor{247}
@section RM C.3.2(25): Package @code{Interrupts}
@@ -14987,7 +15036,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{245}
+@anchor{gnat_rm/implementation_advice rm-c-4-14-pre-elaboration-requirements}@anchor{248}
@section RM C.4(14): Pre-elaboration Requirements
@@ -15003,7 +15052,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{246}
+@anchor{gnat_rm/implementation_advice rm-c-5-8-pragma-discard-names}@anchor{249}
@section RM C.5(8): Pragma @code{Discard_Names}
@@ -15021,7 +15070,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{247}
+@anchor{gnat_rm/implementation_advice rm-c-7-2-30-the-package-task-attributes}@anchor{24a}
@section RM C.7.2(30): The Package Task_Attributes
@@ -15042,7 +15091,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{248}
+@anchor{gnat_rm/implementation_advice rm-d-3-17-locking-policies}@anchor{24b}
@section RM D.3(17): Locking Policies
@@ -15059,7 +15108,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{249}
+@anchor{gnat_rm/implementation_advice rm-d-4-16-entry-queuing-policies}@anchor{24c}
@section RM D.4(16): Entry Queuing Policies
@@ -15074,7 +15123,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{24a}
+@anchor{gnat_rm/implementation_advice rm-d-6-9-10-preemptive-abort}@anchor{24d}
@section RM D.6(9-10): Preemptive Abort
@@ -15100,7 +15149,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{24b}
+@anchor{gnat_rm/implementation_advice rm-d-7-21-tasking-restrictions}@anchor{24e}
@section RM D.7(21): Tasking Restrictions
@@ -15119,7 +15168,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{24c}
+@anchor{gnat_rm/implementation_advice rm-d-8-47-49-monotonic-time}@anchor{24f}
@section RM D.8(47-49): Monotonic Time
@@ -15154,7 +15203,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{24d}
+@anchor{gnat_rm/implementation_advice rm-e-5-28-29-partition-communication-subsystem}@anchor{250}
@section RM E.5(28-29): Partition Communication Subsystem
@@ -15182,7 +15231,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{24e}
+@anchor{gnat_rm/implementation_advice rm-f-7-cobol-support}@anchor{251}
@section RM F(7): COBOL Support
@@ -15202,7 +15251,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{24f}
+@anchor{gnat_rm/implementation_advice rm-f-1-2-decimal-radix-support}@anchor{252}
@section RM F.1(2): Decimal Radix Support
@@ -15218,7 +15267,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{250}
+@anchor{gnat_rm/implementation_advice rm-g-numerics}@anchor{253}
@section RM G: Numerics
@@ -15238,7 +15287,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{251}
+@anchor{gnat_rm/implementation_advice rm-g-1-1-56-58-complex-types}@anchor{254}
@section RM G.1.1(56-58): Complex Types
@@ -15300,7 +15349,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{252}
+@anchor{gnat_rm/implementation_advice rm-g-1-2-49-complex-elementary-functions}@anchor{255}
@section RM G.1.2(49): Complex Elementary Functions
@@ -15322,7 +15371,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{253}
+@anchor{gnat_rm/implementation_advice rm-g-2-4-19-accuracy-requirements}@anchor{256}
@section RM G.2.4(19): Accuracy Requirements
@@ -15346,7 +15395,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{254}
+@anchor{gnat_rm/implementation_advice rm-g-2-6-15-complex-arithmetic-accuracy}@anchor{257}
@section RM G.2.6(15): Complex Arithmetic Accuracy
@@ -15364,7 +15413,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{255}
+@anchor{gnat_rm/implementation_advice rm-h-6-15-2-pragma-partition-elaboration-policy}@anchor{258}
@section RM H.6(15/2): Pragma Partition_Elaboration_Policy
@@ -15379,7 +15428,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{256}@anchor{gnat_rm/implementation_defined_characteristics id1}@anchor{257}
+@anchor{gnat_rm/implementation_defined_characteristics implementation-defined-characteristics}@anchor{b}@anchor{gnat_rm/implementation_defined_characteristics doc}@anchor{259}@anchor{gnat_rm/implementation_defined_characteristics id1}@anchor{25a}
@chapter Implementation Defined Characteristics
@@ -15690,13 +15739,27 @@ The small is the largest power of two that does not exceed the delta.
supported for fixed point types. See 3.5.9(10)."
@end itemize
-For an ordinary fixed point type, the small must lie in 2**(-80) .. 2**80
-and the range in -10.0**36 .. 10.0**36; any combination is permitted that
-does not result in a mantissa larger than 63 bits. However, if the mantissa
-is larger than 53 bits on machines where Long_Long_Float is 64 bits (true
-of all architectures except x86), then the output from Text_IO may be
-accurate to only 53 bits, rather than the full mantissa. This is because
-floating-point conversions may be used to convert fixed point.
+For an ordinary fixed point type, on 32-bit platforms, the small must lie in
+2.0**(-80) .. 2.0**80 and the range in -9.0E+36 .. 9.0E+36; any combination
+is permitted that does not result in a mantissa larger than 63 bits.
+
+On 64-bit platforms, the small must lie in 2.0**(-127) .. 2.0**127 and the
+range in -1.0E+76 .. 1.0E+76; any combination is permitted that does not
+result in a mantissa larger than 63 bits, and any combination is permitted
+that results in a mantissa between 64 and 127 bits if the small is the
+ratio of two integers that lie in 1 .. 2.0**127.
+
+If the small is the ratio of two integers with 64-bit magnitude on 32-bit
+platforms and 128-bit magnitude on 64-bit platforms, which is the case if
+no @code{small} clause is provided, then the operations of the fixed point
+type are entirely implemented by means of integer instructions. In the
+other cases, some operations, in particular input and output, may be
+implemented by means of floating-point instructions and may be affected
+by accuracy issues on architectures other than x86.
+
+For a decimal fixed point type, on 32-bit platforms, the small must lie in
+1.0E-18 .. 1.0E+18 and the digits in 1 .. 18. On 64-bit platforms, the
+small must lie in 1.0E-38 .. 1.0E+38 and the digits in 1 .. 38.
@itemize *
@@ -16584,7 +16647,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{258,,GNAT.Regexp (g-regexp.ads)}.
+See @ref{25b,,GNAT.Regexp (g-regexp.ads)}.
@itemize *
@@ -17632,7 +17695,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{259}@anchor{gnat_rm/intrinsic_subprograms intrinsic-subprograms}@anchor{c}@anchor{gnat_rm/intrinsic_subprograms id1}@anchor{25a}
+@anchor{gnat_rm/intrinsic_subprograms doc}@anchor{25c}@anchor{gnat_rm/intrinsic_subprograms intrinsic-subprograms}@anchor{c}@anchor{gnat_rm/intrinsic_subprograms id1}@anchor{25d}
@chapter Intrinsic Subprograms
@@ -17670,7 +17733,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{25b}@anchor{gnat_rm/intrinsic_subprograms intrinsic-operators}@anchor{25c}
+@anchor{gnat_rm/intrinsic_subprograms id2}@anchor{25e}@anchor{gnat_rm/intrinsic_subprograms intrinsic-operators}@anchor{25f}
@section Intrinsic Operators
@@ -17701,7 +17764,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{25d}@anchor{gnat_rm/intrinsic_subprograms compilation-iso-date}@anchor{25e}
+@anchor{gnat_rm/intrinsic_subprograms id3}@anchor{260}@anchor{gnat_rm/intrinsic_subprograms compilation-iso-date}@anchor{261}
@section Compilation_ISO_Date
@@ -17715,7 +17778,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{25f}@anchor{gnat_rm/intrinsic_subprograms id4}@anchor{260}
+@anchor{gnat_rm/intrinsic_subprograms compilation-date}@anchor{262}@anchor{gnat_rm/intrinsic_subprograms id4}@anchor{263}
@section Compilation_Date
@@ -17725,7 +17788,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{261}@anchor{gnat_rm/intrinsic_subprograms id5}@anchor{262}
+@anchor{gnat_rm/intrinsic_subprograms compilation-time}@anchor{264}@anchor{gnat_rm/intrinsic_subprograms id5}@anchor{265}
@section Compilation_Time
@@ -17739,7 +17802,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{263}@anchor{gnat_rm/intrinsic_subprograms enclosing-entity}@anchor{264}
+@anchor{gnat_rm/intrinsic_subprograms id6}@anchor{266}@anchor{gnat_rm/intrinsic_subprograms enclosing-entity}@anchor{267}
@section Enclosing_Entity
@@ -17753,7 +17816,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{265}@anchor{gnat_rm/intrinsic_subprograms exception-information}@anchor{266}
+@anchor{gnat_rm/intrinsic_subprograms id7}@anchor{268}@anchor{gnat_rm/intrinsic_subprograms exception-information}@anchor{269}
@section Exception_Information
@@ -17767,7 +17830,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{267}@anchor{gnat_rm/intrinsic_subprograms id8}@anchor{268}
+@anchor{gnat_rm/intrinsic_subprograms exception-message}@anchor{26a}@anchor{gnat_rm/intrinsic_subprograms id8}@anchor{26b}
@section Exception_Message
@@ -17781,7 +17844,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{269}@anchor{gnat_rm/intrinsic_subprograms id9}@anchor{26a}
+@anchor{gnat_rm/intrinsic_subprograms exception-name}@anchor{26c}@anchor{gnat_rm/intrinsic_subprograms id9}@anchor{26d}
@section Exception_Name
@@ -17795,7 +17858,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{26b}@anchor{gnat_rm/intrinsic_subprograms file}@anchor{26c}
+@anchor{gnat_rm/intrinsic_subprograms id10}@anchor{26e}@anchor{gnat_rm/intrinsic_subprograms file}@anchor{26f}
@section File
@@ -17809,7 +17872,7 @@ application program should simply call the function
file.
@node Line,Shifts and Rotates,File,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms id11}@anchor{26d}@anchor{gnat_rm/intrinsic_subprograms line}@anchor{26e}
+@anchor{gnat_rm/intrinsic_subprograms id11}@anchor{270}@anchor{gnat_rm/intrinsic_subprograms line}@anchor{271}
@section Line
@@ -17823,7 +17886,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{26f}@anchor{gnat_rm/intrinsic_subprograms id12}@anchor{270}
+@anchor{gnat_rm/intrinsic_subprograms shifts-and-rotates}@anchor{272}@anchor{gnat_rm/intrinsic_subprograms id12}@anchor{273}
@section Shifts and Rotates
@@ -17859,10 +17922,12 @@ The formal parameter names can be anything.
A more convenient way of providing these shift operators is to use
the Provide_Shift_Operators pragma, which provides the function declarations
-and corresponding pragma Import's for all five shift functions.
+and corresponding pragma Import's for all five shift functions. Note that in
+using these provided shift operations, shifts performed on negative numbers
+will result in modification of the sign bit.
@node Source_Location,,Shifts and Rotates,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms source-location}@anchor{271}@anchor{gnat_rm/intrinsic_subprograms id13}@anchor{272}
+@anchor{gnat_rm/intrinsic_subprograms source-location}@anchor{274}@anchor{gnat_rm/intrinsic_subprograms id13}@anchor{275}
@section Source_Location
@@ -17876,7 +17941,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{273}@anchor{gnat_rm/representation_clauses_and_pragmas id1}@anchor{274}
+@anchor{gnat_rm/representation_clauses_and_pragmas representation-clauses-and-pragmas}@anchor{d}@anchor{gnat_rm/representation_clauses_and_pragmas doc}@anchor{276}@anchor{gnat_rm/representation_clauses_and_pragmas id1}@anchor{277}
@chapter Representation Clauses and Pragmas
@@ -17922,7 +17987,7 @@ 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{275}@anchor{gnat_rm/representation_clauses_and_pragmas alignment-clauses}@anchor{276}
+@anchor{gnat_rm/representation_clauses_and_pragmas id2}@anchor{278}@anchor{gnat_rm/representation_clauses_and_pragmas alignment-clauses}@anchor{279}
@section Alignment Clauses
@@ -17944,7 +18009,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{18f,,Attribute Maximum_Alignment}.)
+@code{Standard'Maximum_Alignment}; see @ref{190,,Attribute Maximum_Alignment}.)
@geindex Maximum_Alignment attribute
@@ -18053,7 +18118,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{277}@anchor{gnat_rm/representation_clauses_and_pragmas size-clauses}@anchor{278}
+@anchor{gnat_rm/representation_clauses_and_pragmas id3}@anchor{27a}@anchor{gnat_rm/representation_clauses_and_pragmas size-clauses}@anchor{27b}
@section Size Clauses
@@ -18130,7 +18195,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{279}@anchor{gnat_rm/representation_clauses_and_pragmas id4}@anchor{27a}
+@anchor{gnat_rm/representation_clauses_and_pragmas storage-size-clauses}@anchor{27c}@anchor{gnat_rm/representation_clauses_and_pragmas id4}@anchor{27d}
@section Storage_Size Clauses
@@ -18203,7 +18268,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{27b}@anchor{gnat_rm/representation_clauses_and_pragmas size-of-variant-record-objects}@anchor{27c}
+@anchor{gnat_rm/representation_clauses_and_pragmas id5}@anchor{27e}@anchor{gnat_rm/representation_clauses_and_pragmas size-of-variant-record-objects}@anchor{27f}
@section Size of Variant Record Objects
@@ -18313,7 +18378,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{27d}@anchor{gnat_rm/representation_clauses_and_pragmas biased-representation}@anchor{27e}
+@anchor{gnat_rm/representation_clauses_and_pragmas id6}@anchor{280}@anchor{gnat_rm/representation_clauses_and_pragmas biased-representation}@anchor{281}
@section Biased Representation
@@ -18351,7 +18416,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{27f}@anchor{gnat_rm/representation_clauses_and_pragmas value-size-and-object-size-clauses}@anchor{280}
+@anchor{gnat_rm/representation_clauses_and_pragmas id7}@anchor{282}@anchor{gnat_rm/representation_clauses_and_pragmas value-size-and-object-size-clauses}@anchor{283}
@section Value_Size and Object_Size Clauses
@@ -18667,7 +18732,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{281}@anchor{gnat_rm/representation_clauses_and_pragmas component-size-clauses}@anchor{282}
+@anchor{gnat_rm/representation_clauses_and_pragmas id8}@anchor{284}@anchor{gnat_rm/representation_clauses_and_pragmas component-size-clauses}@anchor{285}
@section Component_Size Clauses
@@ -18715,7 +18780,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{283}@anchor{gnat_rm/representation_clauses_and_pragmas id9}@anchor{284}
+@anchor{gnat_rm/representation_clauses_and_pragmas bit-order-clauses}@anchor{286}@anchor{gnat_rm/representation_clauses_and_pragmas id9}@anchor{287}
@section Bit_Order Clauses
@@ -18821,7 +18886,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{285}@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-bit-order-on-byte-ordering}@anchor{286}
+@anchor{gnat_rm/representation_clauses_and_pragmas id10}@anchor{288}@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-bit-order-on-byte-ordering}@anchor{289}
@section Effect of Bit_Order on Byte Ordering
@@ -19078,7 +19143,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{287}@anchor{gnat_rm/representation_clauses_and_pragmas id11}@anchor{288}
+@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-arrays}@anchor{28a}@anchor{gnat_rm/representation_clauses_and_pragmas id11}@anchor{28b}
@section Pragma Pack for Arrays
@@ -19198,7 +19263,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{289}@anchor{gnat_rm/representation_clauses_and_pragmas id12}@anchor{28a}
+@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-records}@anchor{28c}@anchor{gnat_rm/representation_clauses_and_pragmas id12}@anchor{28d}
@section Pragma Pack for Records
@@ -19282,7 +19347,7 @@ array that is longer than 64 bits, so it is itself non-packable on
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{28b}@anchor{gnat_rm/representation_clauses_and_pragmas record-representation-clauses}@anchor{28c}
+@anchor{gnat_rm/representation_clauses_and_pragmas id13}@anchor{28e}@anchor{gnat_rm/representation_clauses_and_pragmas record-representation-clauses}@anchor{28f}
@section Record Representation Clauses
@@ -19361,7 +19426,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{28d}@anchor{gnat_rm/representation_clauses_and_pragmas id14}@anchor{28e}
+@anchor{gnat_rm/representation_clauses_and_pragmas handling-of-records-with-holes}@anchor{290}@anchor{gnat_rm/representation_clauses_and_pragmas id14}@anchor{291}
@section Handling of Records with Holes
@@ -19437,7 +19502,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{28f}@anchor{gnat_rm/representation_clauses_and_pragmas id15}@anchor{290}
+@anchor{gnat_rm/representation_clauses_and_pragmas enumeration-clauses}@anchor{292}@anchor{gnat_rm/representation_clauses_and_pragmas id15}@anchor{293}
@section Enumeration Clauses
@@ -19480,7 +19545,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{291}@anchor{gnat_rm/representation_clauses_and_pragmas address-clauses}@anchor{292}
+@anchor{gnat_rm/representation_clauses_and_pragmas id16}@anchor{294}@anchor{gnat_rm/representation_clauses_and_pragmas address-clauses}@anchor{295}
@section Address Clauses
@@ -19809,7 +19874,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{293}@anchor{gnat_rm/representation_clauses_and_pragmas use-of-address-clauses-for-memory-mapped-i-o}@anchor{294}
+@anchor{gnat_rm/representation_clauses_and_pragmas id17}@anchor{296}@anchor{gnat_rm/representation_clauses_and_pragmas use-of-address-clauses-for-memory-mapped-i-o}@anchor{297}
@section Use of Address Clauses for Memory-Mapped I/O
@@ -19867,7 +19932,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{295}@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-convention-on-representation}@anchor{296}
+@anchor{gnat_rm/representation_clauses_and_pragmas id18}@anchor{298}@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-convention-on-representation}@anchor{299}
@section Effect of Convention on Representation
@@ -19945,7 +20010,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{297}@anchor{gnat_rm/representation_clauses_and_pragmas id19}@anchor{298}
+@anchor{gnat_rm/representation_clauses_and_pragmas conventions-and-anonymous-access-types}@anchor{29a}@anchor{gnat_rm/representation_clauses_and_pragmas id19}@anchor{29b}
@section Conventions and Anonymous Access Types
@@ -20021,7 +20086,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{299}@anchor{gnat_rm/representation_clauses_and_pragmas determining-the-representations-chosen-by-gnat}@anchor{29a}
+@anchor{gnat_rm/representation_clauses_and_pragmas id20}@anchor{29c}@anchor{gnat_rm/representation_clauses_and_pragmas determining-the-representations-chosen-by-gnat}@anchor{29d}
@section Determining the Representations chosen by GNAT
@@ -20173,7 +20238,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{29b}@anchor{gnat_rm/standard_library_routines id1}@anchor{29c}
+@anchor{gnat_rm/standard_library_routines standard-library-routines}@anchor{e}@anchor{gnat_rm/standard_library_routines doc}@anchor{29e}@anchor{gnat_rm/standard_library_routines id1}@anchor{29f}
@chapter Standard Library Routines
@@ -20997,7 +21062,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{29d}@anchor{gnat_rm/the_implementation_of_standard_i_o id1}@anchor{29e}
+@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{2a0}@anchor{gnat_rm/the_implementation_of_standard_i_o id1}@anchor{2a1}
@chapter The Implementation of Standard I/O
@@ -21049,7 +21114,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{29f}@anchor{gnat_rm/the_implementation_of_standard_i_o id2}@anchor{2a0}
+@anchor{gnat_rm/the_implementation_of_standard_i_o standard-i-o-packages}@anchor{2a2}@anchor{gnat_rm/the_implementation_of_standard_i_o id2}@anchor{2a3}
@section Standard I/O Packages
@@ -21120,7 +21185,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{2a1}@anchor{gnat_rm/the_implementation_of_standard_i_o id3}@anchor{2a2}
+@anchor{gnat_rm/the_implementation_of_standard_i_o form-strings}@anchor{2a4}@anchor{gnat_rm/the_implementation_of_standard_i_o id3}@anchor{2a5}
@section FORM Strings
@@ -21146,7 +21211,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{2a3}@anchor{gnat_rm/the_implementation_of_standard_i_o id4}@anchor{2a4}
+@anchor{gnat_rm/the_implementation_of_standard_i_o direct-io}@anchor{2a6}@anchor{gnat_rm/the_implementation_of_standard_i_o id4}@anchor{2a7}
@section Direct_IO
@@ -21166,7 +21231,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{2a5}@anchor{gnat_rm/the_implementation_of_standard_i_o id5}@anchor{2a6}
+@anchor{gnat_rm/the_implementation_of_standard_i_o sequential-io}@anchor{2a8}@anchor{gnat_rm/the_implementation_of_standard_i_o id5}@anchor{2a9}
@section Sequential_IO
@@ -21213,7 +21278,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{2a7}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io}@anchor{2a8}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id6}@anchor{2aa}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io}@anchor{2ab}
@section Text_IO
@@ -21296,7 +21361,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{2a9}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning}@anchor{2aa}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id7}@anchor{2ac}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning}@anchor{2ad}
@subsection Stream Pointer Positioning
@@ -21332,7 +21397,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{2ab}@anchor{gnat_rm/the_implementation_of_standard_i_o id8}@anchor{2ac}
+@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files}@anchor{2ae}@anchor{gnat_rm/the_implementation_of_standard_i_o id8}@anchor{2af}
@subsection Reading and Writing Non-Regular Files
@@ -21383,7 +21448,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{2ad}@anchor{gnat_rm/the_implementation_of_standard_i_o id9}@anchor{2ae}
+@anchor{gnat_rm/the_implementation_of_standard_i_o get-immediate}@anchor{2b0}@anchor{gnat_rm/the_implementation_of_standard_i_o id9}@anchor{2b1}
@subsection Get_Immediate
@@ -21401,7 +21466,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{2af}@anchor{gnat_rm/the_implementation_of_standard_i_o treating-text-io-files-as-streams}@anchor{2b0}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id10}@anchor{2b2}@anchor{gnat_rm/the_implementation_of_standard_i_o treating-text-io-files-as-streams}@anchor{2b3}
@subsection Treating Text_IO Files as Streams
@@ -21417,7 +21482,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{2b1}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-extensions}@anchor{2b2}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id11}@anchor{2b4}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-extensions}@anchor{2b5}
@subsection Text_IO Extensions
@@ -21445,7 +21510,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{2b3}@anchor{gnat_rm/the_implementation_of_standard_i_o id12}@anchor{2b4}
+@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-facilities-for-unbounded-strings}@anchor{2b6}@anchor{gnat_rm/the_implementation_of_standard_i_o id12}@anchor{2b7}
@subsection Text_IO Facilities for Unbounded Strings
@@ -21493,7 +21558,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{2b5}@anchor{gnat_rm/the_implementation_of_standard_i_o id13}@anchor{2b6}
+@anchor{gnat_rm/the_implementation_of_standard_i_o wide-text-io}@anchor{2b8}@anchor{gnat_rm/the_implementation_of_standard_i_o id13}@anchor{2b9}
@section Wide_Text_IO
@@ -21740,12 +21805,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{2b7}@anchor{gnat_rm/the_implementation_of_standard_i_o id14}@anchor{2b8}
+@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-1}@anchor{2ba}@anchor{gnat_rm/the_implementation_of_standard_i_o id14}@anchor{2bb}
@subsection Stream Pointer Positioning
@code{Ada.Wide_Text_IO} is similar to @code{Ada.Text_IO} in its handling
-of stream pointer positioning (@ref{2a8,,Text_IO}). There is one additional
+of stream pointer positioning (@ref{2ab,,Text_IO}). There is one additional
case:
If @code{Ada.Wide_Text_IO.Look_Ahead} reads a character outside the
@@ -21764,7 +21829,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{2b9}@anchor{gnat_rm/the_implementation_of_standard_i_o id15}@anchor{2ba}
+@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-1}@anchor{2bc}@anchor{gnat_rm/the_implementation_of_standard_i_o id15}@anchor{2bd}
@subsection Reading and Writing Non-Regular Files
@@ -21775,7 +21840,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{2bb}@anchor{gnat_rm/the_implementation_of_standard_i_o wide-wide-text-io}@anchor{2bc}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id16}@anchor{2be}@anchor{gnat_rm/the_implementation_of_standard_i_o wide-wide-text-io}@anchor{2bf}
@section Wide_Wide_Text_IO
@@ -21944,12 +22009,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{2bd}@anchor{gnat_rm/the_implementation_of_standard_i_o id17}@anchor{2be}
+@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-2}@anchor{2c0}@anchor{gnat_rm/the_implementation_of_standard_i_o id17}@anchor{2c1}
@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{2a8,,Text_IO}). There is one additional
+of stream pointer positioning (@ref{2ab,,Text_IO}). There is one additional
case:
If @code{Ada.Wide_Wide_Text_IO.Look_Ahead} reads a character outside the
@@ -21968,7 +22033,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{2bf}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-2}@anchor{2c0}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id18}@anchor{2c2}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-2}@anchor{2c3}
@subsection Reading and Writing Non-Regular Files
@@ -21979,7 +22044,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{2c1}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-io}@anchor{2c2}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id19}@anchor{2c4}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-io}@anchor{2c5}
@section Stream_IO
@@ -22001,7 +22066,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{2c3}@anchor{gnat_rm/the_implementation_of_standard_i_o text-translation}@anchor{2c4}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id20}@anchor{2c6}@anchor{gnat_rm/the_implementation_of_standard_i_o text-translation}@anchor{2c7}
@section Text Translation
@@ -22035,7 +22100,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{2c5}@anchor{gnat_rm/the_implementation_of_standard_i_o shared-files}@anchor{2c6}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id21}@anchor{2c8}@anchor{gnat_rm/the_implementation_of_standard_i_o shared-files}@anchor{2c9}
@section Shared Files
@@ -22098,7 +22163,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{2c7}@anchor{gnat_rm/the_implementation_of_standard_i_o id22}@anchor{2c8}
+@anchor{gnat_rm/the_implementation_of_standard_i_o filenames-encoding}@anchor{2ca}@anchor{gnat_rm/the_implementation_of_standard_i_o id22}@anchor{2cb}
@section Filenames encoding
@@ -22138,7 +22203,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{2c9}@anchor{gnat_rm/the_implementation_of_standard_i_o id23}@anchor{2ca}
+@anchor{gnat_rm/the_implementation_of_standard_i_o file-content-encoding}@anchor{2cc}@anchor{gnat_rm/the_implementation_of_standard_i_o id23}@anchor{2cd}
@section File content encoding
@@ -22171,7 +22236,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{2cb}@anchor{gnat_rm/the_implementation_of_standard_i_o id24}@anchor{2cc}
+@anchor{gnat_rm/the_implementation_of_standard_i_o open-modes}@anchor{2ce}@anchor{gnat_rm/the_implementation_of_standard_i_o id24}@anchor{2cf}
@section Open Modes
@@ -22274,7 +22339,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{2cd}@anchor{gnat_rm/the_implementation_of_standard_i_o id25}@anchor{2ce}
+@anchor{gnat_rm/the_implementation_of_standard_i_o operations-on-c-streams}@anchor{2d0}@anchor{gnat_rm/the_implementation_of_standard_i_o id25}@anchor{2d1}
@section Operations on C Streams
@@ -22434,7 +22499,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{2cf}@anchor{gnat_rm/the_implementation_of_standard_i_o id26}@anchor{2d0}
+@anchor{gnat_rm/the_implementation_of_standard_i_o interfacing-to-c-streams}@anchor{2d2}@anchor{gnat_rm/the_implementation_of_standard_i_o id26}@anchor{2d3}
@section Interfacing to C Streams
@@ -22527,7 +22592,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{2d1}@anchor{gnat_rm/the_gnat_library id1}@anchor{2d2}
+@anchor{gnat_rm/the_gnat_library the-gnat-library}@anchor{10}@anchor{gnat_rm/the_gnat_library doc}@anchor{2d4}@anchor{gnat_rm/the_gnat_library id1}@anchor{2d5}
@chapter The GNAT Library
@@ -22721,7 +22786,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{2d3}@anchor{gnat_rm/the_gnat_library ada-characters-latin-9-a-chlat9-ads}@anchor{2d4}
+@anchor{gnat_rm/the_gnat_library id2}@anchor{2d6}@anchor{gnat_rm/the_gnat_library ada-characters-latin-9-a-chlat9-ads}@anchor{2d7}
@section @code{Ada.Characters.Latin_9} (@code{a-chlat9.ads})
@@ -22738,7 +22803,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{2d5}@anchor{gnat_rm/the_gnat_library id3}@anchor{2d6}
+@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-1-a-cwila1-ads}@anchor{2d8}@anchor{gnat_rm/the_gnat_library id3}@anchor{2d9}
@section @code{Ada.Characters.Wide_Latin_1} (@code{a-cwila1.ads})
@@ -22755,7 +22820,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{2d7}@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-9-a-cwila1-ads}@anchor{2d8}
+@anchor{gnat_rm/the_gnat_library id4}@anchor{2da}@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-9-a-cwila1-ads}@anchor{2db}
@section @code{Ada.Characters.Wide_Latin_9} (@code{a-cwila1.ads})
@@ -22772,7 +22837,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{2d9}@anchor{gnat_rm/the_gnat_library id5}@anchor{2da}
+@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-1-a-chzla1-ads}@anchor{2dc}@anchor{gnat_rm/the_gnat_library id5}@anchor{2dd}
@section @code{Ada.Characters.Wide_Wide_Latin_1} (@code{a-chzla1.ads})
@@ -22789,7 +22854,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{2db}@anchor{gnat_rm/the_gnat_library id6}@anchor{2dc}
+@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-9-a-chzla9-ads}@anchor{2de}@anchor{gnat_rm/the_gnat_library id6}@anchor{2df}
@section @code{Ada.Characters.Wide_Wide_Latin_9} (@code{a-chzla9.ads})
@@ -22806,7 +22871,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{2dd}@anchor{gnat_rm/the_gnat_library ada-containers-formal-doubly-linked-lists-a-cfdlli-ads}@anchor{2de}
+@anchor{gnat_rm/the_gnat_library id7}@anchor{2e0}@anchor{gnat_rm/the_gnat_library ada-containers-formal-doubly-linked-lists-a-cfdlli-ads}@anchor{2e1}
@section @code{Ada.Containers.Formal_Doubly_Linked_Lists} (@code{a-cfdlli.ads})
@@ -22825,7 +22890,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{2df}@anchor{gnat_rm/the_gnat_library ada-containers-formal-hashed-maps-a-cfhama-ads}@anchor{2e0}
+@anchor{gnat_rm/the_gnat_library id8}@anchor{2e2}@anchor{gnat_rm/the_gnat_library ada-containers-formal-hashed-maps-a-cfhama-ads}@anchor{2e3}
@section @code{Ada.Containers.Formal_Hashed_Maps} (@code{a-cfhama.ads})
@@ -22844,7 +22909,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{2e1}@anchor{gnat_rm/the_gnat_library ada-containers-formal-hashed-sets-a-cfhase-ads}@anchor{2e2}
+@anchor{gnat_rm/the_gnat_library id9}@anchor{2e4}@anchor{gnat_rm/the_gnat_library ada-containers-formal-hashed-sets-a-cfhase-ads}@anchor{2e5}
@section @code{Ada.Containers.Formal_Hashed_Sets} (@code{a-cfhase.ads})
@@ -22863,7 +22928,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{2e3}@anchor{gnat_rm/the_gnat_library ada-containers-formal-ordered-maps-a-cforma-ads}@anchor{2e4}
+@anchor{gnat_rm/the_gnat_library id10}@anchor{2e6}@anchor{gnat_rm/the_gnat_library ada-containers-formal-ordered-maps-a-cforma-ads}@anchor{2e7}
@section @code{Ada.Containers.Formal_Ordered_Maps} (@code{a-cforma.ads})
@@ -22882,7 +22947,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{2e5}@anchor{gnat_rm/the_gnat_library id11}@anchor{2e6}
+@anchor{gnat_rm/the_gnat_library ada-containers-formal-ordered-sets-a-cforse-ads}@anchor{2e8}@anchor{gnat_rm/the_gnat_library id11}@anchor{2e9}
@section @code{Ada.Containers.Formal_Ordered_Sets} (@code{a-cforse.ads})
@@ -22901,7 +22966,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{2e7}@anchor{gnat_rm/the_gnat_library ada-containers-formal-vectors-a-cofove-ads}@anchor{2e8}
+@anchor{gnat_rm/the_gnat_library id12}@anchor{2ea}@anchor{gnat_rm/the_gnat_library ada-containers-formal-vectors-a-cofove-ads}@anchor{2eb}
@section @code{Ada.Containers.Formal_Vectors} (@code{a-cofove.ads})
@@ -22920,7 +22985,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{2e9}@anchor{gnat_rm/the_gnat_library ada-containers-formal-indefinite-vectors-a-cfinve-ads}@anchor{2ea}
+@anchor{gnat_rm/the_gnat_library id13}@anchor{2ec}@anchor{gnat_rm/the_gnat_library ada-containers-formal-indefinite-vectors-a-cfinve-ads}@anchor{2ed}
@section @code{Ada.Containers.Formal_Indefinite_Vectors} (@code{a-cfinve.ads})
@@ -22939,7 +23004,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{2eb}@anchor{gnat_rm/the_gnat_library ada-containers-functional-vectors-a-cofuve-ads}@anchor{2ec}
+@anchor{gnat_rm/the_gnat_library id14}@anchor{2ee}@anchor{gnat_rm/the_gnat_library ada-containers-functional-vectors-a-cofuve-ads}@anchor{2ef}
@section @code{Ada.Containers.Functional_Vectors} (@code{a-cofuve.ads})
@@ -22961,7 +23026,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{2ed}@anchor{gnat_rm/the_gnat_library id15}@anchor{2ee}
+@anchor{gnat_rm/the_gnat_library ada-containers-functional-sets-a-cofuse-ads}@anchor{2f0}@anchor{gnat_rm/the_gnat_library id15}@anchor{2f1}
@section @code{Ada.Containers.Functional_Sets} (@code{a-cofuse.ads})
@@ -22983,7 +23048,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{2ef}@anchor{gnat_rm/the_gnat_library ada-containers-functional-maps-a-cofuma-ads}@anchor{2f0}
+@anchor{gnat_rm/the_gnat_library id16}@anchor{2f2}@anchor{gnat_rm/the_gnat_library ada-containers-functional-maps-a-cofuma-ads}@anchor{2f3}
@section @code{Ada.Containers.Functional_Maps} (@code{a-cofuma.ads})
@@ -23005,7 +23070,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{2f1}@anchor{gnat_rm/the_gnat_library id17}@anchor{2f2}
+@anchor{gnat_rm/the_gnat_library ada-containers-bounded-holders-a-coboho-ads}@anchor{2f4}@anchor{gnat_rm/the_gnat_library id17}@anchor{2f5}
@section @code{Ada.Containers.Bounded_Holders} (@code{a-coboho.ads})
@@ -23017,7 +23082,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{2f3}@anchor{gnat_rm/the_gnat_library id18}@anchor{2f4}
+@anchor{gnat_rm/the_gnat_library ada-command-line-environment-a-colien-ads}@anchor{2f6}@anchor{gnat_rm/the_gnat_library id18}@anchor{2f7}
@section @code{Ada.Command_Line.Environment} (@code{a-colien.ads})
@@ -23030,7 +23095,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{2f5}@anchor{gnat_rm/the_gnat_library ada-command-line-remove-a-colire-ads}@anchor{2f6}
+@anchor{gnat_rm/the_gnat_library id19}@anchor{2f8}@anchor{gnat_rm/the_gnat_library ada-command-line-remove-a-colire-ads}@anchor{2f9}
@section @code{Ada.Command_Line.Remove} (@code{a-colire.ads})
@@ -23048,7 +23113,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{2f7}@anchor{gnat_rm/the_gnat_library ada-command-line-response-file-a-clrefi-ads}@anchor{2f8}
+@anchor{gnat_rm/the_gnat_library id20}@anchor{2fa}@anchor{gnat_rm/the_gnat_library ada-command-line-response-file-a-clrefi-ads}@anchor{2fb}
@section @code{Ada.Command_Line.Response_File} (@code{a-clrefi.ads})
@@ -23068,7 +23133,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{2f9}@anchor{gnat_rm/the_gnat_library ada-direct-io-c-streams-a-diocst-ads}@anchor{2fa}
+@anchor{gnat_rm/the_gnat_library id21}@anchor{2fc}@anchor{gnat_rm/the_gnat_library ada-direct-io-c-streams-a-diocst-ads}@anchor{2fd}
@section @code{Ada.Direct_IO.C_Streams} (@code{a-diocst.ads})
@@ -23083,7 +23148,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{2fb}@anchor{gnat_rm/the_gnat_library ada-exceptions-is-null-occurrence-a-einuoc-ads}@anchor{2fc}
+@anchor{gnat_rm/the_gnat_library id22}@anchor{2fe}@anchor{gnat_rm/the_gnat_library ada-exceptions-is-null-occurrence-a-einuoc-ads}@anchor{2ff}
@section @code{Ada.Exceptions.Is_Null_Occurrence} (@code{a-einuoc.ads})
@@ -23097,7 +23162,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{2fd}@anchor{gnat_rm/the_gnat_library ada-exceptions-last-chance-handler-a-elchha-ads}@anchor{2fe}
+@anchor{gnat_rm/the_gnat_library id23}@anchor{300}@anchor{gnat_rm/the_gnat_library ada-exceptions-last-chance-handler-a-elchha-ads}@anchor{301}
@section @code{Ada.Exceptions.Last_Chance_Handler} (@code{a-elchha.ads})
@@ -23111,7 +23176,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{2ff}@anchor{gnat_rm/the_gnat_library id24}@anchor{300}
+@anchor{gnat_rm/the_gnat_library ada-exceptions-traceback-a-exctra-ads}@anchor{302}@anchor{gnat_rm/the_gnat_library id24}@anchor{303}
@section @code{Ada.Exceptions.Traceback} (@code{a-exctra.ads})
@@ -23124,7 +23189,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{301}@anchor{gnat_rm/the_gnat_library id25}@anchor{302}
+@anchor{gnat_rm/the_gnat_library ada-sequential-io-c-streams-a-siocst-ads}@anchor{304}@anchor{gnat_rm/the_gnat_library id25}@anchor{305}
@section @code{Ada.Sequential_IO.C_Streams} (@code{a-siocst.ads})
@@ -23139,7 +23204,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{303}@anchor{gnat_rm/the_gnat_library ada-streams-stream-io-c-streams-a-ssicst-ads}@anchor{304}
+@anchor{gnat_rm/the_gnat_library id26}@anchor{306}@anchor{gnat_rm/the_gnat_library ada-streams-stream-io-c-streams-a-ssicst-ads}@anchor{307}
@section @code{Ada.Streams.Stream_IO.C_Streams} (@code{a-ssicst.ads})
@@ -23154,7 +23219,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{305}@anchor{gnat_rm/the_gnat_library id27}@anchor{306}
+@anchor{gnat_rm/the_gnat_library ada-strings-unbounded-text-io-a-suteio-ads}@anchor{308}@anchor{gnat_rm/the_gnat_library id27}@anchor{309}
@section @code{Ada.Strings.Unbounded.Text_IO} (@code{a-suteio.ads})
@@ -23171,7 +23236,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{307}@anchor{gnat_rm/the_gnat_library ada-strings-wide-unbounded-wide-text-io-a-swuwti-ads}@anchor{308}
+@anchor{gnat_rm/the_gnat_library id28}@anchor{30a}@anchor{gnat_rm/the_gnat_library ada-strings-wide-unbounded-wide-text-io-a-swuwti-ads}@anchor{30b}
@section @code{Ada.Strings.Wide_Unbounded.Wide_Text_IO} (@code{a-swuwti.ads})
@@ -23188,7 +23253,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 Task_Initialization a-tasini ads,Ada Strings Wide_Unbounded Wide_Text_IO a-swuwti ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id29}@anchor{309}@anchor{gnat_rm/the_gnat_library ada-strings-wide-wide-unbounded-wide-wide-text-io-a-szuzti-ads}@anchor{30a}
+@anchor{gnat_rm/the_gnat_library id29}@anchor{30c}@anchor{gnat_rm/the_gnat_library ada-strings-wide-wide-unbounded-wide-wide-text-io-a-szuzti-ads}@anchor{30d}
@section @code{Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_IO} (@code{a-szuzti.ads})
@@ -23205,7 +23270,7 @@ wide wide strings, avoiding the necessity for an intermediate operation
with ordinary wide wide strings.
@node Ada Task_Initialization a-tasini ads,Ada Text_IO C_Streams a-tiocst ads,Ada Strings Wide_Wide_Unbounded Wide_Wide_Text_IO a-szuzti ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-task-initialization-a-tasini-ads}@anchor{30b}@anchor{gnat_rm/the_gnat_library id30}@anchor{30c}
+@anchor{gnat_rm/the_gnat_library ada-task-initialization-a-tasini-ads}@anchor{30e}@anchor{gnat_rm/the_gnat_library id30}@anchor{30f}
@section @code{Ada.Task_Initialization} (@code{a-tasini.ads})
@@ -23217,7 +23282,7 @@ parameterless procedures. Note that such a handler is only invoked for
those tasks activated after the handler is set.
@node Ada Text_IO C_Streams a-tiocst ads,Ada Text_IO Reset_Standard_Files a-tirsfi ads,Ada Task_Initialization a-tasini ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-text-io-c-streams-a-tiocst-ads}@anchor{30d}@anchor{gnat_rm/the_gnat_library id31}@anchor{30e}
+@anchor{gnat_rm/the_gnat_library ada-text-io-c-streams-a-tiocst-ads}@anchor{310}@anchor{gnat_rm/the_gnat_library id31}@anchor{311}
@section @code{Ada.Text_IO.C_Streams} (@code{a-tiocst.ads})
@@ -23232,7 +23297,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{30f}@anchor{gnat_rm/the_gnat_library id32}@anchor{310}
+@anchor{gnat_rm/the_gnat_library ada-text-io-reset-standard-files-a-tirsfi-ads}@anchor{312}@anchor{gnat_rm/the_gnat_library id32}@anchor{313}
@section @code{Ada.Text_IO.Reset_Standard_Files} (@code{a-tirsfi.ads})
@@ -23247,7 +23312,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 id33}@anchor{311}@anchor{gnat_rm/the_gnat_library ada-wide-characters-unicode-a-wichun-ads}@anchor{312}
+@anchor{gnat_rm/the_gnat_library id33}@anchor{314}@anchor{gnat_rm/the_gnat_library ada-wide-characters-unicode-a-wichun-ads}@anchor{315}
@section @code{Ada.Wide_Characters.Unicode} (@code{a-wichun.ads})
@@ -23260,7 +23325,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 id34}@anchor{313}@anchor{gnat_rm/the_gnat_library ada-wide-text-io-c-streams-a-wtcstr-ads}@anchor{314}
+@anchor{gnat_rm/the_gnat_library id34}@anchor{316}@anchor{gnat_rm/the_gnat_library ada-wide-text-io-c-streams-a-wtcstr-ads}@anchor{317}
@section @code{Ada.Wide_Text_IO.C_Streams} (@code{a-wtcstr.ads})
@@ -23275,7 +23340,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{315}@anchor{gnat_rm/the_gnat_library id35}@anchor{316}
+@anchor{gnat_rm/the_gnat_library ada-wide-text-io-reset-standard-files-a-wrstfi-ads}@anchor{318}@anchor{gnat_rm/the_gnat_library id35}@anchor{319}
@section @code{Ada.Wide_Text_IO.Reset_Standard_Files} (@code{a-wrstfi.ads})
@@ -23290,7 +23355,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 id36}@anchor{317}@anchor{gnat_rm/the_gnat_library ada-wide-wide-characters-unicode-a-zchuni-ads}@anchor{318}
+@anchor{gnat_rm/the_gnat_library id36}@anchor{31a}@anchor{gnat_rm/the_gnat_library ada-wide-wide-characters-unicode-a-zchuni-ads}@anchor{31b}
@section @code{Ada.Wide_Wide_Characters.Unicode} (@code{a-zchuni.ads})
@@ -23303,7 +23368,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 id37}@anchor{319}@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-c-streams-a-ztcstr-ads}@anchor{31a}
+@anchor{gnat_rm/the_gnat_library id37}@anchor{31c}@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-c-streams-a-ztcstr-ads}@anchor{31d}
@section @code{Ada.Wide_Wide_Text_IO.C_Streams} (@code{a-ztcstr.ads})
@@ -23318,7 +23383,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 ada-wide-wide-text-io-reset-standard-files-a-zrstfi-ads}@anchor{31b}@anchor{gnat_rm/the_gnat_library id38}@anchor{31c}
+@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-reset-standard-files-a-zrstfi-ads}@anchor{31e}@anchor{gnat_rm/the_gnat_library id38}@anchor{31f}
@section @code{Ada.Wide_Wide_Text_IO.Reset_Standard_Files} (@code{a-zrstfi.ads})
@@ -23333,7 +23398,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{31d}@anchor{gnat_rm/the_gnat_library id39}@anchor{31e}
+@anchor{gnat_rm/the_gnat_library gnat-altivec-g-altive-ads}@anchor{320}@anchor{gnat_rm/the_gnat_library id39}@anchor{321}
@section @code{GNAT.Altivec} (@code{g-altive.ads})
@@ -23346,7 +23411,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{31f}@anchor{gnat_rm/the_gnat_library id40}@anchor{320}
+@anchor{gnat_rm/the_gnat_library gnat-altivec-conversions-g-altcon-ads}@anchor{322}@anchor{gnat_rm/the_gnat_library id40}@anchor{323}
@section @code{GNAT.Altivec.Conversions} (@code{g-altcon.ads})
@@ -23357,7 +23422,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 id41}@anchor{321}@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-operations-g-alveop-ads}@anchor{322}
+@anchor{gnat_rm/the_gnat_library id41}@anchor{324}@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-operations-g-alveop-ads}@anchor{325}
@section @code{GNAT.Altivec.Vector_Operations} (@code{g-alveop.ads})
@@ -23371,7 +23436,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{323}@anchor{gnat_rm/the_gnat_library id42}@anchor{324}
+@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-types-g-alvety-ads}@anchor{326}@anchor{gnat_rm/the_gnat_library id42}@anchor{327}
@section @code{GNAT.Altivec.Vector_Types} (@code{g-alvety.ads})
@@ -23383,7 +23448,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{325}@anchor{gnat_rm/the_gnat_library id43}@anchor{326}
+@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-views-g-alvevi-ads}@anchor{328}@anchor{gnat_rm/the_gnat_library id43}@anchor{329}
@section @code{GNAT.Altivec.Vector_Views} (@code{g-alvevi.ads})
@@ -23398,7 +23463,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{327}@anchor{gnat_rm/the_gnat_library id44}@anchor{328}
+@anchor{gnat_rm/the_gnat_library gnat-array-split-g-arrspl-ads}@anchor{32a}@anchor{gnat_rm/the_gnat_library id44}@anchor{32b}
@section @code{GNAT.Array_Split} (@code{g-arrspl.ads})
@@ -23411,7 +23476,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 id45}@anchor{329}@anchor{gnat_rm/the_gnat_library gnat-awk-g-awk-ads}@anchor{32a}
+@anchor{gnat_rm/the_gnat_library id45}@anchor{32c}@anchor{gnat_rm/the_gnat_library gnat-awk-g-awk-ads}@anchor{32d}
@section @code{GNAT.AWK} (@code{g-awk.ads})
@@ -23426,7 +23491,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 id46}@anchor{32b}@anchor{gnat_rm/the_gnat_library gnat-bind-environment-g-binenv-ads}@anchor{32c}
+@anchor{gnat_rm/the_gnat_library id46}@anchor{32e}@anchor{gnat_rm/the_gnat_library gnat-bind-environment-g-binenv-ads}@anchor{32f}
@section @code{GNAT.Bind_Environment} (@code{g-binenv.ads})
@@ -23439,7 +23504,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 id47}@anchor{32d}@anchor{gnat_rm/the_gnat_library gnat-branch-prediction-g-brapre-ads}@anchor{32e}
+@anchor{gnat_rm/the_gnat_library id47}@anchor{330}@anchor{gnat_rm/the_gnat_library gnat-branch-prediction-g-brapre-ads}@anchor{331}
@section @code{GNAT.Branch_Prediction} (@code{g-brapre.ads})
@@ -23450,7 +23515,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 gnat-bounded-buffers-g-boubuf-ads}@anchor{32f}@anchor{gnat_rm/the_gnat_library id48}@anchor{330}
+@anchor{gnat_rm/the_gnat_library gnat-bounded-buffers-g-boubuf-ads}@anchor{332}@anchor{gnat_rm/the_gnat_library id48}@anchor{333}
@section @code{GNAT.Bounded_Buffers} (@code{g-boubuf.ads})
@@ -23465,7 +23530,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{331}@anchor{gnat_rm/the_gnat_library id49}@anchor{332}
+@anchor{gnat_rm/the_gnat_library gnat-bounded-mailboxes-g-boumai-ads}@anchor{334}@anchor{gnat_rm/the_gnat_library id49}@anchor{335}
@section @code{GNAT.Bounded_Mailboxes} (@code{g-boumai.ads})
@@ -23478,7 +23543,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{333}@anchor{gnat_rm/the_gnat_library id50}@anchor{334}
+@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-bubsor-ads}@anchor{336}@anchor{gnat_rm/the_gnat_library id50}@anchor{337}
@section @code{GNAT.Bubble_Sort} (@code{g-bubsor.ads})
@@ -23493,7 +23558,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 id51}@anchor{335}@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-a-g-busora-ads}@anchor{336}
+@anchor{gnat_rm/the_gnat_library id51}@anchor{338}@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-a-g-busora-ads}@anchor{339}
@section @code{GNAT.Bubble_Sort_A} (@code{g-busora.ads})
@@ -23509,7 +23574,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{337}@anchor{gnat_rm/the_gnat_library id52}@anchor{338}
+@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-g-busorg-ads}@anchor{33a}@anchor{gnat_rm/the_gnat_library id52}@anchor{33b}
@section @code{GNAT.Bubble_Sort_G} (@code{g-busorg.ads})
@@ -23525,7 +23590,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{339}@anchor{gnat_rm/the_gnat_library id53}@anchor{33a}
+@anchor{gnat_rm/the_gnat_library gnat-byte-order-mark-g-byorma-ads}@anchor{33c}@anchor{gnat_rm/the_gnat_library id53}@anchor{33d}
@section @code{GNAT.Byte_Order_Mark} (@code{g-byorma.ads})
@@ -23541,7 +23606,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{33b}@anchor{gnat_rm/the_gnat_library id54}@anchor{33c}
+@anchor{gnat_rm/the_gnat_library gnat-byte-swapping-g-bytswa-ads}@anchor{33e}@anchor{gnat_rm/the_gnat_library id54}@anchor{33f}
@section @code{GNAT.Byte_Swapping} (@code{g-bytswa.ads})
@@ -23555,7 +23620,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 id55}@anchor{33d}@anchor{gnat_rm/the_gnat_library gnat-calendar-g-calend-ads}@anchor{33e}
+@anchor{gnat_rm/the_gnat_library id55}@anchor{340}@anchor{gnat_rm/the_gnat_library gnat-calendar-g-calend-ads}@anchor{341}
@section @code{GNAT.Calendar} (@code{g-calend.ads})
@@ -23569,7 +23634,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 id56}@anchor{33f}@anchor{gnat_rm/the_gnat_library gnat-calendar-time-io-g-catiio-ads}@anchor{340}
+@anchor{gnat_rm/the_gnat_library id56}@anchor{342}@anchor{gnat_rm/the_gnat_library gnat-calendar-time-io-g-catiio-ads}@anchor{343}
@section @code{GNAT.Calendar.Time_IO} (@code{g-catiio.ads})
@@ -23580,7 +23645,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 id57}@anchor{341}@anchor{gnat_rm/the_gnat_library gnat-crc32-g-crc32-ads}@anchor{342}
+@anchor{gnat_rm/the_gnat_library id57}@anchor{344}@anchor{gnat_rm/the_gnat_library gnat-crc32-g-crc32-ads}@anchor{345}
@section @code{GNAT.CRC32} (@code{g-crc32.ads})
@@ -23597,7 +23662,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 id58}@anchor{343}@anchor{gnat_rm/the_gnat_library gnat-case-util-g-casuti-ads}@anchor{344}
+@anchor{gnat_rm/the_gnat_library id58}@anchor{346}@anchor{gnat_rm/the_gnat_library gnat-case-util-g-casuti-ads}@anchor{347}
@section @code{GNAT.Case_Util} (@code{g-casuti.ads})
@@ -23612,7 +23677,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 id59}@anchor{345}@anchor{gnat_rm/the_gnat_library gnat-cgi-g-cgi-ads}@anchor{346}
+@anchor{gnat_rm/the_gnat_library id59}@anchor{348}@anchor{gnat_rm/the_gnat_library gnat-cgi-g-cgi-ads}@anchor{349}
@section @code{GNAT.CGI} (@code{g-cgi.ads})
@@ -23627,7 +23692,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{347}@anchor{gnat_rm/the_gnat_library id60}@anchor{348}
+@anchor{gnat_rm/the_gnat_library gnat-cgi-cookie-g-cgicoo-ads}@anchor{34a}@anchor{gnat_rm/the_gnat_library id60}@anchor{34b}
@section @code{GNAT.CGI.Cookie} (@code{g-cgicoo.ads})
@@ -23642,7 +23707,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{349}@anchor{gnat_rm/the_gnat_library id61}@anchor{34a}
+@anchor{gnat_rm/the_gnat_library gnat-cgi-debug-g-cgideb-ads}@anchor{34c}@anchor{gnat_rm/the_gnat_library id61}@anchor{34d}
@section @code{GNAT.CGI.Debug} (@code{g-cgideb.ads})
@@ -23654,7 +23719,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 id62}@anchor{34b}@anchor{gnat_rm/the_gnat_library gnat-command-line-g-comlin-ads}@anchor{34c}
+@anchor{gnat_rm/the_gnat_library id62}@anchor{34e}@anchor{gnat_rm/the_gnat_library gnat-command-line-g-comlin-ads}@anchor{34f}
@section @code{GNAT.Command_Line} (@code{g-comlin.ads})
@@ -23667,7 +23732,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{34d}@anchor{gnat_rm/the_gnat_library id63}@anchor{34e}
+@anchor{gnat_rm/the_gnat_library gnat-compiler-version-g-comver-ads}@anchor{350}@anchor{gnat_rm/the_gnat_library id63}@anchor{351}
@section @code{GNAT.Compiler_Version} (@code{g-comver.ads})
@@ -23685,7 +23750,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 id64}@anchor{34f}@anchor{gnat_rm/the_gnat_library gnat-ctrl-c-g-ctrl-c-ads}@anchor{350}
+@anchor{gnat_rm/the_gnat_library id64}@anchor{352}@anchor{gnat_rm/the_gnat_library gnat-ctrl-c-g-ctrl-c-ads}@anchor{353}
@section @code{GNAT.Ctrl_C} (@code{g-ctrl_c.ads})
@@ -23696,7 +23761,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 id65}@anchor{351}@anchor{gnat_rm/the_gnat_library gnat-current-exception-g-curexc-ads}@anchor{352}
+@anchor{gnat_rm/the_gnat_library id65}@anchor{354}@anchor{gnat_rm/the_gnat_library gnat-current-exception-g-curexc-ads}@anchor{355}
@section @code{GNAT.Current_Exception} (@code{g-curexc.ads})
@@ -23713,7 +23778,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{353}@anchor{gnat_rm/the_gnat_library id66}@anchor{354}
+@anchor{gnat_rm/the_gnat_library gnat-debug-pools-g-debpoo-ads}@anchor{356}@anchor{gnat_rm/the_gnat_library id66}@anchor{357}
@section @code{GNAT.Debug_Pools} (@code{g-debpoo.ads})
@@ -23730,7 +23795,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{355}@anchor{gnat_rm/the_gnat_library id67}@anchor{356}
+@anchor{gnat_rm/the_gnat_library gnat-debug-utilities-g-debuti-ads}@anchor{358}@anchor{gnat_rm/the_gnat_library id67}@anchor{359}
@section @code{GNAT.Debug_Utilities} (@code{g-debuti.ads})
@@ -23743,7 +23808,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 gnat-decode-string-g-decstr-ads}@anchor{357}@anchor{gnat_rm/the_gnat_library id68}@anchor{358}
+@anchor{gnat_rm/the_gnat_library gnat-decode-string-g-decstr-ads}@anchor{35a}@anchor{gnat_rm/the_gnat_library id68}@anchor{35b}
@section @code{GNAT.Decode_String} (@code{g-decstr.ads})
@@ -23767,7 +23832,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{359}@anchor{gnat_rm/the_gnat_library id69}@anchor{35a}
+@anchor{gnat_rm/the_gnat_library gnat-decode-utf8-string-g-deutst-ads}@anchor{35c}@anchor{gnat_rm/the_gnat_library id69}@anchor{35d}
@section @code{GNAT.Decode_UTF8_String} (@code{g-deutst.ads})
@@ -23788,7 +23853,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 id70}@anchor{35b}@anchor{gnat_rm/the_gnat_library gnat-directory-operations-g-dirope-ads}@anchor{35c}
+@anchor{gnat_rm/the_gnat_library id70}@anchor{35e}@anchor{gnat_rm/the_gnat_library gnat-directory-operations-g-dirope-ads}@anchor{35f}
@section @code{GNAT.Directory_Operations} (@code{g-dirope.ads})
@@ -23801,7 +23866,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 id71}@anchor{35d}@anchor{gnat_rm/the_gnat_library gnat-directory-operations-iteration-g-diopit-ads}@anchor{35e}
+@anchor{gnat_rm/the_gnat_library id71}@anchor{360}@anchor{gnat_rm/the_gnat_library gnat-directory-operations-iteration-g-diopit-ads}@anchor{361}
@section @code{GNAT.Directory_Operations.Iteration} (@code{g-diopit.ads})
@@ -23813,7 +23878,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 id72}@anchor{35f}@anchor{gnat_rm/the_gnat_library gnat-dynamic-htables-g-dynhta-ads}@anchor{360}
+@anchor{gnat_rm/the_gnat_library id72}@anchor{362}@anchor{gnat_rm/the_gnat_library gnat-dynamic-htables-g-dynhta-ads}@anchor{363}
@section @code{GNAT.Dynamic_HTables} (@code{g-dynhta.ads})
@@ -23831,7 +23896,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{361}@anchor{gnat_rm/the_gnat_library id73}@anchor{362}
+@anchor{gnat_rm/the_gnat_library gnat-dynamic-tables-g-dyntab-ads}@anchor{364}@anchor{gnat_rm/the_gnat_library id73}@anchor{365}
@section @code{GNAT.Dynamic_Tables} (@code{g-dyntab.ads})
@@ -23851,7 +23916,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 id74}@anchor{363}@anchor{gnat_rm/the_gnat_library gnat-encode-string-g-encstr-ads}@anchor{364}
+@anchor{gnat_rm/the_gnat_library id74}@anchor{366}@anchor{gnat_rm/the_gnat_library gnat-encode-string-g-encstr-ads}@anchor{367}
@section @code{GNAT.Encode_String} (@code{g-encstr.ads})
@@ -23873,7 +23938,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{365}@anchor{gnat_rm/the_gnat_library id75}@anchor{366}
+@anchor{gnat_rm/the_gnat_library gnat-encode-utf8-string-g-enutst-ads}@anchor{368}@anchor{gnat_rm/the_gnat_library id75}@anchor{369}
@section @code{GNAT.Encode_UTF8_String} (@code{g-enutst.ads})
@@ -23894,7 +23959,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{367}@anchor{gnat_rm/the_gnat_library id76}@anchor{368}
+@anchor{gnat_rm/the_gnat_library gnat-exception-actions-g-excact-ads}@anchor{36a}@anchor{gnat_rm/the_gnat_library id76}@anchor{36b}
@section @code{GNAT.Exception_Actions} (@code{g-excact.ads})
@@ -23907,7 +23972,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{369}@anchor{gnat_rm/the_gnat_library id77}@anchor{36a}
+@anchor{gnat_rm/the_gnat_library gnat-exception-traces-g-exctra-ads}@anchor{36c}@anchor{gnat_rm/the_gnat_library id77}@anchor{36d}
@section @code{GNAT.Exception_Traces} (@code{g-exctra.ads})
@@ -23921,7 +23986,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 id78}@anchor{36b}@anchor{gnat_rm/the_gnat_library gnat-exceptions-g-except-ads}@anchor{36c}
+@anchor{gnat_rm/the_gnat_library id78}@anchor{36e}@anchor{gnat_rm/the_gnat_library gnat-exceptions-g-except-ads}@anchor{36f}
@section @code{GNAT.Exceptions} (@code{g-except.ads})
@@ -23942,7 +24007,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 id79}@anchor{36d}@anchor{gnat_rm/the_gnat_library gnat-expect-g-expect-ads}@anchor{36e}
+@anchor{gnat_rm/the_gnat_library id79}@anchor{370}@anchor{gnat_rm/the_gnat_library gnat-expect-g-expect-ads}@anchor{371}
@section @code{GNAT.Expect} (@code{g-expect.ads})
@@ -23958,7 +24023,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 id80}@anchor{36f}@anchor{gnat_rm/the_gnat_library gnat-expect-tty-g-exptty-ads}@anchor{370}
+@anchor{gnat_rm/the_gnat_library id80}@anchor{372}@anchor{gnat_rm/the_gnat_library gnat-expect-tty-g-exptty-ads}@anchor{373}
@section @code{GNAT.Expect.TTY} (@code{g-exptty.ads})
@@ -23970,7 +24035,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 id81}@anchor{371}@anchor{gnat_rm/the_gnat_library gnat-float-control-g-flocon-ads}@anchor{372}
+@anchor{gnat_rm/the_gnat_library id81}@anchor{374}@anchor{gnat_rm/the_gnat_library gnat-float-control-g-flocon-ads}@anchor{375}
@section @code{GNAT.Float_Control} (@code{g-flocon.ads})
@@ -23984,7 +24049,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 id82}@anchor{373}@anchor{gnat_rm/the_gnat_library gnat-formatted-string-g-forstr-ads}@anchor{374}
+@anchor{gnat_rm/the_gnat_library id82}@anchor{376}@anchor{gnat_rm/the_gnat_library gnat-formatted-string-g-forstr-ads}@anchor{377}
@section @code{GNAT.Formatted_String} (@code{g-forstr.ads})
@@ -23999,7 +24064,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 id83}@anchor{375}@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-heasor-ads}@anchor{376}
+@anchor{gnat_rm/the_gnat_library id83}@anchor{378}@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-heasor-ads}@anchor{379}
@section @code{GNAT.Heap_Sort} (@code{g-heasor.ads})
@@ -24013,7 +24078,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 gnat-heap-sort-a-g-hesora-ads}@anchor{377}@anchor{gnat_rm/the_gnat_library id84}@anchor{378}
+@anchor{gnat_rm/the_gnat_library gnat-heap-sort-a-g-hesora-ads}@anchor{37a}@anchor{gnat_rm/the_gnat_library id84}@anchor{37b}
@section @code{GNAT.Heap_Sort_A} (@code{g-hesora.ads})
@@ -24029,7 +24094,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 id85}@anchor{379}@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-g-hesorg-ads}@anchor{37a}
+@anchor{gnat_rm/the_gnat_library id85}@anchor{37c}@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-g-hesorg-ads}@anchor{37d}
@section @code{GNAT.Heap_Sort_G} (@code{g-hesorg.ads})
@@ -24043,7 +24108,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 id86}@anchor{37b}@anchor{gnat_rm/the_gnat_library gnat-htable-g-htable-ads}@anchor{37c}
+@anchor{gnat_rm/the_gnat_library id86}@anchor{37e}@anchor{gnat_rm/the_gnat_library gnat-htable-g-htable-ads}@anchor{37f}
@section @code{GNAT.HTable} (@code{g-htable.ads})
@@ -24056,7 +24121,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 id87}@anchor{37d}@anchor{gnat_rm/the_gnat_library gnat-io-g-io-ads}@anchor{37e}
+@anchor{gnat_rm/the_gnat_library id87}@anchor{380}@anchor{gnat_rm/the_gnat_library gnat-io-g-io-ads}@anchor{381}
@section @code{GNAT.IO} (@code{g-io.ads})
@@ -24072,7 +24137,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 id88}@anchor{37f}@anchor{gnat_rm/the_gnat_library gnat-io-aux-g-io-aux-ads}@anchor{380}
+@anchor{gnat_rm/the_gnat_library id88}@anchor{382}@anchor{gnat_rm/the_gnat_library gnat-io-aux-g-io-aux-ads}@anchor{383}
@section @code{GNAT.IO_Aux} (@code{g-io_aux.ads})
@@ -24086,7 +24151,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 id89}@anchor{381}@anchor{gnat_rm/the_gnat_library gnat-lock-files-g-locfil-ads}@anchor{382}
+@anchor{gnat_rm/the_gnat_library id89}@anchor{384}@anchor{gnat_rm/the_gnat_library gnat-lock-files-g-locfil-ads}@anchor{385}
@section @code{GNAT.Lock_Files} (@code{g-locfil.ads})
@@ -24100,7 +24165,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 id90}@anchor{383}@anchor{gnat_rm/the_gnat_library gnat-mbbs-discrete-random-g-mbdira-ads}@anchor{384}
+@anchor{gnat_rm/the_gnat_library id90}@anchor{386}@anchor{gnat_rm/the_gnat_library gnat-mbbs-discrete-random-g-mbdira-ads}@anchor{387}
@section @code{GNAT.MBBS_Discrete_Random} (@code{g-mbdira.ads})
@@ -24112,7 +24177,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 id91}@anchor{385}@anchor{gnat_rm/the_gnat_library gnat-mbbs-float-random-g-mbflra-ads}@anchor{386}
+@anchor{gnat_rm/the_gnat_library id91}@anchor{388}@anchor{gnat_rm/the_gnat_library gnat-mbbs-float-random-g-mbflra-ads}@anchor{389}
@section @code{GNAT.MBBS_Float_Random} (@code{g-mbflra.ads})
@@ -24124,7 +24189,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 id92}@anchor{387}@anchor{gnat_rm/the_gnat_library gnat-md5-g-md5-ads}@anchor{388}
+@anchor{gnat_rm/the_gnat_library id92}@anchor{38a}@anchor{gnat_rm/the_gnat_library gnat-md5-g-md5-ads}@anchor{38b}
@section @code{GNAT.MD5} (@code{g-md5.ads})
@@ -24137,7 +24202,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 id93}@anchor{389}@anchor{gnat_rm/the_gnat_library gnat-memory-dump-g-memdum-ads}@anchor{38a}
+@anchor{gnat_rm/the_gnat_library id93}@anchor{38c}@anchor{gnat_rm/the_gnat_library gnat-memory-dump-g-memdum-ads}@anchor{38d}
@section @code{GNAT.Memory_Dump} (@code{g-memdum.ads})
@@ -24150,7 +24215,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{38b}@anchor{gnat_rm/the_gnat_library id94}@anchor{38c}
+@anchor{gnat_rm/the_gnat_library gnat-most-recent-exception-g-moreex-ads}@anchor{38e}@anchor{gnat_rm/the_gnat_library id94}@anchor{38f}
@section @code{GNAT.Most_Recent_Exception} (@code{g-moreex.ads})
@@ -24164,7 +24229,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{38d}@anchor{gnat_rm/the_gnat_library id95}@anchor{38e}
+@anchor{gnat_rm/the_gnat_library gnat-os-lib-g-os-lib-ads}@anchor{390}@anchor{gnat_rm/the_gnat_library id95}@anchor{391}
@section @code{GNAT.OS_Lib} (@code{g-os_lib.ads})
@@ -24180,7 +24245,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{38f}@anchor{gnat_rm/the_gnat_library id96}@anchor{390}
+@anchor{gnat_rm/the_gnat_library gnat-perfect-hash-generators-g-pehage-ads}@anchor{392}@anchor{gnat_rm/the_gnat_library id96}@anchor{393}
@section @code{GNAT.Perfect_Hash_Generators} (@code{g-pehage.ads})
@@ -24198,7 +24263,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{391}@anchor{gnat_rm/the_gnat_library id97}@anchor{392}
+@anchor{gnat_rm/the_gnat_library gnat-random-numbers-g-rannum-ads}@anchor{394}@anchor{gnat_rm/the_gnat_library id97}@anchor{395}
@section @code{GNAT.Random_Numbers} (@code{g-rannum.ads})
@@ -24210,7 +24275,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 id98}@anchor{393}@anchor{gnat_rm/the_gnat_library gnat-regexp-g-regexp-ads}@anchor{258}
+@anchor{gnat_rm/the_gnat_library id98}@anchor{396}@anchor{gnat_rm/the_gnat_library gnat-regexp-g-regexp-ads}@anchor{25b}
@section @code{GNAT.Regexp} (@code{g-regexp.ads})
@@ -24226,7 +24291,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 id99}@anchor{394}@anchor{gnat_rm/the_gnat_library gnat-registry-g-regist-ads}@anchor{395}
+@anchor{gnat_rm/the_gnat_library id99}@anchor{397}@anchor{gnat_rm/the_gnat_library gnat-registry-g-regist-ads}@anchor{398}
@section @code{GNAT.Registry} (@code{g-regist.ads})
@@ -24240,7 +24305,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 id100}@anchor{396}@anchor{gnat_rm/the_gnat_library gnat-regpat-g-regpat-ads}@anchor{397}
+@anchor{gnat_rm/the_gnat_library id100}@anchor{399}@anchor{gnat_rm/the_gnat_library gnat-regpat-g-regpat-ads}@anchor{39a}
@section @code{GNAT.Regpat} (@code{g-regpat.ads})
@@ -24255,7 +24320,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 id101}@anchor{398}@anchor{gnat_rm/the_gnat_library gnat-rewrite-data-g-rewdat-ads}@anchor{399}
+@anchor{gnat_rm/the_gnat_library id101}@anchor{39b}@anchor{gnat_rm/the_gnat_library gnat-rewrite-data-g-rewdat-ads}@anchor{39c}
@section @code{GNAT.Rewrite_Data} (@code{g-rewdat.ads})
@@ -24269,7 +24334,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 gnat-secondary-stack-info-g-sestin-ads}@anchor{39a}@anchor{gnat_rm/the_gnat_library id102}@anchor{39b}
+@anchor{gnat_rm/the_gnat_library gnat-secondary-stack-info-g-sestin-ads}@anchor{39d}@anchor{gnat_rm/the_gnat_library id102}@anchor{39e}
@section @code{GNAT.Secondary_Stack_Info} (@code{g-sestin.ads})
@@ -24281,7 +24346,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 id103}@anchor{39c}@anchor{gnat_rm/the_gnat_library gnat-semaphores-g-semaph-ads}@anchor{39d}
+@anchor{gnat_rm/the_gnat_library id103}@anchor{39f}@anchor{gnat_rm/the_gnat_library gnat-semaphores-g-semaph-ads}@anchor{3a0}
@section @code{GNAT.Semaphores} (@code{g-semaph.ads})
@@ -24292,7 +24357,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{39e}@anchor{gnat_rm/the_gnat_library id104}@anchor{39f}
+@anchor{gnat_rm/the_gnat_library gnat-serial-communications-g-sercom-ads}@anchor{3a1}@anchor{gnat_rm/the_gnat_library id104}@anchor{3a2}
@section @code{GNAT.Serial_Communications} (@code{g-sercom.ads})
@@ -24304,7 +24369,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{3a0}@anchor{gnat_rm/the_gnat_library id105}@anchor{3a1}
+@anchor{gnat_rm/the_gnat_library gnat-sha1-g-sha1-ads}@anchor{3a3}@anchor{gnat_rm/the_gnat_library id105}@anchor{3a4}
@section @code{GNAT.SHA1} (@code{g-sha1.ads})
@@ -24317,7 +24382,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{3a2}@anchor{gnat_rm/the_gnat_library id106}@anchor{3a3}
+@anchor{gnat_rm/the_gnat_library gnat-sha224-g-sha224-ads}@anchor{3a5}@anchor{gnat_rm/the_gnat_library id106}@anchor{3a6}
@section @code{GNAT.SHA224} (@code{g-sha224.ads})
@@ -24330,7 +24395,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{3a4}@anchor{gnat_rm/the_gnat_library id107}@anchor{3a5}
+@anchor{gnat_rm/the_gnat_library gnat-sha256-g-sha256-ads}@anchor{3a7}@anchor{gnat_rm/the_gnat_library id107}@anchor{3a8}
@section @code{GNAT.SHA256} (@code{g-sha256.ads})
@@ -24343,7 +24408,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 id108}@anchor{3a6}@anchor{gnat_rm/the_gnat_library gnat-sha384-g-sha384-ads}@anchor{3a7}
+@anchor{gnat_rm/the_gnat_library id108}@anchor{3a9}@anchor{gnat_rm/the_gnat_library gnat-sha384-g-sha384-ads}@anchor{3aa}
@section @code{GNAT.SHA384} (@code{g-sha384.ads})
@@ -24356,7 +24421,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 id109}@anchor{3a8}@anchor{gnat_rm/the_gnat_library gnat-sha512-g-sha512-ads}@anchor{3a9}
+@anchor{gnat_rm/the_gnat_library id109}@anchor{3ab}@anchor{gnat_rm/the_gnat_library gnat-sha512-g-sha512-ads}@anchor{3ac}
@section @code{GNAT.SHA512} (@code{g-sha512.ads})
@@ -24369,7 +24434,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 gnat-signals-g-signal-ads}@anchor{3aa}@anchor{gnat_rm/the_gnat_library id110}@anchor{3ab}
+@anchor{gnat_rm/the_gnat_library gnat-signals-g-signal-ads}@anchor{3ad}@anchor{gnat_rm/the_gnat_library id110}@anchor{3ae}
@section @code{GNAT.Signals} (@code{g-signal.ads})
@@ -24381,7 +24446,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{3ac}@anchor{gnat_rm/the_gnat_library id111}@anchor{3ad}
+@anchor{gnat_rm/the_gnat_library gnat-sockets-g-socket-ads}@anchor{3af}@anchor{gnat_rm/the_gnat_library id111}@anchor{3b0}
@section @code{GNAT.Sockets} (@code{g-socket.ads})
@@ -24396,7 +24461,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{3ae}@anchor{gnat_rm/the_gnat_library id112}@anchor{3af}
+@anchor{gnat_rm/the_gnat_library gnat-source-info-g-souinf-ads}@anchor{3b1}@anchor{gnat_rm/the_gnat_library id112}@anchor{3b2}
@section @code{GNAT.Source_Info} (@code{g-souinf.ads})
@@ -24410,7 +24475,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 gnat-spelling-checker-g-speche-ads}@anchor{3b0}@anchor{gnat_rm/the_gnat_library id113}@anchor{3b1}
+@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-g-speche-ads}@anchor{3b3}@anchor{gnat_rm/the_gnat_library id113}@anchor{3b4}
@section @code{GNAT.Spelling_Checker} (@code{g-speche.ads})
@@ -24422,7 +24487,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{3b2}@anchor{gnat_rm/the_gnat_library id114}@anchor{3b3}
+@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-generic-g-spchge-ads}@anchor{3b5}@anchor{gnat_rm/the_gnat_library id114}@anchor{3b6}
@section @code{GNAT.Spelling_Checker_Generic} (@code{g-spchge.ads})
@@ -24435,7 +24500,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{3b4}@anchor{gnat_rm/the_gnat_library id115}@anchor{3b5}
+@anchor{gnat_rm/the_gnat_library gnat-spitbol-patterns-g-spipat-ads}@anchor{3b7}@anchor{gnat_rm/the_gnat_library id115}@anchor{3b8}
@section @code{GNAT.Spitbol.Patterns} (@code{g-spipat.ads})
@@ -24451,7 +24516,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 id116}@anchor{3b6}@anchor{gnat_rm/the_gnat_library gnat-spitbol-g-spitbo-ads}@anchor{3b7}
+@anchor{gnat_rm/the_gnat_library id116}@anchor{3b9}@anchor{gnat_rm/the_gnat_library gnat-spitbol-g-spitbo-ads}@anchor{3ba}
@section @code{GNAT.Spitbol} (@code{g-spitbo.ads})
@@ -24466,7 +24531,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 gnat-spitbol-table-boolean-g-sptabo-ads}@anchor{3b8}@anchor{gnat_rm/the_gnat_library id117}@anchor{3b9}
+@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-boolean-g-sptabo-ads}@anchor{3bb}@anchor{gnat_rm/the_gnat_library id117}@anchor{3bc}
@section @code{GNAT.Spitbol.Table_Boolean} (@code{g-sptabo.ads})
@@ -24481,7 +24546,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{3ba}@anchor{gnat_rm/the_gnat_library id118}@anchor{3bb}
+@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-integer-g-sptain-ads}@anchor{3bd}@anchor{gnat_rm/the_gnat_library id118}@anchor{3be}
@section @code{GNAT.Spitbol.Table_Integer} (@code{g-sptain.ads})
@@ -24498,7 +24563,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 id119}@anchor{3bc}@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-vstring-g-sptavs-ads}@anchor{3bd}
+@anchor{gnat_rm/the_gnat_library id119}@anchor{3bf}@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-vstring-g-sptavs-ads}@anchor{3c0}
@section @code{GNAT.Spitbol.Table_VString} (@code{g-sptavs.ads})
@@ -24515,7 +24580,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 id120}@anchor{3be}@anchor{gnat_rm/the_gnat_library gnat-sse-g-sse-ads}@anchor{3bf}
+@anchor{gnat_rm/the_gnat_library id120}@anchor{3c1}@anchor{gnat_rm/the_gnat_library gnat-sse-g-sse-ads}@anchor{3c2}
@section @code{GNAT.SSE} (@code{g-sse.ads})
@@ -24527,7 +24592,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{3c0}@anchor{gnat_rm/the_gnat_library id121}@anchor{3c1}
+@anchor{gnat_rm/the_gnat_library gnat-sse-vector-types-g-ssvety-ads}@anchor{3c3}@anchor{gnat_rm/the_gnat_library id121}@anchor{3c4}
@section @code{GNAT.SSE.Vector_Types} (@code{g-ssvety.ads})
@@ -24536,7 +24601,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{3c2}@anchor{gnat_rm/the_gnat_library id122}@anchor{3c3}
+@anchor{gnat_rm/the_gnat_library gnat-string-hash-g-strhas-ads}@anchor{3c5}@anchor{gnat_rm/the_gnat_library id122}@anchor{3c6}
@section @code{GNAT.String_Hash} (@code{g-strhas.ads})
@@ -24548,7 +24613,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 id123}@anchor{3c4}@anchor{gnat_rm/the_gnat_library gnat-strings-g-string-ads}@anchor{3c5}
+@anchor{gnat_rm/the_gnat_library id123}@anchor{3c7}@anchor{gnat_rm/the_gnat_library gnat-strings-g-string-ads}@anchor{3c8}
@section @code{GNAT.Strings} (@code{g-string.ads})
@@ -24558,7 +24623,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{3c6}@anchor{gnat_rm/the_gnat_library id124}@anchor{3c7}
+@anchor{gnat_rm/the_gnat_library gnat-string-split-g-strspl-ads}@anchor{3c9}@anchor{gnat_rm/the_gnat_library id124}@anchor{3ca}
@section @code{GNAT.String_Split} (@code{g-strspl.ads})
@@ -24572,7 +24637,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 id125}@anchor{3c8}@anchor{gnat_rm/the_gnat_library gnat-table-g-table-ads}@anchor{3c9}
+@anchor{gnat_rm/the_gnat_library id125}@anchor{3cb}@anchor{gnat_rm/the_gnat_library gnat-table-g-table-ads}@anchor{3cc}
@section @code{GNAT.Table} (@code{g-table.ads})
@@ -24592,7 +24657,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 id126}@anchor{3ca}@anchor{gnat_rm/the_gnat_library gnat-task-lock-g-tasloc-ads}@anchor{3cb}
+@anchor{gnat_rm/the_gnat_library id126}@anchor{3cd}@anchor{gnat_rm/the_gnat_library gnat-task-lock-g-tasloc-ads}@anchor{3ce}
@section @code{GNAT.Task_Lock} (@code{g-tasloc.ads})
@@ -24609,7 +24674,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 id127}@anchor{3cc}@anchor{gnat_rm/the_gnat_library gnat-time-stamp-g-timsta-ads}@anchor{3cd}
+@anchor{gnat_rm/the_gnat_library id127}@anchor{3cf}@anchor{gnat_rm/the_gnat_library gnat-time-stamp-g-timsta-ads}@anchor{3d0}
@section @code{GNAT.Time_Stamp} (@code{g-timsta.ads})
@@ -24624,7 +24689,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 gnat-threads-g-thread-ads}@anchor{3ce}@anchor{gnat_rm/the_gnat_library id128}@anchor{3cf}
+@anchor{gnat_rm/the_gnat_library gnat-threads-g-thread-ads}@anchor{3d1}@anchor{gnat_rm/the_gnat_library id128}@anchor{3d2}
@section @code{GNAT.Threads} (@code{g-thread.ads})
@@ -24641,7 +24706,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 id129}@anchor{3d0}@anchor{gnat_rm/the_gnat_library gnat-traceback-g-traceb-ads}@anchor{3d1}
+@anchor{gnat_rm/the_gnat_library id129}@anchor{3d3}@anchor{gnat_rm/the_gnat_library gnat-traceback-g-traceb-ads}@anchor{3d4}
@section @code{GNAT.Traceback} (@code{g-traceb.ads})
@@ -24653,7 +24718,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 id130}@anchor{3d2}@anchor{gnat_rm/the_gnat_library gnat-traceback-symbolic-g-trasym-ads}@anchor{3d3}
+@anchor{gnat_rm/the_gnat_library id130}@anchor{3d5}@anchor{gnat_rm/the_gnat_library gnat-traceback-symbolic-g-trasym-ads}@anchor{3d6}
@section @code{GNAT.Traceback.Symbolic} (@code{g-trasym.ads})
@@ -24662,7 +24727,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 id131}@anchor{3d4}@anchor{gnat_rm/the_gnat_library gnat-utf-32-g-table-ads}@anchor{3d5}
+@anchor{gnat_rm/the_gnat_library id131}@anchor{3d7}@anchor{gnat_rm/the_gnat_library gnat-utf-32-g-table-ads}@anchor{3d8}
@section @code{GNAT.UTF_32} (@code{g-table.ads})
@@ -24681,7 +24746,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{3d6}@anchor{gnat_rm/the_gnat_library id132}@anchor{3d7}
+@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-u3spch-ads}@anchor{3d9}@anchor{gnat_rm/the_gnat_library id132}@anchor{3da}
@section @code{GNAT.Wide_Spelling_Checker} (@code{g-u3spch.ads})
@@ -24694,7 +24759,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{3d8}@anchor{gnat_rm/the_gnat_library id133}@anchor{3d9}
+@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-wispch-ads}@anchor{3db}@anchor{gnat_rm/the_gnat_library id133}@anchor{3dc}
@section @code{GNAT.Wide_Spelling_Checker} (@code{g-wispch.ads})
@@ -24706,7 +24771,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 id134}@anchor{3da}@anchor{gnat_rm/the_gnat_library gnat-wide-string-split-g-wistsp-ads}@anchor{3db}
+@anchor{gnat_rm/the_gnat_library id134}@anchor{3dd}@anchor{gnat_rm/the_gnat_library gnat-wide-string-split-g-wistsp-ads}@anchor{3de}
@section @code{GNAT.Wide_String_Split} (@code{g-wistsp.ads})
@@ -24720,7 +24785,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{3dc}@anchor{gnat_rm/the_gnat_library id135}@anchor{3dd}
+@anchor{gnat_rm/the_gnat_library gnat-wide-wide-spelling-checker-g-zspche-ads}@anchor{3df}@anchor{gnat_rm/the_gnat_library id135}@anchor{3e0}
@section @code{GNAT.Wide_Wide_Spelling_Checker} (@code{g-zspche.ads})
@@ -24732,7 +24797,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{3de}@anchor{gnat_rm/the_gnat_library id136}@anchor{3df}
+@anchor{gnat_rm/the_gnat_library gnat-wide-wide-string-split-g-zistsp-ads}@anchor{3e1}@anchor{gnat_rm/the_gnat_library id136}@anchor{3e2}
@section @code{GNAT.Wide_Wide_String_Split} (@code{g-zistsp.ads})
@@ -24746,7 +24811,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{3e0}@anchor{gnat_rm/the_gnat_library id137}@anchor{3e1}
+@anchor{gnat_rm/the_gnat_library interfaces-c-extensions-i-cexten-ads}@anchor{3e3}@anchor{gnat_rm/the_gnat_library id137}@anchor{3e4}
@section @code{Interfaces.C.Extensions} (@code{i-cexten.ads})
@@ -24757,7 +24822,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 id138}@anchor{3e2}@anchor{gnat_rm/the_gnat_library interfaces-c-streams-i-cstrea-ads}@anchor{3e3}
+@anchor{gnat_rm/the_gnat_library id138}@anchor{3e5}@anchor{gnat_rm/the_gnat_library interfaces-c-streams-i-cstrea-ads}@anchor{3e6}
@section @code{Interfaces.C.Streams} (@code{i-cstrea.ads})
@@ -24770,7 +24835,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 interfaces-packed-decimal-i-pacdec-ads}@anchor{3e4}@anchor{gnat_rm/the_gnat_library id139}@anchor{3e5}
+@anchor{gnat_rm/the_gnat_library interfaces-packed-decimal-i-pacdec-ads}@anchor{3e7}@anchor{gnat_rm/the_gnat_library id139}@anchor{3e8}
@section @code{Interfaces.Packed_Decimal} (@code{i-pacdec.ads})
@@ -24785,7 +24850,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 interfaces-vxworks-i-vxwork-ads}@anchor{3e6}@anchor{gnat_rm/the_gnat_library id140}@anchor{3e7}
+@anchor{gnat_rm/the_gnat_library interfaces-vxworks-i-vxwork-ads}@anchor{3e9}@anchor{gnat_rm/the_gnat_library id140}@anchor{3ea}
@section @code{Interfaces.VxWorks} (@code{i-vxwork.ads})
@@ -24801,7 +24866,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{3e8}@anchor{gnat_rm/the_gnat_library id141}@anchor{3e9}
+@anchor{gnat_rm/the_gnat_library interfaces-vxworks-int-connection-i-vxinco-ads}@anchor{3eb}@anchor{gnat_rm/the_gnat_library id141}@anchor{3ec}
@section @code{Interfaces.VxWorks.Int_Connection} (@code{i-vxinco.ads})
@@ -24817,7 +24882,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{3ea}@anchor{gnat_rm/the_gnat_library id142}@anchor{3eb}
+@anchor{gnat_rm/the_gnat_library interfaces-vxworks-io-i-vxwoio-ads}@anchor{3ed}@anchor{gnat_rm/the_gnat_library id142}@anchor{3ee}
@section @code{Interfaces.VxWorks.IO} (@code{i-vxwoio.ads})
@@ -24840,7 +24905,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{3ec}@anchor{gnat_rm/the_gnat_library id143}@anchor{3ed}
+@anchor{gnat_rm/the_gnat_library system-address-image-s-addima-ads}@anchor{3ef}@anchor{gnat_rm/the_gnat_library id143}@anchor{3f0}
@section @code{System.Address_Image} (@code{s-addima.ads})
@@ -24856,7 +24921,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 id144}@anchor{3ee}@anchor{gnat_rm/the_gnat_library system-assertions-s-assert-ads}@anchor{3ef}
+@anchor{gnat_rm/the_gnat_library id144}@anchor{3f1}@anchor{gnat_rm/the_gnat_library system-assertions-s-assert-ads}@anchor{3f2}
@section @code{System.Assertions} (@code{s-assert.ads})
@@ -24872,7 +24937,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 id145}@anchor{3f0}@anchor{gnat_rm/the_gnat_library system-atomic-counters-s-atocou-ads}@anchor{3f1}
+@anchor{gnat_rm/the_gnat_library id145}@anchor{3f3}@anchor{gnat_rm/the_gnat_library system-atomic-counters-s-atocou-ads}@anchor{3f4}
@section @code{System.Atomic_Counters} (@code{s-atocou.ads})
@@ -24886,7 +24951,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{3f2}@anchor{gnat_rm/the_gnat_library id146}@anchor{3f3}
+@anchor{gnat_rm/the_gnat_library system-memory-s-memory-ads}@anchor{3f5}@anchor{gnat_rm/the_gnat_library id146}@anchor{3f6}
@section @code{System.Memory} (@code{s-memory.ads})
@@ -24904,7 +24969,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 id147}@anchor{3f4}@anchor{gnat_rm/the_gnat_library system-multiprocessors-s-multip-ads}@anchor{3f5}
+@anchor{gnat_rm/the_gnat_library id147}@anchor{3f7}@anchor{gnat_rm/the_gnat_library system-multiprocessors-s-multip-ads}@anchor{3f8}
@section @code{System.Multiprocessors} (@code{s-multip.ads})
@@ -24917,7 +24982,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{3f6}@anchor{gnat_rm/the_gnat_library id148}@anchor{3f7}
+@anchor{gnat_rm/the_gnat_library system-multiprocessors-dispatching-domains-s-mudido-ads}@anchor{3f9}@anchor{gnat_rm/the_gnat_library id148}@anchor{3fa}
@section @code{System.Multiprocessors.Dispatching_Domains} (@code{s-mudido.ads})
@@ -24930,7 +24995,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 id149}@anchor{3f8}@anchor{gnat_rm/the_gnat_library system-partition-interface-s-parint-ads}@anchor{3f9}
+@anchor{gnat_rm/the_gnat_library id149}@anchor{3fb}@anchor{gnat_rm/the_gnat_library system-partition-interface-s-parint-ads}@anchor{3fc}
@section @code{System.Partition_Interface} (@code{s-parint.ads})
@@ -24943,7 +25008,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 id150}@anchor{3fa}@anchor{gnat_rm/the_gnat_library system-pool-global-s-pooglo-ads}@anchor{3fb}
+@anchor{gnat_rm/the_gnat_library id150}@anchor{3fd}@anchor{gnat_rm/the_gnat_library system-pool-global-s-pooglo-ads}@anchor{3fe}
@section @code{System.Pool_Global} (@code{s-pooglo.ads})
@@ -24960,7 +25025,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{3fc}@anchor{gnat_rm/the_gnat_library id151}@anchor{3fd}
+@anchor{gnat_rm/the_gnat_library system-pool-local-s-pooloc-ads}@anchor{3ff}@anchor{gnat_rm/the_gnat_library id151}@anchor{400}
@section @code{System.Pool_Local} (@code{s-pooloc.ads})
@@ -24977,7 +25042,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 id152}@anchor{3fe}@anchor{gnat_rm/the_gnat_library system-restrictions-s-restri-ads}@anchor{3ff}
+@anchor{gnat_rm/the_gnat_library id152}@anchor{401}@anchor{gnat_rm/the_gnat_library system-restrictions-s-restri-ads}@anchor{402}
@section @code{System.Restrictions} (@code{s-restri.ads})
@@ -24993,7 +25058,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{400}@anchor{gnat_rm/the_gnat_library id153}@anchor{401}
+@anchor{gnat_rm/the_gnat_library system-rident-s-rident-ads}@anchor{403}@anchor{gnat_rm/the_gnat_library id153}@anchor{404}
@section @code{System.Rident} (@code{s-rident.ads})
@@ -25009,7 +25074,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 id154}@anchor{402}@anchor{gnat_rm/the_gnat_library system-strings-stream-ops-s-ststop-ads}@anchor{403}
+@anchor{gnat_rm/the_gnat_library id154}@anchor{405}@anchor{gnat_rm/the_gnat_library system-strings-stream-ops-s-ststop-ads}@anchor{406}
@section @code{System.Strings.Stream_Ops} (@code{s-ststop.ads})
@@ -25025,7 +25090,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{404}@anchor{gnat_rm/the_gnat_library id155}@anchor{405}
+@anchor{gnat_rm/the_gnat_library system-unsigned-types-s-unstyp-ads}@anchor{407}@anchor{gnat_rm/the_gnat_library id155}@anchor{408}
@section @code{System.Unsigned_Types} (@code{s-unstyp.ads})
@@ -25038,7 +25103,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{406}@anchor{gnat_rm/the_gnat_library id156}@anchor{407}
+@anchor{gnat_rm/the_gnat_library system-wch-cnv-s-wchcnv-ads}@anchor{409}@anchor{gnat_rm/the_gnat_library id156}@anchor{40a}
@section @code{System.Wch_Cnv} (@code{s-wchcnv.ads})
@@ -25059,7 +25124,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 id157}@anchor{408}@anchor{gnat_rm/the_gnat_library system-wch-con-s-wchcon-ads}@anchor{409}
+@anchor{gnat_rm/the_gnat_library id157}@anchor{40b}@anchor{gnat_rm/the_gnat_library system-wch-con-s-wchcon-ads}@anchor{40c}
@section @code{System.Wch_Con} (@code{s-wchcon.ads})
@@ -25071,7 +25136,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{40a}@anchor{gnat_rm/interfacing_to_other_languages id1}@anchor{40b}
+@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-other-languages}@anchor{11}@anchor{gnat_rm/interfacing_to_other_languages doc}@anchor{40d}@anchor{gnat_rm/interfacing_to_other_languages id1}@anchor{40e}
@chapter Interfacing to Other Languages
@@ -25089,7 +25154,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{40c}@anchor{gnat_rm/interfacing_to_other_languages id2}@anchor{40d}
+@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-c}@anchor{40f}@anchor{gnat_rm/interfacing_to_other_languages id2}@anchor{410}
@section Interfacing to C
@@ -25229,7 +25294,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{40e}@anchor{gnat_rm/interfacing_to_other_languages id3}@anchor{47}
+@anchor{gnat_rm/interfacing_to_other_languages id4}@anchor{411}@anchor{gnat_rm/interfacing_to_other_languages id3}@anchor{47}
@section Interfacing to C++
@@ -25286,7 +25351,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{40f}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-cobol}@anchor{410}
+@anchor{gnat_rm/interfacing_to_other_languages id5}@anchor{412}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-cobol}@anchor{413}
@section Interfacing to COBOL
@@ -25294,7 +25359,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{411}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-fortran}@anchor{412}
+@anchor{gnat_rm/interfacing_to_other_languages id6}@anchor{414}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-fortran}@anchor{415}
@section Interfacing to Fortran
@@ -25304,7 +25369,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{413}@anchor{gnat_rm/interfacing_to_other_languages id7}@anchor{414}
+@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-non-gnat-ada-code}@anchor{416}@anchor{gnat_rm/interfacing_to_other_languages id7}@anchor{417}
@section Interfacing to non-GNAT Ada code
@@ -25328,7 +25393,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{415}@anchor{gnat_rm/specialized_needs_annexes id1}@anchor{416}
+@anchor{gnat_rm/specialized_needs_annexes specialized-needs-annexes}@anchor{12}@anchor{gnat_rm/specialized_needs_annexes doc}@anchor{418}@anchor{gnat_rm/specialized_needs_annexes id1}@anchor{419}
@chapter Specialized Needs Annexes
@@ -25369,7 +25434,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{417}@anchor{gnat_rm/implementation_of_specific_ada_features id1}@anchor{418}
+@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{41a}@anchor{gnat_rm/implementation_of_specific_ada_features id1}@anchor{41b}
@chapter Implementation of Specific Ada Features
@@ -25387,7 +25452,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{169}@anchor{gnat_rm/implementation_of_specific_ada_features id2}@anchor{419}
+@anchor{gnat_rm/implementation_of_specific_ada_features machine-code-insertions}@anchor{169}@anchor{gnat_rm/implementation_of_specific_ada_features id2}@anchor{41c}
@section Machine Code Insertions
@@ -25555,7 +25620,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{41a}@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-tasking}@anchor{41b}
+@anchor{gnat_rm/implementation_of_specific_ada_features id3}@anchor{41d}@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-tasking}@anchor{41e}
@section GNAT Implementation of Tasking
@@ -25571,7 +25636,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{41c}@anchor{gnat_rm/implementation_of_specific_ada_features id4}@anchor{41d}
+@anchor{gnat_rm/implementation_of_specific_ada_features mapping-ada-tasks-onto-the-underlying-kernel-threads}@anchor{41f}@anchor{gnat_rm/implementation_of_specific_ada_features id4}@anchor{420}
@subsection Mapping Ada Tasks onto the Underlying Kernel Threads
@@ -25640,7 +25705,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{41e}@anchor{gnat_rm/implementation_of_specific_ada_features ensuring-compliance-with-the-real-time-annex}@anchor{41f}
+@anchor{gnat_rm/implementation_of_specific_ada_features id5}@anchor{421}@anchor{gnat_rm/implementation_of_specific_ada_features ensuring-compliance-with-the-real-time-annex}@anchor{422}
@subsection Ensuring Compliance with the Real-Time Annex
@@ -25691,7 +25756,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{420}
+@anchor{gnat_rm/implementation_of_specific_ada_features support-for-locking-policies}@anchor{423}
@subsection Support for Locking Policies
@@ -25725,7 +25790,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{421}@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-shared-passive-packages}@anchor{422}
+@anchor{gnat_rm/implementation_of_specific_ada_features id6}@anchor{424}@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-shared-passive-packages}@anchor{425}
@section GNAT Implementation of Shared Passive Packages
@@ -25823,7 +25888,7 @@ This is used to provide the required locking
semantics for proper protected object synchronization.
@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{423}@anchor{gnat_rm/implementation_of_specific_ada_features id7}@anchor{424}
+@anchor{gnat_rm/implementation_of_specific_ada_features code-generation-for-array-aggregates}@anchor{426}@anchor{gnat_rm/implementation_of_specific_ada_features id7}@anchor{427}
@section Code Generation for Array Aggregates
@@ -25854,7 +25919,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{425}@anchor{gnat_rm/implementation_of_specific_ada_features id8}@anchor{426}
+@anchor{gnat_rm/implementation_of_specific_ada_features static-constant-aggregates-with-static-bounds}@anchor{428}@anchor{gnat_rm/implementation_of_specific_ada_features id8}@anchor{429}
@subsection Static constant aggregates with static bounds
@@ -25901,7 +25966,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{427}@anchor{gnat_rm/implementation_of_specific_ada_features id9}@anchor{428}
+@anchor{gnat_rm/implementation_of_specific_ada_features constant-aggregates-with-unconstrained-nominal-types}@anchor{42a}@anchor{gnat_rm/implementation_of_specific_ada_features id9}@anchor{42b}
@subsection Constant aggregates with unconstrained nominal types
@@ -25916,7 +25981,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{429}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-static-bounds}@anchor{42a}
+@anchor{gnat_rm/implementation_of_specific_ada_features id10}@anchor{42c}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-static-bounds}@anchor{42d}
@subsection Aggregates with static bounds
@@ -25944,7 +26009,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{42b}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-nonstatic-bounds}@anchor{42c}
+@anchor{gnat_rm/implementation_of_specific_ada_features id11}@anchor{42e}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-nonstatic-bounds}@anchor{42f}
@subsection Aggregates with nonstatic bounds
@@ -25955,7 +26020,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{42d}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-in-assignment-statements}@anchor{42e}
+@anchor{gnat_rm/implementation_of_specific_ada_features id12}@anchor{430}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-in-assignment-statements}@anchor{431}
@subsection Aggregates in assignment statements
@@ -25997,7 +26062,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{42f}@anchor{gnat_rm/implementation_of_specific_ada_features the-size-of-discriminated-records-with-default-discriminants}@anchor{430}
+@anchor{gnat_rm/implementation_of_specific_ada_features id13}@anchor{432}@anchor{gnat_rm/implementation_of_specific_ada_features the-size-of-discriminated-records-with-default-discriminants}@anchor{433}
@section The Size of Discriminated Records with Default Discriminants
@@ -26077,7 +26142,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{431}@anchor{gnat_rm/implementation_of_specific_ada_features id14}@anchor{432}
+@anchor{gnat_rm/implementation_of_specific_ada_features strict-conformance-to-the-ada-reference-manual}@anchor{434}@anchor{gnat_rm/implementation_of_specific_ada_features id14}@anchor{435}
@section Strict Conformance to the Ada Reference Manual
@@ -26104,7 +26169,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{433}@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{434}
+@anchor{gnat_rm/implementation_of_ada_2012_features doc}@anchor{436}@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{437}
@chapter Implementation of Ada 2012 Features
@@ -28270,7 +28335,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{435}@anchor{gnat_rm/obsolescent_features doc}@anchor{436}@anchor{gnat_rm/obsolescent_features obsolescent-features}@anchor{15}
+@anchor{gnat_rm/obsolescent_features id1}@anchor{438}@anchor{gnat_rm/obsolescent_features doc}@anchor{439}@anchor{gnat_rm/obsolescent_features obsolescent-features}@anchor{15}
@chapter Obsolescent Features
@@ -28289,7 +28354,7 @@ compatibility purposes.
@end menu
@node pragma No_Run_Time,pragma Ravenscar,,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features id2}@anchor{437}@anchor{gnat_rm/obsolescent_features pragma-no-run-time}@anchor{438}
+@anchor{gnat_rm/obsolescent_features id2}@anchor{43a}@anchor{gnat_rm/obsolescent_features pragma-no-run-time}@anchor{43b}
@section pragma No_Run_Time
@@ -28302,7 +28367,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{439}@anchor{gnat_rm/obsolescent_features pragma-ravenscar}@anchor{43a}
+@anchor{gnat_rm/obsolescent_features id3}@anchor{43c}@anchor{gnat_rm/obsolescent_features pragma-ravenscar}@anchor{43d}
@section pragma Ravenscar
@@ -28311,7 +28376,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{43b}@anchor{gnat_rm/obsolescent_features id4}@anchor{43c}
+@anchor{gnat_rm/obsolescent_features pragma-restricted-run-time}@anchor{43e}@anchor{gnat_rm/obsolescent_features id4}@anchor{43f}
@section pragma Restricted_Run_Time
@@ -28321,7 +28386,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{43d}@anchor{gnat_rm/obsolescent_features id5}@anchor{43e}
+@anchor{gnat_rm/obsolescent_features pragma-task-info}@anchor{440}@anchor{gnat_rm/obsolescent_features id5}@anchor{441}
@section pragma Task_Info
@@ -28347,7 +28412,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{43f}@anchor{gnat_rm/obsolescent_features package-system-task-info-s-tasinf-ads}@anchor{440}
+@anchor{gnat_rm/obsolescent_features package-system-task-info}@anchor{442}@anchor{gnat_rm/obsolescent_features package-system-task-info-s-tasinf-ads}@anchor{443}
@section package System.Task_Info (@code{s-tasinf.ads})
@@ -28357,7 +28422,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{441}@anchor{gnat_rm/compatibility_and_porting_guide id1}@anchor{442}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-and-porting-guide}@anchor{16}@anchor{gnat_rm/compatibility_and_porting_guide doc}@anchor{444}@anchor{gnat_rm/compatibility_and_porting_guide id1}@anchor{445}
@chapter Compatibility and Porting Guide
@@ -28379,7 +28444,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{443}@anchor{gnat_rm/compatibility_and_porting_guide writing-portable-fixed-point-declarations}@anchor{444}
+@anchor{gnat_rm/compatibility_and_porting_guide id2}@anchor{446}@anchor{gnat_rm/compatibility_and_porting_guide writing-portable-fixed-point-declarations}@anchor{447}
@section Writing Portable Fixed-Point Declarations
@@ -28501,7 +28566,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{445}@anchor{gnat_rm/compatibility_and_porting_guide id3}@anchor{446}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-ada-83}@anchor{448}@anchor{gnat_rm/compatibility_and_porting_guide id3}@anchor{449}
@section Compatibility with Ada 83
@@ -28529,7 +28594,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{447}@anchor{gnat_rm/compatibility_and_porting_guide legal-ada-83-programs-that-are-illegal-in-ada-95}@anchor{448}
+@anchor{gnat_rm/compatibility_and_porting_guide id4}@anchor{44a}@anchor{gnat_rm/compatibility_and_porting_guide legal-ada-83-programs-that-are-illegal-in-ada-95}@anchor{44b}
@subsection Legal Ada 83 programs that are illegal in Ada 95
@@ -28629,7 +28694,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{449}@anchor{gnat_rm/compatibility_and_porting_guide id5}@anchor{44a}
+@anchor{gnat_rm/compatibility_and_porting_guide more-deterministic-semantics}@anchor{44c}@anchor{gnat_rm/compatibility_and_porting_guide id5}@anchor{44d}
@subsection More deterministic semantics
@@ -28657,7 +28722,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{44b}@anchor{gnat_rm/compatibility_and_porting_guide changed-semantics}@anchor{44c}
+@anchor{gnat_rm/compatibility_and_porting_guide id6}@anchor{44e}@anchor{gnat_rm/compatibility_and_porting_guide changed-semantics}@anchor{44f}
@subsection Changed semantics
@@ -28699,7 +28764,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{44d}@anchor{gnat_rm/compatibility_and_porting_guide id7}@anchor{44e}
+@anchor{gnat_rm/compatibility_and_porting_guide other-language-compatibility-issues}@anchor{450}@anchor{gnat_rm/compatibility_and_porting_guide id7}@anchor{451}
@subsection Other language compatibility issues
@@ -28732,7 +28797,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{44f}@anchor{gnat_rm/compatibility_and_porting_guide id8}@anchor{450}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-between-ada-95-and-ada-2005}@anchor{452}@anchor{gnat_rm/compatibility_and_porting_guide id8}@anchor{453}
@section Compatibility between Ada 95 and Ada 2005
@@ -28804,7 +28869,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{451}@anchor{gnat_rm/compatibility_and_porting_guide id9}@anchor{452}
+@anchor{gnat_rm/compatibility_and_porting_guide implementation-dependent-characteristics}@anchor{454}@anchor{gnat_rm/compatibility_and_porting_guide id9}@anchor{455}
@section Implementation-dependent characteristics
@@ -28827,7 +28892,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{453}@anchor{gnat_rm/compatibility_and_porting_guide id10}@anchor{454}
+@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-pragmas}@anchor{456}@anchor{gnat_rm/compatibility_and_porting_guide id10}@anchor{457}
@subsection Implementation-defined pragmas
@@ -28849,7 +28914,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{455}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-attributes}@anchor{456}
+@anchor{gnat_rm/compatibility_and_porting_guide id11}@anchor{458}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-attributes}@anchor{459}
@subsection Implementation-defined attributes
@@ -28863,7 +28928,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{457}@anchor{gnat_rm/compatibility_and_porting_guide id12}@anchor{458}
+@anchor{gnat_rm/compatibility_and_porting_guide libraries}@anchor{45a}@anchor{gnat_rm/compatibility_and_porting_guide id12}@anchor{45b}
@subsection Libraries
@@ -28892,7 +28957,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{459}@anchor{gnat_rm/compatibility_and_porting_guide id13}@anchor{45a}
+@anchor{gnat_rm/compatibility_and_porting_guide elaboration-order}@anchor{45c}@anchor{gnat_rm/compatibility_and_porting_guide id13}@anchor{45d}
@subsection Elaboration order
@@ -28928,7 +28993,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{45b}@anchor{gnat_rm/compatibility_and_porting_guide id14}@anchor{45c}
+@anchor{gnat_rm/compatibility_and_porting_guide target-specific-aspects}@anchor{45e}@anchor{gnat_rm/compatibility_and_porting_guide id14}@anchor{45f}
@subsection Target-specific aspects
@@ -28941,10 +29006,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{45d,,Representation Clauses}.
+GNAT's approach to these issues is described in @ref{460,,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{45e}@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-other-ada-systems}@anchor{45f}
+@anchor{gnat_rm/compatibility_and_porting_guide id15}@anchor{461}@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-other-ada-systems}@anchor{462}
@section Compatibility with Other Ada Systems
@@ -28987,7 +29052,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{45d}@anchor{gnat_rm/compatibility_and_porting_guide id16}@anchor{460}
+@anchor{gnat_rm/compatibility_and_porting_guide representation-clauses}@anchor{460}@anchor{gnat_rm/compatibility_and_porting_guide id16}@anchor{463}
@section Representation Clauses
@@ -29080,7 +29145,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{461}@anchor{gnat_rm/compatibility_and_porting_guide id17}@anchor{462}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-hp-ada-83}@anchor{464}@anchor{gnat_rm/compatibility_and_porting_guide id17}@anchor{465}
@section Compatibility with HP Ada 83
@@ -29110,7 +29175,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{463}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{464}
+@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license doc}@anchor{466}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{467}
@chapter GNU Free Documentation License
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index 47618f6..14e9271 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 , Sep 29, 2020
+GNAT User's Guide for Native Platforms , Nov 20, 2020
AdaCore
@@ -2970,6 +2970,10 @@ temporary files that are immediately deleted; it doesn't make sense to
depend on a file that no longer exists. Such tools include
@code{gprbuild}, @code{gnatmake}, and @code{gnatcheck}.
+By default, configuration pragma files are stored by their absolute paths in
+ALI files. You can use the @code{-gnateb} switch in order to store them by
+their basename instead.
+
If you are using project file, a separate mechanism is provided using
project attributes.
@@ -8968,6 +8972,19 @@ an exception because @code{Self(Obj)} produces an anonymous object which does
not share the memory location of @code{Obj}.
@end table
+@geindex -gnateb (gcc)
+
+
+@table @asis
+
+@item @code{-gnateb}
+
+Store configuration files by their basename in ALI files. This switch is
+used for instance by gprbuild for distributed builds in order to prevent
+issues where machine-specific absolute paths could end up being stored in
+ALI files.
+@end table
+
@geindex -gnatec (gcc)
@@ -13464,7 +13481,8 @@ but not @code{in} on its own.
All keywords must be in lower case (with the exception of keywords
such as @code{digits} used as attribute names to which this check
-does not apply).
+does not apply). A single error is reported for each line breaking
+this rule even if multiple casing issues exist on a same line.
@end table
@geindex -gnatyl (gcc)
@@ -15918,6 +15936,9 @@ Exclude source files (check object consistency only).
Use the target-independent XDR protocol for stream oriented attributes
instead of the default implementation which is based on direct binary
representations and is therefore target-and endianness-dependent.
+However it does not support 128-bit integer types and the exception
+@code{Ada.IO_Exceptions.Device_Error} is raised if any attempt is made
+at streaming 128-bit integer types with it.
@geindex -Xnnn (gnatbind)
diff --git a/gcc/ada/lib-load.adb b/gcc/ada/lib-load.adb
index 2598285..75226d3 100644
--- a/gcc/ada/lib-load.adb
+++ b/gcc/ada/lib-load.adb
@@ -551,7 +551,7 @@ package body Lib.Load is
-- Note: Unit_Name (Main_Unit) is not set if we are parsing gnat.adc.
if Present (Error_Node)
- and then Unit_Name (Main_Unit) /= No_Unit_Name
+ and then Present (Unit_Name (Main_Unit))
then
-- It seems like In_Extended_Main_Source_Unit (Error_Node) would
-- do the trick here, but that's wrong, it is much too early to
diff --git a/gcc/ada/lib-writ.adb b/gcc/ada/lib-writ.adb
index 6a63b8f..f5b9e30 100644
--- a/gcc/ada/lib-writ.adb
+++ b/gcc/ada/lib-writ.adb
@@ -837,7 +837,7 @@ package body Lib.Writ is
-- preprocessing data and definition files, there is no Unit_Name,
-- check for that first.
- if Unit_Name (J) /= No_Unit_Name
+ if Present (Unit_Name (J))
and then (With_Flags (J) or else Unit_Name (J) = Pname)
then
Num_Withs := Num_Withs + 1;
@@ -1125,9 +1125,7 @@ package body Lib.Writ is
if Nkind (U) = N_Subprogram_Body
and then Present (Corresponding_Spec (U))
- and then
- Ekind (Corresponding_Spec (U)) in E_Generic_Procedure
- | E_Generic_Function
+ and then Is_Generic_Subprogram (Corresponding_Spec (U))
then
null;
@@ -1478,11 +1476,8 @@ package body Lib.Writ is
-- Normal case of a unit entry with a source index
if Sind > No_Source_File then
- -- We never want directory information in ALI files
- -- ???But back out this change temporarily until
- -- gprbuild is fixed.
- if False then
+ if Config_Files_Store_Basename then
Fname := Strip_Directory (File_Name (Sind));
else
Fname := File_Name (Sind);
diff --git a/gcc/ada/lib-xref.adb b/gcc/ada/lib-xref.adb
index 64b9683..0869906 100644
--- a/gcc/ada/lib-xref.adb
+++ b/gcc/ada/lib-xref.adb
@@ -819,7 +819,7 @@ package body Lib.Xref is
end if;
-- For the left hand of an assignment case, we do nothing here.
- -- The processing for Analyze_Assignment_Statement will set the
+ -- The processing for Analyze_Assignment will set the
-- Referenced_As_LHS flag.
else
diff --git a/gcc/ada/lib.adb b/gcc/ada/lib.adb
index 49a352a..d298267 100644
--- a/gcc/ada/lib.adb
+++ b/gcc/ada/lib.adb
@@ -275,7 +275,7 @@ package body Lib is
begin
-- First unregister the old name, if any
- if Old_N /= No_Unit_Name and then Unit_Names.Get (Old_N) = U then
+ if Present (Old_N) and then Unit_Names.Get (Old_N) = U then
Unit_Names.Set (Old_N, No_Unit);
end if;
diff --git a/gcc/ada/libgnarl/s-osinte__solaris.ads b/gcc/ada/libgnarl/s-osinte__solaris.ads
index b3faa10..b9d6b88 100644
--- a/gcc/ada/libgnarl/s-osinte__solaris.ads
+++ b/gcc/ada/libgnarl/s-osinte__solaris.ads
@@ -45,9 +45,6 @@ with Ada.Unchecked_Conversion;
package System.OS_Interface is
pragma Preelaborate;
- pragma Linker_Options ("-lposix4");
- pragma Linker_Options ("-lthread");
-
subtype int is Interfaces.C.int;
subtype short is Interfaces.C.short;
subtype long is Interfaces.C.long;
diff --git a/gcc/ada/libgnarl/s-tasren.adb b/gcc/ada/libgnarl/s-tasren.adb
index 567b955..b7ee865 100644
--- a/gcc/ada/libgnarl/s-tasren.adb
+++ b/gcc/ada/libgnarl/s-tasren.adb
@@ -473,19 +473,7 @@ package body System.Tasking.Rendezvous is
pragma Debug
(Debug.Trace (Self_Id, "Local_Complete_Rendezvous", 'R'));
- if Ex = Ada.Exceptions.Null_Id then
-
- -- The call came from normal end-of-rendezvous, so abort is not yet
- -- deferred.
-
- Initialization.Defer_Abort (Self_Id);
-
- elsif ZCX_By_Default then
-
- -- With ZCX, aborts are not automatically deferred in handlers
-
- Initialization.Defer_Abort (Self_Id);
- end if;
+ Initialization.Defer_Abort (Self_Id);
-- We need to clean up any accepts which Self may have been serving when
-- it was aborted.
diff --git a/gcc/ada/libgnarl/s-tassta.adb b/gcc/ada/libgnarl/s-tassta.adb
index aada734..900b3b7 100644
--- a/gcc/ada/libgnarl/s-tassta.adb
+++ b/gcc/ada/libgnarl/s-tassta.adb
@@ -1096,11 +1096,10 @@ package body System.Tasking.Stages is
-- stack analysis.
Big_Overflow_Guard : constant := 64 * 1024 + 8 * 1024;
- Small_Stack_Limit : constant := 64 * 1024;
- -- ??? These three values are experimental, and seem to work on
- -- most platforms. They still need to be analyzed further. They
- -- also need documentation, what are they and why does the logic
- -- differ depending on whether the stack is large or small???
+ -- These two values are experimental, and seem to work on most
+ -- platforms. They still need to be analyzed further. They also
+ -- need documentation, what are they and why does the logic differ
+ -- depending on whether the stack is large or small???
Pattern_Size : Natural :=
Natural (Self_ID.Common.
@@ -1123,7 +1122,7 @@ package body System.Tasking.Stages is
-- Adjustments for inner frames
Pattern_Size := Pattern_Size -
- (if Pattern_Size < Small_Stack_Limit
+ (if Pattern_Size < Big_Overflow_Guard
then Small_Overflow_Guard
else Big_Overflow_Guard);
else
diff --git a/gcc/ada/libgnarl/s-tpobop.adb b/gcc/ada/libgnarl/s-tpobop.adb
index 5537c1a..b123c19 100644
--- a/gcc/ada/libgnarl/s-tpobop.adb
+++ b/gcc/ada/libgnarl/s-tpobop.adb
@@ -246,17 +246,7 @@ package body System.Tasking.Protected_Objects.Operations is
Entry_Call.Exception_To_Raise := Ex;
if Ex /= Ada.Exceptions.Null_Id then
-
- -- An exception was raised and abort was deferred, so adjust
- -- before propagating, otherwise the task will stay with deferral
- -- enabled for its remaining life.
-
Self_Id := STPO.Self;
-
- if not ZCX_By_Default then
- Initialization.Undefer_Abort_Nestable (Self_Id);
- end if;
-
Transfer_Occurrence
(Entry_Call.Self.Common.Compiler_Data.Current_Excep'Access,
Self_Id.Common.Compiler_Data.Current_Excep);
diff --git a/gcc/ada/libgnat/a-cbhase.adb b/gcc/ada/libgnat/a-cbhase.adb
index 293d722..75b9667 100644
--- a/gcc/ada/libgnat/a-cbhase.adb
+++ b/gcc/ada/libgnat/a-cbhase.adb
@@ -1783,7 +1783,7 @@ is
-- Read --
----------
- procedure Read
+ procedure Read
(Stream : not null access Root_Stream_Type'Class;
Item : out Reference_Type)
is
diff --git a/gcc/ada/libgnat/a-cbmutr.ads b/gcc/ada/libgnat/a-cbmutr.ads
index a9fb55a..d9a4a9a 100644
--- a/gcc/ada/libgnat/a-cbmutr.ads
+++ b/gcc/ada/libgnat/a-cbmutr.ads
@@ -333,7 +333,7 @@ private
Node : Count_Type'Base := No_Node;
end record;
- procedure Read
+ procedure Read
(Stream : not null access Root_Stream_Type'Class;
Position : out Cursor);
for Cursor'Read use Read;
diff --git a/gcc/ada/libgnat/a-cborse.adb b/gcc/ada/libgnat/a-cborse.adb
index e4a2de8..41f0859 100644
--- a/gcc/ada/libgnat/a-cborse.adb
+++ b/gcc/ada/libgnat/a-cborse.adb
@@ -908,7 +908,7 @@ is
-- Read --
----------
- procedure Read
+ procedure Read
(Stream : not null access Root_Stream_Type'Class;
Item : out Reference_Type)
is
diff --git a/gcc/ada/libgnat/a-decima__128.ads b/gcc/ada/libgnat/a-decima__128.ads
new file mode 100644
index 0000000..b29b010
--- /dev/null
+++ b/gcc/ada/libgnat/a-decima__128.ads
@@ -0,0 +1,69 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . D E C I M A L --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- GNAT is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the 128-bit version of this package
+
+package Ada.Decimal is
+ pragma Pure;
+
+ -- The compiler makes a number of assumptions based on the following five
+ -- constants (e.g. there is an assumption that decimal values can always
+ -- be represented in 128-bit signed binary form), so code modifications are
+ -- required to increase these constants.
+
+ Max_Scale : constant := +38;
+ Min_Scale : constant := -38;
+
+ Min_Delta : constant := 1.0E-38;
+ Max_Delta : constant := 1.0E+38;
+
+ Max_Decimal_Digits : constant := 38;
+
+ generic
+ type Dividend_Type is delta <> digits <>;
+ type Divisor_Type is delta <> digits <>;
+ type Quotient_Type is delta <> digits <>;
+ type Remainder_Type is delta <> digits <>;
+
+ procedure Divide
+ (Dividend : Dividend_Type;
+ Divisor : Divisor_Type;
+ Quotient : out Quotient_Type;
+ Remainder : out Remainder_Type);
+
+private
+ pragma Inline (Divide);
+
+end Ada.Decimal;
diff --git a/gcc/ada/libgnat/a-except.adb b/gcc/ada/libgnat/a-except.adb
index 52e716f..f7fd5bb 100644
--- a/gcc/ada/libgnat/a-except.adb
+++ b/gcc/ada/libgnat/a-except.adb
@@ -957,11 +957,6 @@ package body Ada.Exceptions is
begin
Exception_Data.Set_Exception_Msg (X, E, Message);
-
- if not ZCX_By_Default then
- Abort_Defer.all;
- end if;
-
Complete_And_Propagate_Occurrence (X);
end Raise_Exception_Always;
@@ -1041,11 +1036,6 @@ package body Ada.Exceptions is
begin
Exception_Data.Set_Exception_C_Msg (X, E, M);
-
- if not ZCX_By_Default then
- Abort_Defer.all;
- end if;
-
Complete_Occurrence (X);
return X;
end Create_Occurrence_From_Signal_Handler;
@@ -1141,11 +1131,6 @@ package body Ada.Exceptions is
X : constant EOA := Exception_Propagation.Allocate_Occurrence;
begin
Exception_Data.Set_Exception_C_Msg (X, E, F, L, C, M);
-
- if not ZCX_By_Default then
- Abort_Defer.all;
- end if;
-
Complete_And_Propagate_Occurrence (X);
end Raise_With_Location_And_Msg;
@@ -1168,13 +1153,6 @@ package body Ada.Exceptions is
Excep.Msg_Length := Ex.Msg_Length;
Excep.Msg (1 .. Excep.Msg_Length) := Ex.Msg (1 .. Ex.Msg_Length);
- -- The following is a common pattern, should be abstracted
- -- into a procedure call ???
-
- if not ZCX_By_Default then
- Abort_Defer.all;
- end if;
-
Complete_And_Propagate_Occurrence (Excep);
end Raise_With_Msg;
@@ -1507,10 +1485,6 @@ package body Ada.Exceptions is
Saved_MO : constant System.Address := Excep.Machine_Occurrence;
begin
- if not ZCX_By_Default then
- Abort_Defer.all;
- end if;
-
Save_Occurrence (Excep.all, Get_Current_Excep.all.all);
Excep.Machine_Occurrence := Saved_MO;
Complete_And_Propagate_Occurrence (Excep);
@@ -1556,10 +1530,6 @@ package body Ada.Exceptions is
procedure Reraise_Occurrence_Always (X : Exception_Occurrence) is
begin
- if not ZCX_By_Default then
- Abort_Defer.all;
- end if;
-
Reraise_Occurrence_No_Defer (X);
end Reraise_Occurrence_Always;
diff --git a/gcc/ada/libgnat/a-nbnbin.adb b/gcc/ada/libgnat/a-nbnbin.adb
index 70df2c2..9e051d3 100644
--- a/gcc/ada/libgnat/a-nbnbin.adb
+++ b/gcc/ada/libgnat/a-nbnbin.adb
@@ -177,7 +177,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
function To_Big_Integer (Arg : Int) return Valid_Big_Integer is
Result : Big_Integer;
begin
- Set_Bignum (Result, To_Bignum (Long_Long_Integer (Arg)));
+ Set_Bignum (Result, To_Bignum (Long_Long_Long_Integer (Arg)));
return Result;
end To_Big_Integer;
@@ -205,7 +205,7 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
function To_Big_Integer (Arg : Int) return Valid_Big_Integer is
Result : Big_Integer;
begin
- Set_Bignum (Result, To_Bignum (Unsigned_64 (Arg)));
+ Set_Bignum (Result, To_Bignum (Unsigned_128 (Arg)));
return Result;
end To_Big_Integer;
@@ -235,12 +235,197 @@ package body Ada.Numerics.Big_Numbers.Big_Integers is
-- From_String --
-----------------
- function From_String (Arg : String) return Big_Integer is
+ function From_String (Arg : String) return Valid_Big_Integer is
+ procedure Scan_Decimal
+ (Arg : String; J : in out Natural; Result : out Big_Integer);
+ -- Scan decimal value starting at Arg (J). Store value in Result if
+ -- successful, raise Constraint_Error if not. On exit, J points to the
+ -- first index past the decimal value.
+
+ ------------------
+ -- Scan_Decimal --
+ ------------------
+
+ procedure Scan_Decimal
+ (Arg : String; J : in out Natural; Result : out Big_Integer)
+ is
+ Initial_J : constant Natural := J;
+ Ten : constant Big_Integer := To_Big_Integer (10);
+ begin
+ Result := To_Big_Integer (0);
+
+ while J <= Arg'Last loop
+ if Arg (J) in '0' .. '9' then
+ Result :=
+ Result * Ten + To_Big_Integer (Character'Pos (Arg (J))
+ - Character'Pos ('0'));
+
+ elsif Arg (J) = '_' then
+ if J in Initial_J | Arg'Last
+ or else Arg (J - 1) not in '0' .. '9'
+ or else Arg (J + 1) not in '0' .. '9'
+ then
+ raise Constraint_Error with "invalid integer value: " & Arg;
+ end if;
+ else
+ exit;
+ end if;
+
+ J := J + 1;
+ end loop;
+ end Scan_Decimal;
+
Result : Big_Integer;
+
begin
- -- ??? only support Long_Long_Long_Integer, good enough for now
+ -- First try the fast path via Long_Long_Long_Integer'Value
+
Set_Bignum (Result, To_Bignum (Long_Long_Long_Integer'Value (Arg)));
return Result;
+
+ exception
+ when Constraint_Error =>
+ -- Then try the slow path
+
+ declare
+ Neg : Boolean := False;
+ Base_Found : Boolean := False;
+ Base_Int : Positive := 10;
+ J : Natural := Arg'First;
+ Val : Natural;
+ Base : Big_Integer;
+ Exp : Big_Integer;
+
+ begin
+ -- Scan past leading blanks
+
+ while J <= Arg'Last and then Arg (J) = ' ' loop
+ J := J + 1;
+ end loop;
+
+ if J > Arg'Last then
+ raise;
+ end if;
+
+ -- Scan and store negative sign if found
+
+ if Arg (J) = '-' then
+ Neg := True;
+ J := J + 1;
+ end if;
+
+ -- Scan decimal value: either the result itself, or the base
+ -- value if followed by a '#'.
+
+ Scan_Decimal (Arg, J, Result);
+
+ -- Scan explicit base if requested
+
+ if J <= Arg'Last and then Arg (J) = '#' then
+ Base_Int := To_Integer (Result);
+
+ if Base_Int not in 2 .. 16 then
+ raise;
+ end if;
+
+ Base_Found := True;
+ Base := Result;
+ Result := To_Big_Integer (0);
+ J := J + 1;
+
+ while J <= Arg'Last loop
+ case Arg (J) is
+ when '0' .. '9' =>
+ Val := Character'Pos (Arg (J)) - Character'Pos ('0');
+
+ if Val >= Base_Int then
+ raise;
+ end if;
+
+ Result := Result * Base + To_Big_Integer (Val);
+
+ when 'a' .. 'f' =>
+ Val :=
+ 10 + Character'Pos (Arg (J)) - Character'Pos ('a');
+
+ if Val >= Base_Int then
+ raise;
+ end if;
+
+ Result := Result * Base + To_Big_Integer (Val);
+
+ when 'A' .. 'F' =>
+ Val :=
+ 10 + Character'Pos (Arg (J)) - Character'Pos ('A');
+
+ if Val >= Base_Int then
+ raise;
+ end if;
+
+ Result := Result * Base + To_Big_Integer (Val);
+
+ when '_' =>
+
+ -- We only allow _ preceded and followed by a valid
+ -- number and not any other character.
+
+ if J in Arg'First | Arg'Last
+ or else Arg (J - 1) in '_' | '#'
+ or else Arg (J + 1) = '#'
+ then
+ raise;
+ end if;
+
+ when '#' =>
+ J := J + 1;
+ exit;
+
+ when others =>
+ raise;
+ end case;
+
+ J := J + 1;
+ end loop;
+ else
+ Base := To_Big_Integer (10);
+ end if;
+
+ if Base_Found and then Arg (J - 1) /= '#' then
+ raise;
+ end if;
+
+ if J <= Arg'Last then
+
+ -- Scan exponent
+
+ if Arg (J) in 'e' | 'E' then
+ J := J + 1;
+
+ if Arg (J) = '+' then
+ J := J + 1;
+ end if;
+
+ Scan_Decimal (Arg, J, Exp);
+ Result := Result * (Base ** To_Integer (Exp));
+ end if;
+
+ -- Scan past trailing blanks
+
+ while J <= Arg'Last and then Arg (J) = ' ' loop
+ J := J + 1;
+ end loop;
+
+ if J <= Arg'Last then
+ raise;
+ end if;
+ end if;
+
+ if Neg then
+ return -Result;
+ else
+ return Result;
+ end if;
+ end;
end From_String;
---------------
diff --git a/gcc/ada/libgnat/a-nbnbin.ads b/gcc/ada/libgnat/a-nbnbin.ads
index 7b4974a..668da8d 100644
--- a/gcc/ada/libgnat/a-nbnbin.ads
+++ b/gcc/ada/libgnat/a-nbnbin.ads
@@ -113,7 +113,7 @@ is
Post => To_String'Result'First = 1,
Global => null;
- function From_String (Arg : String) return Big_Integer
+ function From_String (Arg : String) return Valid_Big_Integer
with Global => null;
procedure Put_Image (S : in out Sink'Class; V : Big_Integer);
diff --git a/gcc/ada/libgnat/a-nbnbre.adb b/gcc/ada/libgnat/a-nbnbre.adb
index d61668d..4ff5b35 100644
--- a/gcc/ada/libgnat/a-nbnbre.adb
+++ b/gcc/ada/libgnat/a-nbnbre.adb
@@ -29,9 +29,8 @@
-- --
------------------------------------------------------------------------------
--- This is the default version of this package, based on Big_Integers only.
-
with Ada.Strings.Text_Output.Utils;
+with System.Unsigned_Types; use System.Unsigned_Types;
package body Ada.Numerics.Big_Numbers.Big_Reals is
@@ -84,14 +83,16 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is
---------
function "=" (L, R : Valid_Big_Real) return Boolean is
- (abs L.Num = abs R.Num and then L.Den = R.Den);
+ (L.Num = R.Num and then L.Den = R.Den);
---------
-- "<" --
---------
function "<" (L, R : Valid_Big_Real) return Boolean is
- (abs L.Num * R.Den < abs R.Num * L.Den);
+ (L.Num * R.Den < R.Num * L.Den);
+ -- The denominator is guaranteed to be positive since Normalized is
+ -- always called when constructing a Valid_Big_Real
----------
-- "<=" --
@@ -117,22 +118,185 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is
package body Float_Conversions is
+ package Conv is new
+ Big_Integers.Unsigned_Conversions (Long_Long_Unsigned);
+
-----------------
-- To_Big_Real --
-----------------
+ -- We get the fractional representation of the floating-point number by
+ -- multiplying Num'Fraction by 2.0**M, with M the size of the mantissa,
+ -- which gives zero or a number in the range [2.0**(M-1)..2.0**M), which
+ -- means that it is an integer N of M bits. The floating-point number is
+ -- thus equal to N / 2**(M-E) where E is its Num'Exponent.
+
function To_Big_Real (Arg : Num) return Valid_Big_Real is
+
+ A : constant Num'Base := abs (Arg);
+ E : constant Integer := Num'Exponent (A);
+ F : constant Num'Base := Num'Fraction (A);
+ M : constant Natural := Num'Machine_Mantissa;
+
+ N, D : Big_Integer;
+
begin
- return From_String (Arg'Image);
+ pragma Assert (Num'Machine_Radix = 2);
+ -- This implementation does not handle radix 16
+
+ pragma Assert (M <= 64);
+ -- This implementation handles only 80-bit IEEE Extended or smaller
+
+ N := Conv.To_Big_Integer (Long_Long_Unsigned (F * 2.0**M));
+
+ -- If E is smaller than M, the denominator is 2**(M-E)
+
+ if E < M then
+ D := To_Big_Integer (2) ** (M - E);
+
+ -- Or else, if E is larger than M, multiply the numerator by 2**(E-M)
+
+ elsif E > M then
+ N := N * To_Big_Integer (2) ** (E - M);
+ D := To_Big_Integer (1);
+
+ -- Otherwise E is equal to M and the result is just N
+
+ else
+ D := To_Big_Integer (1);
+ end if;
+
+ return (if Arg >= 0.0 then N / D else -N / D);
end To_Big_Real;
-------------------
-- From_Big_Real --
-------------------
+ -- We get the (Frac, Exp) representation of the real number by finding
+ -- the exponent E such that it lies in the range [2.0**(E-1)..2.0**E),
+ -- multiplying the number by 2.0**(M-E) with M the size of the mantissa,
+ -- and converting the result to integer N in the range [2**(M-1)..2**M)
+ -- with rounding to nearest, ties to even, and finally call Num'Compose.
+ -- This does not apply to the zero, for which we return 0.0 early.
+
function From_Big_Real (Arg : Big_Real) return Num is
+
+ M : constant Natural := Num'Machine_Mantissa;
+ One : constant Big_Real := To_Real (1);
+ Two : constant Big_Real := To_Real (2);
+ Half : constant Big_Real := One / Two;
+ TwoI : constant Big_Integer := To_Big_Integer (2);
+
+ function Log2_Estimate (V : Big_Real) return Natural;
+ -- Return an integer not larger than Log2 (V) for V >= 1.0
+
+ function Minus_Log2_Estimate (V : Big_Real) return Natural;
+ -- Return an integer not larger than -Log2 (V) for V < 1.0
+
+ -------------------
+ -- Log2_Estimate --
+ -------------------
+
+ function Log2_Estimate (V : Big_Real) return Natural is
+ Log : Natural := 1;
+ Pow : Big_Real := Two;
+
+ begin
+ while V >= Pow loop
+ Pow := Pow * Pow;
+ Log := Log + Log;
+ end loop;
+
+ return Log / 2;
+ end Log2_Estimate;
+
+ -------------------------
+ -- Minus_Log2_Estimate --
+ -------------------------
+
+ function Minus_Log2_Estimate (V : Big_Real) return Natural is
+ Log : Natural := 1;
+ Pow : Big_Real := Half;
+
+ begin
+ while V <= Pow loop
+ Pow := Pow * Pow;
+ Log := Log + Log;
+ end loop;
+
+ return Log / 2;
+ end Minus_Log2_Estimate;
+
+ -- Local variables
+
+ V : Big_Real := abs (Arg);
+ E : Integer := 0;
+ L : Integer;
+
+ A, B, Q, X : Big_Integer;
+ N : Long_Long_Unsigned;
+ R : Num'Base;
+
begin
- return Num'Value (To_String (Arg));
+ pragma Assert (Num'Machine_Radix = 2);
+ -- This implementation does not handle radix 16
+
+ pragma Assert (M <= 64);
+ -- This implementation handles only 80-bit IEEE Extended or smaller
+
+ -- Protect from degenerate case
+
+ if Numerator (V) = To_Big_Integer (0) then
+ return 0.0;
+ end if;
+
+ -- Use a binary search to compute exponent E
+
+ while V < Half loop
+ L := Minus_Log2_Estimate (V);
+ V := V * (Two ** L);
+ E := E - L;
+ end loop;
+
+ -- The dissymetry with above is expected since we go below 2
+
+ while V >= One loop
+ L := Log2_Estimate (V) + 1;
+ V := V / (Two ** L);
+ E := E + L;
+ end loop;
+
+ -- The multiplication by 2.0**(-E) has already been done in the loops
+
+ V := V * To_Big_Real (TwoI ** M);
+
+ -- Now go into the integer domain and divide
+
+ A := Numerator (V);
+ B := Denominator (V);
+
+ Q := A / B;
+ N := Conv.From_Big_Integer (Q);
+
+ -- Round to nearest, ties to even, by comparing twice the remainder
+
+ X := (A - Q * B) * TwoI;
+
+ if X > B or else (X = B and then (N mod 2) = 1) then
+ N := N + 1;
+
+ -- If the adjusted quotient overflows the mantissa, scale up
+
+ if N = 2**M then
+ N := 1;
+ E := E + 1;
+ end if;
+ end if;
+
+ R := Num'Compose (Num'Base (N), E);
+
+ return (if Numerator (Arg) >= To_Big_Integer (0) then R else -R);
end From_Big_Real;
end Float_Conversions;
@@ -143,22 +307,78 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is
package body Fixed_Conversions is
+ package Float_Aux is new Float_Conversions (Long_Long_Float);
+
+ subtype LLLI is Long_Long_Long_Integer;
+ subtype LLLU is Long_Long_Long_Unsigned;
+
+ Too_Large : constant Boolean :=
+ Num'Small_Numerator > LLLU'Last
+ or else Num'Small_Denominator > LLLU'Last;
+ -- True if the Small is too large for Long_Long_Long_Unsigned, in which
+ -- case we convert to/from Long_Long_Float as an intermediate step.
+
+ package Conv_I is new Big_Integers.Signed_Conversions (LLLI);
+ package Conv_U is new Big_Integers.Unsigned_Conversions (LLLU);
+
-----------------
-- To_Big_Real --
-----------------
+ -- We just compute V * N / D where V is the mantissa value of the fixed
+ -- point number, and N resp. D is the numerator resp. the denominator of
+ -- the Small of the fixed-point type.
+
function To_Big_Real (Arg : Num) return Valid_Big_Real is
+ N, D, V : Big_Integer;
+
begin
- return From_String (Arg'Image);
+ if Too_Large then
+ return Float_Aux.To_Big_Real (Long_Long_Float (Arg));
+ end if;
+
+ N := Conv_U.To_Big_Integer (Num'Small_Numerator);
+ D := Conv_U.To_Big_Integer (Num'Small_Denominator);
+ V := Conv_I.To_Big_Integer (LLLI'Integer_Value (Arg));
+
+ return V * N / D;
end To_Big_Real;
-------------------
-- From_Big_Real --
-------------------
+ -- We first compute A / B = Arg * D / N where N resp. D is the numerator
+ -- resp. the denominator of the Small of the fixed-point type. Then we
+ -- divide A by B and convert the result to the mantissa value.
+
function From_Big_Real (Arg : Big_Real) return Num is
+ N, D, A, B, Q, X : Big_Integer;
+
begin
- return Num'Value (To_String (Arg));
+ if Too_Large then
+ return Num (Float_Aux.From_Big_Real (Arg));
+ end if;
+
+ N := Conv_U.To_Big_Integer (Num'Small_Numerator);
+ D := Conv_U.To_Big_Integer (Num'Small_Denominator);
+ A := Numerator (Arg) * D;
+ B := Denominator (Arg) * N;
+
+ Q := A / B;
+
+ -- Round to nearest, ties to away, by comparing twice the remainder
+
+ X := (A - Q * B) * To_Big_Integer (2);
+
+ if X >= B then
+ Q := Q + To_Big_Integer (1);
+
+ elsif X <= -B then
+ Q := Q - To_Big_Integer (1);
+ end if;
+
+ return Num'Fixed_Value (Conv_I.From_Big_Integer (Q));
end From_Big_Real;
end Fixed_Conversions;
@@ -318,7 +538,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is
-- From_String --
-----------------
- function From_String (Arg : String) return Big_Real is
+ function From_String (Arg : String) return Valid_Big_Real is
Ten : constant Big_Integer := To_Big_Integer (10);
Frac : Big_Integer;
Exp : Integer := 0;
@@ -340,7 +560,7 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is
elsif Arg (J) = '.' then
Index := J - 1;
exit;
- else
+ elsif Arg (J) /= '_' then
Pow := Pow + 1;
end if;
end loop;
@@ -373,6 +593,13 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is
end;
end From_String;
+ function From_String
+ (Numerator, Denominator : String) return Valid_Big_Real is
+ begin
+ return Big_Integers.From_String (Numerator) /
+ Big_Integers.From_String (Denominator);
+ end From_String;
+
--------------------------
-- From_Quotient_String --
--------------------------
diff --git a/gcc/ada/libgnat/a-nbnbre.ads b/gcc/ada/libgnat/a-nbnbre.ads
index 5a8ebb9..ee5636f 100644
--- a/gcc/ada/libgnat/a-nbnbre.ads
+++ b/gcc/ada/libgnat/a-nbnbre.ads
@@ -120,7 +120,9 @@ is
Post => To_String'Result'First = 1,
Global => null;
- function From_String (Arg : String) return Big_Real
+ function From_String (Arg : String) return Valid_Big_Real
+ with Global => null;
+ function From_String (Numerator, Denominator : String) return Valid_Big_Real
with Global => null;
function To_Quotient_String (Arg : Big_Real) return String is
diff --git a/gcc/ada/libgnat/a-strmap.ads b/gcc/ada/libgnat/a-strmap.ads
index ab59402..c922f4e 100644
--- a/gcc/ada/libgnat/a-strmap.ads
+++ b/gcc/ada/libgnat/a-strmap.ads
@@ -33,6 +33,12 @@
-- --
------------------------------------------------------------------------------
+-- Preconditions in this unit are meant for analysis only, not for run-time
+-- checking, so that the expected exceptions are raised. This is enforced by
+-- setting the corresponding assertion policy to Ignore.
+
+pragma Assertion_Policy (Pre => Ignore);
+
with Ada.Characters.Latin_1;
package Ada.Strings.Maps is
@@ -61,23 +67,85 @@ package Ada.Strings.Maps is
type Character_Ranges is array (Positive range <>) of Character_Range;
- function To_Set (Ranges : Character_Ranges) return Character_Set;
-
- function To_Set (Span : Character_Range) return Character_Set;
-
- function To_Ranges (Set : Character_Set) return Character_Ranges;
+ function To_Set (Ranges : Character_Ranges) return Character_Set with
+ Post =>
+ (if Ranges'Length = 0 then To_Set'Result = Null_Set)
+ and then
+ (for all Char in Character =>
+ (if Is_In (Char, To_Set'Result)
+ then (for some Span of Ranges => Char in Span.Low .. Span.High)))
+ and then
+ (for all Span of Ranges =>
+ (for all Char in Span.Low .. Span.High =>
+ Is_In (Char, To_Set'Result)));
+
+ function To_Set (Span : Character_Range) return Character_Set with
+ Post =>
+ (if Span.High < Span.Low then To_Set'Result = Null_Set)
+ and then
+ (for all Char in Character =>
+ (if Is_In (Char, To_Set'Result) then Char in Span.Low .. Span.High))
+ and then
+ (for all Char in Span.Low .. Span.High => Is_In (Char, To_Set'Result));
+
+ function To_Ranges (Set : Character_Set) return Character_Ranges with
+ Post =>
+ (if Set = Null_Set then To_Ranges'Result'Length = 0)
+ and then
+ (for all Char in Character =>
+ (if Is_In (Char, Set)
+ then
+ (for some Span of To_Ranges'Result =>
+ Char in Span.Low .. Span.High)))
+ and then
+ (for all Span of To_Ranges'Result =>
+ (for all Char in Span.Low .. Span.High => Is_In (Char, Set)));
----------------------------------
-- Operations on Character Sets --
----------------------------------
- function "=" (Left, Right : Character_Set) return Boolean;
-
- function "not" (Right : Character_Set) return Character_Set;
- function "and" (Left, Right : Character_Set) return Character_Set;
- function "or" (Left, Right : Character_Set) return Character_Set;
- function "xor" (Left, Right : Character_Set) return Character_Set;
- function "-" (Left, Right : Character_Set) return Character_Set;
+ function "=" (Left, Right : Character_Set) return Boolean with
+ Post =>
+ "="'Result
+ =
+ (for all Char in Character =>
+ (Is_In (Char, Left) = Is_In (Char, Right)));
+
+ function "not" (Right : Character_Set) return Character_Set with
+ Post =>
+ (for all Char in Character =>
+ (Is_In (Char, "not"'Result)
+ =
+ not Is_In (Char, Right)));
+
+ function "and" (Left, Right : Character_Set) return Character_Set with
+ Post =>
+ (for all Char in Character =>
+ (Is_In (Char, "and"'Result)
+ =
+ (Is_In (Char, Left) and Is_In (Char, Right))));
+
+ function "or" (Left, Right : Character_Set) return Character_Set with
+ Post =>
+ (for all Char in Character =>
+ (Is_In (Char, "or"'Result)
+ =
+ (Is_In (Char, Left) or Is_In (Char, Right))));
+
+ function "xor" (Left, Right : Character_Set) return Character_Set with
+ Post =>
+ (for all Char in Character =>
+ (Is_In (Char, "xor"'Result)
+ =
+ (Is_In (Char, Left) xor Is_In (Char, Right))));
+
+ function "-" (Left, Right : Character_Set) return Character_Set with
+ Post =>
+ (for all Char in Character =>
+ (Is_In (Char, "-"'Result)
+ =
+ (Is_In (Char, Left) and not Is_In (Char, Right))));
function Is_In
(Element : Character;
@@ -85,20 +153,54 @@ package Ada.Strings.Maps is
function Is_Subset
(Elements : Character_Set;
- Set : Character_Set) return Boolean;
+ Set : Character_Set) return Boolean
+ with
+ Post =>
+ Is_Subset'Result
+ =
+ (for all Char in Character =>
+ (if Is_In (Char, Elements) then Is_In (Char, Set)));
function "<="
(Left : Character_Set;
- Right : Character_Set) return Boolean
+ Right : Character_Set) return Boolean
renames Is_Subset;
subtype Character_Sequence is String;
-- Alternative representation for a set of character values
- function To_Set (Sequence : Character_Sequence) return Character_Set;
- function To_Set (Singleton : Character) return Character_Set;
-
- function To_Sequence (Set : Character_Set) return Character_Sequence;
+ function To_Set (Sequence : Character_Sequence) return Character_Set with
+ Post =>
+ (if Sequence'Length = 0 then To_Set'Result = Null_Set)
+ and then
+ (for all Char in Character =>
+ (if Is_In (Char, To_Set'Result)
+ then (for some X of Sequence => Char = X)))
+ and then
+ (for all Char of Sequence => Is_In (Char, To_Set'Result));
+
+ function To_Set (Singleton : Character) return Character_Set with
+ Post =>
+ Is_In (Singleton, To_Set'Result)
+ and then
+ (for all Char in Character =>
+ (if Char /= Singleton
+ then not Is_In (Char, To_Set'Result)));
+
+ function To_Sequence (Set : Character_Set) return Character_Sequence with
+ Post =>
+ (if Set = Null_Set then To_Sequence'Result'Length = 0)
+ and then
+ (for all Char in Character =>
+ (if Is_In (Char, Set)
+ then (for some X of To_Sequence'Result => Char = X)))
+ and then
+ (for all Char of To_Sequence'Result => Is_In (Char, Set))
+ and then
+ (for all J in To_Sequence'Result'Range =>
+ (for all K in To_Sequence'Result'Range =>
+ (if J /= K
+ then To_Sequence'Result (J) /= To_Sequence'Result (K))));
------------------------------------
-- Character Mapping Declarations --
@@ -119,13 +221,48 @@ package Ada.Strings.Maps is
----------------------------
function To_Mapping
- (From, To : Character_Sequence) return Character_Mapping;
+ (From, To : Character_Sequence) return Character_Mapping
+ with
+ Pre =>
+ From'Length = To'Length
+ and then
+ (for all J in From'Range =>
+ (for all K in From'Range =>
+ (if J /= K then From (J) /= From (K)))),
+ Post =>
+ (if From = To then To_Mapping'Result = Identity)
+ and then
+ (for all Char in Character =>
+ ((for all J in From'Range =>
+ (if From (J) = Char
+ then Value (To_Mapping'Result, Char)
+ = To (J - From'First + To'First)))
+ and then
+ (if (for all X of From => Char /= X)
+ then Value (To_Mapping'Result, Char) = Char)));
function To_Domain
- (Map : Character_Mapping) return Character_Sequence;
+ (Map : Character_Mapping) return Character_Sequence with
+ Post =>
+ (if Map = Identity then To_Domain'Result'Length = 0)
+ and then
+ To_Domain'Result'First = 1
+ and then
+ (for all Char in Character =>
+ (if (for all X of To_Domain'Result => X /= Char)
+ then Value (Map, Char) = Char))
+ and then
+ (for all Char of To_Domain'Result => Value (Map, Char) /= Char);
function To_Range
- (Map : Character_Mapping) return Character_Sequence;
+ (Map : Character_Mapping) return Character_Sequence with
+ Post =>
+ To_Range'Result'First = 1
+ and then
+ To_Range'Result'Last = To_Domain (Map)'Last
+ and then
+ (for all J in To_Range'Result'Range =>
+ To_Range'Result (J) = Value (Map, To_Domain (Map) (J)));
type Character_Mapping_Function is
access function (From : Character) return Character;
diff --git a/gcc/ada/libgnat/a-stzhas.adb b/gcc/ada/libgnat/a-stzhas.adb
index 43abb80..c055de6 100644
--- a/gcc/ada/libgnat/a-stzhas.adb
+++ b/gcc/ada/libgnat/a-stzhas.adb
@@ -29,8 +29,14 @@
-- --
------------------------------------------------------------------------------
--- This package does not require a body, since it is an instantiation. We
--- provide a dummy file containing a No_Body pragma so that previous versions
--- of the body (which did exist) will not interfere.
+with System.String_Hash;
-pragma No_Body;
+function Ada.Strings.Wide_Wide_Hash
+ (Key : Wide_Wide_String) return Containers.Hash_Type
+is
+ use Ada.Containers;
+ function Hash_Fun is new System.String_Hash.Hash
+ (Wide_Wide_Character, Wide_Wide_String, Hash_Type);
+begin
+ return Hash_Fun (Key);
+end Ada.Strings.Wide_Wide_Hash;
diff --git a/gcc/ada/libgnat/a-stzhas.ads b/gcc/ada/libgnat/a-stzhas.ads
index 0c87672..dea0ff1 100644
--- a/gcc/ada/libgnat/a-stzhas.ads
+++ b/gcc/ada/libgnat/a-stzhas.ads
@@ -13,13 +13,9 @@
-- --
------------------------------------------------------------------------------
--- Is this really an RM unit? Doc needed???
-
with Ada.Containers;
-with System.String_Hash;
function Ada.Strings.Wide_Wide_Hash
-is new System.String_Hash.Hash
- (Wide_Wide_Character, Wide_Wide_String, Containers.Hash_Type);
+ (Key : Wide_Wide_String) return Containers.Hash_Type;
pragma Pure (Ada.Strings.Wide_Wide_Hash);
diff --git a/gcc/ada/libgnat/a-tideau.adb b/gcc/ada/libgnat/a-tideau.adb
index caf77e3..5878234 100644
--- a/gcc/ada/libgnat/a-tideau.adb
+++ b/gcc/ada/libgnat/a-tideau.adb
@@ -32,26 +32,21 @@
with Ada.Text_IO.Generic_Aux; use Ada.Text_IO.Generic_Aux;
with Ada.Text_IO.Float_Aux; use Ada.Text_IO.Float_Aux;
-with System.Img_Dec; use System.Img_Dec;
-with System.Img_LLD; use System.Img_LLD;
-with System.Val_Dec; use System.Val_Dec;
-with System.Val_LLD; use System.Val_LLD;
-
package body Ada.Text_IO.Decimal_Aux is
- -------------
- -- Get_Dec --
- -------------
+ ---------
+ -- Get --
+ ---------
- function Get_Dec
+ function Get
(File : File_Type;
Width : Field;
- Scale : Integer) return Integer
+ Scale : Integer) return Int
is
Buf : String (1 .. Field'Last);
Ptr : aliased Integer;
Stop : Integer := 0;
- Item : Integer;
+ Item : Int;
begin
if Width /= 0 then
@@ -62,114 +57,42 @@ package body Ada.Text_IO.Decimal_Aux is
Ptr := 1;
end if;
- Item := Scan_Decimal (Buf, Ptr'Access, Stop, Scale);
+ Item := Scan (Buf, Ptr'Access, Stop, Scale);
Check_End_Of_Field (Buf, Stop, Ptr, Width);
return Item;
- end Get_Dec;
-
- -------------
- -- Get_LLD --
- -------------
-
- function Get_LLD
- (File : File_Type;
- Width : Field;
- Scale : Integer) return Long_Long_Integer
- is
- Buf : String (1 .. Field'Last);
- Ptr : aliased Integer;
- Stop : Integer := 0;
- Item : Long_Long_Integer;
+ end Get;
- begin
- if Width /= 0 then
- Load_Width (File, Width, Buf, Stop);
- String_Skip (Buf, Ptr);
- else
- Load_Real (File, Buf, Stop);
- Ptr := 1;
- end if;
+ ----------
+ -- Gets --
+ ----------
- Item := Scan_Long_Long_Decimal (Buf, Ptr'Access, Stop, Scale);
- Check_End_Of_Field (Buf, Stop, Ptr, Width);
- return Item;
- end Get_LLD;
-
- --------------
- -- Gets_Dec --
- --------------
-
- function Gets_Dec
+ function Gets
(From : String;
- Last : not null access Positive;
- Scale : Integer) return Integer
+ Last : out Positive;
+ Scale : Integer) return Int
is
Pos : aliased Integer;
- Item : Integer;
+ Item : Int;
begin
String_Skip (From, Pos);
- Item := Scan_Decimal (From, Pos'Access, From'Last, Scale);
- Last.all := Pos - 1;
+ Item := Scan (From, Pos'Access, From'Last, Scale);
+ Last := Pos - 1;
return Item;
exception
when Constraint_Error =>
- Last.all := Pos - 1;
+ Last := Pos - 1;
raise Data_Error;
- end Gets_Dec;
-
- --------------
- -- Gets_LLD --
- --------------
-
- function Gets_LLD
- (From : String;
- Last : not null access Positive;
- Scale : Integer) return Long_Long_Integer
- is
- Pos : aliased Integer;
- Item : Long_Long_Integer;
-
- begin
- String_Skip (From, Pos);
- Item := Scan_Long_Long_Decimal (From, Pos'Access, From'Last, Scale);
- Last.all := Pos - 1;
- return Item;
-
- exception
- when Constraint_Error =>
- Last.all := Pos - 1;
- raise Data_Error;
- end Gets_LLD;
-
- -------------
- -- Put_Dec --
- -------------
+ end Gets;
- procedure Put_Dec
- (File : File_Type;
- Item : Integer;
- Fore : Field;
- Aft : Field;
- Exp : Field;
- Scale : Integer)
- is
- Buf : String (1 .. Field'Last);
- Ptr : Natural := 0;
-
- begin
- Set_Image_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
- Put_Item (File, Buf (1 .. Ptr));
- end Put_Dec;
-
- -------------
- -- Put_LLD --
- -------------
+ ---------
+ -- Put --
+ ---------
- procedure Put_LLD
+ procedure Put
(File : File_Type;
- Item : Long_Long_Integer;
+ Item : Int;
Fore : Field;
Aft : Field;
Exp : Field;
@@ -179,83 +102,51 @@ package body Ada.Text_IO.Decimal_Aux is
Ptr : Natural := 0;
begin
- Set_Image_Long_Long_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
+ Set_Image (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
Put_Item (File, Buf (1 .. Ptr));
- end Put_LLD;
+ end Put;
- --------------
- -- Puts_Dec --
- --------------
+ ----------
+ -- Puts --
+ ----------
- procedure Puts_Dec
+ procedure Puts
(To : out String;
- Item : Integer;
+ Item : Int;
Aft : Field;
Exp : Field;
Scale : Integer)
is
- Buf : String (1 .. Field'Last);
+ Buf : String (1 .. Positive'Max (Field'Last, To'Length));
Fore : Integer;
Ptr : Natural := 0;
begin
- -- Compute Fore, allowing for Aft digits and the decimal dot
+ -- Compute Fore, allowing for the decimal dot and Aft digits
- Fore := To'Length - Field'Max (1, Aft) - 1;
+ Fore := To'Length - 1 - Field'Max (1, Aft);
- -- Allow for Exp and two more for E+ or E- if exponent present
+ -- Allow for Exp and one more for E if exponent present
if Exp /= 0 then
- Fore := Fore - 2 - Exp;
+ Fore := Fore - 1 - Field'Max (2, Exp);
end if;
-- Make sure we have enough room
- if Fore < 1 then
+ if Fore < 1 + Boolean'Pos (Item < 0) then
raise Layout_Error;
end if;
-- Do the conversion and check length of result
- Set_Image_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
-
- if Ptr > To'Length then
- raise Layout_Error;
- else
- To := Buf (1 .. Ptr);
- end if;
- end Puts_Dec;
-
- --------------
- -- Puts_LLD --
- --------------
-
- procedure Puts_LLD
- (To : out String;
- Item : Long_Long_Integer;
- Aft : Field;
- Exp : Field;
- Scale : Integer)
- is
- Buf : String (1 .. Field'Last);
- Fore : Integer;
- Ptr : Natural := 0;
-
- begin
- Fore :=
- (if Exp = 0 then To'Length - 1 - Aft else To'Length - 2 - Aft - Exp);
-
- if Fore < 1 then
- raise Layout_Error;
- end if;
-
- Set_Image_Long_Long_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
+ Set_Image (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
if Ptr > To'Length then
raise Layout_Error;
else
To := Buf (1 .. Ptr);
end if;
- end Puts_LLD;
+ end Puts;
end Ada.Text_IO.Decimal_Aux;
diff --git a/gcc/ada/libgnat/a-tideau.ads b/gcc/ada/libgnat/a-tideau.ads
index e7d7f44..522e351 100644
--- a/gcc/ada/libgnat/a-tideau.ads
+++ b/gcc/ada/libgnat/a-tideau.ads
@@ -29,62 +29,54 @@
-- --
------------------------------------------------------------------------------
--- This package contains the routines for Ada.Text_IO.Decimal_IO that are
--- shared among separate instantiations of this package. The routines in
--- the package are identical semantically to those declared in Text_IO,
--- except that default values have been supplied by the generic, and the
--- Num parameter has been replaced by Integer or Long_Long_Integer, with
--- an additional Scale parameter giving the value of Num'Scale. In addition
--- the Get routines return the value rather than store it in an Out parameter.
+-- This package contains the implementation for Ada.Text_IO.Decimal_IO. The
+-- routines in this package are identical semantically to those in Decimal_IO,
+-- except that the default parameters have been removed because they are
+-- supplied explicitly by the calls from within these units, and there is an
+-- additional Scale parameter giving the value of Num'Scale. In addition the
+-- Get routines return the value rather than store it in an Out parameter.
-private package Ada.Text_IO.Decimal_Aux is
+private generic
+ type Int is range <>;
- function Get_Dec
- (File : File_Type;
- Width : Field;
- Scale : Integer) return Integer;
+ with function Scan
+ (Str : String;
+ Ptr : not null access Integer;
+ Max : Integer;
+ Scale : Integer) return Int;
- function Get_LLD
- (File : File_Type;
- Width : Field;
- Scale : Integer) return Long_Long_Integer;
+ with procedure Set_Image
+ (V : Int;
+ S : in out String;
+ P : in out Natural;
+ Scale : Integer;
+ Fore : Natural;
+ Aft : Natural;
+ Exp : Natural);
+
+package Ada.Text_IO.Decimal_Aux is
- procedure Put_Dec
+ function Get
(File : File_Type;
- Item : Integer;
- Fore : Field;
- Aft : Field;
- Exp : Field;
- Scale : Integer);
+ Width : Field;
+ Scale : Integer) return Int;
- procedure Put_LLD
+ procedure Put
(File : File_Type;
- Item : Long_Long_Integer;
+ Item : Int;
Fore : Field;
Aft : Field;
Exp : Field;
Scale : Integer);
- function Gets_Dec
- (From : String;
- Last : not null access Positive;
- Scale : Integer) return Integer;
-
- function Gets_LLD
+ function Gets
(From : String;
- Last : not null access Positive;
- Scale : Integer) return Long_Long_Integer;
-
- procedure Puts_Dec
- (To : out String;
- Item : Integer;
- Aft : Field;
- Exp : Field;
- Scale : Integer);
+ Last : out Positive;
+ Scale : Integer) return Int;
- procedure Puts_LLD
+ procedure Puts
(To : out String;
- Item : Long_Long_Integer;
+ Item : Int;
Aft : Field;
Exp : Field;
Scale : Integer);
diff --git a/gcc/ada/libgnat/a-tideio.adb b/gcc/ada/libgnat/a-tideio.adb
index 0624c2c..f71cf2d 100644
--- a/gcc/ada/libgnat/a-tideio.adb
+++ b/gcc/ada/libgnat/a-tideio.adb
@@ -29,11 +29,35 @@
-- --
------------------------------------------------------------------------------
+with Interfaces;
with Ada.Text_IO.Decimal_Aux;
+with System.Img_Decimal_32; use System.Img_Decimal_32;
+with System.Img_Decimal_64; use System.Img_Decimal_64;
+with System.Val_Decimal_32; use System.Val_Decimal_32;
+with System.Val_Decimal_64; use System.Val_Decimal_64;
package body Ada.Text_IO.Decimal_IO is
- package Aux renames Ada.Text_IO.Decimal_Aux;
+ subtype Int32 is Interfaces.Integer_32;
+ subtype Int64 is Interfaces.Integer_64;
+
+ package Aux32 is new
+ Ada.Text_IO.Decimal_Aux
+ (Int32,
+ Scan_Decimal32,
+ Set_Image_Decimal32);
+
+ package Aux64 is new
+ Ada.Text_IO.Decimal_Aux
+ (Int64,
+ Scan_Decimal64,
+ Set_Image_Decimal64);
+
+ Need64 : constant Boolean := Num'Size > 32;
+ -- Throughout this generic body, we distinguish between the case where type
+ -- Int32 is acceptable and where type Int64 is needed. This Boolean is used
+ -- to test for these cases and since it is a constant, only code for the
+ -- relevant case will be included in the instance.
Scale : constant Integer := Num'Scale;
@@ -49,10 +73,10 @@ package body Ada.Text_IO.Decimal_IO is
pragma Unsuppress (Range_Check);
begin
- if Num'Size > Integer'Size then
- Item := Num'Fixed_Value (Aux.Get_LLD (File, Width, Scale));
+ if Need64 then
+ Item := Num'Fixed_Value (Aux64.Get (File, Width, Scale));
else
- Item := Num'Fixed_Value (Aux.Get_Dec (File, Width, Scale));
+ Item := Num'Fixed_Value (Aux32.Get (File, Width, Scale));
end if;
exception
@@ -75,12 +99,10 @@ package body Ada.Text_IO.Decimal_IO is
pragma Unsuppress (Range_Check);
begin
- if Num'Size > Integer'Size then
- Item := Num'Fixed_Value
- (Aux.Gets_LLD (From, Last'Unrestricted_Access, Scale));
+ if Need64 then
+ Item := Num'Fixed_Value (Aux64.Gets (From, Last, Scale));
else
- Item := Num'Fixed_Value
- (Aux.Gets_Dec (From, Last'Unrestricted_Access, Scale));
+ Item := Num'Fixed_Value (Aux32.Gets (From, Last, Scale));
end if;
exception
@@ -99,13 +121,12 @@ package body Ada.Text_IO.Decimal_IO is
Exp : Field := Default_Exp)
is
begin
- if Num'Size > Integer'Size then
- Aux.Put_LLD
- (File, Long_Long_Integer'Integer_Value (Item),
- Fore, Aft, Exp, Scale);
+ if Need64 then
+ Aux64.Put
+ (File, Int64'Integer_Value (Item), Fore, Aft, Exp, Scale);
else
- Aux.Put_Dec
- (File, Integer'Integer_Value (Item), Fore, Aft, Exp, Scale);
+ Aux32.Put
+ (File, Int32'Integer_Value (Item), Fore, Aft, Exp, Scale);
end if;
end Put;
@@ -126,11 +147,10 @@ package body Ada.Text_IO.Decimal_IO is
Exp : Field := Default_Exp)
is
begin
- if Num'Size > Integer'Size then
- Aux.Puts_LLD
- (To, Long_Long_Integer'Integer_Value (Item), Aft, Exp, Scale);
+ if Need64 then
+ Aux64.Puts (To, Int64'Integer_Value (Item), Aft, Exp, Scale);
else
- Aux.Puts_Dec (To, Integer'Integer_Value (Item), Aft, Exp, Scale);
+ Aux32.Puts (To, Int32'Integer_Value (Item), Aft, Exp, Scale);
end if;
end Put;
diff --git a/gcc/ada/libgnat/a-tideio__128.adb b/gcc/ada/libgnat/a-tideio__128.adb
new file mode 100644
index 0000000..a8cdf9f
--- /dev/null
+++ b/gcc/ada/libgnat/a-tideio__128.adb
@@ -0,0 +1,177 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . T E X T _ I O . D E C I M A L _ I O --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Interfaces;
+with Ada.Text_IO.Decimal_Aux;
+with System.Img_Decimal_32; use System.Img_Decimal_32;
+with System.Img_Decimal_64; use System.Img_Decimal_64;
+with System.Img_Decimal_128; use System.Img_Decimal_128;
+with System.Val_Decimal_32; use System.Val_Decimal_32;
+with System.Val_Decimal_64; use System.Val_Decimal_64;
+with System.Val_Decimal_128; use System.Val_Decimal_128;
+
+package body Ada.Text_IO.Decimal_IO is
+
+ subtype Int32 is Interfaces.Integer_32;
+ subtype Int64 is Interfaces.Integer_64;
+ subtype Int128 is Interfaces.Integer_128;
+
+ package Aux32 is new
+ Ada.Text_IO.Decimal_Aux
+ (Int32,
+ Scan_Decimal32,
+ Set_Image_Decimal32);
+
+ package Aux64 is new
+ Ada.Text_IO.Decimal_Aux
+ (Int64,
+ Scan_Decimal64,
+ Set_Image_Decimal64);
+
+ package Aux128 is new
+ Ada.Text_IO.Decimal_Aux
+ (Int128,
+ Scan_Decimal128,
+ Set_Image_Decimal128);
+
+ Need64 : constant Boolean := Num'Size > 32;
+ Need128 : constant Boolean := Num'Size > 64;
+ -- Throughout this generic body, we distinguish between the case where type
+ -- Int32 is acceptable, where type Int64 is acceptable and where an Int128
+ -- is needed. These boolean constants are used to test for these cases and
+ -- since it is a constant, only code for the relevant case will be included
+ -- in the instance.
+
+ Scale : constant Integer := Num'Scale;
+
+ ---------
+ -- Get --
+ ---------
+
+ procedure Get
+ (File : File_Type;
+ Item : out Num;
+ Width : Field := 0)
+ is
+ pragma Unsuppress (Range_Check);
+
+ begin
+ if Need128 then
+ Item := Num'Fixed_Value (Aux128.Get (File, Width, Scale));
+ elsif Need64 then
+ Item := Num'Fixed_Value (Aux64.Get (File, Width, Scale));
+ else
+ Item := Num'Fixed_Value (Aux32.Get (File, Width, Scale));
+ end if;
+
+ exception
+ when Constraint_Error => raise Data_Error;
+ end Get;
+
+ procedure Get
+ (Item : out Num;
+ Width : Field := 0)
+ is
+ begin
+ Get (Current_In, Item, Width);
+ end Get;
+
+ procedure Get
+ (From : String;
+ Item : out Num;
+ Last : out Positive)
+ is
+ pragma Unsuppress (Range_Check);
+
+ begin
+ if Need128 then
+ Item := Num'Fixed_Value (Aux128.Gets (From, Last, Scale));
+ elsif Need64 then
+ Item := Num'Fixed_Value (Aux64.Gets (From, Last, Scale));
+ else
+ Item := Num'Fixed_Value (Aux32.Gets (From, Last, Scale));
+ end if;
+
+ exception
+ when Constraint_Error => raise Data_Error;
+ end Get;
+
+ ---------
+ -- Put --
+ ---------
+
+ procedure Put
+ (File : File_Type;
+ Item : Num;
+ Fore : Field := Default_Fore;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ begin
+ if Need128 then
+ Aux128.Put
+ (File, Int128'Integer_Value (Item), Fore, Aft, Exp, Scale);
+ elsif Need64 then
+ Aux64.Put
+ (File, Int64'Integer_Value (Item), Fore, Aft, Exp, Scale);
+ else
+ Aux32.Put
+ (File, Int32'Integer_Value (Item), Fore, Aft, Exp, Scale);
+ end if;
+ end Put;
+
+ procedure Put
+ (Item : Num;
+ Fore : Field := Default_Fore;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ begin
+ Put (Current_Out, Item, Fore, Aft, Exp);
+ end Put;
+
+ procedure Put
+ (To : out String;
+ Item : Num;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ begin
+ if Need128 then
+ Aux128.Puts (To, Int128'Integer_Value (Item), Aft, Exp, Scale);
+ elsif Need64 then
+ Aux64.Puts (To, Int64'Integer_Value (Item), Aft, Exp, Scale);
+ else
+ Aux32.Puts (To, Int32'Integer_Value (Item), Aft, Exp, Scale);
+ end if;
+ end Put;
+
+end Ada.Text_IO.Decimal_IO;
diff --git a/gcc/ada/libgnat/a-tifiau.adb b/gcc/ada/libgnat/a-tifiau.adb
new file mode 100644
index 0000000..9259552
--- /dev/null
+++ b/gcc/ada/libgnat/a-tifiau.adb
@@ -0,0 +1,160 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . T E X T _ I O . F I X E D _ A U X --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Ada.Text_IO.Generic_Aux; use Ada.Text_IO.Generic_Aux;
+with Ada.Text_IO.Float_Aux; use Ada.Text_IO.Float_Aux;
+
+package body Ada.Text_IO.Fixed_Aux is
+
+ ---------
+ -- Get --
+ ---------
+
+ function Get
+ (File : File_Type;
+ Width : Field;
+ Num : Int;
+ Den : Int) return Int
+ is
+ Buf : String (1 .. Field'Last);
+ Ptr : aliased Integer;
+ Stop : Integer := 0;
+ Item : Int;
+
+ begin
+ if Width /= 0 then
+ Load_Width (File, Width, Buf, Stop);
+ String_Skip (Buf, Ptr);
+ else
+ Load_Real (File, Buf, Stop);
+ Ptr := 1;
+ end if;
+
+ Item := Scan (Buf, Ptr'Access, Stop, Num, Den);
+ Check_End_Of_Field (Buf, Stop, Ptr, Width);
+ return Item;
+ end Get;
+
+ ----------
+ -- Gets --
+ ----------
+
+ function Gets
+ (From : String;
+ Last : out Positive;
+ Num : Int;
+ Den : Int) return Int
+ is
+ Pos : aliased Integer;
+ Item : Int;
+
+ begin
+ String_Skip (From, Pos);
+ Item := Scan (From, Pos'Access, From'Last, Num, Den);
+ Last := Pos - 1;
+ return Item;
+
+ exception
+ when Constraint_Error =>
+ Last := Pos - 1;
+ raise Data_Error;
+ end Gets;
+
+ ---------
+ -- Put --
+ ---------
+
+ procedure Put
+ (File : File_Type;
+ Item : Int;
+ Fore : Field;
+ Aft : Field;
+ Exp : Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural)
+ is
+ Buf : String (1 .. Field'Last);
+ Ptr : Natural := 0;
+
+ begin
+ Set_Image (Item, Buf, Ptr, Num, Den, For0, Aft0, Fore, Aft, Exp);
+ Put_Item (File, Buf (1 .. Ptr));
+ end Put;
+
+ ----------
+ -- Puts --
+ ----------
+
+ procedure Puts
+ (To : out String;
+ Item : Int;
+ Aft : Field;
+ Exp : Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural)
+ is
+ Buf : String (1 .. Positive'Max (Field'Last, To'Length));
+ Fore : Integer;
+ Ptr : Natural := 0;
+
+ begin
+ -- Compute Fore, allowing for the decimal dot and Aft digits
+
+ Fore := To'Length - 1 - Field'Max (1, Aft);
+
+ -- Allow for Exp and one more for E if exponent present
+
+ if Exp /= 0 then
+ Fore := Fore - 1 - Field'Max (2, Exp);
+ end if;
+
+ -- Make sure we have enough room
+
+ if Fore < 1 + Boolean'Pos (Item < 0) then
+ raise Layout_Error;
+ end if;
+
+ -- Do the conversion and check length of result
+
+ Set_Image (Item, Buf, Ptr, Num, Den, For0, Aft0, Fore, Aft, Exp);
+
+ if Ptr > To'Length then
+ raise Layout_Error;
+ else
+ To := Buf (1 .. Ptr);
+ end if;
+ end Puts;
+
+end Ada.Text_IO.Fixed_Aux;
diff --git a/gcc/ada/libgnat/a-tifiau.ads b/gcc/ada/libgnat/a-tifiau.ads
new file mode 100644
index 0000000..32701c5
--- /dev/null
+++ b/gcc/ada/libgnat/a-tifiau.ads
@@ -0,0 +1,97 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . T E X T _ I O . F I X E D _ A U X --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the implementation for Ada.Text_IO.Fixed_IO. The
+-- routines in this package are identical semantically to those in Fixed_IO,
+-- except that the default parameters have been removed because they are
+-- supplied explicitly by the calls from within these units, and there are
+-- additional Num and Den parameters giving the value of Num'Small, as well
+-- as For0 and Aft0 giving some properties of Num'Small. In addition the Get
+-- routines return the value rather than store it in an Out parameter.
+
+private generic
+ type Int is range <>;
+
+ with function Scan
+ (Str : String;
+ Ptr : not null access Integer;
+ Max : Integer;
+ Num : Int;
+ Den : Int) return Int;
+
+ with procedure Set_Image
+ (V : Int;
+ S : in out String;
+ P : in out Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural;
+ Fore : Natural;
+ Aft : Natural;
+ Exp : Natural);
+
+package Ada.Text_IO.Fixed_Aux is
+
+ function Get
+ (File : File_Type;
+ Width : Field;
+ Num : Int;
+ Den : Int) return Int;
+
+ procedure Put
+ (File : File_Type;
+ Item : Int;
+ Fore : Field;
+ Aft : Field;
+ Exp : Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural);
+
+ function Gets
+ (From : String;
+ Last : out Positive;
+ Num : Int;
+ Den : Int) return Int;
+
+ procedure Puts
+ (To : out String;
+ Item : Int;
+ Aft : Field;
+ Exp : Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural);
+
+end Ada.Text_IO.Fixed_Aux;
diff --git a/gcc/ada/libgnat/a-tifiio.adb b/gcc/ada/libgnat/a-tifiio.adb
index 2d0b47c..93862be 100644
--- a/gcc/ada/libgnat/a-tifiio.adb
+++ b/gcc/ada/libgnat/a-tifiio.adb
@@ -140,168 +140,108 @@
-- solution. The downside however may be a too limited set of acceptable
-- fixed point types.
-with Interfaces; use Interfaces;
-with System.Arith_64; use System.Arith_64;
-with System.Img_Real; use System.Img_Real;
-with Ada.Text_IO; use Ada.Text_IO;
+with Interfaces;
+with Ada.Text_IO.Fixed_Aux;
with Ada.Text_IO.Float_Aux;
-with Ada.Text_IO.Generic_Aux;
+with System.Img_Fixed_32; use System.Img_Fixed_32;
+with System.Img_Fixed_64; use System.Img_Fixed_64;
+with System.Val_Fixed_32; use System.Val_Fixed_32;
+with System.Val_Fixed_64; use System.Val_Fixed_64;
package body Ada.Text_IO.Fixed_IO is
- -- Note: we still use the floating-point I/O routines for input of
- -- ordinary fixed-point and output using exponent format. This will
- -- result in inaccuracies for fixed point types with a small that is
- -- not a power of two, and for types that require more precision than
- -- is available in Long_Long_Float.
-
- package Aux renames Ada.Text_IO.Float_Aux;
-
- Extra_Layout_Space : constant Field := 5 + Num'Fore;
- -- Extra space that may be needed for output of sign, decimal point,
- -- exponent indication and mandatory decimals after and before the
- -- decimal point. A string with length
-
- -- Fore + Aft + Exp + Extra_Layout_Space
-
- -- is always long enough for formatting any fixed point number.
-
- -- Implementation of Put routines
-
- -- The following section describes a specific implementation choice for
- -- performing base conversions needed for output of values of a fixed
- -- point type T with small T'Small. The goal is to be able to output
- -- all values of types with a precision of 64 bits and a delta of at
- -- least 2.0**(-63), as these are current GNAT limitations already.
-
- -- The chosen algorithm uses fixed precision integer arithmetic for
- -- reasons of simplicity and efficiency. It is important to understand
- -- in what ways the most simple and accurate approach to fixed point I/O
- -- is limiting, before considering more complicated schemes.
-
- -- Without loss of generality assume T has a range (-2.0**63) * T'Small
- -- .. (2.0**63 - 1) * T'Small, and is output with Aft digits after the
- -- decimal point and T'Fore - 1 before. If T'Small is integer, or
- -- 1.0 / T'Small is integer, let S = T'Small and E = 0. For other T'Small,
- -- let S and E be integers such that S / 10**E best approximates T'Small
- -- and S is in the range 10**17 .. 10**18 - 1. The extra decimal scaling
- -- factor 10**E can be trivially handled during final output, by adjusting
- -- the decimal point or exponent.
-
- -- The idea is to convert a value X * S of type T to a 64-bit integer value
- -- Q equal to 10.0**D * (X * S) rounded to the nearest integer, using only
- -- a scaled integer divide of the form
-
- -- Q := (X * Y) / Z,
-
- -- where the variables X, Y, Z are 64-bit integers, and both multiplication
- -- and division are done using full intermediate precision. Then the final
- -- decimal value to be output is
-
- -- Q * 10**(E-D)
-
- -- This value can be written to the output file or to the result string
- -- according to the format described in RM A.3.10. The details of this
- -- operation are omitted here.
-
- -- A 64-bit value can represent all integers with 18 decimal digits, but
- -- not all with 19 decimal digits. If the total number of requested ouput
- -- digits (Fore - 1) + Aft is greater than 18 then, for purposes of the
- -- conversion, Aft is adjusted to 18 - (Fore - 1). In that case, trailing
- -- zeros can complete the output after writing the first 18 significant
- -- digits, or the technique described in the next section can be used.
-
- -- The final expression for D is
-
- -- D := Integer'Max (-18, Integer'Min (Aft, 18 - (Fore - 1)));
-
- -- For Y and Z the following expressions can be derived:
-
- -- Q = X * S * (10.0**D) = (X * Y) / Z
-
- -- S * 10.0**D = Y / Z;
-
- -- If S is an integer greater than or equal to one, then Fore must be at
- -- least 20 in order to print T'First, which is at most -2.0**63. This
- -- means that D < 0, so use
-
- -- (1) Y = -S and Z = -10**(-D)
-
- -- If 1.0 / S is an integer greater than one, use
-
- -- (2) Y = -10**D and Z = -(1.0 / S), for D >= 0
-
- -- or
-
- -- (3) Y = -1 and Z = -(1.0 / S) * 10**(-D), for D < 0
-
- -- Negative values are used for nominator Y and denominator Z, so that S
- -- can have a maximum value of 2.0**63 and a minimum of 2.0**(-63).
- -- For Z in -1 .. -9, Fore will still be 20, and D will be negative, as
- -- (-2.0**63) / -9 is greater than 10**18. In these cases there is room
- -- in the denominator for the extra decimal scaling required, so case (3)
- -- will not overflow.
-
- -- Extra Precision
-
- -- Using a scaled divide which truncates and returns a remainder R,
- -- another K trailing digits can be calculated by computing the value
- -- (R * (10.0**K)) / Z using another scaled divide. This procedure
- -- can be repeated to compute an arbitrary number of digits in linear
- -- time and storage. The last scaled divide should be rounded, with
- -- a possible carry propagating to the more significant digits, to
- -- ensure correct rounding of the unit in the last place.
-
- -- A variant of this technique is to limit the value of Q to 9 decimal
- -- digits, since 32-bit integers can be much more efficient than 64-bit
- -- integers to output.
-
- pragma Assert (System.Fine_Delta >= 2.0**(-63));
- pragma Assert (Num'Small in 2.0**(-80) .. 2.0**80);
- pragma Assert (Num'Fore <= 37);
-
- Max_Digits : constant := 18;
- -- Maximum number of decimal digits that can be represented in a
- -- 64-bit signed number, see above
-
- -- The constants E0 .. E5 implement a binary search for the appropriate
- -- power of ten to scale the small so that it has one digit before the
- -- decimal point.
-
- subtype Int is Integer;
- E0 : constant Int := -(25 * Boolean'Pos (Num'Small >= 1.0E1));
- E1 : constant Int := E0 + 13 * Boolean'Pos (Num'Small * 10.0**E0 < 1.0E-13);
- E2 : constant Int := E1 + 6 * Boolean'Pos (Num'Small * 10.0**E1 < 1.0E-6);
- E3 : constant Int := E2 + 3 * Boolean'Pos (Num'Small * 10.0**E2 < 1.0E-3);
- E4 : constant Int := E3 + 2 * Boolean'Pos (Num'Small * 10.0**E3 < 1.0E-1);
- E5 : constant Int := E4 + 1 * Boolean'Pos (Num'Small * 10.0**E4 < 1.0E-0);
-
- Scale : constant Integer := E5;
-
- pragma Assert (Num'Small * 10.0**Scale >= 1.0
- and then Num'Small * 10.0**Scale < 10.0);
-
- Exact : constant Boolean :=
- (Float'Floor (Num'Small) = Float'Ceiling (Num'Small)
- or else Float'Floor (1.0 / Num'Small) = Float'Ceiling (1.0 / Num'Small)
- or else Num'Small >= 10.0**Max_Digits)
- and then Num'Small >= 2.0**(-63)
- and then Num'Small <= 2.0**63;
- -- True iff a 64-bit numerator and denominator can be calculated such that
- -- their ratio exactly represents the small of Num.
-
- procedure Put
- (To : out String;
- Last : out Natural;
- Item : Num;
- Fore : Integer;
- Aft : Field;
- Exp : Field);
- -- Actual output function, used internally by all other Put routines.
- -- The formal Fore is an Integer, not a Field, because the routine is
- -- also called from the version of Put that performs I/O to a string,
- -- where the starting position depends on the size of the String, and
- -- bears no relation to the bounds of Field.
+ -- Note: we still use the floating-point I/O routines for types whose small
+ -- is not the ratio of two sufficiently small integers. This will result in
+ -- inaccuracies for fixed point types that require more precision than is
+ -- available in Long_Long_Float.
+
+ subtype Int32 is Interfaces.Integer_32; use type Int32;
+ subtype Int64 is Interfaces.Integer_64; use type Int64;
+
+ package Aux32 is new
+ Ada.Text_IO.Fixed_Aux (Int32, Scan_Fixed32, Set_Image_Fixed32);
+
+ package Aux64 is new
+ Ada.Text_IO.Fixed_Aux (Int64, Scan_Fixed64, Set_Image_Fixed64);
+
+ -- Throughout this generic body, we distinguish between the case where type
+ -- Int32 is OK and where type Int64 is OK. These boolean constants are used
+ -- to test for this, such that only code for the relevant case is included
+ -- in the instance; that's why the computation of their value must be fully
+ -- static (although it is not a static expressions in the RM sense).
+
+ OK_Get_32 : constant Boolean :=
+ Num'Object_Size <= 32
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**31)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**31)
+ or else
+ (Num'Small_Numerator <= 2**27
+ and then Num'Small_Denominator <= 2**27));
+ -- These conditions are derived from the prerequisites of System.Value_F
+
+ OK_Put_32 : constant Boolean :=
+ Num'Object_Size <= 32
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**31)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**31)
+ or else
+ (Num'Small_Numerator < Num'Small_Denominator
+ and then Num'Small_Denominator <= 2**27)
+ or else
+ (Num'Small_Denominator < Num'Small_Numerator
+ and then Num'Small_Numerator <= 2**25));
+ -- These conditions are derived from the prerequisites of System.Image_F
+
+ OK_Get_64 : constant Boolean :=
+ Num'Object_Size <= 64
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**63)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**63)
+ or else
+ (Num'Small_Numerator <= 2**59
+ and then Num'Small_Denominator <= 2**59));
+ -- These conditions are derived from the prerequisites of System.Value_F
+
+ OK_Put_64 : constant Boolean :=
+ Num'Object_Size <= 64
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**63)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**63)
+ or else
+ (Num'Small_Numerator < Num'Small_Denominator
+ and then Num'Small_Denominator <= 2**59)
+ or else
+ (Num'Small_Denominator < Num'Small_Numerator
+ and then Num'Small_Numerator <= 2**53));
+ -- These conditions are derived from the prerequisites of System.Image_F
+
+ E : constant Natural := 63 - 32 * Boolean'Pos (OK_Put_32);
+ -- T'Size - 1 for the selected Int{32,64}
+
+ F0 : constant Natural := 0;
+ F1 : constant Natural :=
+ F0 + 18 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F0) >= 1.0E+18);
+ F2 : constant Natural :=
+ F1 + 9 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F1) >= 1.0E+9);
+ F3 : constant Natural :=
+ F2 + 5 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F2) >= 1.0E+5);
+ F4 : constant Natural :=
+ F3 + 3 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F3) >= 1.0E+3);
+ F5 : constant Natural :=
+ F4 + 2 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F4) >= 1.0E+2);
+ F6 : constant Natural :=
+ F5 + 1 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F5) >= 1.0E+1);
+ -- Binary search for the number of digits - 1 before the decimal point of
+ -- the product 2.0**E * Num'Small.
+
+ For0 : constant Natural := 2 + F6;
+ -- Fore value for the fixed point type whose mantissa is Int{32,64} and
+ -- whose small is Num'Small.
---------
-- Get --
@@ -313,8 +253,22 @@ package body Ada.Text_IO.Fixed_IO is
Width : Field := 0)
is
pragma Unsuppress (Range_Check);
+
begin
- Aux.Get (File, Long_Long_Float (Item), Width);
+ if OK_Get_32 then
+ Item := Num'Fixed_Value
+ (Aux32.Get (File, Width,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ elsif OK_Get_64 then
+ Item := Num'Fixed_Value
+ (Aux64.Get (File, Width,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ else
+ Float_Aux.Get (File, Long_Long_Float (Item), Width);
+ end if;
+
exception
when Constraint_Error => raise Data_Error;
end Get;
@@ -323,11 +277,8 @@ package body Ada.Text_IO.Fixed_IO is
(Item : out Num;
Width : Field := 0)
is
- pragma Unsuppress (Range_Check);
begin
- Aux.Get (Current_In, Long_Long_Float (Item), Width);
- exception
- when Constraint_Error => raise Data_Error;
+ Get (Current_Input, Item, Width);
end Get;
procedure Get
@@ -336,8 +287,22 @@ package body Ada.Text_IO.Fixed_IO is
Last : out Positive)
is
pragma Unsuppress (Range_Check);
+
begin
- Aux.Gets (From, Long_Long_Float (Item), Last);
+ if OK_Get_32 then
+ Item := Num'Fixed_Value
+ (Aux32.Gets (From, Last,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ elsif OK_Get_64 then
+ Item := Num'Fixed_Value
+ (Aux64.Gets (From, Last,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ else
+ Float_Aux.Gets (From, Long_Long_Float (Item), Last);
+ end if;
+
exception
when Constraint_Error => raise Data_Error;
end Get;
@@ -353,11 +318,18 @@ package body Ada.Text_IO.Fixed_IO is
Aft : Field := Default_Aft;
Exp : Field := Default_Exp)
is
- S : String (1 .. Fore + Aft + Exp + Extra_Layout_Space);
- Last : Natural;
begin
- Put (S, Last, Item, Fore, Aft, Exp);
- Generic_Aux.Put_Item (File, S (1 .. Last));
+ if OK_Put_32 then
+ Aux32.Put (File, Int32'Integer_Value (Item), Fore, Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ elsif OK_Put_64 then
+ Aux64.Put (File, Int64'Integer_Value (Item), Fore, Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ else
+ Float_Aux.Put (File, Long_Long_Float (Item), Fore, Aft, Exp);
+ end if;
end Put;
procedure Put
@@ -366,11 +338,8 @@ package body Ada.Text_IO.Fixed_IO is
Aft : Field := Default_Aft;
Exp : Field := Default_Exp)
is
- S : String (1 .. Fore + Aft + Exp + Extra_Layout_Space);
- Last : Natural;
begin
- Put (S, Last, Item, Fore, Aft, Exp);
- Generic_Aux.Put_Item (Text_IO.Current_Out, S (1 .. Last));
+ Put (Current_Out, Item, Fore, Aft, Exp);
end Put;
procedure Put
@@ -379,332 +348,18 @@ package body Ada.Text_IO.Fixed_IO is
Aft : Field := Default_Aft;
Exp : Field := Default_Exp)
is
- Fore : constant Integer :=
- To'Length
- - 1 -- Decimal point
- - Field'Max (1, Aft) -- Decimal part
- - Boolean'Pos (Exp /= 0) -- Exponent indicator
- - Exp; -- Exponent
-
- Last : Natural;
-
- begin
- if Fore - Boolean'Pos (Item < 0.0) < 1 then
- raise Layout_Error;
- end if;
-
- Put (To, Last, Item, Fore, Aft, Exp);
-
- if Last /= To'Last then
- raise Layout_Error;
- end if;
- end Put;
-
- procedure Put
- (To : out String;
- Last : out Natural;
- Item : Num;
- Fore : Integer;
- Aft : Field;
- Exp : Field)
- is
- subtype Digit is Int64 range 0 .. 9;
-
- X : constant Int64 := Int64'Integer_Value (Item);
- A : constant Field := Field'Max (Aft, 1);
- Neg : constant Boolean := (Item < 0.0);
- Pos : Integer := 0; -- Next digit X has value X * 10.0**Pos;
-
- procedure Put_Character (C : Character);
- pragma Inline (Put_Character);
- -- Add C to the output string To, updating Last
-
- procedure Put_Digit (X : Digit);
- -- Add digit X to the output string (going from left to right), updating
- -- Last and Pos, and inserting the sign, leading zeros or a decimal
- -- point when necessary. After outputting the first digit, Pos must not
- -- be changed outside Put_Digit anymore.
-
- procedure Put_Int64 (X : Int64; Scale : Integer);
- -- Output the decimal number abs X * 10**Scale
-
- procedure Put_Scaled
- (X, Y, Z : Int64;
- A : Field;
- E : Integer);
- -- Output the decimal number (X * Y / Z) * 10**E, producing A digits
- -- after the decimal point and rounding the final digit. The value
- -- X * Y / Z is computed with full precision, but must be in the
- -- range of Int64.
-
- -------------------
- -- Put_Character --
- -------------------
-
- procedure Put_Character (C : Character) is
- begin
- Last := Last + 1;
-
- -- Never put a character outside of string To. Exception Layout_Error
- -- will be raised later if Last is greater than To'Last.
-
- if Last <= To'Last then
- To (Last) := C;
- end if;
- end Put_Character;
-
- ---------------
- -- Put_Digit --
- ---------------
-
- procedure Put_Digit (X : Digit) is
- Digs : constant array (Digit) of Character := "0123456789";
-
- begin
- if Last = To'First - 1 then
- if X /= 0 or else Pos <= 0 then
-
- -- Before outputting first digit, include leading space,
- -- possible minus sign and, if the first digit is fractional,
- -- decimal seperator and leading zeros.
-
- -- The Fore part has Pos + 1 + Boolean'Pos (Neg) characters,
- -- if Pos >= 0 and otherwise has a single zero digit plus minus
- -- sign if negative. Add leading space if necessary.
-
- for J in Integer'Max (0, Pos) + 2 + Boolean'Pos (Neg) .. Fore
- loop
- Put_Character (' ');
- end loop;
-
- -- Output minus sign, if number is negative
-
- if Neg then
- Put_Character ('-');
- end if;
-
- -- If starting with fractional digit, output leading zeros
-
- if Pos < 0 then
- Put_Character ('0');
- Put_Character ('.');
-
- for J in Pos .. -2 loop
- Put_Character ('0');
- end loop;
- end if;
-
- Put_Character (Digs (X));
- end if;
-
- else
- -- This is not the first digit to be output, so the only
- -- special handling is that for the decimal point
-
- if Pos = -1 then
- Put_Character ('.');
- end if;
-
- Put_Character (Digs (X));
- end if;
-
- Pos := Pos - 1;
- end Put_Digit;
-
- ---------------
- -- Put_Int64 --
- ---------------
-
- procedure Put_Int64 (X : Int64; Scale : Integer) is
- begin
- if X = 0 then
- return;
- end if;
-
- if X not in -9 .. 9 then
- Put_Int64 (X / 10, Scale + 1);
- end if;
-
- -- Use Put_Digit to advance Pos. This fixes a case where the second
- -- or later Scaled_Divide would omit leading zeroes, resulting in
- -- too few digits produced and a Layout_Error as result.
-
- while Pos > Scale loop
- Put_Digit (0);
- end loop;
-
- -- If and only if more than one digit is output before the decimal
- -- point, pos will be unequal to scale when outputting the first
- -- digit.
-
- pragma Assert (Pos = Scale or else Last = To'First - 1);
-
- Pos := Scale;
-
- Put_Digit (abs (X rem 10));
- end Put_Int64;
-
- ----------------
- -- Put_Scaled --
- ----------------
-
- procedure Put_Scaled
- (X, Y, Z : Int64;
- A : Field;
- E : Integer)
- is
- pragma Assert (E >= -Max_Digits);
- 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);
- -- Each element of Q has Max_Digits decimal digits, except the
- -- last, which has AA rem Max_Digits. Only Q (Q'First) may have an
- -- absolute value equal to or larger than 10**Max_Digits. Only the
- -- absolute value of the elements is significant, not the sign.
-
- XX : Int64 := X;
- YY : Int64 := Y;
-
- begin
- for J in Q'Range loop
- exit when XX = 0;
-
- if J > 0 then
- YY := 10**(Integer'Min (Max_Digits, AA - (J - 1) * Max_Digits));
- end if;
-
- Scaled_Divide64 (XX, YY, Z, Q (J), R => XX, Round => False);
- end loop;
-
- if -E > A then
- pragma Assert (N = 1);
-
- Discard_Extra_Digits : declare
- Factor : constant Int64 := 10**(-E - A);
-
- begin
- -- The scaling factors were such that the first division
- -- produced more digits than requested. So divide away extra
- -- digits and compute new remainder for later rounding.
-
- if abs (Q (0) rem Factor) >= Factor / 2 then
- Q (0) := abs (Q (0) / Factor) + 1;
- else
- Q (0) := Q (0) / Factor;
- end if;
-
- XX := 0;
- end Discard_Extra_Digits;
- end if;
-
- -- At this point XX is a remainder and we need to determine if the
- -- quotient in Q must be rounded away from zero.
-
- -- As XX is less than the divisor, it is safe to take its absolute
- -- without chance of overflow. The check to see if XX is at least
- -- half the absolute value of the divisor must be done carefully to
- -- avoid overflow or lose precision.
-
- XX := abs XX;
-
- if XX >= 2**62
- or else (Z < 0 and then (-XX) * 2 <= Z)
- or else (Z >= 0 and then XX * 2 >= Z)
- then
- -- OK, rounding is necessary. As the sign is not significant,
- -- take advantage of the fact that an extra negative value will
- -- always be available when propagating the carry.
-
- Q (Q'Last) := -abs Q (Q'Last) - 1;
-
- Propagate_Carry :
- for J in reverse 1 .. Q'Last loop
- if Q (J) = YY or else Q (J) = -YY then
- Q (J) := 0;
- Q (J - 1) := -abs Q (J - 1) - 1;
-
- else
- exit Propagate_Carry;
- end if;
- end loop Propagate_Carry;
- end if;
-
- for J in Q'First .. Q'Last - 1 loop
- Put_Int64 (Q (J), E - J * Max_Digits);
- end loop;
-
- Put_Int64 (Q (Q'Last), -A);
- end Put_Scaled;
-
- -- Start of processing for Put
-
begin
- Last := To'First - 1;
-
- if Exp /= 0 then
-
- -- With the Exp format, it is not known how many output digits to
- -- generate, as leading zeros must be ignored. Computing too many
- -- digits and then truncating the output will not give the closest
- -- output, it is necessary to round at the correct digit.
-
- -- The general approach is as follows: as long as no digits have
- -- been generated, compute the Aft next digits (without rounding).
- -- Once a non-zero digit is generated, determine the exact number
- -- of digits remaining and compute them with rounding.
-
- -- Since a large number of iterations might be necessary in case
- -- of Aft = 1, the following optimization would be desirable.
-
- -- Count the number Z of leading zero bits in the integer
- -- representation of X, and start with producing Aft + Z * 1000 /
- -- 3322 digits in the first scaled division.
-
- -- However, the floating-point routines are still used now ???
-
- System.Img_Real.Set_Image_Real (Long_Long_Float (Item), To, Last,
- Fore, Aft, Exp);
- return;
+ if OK_Put_32 then
+ Aux32.Puts (To, Int32'Integer_Value (Item), Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ elsif OK_Put_64 then
+ Aux64.Puts (To, Int64'Integer_Value (Item), Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ else
+ Float_Aux.Puts (To, Long_Long_Float (Item), Aft, Exp);
end if;
-
- if Exact then
- declare
- D : constant Integer := Integer'Min (A, Max_Digits
- - (Num'Fore - 1));
- Y : constant Int64 := Int64'Min (Int64 (-Num'Small), -1)
- * 10**Integer'Max (0, D);
- Z : constant Int64 := Int64'Min (Int64 (-(1.0 / Num'Small)), -1)
- * 10**Integer'Max (0, -D);
- begin
- Put_Scaled (X, Y, Z, A, -D);
- end;
-
- else -- not Exact
- declare
- E : constant Integer := Max_Digits - 1 + Scale;
- D : constant Integer := Scale - 1;
- Y : constant Int64 := Int64 (-Num'Small * 10.0**E);
- Z : constant Int64 := -10**Max_Digits;
- begin
- Put_Scaled (X, Y, Z, A, -D);
- end;
- end if;
-
- -- If only zero digits encountered, unit digit has not been output yet
-
- if Last < To'First then
- Pos := 0;
-
- elsif Last > To'Last then
- raise Layout_Error; -- Not enough room in the output variable
- end if;
-
- -- Always output digits up to the first one after the decimal point
-
- while Pos >= -A loop
- Put_Digit (0);
- end loop;
end Put;
end Ada.Text_IO.Fixed_IO;
diff --git a/gcc/ada/libgnat/a-tifiio__128.adb b/gcc/ada/libgnat/a-tifiio__128.adb
new file mode 100644
index 0000000..f2dffcf
--- /dev/null
+++ b/gcc/ada/libgnat/a-tifiio__128.adb
@@ -0,0 +1,418 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . T E X T _ I O . F I X E D _ I O --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- Fixed point I/O
+-- ---------------
+
+-- The following text documents implementation details of the fixed point
+-- input/output routines in the GNAT runtime. The first part describes the
+-- general properties of fixed point types as defined by the Ada standard,
+-- including the Information Systems Annex.
+
+-- Subsequently these are reduced to implementation constraints and the impact
+-- of these constraints on a few possible approaches to input/output is given.
+-- Based on this analysis, a specific implementation is selected for use in
+-- the GNAT runtime. Finally, the chosen algorithm is analyzed numerically in
+-- order to provide user-level documentation on limits for range and precision
+-- of fixed point types as well as accuracy of input/output conversions.
+
+-- -------------------------------------------
+-- - General Properties of Fixed Point Types -
+-- -------------------------------------------
+
+-- Operations on fixed point types, other than input/output, are not important
+-- for the purpose of this document. Only the set of values that a fixed point
+-- type can represent and the input/output operations are significant.
+
+-- Values
+-- ------
+
+-- The set of values of a fixed point type comprise the integral multiples of
+-- a number called the small of the type. The small can be either a power of
+-- two, a power of ten or (if the implementation allows) an arbitrary strictly
+-- positive real value.
+
+-- Implementations need to support ordinary fixed point types with a precision
+-- of at least 24 bits, and (in order to comply with the Information Systems
+-- Annex) decimal fixed point types with at least 18 digits. For the rest, no
+-- requirements exist for the minimal small and range that must be supported.
+
+-- Operations
+-- ----------
+
+-- 'Image and 'Wide_Image (see RM 3.5(34))
+
+-- These attributes return a decimal real literal best approximating
+-- the value (rounded away from zero if halfway between) with a
+-- single leading character that is either a minus sign or a space,
+-- one or more digits before the decimal point (with no redundant
+-- leading zeros), a decimal point, and N digits after the decimal
+-- point. For a subtype S, the value of N is S'Aft, the smallest
+-- positive integer such that (10**N)*S'Delta is greater or equal to
+-- one, see RM 3.5.10(5).
+
+-- For an arbitrary small, this means large number arithmetic needs
+-- to be performed.
+
+-- Put (see RM A.10.9(22-26))
+
+-- The requirements for Put add no extra constraints over the image
+-- attributes, although it would be nice to be able to output more
+-- than S'Aft digits after the decimal point for values of subtype S.
+
+-- 'Value and 'Wide_Value attribute (RM 3.5(40-55))
+
+-- Since the input can be given in any base in the range 2..16,
+-- accurate conversion to a fixed point number may require
+-- arbitrary precision arithmetic if there is no limit on the
+-- magnitude of the small of the fixed point type.
+
+-- Get (see RM A.10.9(12-21))
+
+-- The requirements for Get are identical to those of the Value
+-- attribute.
+
+-- ------------------------------
+-- - Implementation Constraints -
+-- ------------------------------
+
+-- The requirements listed above for the input/output operations lead to
+-- significant complexity, if no constraints are put on supported smalls.
+
+-- Implementation Strategies
+-- -------------------------
+
+-- * Floating point arithmetic
+-- * Arbitrary-precision integer arithmetic
+-- * Fixed-precision integer arithmetic
+
+-- Although it seems convenient to convert fixed point numbers to floating
+-- point and then print them, this leads to a number of restrictions.
+-- The first one is precision. The widest floating-point type generally
+-- available has 53 bits of mantissa. This means that Fine_Delta cannot
+-- be less than 2.0**(-53).
+
+-- In GNAT, Fine_Delta is 2.0**(-63), and Duration for example is a 64-bit
+-- type. This means that a floating-point type with 63 bits of mantissa needs
+-- to be used, which is only generally available on the x86 architecture. It
+-- would still be possible to use multi-precision floating point to perform
+-- calculations using longer mantissas, but this is a much harder approach.
+
+-- The base conversions needed for input/output of (non-decimal) fixed point
+-- types can be seen as pairs of integer multiplications and divisions.
+
+-- Arbitrary-precision integer arithmetic would be suitable for the job at
+-- hand, but has the drawback that it is very heavy implementation-wise.
+-- Especially in embedded systems, where fixed point types are often used,
+-- it may not be desirable to require large amounts of storage and time
+-- for fixed I/O operations.
+
+-- Fixed-precision integer arithmetic has the advantage of simplicity and
+-- speed. For the most common fixed point types this would be a perfect
+-- solution. The downside however may be a too limited set of acceptable
+-- fixed point types.
+
+with Interfaces;
+with Ada.Text_IO.Fixed_Aux;
+with Ada.Text_IO.Float_Aux;
+with System.Img_Fixed_32; use System.Img_Fixed_32;
+with System.Img_Fixed_64; use System.Img_Fixed_64;
+with System.Img_Fixed_128; use System.Img_Fixed_128;
+with System.Val_Fixed_32; use System.Val_Fixed_32;
+with System.Val_Fixed_64; use System.Val_Fixed_64;
+with System.Val_Fixed_128; use System.Val_Fixed_128;
+
+package body Ada.Text_IO.Fixed_IO is
+
+ -- Note: we still use the floating-point I/O routines for types whose small
+ -- is not the ratio of two sufficiently small integers. This will result in
+ -- inaccuracies for fixed point types that require more precision than is
+ -- available in Long_Long_Float.
+
+ subtype Int32 is Interfaces.Integer_32; use type Int32;
+ subtype Int64 is Interfaces.Integer_64; use type Int64;
+ subtype Int128 is Interfaces.Integer_128; use type Int128;
+
+ package Aux32 is new
+ Ada.Text_IO.Fixed_Aux (Int32, Scan_Fixed32, Set_Image_Fixed32);
+
+ package Aux64 is new
+ Ada.Text_IO.Fixed_Aux (Int64, Scan_Fixed64, Set_Image_Fixed64);
+
+ package Aux128 is new
+ Ada.Text_IO.Fixed_Aux (Int128, Scan_Fixed128, Set_Image_Fixed128);
+
+ -- Throughout this generic body, we distinguish between the case where type
+ -- Int32 is OK, where type Int64 is OK and where type Int128 is OK. These
+ -- boolean constants are used to test for this, such that only code for the
+ -- relevant case is included in the instance; that's why the computation of
+ -- their value must be fully static (although it is not a static expression
+ -- in the RM sense).
+
+ OK_Get_32 : constant Boolean :=
+ Num'Object_Size <= 32
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**31)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**31)
+ or else
+ (Num'Small_Numerator <= 2**27
+ and then Num'Small_Denominator <= 2**27));
+ -- These conditions are derived from the prerequisites of System.Value_F
+
+ OK_Put_32 : constant Boolean :=
+ Num'Object_Size <= 32
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**31)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**31)
+ or else
+ (Num'Small_Numerator < Num'Small_Denominator
+ and then Num'Small_Denominator <= 2**27)
+ or else
+ (Num'Small_Denominator < Num'Small_Numerator
+ and then Num'Small_Numerator <= 2**25));
+ -- These conditions are derived from the prerequisites of System.Image_F
+
+ OK_Get_64 : constant Boolean :=
+ Num'Object_Size <= 64
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**63)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**63)
+ or else
+ (Num'Small_Numerator <= 2**59
+ and then Num'Small_Denominator <= 2**59));
+ -- These conditions are derived from the prerequisites of System.Value_F
+
+ OK_Put_64 : constant Boolean :=
+ Num'Object_Size <= 64
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**63)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**63)
+ or else
+ (Num'Small_Numerator < Num'Small_Denominator
+ and then Num'Small_Denominator <= 2**59)
+ or else
+ (Num'Small_Denominator < Num'Small_Numerator
+ and then Num'Small_Numerator <= 2**53));
+ -- These conditions are derived from the prerequisites of System.Image_F
+
+ OK_Get_128 : constant Boolean :=
+ Num'Object_Size <= 128
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**127)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**127)
+ or else
+ (Num'Small_Numerator <= 2**123
+ and then Num'Small_Denominator <= 2**123));
+ -- These conditions are derived from the prerequisites of System.Value_F
+
+ OK_Put_128 : constant Boolean :=
+ Num'Object_Size <= 128
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**127)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**127)
+ or else
+ (Num'Small_Numerator < Num'Small_Denominator
+ and then Num'Small_Denominator <= 2**123)
+ or else
+ (Num'Small_Denominator < Num'Small_Numerator
+ and then Num'Small_Numerator <= 2**122));
+ -- These conditions are derived from the prerequisites of System.Image_F
+
+ E : constant Natural :=
+ 127 - 64 * Boolean'Pos (OK_Put_64) - 32 * Boolean'Pos (OK_Put_32);
+ -- T'Size - 1 for the selected Int{32,64,128}
+
+ F0 : constant Natural := 0;
+ F1 : constant Natural :=
+ F0 + 38 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F0) >= 1.0E+38);
+ F2 : constant Natural :=
+ F1 + 19 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F1) >= 1.0E+19);
+ F3 : constant Natural :=
+ F2 + 9 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F2) >= 1.0E+9);
+ F4 : constant Natural :=
+ F3 + 5 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F3) >= 1.0E+5);
+ F5 : constant Natural :=
+ F4 + 3 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F4) >= 1.0E+3);
+ F6 : constant Natural :=
+ F5 + 2 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F5) >= 1.0E+2);
+ F7 : constant Natural :=
+ F6 + 1 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F6) >= 1.0E+1);
+ -- Binary search for the number of digits - 1 before the decimal point of
+ -- the product 2.0**E * Num'Small.
+
+ For0 : constant Natural := 2 + F7;
+ -- Fore value for the fixed point type whose mantissa is Int{32,64,128} and
+ -- whose small is Num'Small.
+
+ ---------
+ -- Get --
+ ---------
+
+ procedure Get
+ (File : File_Type;
+ Item : out Num;
+ Width : Field := 0)
+ is
+ pragma Unsuppress (Range_Check);
+
+ begin
+ if OK_Get_32 then
+ Item := Num'Fixed_Value
+ (Aux32.Get (File, Width,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ elsif OK_Get_64 then
+ Item := Num'Fixed_Value
+ (Aux64.Get (File, Width,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ elsif OK_Get_128 then
+ Item := Num'Fixed_Value
+ (Aux128.Get (File, Width,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ else
+ Float_Aux.Get (File, Long_Long_Float (Item), Width);
+ end if;
+
+ exception
+ when Constraint_Error => raise Data_Error;
+ end Get;
+
+ procedure Get
+ (Item : out Num;
+ Width : Field := 0)
+ is
+ begin
+ Get (Current_Input, Item, Width);
+ end Get;
+
+ procedure Get
+ (From : String;
+ Item : out Num;
+ Last : out Positive)
+ is
+ pragma Unsuppress (Range_Check);
+
+ begin
+ if OK_Get_32 then
+ Item := Num'Fixed_Value
+ (Aux32.Gets (From, Last,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ elsif OK_Get_64 then
+ Item := Num'Fixed_Value
+ (Aux64.Gets (From, Last,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ elsif OK_Get_128 then
+ Item := Num'Fixed_Value
+ (Aux128.Gets (From, Last,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ else
+ Float_Aux.Gets (From, Long_Long_Float (Item), Last);
+ end if;
+
+ exception
+ when Constraint_Error => raise Data_Error;
+ end Get;
+
+ ---------
+ -- Put --
+ ---------
+
+ procedure Put
+ (File : File_Type;
+ Item : Num;
+ Fore : Field := Default_Fore;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ begin
+ if OK_Put_32 then
+ Aux32.Put (File, Int32'Integer_Value (Item), Fore, Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ elsif OK_Put_64 then
+ Aux64.Put (File, Int64'Integer_Value (Item), Fore, Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ elsif OK_Put_128 then
+ Aux128.Put (File, Int128'Integer_Value (Item), Fore, Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ else
+ Float_Aux.Put (File, Long_Long_Float (Item), Fore, Aft, Exp);
+ end if;
+ end Put;
+
+ procedure Put
+ (Item : Num;
+ Fore : Field := Default_Fore;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ begin
+ Put (Current_Out, Item, Fore, Aft, Exp);
+ end Put;
+
+ procedure Put
+ (To : out String;
+ Item : Num;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ begin
+ if OK_Put_32 then
+ Aux32.Puts (To, Int32'Integer_Value (Item), Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ elsif OK_Put_64 then
+ Aux64.Puts (To, Int64'Integer_Value (Item), Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ elsif OK_Put_128 then
+ Aux128.Puts (To, Int128'Integer_Value (Item), Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ else
+ Float_Aux.Puts (To, Long_Long_Float (Item), Aft, Exp);
+ end if;
+ end Put;
+
+end Ada.Text_IO.Fixed_IO;
diff --git a/gcc/ada/libgnat/a-tiflau.adb b/gcc/ada/libgnat/a-tiflau.adb
index 214b5c8..ddb52a5 100644
--- a/gcc/ada/libgnat/a-tiflau.adb
+++ b/gcc/ada/libgnat/a-tiflau.adb
@@ -47,7 +47,7 @@ package body Ada.Text_IO.Float_Aux is
is
Buf : String (1 .. Field'Last);
Stop : Integer := 0;
- Ptr : aliased Integer := 1;
+ Ptr : aliased Integer;
begin
if Width /= 0 then
@@ -55,10 +55,10 @@ package body Ada.Text_IO.Float_Aux is
String_Skip (Buf, Ptr);
else
Load_Real (File, Buf, Stop);
+ Ptr := 1;
end if;
Item := Scan_Real (Buf, Ptr'Access, Stop);
-
Check_End_Of_Field (Buf, Stop, Ptr, Width);
end Get;
@@ -79,8 +79,7 @@ package body Ada.Text_IO.Float_Aux is
Last := Pos - 1;
exception
- when Constraint_Error =>
- raise Data_Error;
+ when Constraint_Error => raise Data_Error;
end Gets;
---------------
diff --git a/gcc/ada/libgnat/a-wtdeau.adb b/gcc/ada/libgnat/a-wtdeau.adb
index 7bfc613..268ba4d 100644
--- a/gcc/ada/libgnat/a-wtdeau.adb
+++ b/gcc/ada/libgnat/a-wtdeau.adb
@@ -32,54 +32,21 @@
with Ada.Wide_Text_IO.Generic_Aux; use Ada.Wide_Text_IO.Generic_Aux;
with Ada.Wide_Text_IO.Float_Aux; use Ada.Wide_Text_IO.Float_Aux;
-with System.Img_Dec; use System.Img_Dec;
-with System.Img_LLD; use System.Img_LLD;
-with System.Val_Dec; use System.Val_Dec;
-with System.Val_LLD; use System.Val_LLD;
-
package body Ada.Wide_Text_IO.Decimal_Aux is
- -------------
- -- Get_Dec --
- -------------
-
- function Get_Dec
- (File : File_Type;
- Width : Field;
- Scale : Integer) return Integer
- is
- Buf : String (1 .. Field'Last);
- Ptr : aliased Integer;
- Stop : Integer := 0;
- Item : Integer;
-
- begin
- if Width /= 0 then
- Load_Width (File, Width, Buf, Stop);
- String_Skip (Buf, Ptr);
- else
- Load_Real (File, Buf, Stop);
- Ptr := 1;
- end if;
-
- Item := Scan_Decimal (Buf, Ptr'Access, Stop, Scale);
- Check_End_Of_Field (Buf, Stop, Ptr, Width);
- return Item;
- end Get_Dec;
-
- -------------
- -- Get_LLD --
- -------------
+ ---------
+ -- Get --
+ ---------
- function Get_LLD
+ function Get
(File : File_Type;
Width : Field;
- Scale : Integer) return Long_Long_Integer
+ Scale : Integer) return Int
is
Buf : String (1 .. Field'Last);
Ptr : aliased Integer;
Stop : Integer := 0;
- Item : Long_Long_Integer;
+ Item : Int;
begin
if Width /= 0 then
@@ -90,68 +57,42 @@ package body Ada.Wide_Text_IO.Decimal_Aux is
Ptr := 1;
end if;
- Item := Scan_Long_Long_Decimal (Buf, Ptr'Access, Stop, Scale);
+ Item := Scan (Buf, Ptr'Access, Stop, Scale);
Check_End_Of_Field (Buf, Stop, Ptr, Width);
return Item;
- end Get_LLD;
-
- --------------
- -- Gets_Dec --
- --------------
-
- function Gets_Dec
- (From : String;
- Last : not null access Positive;
- Scale : Integer) return Integer
- is
- Pos : aliased Integer;
- Item : Integer;
-
- begin
- String_Skip (From, Pos);
- Item := Scan_Decimal (From, Pos'Access, From'Last, Scale);
- Last.all := Pos - 1;
- return Item;
+ end Get;
- exception
- when Constraint_Error =>
- Last.all := Pos - 1;
- raise Data_Error;
-
- end Gets_Dec;
+ ----------
+ -- Gets --
+ ----------
- --------------
- -- Gets_LLD --
- --------------
-
- function Gets_LLD
+ function Gets
(From : String;
- Last : not null access Positive;
- Scale : Integer) return Long_Long_Integer
+ Last : out Positive;
+ Scale : Integer) return Int
is
Pos : aliased Integer;
- Item : Long_Long_Integer;
+ Item : Int;
begin
String_Skip (From, Pos);
- Item := Scan_Long_Long_Decimal (From, Pos'Access, From'Last, Scale);
- Last.all := Pos - 1;
+ Item := Scan (From, Pos'Access, From'Last, Scale);
+ Last := Pos - 1;
return Item;
exception
when Constraint_Error =>
- Last.all := Pos - 1;
+ Last := Pos - 1;
raise Data_Error;
+ end Gets;
- end Gets_LLD;
-
- -------------
- -- Put_Dec --
- -------------
+ ---------
+ -- Put --
+ ---------
- procedure Put_Dec
+ procedure Put
(File : File_Type;
- Item : Integer;
+ Item : Int;
Fore : Field;
Aft : Field;
Exp : Field;
@@ -161,105 +102,51 @@ package body Ada.Wide_Text_IO.Decimal_Aux is
Ptr : Natural := 0;
begin
- Set_Image_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
+ Set_Image (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
Put_Item (File, Buf (1 .. Ptr));
- end Put_Dec;
+ end Put;
- -------------
- -- Put_LLD --
- -------------
+ ----------
+ -- Puts --
+ ----------
- procedure Put_LLD
- (File : File_Type;
- Item : Long_Long_Integer;
- Fore : Field;
- Aft : Field;
- Exp : Field;
- Scale : Integer)
- is
- Buf : String (1 .. Field'Last);
- Ptr : Natural := 0;
-
- begin
- Set_Image_Long_Long_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
- Put_Item (File, Buf (1 .. Ptr));
- end Put_LLD;
-
- --------------
- -- Puts_Dec --
- --------------
-
- procedure Puts_Dec
+ procedure Puts
(To : out String;
- Item : Integer;
+ Item : Int;
Aft : Field;
Exp : Field;
Scale : Integer)
is
- Buf : String (1 .. Field'Last);
+ Buf : String (1 .. Positive'Max (Field'Last, To'Length));
Fore : Integer;
Ptr : Natural := 0;
begin
- -- Compute Fore, allowing for Aft digits and the decimal dot
+ -- Compute Fore, allowing for the decimal dot and Aft digits
- Fore := To'Length - Field'Max (1, Aft) - 1;
+ Fore := To'Length - 1 - Field'Max (1, Aft);
- -- Allow for Exp and two more for E+ or E- if exponent present
+ -- Allow for Exp and one more for E if exponent present
if Exp /= 0 then
- Fore := Fore - 2 - Exp;
+ Fore := Fore - 1 - Field'Max (2, Exp);
end if;
-- Make sure we have enough room
- if Fore < 1 then
+ if Fore < 1 + Boolean'Pos (Item < 0) then
raise Layout_Error;
end if;
-- Do the conversion and check length of result
- Set_Image_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
-
- if Ptr > To'Length then
- raise Layout_Error;
- else
- To := Buf (1 .. Ptr);
- end if;
- end Puts_Dec;
-
- --------------
- -- Puts_LLD --
- --------------
-
- procedure Puts_LLD
- (To : out String;
- Item : Long_Long_Integer;
- Aft : Field;
- Exp : Field;
- Scale : Integer)
- is
- Buf : String (1 .. Field'Last);
- Fore : Integer;
- Ptr : Natural := 0;
-
- begin
- Fore :=
- (if Exp = 0
- then To'Length - 1 - Aft
- else To'Length - 2 - Aft - Exp);
-
- if Fore < 1 then
- raise Layout_Error;
- end if;
-
- Set_Image_Long_Long_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
+ Set_Image (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
if Ptr > To'Length then
raise Layout_Error;
else
To := Buf (1 .. Ptr);
end if;
- end Puts_LLD;
+ end Puts;
end Ada.Wide_Text_IO.Decimal_Aux;
diff --git a/gcc/ada/libgnat/a-wtdeau.ads b/gcc/ada/libgnat/a-wtdeau.ads
index 0465455..5c0c4d6 100644
--- a/gcc/ada/libgnat/a-wtdeau.ads
+++ b/gcc/ada/libgnat/a-wtdeau.ads
@@ -29,63 +29,54 @@
-- --
------------------------------------------------------------------------------
--- This package contains the routines for Ada.Wide_Text_IO.Decimal_IO
--- that are shared among separate instantiations of this package. The
--- routines in the package are identical semantically to those declared
--- in Wide_Text_IO, except that default values have been supplied by the
--- generic, and the Num parameter has been replaced by Integer or
--- Long_Long_Integer, with an additional Scale parameter giving the
--- value of Num'Scale. In addition the Get routines return the value
--- rather than store it in an Out parameter.
+-- This package contains the implementation for Ada.Wide_Text_IO.Decimal_IO.
+-- Routines in this package are identical semantically to those in Decimal_IO,
+-- except that the default parameters have been removed because they are
+-- supplied explicitly by the calls from within these units, and there is an
+-- additional Scale parameter giving the value of Num'Scale. In addition the
+-- Get routines return the value rather than store it in an Out parameter.
-private package Ada.Wide_Text_IO.Decimal_Aux is
+private generic
+ type Int is range <>;
- function Get_Dec
- (File : File_Type;
- Width : Field;
- Scale : Integer) return Integer;
+ with function Scan
+ (Str : String;
+ Ptr : not null access Integer;
+ Max : Integer;
+ Scale : Integer) return Int;
- function Get_LLD
- (File : File_Type;
- Width : Field;
- Scale : Integer) return Long_Long_Integer;
+ with procedure Set_Image
+ (V : Int;
+ S : in out String;
+ P : in out Natural;
+ Scale : Integer;
+ Fore : Natural;
+ Aft : Natural;
+ Exp : Natural);
- function Gets_Dec
- (From : String;
- Last : not null access Positive;
- Scale : Integer) return Integer;
+package Ada.Wide_Text_IO.Decimal_Aux is
- function Gets_LLD
- (From : String;
- Last : not null access Positive;
- Scale : Integer) return Long_Long_Integer;
-
- procedure Put_Dec
+ function Get
(File : File_Type;
- Item : Integer;
- Fore : Field;
- Aft : Field;
- Exp : Field;
- Scale : Integer);
+ Width : Field;
+ Scale : Integer) return Int;
- procedure Put_LLD
+ procedure Put
(File : File_Type;
- Item : Long_Long_Integer;
+ Item : Int;
Fore : Field;
Aft : Field;
Exp : Field;
Scale : Integer);
- procedure Puts_Dec
- (To : out String;
- Item : Integer;
- Aft : Field;
- Exp : Field;
- Scale : Integer);
+ function Gets
+ (From : String;
+ Last : out Positive;
+ Scale : Integer) return Int;
- procedure Puts_LLD
+ procedure Puts
(To : out String;
- Item : Long_Long_Integer;
+ Item : Int;
Aft : Field;
Exp : Field;
Scale : Integer);
diff --git a/gcc/ada/libgnat/a-wtdeio.adb b/gcc/ada/libgnat/a-wtdeio.adb
index 845a217..b432cac 100644
--- a/gcc/ada/libgnat/a-wtdeio.adb
+++ b/gcc/ada/libgnat/a-wtdeio.adb
@@ -30,16 +30,35 @@
------------------------------------------------------------------------------
with Ada.Wide_Text_IO.Decimal_Aux;
-
+with System.Img_Decimal_32; use System.Img_Decimal_32;
+with System.Img_Decimal_64; use System.Img_Decimal_64;
+with System.Val_Decimal_32; use System.Val_Decimal_32;
+with System.Val_Decimal_64; use System.Val_Decimal_64;
with System.WCh_Con; use System.WCh_Con;
with System.WCh_WtS; use System.WCh_WtS;
package body Ada.Wide_Text_IO.Decimal_IO is
- subtype TFT is Ada.Wide_Text_IO.File_Type;
- -- File type required for calls to routines in Aux
+ subtype Int32 is Interfaces.Integer_32;
+ subtype Int64 is Interfaces.Integer_64;
+
+ package Aux32 is new
+ Ada.Wide_Text_IO.Decimal_Aux
+ (Int32,
+ Scan_Decimal32,
+ Set_Image_Decimal32);
- package Aux renames Ada.Wide_Text_IO.Decimal_Aux;
+ package Aux64 is new
+ Ada.Wide_Text_IO.Decimal_Aux
+ (Int64,
+ Scan_Decimal64,
+ Set_Image_Decimal64);
+
+ Need64 : constant Boolean := Num'Size > 32;
+ -- Throughout this generic body, we distinguish between the case where type
+ -- Int32 is acceptable and where type Int64 is needed. This Boolean is used
+ -- to test for these cases and since it is a constant, only code for the
+ -- relevant case will be included in the instance.
Scale : constant Integer := Num'Scale;
@@ -52,12 +71,15 @@ package body Ada.Wide_Text_IO.Decimal_IO is
Item : out Num;
Width : Field := 0)
is
+ pragma Unsuppress (Range_Check);
+
begin
- if Num'Size > Integer'Size then
- Item := Num'Fixed_Value (Aux.Get_LLD (TFT (File), Width, Scale));
+ if Need64 then
+ Item := Num'Fixed_Value (Aux64.Get (File, Width, Scale));
else
- Item := Num'Fixed_Value (Aux.Get_Dec (TFT (File), Width, Scale));
+ Item := Num'Fixed_Value (Aux32.Get (File, Width, Scale));
end if;
+
exception
when Constraint_Error => raise Data_Error;
end Get;
@@ -75,6 +97,8 @@ package body Ada.Wide_Text_IO.Decimal_IO is
Item : out Num;
Last : out Positive)
is
+ pragma Unsuppress (Range_Check);
+
S : constant String := Wide_String_To_String (From, WCEM_Upper);
-- String on which we do the actual conversion. Note that the method
-- used for wide character encoding is irrelevant, since if there is
@@ -82,16 +106,10 @@ package body Ada.Wide_Text_IO.Decimal_IO is
-- Aux.Gets will raise Data_Error in any case.
begin
- if Num'Size > Integer'Size then
- -- Item := Num'Fixed_Value
- -- should write above, but gets assert error ???
- Item := Num
- (Aux.Gets_LLD (S, Last'Unrestricted_Access, Scale));
+ if Need64 then
+ Item := Num'Fixed_Value (Aux64.Gets (S, Last, Scale));
else
- -- Item := Num'Fixed_Value
- -- should write above, but gets assert error ???
- Item := Num
- (Aux.Gets_Dec (S, Last'Unrestricted_Access, Scale));
+ Item := Num'Fixed_Value (Aux32.Gets (S, Last, Scale));
end if;
exception
@@ -110,13 +128,12 @@ package body Ada.Wide_Text_IO.Decimal_IO is
Exp : Field := Default_Exp)
is
begin
- if Num'Size > Integer'Size then
- Aux.Put_LLD
- (TFT (File), Long_Long_Integer'Integer_Value (Item),
- Fore, Aft, Exp, Scale);
+ if Need64 then
+ Aux64.Put
+ (File, Int64'Integer_Value (Item), Fore, Aft, Exp, Scale);
else
- Aux.Put_Dec
- (TFT (File), Integer'Integer_Value (Item), Fore, Aft, Exp, Scale);
+ Aux32.Put
+ (File, Int32'Integer_Value (Item), Fore, Aft, Exp, Scale);
end if;
end Put;
@@ -139,12 +156,10 @@ package body Ada.Wide_Text_IO.Decimal_IO is
S : String (To'First .. To'Last);
begin
- if Num'Size > Integer'Size then
- Aux.Puts_LLD
- (S, Long_Long_Integer'Integer_Value (Item), Aft, Exp, Scale);
-
+ if Need64 then
+ Aux64.Puts (S, Int64'Integer_Value (Item), Aft, Exp, Scale);
else
- Aux.Puts_Dec (S, Integer'Integer_Value (Item), Aft, Exp, Scale);
+ Aux32.Puts (S, Int32'Integer_Value (Item), Aft, Exp, Scale);
end if;
for J in S'Range loop
diff --git a/gcc/ada/libgnat/a-wtdeio__128.adb b/gcc/ada/libgnat/a-wtdeio__128.adb
new file mode 100644
index 0000000..6e23e08
--- /dev/null
+++ b/gcc/ada/libgnat/a-wtdeio__128.adb
@@ -0,0 +1,190 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . W I D E _ T E X T _ I O . D E C I M A L _ I O --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Ada.Wide_Text_IO.Decimal_Aux;
+with System.Img_Decimal_32; use System.Img_Decimal_32;
+with System.Img_Decimal_64; use System.Img_Decimal_64;
+with System.Img_Decimal_128; use System.Img_Decimal_128;
+with System.Val_Decimal_32; use System.Val_Decimal_32;
+with System.Val_Decimal_64; use System.Val_Decimal_64;
+with System.Val_Decimal_128; use System.Val_Decimal_128;
+with System.WCh_Con; use System.WCh_Con;
+with System.WCh_WtS; use System.WCh_WtS;
+
+package body Ada.Wide_Text_IO.Decimal_IO is
+
+ subtype Int32 is Interfaces.Integer_32;
+ subtype Int64 is Interfaces.Integer_64;
+ subtype Int128 is Interfaces.Integer_128;
+
+ package Aux32 is new
+ Ada.Wide_Text_IO.Decimal_Aux
+ (Int32,
+ Scan_Decimal32,
+ Set_Image_Decimal32);
+
+ package Aux64 is new
+ Ada.Wide_Text_IO.Decimal_Aux
+ (Int64,
+ Scan_Decimal64,
+ Set_Image_Decimal64);
+
+ package Aux128 is new
+ Ada.Wide_Text_IO.Decimal_Aux
+ (Int128,
+ Scan_Decimal128,
+ Set_Image_Decimal128);
+
+ Need64 : constant Boolean := Num'Size > 32;
+ Need128 : constant Boolean := Num'Size > 64;
+ -- Throughout this generic body, we distinguish between the case where type
+ -- Int32 is acceptable, where type Int64 is acceptable and where an Int128
+ -- is needed. These boolean constants are used to test for these cases and
+ -- since it is a constant, only code for the relevant case will be included
+ -- in the instance.
+
+ Scale : constant Integer := Num'Scale;
+
+ ---------
+ -- Get --
+ ---------
+
+ procedure Get
+ (File : File_Type;
+ Item : out Num;
+ Width : Field := 0)
+ is
+ pragma Unsuppress (Range_Check);
+
+ begin
+ if Need128 then
+ Item := Num'Fixed_Value (Aux128.Get (File, Width, Scale));
+ elsif Need64 then
+ Item := Num'Fixed_Value (Aux64.Get (File, Width, Scale));
+ else
+ Item := Num'Fixed_Value (Aux32.Get (File, Width, Scale));
+ end if;
+
+ exception
+ when Constraint_Error => raise Data_Error;
+ end Get;
+
+ procedure Get
+ (Item : out Num;
+ Width : Field := 0)
+ is
+ begin
+ Get (Current_Input, Item, Width);
+ end Get;
+
+ procedure Get
+ (From : Wide_String;
+ Item : out Num;
+ Last : out Positive)
+ is
+ pragma Unsuppress (Range_Check);
+
+ S : constant String := Wide_String_To_String (From, WCEM_Upper);
+ -- String on which we do the actual conversion. Note that the method
+ -- used for wide character encoding is irrelevant, since if there is
+ -- a character outside the Standard.Character range then the call to
+ -- Aux.Gets will raise Data_Error in any case.
+
+ begin
+ if Need128 then
+ Item := Num'Fixed_Value (Aux128.Gets (S, Last, Scale));
+ elsif Need64 then
+ Item := Num'Fixed_Value (Aux64.Gets (S, Last, Scale));
+ else
+ Item := Num'Fixed_Value (Aux32.Gets (S, Last, Scale));
+ end if;
+
+ exception
+ when Constraint_Error => raise Data_Error;
+ end Get;
+
+ ---------
+ -- Put --
+ ---------
+
+ procedure Put
+ (File : File_Type;
+ Item : Num;
+ Fore : Field := Default_Fore;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ begin
+ if Need128 then
+ Aux128.Put
+ (File, Int128'Integer_Value (Item), Fore, Aft, Exp, Scale);
+ elsif Need64 then
+ Aux64.Put
+ (File, Int64'Integer_Value (Item), Fore, Aft, Exp, Scale);
+ else
+ Aux32.Put
+ (File, Int32'Integer_Value (Item), Fore, Aft, Exp, Scale);
+ end if;
+ end Put;
+
+ procedure Put
+ (Item : Num;
+ Fore : Field := Default_Fore;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ begin
+ Put (Current_Output, Item, Fore, Aft, Exp);
+ end Put;
+
+ procedure Put
+ (To : out Wide_String;
+ Item : Num;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ S : String (To'First .. To'Last);
+
+ begin
+ if Need128 then
+ Aux128.Puts (S, Int128'Integer_Value (Item), Aft, Exp, Scale);
+ elsif Need64 then
+ Aux64.Puts (S, Int64'Integer_Value (Item), Aft, Exp, Scale);
+ else
+ Aux32.Puts (S, Int32'Integer_Value (Item), Aft, Exp, Scale);
+ end if;
+
+ for J in S'Range loop
+ To (J) := Wide_Character'Val (Character'Pos (S (J)));
+ end loop;
+ end Put;
+
+end Ada.Wide_Text_IO.Decimal_IO;
diff --git a/gcc/ada/libgnat/a-wtenau.adb b/gcc/ada/libgnat/a-wtenau.adb
index 3fb6f76..6dcda30 100644
--- a/gcc/ada/libgnat/a-wtenau.adb
+++ b/gcc/ada/libgnat/a-wtenau.adb
@@ -36,9 +36,6 @@ with System.WCh_Con; use System.WCh_Con;
package body Ada.Wide_Text_IO.Enumeration_Aux is
- subtype TFT is Ada.Wide_Text_IO.File_Type;
- -- File type required for calls to routines in Aux
-
-----------------------
-- Local Subprograms --
-----------------------
@@ -69,8 +66,8 @@ package body Ada.Wide_Text_IO.Enumeration_Aux is
begin
Buflen := 0;
- Load_Skip (TFT (File));
- ch := Nextc (TFT (File));
+ Load_Skip (File);
+ ch := Nextc (File);
-- Character literal case. If the initial character is a quote, then
-- we read as far as we can without backup (see ACVC test CE3905L)
@@ -79,7 +76,7 @@ package body Ada.Wide_Text_IO.Enumeration_Aux is
Get (File, WC);
Store_Char (WC, Buf, Buflen);
- ch := Nextc (TFT (File));
+ ch := Nextc (File);
if ch = LM or else ch = EOF then
return;
@@ -88,7 +85,7 @@ package body Ada.Wide_Text_IO.Enumeration_Aux is
Get (File, WC);
Store_Char (WC, Buf, Buflen);
- ch := Nextc (TFT (File));
+ ch := Nextc (File);
if ch /= Character'Pos (''') then
return;
@@ -117,7 +114,7 @@ package body Ada.Wide_Text_IO.Enumeration_Aux is
Get (File, WC);
Store_Char (WC, Buf, Buflen);
- ch := Nextc (TFT (File));
+ ch := Nextc (File);
exit when ch = EOF;
@@ -155,7 +152,7 @@ package body Ada.Wide_Text_IO.Enumeration_Aux is
Integer'Max (Integer (Width), Item'Length);
begin
- Check_On_One_Line (TFT (File), Actual_Width);
+ Check_On_One_Line (File, Actual_Width);
if Set = Lower_Case and then Item (Item'First) /= ''' then
declare
diff --git a/gcc/ada/libgnat/a-wtfiau.adb b/gcc/ada/libgnat/a-wtfiau.adb
new file mode 100644
index 0000000..d4a1534
--- /dev/null
+++ b/gcc/ada/libgnat/a-wtfiau.adb
@@ -0,0 +1,160 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . W I D E _ T E X T _ I O . F I X E D _ I O --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Ada.Wide_Text_IO.Generic_Aux; use Ada.Wide_Text_IO.Generic_Aux;
+with Ada.Wide_Text_IO.Float_Aux; use Ada.Wide_Text_IO.Float_Aux;
+
+package body Ada.Wide_Text_IO.Fixed_Aux is
+
+ ---------
+ -- Get --
+ ---------
+
+ function Get
+ (File : File_Type;
+ Width : Field;
+ Num : Int;
+ Den : Int) return Int
+ is
+ Buf : String (1 .. Field'Last);
+ Ptr : aliased Integer;
+ Stop : Integer := 0;
+ Item : Int;
+
+ begin
+ if Width /= 0 then
+ Load_Width (File, Width, Buf, Stop);
+ String_Skip (Buf, Ptr);
+ else
+ Load_Real (File, Buf, Stop);
+ Ptr := 1;
+ end if;
+
+ Item := Scan (Buf, Ptr'Access, Stop, Num, Den);
+ Check_End_Of_Field (Buf, Stop, Ptr, Width);
+ return Item;
+ end Get;
+
+ ----------
+ -- Gets --
+ ----------
+
+ function Gets
+ (From : String;
+ Last : out Positive;
+ Num : Int;
+ Den : Int) return Int
+ is
+ Pos : aliased Integer;
+ Item : Int;
+
+ begin
+ String_Skip (From, Pos);
+ Item := Scan (From, Pos'Access, From'Last, Num, Den);
+ Last := Pos - 1;
+ return Item;
+
+ exception
+ when Constraint_Error =>
+ Last := Pos - 1;
+ raise Data_Error;
+ end Gets;
+
+ ---------
+ -- Put --
+ ---------
+
+ procedure Put
+ (File : File_Type;
+ Item : Int;
+ Fore : Field;
+ Aft : Field;
+ Exp : Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural)
+ is
+ Buf : String (1 .. Field'Last);
+ Ptr : Natural := 0;
+
+ begin
+ Set_Image (Item, Buf, Ptr, Num, Den, For0, Aft0, Fore, Aft, Exp);
+ Put_Item (File, Buf (1 .. Ptr));
+ end Put;
+
+ ----------
+ -- Puts --
+ ----------
+
+ procedure Puts
+ (To : out String;
+ Item : Int;
+ Aft : Field;
+ Exp : Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural)
+ is
+ Buf : String (1 .. Positive'Max (Field'Last, To'Length));
+ Fore : Integer;
+ Ptr : Natural := 0;
+
+ begin
+ -- Compute Fore, allowing for the decimal dot and Aft digits
+
+ Fore := To'Length - 1 - Field'Max (1, Aft);
+
+ -- Allow for Exp and one more for E if exponent present
+
+ if Exp /= 0 then
+ Fore := Fore - 1 - Field'Max (2, Exp);
+ end if;
+
+ -- Make sure we have enough room
+
+ if Fore < 1 + Boolean'Pos (Item < 0) then
+ raise Layout_Error;
+ end if;
+
+ -- Do the conversion and check length of result
+
+ Set_Image (Item, Buf, Ptr, Num, Den, For0, Aft0, Fore, Aft, Exp);
+
+ if Ptr > To'Length then
+ raise Layout_Error;
+ else
+ To := Buf (1 .. Ptr);
+ end if;
+ end Puts;
+
+end Ada.Wide_Text_IO.Fixed_Aux;
diff --git a/gcc/ada/libgnat/a-wtfiau.ads b/gcc/ada/libgnat/a-wtfiau.ads
new file mode 100644
index 0000000..f487931
--- /dev/null
+++ b/gcc/ada/libgnat/a-wtfiau.ads
@@ -0,0 +1,97 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . W I D E _ T E X T _ I O . F I X E D _ I O --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the implementation for Ada.Wide_Text_IO.Fixed_IO.
+-- Routines in this package are identical semantically to those in Fixed_IO,
+-- except that the default parameters have been removed because they are
+-- supplied explicitly by the calls from within these units, and there are
+-- additional Num and Den parameters giving the value of Num'Small, as well
+-- as For0 and Aft0 giving some properties of Num'Small. In addition the Get
+-- routines return the value rather than store it in an Out parameter.
+
+private generic
+ type Int is range <>;
+
+ with function Scan
+ (Str : String;
+ Ptr : not null access Integer;
+ Max : Integer;
+ Num : Int;
+ Den : Int) return Int;
+
+ with procedure Set_Image
+ (V : Int;
+ S : in out String;
+ P : in out Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural;
+ Fore : Natural;
+ Aft : Natural;
+ Exp : Natural);
+
+package Ada.Wide_Text_IO.Fixed_Aux is
+
+ function Get
+ (File : File_Type;
+ Width : Field;
+ Num : Int;
+ Den : Int) return Int;
+
+ procedure Put
+ (File : File_Type;
+ Item : Int;
+ Fore : Field;
+ Aft : Field;
+ Exp : Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural);
+
+ function Gets
+ (From : String;
+ Last : out Positive;
+ Num : Int;
+ Den : Int) return Int;
+
+ procedure Puts
+ (To : out String;
+ Item : Int;
+ Aft : Field;
+ Exp : Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural);
+
+end Ada.Wide_Text_IO.Fixed_Aux;
diff --git a/gcc/ada/libgnat/a-wtfiio.adb b/gcc/ada/libgnat/a-wtfiio.adb
index f70c8e4..142a445 100644
--- a/gcc/ada/libgnat/a-wtfiio.adb
+++ b/gcc/ada/libgnat/a-wtfiio.adb
@@ -2,7 +2,7 @@
-- --
-- GNAT RUN-TIME COMPONENTS --
-- --
--- A D A . T E X T _ I O . W I D E _ T E X T _ I O . F I X E D _ I O --
+-- A D A . W I D E _ T E X T _ I O . F I X E D _ I O --
-- --
-- B o d y --
-- --
@@ -29,16 +29,110 @@
-- --
------------------------------------------------------------------------------
+with Interfaces;
+with Ada.Wide_Text_IO.Fixed_Aux;
with Ada.Wide_Text_IO.Float_Aux;
-with System.WCh_Con; use System.WCh_Con;
-with System.WCh_WtS; use System.WCh_WtS;
+with System.Img_Fixed_32; use System.Img_Fixed_32;
+with System.Img_Fixed_64; use System.Img_Fixed_64;
+with System.Val_Fixed_32; use System.Val_Fixed_32;
+with System.Val_Fixed_64; use System.Val_Fixed_64;
+with System.WCh_Con; use System.WCh_Con;
+with System.WCh_WtS; use System.WCh_WtS;
package body Ada.Wide_Text_IO.Fixed_IO is
- subtype TFT is Ada.Wide_Text_IO.File_Type;
- -- File type required for calls to routines in Aux
+ -- Note: we still use the floating-point I/O routines for types whose small
+ -- is not the ratio of two sufficiently small integers. This will result in
+ -- inaccuracies for fixed point types that require more precision than is
+ -- available in Long_Long_Float.
- package Aux renames Ada.Wide_Text_IO.Float_Aux;
+ subtype Int32 is Interfaces.Integer_32; use type Int32;
+ subtype Int64 is Interfaces.Integer_64; use type Int64;
+
+ package Aux32 is new
+ Ada.Wide_Text_IO.Fixed_Aux (Int32, Scan_Fixed32, Set_Image_Fixed32);
+
+ package Aux64 is new
+ Ada.Wide_Text_IO.Fixed_Aux (Int64, Scan_Fixed64, Set_Image_Fixed64);
+
+ -- Throughout this generic body, we distinguish between the case where type
+ -- Int32 is OK and where type Int64 is OK. These boolean constants are used
+ -- to test for this, such that only code for the relevant case is included
+ -- in the instance; that's why the computation of their value must be fully
+ -- static (although it is not a static expressions in the RM sense).
+
+ OK_Get_32 : constant Boolean :=
+ Num'Object_Size <= 32
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**31)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**31)
+ or else
+ (Num'Small_Numerator <= 2**27
+ and then Num'Small_Denominator <= 2**27));
+ -- These conditions are derived from the prerequisites of System.Value_F
+
+ OK_Put_32 : constant Boolean :=
+ Num'Object_Size <= 32
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**31)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**31)
+ or else
+ (Num'Small_Numerator < Num'Small_Denominator
+ and then Num'Small_Denominator <= 2**27)
+ or else
+ (Num'Small_Denominator < Num'Small_Numerator
+ and then Num'Small_Numerator <= 2**25));
+ -- These conditions are derived from the prerequisites of System.Image_F
+
+ OK_Get_64 : constant Boolean :=
+ Num'Object_Size <= 64
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**63)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**63)
+ or else
+ (Num'Small_Numerator <= 2**59
+ and then Num'Small_Denominator <= 2**59));
+ -- These conditions are derived from the prerequisites of System.Value_F
+
+ OK_Put_64 : constant Boolean :=
+ Num'Object_Size <= 64
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**63)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**63)
+ or else
+ (Num'Small_Numerator < Num'Small_Denominator
+ and then Num'Small_Denominator <= 2**59)
+ or else
+ (Num'Small_Denominator < Num'Small_Numerator
+ and then Num'Small_Numerator <= 2**53));
+ -- These conditions are derived from the prerequisites of System.Image_F
+
+ E : constant Natural := 63 - 32 * Boolean'Pos (OK_Put_32);
+ -- T'Size - 1 for the selected Int{32,64}
+
+ F0 : constant Natural := 0;
+ F1 : constant Natural :=
+ F0 + 18 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F0) >= 1.0E+18);
+ F2 : constant Natural :=
+ F1 + 9 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F1) >= 1.0E+9);
+ F3 : constant Natural :=
+ F2 + 5 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F2) >= 1.0E+5);
+ F4 : constant Natural :=
+ F3 + 3 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F3) >= 1.0E+3);
+ F5 : constant Natural :=
+ F4 + 2 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F4) >= 1.0E+2);
+ F6 : constant Natural :=
+ F5 + 1 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F5) >= 1.0E+1);
+ -- Binary search for the number of digits - 1 before the decimal point of
+ -- the product 2.0**E * Num'Small.
+
+ For0 : constant Natural := 2 + F6;
+ -- Fore value for the fixed point type whose mantissa is Int{32,64} and
+ -- whose small is Num'Small.
---------
-- Get --
@@ -49,8 +143,22 @@ package body Ada.Wide_Text_IO.Fixed_IO is
Item : out Num;
Width : Field := 0)
is
+ pragma Unsuppress (Range_Check);
+
begin
- Aux.Get (TFT (File), Long_Long_Float (Item), Width);
+ if OK_Get_32 then
+ Item := Num'Fixed_Value
+ (Aux32.Get (File, Width,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ elsif OK_Get_64 then
+ Item := Num'Fixed_Value
+ (Aux64.Get (File, Width,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ else
+ Float_Aux.Get (File, Long_Long_Float (Item), Width);
+ end if;
exception
when Constraint_Error => raise Data_Error;
@@ -69,6 +177,8 @@ package body Ada.Wide_Text_IO.Fixed_IO is
Item : out Num;
Last : out Positive)
is
+ pragma Unsuppress (Range_Check);
+
S : constant String := Wide_String_To_String (From, WCEM_Upper);
-- String on which we do the actual conversion. Note that the method
-- used for wide character encoding is irrelevant, since if there is
@@ -76,7 +186,19 @@ package body Ada.Wide_Text_IO.Fixed_IO is
-- Aux.Gets will raise Data_Error in any case.
begin
- Aux.Gets (S, Long_Long_Float (Item), Last);
+ if OK_Get_32 then
+ Item := Num'Fixed_Value
+ (Aux32.Gets (S, Last,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ elsif OK_Get_64 then
+ Item := Num'Fixed_Value
+ (Aux64.Gets (S, Last,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ else
+ Float_Aux.Gets (S, Long_Long_Float (Item), Last);
+ end if;
exception
when Constraint_Error => raise Data_Error;
@@ -94,7 +216,17 @@ package body Ada.Wide_Text_IO.Fixed_IO is
Exp : Field := Default_Exp)
is
begin
- Aux.Put (TFT (File), Long_Long_Float (Item), Fore, Aft, Exp);
+ if OK_Put_32 then
+ Aux32.Put (File, Int32'Integer_Value (Item), Fore, Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ elsif OK_Put_64 then
+ Aux64.Put (File, Int64'Integer_Value (Item), Fore, Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ else
+ Float_Aux.Put (File, Long_Long_Float (Item), Fore, Aft, Exp);
+ end if;
end Put;
procedure Put
@@ -116,7 +248,17 @@ package body Ada.Wide_Text_IO.Fixed_IO is
S : String (To'First .. To'Last);
begin
- Aux.Puts (S, Long_Long_Float (Item), Aft, Exp);
+ if OK_Put_32 then
+ Aux32.Puts (S, Int32'Integer_Value (Item), Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ elsif OK_Put_64 then
+ Aux64.Puts (S, Int64'Integer_Value (Item), Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ else
+ Float_Aux.Puts (S, Long_Long_Float (Item), Aft, Exp);
+ end if;
for J in S'Range loop
To (J) := Wide_Character'Val (Character'Pos (S (J)));
diff --git a/gcc/ada/libgnat/a-wtfiio__128.adb b/gcc/ada/libgnat/a-wtfiio__128.adb
new file mode 100644
index 0000000..b4f1b1d
--- /dev/null
+++ b/gcc/ada/libgnat/a-wtfiio__128.adb
@@ -0,0 +1,321 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . W I D E _ T E X T _ I O . F I X E D _ I O --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Interfaces;
+with Ada.Wide_Text_IO.Fixed_Aux;
+with Ada.Wide_Text_IO.Float_Aux;
+with System.Img_Fixed_32; use System.Img_Fixed_32;
+with System.Img_Fixed_64; use System.Img_Fixed_64;
+with System.Img_Fixed_128; use System.Img_Fixed_128;
+with System.Val_Fixed_32; use System.Val_Fixed_32;
+with System.Val_Fixed_64; use System.Val_Fixed_64;
+with System.Val_Fixed_128; use System.Val_Fixed_128;
+with System.WCh_Con; use System.WCh_Con;
+with System.WCh_WtS; use System.WCh_WtS;
+
+package body Ada.Wide_Text_IO.Fixed_IO is
+
+ -- Note: we still use the floating-point I/O routines for types whose small
+ -- is not the ratio of two sufficiently small integers. This will result in
+ -- inaccuracies for fixed point types that require more precision than is
+ -- available in Long_Long_Float.
+
+ subtype Int32 is Interfaces.Integer_32; use type Int32;
+ subtype Int64 is Interfaces.Integer_64; use type Int64;
+ subtype Int128 is Interfaces.Integer_128; use type Int128;
+
+ package Aux32 is new
+ Ada.Wide_Text_IO.Fixed_Aux (Int32, Scan_Fixed32, Set_Image_Fixed32);
+
+ package Aux64 is new
+ Ada.Wide_Text_IO.Fixed_Aux (Int64, Scan_Fixed64, Set_Image_Fixed64);
+
+ package Aux128 is new
+ Ada.Wide_Text_IO.Fixed_Aux (Int128, Scan_Fixed128, Set_Image_Fixed128);
+
+ -- Throughout this generic body, we distinguish between the case where type
+ -- Int32 is OK, where type Int64 is OK and where type Int128 is OK. These
+ -- boolean constants are used to test for this, such that only code for the
+ -- relevant case is included in the instance; that's why the computation of
+ -- their value must be fully static (although it is not a static expression
+ -- in the RM sense).
+
+ OK_Get_32 : constant Boolean :=
+ Num'Object_Size <= 32
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**31)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**31)
+ or else
+ (Num'Small_Numerator <= 2**27
+ and then Num'Small_Denominator <= 2**27));
+ -- These conditions are derived from the prerequisites of System.Value_F
+
+ OK_Put_32 : constant Boolean :=
+ Num'Object_Size <= 32
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**31)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**31)
+ or else
+ (Num'Small_Numerator < Num'Small_Denominator
+ and then Num'Small_Denominator <= 2**27)
+ or else
+ (Num'Small_Denominator < Num'Small_Numerator
+ and then Num'Small_Numerator <= 2**25));
+ -- These conditions are derived from the prerequisites of System.Image_F
+
+ OK_Get_64 : constant Boolean :=
+ Num'Object_Size <= 64
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**63)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**63)
+ or else
+ (Num'Small_Numerator <= 2**59
+ and then Num'Small_Denominator <= 2**59));
+ -- These conditions are derived from the prerequisites of System.Value_F
+
+ OK_Put_64 : constant Boolean :=
+ Num'Object_Size <= 64
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**63)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**63)
+ or else
+ (Num'Small_Numerator < Num'Small_Denominator
+ and then Num'Small_Denominator <= 2**59)
+ or else
+ (Num'Small_Denominator < Num'Small_Numerator
+ and then Num'Small_Numerator <= 2**53));
+ -- These conditions are derived from the prerequisites of System.Image_F
+
+ OK_Get_128 : constant Boolean :=
+ Num'Object_Size <= 128
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**127)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**127)
+ or else
+ (Num'Small_Numerator <= 2**123
+ and then Num'Small_Denominator <= 2**123));
+ -- These conditions are derived from the prerequisites of System.Value_F
+
+ OK_Put_128 : constant Boolean :=
+ Num'Object_Size <= 128
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**127)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**127)
+ or else
+ (Num'Small_Numerator < Num'Small_Denominator
+ and then Num'Small_Denominator <= 2**123)
+ or else
+ (Num'Small_Denominator < Num'Small_Numerator
+ and then Num'Small_Numerator <= 2**122));
+ -- These conditions are derived from the prerequisites of System.Image_F
+
+ E : constant Natural :=
+ 127 - 64 * Boolean'Pos (OK_Put_64) - 32 * Boolean'Pos (OK_Put_32);
+ -- T'Size - 1 for the selected Int{32,64,128}
+
+ F0 : constant Natural := 0;
+ F1 : constant Natural :=
+ F0 + 38 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F0) >= 1.0E+38);
+ F2 : constant Natural :=
+ F1 + 19 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F1) >= 1.0E+19);
+ F3 : constant Natural :=
+ F2 + 9 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F2) >= 1.0E+9);
+ F4 : constant Natural :=
+ F3 + 5 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F3) >= 1.0E+5);
+ F5 : constant Natural :=
+ F4 + 3 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F4) >= 1.0E+3);
+ F6 : constant Natural :=
+ F5 + 2 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F5) >= 1.0E+2);
+ F7 : constant Natural :=
+ F6 + 1 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F6) >= 1.0E+1);
+ -- Binary search for the number of digits - 1 before the decimal point of
+ -- the product 2.0**E * Num'Small.
+
+ For0 : constant Natural := 2 + F7;
+ -- Fore value for the fixed point type whose mantissa is Int{32,64,128} and
+ -- whose small is Num'Small.
+
+ ---------
+ -- Get --
+ ---------
+
+ procedure Get
+ (File : File_Type;
+ Item : out Num;
+ Width : Field := 0)
+ is
+ pragma Unsuppress (Range_Check);
+
+ begin
+ if OK_Get_32 then
+ Item := Num'Fixed_Value
+ (Aux32.Get (File, Width,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ elsif OK_Get_64 then
+ Item := Num'Fixed_Value
+ (Aux64.Get (File, Width,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ elsif OK_Get_128 then
+ Item := Num'Fixed_Value
+ (Aux128.Get (File, Width,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ else
+ Float_Aux.Get (File, Long_Long_Float (Item), Width);
+ end if;
+
+ exception
+ when Constraint_Error => raise Data_Error;
+ end Get;
+
+ procedure Get
+ (Item : out Num;
+ Width : Field := 0)
+ is
+ begin
+ Get (Current_Input, Item, Width);
+ end Get;
+
+ procedure Get
+ (From : Wide_String;
+ Item : out Num;
+ Last : out Positive)
+ is
+ pragma Unsuppress (Range_Check);
+
+ S : constant String := Wide_String_To_String (From, WCEM_Upper);
+ -- String on which we do the actual conversion. Note that the method
+ -- used for wide character encoding is irrelevant, since if there is
+ -- a character outside the Standard.Character range then the call to
+ -- Aux.Gets will raise Data_Error in any case.
+
+ begin
+ if OK_Get_32 then
+ Item := Num'Fixed_Value
+ (Aux32.Gets (S, Last,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ elsif OK_Get_64 then
+ Item := Num'Fixed_Value
+ (Aux64.Gets (S, Last,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ elsif OK_Get_128 then
+ Item := Num'Fixed_Value
+ (Aux128.Gets (S, Last,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ else
+ Float_Aux.Gets (S, Long_Long_Float (Item), Last);
+ end if;
+
+ exception
+ when Constraint_Error => raise Data_Error;
+ end Get;
+
+ ---------
+ -- Put --
+ ---------
+
+ procedure Put
+ (File : File_Type;
+ Item : Num;
+ Fore : Field := Default_Fore;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ begin
+ if OK_Put_32 then
+ Aux32.Put (File, Int32'Integer_Value (Item), Fore, Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ elsif OK_Put_64 then
+ Aux64.Put (File, Int64'Integer_Value (Item), Fore, Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ elsif OK_Put_128 then
+ Aux128.Put (File, Int128'Integer_Value (Item), Fore, Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ else
+ Float_Aux.Put (File, Long_Long_Float (Item), Fore, Aft, Exp);
+ end if;
+ end Put;
+
+ procedure Put
+ (Item : Num;
+ Fore : Field := Default_Fore;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ begin
+ Put (Current_Output, Item, Fore, Aft, Exp);
+ end Put;
+
+ procedure Put
+ (To : out Wide_String;
+ Item : Num;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ S : String (To'First .. To'Last);
+
+ begin
+ if OK_Put_32 then
+ Aux32.Puts (S, Int32'Integer_Value (Item), Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ elsif OK_Put_64 then
+ Aux64.Puts (S, Int64'Integer_Value (Item), Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ elsif OK_Put_128 then
+ Aux128.Puts (S, Int128'Integer_Value (Item), Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ else
+ Float_Aux.Puts (S, Long_Long_Float (Item), Aft, Exp);
+ end if;
+
+ for J in S'Range loop
+ To (J) := Wide_Character'Val (Character'Pos (S (J)));
+ end loop;
+ end Put;
+
+end Ada.Wide_Text_IO.Fixed_IO;
diff --git a/gcc/ada/libgnat/a-wtflio.adb b/gcc/ada/libgnat/a-wtflio.adb
index 5a36d88..a7df6d9 100644
--- a/gcc/ada/libgnat/a-wtflio.adb
+++ b/gcc/ada/libgnat/a-wtflio.adb
@@ -36,9 +36,6 @@ with System.WCh_WtS; use System.WCh_WtS;
package body Ada.Wide_Text_IO.Float_IO is
- subtype TFT is Ada.Wide_Text_IO.File_Type;
- -- File type required for calls to routines in Aux
-
package Aux renames Ada.Wide_Text_IO.Float_Aux;
---------
@@ -51,7 +48,7 @@ package body Ada.Wide_Text_IO.Float_IO is
Width : Field := 0)
is
begin
- Aux.Get (TFT (File), Long_Long_Float (Item), Width);
+ Aux.Get (File, Long_Long_Float (Item), Width);
exception
when Constraint_Error => raise Data_Error;
@@ -95,7 +92,7 @@ package body Ada.Wide_Text_IO.Float_IO is
Exp : Field := Default_Exp)
is
begin
- Aux.Put (TFT (File), Long_Long_Float (Item), Fore, Aft, Exp);
+ Aux.Put (File, Long_Long_Float (Item), Fore, Aft, Exp);
end Put;
procedure Put
diff --git a/gcc/ada/libgnat/a-wtinio.adb b/gcc/ada/libgnat/a-wtinio.adb
index a3f666e..dff0b68 100644
--- a/gcc/ada/libgnat/a-wtinio.adb
+++ b/gcc/ada/libgnat/a-wtinio.adb
@@ -65,9 +65,6 @@ package body Ada.Wide_Text_IO.Integer_IO is
-- Boolean is used to test for these cases and since it is a constant, only
-- code for the relevant case will be included in the instance.
- subtype TFT is Ada.Wide_Text_IO.File_Type;
- -- File type required for calls to routines in Aux
-
---------
-- Get --
---------
@@ -84,9 +81,9 @@ package body Ada.Wide_Text_IO.Integer_IO is
begin
if Need_LLI then
- Aux_LLI.Get (TFT (File), Long_Long_Integer (Item), Width);
+ Aux_LLI.Get (File, Long_Long_Integer (Item), Width);
else
- Aux_Int.Get (TFT (File), Integer (Item), Width);
+ Aux_Int.Get (File, Integer (Item), Width);
end if;
exception
@@ -140,9 +137,9 @@ package body Ada.Wide_Text_IO.Integer_IO is
is
begin
if Need_LLI then
- Aux_LLI.Put (TFT (File), Long_Long_Integer (Item), Width, Base);
+ Aux_LLI.Put (File, Long_Long_Integer (Item), Width, Base);
else
- Aux_Int.Put (TFT (File), Integer (Item), Width, Base);
+ Aux_Int.Put (File, Integer (Item), Width, Base);
end if;
end Put;
diff --git a/gcc/ada/libgnat/a-wtinio__128.adb b/gcc/ada/libgnat/a-wtinio__128.adb
index edc78c3..8936f49 100644
--- a/gcc/ada/libgnat/a-wtinio__128.adb
+++ b/gcc/ada/libgnat/a-wtinio__128.adb
@@ -79,9 +79,6 @@ package body Ada.Wide_Text_IO.Integer_IO is
-- are used to test for these cases and since they are constant, only code
-- for the relevant case will be included in the instance.
- subtype TFT is Ada.Wide_Text_IO.File_Type;
- -- File type required for calls to routines in Aux
-
---------
-- Get --
---------
@@ -98,11 +95,11 @@ package body Ada.Wide_Text_IO.Integer_IO is
begin
if Need_LLLI then
- Aux_LLLI.Get (TFT (File), Long_Long_Long_Integer (Item), Width);
+ Aux_LLLI.Get (File, Long_Long_Long_Integer (Item), Width);
elsif Need_LLI then
- Aux_LLI.Get (TFT (File), Long_Long_Integer (Item), Width);
+ Aux_LLI.Get (File, Long_Long_Integer (Item), Width);
else
- Aux_Int.Get (TFT (File), Integer (Item), Width);
+ Aux_Int.Get (File, Integer (Item), Width);
end if;
exception
@@ -158,11 +155,11 @@ package body Ada.Wide_Text_IO.Integer_IO is
is
begin
if Need_LLLI then
- Aux_LLLI.Put (TFT (File), Long_Long_Long_Integer (Item), Width, Base);
+ Aux_LLLI.Put (File, Long_Long_Long_Integer (Item), Width, Base);
elsif Need_LLI then
- Aux_LLI.Put (TFT (File), Long_Long_Integer (Item), Width, Base);
+ Aux_LLI.Put (File, Long_Long_Integer (Item), Width, Base);
else
- Aux_Int.Put (TFT (File), Integer (Item), Width, Base);
+ Aux_Int.Put (File, Integer (Item), Width, Base);
end if;
end Put;
diff --git a/gcc/ada/libgnat/a-wtmoio.adb b/gcc/ada/libgnat/a-wtmoio.adb
index 702dcbb..4fe5beb 100644
--- a/gcc/ada/libgnat/a-wtmoio.adb
+++ b/gcc/ada/libgnat/a-wtmoio.adb
@@ -65,9 +65,6 @@ package body Ada.Wide_Text_IO.Modular_IO is
-- Boolean is used to test for these cases and since it is a constant, only
-- code for the relevant case will be included in the instance.
- subtype TFT is Ada.Wide_Text_IO.File_Type;
- -- File type required for calls to routines in Aux
-
---------
-- Get --
---------
@@ -83,9 +80,9 @@ package body Ada.Wide_Text_IO.Modular_IO is
begin
if Need_LLU then
- Aux_LLU.Get (TFT (File), Long_Long_Unsigned (Item), Width);
+ Aux_LLU.Get (File, Long_Long_Unsigned (Item), Width);
else
- Aux_Uns.Get (TFT (File), Unsigned (Item), Width);
+ Aux_Uns.Get (File, Unsigned (Item), Width);
end if;
exception
@@ -138,9 +135,9 @@ package body Ada.Wide_Text_IO.Modular_IO is
is
begin
if Need_LLU then
- Aux_LLU.Put (TFT (File), Long_Long_Unsigned (Item), Width, Base);
+ Aux_LLU.Put (File, Long_Long_Unsigned (Item), Width, Base);
else
- Aux_Uns.Put (TFT (File), Unsigned (Item), Width, Base);
+ Aux_Uns.Put (File, Unsigned (Item), Width, Base);
end if;
end Put;
diff --git a/gcc/ada/libgnat/a-wtmoio__128.adb b/gcc/ada/libgnat/a-wtmoio__128.adb
index 661faec..0dbf06e 100644
--- a/gcc/ada/libgnat/a-wtmoio__128.adb
+++ b/gcc/ada/libgnat/a-wtmoio__128.adb
@@ -79,9 +79,6 @@ package body Ada.Wide_Text_IO.Modular_IO is
-- are used to test for these cases and since they are constant, only code
-- for the relevant case will be included in the instance.
- subtype TFT is Ada.Wide_Text_IO.File_Type;
- -- File type required for calls to routines in Aux
-
---------
-- Get --
---------
@@ -99,9 +96,9 @@ package body Ada.Wide_Text_IO.Modular_IO is
if Need_LLLU then
Aux_LLLU.Get (File, Long_Long_Long_Unsigned (Item), Width);
elsif Need_LLU then
- Aux_LLU.Get (TFT (File), Long_Long_Unsigned (Item), Width);
+ Aux_LLU.Get (File, Long_Long_Unsigned (Item), Width);
else
- Aux_Uns.Get (TFT (File), Unsigned (Item), Width);
+ Aux_Uns.Get (File, Unsigned (Item), Width);
end if;
exception
@@ -158,9 +155,9 @@ package body Ada.Wide_Text_IO.Modular_IO is
if Need_LLLU then
Aux_LLLU.Put (File, Long_Long_Long_Unsigned (Item), Width, Base);
elsif Need_LLU then
- Aux_LLU.Put (TFT (File), Long_Long_Unsigned (Item), Width, Base);
+ Aux_LLU.Put (File, Long_Long_Unsigned (Item), Width, Base);
else
- Aux_Uns.Put (TFT (File), Unsigned (Item), Width, Base);
+ Aux_Uns.Put (File, Unsigned (Item), Width, Base);
end if;
end Put;
diff --git a/gcc/ada/libgnat/a-ztdeau.adb b/gcc/ada/libgnat/a-ztdeau.adb
index 3daff0f..6c2af9f 100644
--- a/gcc/ada/libgnat/a-ztdeau.adb
+++ b/gcc/ada/libgnat/a-ztdeau.adb
@@ -32,54 +32,21 @@
with Ada.Wide_Wide_Text_IO.Generic_Aux; use Ada.Wide_Wide_Text_IO.Generic_Aux;
with Ada.Wide_Wide_Text_IO.Float_Aux; use Ada.Wide_Wide_Text_IO.Float_Aux;
-with System.Img_Dec; use System.Img_Dec;
-with System.Img_LLD; use System.Img_LLD;
-with System.Val_Dec; use System.Val_Dec;
-with System.Val_LLD; use System.Val_LLD;
-
package body Ada.Wide_Wide_Text_IO.Decimal_Aux is
- -------------
- -- Get_Dec --
- -------------
-
- function Get_Dec
- (File : File_Type;
- Width : Field;
- Scale : Integer) return Integer
- is
- Buf : String (1 .. Field'Last);
- Ptr : aliased Integer;
- Stop : Integer := 0;
- Item : Integer;
-
- begin
- if Width /= 0 then
- Load_Width (File, Width, Buf, Stop);
- String_Skip (Buf, Ptr);
- else
- Load_Real (File, Buf, Stop);
- Ptr := 1;
- end if;
-
- Item := Scan_Decimal (Buf, Ptr'Access, Stop, Scale);
- Check_End_Of_Field (Buf, Stop, Ptr, Width);
- return Item;
- end Get_Dec;
-
- -------------
- -- Get_LLD --
- -------------
+ ---------
+ -- Get --
+ ---------
- function Get_LLD
+ function Get
(File : File_Type;
Width : Field;
- Scale : Integer) return Long_Long_Integer
+ Scale : Integer) return Int
is
Buf : String (1 .. Field'Last);
Ptr : aliased Integer;
Stop : Integer := 0;
- Item : Long_Long_Integer;
+ Item : Int;
begin
if Width /= 0 then
@@ -90,68 +57,42 @@ package body Ada.Wide_Wide_Text_IO.Decimal_Aux is
Ptr := 1;
end if;
- Item := Scan_Long_Long_Decimal (Buf, Ptr'Access, Stop, Scale);
+ Item := Scan (Buf, Ptr'Access, Stop, Scale);
Check_End_Of_Field (Buf, Stop, Ptr, Width);
return Item;
- end Get_LLD;
-
- --------------
- -- Gets_Dec --
- --------------
-
- function Gets_Dec
- (From : String;
- Last : not null access Positive;
- Scale : Integer) return Integer
- is
- Pos : aliased Integer;
- Item : Integer;
-
- begin
- String_Skip (From, Pos);
- Item := Scan_Decimal (From, Pos'Access, From'Last, Scale);
- Last.all := Pos - 1;
- return Item;
+ end Get;
- exception
- when Constraint_Error =>
- Last.all := Pos - 1;
- raise Data_Error;
-
- end Gets_Dec;
+ ----------
+ -- Gets --
+ ----------
- --------------
- -- Gets_LLD --
- --------------
-
- function Gets_LLD
+ function Gets
(From : String;
- Last : not null access Positive;
- Scale : Integer) return Long_Long_Integer
+ Last : out Positive;
+ Scale : Integer) return Int
is
Pos : aliased Integer;
- Item : Long_Long_Integer;
+ Item : Int;
begin
String_Skip (From, Pos);
- Item := Scan_Long_Long_Decimal (From, Pos'Access, From'Last, Scale);
- Last.all := Pos - 1;
+ Item := Scan (From, Pos'Access, From'Last, Scale);
+ Last := Pos - 1;
return Item;
exception
when Constraint_Error =>
- Last.all := Pos - 1;
+ Last := Pos - 1;
raise Data_Error;
+ end Gets;
- end Gets_LLD;
-
- -------------
- -- Put_Dec --
- -------------
+ ---------
+ -- Put --
+ ---------
- procedure Put_Dec
+ procedure Put
(File : File_Type;
- Item : Integer;
+ Item : Int;
Fore : Field;
Aft : Field;
Exp : Field;
@@ -161,103 +102,51 @@ package body Ada.Wide_Wide_Text_IO.Decimal_Aux is
Ptr : Natural := 0;
begin
- Set_Image_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
+ Set_Image (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
Put_Item (File, Buf (1 .. Ptr));
- end Put_Dec;
+ end Put;
- -------------
- -- Put_LLD --
- -------------
+ ----------
+ -- Puts --
+ ----------
- procedure Put_LLD
- (File : File_Type;
- Item : Long_Long_Integer;
- Fore : Field;
- Aft : Field;
- Exp : Field;
- Scale : Integer)
- is
- Buf : String (1 .. Field'Last);
- Ptr : Natural := 0;
-
- begin
- Set_Image_Long_Long_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
- Put_Item (File, Buf (1 .. Ptr));
- end Put_LLD;
-
- --------------
- -- Puts_Dec --
- --------------
-
- procedure Puts_Dec
+ procedure Puts
(To : out String;
- Item : Integer;
+ Item : Int;
Aft : Field;
Exp : Field;
Scale : Integer)
is
- Buf : String (1 .. Field'Last);
+ Buf : String (1 .. Positive'Max (Field'Last, To'Length));
Fore : Integer;
Ptr : Natural := 0;
begin
- -- Compute Fore, allowing for Aft digits and the decimal dot
+ -- Compute Fore, allowing for the decimal dot and Aft digits
- Fore := To'Length - Field'Max (1, Aft) - 1;
+ Fore := To'Length - 1 - Field'Max (1, Aft);
- -- Allow for Exp and two more for E+ or E- if exponent present
+ -- Allow for Exp and one more for E if exponent present
if Exp /= 0 then
- Fore := Fore - 2 - Exp;
+ Fore := Fore - 1 - Field'Max (2, Exp);
end if;
-- Make sure we have enough room
- if Fore < 1 then
+ if Fore < 1 + Boolean'Pos (Item < 0) then
raise Layout_Error;
end if;
-- Do the conversion and check length of result
- Set_Image_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
-
- if Ptr > To'Length then
- raise Layout_Error;
- else
- To := Buf (1 .. Ptr);
- end if;
- end Puts_Dec;
-
- --------------
- -- Puts_LLD --
- --------------
-
- procedure Puts_LLD
- (To : out String;
- Item : Long_Long_Integer;
- Aft : Field;
- Exp : Field;
- Scale : Integer)
- is
- Buf : String (1 .. Field'Last);
- Fore : Integer;
- Ptr : Natural := 0;
-
- begin
- Fore :=
- (if Exp = 0 then To'Length - 1 - Aft else To'Length - 2 - Aft - Exp);
-
- if Fore < 1 then
- raise Layout_Error;
- end if;
-
- Set_Image_Long_Long_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
+ Set_Image (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
if Ptr > To'Length then
raise Layout_Error;
else
To := Buf (1 .. Ptr);
end if;
- end Puts_LLD;
+ end Puts;
end Ada.Wide_Wide_Text_IO.Decimal_Aux;
diff --git a/gcc/ada/libgnat/a-ztdeau.ads b/gcc/ada/libgnat/a-ztdeau.ads
index b493b80..962f479 100644
--- a/gcc/ada/libgnat/a-ztdeau.ads
+++ b/gcc/ada/libgnat/a-ztdeau.ads
@@ -29,63 +29,54 @@
-- --
------------------------------------------------------------------------------
--- This package contains the routines for Ada.Wide_Wide_Text_IO.Decimal_IO
--- that are shared among separate instantiations of this package. The
--- routines in the package are identical semantically to those declared
--- in Wide_Wide_Text_IO, except that default values have been supplied by the
--- generic, and the Num parameter has been replaced by Integer or
--- Long_Long_Integer, with an additional Scale parameter giving the
--- value of Num'Scale. In addition the Get routines return the value
--- rather than store it in an Out parameter.
+-- This package contains implementation for Ada.Wide_Wide_Text_IO.Decimal_IO
+-- Routines in this package are identical semantically to those in Decimal_IO,
+-- except that the default parameters have been removed because they are
+-- supplied explicitly by the calls from within these units, and there is an
+-- additional Scale parameter giving the value of Num'Scale. In addition the
+-- Get routines return the value rather than store it in an Out parameter.
-private package Ada.Wide_Wide_Text_IO.Decimal_Aux is
+private generic
+ type Int is range <>;
- function Get_Dec
- (File : File_Type;
- Width : Field;
- Scale : Integer) return Integer;
+ with function Scan
+ (Str : String;
+ Ptr : not null access Integer;
+ Max : Integer;
+ Scale : Integer) return Int;
- function Get_LLD
- (File : File_Type;
- Width : Field;
- Scale : Integer) return Long_Long_Integer;
+ with procedure Set_Image
+ (V : Int;
+ S : in out String;
+ P : in out Natural;
+ Scale : Integer;
+ Fore : Natural;
+ Aft : Natural;
+ Exp : Natural);
- function Gets_Dec
- (From : String;
- Last : not null access Positive;
- Scale : Integer) return Integer;
+package Ada.Wide_Wide_Text_IO.Decimal_Aux is
- function Gets_LLD
- (From : String;
- Last : not null access Positive;
- Scale : Integer) return Long_Long_Integer;
-
- procedure Put_Dec
+ function Get
(File : File_Type;
- Item : Integer;
- Fore : Field;
- Aft : Field;
- Exp : Field;
- Scale : Integer);
+ Width : Field;
+ Scale : Integer) return Int;
- procedure Put_LLD
+ procedure Put
(File : File_Type;
- Item : Long_Long_Integer;
+ Item : Int;
Fore : Field;
Aft : Field;
Exp : Field;
Scale : Integer);
- procedure Puts_Dec
- (To : out String;
- Item : Integer;
- Aft : Field;
- Exp : Field;
- Scale : Integer);
+ function Gets
+ (From : String;
+ Last : out Positive;
+ Scale : Integer) return Int;
- procedure Puts_LLD
+ procedure Puts
(To : out String;
- Item : Long_Long_Integer;
+ Item : Int;
Aft : Field;
Exp : Field;
Scale : Integer);
diff --git a/gcc/ada/libgnat/a-ztdeio.adb b/gcc/ada/libgnat/a-ztdeio.adb
index 3655386..cd26914 100644
--- a/gcc/ada/libgnat/a-ztdeio.adb
+++ b/gcc/ada/libgnat/a-ztdeio.adb
@@ -30,16 +30,35 @@
------------------------------------------------------------------------------
with Ada.Wide_Wide_Text_IO.Decimal_Aux;
-
+with System.Img_Decimal_32; use System.Img_Decimal_32;
+with System.Img_Decimal_64; use System.Img_Decimal_64;
+with System.Val_Decimal_32; use System.Val_Decimal_32;
+with System.Val_Decimal_64; use System.Val_Decimal_64;
with System.WCh_Con; use System.WCh_Con;
with System.WCh_WtS; use System.WCh_WtS;
package body Ada.Wide_Wide_Text_IO.Decimal_IO is
- subtype TFT is Ada.Wide_Wide_Text_IO.File_Type;
- -- File type required for calls to routines in Aux
+ subtype Int32 is Interfaces.Integer_32;
+ subtype Int64 is Interfaces.Integer_64;
+
+ package Aux32 is new
+ Ada.Wide_Wide_Text_IO.Decimal_Aux
+ (Int32,
+ Scan_Decimal32,
+ Set_Image_Decimal32);
- package Aux renames Ada.Wide_Wide_Text_IO.Decimal_Aux;
+ package Aux64 is new
+ Ada.Wide_Wide_Text_IO.Decimal_Aux
+ (Int64,
+ Scan_Decimal64,
+ Set_Image_Decimal64);
+
+ Need64 : constant Boolean := Num'Size > 32;
+ -- Throughout this generic body, we distinguish between the case where type
+ -- Int32 is acceptable and where type Int64 is needed. This Boolean is used
+ -- to test for these cases and since it is a constant, only code for the
+ -- relevant case will be included in the instance.
Scale : constant Integer := Num'Scale;
@@ -52,12 +71,15 @@ package body Ada.Wide_Wide_Text_IO.Decimal_IO is
Item : out Num;
Width : Field := 0)
is
+ pragma Unsuppress (Range_Check);
+
begin
- if Num'Size > Integer'Size then
- Item := Num'Fixed_Value (Aux.Get_LLD (TFT (File), Width, Scale));
+ if Need64 then
+ Item := Num'Fixed_Value (Aux64.Get (File, Width, Scale));
else
- Item := Num'Fixed_Value (Aux.Get_Dec (TFT (File), Width, Scale));
+ Item := Num'Fixed_Value (Aux32.Get (File, Width, Scale));
end if;
+
exception
when Constraint_Error => raise Data_Error;
end Get;
@@ -75,6 +97,8 @@ package body Ada.Wide_Wide_Text_IO.Decimal_IO is
Item : out Num;
Last : out Positive)
is
+ pragma Unsuppress (Range_Check);
+
S : constant String := Wide_Wide_String_To_String (From, WCEM_Upper);
-- String on which we do the actual conversion. Note that the method
-- used for wide character encoding is irrelevant, since if there is
@@ -82,16 +106,10 @@ package body Ada.Wide_Wide_Text_IO.Decimal_IO is
-- Aux.Gets will raise Data_Error in any case.
begin
- if Num'Size > Integer'Size then
- -- Item := Num'Fixed_Value
- -- should write above, but gets assert error ???
- Item := Num
- (Aux.Gets_LLD (S, Last'Unrestricted_Access, Scale));
+ if Need64 then
+ Item := Num'Fixed_Value (Aux64.Gets (S, Last, Scale));
else
- -- Item := Num'Fixed_Value
- -- should write above, but gets assert error ???
- Item := Num
- (Aux.Gets_Dec (S, Last'Unrestricted_Access, Scale));
+ Item := Num'Fixed_Value (Aux32.Gets (S, Last, Scale));
end if;
exception
@@ -110,18 +128,12 @@ package body Ada.Wide_Wide_Text_IO.Decimal_IO is
Exp : Field := Default_Exp)
is
begin
- if Num'Size > Integer'Size then
- Aux.Put_LLD
--- (TFT (File), Long_Long_Integer'Integer_Value (Item),
--- ???
- (TFT (File), Long_Long_Integer (Item),
- Fore, Aft, Exp, Scale);
+ if Need64 then
+ Aux64.Put
+ (File, Int64'Integer_Value (Item), Fore, Aft, Exp, Scale);
else
- Aux.Put_Dec
--- (TFT (File), Integer'Integer_Value (Item), Fore, Aft, Exp, Scale);
--- ???
- (TFT (File), Integer (Item), Fore, Aft, Exp, Scale);
-
+ Aux32.Put
+ (File, Int32'Integer_Value (Item), Fore, Aft, Exp, Scale);
end if;
end Put;
@@ -144,16 +156,10 @@ package body Ada.Wide_Wide_Text_IO.Decimal_IO is
S : String (To'First .. To'Last);
begin
- if Num'Size > Integer'Size then
--- Aux.Puts_LLD
--- (S, Long_Long_Integer'Integer_Value (Item), Aft, Exp, Scale);
--- ???
- Aux.Puts_LLD
- (S, Long_Long_Integer (Item), Aft, Exp, Scale);
+ if Need64 then
+ Aux64.Puts (S, Int64'Integer_Value (Item), Aft, Exp, Scale);
else
--- Aux.Puts_Dec (S, Integer'Integer_Value (Item), Aft, Exp, Scale);
--- ???
- Aux.Puts_Dec (S, Integer (Item), Aft, Exp, Scale);
+ Aux32.Puts (S, Int32'Integer_Value (Item), Aft, Exp, Scale);
end if;
for J in S'Range loop
diff --git a/gcc/ada/libgnat/a-ztdeio__128.adb b/gcc/ada/libgnat/a-ztdeio__128.adb
new file mode 100644
index 0000000..e160a01
--- /dev/null
+++ b/gcc/ada/libgnat/a-ztdeio__128.adb
@@ -0,0 +1,190 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . W I D E _ W I D E _ T E X T _ I O . D E C I M A L _ I O --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Ada.Wide_Wide_Text_IO.Decimal_Aux;
+with System.Img_Decimal_32; use System.Img_Decimal_32;
+with System.Img_Decimal_64; use System.Img_Decimal_64;
+with System.Img_Decimal_128; use System.Img_Decimal_128;
+with System.Val_Decimal_32; use System.Val_Decimal_32;
+with System.Val_Decimal_64; use System.Val_Decimal_64;
+with System.Val_Decimal_128; use System.Val_Decimal_128;
+with System.WCh_Con; use System.WCh_Con;
+with System.WCh_WtS; use System.WCh_WtS;
+
+package body Ada.Wide_Wide_Text_IO.Decimal_IO is
+
+ subtype Int32 is Interfaces.Integer_32;
+ subtype Int64 is Interfaces.Integer_64;
+ subtype Int128 is Interfaces.Integer_128;
+
+ package Aux32 is new
+ Ada.Wide_Wide_Text_IO.Decimal_Aux
+ (Int32,
+ Scan_Decimal32,
+ Set_Image_Decimal32);
+
+ package Aux64 is new
+ Ada.Wide_Wide_Text_IO.Decimal_Aux
+ (Int64,
+ Scan_Decimal64,
+ Set_Image_Decimal64);
+
+ package Aux128 is new
+ Ada.Wide_Wide_Text_IO.Decimal_Aux
+ (Int128,
+ Scan_Decimal128,
+ Set_Image_Decimal128);
+
+ Need64 : constant Boolean := Num'Size > 32;
+ Need128 : constant Boolean := Num'Size > 64;
+ -- Throughout this generic body, we distinguish between the case where type
+ -- Int32 is acceptable, where type Int64 is acceptable and where an Int128
+ -- is needed. These boolean constants are used to test for these cases and
+ -- since it is a constant, only code for the relevant case will be included
+ -- in the instance.
+
+ Scale : constant Integer := Num'Scale;
+
+ ---------
+ -- Get --
+ ---------
+
+ procedure Get
+ (File : File_Type;
+ Item : out Num;
+ Width : Field := 0)
+ is
+ pragma Unsuppress (Range_Check);
+
+ begin
+ if Need128 then
+ Item := Num'Fixed_Value (Aux128.Get (File, Width, Scale));
+ elsif Need64 then
+ Item := Num'Fixed_Value (Aux64.Get (File, Width, Scale));
+ else
+ Item := Num'Fixed_Value (Aux32.Get (File, Width, Scale));
+ end if;
+
+ exception
+ when Constraint_Error => raise Data_Error;
+ end Get;
+
+ procedure Get
+ (Item : out Num;
+ Width : Field := 0)
+ is
+ begin
+ Get (Current_Input, Item, Width);
+ end Get;
+
+ procedure Get
+ (From : Wide_Wide_String;
+ Item : out Num;
+ Last : out Positive)
+ is
+ pragma Unsuppress (Range_Check);
+
+ S : constant String := Wide_Wide_String_To_String (From, WCEM_Upper);
+ -- String on which we do the actual conversion. Note that the method
+ -- used for wide character encoding is irrelevant, since if there is
+ -- a character outside the Standard.Character range then the call to
+ -- Aux.Gets will raise Data_Error in any case.
+
+ begin
+ if Need128 then
+ Item := Num'Fixed_Value (Aux128.Gets (S, Last, Scale));
+ elsif Need64 then
+ Item := Num'Fixed_Value (Aux64.Gets (S, Last, Scale));
+ else
+ Item := Num'Fixed_Value (Aux32.Gets (S, Last, Scale));
+ end if;
+
+ exception
+ when Constraint_Error => raise Data_Error;
+ end Get;
+
+ ---------
+ -- Put --
+ ---------
+
+ procedure Put
+ (File : File_Type;
+ Item : Num;
+ Fore : Field := Default_Fore;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ begin
+ if Need128 then
+ Aux128.Put
+ (File, Int128'Integer_Value (Item), Fore, Aft, Exp, Scale);
+ elsif Need64 then
+ Aux64.Put
+ (File, Int64'Integer_Value (Item), Fore, Aft, Exp, Scale);
+ else
+ Aux32.Put
+ (File, Int32'Integer_Value (Item), Fore, Aft, Exp, Scale);
+ end if;
+ end Put;
+
+ procedure Put
+ (Item : Num;
+ Fore : Field := Default_Fore;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ begin
+ Put (Current_Output, Item, Fore, Aft, Exp);
+ end Put;
+
+ procedure Put
+ (To : out Wide_Wide_String;
+ Item : Num;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ S : String (To'First .. To'Last);
+
+ begin
+ if Need128 then
+ Aux128.Puts (S, Int128'Integer_Value (Item), Aft, Exp, Scale);
+ elsif Need64 then
+ Aux64.Puts (S, Int64'Integer_Value (Item), Aft, Exp, Scale);
+ else
+ Aux32.Puts (S, Int32'Integer_Value (Item), Aft, Exp, Scale);
+ end if;
+
+ for J in S'Range loop
+ To (J) := Wide_Wide_Character'Val (Character'Pos (S (J)));
+ end loop;
+ end Put;
+
+end Ada.Wide_Wide_Text_IO.Decimal_IO;
diff --git a/gcc/ada/libgnat/a-ztenau.adb b/gcc/ada/libgnat/a-ztenau.adb
index f985d52d..f3b11af 100644
--- a/gcc/ada/libgnat/a-ztenau.adb
+++ b/gcc/ada/libgnat/a-ztenau.adb
@@ -37,9 +37,6 @@ with System.WCh_Con; use System.WCh_Con;
package body Ada.Wide_Wide_Text_IO.Enumeration_Aux is
- subtype TFT is Ada.Wide_Wide_Text_IO.File_Type;
- -- File type required for calls to routines in Aux
-
-----------------------
-- Local Subprograms --
-----------------------
@@ -70,8 +67,8 @@ package body Ada.Wide_Wide_Text_IO.Enumeration_Aux is
begin
Buflen := 0;
- Load_Skip (TFT (File));
- ch := Nextc (TFT (File));
+ Load_Skip (File);
+ ch := Nextc (File);
-- Character literal case. If the initial character is a quote, then
-- we read as far as we can without backup (see ACVC test CE3905L)
@@ -80,7 +77,7 @@ package body Ada.Wide_Wide_Text_IO.Enumeration_Aux is
Get (File, WC);
Store_Char (WC, Buf, Buflen);
- ch := Nextc (TFT (File));
+ ch := Nextc (File);
if ch = LM or else ch = EOF then
return;
@@ -89,7 +86,7 @@ package body Ada.Wide_Wide_Text_IO.Enumeration_Aux is
Get (File, WC);
Store_Char (WC, Buf, Buflen);
- ch := Nextc (TFT (File));
+ ch := Nextc (File);
if ch /= Character'Pos (''') then
return;
@@ -118,7 +115,7 @@ package body Ada.Wide_Wide_Text_IO.Enumeration_Aux is
Get (File, WC);
Store_Char (WC, Buf, Buflen);
- ch := Nextc (TFT (File));
+ ch := Nextc (File);
exit when ch = EOF;
@@ -156,7 +153,7 @@ package body Ada.Wide_Wide_Text_IO.Enumeration_Aux is
Integer'Max (Integer (Width), Item'Length);
begin
- Check_On_One_Line (TFT (File), Actual_Width);
+ Check_On_One_Line (File, Actual_Width);
if Set = Lower_Case and then Item (Item'First) /= ''' then
declare
diff --git a/gcc/ada/libgnat/a-ztfiau.adb b/gcc/ada/libgnat/a-ztfiau.adb
new file mode 100644
index 0000000..f26a16a
--- /dev/null
+++ b/gcc/ada/libgnat/a-ztfiau.adb
@@ -0,0 +1,160 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . W I D E _ W I D E _ T E X T _ I O . F I X E D _ I O --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Ada.Wide_Wide_Text_IO.Generic_Aux; use Ada.Wide_Wide_Text_IO.Generic_Aux;
+with Ada.Wide_Wide_Text_IO.Float_Aux; use Ada.Wide_Wide_Text_IO.Float_Aux;
+
+package body Ada.Wide_Wide_Text_IO.Fixed_Aux is
+
+ ---------
+ -- Get --
+ ---------
+
+ function Get
+ (File : File_Type;
+ Width : Field;
+ Num : Int;
+ Den : Int) return Int
+ is
+ Buf : String (1 .. Field'Last);
+ Ptr : aliased Integer;
+ Stop : Integer := 0;
+ Item : Int;
+
+ begin
+ if Width /= 0 then
+ Load_Width (File, Width, Buf, Stop);
+ String_Skip (Buf, Ptr);
+ else
+ Load_Real (File, Buf, Stop);
+ Ptr := 1;
+ end if;
+
+ Item := Scan (Buf, Ptr'Access, Stop, Num, Den);
+ Check_End_Of_Field (Buf, Stop, Ptr, Width);
+ return Item;
+ end Get;
+
+ ----------
+ -- Gets --
+ ----------
+
+ function Gets
+ (From : String;
+ Last : out Positive;
+ Num : Int;
+ Den : Int) return Int
+ is
+ Pos : aliased Integer;
+ Item : Int;
+
+ begin
+ String_Skip (From, Pos);
+ Item := Scan (From, Pos'Access, From'Last, Num, Den);
+ Last := Pos - 1;
+ return Item;
+
+ exception
+ when Constraint_Error =>
+ Last := Pos - 1;
+ raise Data_Error;
+ end Gets;
+
+ ---------
+ -- Put --
+ ---------
+
+ procedure Put
+ (File : File_Type;
+ Item : Int;
+ Fore : Field;
+ Aft : Field;
+ Exp : Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural)
+ is
+ Buf : String (1 .. Field'Last);
+ Ptr : Natural := 0;
+
+ begin
+ Set_Image (Item, Buf, Ptr, Num, Den, For0, Aft0, Fore, Aft, Exp);
+ Put_Item (File, Buf (1 .. Ptr));
+ end Put;
+
+ ----------
+ -- Puts --
+ ----------
+
+ procedure Puts
+ (To : out String;
+ Item : Int;
+ Aft : Field;
+ Exp : Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural)
+ is
+ Buf : String (1 .. Positive'Max (Field'Last, To'Length));
+ Fore : Integer;
+ Ptr : Natural := 0;
+
+ begin
+ -- Compute Fore, allowing for the decimal dot and Aft digits
+
+ Fore := To'Length - 1 - Field'Max (1, Aft);
+
+ -- Allow for Exp and one more for E if exponent present
+
+ if Exp /= 0 then
+ Fore := Fore - 1 - Field'Max (2, Exp);
+ end if;
+
+ -- Make sure we have enough room
+
+ if Fore < 1 + Boolean'Pos (Item < 0) then
+ raise Layout_Error;
+ end if;
+
+ -- Do the conversion and check length of result
+
+ Set_Image (Item, Buf, Ptr, Num, Den, For0, Aft0, Fore, Aft, Exp);
+
+ if Ptr > To'Length then
+ raise Layout_Error;
+ else
+ To := Buf (1 .. Ptr);
+ end if;
+ end Puts;
+
+end Ada.Wide_Wide_Text_IO.Fixed_Aux;
diff --git a/gcc/ada/libgnat/a-ztfiau.ads b/gcc/ada/libgnat/a-ztfiau.ads
new file mode 100644
index 0000000..aac4e42
--- /dev/null
+++ b/gcc/ada/libgnat/a-ztfiau.ads
@@ -0,0 +1,97 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . W I D E _ W I D E _ T E X T _ I O . F I X E D _ I O --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the implementation for Ada.Wide_Wide_Text_IO.Fixed_IO
+-- Routines in this package are identical semantically to those in Fixed_IO,
+-- except that the default parameters have been removed because they are
+-- supplied explicitly by the calls from within these units, and there are
+-- additional Num and Den parameters giving the value of Num'Small, as well
+-- as For0 and Aft0 giving some properties of Num'Small. In addition the Get
+-- routines return the value rather than store it in an Out parameter.
+
+private generic
+ type Int is range <>;
+
+ with function Scan
+ (Str : String;
+ Ptr : not null access Integer;
+ Max : Integer;
+ Num : Int;
+ Den : Int) return Int;
+
+ with procedure Set_Image
+ (V : Int;
+ S : in out String;
+ P : in out Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural;
+ Fore : Natural;
+ Aft : Natural;
+ Exp : Natural);
+
+package Ada.Wide_Wide_Text_IO.Fixed_Aux is
+
+ function Get
+ (File : File_Type;
+ Width : Field;
+ Num : Int;
+ Den : Int) return Int;
+
+ procedure Put
+ (File : File_Type;
+ Item : Int;
+ Fore : Field;
+ Aft : Field;
+ Exp : Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural);
+
+ function Gets
+ (From : String;
+ Last : out Positive;
+ Num : Int;
+ Den : Int) return Int;
+
+ procedure Puts
+ (To : out String;
+ Item : Int;
+ Aft : Field;
+ Exp : Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural);
+
+end Ada.Wide_Wide_Text_IO.Fixed_Aux;
diff --git a/gcc/ada/libgnat/a-ztfiio.adb b/gcc/ada/libgnat/a-ztfiio.adb
index 7c0c95d..c666c7b5 100644
--- a/gcc/ada/libgnat/a-ztfiio.adb
+++ b/gcc/ada/libgnat/a-ztfiio.adb
@@ -2,7 +2,7 @@
-- --
-- GNAT RUN-TIME COMPONENTS --
-- --
--- A D A . T E X T _ I O . W I D E _ T E X T _ I O . F I X E D _ I O --
+-- A D A . W I D E _ W I D E _ T E X T _ I O . F I X E D _ I O --
-- --
-- B o d y --
-- --
@@ -29,16 +29,110 @@
-- --
------------------------------------------------------------------------------
+with Interfaces;
+with Ada.Wide_Wide_Text_IO.Fixed_Aux;
with Ada.Wide_Wide_Text_IO.Float_Aux;
-with System.WCh_Con; use System.WCh_Con;
-with System.WCh_WtS; use System.WCh_WtS;
+with System.Img_Fixed_32; use System.Img_Fixed_32;
+with System.Img_Fixed_64; use System.Img_Fixed_64;
+with System.Val_Fixed_32; use System.Val_Fixed_32;
+with System.Val_Fixed_64; use System.Val_Fixed_64;
+with System.WCh_Con; use System.WCh_Con;
+with System.WCh_WtS; use System.WCh_WtS;
package body Ada.Wide_Wide_Text_IO.Fixed_IO is
- subtype TFT is Ada.Wide_Wide_Text_IO.File_Type;
- -- File type required for calls to routines in Aux
+ -- Note: we still use the floating-point I/O routines for types whose small
+ -- is not the ratio of two sufficiently small integers. This will result in
+ -- inaccuracies for fixed point types that require more precision than is
+ -- available in Long_Long_Float.
- package Aux renames Ada.Wide_Wide_Text_IO.Float_Aux;
+ subtype Int32 is Interfaces.Integer_32; use type Int32;
+ subtype Int64 is Interfaces.Integer_64; use type Int64;
+
+ package Aux32 is new
+ Ada.Wide_Wide_Text_IO.Fixed_Aux (Int32, Scan_Fixed32, Set_Image_Fixed32);
+
+ package Aux64 is new
+ Ada.Wide_Wide_Text_IO.Fixed_Aux (Int64, Scan_Fixed64, Set_Image_Fixed64);
+
+ -- Throughout this generic body, we distinguish between the case where type
+ -- Int32 is OK and where type Int64 is OK. These boolean constants are used
+ -- to test for this, such that only code for the relevant case is included
+ -- in the instance; that's why the computation of their value must be fully
+ -- static (although it is not a static expressions in the RM sense).
+
+ OK_Get_32 : constant Boolean :=
+ Num'Object_Size <= 32
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**31)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**31)
+ or else
+ (Num'Small_Numerator <= 2**27
+ and then Num'Small_Denominator <= 2**27));
+ -- These conditions are derived from the prerequisites of System.Value_F
+
+ OK_Put_32 : constant Boolean :=
+ Num'Object_Size <= 32
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**31)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**31)
+ or else
+ (Num'Small_Numerator < Num'Small_Denominator
+ and then Num'Small_Denominator <= 2**27)
+ or else
+ (Num'Small_Denominator < Num'Small_Numerator
+ and then Num'Small_Numerator <= 2**25));
+ -- These conditions are derived from the prerequisites of System.Image_F
+
+ OK_Get_64 : constant Boolean :=
+ Num'Object_Size <= 64
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**63)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**63)
+ or else
+ (Num'Small_Numerator <= 2**59
+ and then Num'Small_Denominator <= 2**59));
+ -- These conditions are derived from the prerequisites of System.Value_F
+
+ OK_Put_64 : constant Boolean :=
+ Num'Object_Size <= 64
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**63)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**63)
+ or else
+ (Num'Small_Numerator < Num'Small_Denominator
+ and then Num'Small_Denominator <= 2**59)
+ or else
+ (Num'Small_Denominator < Num'Small_Numerator
+ and then Num'Small_Numerator <= 2**53));
+ -- These conditions are derived from the prerequisites of System.Image_F
+
+ E : constant Natural := 63 - 32 * Boolean'Pos (OK_Put_32);
+ -- T'Size - 1 for the selected Int{32,64}
+
+ F0 : constant Natural := 0;
+ F1 : constant Natural :=
+ F0 + 18 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F0) >= 1.0E+18);
+ F2 : constant Natural :=
+ F1 + 9 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F1) >= 1.0E+9);
+ F3 : constant Natural :=
+ F2 + 5 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F2) >= 1.0E+5);
+ F4 : constant Natural :=
+ F3 + 3 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F3) >= 1.0E+3);
+ F5 : constant Natural :=
+ F4 + 2 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F4) >= 1.0E+2);
+ F6 : constant Natural :=
+ F5 + 1 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F5) >= 1.0E+1);
+ -- Binary search for the number of digits - 1 before the decimal point of
+ -- the product 2.0**E * Num'Small.
+
+ For0 : constant Natural := 2 + F6;
+ -- Fore value for the fixed point type whose mantissa is Int{32,64} and
+ -- whose small is Num'Small.
---------
-- Get --
@@ -49,8 +143,22 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
Item : out Num;
Width : Field := 0)
is
+ pragma Unsuppress (Range_Check);
+
begin
- Aux.Get (TFT (File), Long_Long_Float (Item), Width);
+ if OK_Get_32 then
+ Item := Num'Fixed_Value
+ (Aux32.Get (File, Width,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ elsif OK_Get_64 then
+ Item := Num'Fixed_Value
+ (Aux64.Get (File, Width,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ else
+ Float_Aux.Get (File, Long_Long_Float (Item), Width);
+ end if;
exception
when Constraint_Error => raise Data_Error;
@@ -69,6 +177,8 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
Item : out Num;
Last : out Positive)
is
+ pragma Unsuppress (Range_Check);
+
S : constant String := Wide_Wide_String_To_String (From, WCEM_Upper);
-- String on which we do the actual conversion. Note that the method
-- used for wide character encoding is irrelevant, since if there is
@@ -76,7 +186,19 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
-- Aux.Gets will raise Data_Error in any case.
begin
- Aux.Gets (S, Long_Long_Float (Item), Last);
+ if OK_Get_32 then
+ Item := Num'Fixed_Value
+ (Aux32.Gets (S, Last,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ elsif OK_Get_64 then
+ Item := Num'Fixed_Value
+ (Aux64.Gets (S, Last,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ else
+ Float_Aux.Gets (S, Long_Long_Float (Item), Last);
+ end if;
exception
when Constraint_Error => raise Data_Error;
@@ -94,7 +216,17 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
Exp : Field := Default_Exp)
is
begin
- Aux.Put (TFT (File), Long_Long_Float (Item), Fore, Aft, Exp);
+ if OK_Put_32 then
+ Aux32.Put (File, Int32'Integer_Value (Item), Fore, Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ elsif OK_Put_64 then
+ Aux64.Put (File, Int64'Integer_Value (Item), Fore, Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ else
+ Float_Aux.Put (File, Long_Long_Float (Item), Fore, Aft, Exp);
+ end if;
end Put;
procedure Put
@@ -116,7 +248,17 @@ package body Ada.Wide_Wide_Text_IO.Fixed_IO is
S : String (To'First .. To'Last);
begin
- Aux.Puts (S, Long_Long_Float (Item), Aft, Exp);
+ if OK_Put_32 then
+ Aux32.Puts (S, Int32'Integer_Value (Item), Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ elsif OK_Put_64 then
+ Aux64.Puts (S, Int64'Integer_Value (Item), Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ else
+ Float_Aux.Puts (S, Long_Long_Float (Item), Aft, Exp);
+ end if;
for J in S'Range loop
To (J) := Wide_Wide_Character'Val (Character'Pos (S (J)));
diff --git a/gcc/ada/libgnat/a-ztfiio__128.adb b/gcc/ada/libgnat/a-ztfiio__128.adb
new file mode 100644
index 0000000..4704146
--- /dev/null
+++ b/gcc/ada/libgnat/a-ztfiio__128.adb
@@ -0,0 +1,322 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . W I D E _ W I D E _ T E X T _ I O . F I X E D _ I O --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Interfaces;
+with Ada.Wide_Wide_Text_IO.Fixed_Aux;
+with Ada.Wide_Wide_Text_IO.Float_Aux;
+with System.Img_Fixed_32; use System.Img_Fixed_32;
+with System.Img_Fixed_64; use System.Img_Fixed_64;
+with System.Img_Fixed_128; use System.Img_Fixed_128;
+with System.Val_Fixed_32; use System.Val_Fixed_32;
+with System.Val_Fixed_64; use System.Val_Fixed_64;
+with System.Val_Fixed_128; use System.Val_Fixed_128;
+with System.WCh_Con; use System.WCh_Con;
+with System.WCh_WtS; use System.WCh_WtS;
+
+package body Ada.Wide_Wide_Text_IO.Fixed_IO is
+
+ -- Note: we still use the floating-point I/O routines for types whose small
+ -- is not the ratio of two sufficiently small integers. This will result in
+ -- inaccuracies for fixed point types that require more precision than is
+ -- available in Long_Long_Float.
+
+ subtype Int32 is Interfaces.Integer_32; use type Int32;
+ subtype Int64 is Interfaces.Integer_64; use type Int64;
+ subtype Int128 is Interfaces.Integer_128; use type Int128;
+
+ package Aux32 is new
+ Ada.Wide_Wide_Text_IO.Fixed_Aux (Int32, Scan_Fixed32, Set_Image_Fixed32);
+
+ package Aux64 is new
+ Ada.Wide_Wide_Text_IO.Fixed_Aux (Int64, Scan_Fixed64, Set_Image_Fixed64);
+
+ package Aux128 is new
+ Ada.Wide_Wide_Text_IO.Fixed_Aux
+ (Int128, Scan_Fixed128, Set_Image_Fixed128);
+
+ -- Throughout this generic body, we distinguish between the case where type
+ -- Int32 is OK, where type Int64 is OK and where type Int128 is OK. These
+ -- boolean constants are used to test for this, such that only code for the
+ -- relevant case is included in the instance; that's why the computation of
+ -- their value must be fully static (although it is not a static expression
+ -- in the RM sense).
+
+ OK_Get_32 : constant Boolean :=
+ Num'Object_Size <= 32
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**31)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**31)
+ or else
+ (Num'Small_Numerator <= 2**27
+ and then Num'Small_Denominator <= 2**27));
+ -- These conditions are derived from the prerequisites of System.Value_F
+
+ OK_Put_32 : constant Boolean :=
+ Num'Object_Size <= 32
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**31)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**31)
+ or else
+ (Num'Small_Numerator < Num'Small_Denominator
+ and then Num'Small_Denominator <= 2**27)
+ or else
+ (Num'Small_Denominator < Num'Small_Numerator
+ and then Num'Small_Numerator <= 2**25));
+ -- These conditions are derived from the prerequisites of System.Image_F
+
+ OK_Get_64 : constant Boolean :=
+ Num'Object_Size <= 64
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**63)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**63)
+ or else
+ (Num'Small_Numerator <= 2**59
+ and then Num'Small_Denominator <= 2**59));
+ -- These conditions are derived from the prerequisites of System.Value_F
+
+ OK_Put_64 : constant Boolean :=
+ Num'Object_Size <= 64
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**63)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**63)
+ or else
+ (Num'Small_Numerator < Num'Small_Denominator
+ and then Num'Small_Denominator <= 2**59)
+ or else
+ (Num'Small_Denominator < Num'Small_Numerator
+ and then Num'Small_Numerator <= 2**53));
+ -- These conditions are derived from the prerequisites of System.Image_F
+
+ OK_Get_128 : constant Boolean :=
+ Num'Object_Size <= 128
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**127)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**127)
+ or else
+ (Num'Small_Numerator <= 2**123
+ and then Num'Small_Denominator <= 2**123));
+ -- These conditions are derived from the prerequisites of System.Value_F
+
+ OK_Put_128 : constant Boolean :=
+ Num'Object_Size <= 128
+ and then
+ ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**127)
+ or else
+ (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**127)
+ or else
+ (Num'Small_Numerator < Num'Small_Denominator
+ and then Num'Small_Denominator <= 2**123)
+ or else
+ (Num'Small_Denominator < Num'Small_Numerator
+ and then Num'Small_Numerator <= 2**122));
+ -- These conditions are derived from the prerequisites of System.Image_F
+
+ E : constant Natural :=
+ 127 - 64 * Boolean'Pos (OK_Put_64) - 32 * Boolean'Pos (OK_Put_32);
+ -- T'Size - 1 for the selected Int{32,64,128}
+
+ F0 : constant Natural := 0;
+ F1 : constant Natural :=
+ F0 + 38 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F0) >= 1.0E+38);
+ F2 : constant Natural :=
+ F1 + 19 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F1) >= 1.0E+19);
+ F3 : constant Natural :=
+ F2 + 9 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F2) >= 1.0E+9);
+ F4 : constant Natural :=
+ F3 + 5 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F3) >= 1.0E+5);
+ F5 : constant Natural :=
+ F4 + 3 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F4) >= 1.0E+3);
+ F6 : constant Natural :=
+ F5 + 2 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F5) >= 1.0E+2);
+ F7 : constant Natural :=
+ F6 + 1 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F6) >= 1.0E+1);
+ -- Binary search for the number of digits - 1 before the decimal point of
+ -- the product 2.0**E * Num'Small.
+
+ For0 : constant Natural := 2 + F7;
+ -- Fore value for the fixed point type whose mantissa is Int{32,64,128} and
+ -- whose small is Num'Small.
+
+ ---------
+ -- Get --
+ ---------
+
+ procedure Get
+ (File : File_Type;
+ Item : out Num;
+ Width : Field := 0)
+ is
+ pragma Unsuppress (Range_Check);
+
+ begin
+ if OK_Get_32 then
+ Item := Num'Fixed_Value
+ (Aux32.Get (File, Width,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ elsif OK_Get_64 then
+ Item := Num'Fixed_Value
+ (Aux64.Get (File, Width,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ elsif OK_Get_128 then
+ Item := Num'Fixed_Value
+ (Aux128.Get (File, Width,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ else
+ Float_Aux.Get (File, Long_Long_Float (Item), Width);
+ end if;
+
+ exception
+ when Constraint_Error => raise Data_Error;
+ end Get;
+
+ procedure Get
+ (Item : out Num;
+ Width : Field := 0)
+ is
+ begin
+ Get (Current_Input, Item, Width);
+ end Get;
+
+ procedure Get
+ (From : Wide_Wide_String;
+ Item : out Num;
+ Last : out Positive)
+ is
+ pragma Unsuppress (Range_Check);
+
+ S : constant String := Wide_Wide_String_To_String (From, WCEM_Upper);
+ -- String on which we do the actual conversion. Note that the method
+ -- used for wide character encoding is irrelevant, since if there is
+ -- a character outside the Standard.Character range then the call to
+ -- Aux.Gets will raise Data_Error in any case.
+
+ begin
+ if OK_Get_32 then
+ Item := Num'Fixed_Value
+ (Aux32.Gets (S, Last,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ elsif OK_Get_64 then
+ Item := Num'Fixed_Value
+ (Aux64.Gets (S, Last,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ elsif OK_Get_128 then
+ Item := Num'Fixed_Value
+ (Aux128.Gets (S, Last,
+ -Num'Small_Numerator,
+ -Num'Small_Denominator));
+ else
+ Float_Aux.Gets (S, Long_Long_Float (Item), Last);
+ end if;
+
+ exception
+ when Constraint_Error => raise Data_Error;
+ end Get;
+
+ ---------
+ -- Put --
+ ---------
+
+ procedure Put
+ (File : File_Type;
+ Item : Num;
+ Fore : Field := Default_Fore;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ begin
+ if OK_Put_32 then
+ Aux32.Put (File, Int32'Integer_Value (Item), Fore, Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ elsif OK_Put_64 then
+ Aux64.Put (File, Int64'Integer_Value (Item), Fore, Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ elsif OK_Put_128 then
+ Aux128.Put (File, Int128'Integer_Value (Item), Fore, Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ else
+ Float_Aux.Put (File, Long_Long_Float (Item), Fore, Aft, Exp);
+ end if;
+ end Put;
+
+ procedure Put
+ (Item : Num;
+ Fore : Field := Default_Fore;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ begin
+ Put (Current_Output, Item, Fore, Aft, Exp);
+ end Put;
+
+ procedure Put
+ (To : out Wide_Wide_String;
+ Item : Num;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ S : String (To'First .. To'Last);
+
+ begin
+ if OK_Put_32 then
+ Aux32.Puts (S, Int32'Integer_Value (Item), Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ elsif OK_Put_64 then
+ Aux64.Puts (S, Int64'Integer_Value (Item), Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ elsif OK_Put_128 then
+ Aux128.Puts (S, Int128'Integer_Value (Item), Aft, Exp,
+ -Num'Small_Numerator, -Num'Small_Denominator,
+ For0, Num'Aft);
+ else
+ Float_Aux.Puts (S, Long_Long_Float (Item), Aft, Exp);
+ end if;
+
+ for J in S'Range loop
+ To (J) := Wide_Wide_Character'Val (Character'Pos (S (J)));
+ end loop;
+ end Put;
+
+end Ada.Wide_Wide_Text_IO.Fixed_IO;
diff --git a/gcc/ada/libgnat/a-ztflio.adb b/gcc/ada/libgnat/a-ztflio.adb
index fd6bf52..bb52f38 100644
--- a/gcc/ada/libgnat/a-ztflio.adb
+++ b/gcc/ada/libgnat/a-ztflio.adb
@@ -35,9 +35,6 @@ with System.WCh_WtS; use System.WCh_WtS;
package body Ada.Wide_Wide_Text_IO.Float_IO is
- subtype TFT is Ada.Wide_Wide_Text_IO.File_Type;
- -- File type required for calls to routines in Aux
-
package Aux renames Ada.Wide_Wide_Text_IO.Float_Aux;
---------
@@ -50,7 +47,7 @@ package body Ada.Wide_Wide_Text_IO.Float_IO is
Width : Field := 0)
is
begin
- Aux.Get (TFT (File), Long_Long_Float (Item), Width);
+ Aux.Get (File, Long_Long_Float (Item), Width);
exception
when Constraint_Error => raise Data_Error;
@@ -94,7 +91,7 @@ package body Ada.Wide_Wide_Text_IO.Float_IO is
Exp : Field := Default_Exp)
is
begin
- Aux.Put (TFT (File), Long_Long_Float (Item), Fore, Aft, Exp);
+ Aux.Put (File, Long_Long_Float (Item), Fore, Aft, Exp);
end Put;
procedure Put
diff --git a/gcc/ada/libgnat/a-ztinio.adb b/gcc/ada/libgnat/a-ztinio.adb
index ab8741e..4d4708a 100644
--- a/gcc/ada/libgnat/a-ztinio.adb
+++ b/gcc/ada/libgnat/a-ztinio.adb
@@ -65,9 +65,6 @@ package body Ada.Wide_Wide_Text_IO.Integer_IO is
-- Boolean is used to test for these cases and since it is a constant, only
-- code for the relevant case will be included in the instance.
- subtype TFT is Ada.Wide_Wide_Text_IO.File_Type;
- -- File type required for calls to routines in Aux
-
---------
-- Get --
---------
@@ -84,9 +81,9 @@ package body Ada.Wide_Wide_Text_IO.Integer_IO is
begin
if Need_LLI then
- Aux_LLI.Get (TFT (File), Long_Long_Integer (Item), Width);
+ Aux_LLI.Get (File, Long_Long_Integer (Item), Width);
else
- Aux_Int.Get (TFT (File), Integer (Item), Width);
+ Aux_Int.Get (File, Integer (Item), Width);
end if;
exception
@@ -140,9 +137,9 @@ package body Ada.Wide_Wide_Text_IO.Integer_IO is
is
begin
if Need_LLI then
- Aux_LLI.Put (TFT (File), Long_Long_Integer (Item), Width, Base);
+ Aux_LLI.Put (File, Long_Long_Integer (Item), Width, Base);
else
- Aux_Int.Put (TFT (File), Integer (Item), Width, Base);
+ Aux_Int.Put (File, Integer (Item), Width, Base);
end if;
end Put;
diff --git a/gcc/ada/libgnat/a-ztinio__128.adb b/gcc/ada/libgnat/a-ztinio__128.adb
index c809eeb..560539a9 100644
--- a/gcc/ada/libgnat/a-ztinio__128.adb
+++ b/gcc/ada/libgnat/a-ztinio__128.adb
@@ -79,9 +79,6 @@ package body Ada.Wide_Wide_Text_IO.Integer_IO is
-- are used to test for these cases and since they are constant, only code
-- for the relevant case will be included in the instance.
- subtype TFT is Ada.Wide_Wide_Text_IO.File_Type;
- -- File type required for calls to routines in Aux
-
---------
-- Get --
---------
@@ -98,11 +95,11 @@ package body Ada.Wide_Wide_Text_IO.Integer_IO is
begin
if Need_LLLI then
- Aux_LLLI.Get (TFT (File), Long_Long_Long_Integer (Item), Width);
+ Aux_LLLI.Get (File, Long_Long_Long_Integer (Item), Width);
elsif Need_LLI then
- Aux_LLI.Get (TFT (File), Long_Long_Integer (Item), Width);
+ Aux_LLI.Get (File, Long_Long_Integer (Item), Width);
else
- Aux_Int.Get (TFT (File), Integer (Item), Width);
+ Aux_Int.Get (File, Integer (Item), Width);
end if;
exception
@@ -158,11 +155,11 @@ package body Ada.Wide_Wide_Text_IO.Integer_IO is
is
begin
if Need_LLLI then
- Aux_LLLI.Put (TFT (File), Long_Long_Long_Integer (Item), Width, Base);
+ Aux_LLLI.Put (File, Long_Long_Long_Integer (Item), Width, Base);
elsif Need_LLI then
- Aux_LLI.Put (TFT (File), Long_Long_Integer (Item), Width, Base);
+ Aux_LLI.Put (File, Long_Long_Integer (Item), Width, Base);
else
- Aux_Int.Put (TFT (File), Integer (Item), Width, Base);
+ Aux_Int.Put (File, Integer (Item), Width, Base);
end if;
end Put;
diff --git a/gcc/ada/libgnat/a-ztmoio.adb b/gcc/ada/libgnat/a-ztmoio.adb
index d2f81e2..67087c6 100644
--- a/gcc/ada/libgnat/a-ztmoio.adb
+++ b/gcc/ada/libgnat/a-ztmoio.adb
@@ -65,9 +65,6 @@ package body Ada.Wide_Wide_Text_IO.Modular_IO is
-- Boolean is used to test for these cases and since it is a constant, only
-- code for the relevant case will be included in the instance.
- subtype TFT is Ada.Wide_Wide_Text_IO.File_Type;
- -- File type required for calls to routines in Aux
-
---------
-- Get --
---------
@@ -83,9 +80,9 @@ package body Ada.Wide_Wide_Text_IO.Modular_IO is
begin
if Need_LLU then
- Aux_LLU.Get (TFT (File), Long_Long_Unsigned (Item), Width);
+ Aux_LLU.Get (File, Long_Long_Unsigned (Item), Width);
else
- Aux_Uns.Get (TFT (File), Unsigned (Item), Width);
+ Aux_Uns.Get (File, Unsigned (Item), Width);
end if;
exception
@@ -138,9 +135,9 @@ package body Ada.Wide_Wide_Text_IO.Modular_IO is
is
begin
if Need_LLU then
- Aux_LLU.Put (TFT (File), Long_Long_Unsigned (Item), Width, Base);
+ Aux_LLU.Put (File, Long_Long_Unsigned (Item), Width, Base);
else
- Aux_Uns.Put (TFT (File), Unsigned (Item), Width, Base);
+ Aux_Uns.Put (File, Unsigned (Item), Width, Base);
end if;
end Put;
diff --git a/gcc/ada/libgnat/a-ztmoio__128.adb b/gcc/ada/libgnat/a-ztmoio__128.adb
index e6e11de..71626cc 100644
--- a/gcc/ada/libgnat/a-ztmoio__128.adb
+++ b/gcc/ada/libgnat/a-ztmoio__128.adb
@@ -79,9 +79,6 @@ package body Ada.Wide_Wide_Text_IO.Modular_IO is
-- are used to test for these cases and since they are constant, only code
-- for the relevant case will be included in the instance.
- subtype TFT is Ada.Wide_Wide_Text_IO.File_Type;
- -- File type required for calls to routines in Aux
-
---------
-- Get --
---------
@@ -99,9 +96,9 @@ package body Ada.Wide_Wide_Text_IO.Modular_IO is
if Need_LLLU then
Aux_LLLU.Get (File, Long_Long_Long_Unsigned (Item), Width);
elsif Need_LLU then
- Aux_LLU.Get (TFT (File), Long_Long_Unsigned (Item), Width);
+ Aux_LLU.Get (File, Long_Long_Unsigned (Item), Width);
else
- Aux_Uns.Get (TFT (File), Unsigned (Item), Width);
+ Aux_Uns.Get (File, Unsigned (Item), Width);
end if;
exception
@@ -158,9 +155,9 @@ package body Ada.Wide_Wide_Text_IO.Modular_IO is
if Need_LLLU then
Aux_LLLU.Put (File, Long_Long_Long_Unsigned (Item), Width, Base);
elsif Need_LLU then
- Aux_LLU.Put (TFT (File), Long_Long_Unsigned (Item), Width, Base);
+ Aux_LLU.Put (File, Long_Long_Unsigned (Item), Width, Base);
else
- Aux_Uns.Put (TFT (File), Unsigned (Item), Width, Base);
+ Aux_Uns.Put (File, Unsigned (Item), Width, Base);
end if;
end Put;
diff --git a/gcc/ada/libgnat/g-rannum.adb b/gcc/ada/libgnat/g-rannum.adb
index b7ef7d1..9c6693b 100644
--- a/gcc/ada/libgnat/g-rannum.adb
+++ b/gcc/ada/libgnat/g-rannum.adb
@@ -58,6 +58,8 @@ is
new Ada.Unchecked_Conversion (Unsigned_32, Integer_32);
function To_Signed is
new Ada.Unchecked_Conversion (Unsigned_64, Integer_64);
+ function To_Signed is
+ new Ada.Unchecked_Conversion (Unsigned_128, Integer_128);
------------------
-- Insert_Image --
@@ -98,12 +100,37 @@ is
Min : Result_Subtype := Default_Min;
Max : Result_Subtype := Result_Subtype'Last) return Result_Subtype
is
- subtype IntV is Integer_64 range
- Integer_64'Integer_Value (Min) ..
- Integer_64'Integer_Value (Max);
- function R is new Random_Discrete (Integer_64, IntV'First);
begin
- return Result_Subtype'Fixed_Value (R (Gen, IntV'First, IntV'Last));
+ if Result_Subtype'Base'Size > 64 then
+ declare
+ subtype IntV is Integer_128 range
+ Integer_128'Integer_Value (Min) ..
+ Integer_128'Integer_Value (Max);
+ function R is new Random_Discrete (Integer_128, IntV'First);
+ begin
+ return Result_Subtype'Fixed_Value (R (Gen, IntV'First, IntV'Last));
+ end;
+
+ elsif Result_Subtype'Base'Size > 32 then
+ declare
+ subtype IntV is Integer_64 range
+ Integer_64'Integer_Value (Min) ..
+ Integer_64'Integer_Value (Max);
+ function R is new Random_Discrete (Integer_64, IntV'First);
+ begin
+ return Result_Subtype'Fixed_Value (R (Gen, IntV'First, IntV'Last));
+ end;
+
+ else
+ declare
+ subtype IntV is Integer_32 range
+ Integer_32'Integer_Value (Min) ..
+ Integer_32'Integer_Value (Max);
+ function R is new Random_Discrete (Integer_32, IntV'First);
+ begin
+ return Result_Subtype'Fixed_Value (R (Gen, IntV'First, IntV'Last));
+ end;
+ end if;
end Random_Decimal_Fixed;
---------------------------
@@ -115,12 +142,37 @@ is
Min : Result_Subtype := Default_Min;
Max : Result_Subtype := Result_Subtype'Last) return Result_Subtype
is
- subtype IntV is Integer_64 range
- Integer_64'Integer_Value (Min) ..
- Integer_64'Integer_Value (Max);
- function R is new Random_Discrete (Integer_64, IntV'First);
begin
- return Result_Subtype'Fixed_Value (R (Gen, IntV'First, IntV'Last));
+ if Result_Subtype'Base'Size > 64 then
+ declare
+ subtype IntV is Integer_128 range
+ Integer_128'Integer_Value (Min) ..
+ Integer_128'Integer_Value (Max);
+ function R is new Random_Discrete (Integer_128, IntV'First);
+ begin
+ return Result_Subtype'Fixed_Value (R (Gen, IntV'First, IntV'Last));
+ end;
+
+ elsif Result_Subtype'Base'Size > 32 then
+ declare
+ subtype IntV is Integer_64 range
+ Integer_64'Integer_Value (Min) ..
+ Integer_64'Integer_Value (Max);
+ function R is new Random_Discrete (Integer_64, IntV'First);
+ begin
+ return Result_Subtype'Fixed_Value (R (Gen, IntV'First, IntV'Last));
+ end;
+
+ else
+ declare
+ subtype IntV is Integer_32 range
+ Integer_32'Integer_Value (Min) ..
+ Integer_32'Integer_Value (Max);
+ function R is new Random_Discrete (Integer_32, IntV'First);
+ begin
+ return Result_Subtype'Fixed_Value (R (Gen, IntV'First, IntV'Last));
+ end;
+ end if;
end Random_Ordinary_Fixed;
------------
@@ -147,9 +199,9 @@ is
return Random (Gen.Rep);
end Random;
- function Random (Gen : Generator) return Integer_64 is
+ function Random (Gen : Generator) return Interfaces.Unsigned_128 is
begin
- return To_Signed (Unsigned_64'(Random (Gen)));
+ return Random (Gen.Rep);
end Random;
function Random (Gen : Generator) return Integer_32 is
@@ -157,6 +209,16 @@ is
return To_Signed (Unsigned_32'(Random (Gen)));
end Random;
+ function Random (Gen : Generator) return Integer_64 is
+ begin
+ return To_Signed (Unsigned_64'(Random (Gen)));
+ end Random;
+
+ function Random (Gen : Generator) return Integer_128 is
+ begin
+ return To_Signed (Unsigned_128'(Random (Gen)));
+ end Random;
+
function Random (Gen : Generator) return Long_Integer is
function Random_Long_Integer is new Random_Discrete (Long_Integer);
begin
diff --git a/gcc/ada/libgnat/g-rannum.ads b/gcc/ada/libgnat/g-rannum.ads
index 5b633ff..f795ae0 100644
--- a/gcc/ada/libgnat/g-rannum.ads
+++ b/gcc/ada/libgnat/g-rannum.ads
@@ -69,6 +69,8 @@ is
function Random (Gen : Generator) return Interfaces.Unsigned_32;
function Random (Gen : Generator) return Interfaces.Integer_64;
function Random (Gen : Generator) return Interfaces.Unsigned_64;
+ function Random (Gen : Generator) return Interfaces.Integer_128;
+ function Random (Gen : Generator) return Interfaces.Unsigned_128;
function Random (Gen : Generator) return Integer;
function Random (Gen : Generator) return Long_Integer;
-- Return pseudo-random numbers uniformly distributed on T'First .. T'Last
diff --git a/gcc/ada/libgnat/g-sercom__linux.adb b/gcc/ada/libgnat/g-sercom__linux.adb
index 7d93e57..10b456f 100644
--- a/gcc/ada/libgnat/g-sercom__linux.adb
+++ b/gcc/ada/libgnat/g-sercom__linux.adb
@@ -31,14 +31,13 @@
-- This is the GNU/Linux implementation of this package
-with Ada.Streams; use Ada.Streams;
-with Ada; use Ada;
+with Ada.Streams; use Ada.Streams;
with System; use System;
with System.Communication; use System.Communication;
with System.CRTL; use System.CRTL;
-with GNAT.OS_Lib; use GNAT.OS_Lib;
+with GNAT.OS_Lib; use GNAT.OS_Lib;
package body GNAT.Serial_Communications is
@@ -53,34 +52,6 @@ package body GNAT.Serial_Communications is
function fcntl (fd : int; cmd : int; value : int) return int;
pragma Import (C, fcntl, "fcntl");
- C_Data_Rate : constant array (Data_Rate) of unsigned :=
- (B75 => OSC.B75,
- B110 => OSC.B110,
- B150 => OSC.B150,
- B300 => OSC.B300,
- B600 => OSC.B600,
- B1200 => OSC.B1200,
- B2400 => OSC.B2400,
- B4800 => OSC.B4800,
- B9600 => OSC.B9600,
- B19200 => OSC.B19200,
- B38400 => OSC.B38400,
- B57600 => OSC.B57600,
- B115200 => OSC.B115200,
- B230400 => OSC.B230400,
- B460800 => OSC.B460800,
- B500000 => OSC.B500000,
- B576000 => OSC.B576000,
- B921600 => OSC.B921600,
- B1000000 => OSC.B1000000,
- B1152000 => OSC.B1152000,
- B1500000 => OSC.B1500000,
- B2000000 => OSC.B2000000,
- B2500000 => OSC.B2500000,
- B3000000 => OSC.B3000000,
- B3500000 => OSC.B3500000,
- B4000000 => OSC.B4000000);
-
C_Bits : constant array (Data_Bits) of unsigned :=
(CS7 => OSC.CS7, CS8 => OSC.CS8);
@@ -230,8 +201,7 @@ package body GNAT.Serial_Communications is
-- Change settings now
- Current.c_cflag := C_Data_Rate (Rate)
- or C_Bits (Bits)
+ Current.c_cflag := C_Bits (Bits)
or C_Stop_Bits (Stop_Bits)
or C_Parity (Parity)
or CREAD;
diff --git a/gcc/ada/libgnat/s-arit32.adb b/gcc/ada/libgnat/s-arit32.adb
new file mode 100644
index 0000000..742f2e1
--- /dev/null
+++ b/gcc/ada/libgnat/s-arit32.adb
@@ -0,0 +1,182 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . A R I T H _ 3 2 --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Ada.Unchecked_Conversion;
+
+package body System.Arith_32 is
+
+ pragma Suppress (Overflow_Check);
+ pragma Suppress (Range_Check);
+
+ subtype Uns32 is Interfaces.Unsigned_32;
+ subtype Uns64 is Interfaces.Unsigned_64;
+
+ use Interfaces;
+
+ function To_Int is new Ada.Unchecked_Conversion (Uns32, Int32);
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ function "abs" (X : Int32) return Uns32 is
+ (if X = Int32'First
+ then 2**31
+ else Uns32 (Int32'(abs X)));
+ -- Convert absolute value of X to unsigned. Note that we can't just use
+ -- the expression of the Else since it overflows for X = Int32'First.
+
+ function Hi (A : Uns64) return Uns32 is (Uns32 (Shift_Right (A, 32)));
+ -- High order half of 64-bit value
+
+ function To_Neg_Int (A : Uns32) return Int32;
+ -- Convert to negative integer equivalent. If the input is in the range
+ -- 0 .. 2**31, then the corresponding nonpositive signed integer (obtained
+ -- by negating the given value) is returned, otherwise constraint error is
+ -- raised.
+
+ function To_Pos_Int (A : Uns32) return Int32;
+ -- Convert to positive integer equivalent. If the input is in the range
+ -- 0 .. 2**31 - 1, then the corresponding nonnegative signed integer is
+ -- returned, otherwise constraint error is raised.
+
+ procedure Raise_Error;
+ pragma No_Return (Raise_Error);
+ -- Raise constraint error with appropriate message
+
+ -----------------
+ -- Raise_Error --
+ -----------------
+
+ procedure Raise_Error is
+ begin
+ raise Constraint_Error with "32-bit arithmetic overflow";
+ end Raise_Error;
+
+ -------------------
+ -- Scaled_Divide --
+ -------------------
+
+ procedure Scaled_Divide32
+ (X, Y, Z : Int32;
+ Q, R : out Int32;
+ Round : Boolean)
+ is
+ Xu : constant Uns32 := abs X;
+ Yu : constant Uns32 := abs Y;
+ Zu : constant Uns32 := abs Z;
+
+ D : Uns64;
+ -- The dividend
+
+ Qu : Uns32;
+ Ru : Uns32;
+ -- Unsigned quotient and remainder
+
+ begin
+ -- First do the 64-bit multiplication
+
+ D := Uns64 (Xu) * Uns64 (Yu);
+
+ -- If dividend is too large, raise error
+
+ if Hi (D) >= Zu then
+ Raise_Error;
+
+ -- Then do the 64-bit division
+
+ else
+ Qu := Uns32 (D / Uns64 (Zu));
+ Ru := Uns32 (D rem Uns64 (Zu));
+ end if;
+
+ -- Deal with rounding case
+
+ if Round and then Ru > (Zu - Uns32'(1)) / Uns32'(2) then
+
+ -- Protect against wrapping around when rounding, by signaling
+ -- an overflow when the quotient is too large.
+
+ if Qu = Uns32'Last then
+ Raise_Error;
+ end if;
+
+ Qu := Qu + Uns32'(1);
+ end if;
+
+ -- Set final signs (RM 4.5.5(27-30))
+
+ -- Case of dividend (X * Y) sign positive
+
+ if (X >= 0 and then Y >= 0) or else (X < 0 and then Y < 0) then
+ R := To_Pos_Int (Ru);
+ Q := (if Z > 0 then To_Pos_Int (Qu) else To_Neg_Int (Qu));
+
+ -- Case of dividend (X * Y) sign negative
+
+ else
+ R := To_Neg_Int (Ru);
+ Q := (if Z > 0 then To_Neg_Int (Qu) else To_Pos_Int (Qu));
+ end if;
+ end Scaled_Divide32;
+
+ ----------------
+ -- To_Neg_Int --
+ ----------------
+
+ function To_Neg_Int (A : Uns32) return Int32 is
+ R : constant Int32 :=
+ (if A = 2**31 then Int32'First else -To_Int (A));
+ -- Note that we can't just use the expression of the Else, because it
+ -- overflows for A = 2**31.
+ begin
+ if R <= 0 then
+ return R;
+ else
+ Raise_Error;
+ end if;
+ end To_Neg_Int;
+
+ ----------------
+ -- To_Pos_Int --
+ ----------------
+
+ function To_Pos_Int (A : Uns32) return Int32 is
+ R : constant Int32 := To_Int (A);
+ begin
+ if R >= 0 then
+ return R;
+ else
+ Raise_Error;
+ end if;
+ end To_Pos_Int;
+
+end System.Arith_32;
diff --git a/gcc/ada/libgnat/s-arit32.ads b/gcc/ada/libgnat/s-arit32.ads
new file mode 100644
index 0000000..5656855
--- /dev/null
+++ b/gcc/ada/libgnat/s-arit32.ads
@@ -0,0 +1,55 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . A R I T H _ 3 2 --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This unit provides software routines for doing arithmetic on 32-bit
+-- signed integer values in cases where either overflow checking is
+-- required, or intermediate results are longer than 32 bits.
+
+with Interfaces;
+
+package System.Arith_32 is
+ pragma Pure;
+
+ subtype Int32 is Interfaces.Integer_32;
+
+ procedure Scaled_Divide32
+ (X, Y, Z : Int32;
+ Q, R : out Int32;
+ Round : Boolean);
+ -- Performs the division of (X * Y) / Z, storing the quotient in Q
+ -- and the remainder in R. Constraint_Error is raised if Z is zero,
+ -- or if the quotient does not fit in 32 bits. Round indicates if
+ -- the result should be rounded. If Round is False, then Q, R are
+ -- the normal quotient and remainder from a truncating division.
+ -- If Round is True, then Q is the rounded quotient. The remainder
+ -- R is not affected by the setting of the Round flag.
+
+end System.Arith_32;
diff --git a/gcc/ada/libgnat/s-bitfie.ads b/gcc/ada/libgnat/s-bitfie.ads
index 4f17a9c..21b7294 100644
--- a/gcc/ada/libgnat/s-bitfie.ads
+++ b/gcc/ada/libgnat/s-bitfie.ads
@@ -47,6 +47,12 @@ package System.Bitfields is
pragma Provide_Shift_Operators (Val_2);
type Val is mod 2**Val_Bits with Alignment => Val_Bytes;
+ -- ??? It turns out that enabling checks on the instantiation of
+ -- System.Bitfield_Utils.G makes a latent visibility bug appear on strict
+ -- alignment platforms related to alignment checks. Work around it by
+ -- suppressing these checks explicitly.
+
+ pragma Suppress (Alignment_Check);
package Utils is new System.Bitfield_Utils.G (Val, Val_2);
procedure Copy_Bitfield
diff --git a/gcc/ada/libgnat/s-bituti.adb b/gcc/ada/libgnat/s-bituti.adb
index e3bd70a..ef839a8 100644
--- a/gcc/ada/libgnat/s-bituti.adb
+++ b/gcc/ada/libgnat/s-bituti.adb
@@ -317,6 +317,7 @@ package body System.Bitfield_Utils is
Get_Val_2 (S_Addr, S_Off, Initial_Size);
Initial_Val : constant Val :=
Get_Bitfield (Initial_Val_2, S_Off, Initial_Size);
+
begin
Set_Bitfield
(Initial_Val, D_Addr, D_Off, Initial_Size);
diff --git a/gcc/ada/libgnat/s-fode128.ads b/gcc/ada/libgnat/s-fode128.ads
new file mode 100644
index 0000000..200a020
--- /dev/null
+++ b/gcc/ada/libgnat/s-fode128.ads
@@ -0,0 +1,48 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . F O R E _ D E C I M A L _ 1 2 8 --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the routine used for the 'Fore attribute for decimal
+-- fixed point types up to 128-bit mantissa.
+
+with Interfaces;
+with System.Fore_D;
+
+package System.Fore_Decimal_128 is
+ pragma Pure;
+
+ subtype Int128 is Interfaces.Integer_128;
+
+ package Impl is new Fore_D (Int128);
+
+ function Fore_Decimal128 (Lo, Hi : Int128; Scale : Integer) return Natural
+ renames Impl.Fore_Decimal;
+
+end System.Fore_Decimal_128;
diff --git a/gcc/ada/libgnat/s-fode32.ads b/gcc/ada/libgnat/s-fode32.ads
new file mode 100644
index 0000000..15c07a4
--- /dev/null
+++ b/gcc/ada/libgnat/s-fode32.ads
@@ -0,0 +1,48 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . F O R E _ D E C I M A L _ 3 2 --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the routine used for the 'Fore attribute for decimal
+-- fixed point types up to 32-bit mantissa.
+
+with Interfaces;
+with System.Fore_D;
+
+package System.Fore_Decimal_32 is
+ pragma Pure;
+
+ subtype Int32 is Interfaces.Integer_32;
+
+ package Impl is new Fore_D (Int32);
+
+ function Fore_Decimal32 (Lo, Hi : Int32; Scale : Integer) return Natural
+ renames Impl.Fore_Decimal;
+
+end System.Fore_Decimal_32;
diff --git a/gcc/ada/libgnat/s-fode64.ads b/gcc/ada/libgnat/s-fode64.ads
new file mode 100644
index 0000000..7e98185
--- /dev/null
+++ b/gcc/ada/libgnat/s-fode64.ads
@@ -0,0 +1,48 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . F O R E _ D E C I M A L _ 6 4 --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the routine used for the 'Fore attribute for decimal
+-- fixed point types up to 64-bit mantissa.
+
+with Interfaces;
+with System.Fore_D;
+
+package System.Fore_Decimal_64 is
+ pragma Pure;
+
+ subtype Int64 is Interfaces.Integer_64;
+
+ package Impl is new Fore_D (Int64);
+
+ function Fore_Decimal64 (Lo, Hi : Int64; Scale : Integer) return Natural
+ renames Impl.Fore_Decimal;
+
+end System.Fore_Decimal_64;
diff --git a/gcc/ada/libgnat/s-fofi128.ads b/gcc/ada/libgnat/s-fofi128.ads
new file mode 100644
index 0000000..aaa117f
--- /dev/null
+++ b/gcc/ada/libgnat/s-fofi128.ads
@@ -0,0 +1,50 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . F O F I _ 1 2 8 --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the routine used for the 'Fore attribute for ordinary
+-- fixed point types up to 128-bit small and mantissa.
+
+with Interfaces;
+with System.Arith_128;
+with System.Fore_F;
+
+package System.Fore_Fixed_128 is
+ pragma Pure;
+
+ subtype Int128 is Interfaces.Integer_128;
+
+ package Impl is new Fore_F (Int128, Arith_128.Scaled_Divide128);
+
+ function Fore_Fixed128
+ (Lo, Hi, Num, Den : Int128; Scale : Integer) return Natural
+ renames Impl.Fore_Fixed;
+
+end System.Fore_Fixed_128;
diff --git a/gcc/ada/libgnat/s-fofi32.ads b/gcc/ada/libgnat/s-fofi32.ads
new file mode 100644
index 0000000..cf94fb8
--- /dev/null
+++ b/gcc/ada/libgnat/s-fofi32.ads
@@ -0,0 +1,50 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . F O R E _ F I X E D _ 3 2 --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the routine used for the 'Fore attribute for ordinary
+-- fixed point types up to 32-bit small and mantissa.
+
+with Interfaces;
+with System.Arith_32;
+with System.Fore_F;
+
+package System.Fore_Fixed_32 is
+ pragma Pure;
+
+ subtype Int32 is Interfaces.Integer_32;
+
+ package Impl is new Fore_F (Int32, Arith_32.Scaled_Divide32);
+
+ function Fore_Fixed32
+ (Lo, Hi, Num, Den : Int32; Scale : Integer) return Natural
+ renames Impl.Fore_Fixed;
+
+end System.Fore_Fixed_32;
diff --git a/gcc/ada/libgnat/s-fofi64.ads b/gcc/ada/libgnat/s-fofi64.ads
new file mode 100644
index 0000000..cdde204
--- /dev/null
+++ b/gcc/ada/libgnat/s-fofi64.ads
@@ -0,0 +1,50 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . F O R E _ F I X E D _ 6 4 --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the routine used for the 'Fore attribute for ordinary
+-- fixed point types up to 64-bit small and mantissa.
+
+with Interfaces;
+with System.Arith_64;
+with System.Fore_F;
+
+package System.Fore_Fixed_64 is
+ pragma Pure;
+
+ subtype Int64 is Interfaces.Integer_64;
+
+ package Impl is new Fore_F (Int64, Arith_64.Scaled_Divide64);
+
+ function Fore_Fixed64
+ (Lo, Hi, Num, Den : Int64; Scale : Integer) return Natural
+ renames Impl.Fore_Fixed;
+
+end System.Fore_Fixed_64;
diff --git a/gcc/ada/libgnat/s-fore_d.adb b/gcc/ada/libgnat/s-fore_d.adb
new file mode 100644
index 0000000..1141c67
--- /dev/null
+++ b/gcc/ada/libgnat/s-fore_d.adb
@@ -0,0 +1,62 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . F O R E _ D --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package body System.Fore_D is
+
+ ------------------
+ -- Fore_Decimal --
+ ------------------
+
+ function Fore_Decimal (Lo, Hi : Int; Scale : Integer) return Natural is
+
+ function Negative_Abs (Val : Int) return Int is
+ (if Val <= 0 then Val else -Val);
+ -- Return the opposite of the absolute value of Val
+
+ T : Int := Int'Min (Negative_Abs (Lo), Negative_Abs (Hi));
+ F : Natural;
+
+ begin
+ -- Initial value of 2 allows for sign and mandatory single digit
+
+ F := 2;
+
+ -- Loop to increase Fore as needed to include full range of values
+
+ while T <= -10 loop
+ T := T / 10;
+ F := F + 1;
+ end loop;
+
+ return Natural'Max (F - Scale, 2);
+ end Fore_Decimal;
+
+end System.Fore_D;
diff --git a/gcc/ada/libgnat/s-fore_d.ads b/gcc/ada/libgnat/s-fore_d.ads
new file mode 100644
index 0000000..25e3449
--- /dev/null
+++ b/gcc/ada/libgnat/s-fore_d.ads
@@ -0,0 +1,47 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . F O R E _ D --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the routine used for the Fore attribute of decimal
+-- fixed point types.
+
+generic
+
+ type Int is range <>;
+
+package System.Fore_D is
+ pragma Pure;
+
+ function Fore_Decimal (Lo, Hi : Int; Scale : Integer) return Natural;
+ -- Compute Fore attribute value for a decimal fixed point type. The
+ -- parameters are the low and high bounds (in units of delta) and the
+ -- scale.
+
+end System.Fore_D;
diff --git a/gcc/ada/libgnat/s-fore_f.adb b/gcc/ada/libgnat/s-fore_f.adb
new file mode 100644
index 0000000..c9c476d
--- /dev/null
+++ b/gcc/ada/libgnat/s-fore_f.adb
@@ -0,0 +1,136 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . F O R E _ F --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package body System.Fore_F is
+
+ Maxdigs : constant Natural := Int'Width - 2;
+ -- Maximum number of decimal digits that can be represented in an Int.
+ -- The "-2" accounts for the sign and one extra digit, since we need the
+ -- maximum number of 9's that can be represented, e.g. for the 64-bit case,
+ -- Integer_64'Width is 20 since the maximum value is approximately 9.2E+18
+ -- and has 19 digits, but the maximum number of 9's that can be represented
+ -- in Integer_64 is only 18.
+
+ -- The first prerequisite of the implementation is that the scaled divide
+ -- does not overflow, which means that the absolute value of the bounds of
+ -- the subtype must be smaller than 10**Maxdigs * 2**(Int'Size - 1).
+ -- Otherwise Constraint_Error is raised by the scaled divide operation.
+
+ -- The second prerequisite is that the computation of the operands does not
+ -- overflow, which means that, if the small is larger than 1, it is either
+ -- an integer or its numerator and denominator must be both smaller than
+ -- the power 10**(Maxdigs - 1).
+
+ ----------------
+ -- Fore_Fixed --
+ ----------------
+
+ function Fore_Fixed (Lo, Hi, Num, Den : Int; Scale : Integer) return Natural
+ is
+ pragma Assert (Num < 0 and then Den < 0);
+ -- Accept only negative numbers to allow -2**(Int'Size - 1)
+
+ function Negative_Abs (Val : Int) return Int is
+ (if Val <= 0 then Val else -Val);
+ -- Return the opposite of the absolute value of Val
+
+ T : Int := Int'Min (Negative_Abs (Lo), Negative_Abs (Hi));
+ F : Natural;
+
+ Q, R : Int;
+
+ begin
+ -- Initial value of 2 allows for sign and mandatory single digit
+
+ F := 2;
+
+ -- The easy case is when Num is not larger than Den in magnitude,
+ -- i.e. if S = Num / Den, then S <= 1, in which case we can just
+ -- compute the product Q = T * S.
+
+ if Num >= Den then
+ Scaled_Divide (T, Num, Den, Q, R, Round => False);
+ T := Q;
+
+ -- Otherwise S > 1 and thus Scale <= 0, compute Q and R such that
+
+ -- T * Num = Q * (Den * 10**(-D)) + R
+
+ -- with
+
+ -- D = Integer'Max (-Maxdigs, Scale - 1)
+
+ -- then reason on Q if it is non-zero or else on R / Den.
+
+ -- This works only if Den * 10**(-D) does not overflow, which is true
+ -- if Den = 1. Suppose that Num corresponds to the maximum value of -D,
+ -- i.e. Maxdigs and 10**(-D) = 10**Maxdigs. If you change Den into 10,
+ -- then S becomes 10 times smaller and, therefore, Scale is incremented
+ -- by 1, which means that -D is decremented by 1 provided that Scale was
+ -- initially not smaller than 1 - Maxdigs, so the multiplication still
+ -- does not overflow. But you need to reach 10 to trigger this effect,
+ -- which means that a leeway of 10 is required, so let's restrict this
+ -- to a Num for which 10**(-D) <= 10**(Maxdigs - 1). To sum up, if S is
+ -- the ratio of two integers with
+
+ -- 1 < Den < Num <= B
+
+ -- where B is a fixed limit, then the multiplication does not overflow.
+ -- B can be taken as the largest integer Small such that D = 1 - Maxdigs
+ -- i.e. such that Scale = 2 - Maxdigs, which is 10**(Maxdigs - 1) - 1.
+
+ else
+ declare
+ D : constant Integer := Integer'Max (-Maxdigs, Scale - 1);
+
+ begin
+ Scaled_Divide (T, Num, Den * 10**(-D), Q, R, Round => False);
+
+ if Q /= 0 then
+ T := Q;
+ F := F - D;
+ else
+ T := R / Den;
+ end if;
+ end;
+ end if;
+
+ -- Loop to increase Fore as needed to include full range of values
+
+ while T <= -10 or else T >= 10 loop
+ T := T / 10;
+ F := F + 1;
+ end loop;
+
+ return F;
+ end Fore_Fixed;
+
+end System.Fore_F;
diff --git a/gcc/ada/libgnat/s-fore_f.ads b/gcc/ada/libgnat/s-fore_f.ads
new file mode 100644
index 0000000..cf6d983
--- /dev/null
+++ b/gcc/ada/libgnat/s-fore_f.ads
@@ -0,0 +1,54 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . F O R E _ F --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the routine used for the Fore attribute of ordinary
+-- fixed point types whose Small is the ratio of two Int values.
+
+generic
+
+ type Int is range <>;
+
+ with procedure Scaled_Divide
+ (X, Y, Z : Int;
+ Q, R : out Int;
+ Round : Boolean);
+
+package System.Fore_F is
+ pragma Pure;
+
+ function Fore_Fixed
+ (Lo, Hi, Num, Den : Int; Scale : Integer) return Natural;
+ -- Compute Fore attribute value for an ordinary fixed point type. The
+ -- parameters are the low and high bounds (in units of small), the small
+ -- Num/Den and the associated scale, which is the smallest integer N such
+ -- that 10**N * (Num/Den) is greater or equal to 1, if it is nonpositive.
+
+end System.Fore_F;
diff --git a/gcc/ada/libgnat/s-fore.adb b/gcc/ada/libgnat/s-forrea.adb
index 2a4aa81..cb74dc6 100644
--- a/gcc/ada/libgnat/s-fore.adb
+++ b/gcc/ada/libgnat/s-forrea.adb
@@ -2,7 +2,7 @@
-- --
-- GNAT RUN-TIME COMPONENTS --
-- --
--- S Y S T E M . F O R E --
+-- S Y S T E M . F O R E _ R E A L --
-- --
-- B o d y --
-- --
@@ -29,28 +29,29 @@
-- --
------------------------------------------------------------------------------
-package body System.Fore is
+package body System.Fore_Real is
- ----------
- -- Fore --
- ----------
+ ---------------
+ -- Fore_Real --
+ ---------------
- function Fore (Lo, Hi : Long_Long_Float) return Natural is
+ function Fore_Real (Lo, Hi : Long_Long_Float) return Natural is
T : Long_Long_Float := Long_Long_Float'Max (abs Lo, abs Hi);
- R : Natural;
+ F : Natural;
begin
-- Initial value of 2 allows for sign and mandatory single digit
- R := 2;
+ F := 2;
-- Loop to increase Fore as needed to include full range of values
while T >= 10.0 loop
T := T / 10.0;
- R := R + 1;
+ F := F + 1;
end loop;
- return R;
- end Fore;
-end System.Fore;
+ return F;
+ end Fore_Real;
+
+end System.Fore_Real;
diff --git a/gcc/ada/libgnat/s-fore.ads b/gcc/ada/libgnat/s-forrea.ads
index 7d78952..6b0a211 100644
--- a/gcc/ada/libgnat/s-fore.ads
+++ b/gcc/ada/libgnat/s-forrea.ads
@@ -2,7 +2,7 @@
-- --
-- GNAT RUN-TIME COMPONENTS --
-- --
--- S Y S T E M . F O R E --
+-- S Y S T E M . F O R E _ R E A L --
-- --
-- S p e c --
-- --
@@ -29,13 +29,14 @@
-- --
------------------------------------------------------------------------------
--- This package contains the routine used for the 'Fore attribute
+-- This package contains the routine used for the Fore attribute of ordinary
+-- fixed point types whose Small is neither an integer nor its reciprocal.
-package System.Fore is
+package System.Fore_Real is
pragma Pure;
- function Fore (Lo, Hi : Long_Long_Float) return Natural;
- -- Compute Fore attribute value for a fixed-point type. The parameters
- -- are the low and high bounds values, converted to Long_Long_Float.
+ function Fore_Real (Lo, Hi : Long_Long_Float) return Natural;
+ -- Compute Fore attribute value for a fixed point type. The parameters
+ -- are the low and high bounds, converted to Long_Long_Float.
-end System.Fore;
+end System.Fore_Real;
diff --git a/gcc/ada/libgnat/s-genbig.adb b/gcc/ada/libgnat/s-genbig.adb
index 12167ac..bf222ac 100644
--- a/gcc/ada/libgnat/s-genbig.adb
+++ b/gcc/ada/libgnat/s-genbig.adb
@@ -1193,7 +1193,7 @@ package body System.Generic_Bignums is
return To_Bignum (Long_Long_Long_Integer (X));
end To_Bignum;
- function To_Bignum (X : Unsigned_64) return Big_Integer is
+ function To_Bignum (X : Unsigned_128) return Big_Integer is
begin
if X = 0 then
return Allocate_Big_Integer ((1 .. 0 => <>), False);
@@ -1205,11 +1205,33 @@ package body System.Generic_Bignums is
-- Two word result
- else
+ elsif Shift_Right (X, 32) < 2 ** 32 then
return Allocate_Big_Integer ((SD (X / Base), SD (X mod Base)), False);
+
+ -- Three or four word result
+
+ else
+ declare
+ Vector : Digit_Vector (1 .. 4);
+ High : constant Unsigned_64 := Unsigned_64 (Shift_Right (X, 64));
+ Low : constant Unsigned_64 :=
+ Unsigned_64 (X and 16#FFFF_FFFF_FFFF_FFFF#);
+
+ begin
+ Vector (1) := SD (High / Base);
+ Vector (2) := SD (High mod Base);
+ Vector (3) := SD (Low / Base);
+ Vector (4) := SD (Low mod Base);
+ return Normalize (Vector, False);
+ end;
end if;
end To_Bignum;
+ function To_Bignum (X : Unsigned_64) return Big_Integer is
+ begin
+ return To_Bignum (Unsigned_128 (X));
+ end To_Bignum;
+
---------------
-- To_String --
---------------
diff --git a/gcc/ada/libgnat/s-genbig.ads b/gcc/ada/libgnat/s-genbig.ads
index 81e3843..be8340e 100644
--- a/gcc/ada/libgnat/s-genbig.ads
+++ b/gcc/ada/libgnat/s-genbig.ads
@@ -109,6 +109,10 @@ package System.Generic_Bignums is
-- Convert Unsigned_64 to a big integer. No exception can be raised for any
-- input argument.
+ function To_Bignum (X : Interfaces.Unsigned_128) return Big_Integer;
+ -- Convert Unsigned_128 to a big integer. No exception can be raised for
+ -- any input argument.
+
function From_Bignum (X : Bignum) return Long_Long_Integer;
-- Convert Bignum to Long_Long_Integer. Constraint_Error raised with
-- appropriate message if value is out of range of Long_Long_Integer.
diff --git a/gcc/ada/libgnat/s-imglld.adb b/gcc/ada/libgnat/s-imaged.adb
index c70f409..726b9d8 100644
--- a/gcc/ada/libgnat/s-imglld.adb
+++ b/gcc/ada/libgnat/s-imaged.adb
@@ -2,11 +2,11 @@
-- --
-- GNAT RUN-TIME COMPONENTS --
-- --
--- S Y S T E M . I M G _ L L D --
+-- S Y S T E M . I M A G E _ D --
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2020, Free Software Foundation, Inc. --
+-- Copyright (C) 2020, 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- --
@@ -29,16 +29,16 @@
-- --
------------------------------------------------------------------------------
-with System.Img_Dec; use System.Img_Dec;
+with System.Img_Util; use System.Img_Util;
-package body System.Img_LLD is
+package body System.Image_D is
- -----------------------------
- -- Image_Long_Long_Decimal --
- ----------------------------
+ -------------------
+ -- Image_Decimal --
+ -------------------
- procedure Image_Long_Long_Decimal
- (V : Long_Long_Integer;
+ procedure Image_Decimal
+ (V : Int;
S : in out String;
P : out Natural;
Scale : Integer)
@@ -55,16 +55,15 @@ package body System.Img_LLD is
P := 0;
end if;
- Set_Image_Long_Long_Decimal
- (V, S, P, Scale, 1, Integer'Max (1, Scale), 0);
- end Image_Long_Long_Decimal;
+ Set_Image_Decimal (V, S, P, Scale, 1, Integer'Max (1, Scale), 0);
+ end Image_Decimal;
- ---------------------------------
- -- Set_Image_Long_Long_Decimal --
- ---------------------------------
+ -----------------------
+ -- Set_Image_Decimal --
+ -----------------------
- procedure Set_Image_Long_Long_Decimal
- (V : Long_Long_Integer;
+ procedure Set_Image_Decimal
+ (V : Int;
S : in out String;
P : in out Natural;
Scale : Integer;
@@ -72,11 +71,11 @@ package body System.Img_LLD is
Aft : Natural;
Exp : Natural)
is
- Digs : String := Long_Long_Integer'Image (V);
+ Digs : String := Int'Image (V);
-- Sign and digits of decimal value
begin
Set_Decimal_Digits (Digs, Digs'Length, S, P, Scale, Fore, Aft, Exp);
- end Set_Image_Long_Long_Decimal;
+ end Set_Image_Decimal;
-end System.Img_LLD;
+end System.Image_D;
diff --git a/gcc/ada/libgnat/s-imglld.ads b/gcc/ada/libgnat/s-imaged.ads
index fdb25b4..5c3f82a 100644
--- a/gcc/ada/libgnat/s-imglld.ads
+++ b/gcc/ada/libgnat/s-imaged.ads
@@ -2,11 +2,11 @@
-- --
-- GNAT RUN-TIME COMPONENTS --
-- --
--- S Y S T E M . I M G _ L L D --
+-- S Y S T E M . I M A G E _ D --
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2020, Free Software Foundation, Inc. --
+-- Copyright (C) 2020, 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- --
@@ -29,26 +29,31 @@
-- --
------------------------------------------------------------------------------
--- Image for decimal fixed types where the size of the corresponding integer
--- type does exceeds Integer'Size (also used for Text_IO.Decimal_IO output)
+-- This package contains the routines for supporting the Image attribute for
+-- decimal fixed point types, and also for conversion operations required in
+-- Text_IO.Decimal_IO for such types.
-package System.Img_LLD is
+generic
+
+ type Int is range <>;
+
+package System.Image_D is
pragma Pure;
- procedure Image_Long_Long_Decimal
- (V : Long_Long_Integer;
+ procedure Image_Decimal
+ (V : Int;
S : in out String;
P : out Natural;
Scale : Integer);
-- Computes fixed_type'Image (V), where V is the integer value (in units of
- -- delta) of a decimal type whose Scale is as given and store the result in
- -- S (P + 1 .. L), updating P to the value of L. The image is given by the
+ -- delta) of a decimal type whose Scale is as given and stores the result
+ -- S (1 .. P), updating P to the value of L. The image is given by the
-- rules in RM 3.5(34) for fixed-point type image functions. The caller
- -- guarantees that S is long enough to hold the result. S need not have a
- -- lower bound of 1.
+ -- guarantees that S is long enough to hold the result and has a lower
+ -- bound of 1.
- procedure Set_Image_Long_Long_Decimal
- (V : Long_Long_Integer;
+ procedure Set_Image_Decimal
+ (V : Int;
S : in out String;
P : in out Natural;
Scale : Integer;
@@ -56,12 +61,12 @@ package System.Img_LLD is
Aft : Natural;
Exp : Natural);
-- Sets the image of V, where V is the integer value (in units of delta)
- -- of a decimal type with the given Scale, starting at S (P + 1), updating
- -- P to point to the last character stored, the caller promises that the
- -- buffer is large enough and no check is made for this. Constraint_Error
+ -- of a decimal type with the specified Scale, starting at S (P + 1) and
+ -- updating P to point to the last character stored, the caller promises
+ -- that the buffer is large enough and no check is made. Constraint_Error
-- will not necessarily be raised if this requirement is violated, since
-- it is perfectly valid to compile this unit with checks off. The Fore,
-- Aft and Exp values can be set to any valid values for the case of use
- -- by Text_IO.Decimal_IO. Note that there is no leading space stored.
+ -- by Text_IO.Decimal_IO.
-end System.Img_LLD;
+end System.Image_D;
diff --git a/gcc/ada/libgnat/s-imagef.adb b/gcc/ada/libgnat/s-imagef.adb
new file mode 100644
index 0000000..94a7a2f
--- /dev/null
+++ b/gcc/ada/libgnat/s-imagef.adb
@@ -0,0 +1,362 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . I M A G E _ F --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with System.Image_I;
+with System.Img_Util; use System.Img_Util;
+
+package body System.Image_F is
+
+ Maxdigs : constant Natural := Int'Width - 2;
+ -- Maximum number of decimal digits that can be represented in an Int.
+ -- The "-2" accounts for the sign and one extra digit, since we need the
+ -- maximum number of 9's that can be represented, e.g. for the 64-bit case,
+ -- Integer_64'Width is 20 since the maximum value is approximately 9.2E+18
+ -- and has 19 digits, but the maximum number of 9's that can be represented
+ -- in Integer_64 is only 18.
+
+ -- The first prerequisite of the implementation is that the first scaled
+ -- divide does not overflow, which means that the absolute value of the
+ -- input X must always be smaller than 10**Maxdigs * 2**(Int'Size - 1).
+ -- Otherwise Constraint_Error is raised by the scaled divide operation.
+
+ -- The second prerequisite of the implementation is that the computation
+ -- of the operands does not overflow when the small is neither an integer
+ -- nor the reciprocal of an integer, which means that its numerator and
+ -- denominator must be smaller than 10**(2*Maxdigs-1) / 2**(Int'Size - 1)
+ -- if the small is larger than 1, and smaller than 2**(Int'Size - 1) / 10
+ -- if the small is smaller than 1.
+
+ package Image_I is new System.Image_I (Int);
+
+ procedure Set_Image_Integer
+ (V : Int;
+ S : in out String;
+ P : in out Natural)
+ renames Image_I.Set_Image_Integer;
+
+ -- The following section describes a specific implementation choice for
+ -- performing base conversions needed for output of values of a fixed
+ -- point type T with small T'Small. The goal is to be able to output
+ -- all values of fixed point types with a precision of 64 bits and a
+ -- small in the range 2.0**(-63) .. 2.0**63. The reasoning can easily
+ -- be adapted to fixed point types with a precision of 32 or 128 bits.
+
+ -- The chosen algorithm uses fixed precision integer arithmetic for
+ -- reasons of simplicity and efficiency. It is important to understand
+ -- in what ways the most simple and accurate approach to fixed point I/O
+ -- is limiting, before considering more complicated schemes.
+
+ -- Without loss of generality assume T has a range (-2.0**63) * T'Small
+ -- .. (2.0**63 - 1) * T'Small, and is output with Aft digits after the
+ -- decimal point and T'Fore - 1 before. If T'Small is integer, or
+ -- 1.0 / T'Small is integer, let S = T'Small.
+
+ -- The idea is to convert a value X * S of type T to a 64-bit integer value
+ -- Q equal to 10.0**D * (X * S) rounded to the nearest integer, using only
+ -- a scaled integer divide of the form
+
+ -- Q = (X * Y) / Z,
+
+ -- where the variables X, Y, Z are 64-bit integers, and both multiplication
+ -- and division are done using full intermediate precision. Then the final
+ -- decimal value to be output is
+
+ -- Q * 10**(-D)
+
+ -- This value can be written to the output file or to the result string
+ -- according to the format described in RM A.3.10. The details of this
+ -- operation are omitted here.
+
+ -- A 64-bit value can represent all integers with 18 decimal digits, but
+ -- not all with 19 decimal digits. If the total number of requested ouput
+ -- digits (Fore - 1) + Aft is greater than 18 then, for purposes of the
+ -- conversion, Aft is adjusted to 18 - (Fore - 1). In that case, trailing
+ -- zeros can complete the output after writing the first 18 significant
+ -- digits, or the technique described in the next section can be used.
+ -- In addition, D cannot be smaller than -18, in order for 10.0**(-D) to
+ -- fit in a 64-bit integer.
+
+ -- The final expression for D is
+
+ -- D = Integer'Max (-18, Integer'Min (Aft, 18 - (Fore - 1)));
+
+ -- For Y and Z the following expressions can be derived:
+
+ -- Q = X * S * (10.0**D) = (X * Y) / Z
+
+ -- If S is an integer greater than or equal to one, then Fore must be at
+ -- least 20 in order to print T'First, which is at most -2.0**63. This
+ -- means that D < 0, so use
+
+ -- (1) Y = -S and Z = -10**(-D)
+
+ -- If 1.0 / S is an integer greater than one, use
+
+ -- (2) Y = -10**D and Z = -(1.0 / S), for D >= 0
+
+ -- or
+
+ -- (3) Y = -1 and Z = -(1.0 / S) * 10**(-D), for D < 0
+
+ -- Negative values are used for nominator Y and denominator Z, so that S
+ -- can have a maximum value of 2.0**63 and a minimum of 2.0**(-63). For
+ -- -(1.0 / S) in -1 .. -9, Fore will still be 20, and D will be negative,
+ -- as (-2.0**63) / -9 is greater than 10**18. In these cases there is room
+ -- in the denominator for the extra decimal scaling required, so case (3)
+ -- will not overflow.
+
+ -- In fact this reasoning can be generalized to most S which are the ratio
+ -- of two integers with bounded magnitude. Let S = Num / Den and rewrite
+ -- case (1) above where Den = 1 into
+
+ -- (1b) Y = -Num and Z = -Den * 10**(-D)
+
+ -- Suppose that Num corresponds to the maximum value of -D, i.e. 18 and
+ -- 10**(-D) = 10**18. If you change Den into 10, then S becomes 10 times
+ -- smaller and, therefore, Fore is decremented by 1, which means that -D
+ -- is as well, provided that Fore was initially not larger than 37, so the
+ -- multiplication for Z still does not overflow. But you need to reach 10
+ -- to trigger this effect, which means that a leeway of 10 is required, so
+ -- let's restrict this to a Num for which 10**(-D) <= 10**17. To summarize
+ -- this case, if S is the ratio of two integers with
+
+ -- Den < Num <= B1
+
+ -- where B1 is a fixed limit, then case (1b) does not overflow. B1 can be
+ -- taken as the largest integer Small such that D = -17, i.e. Fore = 36,
+ -- which means that B1 * 2.0**63 must be smaller than 10**35.
+
+ -- Let's continue and rewrite case (2) above when Num = 1 into
+
+ -- (2b) Y = -Num * 10**D and Z = -Den, for D >= 0
+
+ -- Note that D <= 18 - (Fore - 1) and Fore >= 2 so D <= 17, thus you can
+ -- safely change Num into 10 in the product, but then S becomes 10 times
+ -- larger and, therefore, Fore is incremented by 1, which means that D is
+ -- decremented by 1 so you again have a product lesser or equal to 10**17.
+ -- To sum up, if S is the ratio of two integers with
+
+ -- Num <= Den * S0
+
+ -- where S0 is the largest Small such that D >= 0, then case (2b) does not
+ -- overflow.
+
+ -- Let's conclude and rewrite case (3) above when Num = 1 into
+
+ -- (3b) Y = -Num and Z = -Den * 10**(-D), for D < 0
+
+ -- As explained above, this occurs only if both S0 < S < 1 and D = -1 and
+ -- is preserved if you scale up Num and Den simultaneously, what you can
+ -- do until Den * 10 tops the upper bound. To sum up, if S is the ratio of
+ -- two integers with
+
+ -- Den * S0 < Num < Den <= B2
+
+ -- where B2 is a fixed limit, then case (3b) does not overflow. B2 can be
+ -- taken as the largest integer such that B2 * 10 is smaller than 2.0**63.
+
+ -- The conclusion is that the algorithm works if the small is the ratio of
+ -- two integers in the range 1 .. 2**63 if either is equal to 1, or of two
+ -- integers in the range 1 .. B1 if the small is larger than 1, or of two
+ -- integers in the range 1 .. B2 if the small is smaller than 1.
+
+ -- Using a scaled divide which truncates and returns a remainder R,
+ -- another K trailing digits can be calculated by computing the value
+ -- (R * (10.0**K)) / Z using another scaled divide. This procedure
+ -- can be repeated to compute an arbitrary number of digits in linear
+ -- time and storage. The last scaled divide should be rounded, with
+ -- a possible carry propagating to the more significant digits, to
+ -- ensure correct rounding of the unit in the last place.
+
+ -----------------
+ -- Image_Fixed --
+ -----------------
+
+ procedure Image_Fixed
+ (V : Int;
+ S : in out String;
+ P : out Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural)
+ is
+ pragma Assert (S'First = 1);
+
+ begin
+ -- Add space at start for non-negative numbers
+
+ if V >= 0 then
+ S (1) := ' ';
+ P := 1;
+ else
+ P := 0;
+ end if;
+
+ Set_Image_Fixed (V, S, P, Num, Den, For0, Aft0, 1, Aft0, 0);
+ end Image_Fixed;
+
+ ---------------------
+ -- Set_Image_Fixed --
+ ---------------------
+
+ procedure Set_Image_Fixed
+ (V : Int;
+ S : in out String;
+ P : in out Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural;
+ Fore : Natural;
+ Aft : Natural;
+ Exp : Natural)
+ is
+ pragma Assert (Num < 0 and then Den < 0);
+ -- Accept only negative numbers to allow -2**(Int'Size - 1)
+
+ A : constant Natural :=
+ Boolean'Pos (Exp > 0) * Aft0 + Natural'Max (Aft, 1) + 1;
+ -- Number of digits after the decimal point to be computed. If Exp is
+ -- positive, we need to compute Aft decimal digits after the first non
+ -- zero digit and we are guaranteed there is at least one in the first
+ -- Aft0 digits (unless V is zero). In both cases, we compute one more
+ -- digit than requested so that Set_Decimal_Digits can round at Aft.
+
+ D : constant Integer :=
+ Integer'Max (-Maxdigs, Integer'Min (A, Maxdigs - (For0 - 1)));
+ Y : constant Int := Num * 10**Integer'Max (0, D);
+ Z : constant Int := Den * 10**Integer'Max (0, -D);
+ -- See the description of the algorithm above
+
+ AF : constant Natural := A - D;
+ -- Number of remaining digits to be computed after the first round. It
+ -- is larger than A if the first round does not compute all the digits
+ -- before the decimal point, i.e. (For0 - 1) larger than Maxdigs.
+
+ N : constant Natural := 1 + (AF + Maxdigs - 1) / Maxdigs;
+ -- Number of rounds of scaled divide to be performed
+
+ Q : Int;
+ -- Quotient of the scaled divide in this round. Only the first round may
+ -- yield more than Maxdigs digits and has a significant sign.
+
+ Buf : String (1 .. Maxdigs);
+ Len : Natural;
+ -- Buffer for the image of the quotient
+
+ Digs : String (1 .. 2 + N * Maxdigs);
+ Ndigs : Natural;
+ -- Concatenated image of the successive quotients
+
+ Scale : Integer := 0;
+ -- Exponent such that the result is Digs (1 .. NDigs) * 10**(-Scale)
+
+ XX : Int := V;
+ YY : Int := Y;
+ -- First two operands of the scaled divide
+
+ begin
+ -- Set the first character like Image
+
+ if V >= 0 then
+ Digs (1) := ' ';
+ Ndigs := 1;
+ else
+ Ndigs := 0;
+ end if;
+
+ for J in 1 .. N loop
+ exit when XX = 0;
+
+ Scaled_Divide (XX, YY, Z, Q, R => XX, Round => False);
+
+ if J = 1 then
+ if Q /= 0 then
+ Set_Image_Integer (Q, Digs, Ndigs);
+ end if;
+
+ Scale := Scale + D;
+
+ -- Prepare for next round, if any
+
+ YY := 10**Maxdigs;
+
+ else
+ pragma Assert (-10**Maxdigs < Q and then Q < 10**Maxdigs);
+
+ Len := 0;
+ Set_Image_Integer (abs Q, Buf, Len);
+
+ pragma Assert (1 <= Len and then Len <= Maxdigs);
+
+ -- If no character but the space has been written, write the
+ -- minus if need be, since Set_Image_Integer did not do it.
+
+ if Ndigs <= 1 then
+ if Q /= 0 then
+ if Ndigs = 0 then
+ Digs (1) := '-';
+ end if;
+
+ Digs (2 .. Len + 1) := Buf (1 .. Len);
+ Ndigs := Len + 1;
+ end if;
+
+ -- Or else pad the output with zeroes up to Maxdigs
+
+ else
+ for K in 1 .. Maxdigs - Len loop
+ Digs (Ndigs + K) := '0';
+ end loop;
+
+ for K in 1 .. Len loop
+ Digs (Ndigs + Maxdigs - Len + K) := Buf (K);
+ end loop;
+
+ Ndigs := Ndigs + Maxdigs;
+ end if;
+
+ Scale := Scale + Maxdigs;
+ end if;
+ end loop;
+
+ -- If no digit was output, this is zero
+
+ if Ndigs <= 1 then
+ Digs (1 .. 2) := " 0";
+ Ndigs := 2;
+ end if;
+
+ Set_Decimal_Digits (Digs, Ndigs, S, P, Scale, Fore, Aft, Exp);
+ end Set_Image_Fixed;
+
+end System.Image_F;
diff --git a/gcc/ada/libgnat/s-imgdec.ads b/gcc/ada/libgnat/s-imagef.ads
index d45a05f..ace7e6b 100644
--- a/gcc/ada/libgnat/s-imgdec.ads
+++ b/gcc/ada/libgnat/s-imagef.ads
@@ -2,11 +2,11 @@
-- --
-- GNAT RUN-TIME COMPONENTS --
-- --
--- S Y S T E M . I M G _ D E C --
+-- S Y S T E M . I M A G E _ F --
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2020, Free Software Foundation, Inc. --
+-- Copyright (C) 2020, 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- --
@@ -29,55 +29,60 @@
-- --
------------------------------------------------------------------------------
--- Image for decimal fixed types where the size of the corresponding integer
--- type does not exceed Integer'Size (also used for Text_IO.Decimal_IO output)
+-- This package contains the routines for supporting the Image attribute for
+-- ordinary fixed point types whose Small is the ratio of two Int values, and
+-- also for conversion operations required in Text_IO.Fixed_IO for such types.
-package System.Img_Dec is
+generic
+
+ type Int is range <>;
+
+ with procedure Scaled_Divide
+ (X, Y, Z : Int;
+ Q, R : out Int;
+ Round : Boolean);
+
+package System.Image_F is
pragma Pure;
- procedure Image_Decimal
- (V : Integer;
- S : in out String;
- P : out Natural;
- Scale : Integer);
+ procedure Image_Fixed
+ (V : Int;
+ S : in out String;
+ P : out Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural);
-- Computes fixed_type'Image (V), where V is the integer value (in units of
- -- delta) of a decimal type whose Scale is as given and stores the result
- -- S (1 .. P), updating P to the value of L. The image is given by the
- -- rules in RM 3.5(34) for fixed-point type image functions. The caller
- -- guarantees that S is long enough to hold the result. S need not have a
- -- lower bound of 1.
+ -- small) of an ordinary fixed point type with small Num/Den, and stores
+ -- the result in S (1 .. P), updating P on return. The result is computed
+ -- according to the rules for image for fixed-point types (RM 3.5(34)).
+ -- For0 and Aft0 are the values of the Fore and Aft attributes for the
+ -- fixed point type whose mantissa type is Int and whose small is Num/Den.
+ -- This function is used only for fixed point whose Small is an integer or
+ -- its reciprocal (see package System.Img_Real for the handling of other
+ -- ordinary fixed-point types). The caller guarantees that S is long enough
+ -- to hold the result and has a lower bound of 1.
- procedure Set_Image_Decimal
- (V : Integer;
- S : in out String;
- P : in out Natural;
- Scale : Integer;
- Fore : Natural;
- Aft : Natural;
- Exp : Natural);
- -- Sets the image of V, where V is the integer value (in units of delta)
- -- of a decimal type with the given Scale, starting at S (P + 1), updating
- -- P to point to the last character stored, the caller promises that the
- -- buffer is large enough and no check is made for this. Constraint_Error
+ procedure Set_Image_Fixed
+ (V : Int;
+ S : in out String;
+ P : in out Natural;
+ Num : Int;
+ Den : Int;
+ For0 : Natural;
+ Aft0 : Natural;
+ Fore : Natural;
+ Aft : Natural;
+ Exp : Natural);
+ -- Sets the image of V, where V is the integer value (in units of small)
+ -- of a fixed point type with small Num/Den, starting at S (P + 1) and
+ -- updating P to point to the last character stored, the caller promises
+ -- that the buffer is large enough and no check is made. Constraint_Error
-- will not necessarily be raised if this requirement is violated, since
- -- it is perfectly valid to compile this unit with checks off. The Fore,
- -- Aft and Exp values can be set to any valid values for the case of use
- -- by Text_IO.Decimal_IO. Note that there is no leading space stored.
-
- procedure Set_Decimal_Digits
- (Digs : in out String;
- NDigs : Natural;
- S : out String;
- P : in out Natural;
- Scale : Integer;
- Fore : Natural;
- Aft : Natural;
- Exp : Natural);
- -- This procedure has the same semantics as Set_Image_Decimal, except that
- -- the value in Digs (1 .. NDigs) is given as a string of decimal digits
- -- preceded by either a minus sign or a space (i.e. the integer image of
- -- the value in units of delta). The call may destroy the value in Digs,
- -- which is why Digs is in-out (this happens if rounding is required).
- -- Set_Decimal_Digits is shared by all the decimal image routines.
+ -- it is perfectly valid to compile this unit with checks off. For0 and
+ -- Aft0 are the values of the Fore and Aft attributes for the fixed point
+ -- type whose mantissa type is Int and whose small is Num/Den. The Fore,
+ -- Aft and Exp can be set to any valid values for use by Text_IO.Fixed_IO.
-end System.Img_Dec;
+end System.Image_F;
diff --git a/gcc/ada/libgnat/s-imagei.adb b/gcc/ada/libgnat/s-imagei.adb
index c739dfb..36c1f6f 100644
--- a/gcc/ada/libgnat/s-imagei.adb
+++ b/gcc/ada/libgnat/s-imagei.adb
@@ -56,8 +56,11 @@ package body System.Image_I is
if V >= 0 then
S (1) := ' ';
P := 1;
+ pragma Assert (P < S'Last);
+
else
P := 0;
+ pragma Assert (P < S'Last - 1);
end if;
Set_Image_Integer (V, S, P);
@@ -72,26 +75,31 @@ package body System.Image_I is
S : in out String;
P : in out Natural)
is
+ Nb_Digits : Natural := 0;
+ Value : Non_Positive := T;
begin
- if T <= -10 then
- Set_Digits (T / 10, S, P);
- pragma Assert (P >= (S'First - 1) and P < S'Last and
- P < Natural'Last);
- -- No check is done since, as documented in the Set_Image_Integer
- -- specification, the caller guarantees that S is long enough to
- -- hold the result.
- P := P + 1;
- S (P) := Character'Val (48 - (T rem 10));
+ pragma Assert (P >= S'First - 1 and P < S'Last);
+ -- No check is done since, as documented in the Set_Image_Integer
+ -- specification, the caller guarantees that S is long enough to
+ -- hold the result.
- else
- pragma Assert (P >= (S'First - 1) and P < S'Last and
- P < Natural'Last);
- -- No check is done since, as documented in the Set_Image_Integer
- -- specification, the caller guarantees that S is long enough to
- -- hold the result.
- P := P + 1;
- S (P) := Character'Val (48 - T);
- end if;
+ -- First we compute the number of characters needed for representing
+ -- the number.
+ loop
+ Value := Value / 10;
+ Nb_Digits := Nb_Digits + 1;
+ exit when Value = 0;
+ end loop;
+
+ Value := T;
+
+ -- We now populate digits from the end of the string to the beginning
+ for J in reverse 1 .. Nb_Digits loop
+ S (P + J) := Character'Val (48 - (Value rem 10));
+ Value := Value / 10;
+ end loop;
+
+ P := P + Nb_Digits;
end Set_Digits;
-----------------------
@@ -108,8 +116,7 @@ package body System.Image_I is
Set_Digits (-V, S, P);
else
- pragma Assert (P >= (S'First - 1) and P < S'Last and
- P < Natural'Last);
+ pragma Assert (P >= S'First - 1 and P < S'Last);
-- No check is done since, as documented in the specification,
-- the caller guarantees that S is long enough to hold the result.
P := P + 1;
diff --git a/gcc/ada/libgnat/s-imageu.adb b/gcc/ada/libgnat/s-imageu.adb
index c995d55..8ffb8f0 100644
--- a/gcc/ada/libgnat/s-imageu.adb
+++ b/gcc/ada/libgnat/s-imageu.adb
@@ -56,24 +56,31 @@ package body System.Image_U is
S : in out String;
P : in out Natural)
is
+ Nb_Digits : Natural := 0;
+ Value : Uns := V;
begin
- if V >= 10 then
- Set_Image_Unsigned (V / 10, S, P);
- pragma Assert (P >= (S'First - 1) and P < S'Last and
- P < Natural'Last);
- -- No check is done since, as documented in the specification,
- -- the caller guarantees that S is long enough to hold the result.
- P := P + 1;
- S (P) := Character'Val (48 + (V rem 10));
+ pragma Assert (P >= S'First - 1 and then P < S'Last and then
+ P < Natural'Last);
+ -- No check is done since, as documented in the specification, the
+ -- caller guarantees that S is long enough to hold the result.
- else
- pragma Assert (P >= (S'First - 1) and P < S'Last and
- P < Natural'Last);
- -- No check is done since, as documented in the specification,
- -- the caller guarantees that S is long enough to hold the result.
- P := P + 1;
- S (P) := Character'Val (48 + V);
- end if;
+ -- First we compute the number of characters needed for representing
+ -- the number.
+ loop
+ Value := Value / 10;
+ Nb_Digits := Nb_Digits + 1;
+ exit when Value = 0;
+ end loop;
+
+ Value := V;
+
+ -- We now populate digits from the end of the string to the beginning
+ for J in reverse 1 .. Nb_Digits loop
+ S (P + J) := Character'Val (48 + (Value rem 10));
+ Value := Value / 10;
+ end loop;
+
+ P := P + Nb_Digits;
end Set_Image_Unsigned;
end System.Image_U;
diff --git a/gcc/ada/libgnat/s-imde128.ads b/gcc/ada/libgnat/s-imde128.ads
new file mode 100644
index 0000000..cffd0c0
--- /dev/null
+++ b/gcc/ada/libgnat/s-imde128.ads
@@ -0,0 +1,63 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . I M G _ D E C I M A L _ 1 2 8 --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the routines for supporting the Image attribute for
+-- decimal fixed point types up to 128-bit mantissa, and also for conversion
+-- operations required in Text_IO.Decimal_IO for them.
+
+with Interfaces;
+with System.Image_D;
+
+package System.Img_Decimal_128 is
+ pragma Pure;
+
+ subtype Int128 is Interfaces.Integer_128;
+
+ package Impl is new Image_D (Int128);
+
+ procedure Image_Decimal128
+ (V : Int128;
+ S : in out String;
+ P : out Natural;
+ Scale : Integer)
+ renames Impl.Image_Decimal;
+
+ procedure Set_Image_Decimal128
+ (V : Int128;
+ S : in out String;
+ P : in out Natural;
+ Scale : Integer;
+ Fore : Natural;
+ Aft : Natural;
+ Exp : Natural)
+ renames Impl.Set_Image_Decimal;
+
+end System.Img_Decimal_128;
diff --git a/gcc/ada/libgnat/s-imde32.ads b/gcc/ada/libgnat/s-imde32.ads
new file mode 100644
index 0000000..bf19e9c
--- /dev/null
+++ b/gcc/ada/libgnat/s-imde32.ads
@@ -0,0 +1,63 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . I M G _ D E C I M A L _ 3 2 --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the routines for supporting the Image attribute for
+-- decimal fixed point types up to 32-bit mantissa, and also for conversion
+-- operations required in Text_IO.Decimal_IO for such types.
+
+with Interfaces;
+with System.Image_D;
+
+package System.Img_Decimal_32 is
+ pragma Pure;
+
+ subtype Int32 is Interfaces.Integer_32;
+
+ package Impl is new Image_D (Int32);
+
+ procedure Image_Decimal32
+ (V : Int32;
+ S : in out String;
+ P : out Natural;
+ Scale : Integer)
+ renames Impl.Image_Decimal;
+
+ procedure Set_Image_Decimal32
+ (V : Int32;
+ S : in out String;
+ P : in out Natural;
+ Scale : Integer;
+ Fore : Natural;
+ Aft : Natural;
+ Exp : Natural)
+ renames Impl.Set_Image_Decimal;
+
+end System.Img_Decimal_32;
diff --git a/gcc/ada/libgnat/s-imde64.ads b/gcc/ada/libgnat/s-imde64.ads
new file mode 100644
index 0000000..dfc8403
--- /dev/null
+++ b/gcc/ada/libgnat/s-imde64.ads
@@ -0,0 +1,63 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . I M G _ D E C I M A L _ 6 4 --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the routines for supporting the Image attribute for
+-- decimal fixed point types up to 64-bit mantissa, and also for conversion
+-- operations required in Text_IO.Decimal_IO for such types.
+
+with Interfaces;
+with System.Image_D;
+
+package System.Img_Decimal_64 is
+ pragma Pure;
+
+ subtype Int64 is Interfaces.Integer_64;
+
+ package Impl is new Image_D (Int64);
+
+ procedure Image_Decimal64
+ (V : Int64;
+ S : in out String;
+ P : out Natural;
+ Scale : Integer)
+ renames Impl.Image_Decimal;
+
+ procedure Set_Image_Decimal64
+ (V : Int64;
+ S : in out String;
+ P : in out Natural;
+ Scale : Integer;
+ Fore : Natural;
+ Aft : Natural;
+ Exp : Natural)
+ renames Impl.Set_Image_Decimal;
+
+end System.Img_Decimal_64;
diff --git a/gcc/ada/libgnat/s-imfi128.ads b/gcc/ada/libgnat/s-imfi128.ads
new file mode 100644
index 0000000..24fdf97
--- /dev/null
+++ b/gcc/ada/libgnat/s-imfi128.ads
@@ -0,0 +1,69 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . I M G _ F I X E D _ 1 2 8 --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the routines for supporting the Image attribute for
+-- ordinary fixed point types up to 128-bit small and mantissa.
+
+with Interfaces;
+with System.Arith_128;
+with System.Image_F;
+
+package System.Img_Fixed_128 is
+ pragma Pure;
+
+ subtype Int128 is Interfaces.Integer_128;
+
+ package Impl is new Image_F (Int128, Arith_128.Scaled_Divide128);
+
+ procedure Image_Fixed128
+ (V : Int128;
+ S : in out String;
+ P : out Natural;
+ Num : Int128;
+ Den : Int128;
+ For0 : Natural;
+ Aft0 : Natural)
+ renames Impl.Image_Fixed;
+
+ procedure Set_Image_Fixed128
+ (V : Int128;
+ S : in out String;
+ P : in out Natural;
+ Num : Int128;
+ Den : Int128;
+ For0 : Natural;
+ Aft0 : Natural;
+ Fore : Natural;
+ Aft : Natural;
+ Exp : Natural)
+ renames Impl.Set_Image_Fixed;
+
+end System.Img_Fixed_128;
diff --git a/gcc/ada/libgnat/s-imfi32.ads b/gcc/ada/libgnat/s-imfi32.ads
new file mode 100644
index 0000000..8c425df
--- /dev/null
+++ b/gcc/ada/libgnat/s-imfi32.ads
@@ -0,0 +1,69 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . I M G _ F I X E D _ 3 2 --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the routines for supporting the Image attribute for
+-- ordinary fixed point types up to 32-bit small and mantissa.
+
+with Interfaces;
+with System.Arith_32;
+with System.Image_F;
+
+package System.Img_Fixed_32 is
+ pragma Pure;
+
+ subtype Int32 is Interfaces.Integer_32;
+
+ package Impl is new Image_F (Int32, Arith_32.Scaled_Divide32);
+
+ procedure Image_Fixed32
+ (V : Int32;
+ S : in out String;
+ P : out Natural;
+ Num : Int32;
+ Den : Int32;
+ For0 : Natural;
+ Aft0 : Natural)
+ renames Impl.Image_Fixed;
+
+ procedure Set_Image_Fixed32
+ (V : Int32;
+ S : in out String;
+ P : in out Natural;
+ Num : Int32;
+ Den : Int32;
+ For0 : Natural;
+ Aft0 : Natural;
+ Fore : Natural;
+ Aft : Natural;
+ Exp : Natural)
+ renames Impl.Set_Image_Fixed;
+
+end System.Img_Fixed_32;
diff --git a/gcc/ada/libgnat/s-imfi64.ads b/gcc/ada/libgnat/s-imfi64.ads
new file mode 100644
index 0000000..9045bf6
--- /dev/null
+++ b/gcc/ada/libgnat/s-imfi64.ads
@@ -0,0 +1,69 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . I M G _ F I X E D _ 6 4 --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the routines for supporting the Image attribute for
+-- ordinary fixed point types up to 64-bit small and mantissa.
+
+with Interfaces;
+with System.Arith_64;
+with System.Image_F;
+
+package System.Img_Fixed_64 is
+ pragma Pure;
+
+ subtype Int64 is Interfaces.Integer_64;
+
+ package Impl is new Image_F (Int64, Arith_64.Scaled_Divide64);
+
+ procedure Image_Fixed64
+ (V : Int64;
+ S : in out String;
+ P : out Natural;
+ Num : Int64;
+ Den : Int64;
+ For0 : Natural;
+ Aft0 : Natural)
+ renames Impl.Image_Fixed;
+
+ procedure Set_Image_Fixed64
+ (V : Int64;
+ S : in out String;
+ P : in out Natural;
+ Num : Int64;
+ Den : Int64;
+ For0 : Natural;
+ Aft0 : Natural;
+ Fore : Natural;
+ Aft : Natural;
+ Exp : Natural)
+ renames Impl.Set_Image_Fixed;
+
+end System.Img_Fixed_64;
diff --git a/gcc/ada/libgnat/s-imgrea.adb b/gcc/ada/libgnat/s-imgrea.adb
index 45d0ae5..03d30bd 100644
--- a/gcc/ada/libgnat/s-imgrea.adb
+++ b/gcc/ada/libgnat/s-imgrea.adb
@@ -47,10 +47,10 @@ package body System.Img_Real is
-- in very high precision floating-point output.
-- Note that in the following, the "-2" accounts for the sign and one
- -- extra digits, since we need the maximum number of 9's that can be
- -- supported, e.g. for the normal 64 bit case, Long_Long_Integer'Width
- -- is 21, since the maximum value (approx 1.6 * 10**19) has 20 digits,
- -- but the maximum number of 9's that can be supported is 19.
+ -- extra digit, since we need the maximum number of 9's that can be
+ -- represented, e.g. for the 64-bit case, Long_Long_Unsigned'Width is
+ -- 21, since the maximum value (approx 1.8E+19) has 20 digits, but the
+ -- maximum number of 9's that can be represented is only 19.
Maxdigs : constant :=
Natural'Min
@@ -58,7 +58,6 @@ package body System.Img_Real is
Unsdigs : constant := Unsigned'Width - 2;
-- Number of digits that can be converted using type Unsigned
- -- See above for the explanation of the -2.
Maxscaling : constant := 5000;
-- Max decimal scaling required during conversion of floating-point
@@ -88,11 +87,8 @@ package body System.Img_Real is
-- Decide whether a blank should be prepended before the call to
-- Set_Image_Real. We generate a blank for positive values, and
-- also for positive zeroes. For negative zeroes, we generate a
- -- space only if Signed_Zeroes is True (the RM only permits the
- -- output of -0.0 on targets where this is the case). We can of
- -- course still see a -0.0 on a target where Signed_Zeroes is
- -- False (since this attribute refers to the proper handling of
- -- negative zeroes, not to their existence). We do not generate
+ -- blank only if Signed_Zeros is False (the RM only permits the
+ -- output of -0.0 when Signed_Zeros is True). We do not generate
-- a blank for positive infinity, since we output an explicit +.
if (not Is_Negative (V) and then V <= Long_Long_Float'Last)
@@ -150,7 +146,7 @@ package body System.Img_Real is
Exp : Natural)
is
NFrac : constant Natural := Natural'Max (Aft, 1);
- Sign : Character;
+ Minus : Boolean;
X : Long_Long_Float;
Scale : Integer;
Expon : Integer;
@@ -419,7 +415,7 @@ package body System.Img_Real is
procedure Set_Blanks_And_Sign (N : Integer) is
begin
- if Sign = '-' then
+ if Minus then
for J in 1 .. N - 1 loop
Set (' ');
end loop;
@@ -483,10 +479,10 @@ package body System.Img_Real is
-- Start of processing for Set_Image_Real
begin
- -- We call the floating-point processor reset routine so that we can
- -- be sure the floating-point processor is properly set for conversion
- -- calls. This is notably need on Windows, where calls to the operating
- -- system randomly reset the processor into 64-bit mode.
+ -- We call the floating-point processor reset routine so we can be sure
+ -- that the processor is properly set for conversions. This is notably
+ -- needed on Windows, where calls to the operating system randomly reset
+ -- the processor into 64-bit mode.
System.Float_Control.Reset;
@@ -539,21 +535,21 @@ package body System.Img_Real is
if V > 0.0 then
X := V;
- Sign := '+';
+ Minus := False;
-- Negative values
elsif V < 0.0 then
X := -V;
- Sign := '-';
+ Minus := True;
-- Zero values
elsif V = 0.0 then
if Long_Long_Float'Signed_Zeros and then Is_Negative (V) then
- Sign := '-';
+ Minus := True;
else
- Sign := '+';
+ Minus := False;
end if;
Set_Blanks_And_Sign (Fore - 1);
@@ -578,7 +574,7 @@ package body System.Img_Real is
raise Constraint_Error;
end if;
- -- X and Sign are set here, and X is known to be a valid,
+ -- X and Minus are set here, and X is known to be a valid,
-- non-zero floating-point number.
-- Case of non-zero value with Exp = 0
diff --git a/gcc/ada/libgnat/s-imgrea.ads b/gcc/ada/libgnat/s-imgrea.ads
index 565666a..d8eb721 100644
--- a/gcc/ada/libgnat/s-imgrea.ads
+++ b/gcc/ada/libgnat/s-imgrea.ads
@@ -46,6 +46,9 @@ package System.Img_Real is
-- ordinary fixed point (see package System.Img_Dec for handling of decimal
-- fixed point). The caller guarantees that S is long enough to hold the
-- result and has a lower bound of 1.
+ --
+ -- Remark: This procedure should NOT be called with V = -0.0 or V = +/-Inf,
+ -- The result is irrelevant.
procedure Image_Floating_Point
(V : Long_Long_Float;
diff --git a/gcc/ada/libgnat/s-imgdec.adb b/gcc/ada/libgnat/s-imguti.adb
index 840dadb..571fb67 100644
--- a/gcc/ada/libgnat/s-imgdec.adb
+++ b/gcc/ada/libgnat/s-imguti.adb
@@ -2,11 +2,11 @@
-- --
-- GNAT RUN-TIME COMPONENTS --
-- --
--- S Y S T E M . I M G _ D E C --
+-- S Y S T E M . I M G _ U T I L --
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2020, Free Software Foundation, Inc. --
+-- Copyright (C) 2020, 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- --
@@ -29,34 +29,9 @@
-- --
------------------------------------------------------------------------------
-with System.Img_Int; use System.Img_Int;
+with System.Img_Uns; use System.Img_Uns;
-package body System.Img_Dec is
-
- -------------------
- -- Image_Decimal --
- -------------------
-
- procedure Image_Decimal
- (V : Integer;
- S : in out String;
- P : out Natural;
- Scale : Integer)
- is
- pragma Assert (S'First = 1);
-
- begin
- -- Add space at start for non-negative numbers
-
- if V >= 0 then
- S (1) := ' ';
- P := 1;
- else
- P := 0;
- end if;
-
- Set_Image_Decimal (V, S, P, Scale, 1, Integer'Max (1, Scale), 0);
- end Image_Decimal;
+package body System.Img_Util is
------------------------
-- Set_Decimal_Digits --
@@ -121,8 +96,8 @@ package body System.Img_Dec is
procedure Set_Blanks_And_Sign (N : Integer);
-- Sets leading blanks and minus sign if needed. N is the number of
-- positions to be filled (a minus sign is output even if N is zero
- -- or negative, For a positive value, if N is non-positive, then
- -- a leading blank is filled.
+ -- or negative, but for a positive value, if N is non-positive, then
+ -- the call has no effect).
procedure Set_Digits (S, E : Natural);
pragma Inline (Set_Digits);
@@ -219,9 +194,6 @@ package body System.Img_Dec is
-- Constraint_Error will not necessarily be raised if this
-- requirement is violated, since it is perfectly valid to compile
-- this unit with checks off.
- --
- -- Due to codepeer limitation, codepeer should be used with switch:
- -- -no-propagation system.img_dec.set_decimal_digits.set
P := P + 1;
S (P) := C;
end Set;
@@ -231,20 +203,16 @@ package body System.Img_Dec is
-------------------------
procedure Set_Blanks_And_Sign (N : Integer) is
- W : Integer := N;
-
begin
if Minus then
- W := W - 1;
-
- for J in 1 .. W loop
+ for J in 1 .. N - 1 loop
Set (' ');
end loop;
Set ('-');
else
- for J in 1 .. W loop
+ for J in 1 .. N loop
Set (' ');
end loop;
end if;
@@ -305,15 +273,16 @@ package body System.Img_Dec is
-- exponent of +0.
Expon := (if Zero then 0 else Digits_Before_Point - 1);
+
Set ('E');
ND := 0;
if Expon >= 0 then
Set ('+');
- Set_Image_Integer (Expon, Digs, ND);
+ Set_Image_Unsigned (Unsigned (Expon), Digs, ND);
else
Set ('-');
- Set_Image_Integer (-Expon, Digs, ND);
+ Set_Image_Unsigned (Unsigned (-Expon), Digs, ND);
end if;
Set_Zeroes (Exp - ND - 1);
@@ -431,24 +400,4 @@ package body System.Img_Dec is
end if;
end Set_Decimal_Digits;
- -----------------------
- -- Set_Image_Decimal --
- -----------------------
-
- procedure Set_Image_Decimal
- (V : Integer;
- S : in out String;
- P : in out Natural;
- Scale : Integer;
- Fore : Natural;
- Aft : Natural;
- Exp : Natural)
- is
- Digs : String := Integer'Image (V);
- -- Sign and digits of decimal value
-
- begin
- Set_Decimal_Digits (Digs, Digs'Length, S, P, Scale, Fore, Aft, Exp);
- end Set_Image_Decimal;
-
-end System.Img_Dec;
+end System.Img_Util;
diff --git a/gcc/ada/libgnat/s-imguti.ads b/gcc/ada/libgnat/s-imguti.ads
new file mode 100644
index 0000000..f980bb7
--- /dev/null
+++ b/gcc/ada/libgnat/s-imguti.ads
@@ -0,0 +1,58 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . I M G _ U T I L --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides some common utilities used by the s-imgxxx files
+
+package System.Img_Util is
+ pragma Pure;
+
+ procedure Set_Decimal_Digits
+ (Digs : in out String;
+ NDigs : Natural;
+ S : out String;
+ P : in out Natural;
+ Scale : Integer;
+ Fore : Natural;
+ Aft : Natural;
+ Exp : Natural);
+ -- Sets the image of Digs (1 .. NDigs), which is a string of decimal digits
+ -- preceded by either a minus sign or a space, i.e. the integer image of
+ -- the value in units of delta of a decimal fixed point type with the given
+ -- Scale, starting at S (P + 1), updating P to point to the last character
+ -- stored, the caller promises that the buffer is large enough and no check
+ -- is made for this. Constraint_Error will not necessarily be raised if the
+ -- requirement is violated since it is perfectly valid to compile this unit
+ -- with checks off. The Fore, Aft and Exp values can be set to any valid
+ -- values for the case of use by Text_IO.Decimal_IO. Note that there is no
+ -- leading space stored. The call may destroy the value in Digs, which is
+ -- why Digs is in-out (this happens if rounding is required).
+
+end System.Img_Util;
diff --git a/gcc/ada/libgnat/s-os_lib.adb b/gcc/ada/libgnat/s-os_lib.adb
index 288325c..93522bc 100644
--- a/gcc/ada/libgnat/s-os_lib.adb
+++ b/gcc/ada/libgnat/s-os_lib.adb
@@ -1365,6 +1365,21 @@ package body System.OS_Lib is
S : Integer;
begin
+ -- Special case Invalid_Time which is handled differently between
+ -- Windows and Linux: Linux will set to 1 second before 1970-01-01
+ -- while Windows will set the time to 1970-01-01 with Second set to -1,
+ -- which is not a valid value.
+
+ if Date = Invalid_Time then
+ Year := 1969;
+ Month := 12;
+ Day := 31;
+ Hour := 23;
+ Minute := 59;
+ Second := 59;
+ return;
+ end if;
+
-- Use the global lock because To_GM_Time is not thread safe
Locked_Processing : begin
@@ -1387,7 +1402,15 @@ package body System.OS_Lib is
Year := Y + 1900;
Month := Mo + 1;
- Day := D;
+
+ -- May happen if To_GM_Time fails
+
+ if D = 0 then
+ Day := 1;
+ else
+ Day := D;
+ end if;
+
Hour := H;
Minute := Mn;
Second := S;
diff --git a/gcc/ada/libgnat/s-rannum.adb b/gcc/ada/libgnat/s-rannum.adb
index e65e6a7..ab6428f 100644
--- a/gcc/ada/libgnat/s-rannum.adb
+++ b/gcc/ada/libgnat/s-rannum.adb
@@ -409,6 +409,41 @@ is
elsif Max < Min then
raise Constraint_Error;
+ -- In the 128-bit case, we have to be careful since not all 128-bit
+ -- unsigned values are representable in GNAT's universal integer.
+
+ elsif Result_Subtype'Base'Size > 64 then
+ declare
+ -- Ignore unequal-size warnings since GNAT's handling is correct.
+
+ pragma Warnings ("Z");
+ function Conv_To_Unsigned is
+ new Unchecked_Conversion (Result_Subtype'Base, Unsigned_128);
+ function Conv_To_Result is
+ new Unchecked_Conversion (Unsigned_128, Result_Subtype'Base);
+ pragma Warnings ("z");
+
+ N : constant Unsigned_128 :=
+ Conv_To_Unsigned (Max) - Conv_To_Unsigned (Min) + 1;
+
+ X, Slop : Unsigned_128;
+
+ begin
+ if N = 0 then
+ return Conv_To_Result (Conv_To_Unsigned (Min) + Random (Gen));
+
+ else
+ Slop := Unsigned_128'Last rem N + 1;
+
+ loop
+ X := Random (Gen);
+ exit when Slop = N or else X <= Unsigned_128'Last - Slop;
+ end loop;
+
+ return Conv_To_Result (Conv_To_Unsigned (Min) + X rem N);
+ end if;
+ end;
+
-- In the 64-bit case, we have to be careful since not all 64-bit
-- unsigned values are representable in GNAT's universal integer.
diff --git a/gcc/ada/libgnat/s-rident.ads b/gcc/ada/libgnat/s-rident.ads
index 662721a..c6c3d3d 100644
--- a/gcc/ada/libgnat/s-rident.ads
+++ b/gcc/ada/libgnat/s-rident.ads
@@ -184,6 +184,8 @@ package System.Rident is
No_Implicit_Loops, -- GNAT
No_Elaboration_Code, -- GNAT
No_Obsolescent_Features, -- Ada 2005 AI-368
+ No_Unrecognized_Aspects, -- AI12-0389-1/02
+ No_Unrecognized_Pragmas, -- AI12-0389-1/02
No_Wide_Characters, -- GNAT
Static_Dispatch_Tables, -- GNAT
SPARK_05, -- GNAT
diff --git a/gcc/ada/libgnat/s-secsta.adb b/gcc/ada/libgnat/s-secsta.adb
index 7ec8462..f2d264d 100644
--- a/gcc/ada/libgnat/s-secsta.adb
+++ b/gcc/ada/libgnat/s-secsta.adb
@@ -587,15 +587,18 @@ package body System.Secondary_Stack is
-- Start of processing for SS_Allocate
begin
- -- It should not be possible to request an allocation of negative or
- -- zero size.
-
- pragma Assert (Storage_Size > 0);
-
-- Round the requested size up to the nearest multiple of the maximum
-- alignment to ensure efficient access.
- Mem_Size := Round_Up (Storage_Size);
+ if Storage_Size = 0 then
+ Mem_Size := Memory_Alignment;
+ else
+ -- It should not be possible to request an allocation of negative
+ -- size.
+
+ pragma Assert (Storage_Size >= 0);
+ Mem_Size := Round_Up (Storage_Size);
+ end if;
if Sec_Stack_Dynamic then
Allocate_Dynamic (Stack, Mem_Size, Addr);
diff --git a/gcc/ada/libgnat/s-stratt.adb b/gcc/ada/libgnat/s-stratt.adb
index 366dabd..8fe2721 100644
--- a/gcc/ada/libgnat/s-stratt.adb
+++ b/gcc/ada/libgnat/s-stratt.adb
@@ -44,7 +44,8 @@ package body System.Stream_Attributes is
function XDR_Support return Boolean;
pragma Inline (XDR_Support);
- -- Return True if XDR streaming should be used
+ -- Return True if XDR streaming should be used. Note that 128-bit integers
+ -- are not supported by the XDR protocol and will raise Device_Error.
Err : exception renames Ada.IO_Exceptions.End_Error;
-- Exception raised if insufficient data read (note that the RM implies
@@ -64,74 +65,81 @@ package body System.Stream_Attributes is
Thin_Pointer_Size : constant := System.Address'Size;
Fat_Pointer_Size : constant := System.Address'Size * 2;
- subtype S_AD is SEA (1 .. (Fat_Pointer_Size + SU - 1) / SU);
- subtype S_AS is SEA (1 .. (Thin_Pointer_Size + SU - 1) / SU);
- subtype S_B is SEA (1 .. (Boolean'Size + SU - 1) / SU);
- subtype S_C is SEA (1 .. (Character'Size + SU - 1) / SU);
- subtype S_F is SEA (1 .. (Float'Size + SU - 1) / SU);
- subtype S_I is SEA (1 .. (Integer'Size + SU - 1) / SU);
- subtype S_I24 is SEA (1 .. (Integer_24'Size + SU - 1) / SU);
- subtype S_LF is SEA (1 .. (Long_Float'Size + SU - 1) / SU);
- subtype S_LI is SEA (1 .. (Long_Integer'Size + SU - 1) / SU);
- subtype S_LLF is SEA (1 .. (Long_Long_Float'Size + SU - 1) / SU);
- subtype S_LLI is SEA (1 .. (Long_Long_Integer'Size + SU - 1) / SU);
- subtype S_LLU is SEA (1 .. (UST.Long_Long_Unsigned'Size + SU - 1) / SU);
- subtype S_LU is SEA (1 .. (UST.Long_Unsigned'Size + SU - 1) / SU);
- subtype S_SF is SEA (1 .. (Short_Float'Size + SU - 1) / SU);
- subtype S_SI is SEA (1 .. (Short_Integer'Size + SU - 1) / SU);
- subtype S_SSI is SEA (1 .. (Short_Short_Integer'Size + SU - 1) / SU);
- subtype S_SSU is SEA (1 .. (UST.Short_Short_Unsigned'Size + SU - 1) / SU);
- subtype S_SU is SEA (1 .. (UST.Short_Unsigned'Size + SU - 1) / SU);
- subtype S_U is SEA (1 .. (UST.Unsigned'Size + SU - 1) / SU);
- subtype S_U24 is SEA (1 .. (Unsigned_24'Size + SU - 1) / SU);
- subtype S_WC is SEA (1 .. (Wide_Character'Size + SU - 1) / SU);
- subtype S_WWC is SEA (1 .. (Wide_Wide_Character'Size + SU - 1) / SU);
+ subtype S_AD is SEA (1 .. (Fat_Pointer_Size + SU - 1) / SU);
+ subtype S_AS is SEA (1 .. (Thin_Pointer_Size + SU - 1) / SU);
+ subtype S_B is SEA (1 .. (Boolean'Size + SU - 1) / SU);
+ subtype S_C is SEA (1 .. (Character'Size + SU - 1) / SU);
+ subtype S_F is SEA (1 .. (Float'Size + SU - 1) / SU);
+ subtype S_I is SEA (1 .. (Integer'Size + SU - 1) / SU);
+ subtype S_I24 is SEA (1 .. (Integer_24'Size + SU - 1) / SU);
+ subtype S_LF is SEA (1 .. (Long_Float'Size + SU - 1) / SU);
+ subtype S_LI is SEA (1 .. (Long_Integer'Size + SU - 1) / SU);
+ subtype S_LLF is SEA (1 .. (Long_Long_Float'Size + SU - 1) / SU);
+ subtype S_LLI is SEA (1 .. (Long_Long_Integer'Size + SU - 1) / SU);
+ subtype S_LLLI is SEA (1 .. (Long_Long_Long_Integer'Size + SU - 1) / SU);
+ subtype S_LLLU is
+ SEA (1 .. (UST.Long_Long_Long_Unsigned'Size + SU - 1) / SU);
+ subtype S_LLU is SEA (1 .. (UST.Long_Long_Unsigned'Size + SU - 1) / SU);
+ subtype S_LU is SEA (1 .. (UST.Long_Unsigned'Size + SU - 1) / SU);
+ subtype S_SF is SEA (1 .. (Short_Float'Size + SU - 1) / SU);
+ subtype S_SI is SEA (1 .. (Short_Integer'Size + SU - 1) / SU);
+ subtype S_SSI is SEA (1 .. (Short_Short_Integer'Size + SU - 1) / SU);
+ subtype S_SSU is SEA (1 .. (UST.Short_Short_Unsigned'Size + SU - 1) / SU);
+ subtype S_SU is SEA (1 .. (UST.Short_Unsigned'Size + SU - 1) / SU);
+ subtype S_U is SEA (1 .. (UST.Unsigned'Size + SU - 1) / SU);
+ subtype S_U24 is SEA (1 .. (Unsigned_24'Size + SU - 1) / SU);
+ subtype S_WC is SEA (1 .. (Wide_Character'Size + SU - 1) / SU);
+ subtype S_WWC is SEA (1 .. (Wide_Wide_Character'Size + SU - 1) / SU);
-- Unchecked conversions from the elementary type to the stream type
- function From_AD is new UC (Fat_Pointer, S_AD);
- function From_AS is new UC (Thin_Pointer, S_AS);
- function From_F is new UC (Float, S_F);
- function From_I is new UC (Integer, S_I);
- function From_I24 is new UC (Integer_24, S_I24);
- function From_LF is new UC (Long_Float, S_LF);
- function From_LI is new UC (Long_Integer, S_LI);
- function From_LLF is new UC (Long_Long_Float, S_LLF);
- function From_LLI is new UC (Long_Long_Integer, S_LLI);
- function From_LLU is new UC (UST.Long_Long_Unsigned, S_LLU);
- function From_LU is new UC (UST.Long_Unsigned, S_LU);
- function From_SF is new UC (Short_Float, S_SF);
- function From_SI is new UC (Short_Integer, S_SI);
- function From_SSI is new UC (Short_Short_Integer, S_SSI);
- function From_SSU is new UC (UST.Short_Short_Unsigned, S_SSU);
- function From_SU is new UC (UST.Short_Unsigned, S_SU);
- function From_U is new UC (UST.Unsigned, S_U);
- function From_U24 is new UC (Unsigned_24, S_U24);
- function From_WC is new UC (Wide_Character, S_WC);
- function From_WWC is new UC (Wide_Wide_Character, S_WWC);
+ function From_AD is new UC (Fat_Pointer, S_AD);
+ function From_AS is new UC (Thin_Pointer, S_AS);
+ function From_F is new UC (Float, S_F);
+ function From_I is new UC (Integer, S_I);
+ function From_I24 is new UC (Integer_24, S_I24);
+ function From_LF is new UC (Long_Float, S_LF);
+ function From_LI is new UC (Long_Integer, S_LI);
+ function From_LLF is new UC (Long_Long_Float, S_LLF);
+ function From_LLI is new UC (Long_Long_Integer, S_LLI);
+ function From_LLLI is new UC (Long_Long_Long_Integer, S_LLLI);
+ function From_LLLU is new UC (UST.Long_Long_Long_Unsigned, S_LLLU);
+ function From_LLU is new UC (UST.Long_Long_Unsigned, S_LLU);
+ function From_LU is new UC (UST.Long_Unsigned, S_LU);
+ function From_SF is new UC (Short_Float, S_SF);
+ function From_SI is new UC (Short_Integer, S_SI);
+ function From_SSI is new UC (Short_Short_Integer, S_SSI);
+ function From_SSU is new UC (UST.Short_Short_Unsigned, S_SSU);
+ function From_SU is new UC (UST.Short_Unsigned, S_SU);
+ function From_U is new UC (UST.Unsigned, S_U);
+ function From_U24 is new UC (Unsigned_24, S_U24);
+ function From_WC is new UC (Wide_Character, S_WC);
+ function From_WWC is new UC (Wide_Wide_Character, S_WWC);
-- Unchecked conversions from the stream type to elementary type
- function To_AD is new UC (S_AD, Fat_Pointer);
- function To_AS is new UC (S_AS, Thin_Pointer);
- function To_F is new UC (S_F, Float);
- function To_I is new UC (S_I, Integer);
- function To_I24 is new UC (S_I24, Integer_24);
- function To_LF is new UC (S_LF, Long_Float);
- function To_LI is new UC (S_LI, Long_Integer);
- function To_LLF is new UC (S_LLF, Long_Long_Float);
- function To_LLI is new UC (S_LLI, Long_Long_Integer);
- function To_LLU is new UC (S_LLU, UST.Long_Long_Unsigned);
- function To_LU is new UC (S_LU, UST.Long_Unsigned);
- function To_SF is new UC (S_SF, Short_Float);
- function To_SI is new UC (S_SI, Short_Integer);
- function To_SSI is new UC (S_SSI, Short_Short_Integer);
- function To_SSU is new UC (S_SSU, UST.Short_Short_Unsigned);
- function To_SU is new UC (S_SU, UST.Short_Unsigned);
- function To_U is new UC (S_U, UST.Unsigned);
- function To_U24 is new UC (S_U24, Unsigned_24);
- function To_WC is new UC (S_WC, Wide_Character);
- function To_WWC is new UC (S_WWC, Wide_Wide_Character);
+ function To_AD is new UC (S_AD, Fat_Pointer);
+ function To_AS is new UC (S_AS, Thin_Pointer);
+ function To_F is new UC (S_F, Float);
+ function To_I is new UC (S_I, Integer);
+ function To_I24 is new UC (S_I24, Integer_24);
+ function To_LF is new UC (S_LF, Long_Float);
+ function To_LI is new UC (S_LI, Long_Integer);
+ function To_LLF is new UC (S_LLF, Long_Long_Float);
+ function To_LLI is new UC (S_LLI, Long_Long_Integer);
+ function To_LLLI is new UC (S_LLLI, Long_Long_Long_Integer);
+ function To_LLLU is new UC (S_LLLU, UST.Long_Long_Long_Unsigned);
+ function To_LLU is new UC (S_LLU, UST.Long_Long_Unsigned);
+ function To_LU is new UC (S_LU, UST.Long_Unsigned);
+ function To_SF is new UC (S_SF, Short_Float);
+ function To_SI is new UC (S_SI, Short_Integer);
+ function To_SSI is new UC (S_SSI, Short_Short_Integer);
+ function To_SSU is new UC (S_SSU, UST.Short_Short_Unsigned);
+ function To_SU is new UC (S_SU, UST.Short_Unsigned);
+ function To_U is new UC (S_U, UST.Unsigned);
+ function To_U24 is new UC (S_U24, Unsigned_24);
+ function To_WC is new UC (S_WC, Wide_Character);
+ function To_WWC is new UC (S_WWC, Wide_Wide_Character);
-----------------
-- XDR_Support --
@@ -393,6 +401,53 @@ package body System.Stream_Attributes is
end if;
end I_LLI;
+ ------------
+ -- I_LLLI --
+ ------------
+
+ function I_LLLI (Stream : not null access RST) return Long_Long_Long_Integer
+ is
+ T : S_LLLI;
+ L : SEO;
+
+ begin
+ if XDR_Support then
+ raise Ada.IO_Exceptions.Device_Error;
+ end if;
+
+ Ada.Streams.Read (Stream.all, T, L);
+
+ if L < T'Last then
+ raise Err;
+ else
+ return To_LLLI (T);
+ end if;
+ end I_LLLI;
+
+ ------------
+ -- I_LLLU --
+ ------------
+
+ function I_LLLU
+ (Stream : not null access RST) return UST.Long_Long_Long_Unsigned
+ is
+ T : S_LLLU;
+ L : SEO;
+
+ begin
+ if XDR_Support then
+ raise Ada.IO_Exceptions.Device_Error;
+ end if;
+
+ Ada.Streams.Read (Stream.all, T, L);
+
+ if L < T'Last then
+ raise Err;
+ else
+ return To_LLLU (T);
+ end if;
+ end I_LLLU;
+
-----------
-- I_LLU --
-----------
@@ -799,6 +854,35 @@ package body System.Stream_Attributes is
Ada.Streams.Write (Stream.all, From_LLI (Item));
end W_LLI;
+ ------------
+ -- W_LLLI --
+ ------------
+
+ procedure W_LLLI
+ (Stream : not null access RST; Item : Long_Long_Long_Integer) is
+ begin
+ if XDR_Support then
+ raise Ada.IO_Exceptions.Device_Error;
+ end if;
+
+ Ada.Streams.Write (Stream.all, From_LLLI (Item));
+ end W_LLLI;
+
+ ------------
+ -- W_LLLU --
+ ------------
+
+ procedure W_LLLU
+ (Stream : not null access RST; Item : UST.Long_Long_Long_Unsigned)
+ is
+ begin
+ if XDR_Support then
+ raise Ada.IO_Exceptions.Device_Error;
+ end if;
+
+ Ada.Streams.Write (Stream.all, From_LLLU (Item));
+ end W_LLLU;
+
-----------
-- W_LLU --
-----------
diff --git a/gcc/ada/libgnat/s-stratt.ads b/gcc/ada/libgnat/s-stratt.ads
index c8c453a..965dff6 100644
--- a/gcc/ada/libgnat/s-stratt.ads
+++ b/gcc/ada/libgnat/s-stratt.ads
@@ -104,29 +104,34 @@ package System.Stream_Attributes is
-- is the same for all elementary types (no bounds or discriminants
-- are involved).
- function I_AD (Stream : not null access RST) return Fat_Pointer;
- function I_AS (Stream : not null access RST) return Thin_Pointer;
- function I_B (Stream : not null access RST) return Boolean;
- function I_C (Stream : not null access RST) return Character;
- function I_F (Stream : not null access RST) return Float;
- function I_I (Stream : not null access RST) return Integer;
- function I_I24 (Stream : not null access RST) return Integer_24;
- function I_LF (Stream : not null access RST) return Long_Float;
- function I_LI (Stream : not null access RST) return Long_Integer;
- function I_LLF (Stream : not null access RST) return Long_Long_Float;
- function I_LLI (Stream : not null access RST) return Long_Long_Integer;
- function I_LLU (Stream : not null access RST) return UST.Long_Long_Unsigned;
- function I_LU (Stream : not null access RST) return UST.Long_Unsigned;
- function I_SF (Stream : not null access RST) return Short_Float;
- function I_SI (Stream : not null access RST) return Short_Integer;
- function I_SSI (Stream : not null access RST) return Short_Short_Integer;
- function I_SSU (Stream : not null access RST) return
- UST.Short_Short_Unsigned;
- function I_SU (Stream : not null access RST) return UST.Short_Unsigned;
- function I_U (Stream : not null access RST) return UST.Unsigned;
- function I_U24 (Stream : not null access RST) return Unsigned_24;
- function I_WC (Stream : not null access RST) return Wide_Character;
- function I_WWC (Stream : not null access RST) return Wide_Wide_Character;
+ function I_AD (Stream : not null access RST) return Fat_Pointer;
+ function I_AS (Stream : not null access RST) return Thin_Pointer;
+ function I_B (Stream : not null access RST) return Boolean;
+ function I_C (Stream : not null access RST) return Character;
+ function I_F (Stream : not null access RST) return Float;
+ function I_I (Stream : not null access RST) return Integer;
+ function I_I24 (Stream : not null access RST) return Integer_24;
+ function I_LF (Stream : not null access RST) return Long_Float;
+ function I_LI (Stream : not null access RST) return Long_Integer;
+ function I_LLF (Stream : not null access RST) return Long_Long_Float;
+ function I_LLI (Stream : not null access RST) return Long_Long_Integer;
+ function I_LLLI (Stream : not null access RST) return
+ Long_Long_Long_Integer;
+ function I_LLLU (Stream : not null access RST) return
+ UST.Long_Long_Long_Unsigned;
+ function I_LLU (Stream : not null access RST) return
+ UST.Long_Long_Unsigned;
+ function I_LU (Stream : not null access RST) return UST.Long_Unsigned;
+ function I_SF (Stream : not null access RST) return Short_Float;
+ function I_SI (Stream : not null access RST) return Short_Integer;
+ function I_SSI (Stream : not null access RST) return Short_Short_Integer;
+ function I_SSU (Stream : not null access RST) return
+ UST.Short_Short_Unsigned;
+ function I_SU (Stream : not null access RST) return UST.Short_Unsigned;
+ function I_U (Stream : not null access RST) return UST.Unsigned;
+ function I_U24 (Stream : not null access RST) return Unsigned_24;
+ function I_WC (Stream : not null access RST) return Wide_Character;
+ function I_WWC (Stream : not null access RST) return Wide_Wide_Character;
-----------------------
-- Output Procedures --
@@ -137,30 +142,34 @@ package System.Stream_Attributes is
-- 'Write and 'Output because there are no discriminants or bounds to
-- be written.
- procedure W_AD (Stream : not null access RST; Item : Fat_Pointer);
- procedure W_AS (Stream : not null access RST; Item : Thin_Pointer);
- procedure W_B (Stream : not null access RST; Item : Boolean);
- procedure W_C (Stream : not null access RST; Item : Character);
- procedure W_F (Stream : not null access RST; Item : Float);
- procedure W_I (Stream : not null access RST; Item : Integer);
- procedure W_I24 (Stream : not null access RST; Item : Integer_24);
- procedure W_LF (Stream : not null access RST; Item : Long_Float);
- procedure W_LI (Stream : not null access RST; Item : Long_Integer);
- procedure W_LLF (Stream : not null access RST; Item : Long_Long_Float);
- procedure W_LLI (Stream : not null access RST; Item : Long_Long_Integer);
- procedure W_LLU (Stream : not null access RST; Item :
- UST.Long_Long_Unsigned);
- procedure W_LU (Stream : not null access RST; Item : UST.Long_Unsigned);
- procedure W_SF (Stream : not null access RST; Item : Short_Float);
- procedure W_SI (Stream : not null access RST; Item : Short_Integer);
- procedure W_SSI (Stream : not null access RST; Item : Short_Short_Integer);
- procedure W_SSU (Stream : not null access RST; Item :
- UST.Short_Short_Unsigned);
- procedure W_SU (Stream : not null access RST; Item : UST.Short_Unsigned);
- procedure W_U (Stream : not null access RST; Item : UST.Unsigned);
- procedure W_U24 (Stream : not null access RST; Item : Unsigned_24);
- procedure W_WC (Stream : not null access RST; Item : Wide_Character);
- procedure W_WWC (Stream : not null access RST; Item : Wide_Wide_Character);
+ procedure W_AD (Stream : not null access RST; Item : Fat_Pointer);
+ procedure W_AS (Stream : not null access RST; Item : Thin_Pointer);
+ procedure W_B (Stream : not null access RST; Item : Boolean);
+ procedure W_C (Stream : not null access RST; Item : Character);
+ procedure W_F (Stream : not null access RST; Item : Float);
+ procedure W_I (Stream : not null access RST; Item : Integer);
+ procedure W_I24 (Stream : not null access RST; Item : Integer_24);
+ procedure W_LF (Stream : not null access RST; Item : Long_Float);
+ procedure W_LI (Stream : not null access RST; Item : Long_Integer);
+ procedure W_LLF (Stream : not null access RST; Item : Long_Long_Float);
+ procedure W_LLI (Stream : not null access RST; Item : Long_Long_Integer);
+ procedure W_LLLI (Stream : not null access RST; Item :
+ Long_Long_Long_Integer);
+ procedure W_LLLU (Stream : not null access RST; Item :
+ UST.Long_Long_Long_Unsigned);
+ procedure W_LLU (Stream : not null access RST; Item :
+ UST.Long_Long_Unsigned);
+ procedure W_LU (Stream : not null access RST; Item : UST.Long_Unsigned);
+ procedure W_SF (Stream : not null access RST; Item : Short_Float);
+ procedure W_SI (Stream : not null access RST; Item : Short_Integer);
+ procedure W_SSI (Stream : not null access RST; Item : Short_Short_Integer);
+ procedure W_SSU (Stream : not null access RST; Item :
+ UST.Short_Short_Unsigned);
+ procedure W_SU (Stream : not null access RST; Item : UST.Short_Unsigned);
+ procedure W_U (Stream : not null access RST; Item : UST.Unsigned);
+ procedure W_U24 (Stream : not null access RST; Item : Unsigned_24);
+ procedure W_WC (Stream : not null access RST; Item : Wide_Character);
+ procedure W_WWC (Stream : not null access RST; Item : Wide_Wide_Character);
function Block_IO_OK return Boolean;
-- Indicate whether the current setting supports block IO. See
@@ -177,6 +186,8 @@ private
pragma Inline (I_LI);
pragma Inline (I_LLF);
pragma Inline (I_LLI);
+ pragma Inline (I_LLLI);
+ pragma Inline (I_LLLU);
pragma Inline (I_LLU);
pragma Inline (I_LU);
pragma Inline (I_SF);
@@ -198,6 +209,8 @@ private
pragma Inline (W_LI);
pragma Inline (W_LLF);
pragma Inline (W_LLI);
+ pragma Inline (W_LLLI);
+ pragma Inline (W_LLLU);
pragma Inline (W_LLU);
pragma Inline (W_LU);
pragma Inline (W_SF);
diff --git a/gcc/ada/libgnat/s-trasym.ads b/gcc/ada/libgnat/s-trasym.ads
index e974ee9..fbeec8d 100644
--- a/gcc/ada/libgnat/s-trasym.ads
+++ b/gcc/ada/libgnat/s-trasym.ads
@@ -33,7 +33,8 @@
-- The full capability is currently supported on the following targets:
--- GNU/Linux x86, x86_64, ia64
+-- GNU/Linux x86, x86_64
+-- Windows x86, x86_64
-- Note: on targets other than those listed above, a dummy implementation
-- of the body returns a series of LF separated strings of the form "0x..."
diff --git a/gcc/ada/libgnat/s-valdec.adb b/gcc/ada/libgnat/s-vade128.ads
index 99fffaf..8edc742 100644
--- a/gcc/ada/libgnat/s-valdec.adb
+++ b/gcc/ada/libgnat/s-vade128.ads
@@ -2,11 +2,11 @@
-- --
-- GNAT COMPILER COMPONENTS --
-- --
--- S Y S T E M . V A L _ D E C --
+-- S Y S T E M . V A L _ D E C I M A L _ 1 2 8 --
-- --
--- B o d y --
+-- S p e c --
-- --
--- Copyright (C) 1992-2020, Free Software Foundation, Inc. --
+-- Copyright (C) 2020, 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- --
@@ -29,40 +29,32 @@
-- --
------------------------------------------------------------------------------
-with System.Val_Real; use System.Val_Real;
+-- This package contains routines for scanning values for decimal fixed point
+-- types up to 128-bit mantissa, for use in Text_IO.Decimal_IO, and the Value
+-- attribute for such decimal types.
-package body System.Val_Dec is
+with Interfaces;
+with System.Arith_128;
+with System.Value_D;
- ------------------
- -- Scan_Decimal --
- ------------------
+package System.Val_Decimal_128 is
+ pragma Preelaborate;
- -- For decimal types where Size < Integer'Size, it is fine to use
- -- the floating-point circuit, since it certainly has sufficient
- -- precision for any reasonable hardware, and we just don't support
- -- things on junk hardware.
+ subtype Int128 is Interfaces.Integer_128;
+ subtype Uns128 is Interfaces.Unsigned_128;
- function Scan_Decimal
+ package Impl is new Value_D (Int128, Uns128, Arith_128.Scaled_Divide128);
+
+ function Scan_Decimal128
(Str : String;
Ptr : not null access Integer;
Max : Integer;
- Scale : Integer) return Integer
- is
- Val : Long_Long_Float;
- begin
- Val := Scan_Real (Str, Ptr, Max);
- return Integer (Val * 10.0 ** Scale);
- end Scan_Decimal;
-
- -------------------
- -- Value_Decimal --
- -------------------
+ Scale : Integer) return Int128
+ renames Impl.Scan_Decimal;
- -- Again, we use the real circuit for this purpose
-
- function Value_Decimal (Str : String; Scale : Integer) return Integer is
- begin
- return Integer (Value_Real (Str) * 10.0 ** Scale);
- end Value_Decimal;
+ function Value_Decimal128
+ (Str : String;
+ Scale : Integer) return Int128
+ renames Impl.Value_Decimal;
-end System.Val_Dec;
+end System.Val_Decimal_128;
diff --git a/gcc/ada/libgnat/s-vade32.ads b/gcc/ada/libgnat/s-vade32.ads
new file mode 100644
index 0000000..b86ae52
--- /dev/null
+++ b/gcc/ada/libgnat/s-vade32.ads
@@ -0,0 +1,58 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . V A L _ D E C I M A L _ 3 2 --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains routines for scanning values for decimal fixed point
+-- types up to 32-bit mantissa, for use in Text_IO.Decimal_IO, and the Value
+-- attribute for such decimal types.
+
+with Interfaces;
+with System.Arith_32;
+with System.Value_D;
+
+package System.Val_Decimal_32 is
+ pragma Preelaborate;
+
+ subtype Int32 is Interfaces.Integer_32;
+ subtype Uns32 is Interfaces.Unsigned_32;
+
+ package Impl is new Value_D (Int32, Uns32, Arith_32.Scaled_Divide32);
+
+ function Scan_Decimal32
+ (Str : String;
+ Ptr : not null access Integer;
+ Max : Integer;
+ Scale : Integer) return Int32
+ renames Impl.Scan_Decimal;
+
+ function Value_Decimal32 (Str : String; Scale : Integer) return Int32
+ renames Impl.Value_Decimal;
+
+end System.Val_Decimal_32;
diff --git a/gcc/ada/libgnat/s-vallld.adb b/gcc/ada/libgnat/s-vade64.ads
index 4efa969..d3a5b4f 100644
--- a/gcc/ada/libgnat/s-vallld.adb
+++ b/gcc/ada/libgnat/s-vade64.ads
@@ -2,11 +2,11 @@
-- --
-- GNAT COMPILER COMPONENTS --
-- --
--- S Y S T E M . V A L _ L L D --
+-- S Y S T E M . V A L _ D E C I M A L _ 6 4 --
-- --
--- B o d y --
+-- S p e c --
-- --
--- Copyright (C) 1992-2020, Free Software Foundation, Inc. --
+-- Copyright (C) 2020, 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- --
@@ -29,42 +29,32 @@
-- --
------------------------------------------------------------------------------
-with System.Val_Real; use System.Val_Real;
+-- This package contains routines for scanning values for decimal fixed point
+-- types up to 64-bit mantissa, for use in Text_IO.Decimal_IO, and the Value
+-- attribute for such decimal types.
-package body System.Val_LLD is
+with Interfaces;
+with System.Arith_64;
+with System.Value_D;
- ----------------------------
- -- Scan_Long_Long_Decimal --
- ----------------------------
+package System.Val_Decimal_64 is
+ pragma Preelaborate;
- -- We use the floating-point circuit for now, this will be OK on a PC,
- -- but definitely does NOT have the required precision if the longest
- -- float type is IEEE double. This must be fixed in the future ???
+ subtype Int64 is Interfaces.Integer_64;
+ subtype Uns64 is Interfaces.Unsigned_64;
- function Scan_Long_Long_Decimal
+ package Impl is new Value_D (Int64, Uns64, Arith_64.Scaled_Divide64);
+
+ function Scan_Decimal64
(Str : String;
Ptr : not null access Integer;
Max : Integer;
- Scale : Integer) return Long_Long_Integer
- is
- Val : Long_Long_Float;
- begin
- Val := Scan_Real (Str, Ptr, Max);
- return Long_Long_Integer (Val * 10.0 ** Scale);
- end Scan_Long_Long_Decimal;
-
- -----------------------------
- -- Value_Long_Long_Decimal --
- -----------------------------
-
- -- Again we cheat and use floating-point ???
+ Scale : Integer) return Int64
+ renames Impl.Scan_Decimal;
- function Value_Long_Long_Decimal
+ function Value_Decimal64
(Str : String;
- Scale : Integer) return Long_Long_Integer
- is
- begin
- return Long_Long_Integer (Value_Real (Str) * 10.0 ** Scale);
- end Value_Long_Long_Decimal;
+ Scale : Integer) return Int64
+ renames Impl.Value_Decimal;
-end System.Val_LLD;
+end System.Val_Decimal_64;
diff --git a/gcc/ada/libgnat/s-vafi128.ads b/gcc/ada/libgnat/s-vafi128.ads
new file mode 100644
index 0000000..03fbe80
--- /dev/null
+++ b/gcc/ada/libgnat/s-vafi128.ads
@@ -0,0 +1,60 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . V A L _ F I X E D _ 1 2 8 --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains routines for scanning values for ordinary fixed point
+-- types up to 128-bit small and mantissa, for use in Text_IO.Decimal_IO, and
+-- the Value attribute for such decimal types.
+
+with Interfaces;
+with System.Arith_128;
+with System.Value_F;
+
+package System.Val_Fixed_128 is
+ pragma Preelaborate;
+
+ subtype Int128 is Interfaces.Integer_128;
+ subtype Uns128 is Interfaces.Unsigned_128;
+
+ package Impl is new Value_F (Int128, Uns128, Arith_128.Scaled_Divide128);
+
+ function Scan_Fixed128
+ (Str : String;
+ Ptr : not null access Integer;
+ Max : Integer;
+ Num : Int128;
+ Den : Int128) return Int128
+ renames Impl.Scan_Fixed;
+
+ function Value_Fixed128
+ (Str : String; Num : Int128; Den : Int128) return Int128
+ renames Impl.Value_Fixed;
+
+end System.Val_Fixed_128;
diff --git a/gcc/ada/libgnat/s-vafi32.ads b/gcc/ada/libgnat/s-vafi32.ads
new file mode 100644
index 0000000..6235a82
--- /dev/null
+++ b/gcc/ada/libgnat/s-vafi32.ads
@@ -0,0 +1,60 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . V A L _ F I X E D _ 3 2 --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains routines for scanning values for decimal fixed point
+-- types up to 32-bit small and mantissa, for use in Text_IO.Decimal_IO, and
+-- the Value attribute for such decimal types.
+
+with Interfaces;
+with System.Arith_32;
+with System.Value_F;
+
+package System.Val_Fixed_32 is
+ pragma Preelaborate;
+
+ subtype Int32 is Interfaces.Integer_32;
+ subtype Uns32 is Interfaces.Unsigned_32;
+
+ package Impl is new Value_F (Int32, Uns32, Arith_32.Scaled_Divide32);
+
+ function Scan_Fixed32
+ (Str : String;
+ Ptr : not null access Integer;
+ Max : Integer;
+ Num : Int32;
+ Den : Int32) return Int32
+ renames Impl.Scan_Fixed;
+
+ function Value_Fixed32
+ (Str : String; Num : Int32; Den : Int32) return Int32
+ renames Impl.Value_Fixed;
+
+end System.Val_Fixed_32;
diff --git a/gcc/ada/libgnat/s-vafi64.ads b/gcc/ada/libgnat/s-vafi64.ads
new file mode 100644
index 0000000..9f98df4
--- /dev/null
+++ b/gcc/ada/libgnat/s-vafi64.ads
@@ -0,0 +1,60 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . V A L _ F I X E D _ 6 4 --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains routines for scanning values for decimal fixed point
+-- types up to 64-bit small and mantissa, for use in Text_IO.Decimal_IO, and
+-- the Value attribute for such decimal types.
+
+with Interfaces;
+with System.Arith_64;
+with System.Value_F;
+
+package System.Val_Fixed_64 is
+ pragma Preelaborate;
+
+ subtype Int64 is Interfaces.Integer_64;
+ subtype Uns64 is Interfaces.Unsigned_64;
+
+ package Impl is new Value_F (Int64, Uns64, Arith_64.Scaled_Divide64);
+
+ function Scan_Fixed64
+ (Str : String;
+ Ptr : not null access Integer;
+ Max : Integer;
+ Num : Int64;
+ Den : Int64) return Int64
+ renames Impl.Scan_Fixed;
+
+ function Value_Fixed64
+ (Str : String; Num : Int64; Den : Int64) return Int64
+ renames Impl.Value_Fixed;
+
+end System.Val_Fixed_64;
diff --git a/gcc/ada/libgnat/s-valrea.adb b/gcc/ada/libgnat/s-valrea.adb
index 1a47dc2..693b261 100644
--- a/gcc/ada/libgnat/s-valrea.adb
+++ b/gcc/ada/libgnat/s-valrea.adb
@@ -29,282 +29,58 @@
-- --
------------------------------------------------------------------------------
-with System.Val_Util; use System.Val_Util;
with System.Float_Control;
+with System.Unsigned_Types; use System.Unsigned_Types;
+with System.Val_Util; use System.Val_Util;
+with System.Value_R;
package body System.Val_Real is
- procedure Scan_Integral_Digits
- (Str : String;
- Index : in out Integer;
- Max : Integer;
- Value : out Long_Long_Integer;
- Scale : out Integer;
- Base_Violation : in out Boolean;
- Base : Long_Long_Integer := 10;
- Base_Specified : Boolean := False);
- -- Scan the integral part of a real (i.e: before decimal separator)
- --
- -- The string parsed is Str (Index .. Max), and after the call Index will
- -- point to the first non parsed character.
- --
- -- For each digit parsed either value := value * base + digit, or scale
- -- is incremented by 1.
- --
- -- Base_Violation will be set to True a digit found is not part of the Base
-
- procedure Scan_Decimal_Digits
- (Str : String;
- Index : in out Integer;
- Max : Integer;
- Value : in out Long_Long_Integer;
- Scale : in out Integer;
- Base_Violation : in out Boolean;
- Base : Long_Long_Integer := 10;
- Base_Specified : Boolean := False);
- -- Scan the decimal part of a real (i.e: after decimal separator)
- --
- -- The string parsed is Str (Index .. Max), and after the call Index will
- -- point to the first non parsed character.
- --
- -- For each digit parsed value = value * base + digit and scale is
- -- decremented by 1. If precision limit is reached remaining digits are
- -- still parsed but ignored.
- --
- -- Base_Violation will be set to True a digit found is not part of the Base
-
- subtype Char_As_Digit is Long_Long_Integer range -2 .. 15;
- subtype Valid_Digit is Char_As_Digit range 0 .. Char_As_Digit'Last;
- Underscore : constant Char_As_Digit := -2;
- E_Digit : constant Char_As_Digit := 14;
-
- function As_Digit (C : Character) return Char_As_Digit;
- -- Given a character return the digit it represent. If the character is
- -- not a digit then a negative value is returned, -2 for underscore and
- -- -1 for any other character.
-
- Precision_Limit : constant Long_Long_Integer :=
- 2 ** (Long_Long_Float'Machine_Mantissa - 1) - 1;
- -- This is an upper bound for the number of bits used to represent the
- -- mantissa. Beyond that number, any digits parsed are useless.
-
- --------------
- -- As_Digit --
- --------------
-
- function As_Digit (C : Character) return Char_As_Digit is
- begin
- case C is
- when '0' .. '9' =>
- return Character'Pos (C) - Character'Pos ('0');
- when 'a' .. 'f' =>
- return Character'Pos (C) - (Character'Pos ('a') - 10);
- when 'A' .. 'F' =>
- return Character'Pos (C) - (Character'Pos ('A') - 10);
- when '_' =>
- return Underscore;
- when others =>
- return -1;
- end case;
- end As_Digit;
-
- -------------------------
- -- Scan_Decimal_Digits --
- -------------------------
-
- procedure Scan_Decimal_Digits
- (Str : String;
- Index : in out Integer;
- Max : Integer;
- Value : in out Long_Long_Integer;
- Scale : in out Integer;
- Base_Violation : in out Boolean;
- Base : Long_Long_Integer := 10;
- Base_Specified : Boolean := False)
-
+ package Impl is new Value_R (Long_Long_Unsigned, Floating => True);
+
+ function Integer_to_Real
+ (Str : String;
+ Val : Long_Long_Unsigned;
+ Base : Unsigned;
+ Scale : Integer;
+ Minus : Boolean) return Long_Long_Float;
+ -- Convert the real value from integer to real representation
+
+ ---------------------
+ -- Integer_to_Real --
+ ---------------------
+
+ function Integer_to_Real
+ (Str : String;
+ Val : Long_Long_Unsigned;
+ Base : Unsigned;
+ Scale : Integer;
+ Minus : Boolean) return Long_Long_Float
is
- Precision_Limit_Reached : Boolean := False;
- -- Set to True if addition of a digit will cause Value to be superior
- -- to Precision_Limit.
-
- Digit : Char_As_Digit;
- -- The current digit.
+ pragma Unsuppress (Range_Check);
- Trailing_Zeros : Natural := 0;
- -- Number of trailing zeros at a given point.
+ R_Val : Long_Long_Float;
begin
- pragma Assert (Base in 2 .. 16);
-
- -- If initial Scale is not 0 then it means that Precision_Limit was
- -- reached during integral part scanning.
- if Scale > 0 then
- Precision_Limit_Reached := True;
- end if;
-
- -- The function precondition is that the first character is a valid
- -- digit.
- Digit := As_Digit (Str (Index));
-
- loop
- -- Check if base is correct. If the base is not specified the digit
- -- E or e cannot be considered as a base violation as it can be used
- -- for exponentiation.
- if Digit >= Base then
- if Base_Specified then
- Base_Violation := True;
- elsif Digit = E_Digit then
- return;
- else
- Base_Violation := True;
- end if;
- end if;
-
- -- If precision limit has been reached just ignore any remaining
- -- digits for the computation of Value and Scale. The scanning
- -- should continue only to assess the validity of the string
- if not Precision_Limit_Reached then
- if Digit = 0 then
- -- Trailing '0' digits are ignored unless a non-zero digit is
- -- found.
- Trailing_Zeros := Trailing_Zeros + 1;
- else
-
- -- Handle accumulated zeros.
- for J in 1 .. Trailing_Zeros loop
- if Value > Precision_Limit / Base then
- Precision_Limit_Reached := True;
- exit;
- else
- Value := Value * Base;
- Scale := Scale - 1;
- end if;
- end loop;
-
- -- Reset trailing zero counter
- Trailing_Zeros := 0;
-
- -- Handle current non zero digit
- if Value > (Precision_Limit - Digit) / Base then
- Precision_Limit_Reached := True;
- else
- Value := Value * Base + Digit;
- Scale := Scale - 1;
- end if;
- end if;
- end if;
+ -- We call the floating-point processor reset routine so we can be sure
+ -- that the processor is properly set for conversions. This is notably
+ -- needed on Windows, where calls to the operating system randomly reset
+ -- the processor into 64-bit mode.
- -- Check next character
- Index := Index + 1;
-
- if Index > Max then
- return;
- end if;
-
- Digit := As_Digit (Str (Index));
-
- if Digit < 0 then
- if Digit = Underscore and Index + 1 <= Max then
- -- Underscore is only allowed if followed by a digit
- Digit := As_Digit (Str (Index + 1));
- if Digit in Valid_Digit then
- Index := Index + 1;
- else
- return;
- end if;
- else
- -- Neither a valid underscore nor a digit.
- return;
- end if;
- end if;
- end loop;
- end Scan_Decimal_Digits;
-
- --------------------------
- -- Scan_Integral_Digits --
- --------------------------
-
- procedure Scan_Integral_Digits
- (Str : String;
- Index : in out Integer;
- Max : Integer;
- Value : out Long_Long_Integer;
- Scale : out Integer;
- Base_Violation : in out Boolean;
- Base : Long_Long_Integer := 10;
- Base_Specified : Boolean := False)
- is
- Precision_Limit_Reached : Boolean := False;
- -- Set to True if addition of a digit will cause Value to be superior
- -- to Precision_Limit.
-
- Digit : Char_As_Digit;
- -- The current digit
- begin
-
- -- Initialize Scale and Value
- Value := 0;
- Scale := 0;
-
- -- The function precondition is that the first character is a valid
- -- digit.
- Digit := As_Digit (Str (Index));
-
- loop
- -- Check if base is correct. If the base is not specified the digit
- -- E or e cannot be considered as a base violation as it can be used
- -- for exponentiation.
- if Digit >= Base then
- if Base_Specified then
- Base_Violation := True;
- elsif Digit = E_Digit then
- return;
- else
- Base_Violation := True;
- end if;
- end if;
-
- if Precision_Limit_Reached then
- -- Precision limit has been reached so just update the exponent
- Scale := Scale + 1;
- else
- pragma Assert (Base /= 0);
+ System.Float_Control.Reset;
- if Value > (Precision_Limit - Digit) / Base then
- -- Updating Value will overflow so ignore this digit and any
- -- following ones. Only update the scale
- Precision_Limit_Reached := True;
- Scale := Scale + 1;
- else
- Value := Value * Base + Digit;
- end if;
- end if;
+ -- Compute the final value
- -- Look for the next character
- Index := Index + 1;
- if Index > Max then
- return;
- end if;
+ R_Val := Long_Long_Float (Val) * Long_Long_Float (Base) ** Scale;
- Digit := As_Digit (Str (Index));
+ -- Finally deal with initial minus sign, note that this processing is
+ -- done even if Uval is zero, so that -0.0 is correctly interpreted.
- if Digit not in Valid_Digit then
- -- Next character is not a digit. In that case stop scanning
- -- unless the next chracter is an underscore followed by a digit.
- if Digit = Underscore and Index + 1 <= Max then
- Digit := As_Digit (Str (Index + 1));
- if Digit in Valid_Digit then
- Index := Index + 1;
- else
- return;
- end if;
- else
- return;
- end if;
- end if;
- end loop;
+ return (if Minus then -R_Val else R_Val);
- end Scan_Integral_Digits;
+ exception
+ when Constraint_Error => Bad_Value (Str);
+ end Integer_to_Real;
---------------
-- Scan_Real --
@@ -315,197 +91,17 @@ package body System.Val_Real is
Ptr : not null access Integer;
Max : Integer)
return Long_Long_Float
-
is
- Start : Positive;
- -- Position of starting non-blank character
-
+ Base : Unsigned;
+ Scale : Integer;
+ Extra : Unsigned;
Minus : Boolean;
- -- Set to True if minus sign is present, otherwise to False
-
- Index : Integer;
- -- Local copy of string pointer
-
- Int_Value : Long_Long_Integer := -1;
- -- Mantissa as an Integer
-
- Int_Scale : Integer := 0;
- -- Exponent value
-
- Base_Violation : Boolean := False;
- -- If True some digits where not in the base. The float is still scan
- -- till the end even if an error will be raised.
-
- Uval : Long_Long_Float := 0.0;
- -- Contain the final value at the end of the function
-
- After_Point : Boolean := False;
- -- True if a decimal should be parsed
-
- Base : Long_Long_Integer := 10;
- -- Current base (default: 10)
-
- Base_Char : Character := ASCII.NUL;
- -- Character used to set the base. If Nul this means that default
- -- base is used.
+ Val : Long_Long_Unsigned;
begin
- -- We do not tolerate strings with Str'Last = Positive'Last
-
- if Str'Last = Positive'Last then
- raise Program_Error with
- "string upper bound is Positive'Last, not supported";
- end if;
-
- -- We call the floating-point processor reset routine so that we can
- -- be sure the floating-point processor is properly set for conversion
- -- calls. This is notably need on Windows, where calls to the operating
- -- system randomly reset the processor into 64-bit mode.
-
- System.Float_Control.Reset;
-
- -- Scan the optional sign
- Scan_Sign (Str, Ptr, Max, Minus, Start);
- Index := Ptr.all;
- Ptr.all := Start;
-
- -- First character can be either a decimal digit or a dot.
- if Str (Index) in '0' .. '9' then
- pragma Annotate
- (CodePeer, Intentional,
- "test always true", "defensive code below");
-
- -- If this is a digit it can indicates either the float decimal
- -- part or the base to use
- Scan_Integral_Digits
- (Str,
- Index,
- Max => Max,
- Value => Int_Value,
- Scale => Int_Scale,
- Base_Violation => Base_Violation,
- Base => 10);
- elsif Str (Index) = '.' and then
- -- A dot is only allowed if followed by a digit.
- Index < Max and then
- Str (Index + 1) in '0' .. '9'
- then
- -- Initial point, allowed only if followed by digit (RM 3.5(47))
- After_Point := True;
- Index := Index + 1;
- Int_Value := 0;
- else
- Bad_Value (Str);
- end if;
-
- -- Check if the first number encountered is a base
- if Index < Max and then
- (Str (Index) = '#' or else Str (Index) = ':')
- then
- Base_Char := Str (Index);
- Base := Int_Value;
-
- -- Reset Int_Value to indicate that parsing of integral value should
- -- be done
- Int_Value := -1;
- if Base < 2 or else Base > 16 then
- Base_Violation := True;
- Base := 16;
- end if;
-
- Index := Index + 1;
-
- if Str (Index) = '.' and then
- Index < Max and then
- As_Digit (Str (Index + 1)) in Valid_Digit
- then
- After_Point := True;
- Index := Index + 1;
- Int_Value := 0;
- end if;
- end if;
-
- -- Does scanning of integral part needed
- if Int_Value < 0 then
- if Index > Max or else As_Digit (Str (Index)) not in Valid_Digit then
- Bad_Value (Str);
- end if;
-
- Scan_Integral_Digits
- (Str,
- Index,
- Max => Max,
- Value => Int_Value,
- Scale => Int_Scale,
- Base_Violation => Base_Violation,
- Base => Base,
- Base_Specified => Base_Char /= ASCII.NUL);
- end if;
-
- -- Do we have a dot ?
- if not After_Point and then
- Index <= Max and then
- Str (Index) = '.'
- then
- -- At this stage if After_Point was not set, this means that an
- -- integral part has been found. Thus the dot is valid even if not
- -- followed by a digit.
- if Index < Max and then As_Digit (Str (Index + 1)) in Valid_Digit then
- After_Point := True;
- end if;
-
- Index := Index + 1;
- end if;
-
- if After_Point then
- -- Parse decimal part
- Scan_Decimal_Digits
- (Str,
- Index,
- Max => Max,
- Value => Int_Value,
- Scale => Int_Scale,
- Base_Violation => Base_Violation,
- Base => Base,
- Base_Specified => Base_Char /= ASCII.NUL);
- end if;
-
- -- If an explicit base was specified ensure that the delimiter is found
- if Base_Char /= ASCII.NUL then
- if Index > Max or else Str (Index) /= Base_Char then
- Bad_Value (Str);
- else
- Index := Index + 1;
- end if;
- end if;
-
- -- Compute the final value
- Uval := Long_Long_Float (Int_Value);
-
- -- Update pointer and scan exponent.
- Ptr.all := Index;
-
- Int_Scale := Int_Scale + Scan_Exponent (Str,
- Ptr,
- Max,
- Real => True);
-
- Uval := Uval * Long_Long_Float (Base) ** Int_Scale;
-
- -- Here is where we check for a bad based number
- if Base_Violation then
- Bad_Value (Str);
-
- -- If OK, then deal with initial minus sign, note that this processing
- -- is done even if Uval is zero, so that -0.0 is correctly interpreted.
- else
- if Minus then
- return -Uval;
- else
- return Uval;
- end if;
- end if;
+ Val := Impl.Scan_Raw_Real (Str, Ptr, Max, Base, Scale, Extra, Minus);
+ return Integer_to_Real (Str, Val, Base, Scale, Minus);
end Scan_Real;
----------------
@@ -513,30 +109,16 @@ package body System.Val_Real is
----------------
function Value_Real (Str : String) return Long_Long_Float is
- begin
- -- We have to special case Str'Last = Positive'Last because the normal
- -- circuit ends up setting P to Str'Last + 1 which is out of bounds. We
- -- deal with this by converting to a subtype which fixes the bounds.
-
- if Str'Last = Positive'Last then
- declare
- subtype NT is String (1 .. Str'Length);
- begin
- return Value_Real (NT (Str));
- end;
+ Base : Unsigned;
+ Scale : Integer;
+ Extra : Unsigned;
+ Minus : Boolean;
+ Val : Long_Long_Unsigned;
- -- Normal case where Str'Last < Positive'Last
+ begin
+ Val := Impl.Value_Raw_Real (Str, Base, Scale, Extra, Minus);
- else
- declare
- V : Long_Long_Float;
- P : aliased Integer := Str'First;
- begin
- V := Scan_Real (Str, P'Access, Str'Last);
- Scan_Trailing_Blanks (Str, P);
- return V;
- end;
- end if;
+ return Integer_to_Real (Str, Val, Base, Scale, Minus);
end Value_Real;
end System.Val_Real;
diff --git a/gcc/ada/libgnat/s-valued.adb b/gcc/ada/libgnat/s-valued.adb
new file mode 100644
index 0000000..5fa8a99
--- /dev/null
+++ b/gcc/ada/libgnat/s-valued.adb
@@ -0,0 +1,257 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . V A L U E _ D --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with System.Unsigned_Types; use System.Unsigned_Types;
+with System.Val_Util; use System.Val_Util;
+with System.Value_R;
+
+package body System.Value_D is
+
+ package Impl is new Value_R (Uns, Floating => False);
+
+ function Integer_to_Decimal
+ (Str : String;
+ Val : Uns;
+ Base : Unsigned;
+ ScaleB : Integer;
+ Minus : Boolean;
+ Scale : Integer) return Int;
+ -- Convert the real value from integer to decimal representation
+
+ ------------------------
+ -- Integer_to_Decimal --
+ ------------------------
+
+ function Integer_to_Decimal
+ (Str : String;
+ Val : Uns;
+ Base : Unsigned;
+ ScaleB : Integer;
+ Minus : Boolean;
+ Scale : Integer) return Int
+ is
+ function Safe_Expont
+ (Base : Int;
+ Exp : in out Natural;
+ Factor : Int) return Int;
+ -- Return (Base ** Exp) * Factor if the computation does not overflow,
+ -- or else the number of the form (Base ** K) * Factor with the largest
+ -- magnitude if the former computation overflows. In both cases, Exp is
+ -- updated to contain the remaining power in the computation. Note that
+ -- Factor is expected to be positive in this context.
+
+ function Unsigned_To_Signed (Val : Uns) return Int;
+ -- Convert an integer value from unsigned to signed representation
+
+ -----------------
+ -- Safe_Expont --
+ -----------------
+
+ function Safe_Expont
+ (Base : Int;
+ Exp : in out Natural;
+ Factor : Int) return Int
+ is
+ pragma Assert (Base /= 0 and then Factor > 0);
+
+ Max : constant Int := Int'Last / Base;
+
+ Result : Int := Factor;
+
+ begin
+ while Exp > 0 and then Result <= Max loop
+ Result := Result * Base;
+ Exp := Exp - 1;
+ end loop;
+
+ return Result;
+ end Safe_Expont;
+
+ ------------------------
+ -- Unsigned_To_Signed --
+ ------------------------
+
+ function Unsigned_To_Signed (Val : Uns) return Int is
+ begin
+ -- Deal with overflow cases, and also with largest negative number
+
+ if Val > Uns (Int'Last) then
+ if Minus and then Val = Uns (-(Int'First)) then
+ return Int'First;
+ else
+ Bad_Value (Str);
+ end if;
+
+ -- Negative values
+
+ elsif Minus then
+ return -(Int (Val));
+
+ -- Positive values
+
+ else
+ return Int (Val);
+ end if;
+ end Unsigned_To_Signed;
+
+ begin
+ -- If the base of the value is 10 or its scaling factor is zero, then
+ -- add the scales (they are defined in the opposite sense) and apply
+ -- the result to the value, checking for overflow in the process.
+
+ if Base = 10 or else ScaleB = 0 then
+ declare
+ S : Integer := ScaleB + Scale;
+ V : Uns := Val;
+
+ begin
+ while S < 0 loop
+ V := V / 10;
+ S := S + 1;
+ end loop;
+
+ while S > 0 loop
+ if V <= Uns'Last / 10 then
+ V := V * 10;
+ S := S - 1;
+ else
+ Bad_Value (Str);
+ end if;
+ end loop;
+
+ return Unsigned_To_Signed (V);
+ end;
+
+ -- If the base of the value is not 10, use a scaled divide operation
+ -- to compute Val * (Base ** ScaleB) * (10 ** Scale).
+
+ else
+ declare
+ B : constant Int := Int (Base);
+ S : constant Integer := ScaleB;
+
+ V : Uns := Val;
+
+ Y, Z, Q, R : Int;
+
+ begin
+ -- If S is too negative, then drop trailing digits
+
+ if S < 0 then
+ declare
+ LS : Integer := -S;
+
+ begin
+ Y := 10 ** Integer'Max (0, Scale);
+ Z := Safe_Expont (B, LS, 10 ** Integer'Max (0, -Scale));
+
+ for J in 1 .. LS loop
+ V := V / Uns (B);
+ end loop;
+ end;
+
+ -- If S is too positive, then scale V up, which may then overflow
+
+ elsif S > 0 then
+ declare
+ LS : Integer := S;
+
+ begin
+ Y := Safe_Expont (B, LS, 10 ** Integer'Max (0, Scale));
+ Z := 10 ** Integer'Max (0, -Scale);
+
+ for J in 1 .. LS loop
+ if V <= Uns'Last / Uns (B) then
+ V := V * Uns (B);
+ else
+ Bad_Value (Str);
+ end if;
+ end loop;
+ end;
+
+ -- The case S equal to zero should have been handled earlier
+
+ else
+ raise Program_Error;
+ end if;
+
+ -- Perform a scale divide operation with rounding to match 'Image
+
+ Scaled_Divide (Unsigned_To_Signed (V), Y, Z, Q, R, Round => True);
+
+ return Q;
+ end;
+ end if;
+
+ exception
+ when Constraint_Error => Bad_Value (Str);
+ end Integer_to_Decimal;
+
+ ------------------
+ -- Scan_Decimal --
+ ------------------
+
+ function Scan_Decimal
+ (Str : String;
+ Ptr : not null access Integer;
+ Max : Integer;
+ Scale : Integer) return Int
+ is
+ Base : Unsigned;
+ ScaleB : Integer;
+ Extra : Unsigned;
+ Minus : Boolean;
+ Val : Uns;
+
+ begin
+ Val := Impl.Scan_Raw_Real (Str, Ptr, Max, Base, ScaleB, Extra, Minus);
+
+ return Integer_to_Decimal (Str, Val, Base, ScaleB, Minus, Scale);
+ end Scan_Decimal;
+
+ -------------------
+ -- Value_Decimal --
+ -------------------
+
+ function Value_Decimal (Str : String; Scale : Integer) return Int is
+ Base : Unsigned;
+ ScaleB : Integer;
+ Extra : Unsigned;
+ Minus : Boolean;
+ Val : Uns;
+
+ begin
+ Val := Impl.Value_Raw_Real (Str, Base, ScaleB, Extra, Minus);
+
+ return Integer_to_Decimal (Str, Val, Base, ScaleB, Minus, Scale);
+ end Value_Decimal;
+
+end System.Value_D;
diff --git a/gcc/ada/libgnat/s-valdec.ads b/gcc/ada/libgnat/s-valued.ads
index 05fab98..e27e171 100644
--- a/gcc/ada/libgnat/s-valdec.ads
+++ b/gcc/ada/libgnat/s-valued.ads
@@ -2,11 +2,11 @@
-- --
-- GNAT COMPILER COMPONENTS --
-- --
--- S Y S T E M . V A L _ D E C --
+-- S Y S T E M . V A L U E _ D --
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2020, Free Software Foundation, Inc. --
+-- Copyright (C) 2020, 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- --
@@ -29,18 +29,29 @@
-- --
------------------------------------------------------------------------------
--- This package contains routines for scanning decimal values where the size
--- of the type is no greater than Standard.Integer'Size, for use in Text_IO.
--- Decimal_IO, and the Value attribute for such decimal types.
+-- This package contains the routines for supporting the Value attribute for
+-- decimal fixed point types, and also for conversion operations required in
+-- Text_IO.Decimal_IO for such types.
-package System.Val_Dec is
+generic
+
+ type Int is range <>;
+
+ type Uns is mod <>;
+
+ with procedure Scaled_Divide
+ (X, Y, Z : Int;
+ Q, R : out Int;
+ Round : Boolean);
+
+package System.Value_D is
pragma Preelaborate;
function Scan_Decimal
(Str : String;
Ptr : not null access Integer;
Max : Integer;
- Scale : Integer) return Integer;
+ Scale : Integer) return Int;
-- This function scans the string starting at Str (Ptr.all) for a valid
-- real literal according to the syntax described in (RM 3.5(43)). The
-- substring scanned extends no further than Str (Max). There are three
@@ -49,8 +60,8 @@ package System.Val_Dec is
-- If a valid real literal is found after scanning past any initial spaces,
-- then Ptr.all is updated past the last character of the literal (but
-- trailing spaces are not scanned out). The value returned is the value
- -- Integer'Integer_Value (decimal-literal-value), using the given Scale
- -- to determine this value.
+ -- Int'Integer_Value (decimal-literal-value), using the given Scale to
+ -- determine this value.
--
-- If no valid real literal is found, then Ptr.all points either to an
-- initial non-digit character, or to Max + 1 if the field is all spaces
@@ -68,13 +79,12 @@ package System.Val_Dec is
-- special case of an all-blank string, and Ptr is unchanged, and hence
-- is greater than Max as required in this case.
- function Value_Decimal (Str : String; Scale : Integer) return Integer;
- -- Used in computing X'Value (Str) where X is a decimal fixed-point type
- -- whose size does not exceed Standard.Integer'Size. Str is the string
- -- argument of the attribute. Constraint_Error is raised if the string
- -- is malformed or if the value is out of range of Integer (not the
- -- range of the fixed-point type, that check must be done by the caller.
- -- Otherwise the value returned is the value Integer'Integer_Value
+ function Value_Decimal (Str : String; Scale : Integer) return Int;
+ -- Used in computing X'Value (Str) where X is a decimal fixed-point type.
+ -- Str is the string argument of the attribute. Constraint_Error is raised
+ -- if the string is malformed or if the value is out of range of Int (not
+ -- the range of the fixed-point type, which must be done by the caller).
+ -- Otherwise the value returned is the value Int'Integer_Value
-- (decimal-literal-value), using Scale to determine this value.
-end System.Val_Dec;
+end System.Value_D;
diff --git a/gcc/ada/libgnat/s-valuef.adb b/gcc/ada/libgnat/s-valuef.adb
new file mode 100644
index 0000000..9a54cf3
--- /dev/null
+++ b/gcc/ada/libgnat/s-valuef.adb
@@ -0,0 +1,364 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . V A L U E _ F --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with System.Unsigned_Types; use System.Unsigned_Types;
+with System.Val_Util; use System.Val_Util;
+with System.Value_R;
+
+package body System.Value_F is
+
+ -- The prerequisite of the implementation is that the computation of the
+ -- operands of the scaled divide does not unduly overflow when the small
+ -- is neither an integer nor the reciprocal of an integer, which means
+ -- that its numerator and denominator must be both not larger than the
+ -- smallest divide 2**(Int'Size - 1) / Base where Base ranges over the
+ -- supported values for the base of the literal. Given that the largest
+ -- supported base is 16, this gives a limit of 2**(Int'Size - 5).
+
+ package Impl is new Value_R (Uns, Floating => False);
+
+ function Integer_To_Fixed
+ (Str : String;
+ Val : Uns;
+ Base : Unsigned;
+ ScaleB : Integer;
+ Extra : Unsigned;
+ Minus : Boolean;
+ Num : Int;
+ Den : Int) return Int;
+ -- Convert the real value from integer to fixed point representation
+
+ -- The goal is to compute Val * (Base ** ScaleB) / (Num / Den) with correct
+ -- rounding for all decimal values output by Typ'Image, that is to say up
+ -- to Typ'Aft decimal digits. Unlike for the output, the RM does not say
+ -- what the rounding must be for the input, but a reasonable exegesis of
+ -- the intent is that Typ'Value o Typ'Image should be the identity, which
+ -- is made possible because 'Aft is defined such that 'Image is injective.
+
+ -- For a type with a mantissa of M bits including the sign, the number N1
+ -- of decimal digits required to represent all the numbers is given by:
+
+ -- N1 = ceil ((M - 1) * log 2 / log 10) [N1 = 10/19/39 for M = 32/64/128]
+
+ -- but this mantissa can represent any set of contiguous numbers with only
+ -- N2 different decimal digits where:
+
+ -- N2 = floor ((M - 1) * log 2 / log 10) [N2 = 9/18/38 for M = 32/64/128]
+
+ -- Of course N1 = N2 + 1 holds, which means both that Val may not contain
+ -- enough significant bits to represent all the values of the type and that
+ -- 1 extra decimal digit contains the information for the missing bits.
+
+ -- Therefore the actual computation to be performed is
+
+ -- V = (Val * Base + Extra) * (Base ** (ScaleB - 1)) / (Num / Den)
+
+ -- using two steps of scaled divide if Extra is positive and ScaleB too
+
+ -- (1) Val * (Den * (Base ** ScaleB)) = Q1 * Num + R1
+
+ -- (2) Extra * (Den * (Base ** ScaleB)) = Q2 * -Base + R2
+
+ -- which yields after dividing (1) by Num and (2) by Num * Base and summing
+
+ -- V = Q1 + (R1 - Q2) / Num + R2 / (Num * Base)
+
+ -- but we get rid of the third term by using a rounding divide for (2).
+
+ -- This works only if Den * (Base ** ScaleB) does not overflow for inputs
+ -- corresponding to 'Image. Let S = Num / Den, B = Base and N the scale in
+ -- base B of S, i.e. the smallest integer such that B**N * S >= 1. Then,
+ -- for X a positive of the mantissa, i.e. 1 <= X <= 2**(M-1), we have
+
+ -- 1/B <= X * S * B**(N-1) < 2**(M-1)
+
+ -- which means that the inputs corresponding to the output of 'Image have a
+ -- ScaleB equal either to 1 - N or (after multiplying the inequality by B)
+ -- to -N, possibly after renormalizing X, i.e. multiplying it by a suitable
+ -- power of B. Therefore
+
+ -- Den * (Base ** ScaleB) <= Den * (B ** (1 - N)) < Num * B
+
+ -- which means that the product does not overflow if Num <= 2**(M-1) / B.
+
+ -- On the other hand, if Extra is positive and ScaleB negative, the above
+ -- two steps are
+
+ -- (1b) Val * Den = Q1 * (Num * (Base ** -ScaleB)) + R1
+
+ -- (2b) Extra * Den = Q2 * -Base + R2
+
+ -- which yields after dividing (1b) by Num * (Base ** -ScaleB) and (2b) by
+ -- Num * (Base ** (1 - ScaleB)) and summing
+
+ -- V = Q1 + (R1 - Q2) / (Num * (Base ** -ScaleB)) + R2 / ...
+
+ -- but we get rid of the third term by using a rounding divide for (2b).
+
+ -- This works only if Num * (Base ** -ScaleB) does not overflow for inputs
+ -- corresponding to 'Image. With the determination of ScaleB above, we have
+
+ -- Num * (Base ** -ScaleB) <= Num * (B ** N) < Den * B
+
+ -- which means that the product does not overflow if Den <= 2**(M-1) / B.
+
+ ----------------------
+ -- Integer_To_Fixed --
+ ----------------------
+
+ function Integer_To_Fixed
+ (Str : String;
+ Val : Uns;
+ Base : Unsigned;
+ ScaleB : Integer;
+ Extra : Unsigned;
+ Minus : Boolean;
+ Num : Int;
+ Den : Int) return Int
+ is
+ pragma Assert (Base in 2 .. 16);
+
+ pragma Assert (Extra < Base);
+ -- Accept only one extra digit after those used for Val
+
+ pragma Assert (Num < 0 and then Den < 0);
+ -- Accept only negative numbers to allow -2**(Int'Size - 1)
+
+ function Safe_Expont
+ (Base : Int;
+ Exp : in out Natural;
+ Factor : Int) return Int;
+ -- Return (Base ** Exp) * Factor if the computation does not overflow,
+ -- or else the number of the form (Base ** K) * Factor with the largest
+ -- magnitude if the former computation overflows. In both cases, Exp is
+ -- updated to contain the remaining power in the computation. Note that
+ -- Factor is expected to be negative in this context.
+
+ function Unsigned_To_Signed (Val : Uns) return Int;
+ -- Convert an integer value from unsigned to signed representation
+
+ -----------------
+ -- Safe_Expont --
+ -----------------
+
+ function Safe_Expont
+ (Base : Int;
+ Exp : in out Natural;
+ Factor : Int) return Int
+ is
+ pragma Assert (Base /= 0 and then Factor < 0);
+
+ Min : constant Int := Int'First / Base;
+
+ Result : Int := Factor;
+
+ begin
+ while Exp > 0 and then Result >= Min loop
+ Result := Result * Base;
+ Exp := Exp - 1;
+ end loop;
+
+ return Result;
+ end Safe_Expont;
+
+ ------------------------
+ -- Unsigned_To_Signed --
+ ------------------------
+
+ function Unsigned_To_Signed (Val : Uns) return Int is
+ begin
+ -- Deal with overflow cases, and also with largest negative number
+
+ if Val > Uns (Int'Last) then
+ if Minus and then Val = Uns (-(Int'First)) then
+ return Int'First;
+ else
+ Bad_Value (Str);
+ end if;
+
+ -- Negative values
+
+ elsif Minus then
+ return -(Int (Val));
+
+ -- Positive values
+
+ else
+ return Int (Val);
+ end if;
+ end Unsigned_To_Signed;
+
+ -- Local variables
+
+ B : constant Int := Int (Base);
+
+ V : Uns := Val;
+ E : Uns := Uns (Extra);
+
+ Y, Z, Q1, R1, Q2, R2 : Int;
+
+ begin
+ -- We will use a scaled divide operation for which we must control the
+ -- magnitude of operands so that an overflow exception is not unduly
+ -- raised during the computation. The only real concern is the exponent.
+
+ -- If ScaleB is too negative, then drop trailing digits, but preserve
+ -- the last dropped digit.
+
+ if ScaleB < 0 then
+ declare
+ LS : Integer := -ScaleB;
+
+ begin
+ Y := Den;
+ Z := Safe_Expont (B, LS, Num);
+
+ for J in 1 .. LS loop
+ E := V rem Uns (B);
+ V := V / Uns (B);
+ end loop;
+ end;
+
+ -- If ScaleB is too positive, then scale V up, which may then overflow
+
+ elsif ScaleB > 0 then
+ declare
+ LS : Integer := ScaleB;
+
+ begin
+ Y := Safe_Expont (B, LS, Den);
+ Z := Num;
+
+ for J in 1 .. LS loop
+ if V <= (Uns'Last - E) / Uns (B) then
+ V := V * Uns (B) + E;
+ E := 0;
+ else
+ Bad_Value (Str);
+ end if;
+ end loop;
+ end;
+
+ -- If ScaleB is zero, then proceed directly
+
+ else
+ Y := Den;
+ Z := Num;
+ end if;
+
+ -- Perform a scaled divide operation with final rounding to match Image
+ -- using two steps if there is an extra digit available. The second and
+ -- third operands are always negative so the sign of the quotient is the
+ -- sign of the first operand and the sign of the remainder the opposite.
+
+ if E > 0 then
+ Scaled_Divide (Unsigned_To_Signed (V), Y, Z, Q1, R1, Round => False);
+ Scaled_Divide (Unsigned_To_Signed (E), Y, -B, Q2, R2, Round => True);
+
+ -- Avoid an overflow during the subtraction. Note that Q2 is smaller
+ -- than Y and R1 smaller than Z in magnitude, so it is safe to take
+ -- their absolute value.
+
+ if abs Q2 >= 2 ** (Int'Size - 2)
+ or else abs R1 >= 2 ** (Int'Size - 2)
+ then
+ declare
+ Bit : constant Int := Q2 rem 2;
+
+ begin
+ Q2 := (Q2 - Bit) / 2;
+ R1 := (R1 - Bit) / 2;
+ Y := -2;
+ end;
+
+ else
+ Y := -1;
+ end if;
+
+ Scaled_Divide (Q2 - R1, Y, Z, Q2, R2, Round => True);
+
+ return Q1 + Q2;
+
+ else
+ Scaled_Divide (Unsigned_To_Signed (V), Y, Z, Q1, R1, Round => True);
+
+ return Q1;
+ end if;
+
+ exception
+ when Constraint_Error => Bad_Value (Str);
+ end Integer_To_Fixed;
+
+ ----------------
+ -- Scan_Fixed --
+ ----------------
+
+ function Scan_Fixed
+ (Str : String;
+ Ptr : not null access Integer;
+ Max : Integer;
+ Num : Int;
+ Den : Int) return Int
+ is
+ Base : Unsigned;
+ ScaleB : Integer;
+ Extra : Unsigned;
+ Minus : Boolean;
+ Val : Uns;
+
+ begin
+ Val := Impl.Scan_Raw_Real (Str, Ptr, Max, Base, ScaleB, Extra, Minus);
+
+ return Integer_To_Fixed (Str, Val, Base, ScaleB, Extra, Minus, Num, Den);
+ end Scan_Fixed;
+
+ -----------------
+ -- Value_Fixed --
+ -----------------
+
+ function Value_Fixed
+ (Str : String;
+ Num : Int;
+ Den : Int) return Int
+ is
+ Base : Unsigned;
+ ScaleB : Integer;
+ Extra : Unsigned;
+ Minus : Boolean;
+ Val : Uns;
+
+ begin
+ Val := Impl.Value_Raw_Real (Str, Base, ScaleB, Extra, Minus);
+
+ return Integer_To_Fixed (Str, Val, Base, ScaleB, Extra, Minus, Num, Den);
+ end Value_Fixed;
+
+end System.Value_F;
diff --git a/gcc/ada/libgnat/s-vallld.ads b/gcc/ada/libgnat/s-valuef.ads
index 652362d..abd4817 100644
--- a/gcc/ada/libgnat/s-vallld.ads
+++ b/gcc/ada/libgnat/s-valuef.ads
@@ -2,11 +2,11 @@
-- --
-- GNAT COMPILER COMPONENTS --
-- --
--- S Y S T E M . V A L _ L L D --
+-- S Y S T E M . V A L U E _ F --
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2020, Free Software Foundation, Inc. --
+-- Copyright (C) 2020, 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- --
@@ -29,18 +29,30 @@
-- --
------------------------------------------------------------------------------
--- This package contains routines for scanning decimal values where the size
--- of the type is greater than Standard.Integer'Size, for use in Text_IO.
--- Decimal_IO, and the Value attribute for such decimal types.
+-- This package contains the routines for supporting the Value attribute for
+-- ordinary fixed point types whose Small is the ratio of two Int values, and
+-- also for conversion operations required in Text_IO.Fixed_IO for such types.
-package System.Val_LLD is
+generic
+
+ type Int is range <>;
+
+ type Uns is mod <>;
+
+ with procedure Scaled_Divide
+ (X, Y, Z : Int;
+ Q, R : out Int;
+ Round : Boolean);
+
+package System.Value_F is
pragma Preelaborate;
- function Scan_Long_Long_Decimal
- (Str : String;
- Ptr : not null access Integer;
- Max : Integer;
- Scale : Integer) return Long_Long_Integer;
+ function Scan_Fixed
+ (Str : String;
+ Ptr : not null access Integer;
+ Max : Integer;
+ Num : Int;
+ Den : Int) return Int;
-- This function scans the string starting at Str (Ptr.all) for a valid
-- real literal according to the syntax described in (RM 3.5(43)). The
-- substring scanned extends no further than Str (Max). There are three
@@ -49,8 +61,8 @@ package System.Val_LLD is
-- If a valid real literal is found after scanning past any initial spaces,
-- then Ptr.all is updated past the last character of the literal (but
-- trailing spaces are not scanned out). The value returned is the value
- -- Long_Long_Integer'Integer_Value (decimal-literal-value), using the given
- -- Scale to determine this value.
+ -- Int'Integer_Value (decimal-literal-value), using the given Num/Den to
+ -- determine this value.
--
-- If no valid real literal is found, then Ptr.all points either to an
-- initial non-digit character, or to Max + 1 if the field is all spaces
@@ -68,14 +80,15 @@ package System.Val_LLD is
-- special case of an all-blank string, and Ptr is unchanged, and hence
-- is greater than Max as required in this case.
- function Value_Long_Long_Decimal
- (Str : String;
- Scale : Integer) return Long_Long_Integer;
- -- Used in computing X'Value (Str) where X is a decimal types whose size
- -- exceeds Standard.Integer'Size. Str is the string argument of the
- -- attribute. Constraint_Error is raised if the string is malformed
- -- or if the value is out of range, otherwise the value returned is the
- -- value Long_Long_Integer'Integer_Value (decimal-literal-value), using
- -- the given Scale to determine this value.
+ function Value_Fixed
+ (Str : String;
+ Num : Int;
+ Den : Int) return Int;
+ -- Used in computing X'Value (Str) where X is an ordinary fixed-point type.
+ -- Str is the string argument of the attribute. Constraint_Error is raised
+ -- if the string is malformed or if the value is out of range of Int (not
+ -- the range of the fixed-point type, which must be done by the caller).
+ -- Otherwise the value returned is the value Int'Integer_Value
+ -- (decimal-literal-value), using Small Num/Den to determine this value.
-end System.Val_LLD;
+end System.Value_F;
diff --git a/gcc/ada/libgnat/s-valuei.adb b/gcc/ada/libgnat/s-valuei.adb
index 1bc8b32..ac5a776 100644
--- a/gcc/ada/libgnat/s-valuei.adb
+++ b/gcc/ada/libgnat/s-valuei.adb
@@ -61,7 +61,7 @@ package body System.Value_I is
Uval := Scan_Raw_Unsigned (Str, Ptr, Max);
- -- Deal with overflow cases, and also with maximum negative number
+ -- Deal with overflow cases, and also with largest negative number
if Uval > Uns (Int'Last) then
if Minus and then Uval = Uns (-(Int'First)) then
diff --git a/gcc/ada/libgnat/s-valuer.adb b/gcc/ada/libgnat/s-valuer.adb
new file mode 100644
index 0000000..06d7adc
--- /dev/null
+++ b/gcc/ada/libgnat/s-valuer.adb
@@ -0,0 +1,620 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . V A L U E _ R --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with System.Val_Util; use System.Val_Util;
+
+package body System.Value_R is
+
+ F_Limit : constant Uns := 2 ** (Long_Long_Float'Machine_Mantissa - 1);
+ I_Limit : constant Uns := 2 ** (Uns'Size - 1);
+ -- Absolute value of largest representable signed integer
+
+ Precision_Limit : constant Uns := (if Floating then F_Limit else I_Limit);
+ -- Limit beyond which additional digits are dropped
+
+ subtype Char_As_Digit is Unsigned range 0 .. 17;
+ subtype Valid_Digit is Char_As_Digit range 0 .. 15;
+ E_Digit : constant Char_As_Digit := 14;
+ Underscore : constant Char_As_Digit := 16;
+ Not_A_Digit : constant Char_As_Digit := 17;
+
+ function As_Digit (C : Character) return Char_As_Digit;
+ -- Given a character return the digit it represents
+
+ procedure Scan_Decimal_Digits
+ (Str : String;
+ Index : in out Integer;
+ Max : Integer;
+ Value : in out Uns;
+ Scale : in out Integer;
+ Extra : in out Char_As_Digit;
+ Base_Violation : in out Boolean;
+ Base : Unsigned;
+ Base_Specified : Boolean);
+ -- Scan the decimal part of a real (i.e. after decimal separator)
+ --
+ -- The string parsed is Str (Index .. Max) and after the call Index will
+ -- point to the first non-parsed character.
+ --
+ -- For each digit parsed, Value = Value * Base + Digit and Scale is
+ -- decremented by 1. If precision limit is reached, remaining digits are
+ -- still parsed but ignored, except for the first which is stored in Extra.
+ --
+ -- Base_Violation is set to True if a digit found is not part of the Base
+ --
+ -- If Base_Specified is set, then the base was specified in the real
+
+ procedure Scan_Integral_Digits
+ (Str : String;
+ Index : in out Integer;
+ Max : Integer;
+ Value : out Uns;
+ Scale : out Integer;
+ Extra : out Char_As_Digit;
+ Base_Violation : in out Boolean;
+ Base : Unsigned;
+ Base_Specified : Boolean);
+ -- Scan the integral part of a real (i.e. before decimal separator)
+ --
+ -- The string parsed is Str (Index .. Max) and after the call Index will
+ -- point to the first non-parsed character.
+ --
+ -- For each digit parsed, either Value := Value * Base + Digit or Scale
+ -- is incremented by 1 if precision limit is reached, in which case the
+ -- remaining digits are still parsed but ignored, except for the first
+ -- which is stored in Extra.
+ --
+ -- Base_Violation is set to True if a digit found is not part of the Base
+ --
+ -- If Base_Specified is set, then the base was specified in the real
+
+ --------------
+ -- As_Digit --
+ --------------
+
+ function As_Digit (C : Character) return Char_As_Digit is
+ begin
+ case C is
+ when '0' .. '9' =>
+ return Character'Pos (C) - Character'Pos ('0');
+ when 'a' .. 'f' =>
+ return Character'Pos (C) - (Character'Pos ('a') - 10);
+ when 'A' .. 'F' =>
+ return Character'Pos (C) - (Character'Pos ('A') - 10);
+ when '_' =>
+ return Underscore;
+ when others =>
+ return Not_A_Digit;
+ end case;
+ end As_Digit;
+
+ -------------------------
+ -- Scan_Decimal_Digits --
+ -------------------------
+
+ procedure Scan_Decimal_Digits
+ (Str : String;
+ Index : in out Integer;
+ Max : Integer;
+ Value : in out Uns;
+ Scale : in out Integer;
+ Extra : in out Char_As_Digit;
+ Base_Violation : in out Boolean;
+ Base : Unsigned;
+ Base_Specified : Boolean)
+
+ is
+ pragma Assert (Base in 2 .. 16);
+
+ Umax : constant Uns := (Precision_Limit - Uns (Base) + 1) / Uns (Base);
+ -- Max value which cannot overflow on accumulating next digit
+
+ UmaxB : constant Uns := Precision_Limit / Uns (Base);
+ -- Numbers bigger than UmaxB overflow if multiplied by base
+
+ Precision_Limit_Reached : Boolean := False;
+ -- Set to True if addition of a digit will cause Value to be superior
+ -- to Precision_Limit.
+
+ Precision_Limit_Just_Reached : Boolean := False;
+ -- Set to True if Precision_Limit_Reached was just set to True
+
+ Digit : Char_As_Digit;
+ -- The current digit
+
+ Temp : Uns;
+ -- Temporary
+
+ Trailing_Zeros : Natural := 0;
+ -- Number of trailing zeros at a given point
+
+ begin
+ -- If initial Scale is not 0 then it means that Precision_Limit was
+ -- reached during scanning of the integral part.
+
+ if Scale > 0 then
+ Precision_Limit_Reached := True;
+ else
+ Extra := 0;
+ end if;
+
+ -- The function precondition is that the first character is a valid
+ -- digit.
+
+ Digit := As_Digit (Str (Index));
+
+ loop
+ -- Check if base is correct. If the base is not specified, the digit
+ -- E or e cannot be considered as a base violation as it can be used
+ -- for exponentiation.
+
+ if Digit >= Base then
+ if Base_Specified then
+ Base_Violation := True;
+ elsif Digit = E_Digit then
+ return;
+ else
+ Base_Violation := True;
+ end if;
+ end if;
+
+ -- If precision limit has been reached, just ignore any remaining
+ -- digits for the computation of Value and Scale, but store the
+ -- first in Extra and use the second to round Extra if this is for
+ -- a fixed-point type (we skip the rounding for a floating-point
+ -- type to preserve backward compatibility). The scanning should
+ -- continue only to assess the validity of the string.
+
+ if Precision_Limit_Reached then
+ if Precision_Limit_Just_Reached and then not Floating then
+ if Digit >= Base / 2 then
+ if Extra = Base - 1 then
+ Extra := 0;
+ Value := Value + 1;
+ else
+ Extra := Extra + 1;
+ end if;
+ end if;
+
+ Precision_Limit_Just_Reached := False;
+ end if;
+
+ else
+ -- Trailing '0' digits are ignored until a non-zero digit is found
+
+ if Digit = 0 then
+ Trailing_Zeros := Trailing_Zeros + 1;
+
+ else
+ -- Handle accumulated zeros.
+
+ for J in 1 .. Trailing_Zeros loop
+ if Value <= UmaxB then
+ Value := Value * Uns (Base);
+ Scale := Scale - 1;
+
+ else
+ Precision_Limit_Reached := True;
+ exit;
+ end if;
+ end loop;
+
+ -- Reset trailing zero counter
+
+ Trailing_Zeros := 0;
+
+ -- Handle current non zero digit
+
+ Temp := Value * Uns (Base) + Uns (Digit);
+
+ if Value <= Umax
+ or else (Value <= UmaxB and then Temp <= Precision_Limit)
+ then
+ Value := Temp;
+ Scale := Scale - 1;
+
+ else
+ Extra := Digit;
+ Precision_Limit_Reached := True;
+ Precision_Limit_Just_Reached := True;
+ end if;
+ end if;
+ end if;
+
+ -- Check next character
+
+ Index := Index + 1;
+
+ if Index > Max then
+ return;
+ end if;
+
+ Digit := As_Digit (Str (Index));
+
+ if Digit not in Valid_Digit then
+
+ -- Underscore is only allowed if followed by a digit
+
+ if Digit = Underscore and Index + 1 <= Max then
+
+ Digit := As_Digit (Str (Index + 1));
+ if Digit in Valid_Digit then
+ Index := Index + 1;
+ else
+ return;
+ end if;
+
+ -- Neither a valid underscore nor a digit
+
+ else
+ return;
+ end if;
+ end if;
+ end loop;
+ end Scan_Decimal_Digits;
+
+ --------------------------
+ -- Scan_Integral_Digits --
+ --------------------------
+
+ procedure Scan_Integral_Digits
+ (Str : String;
+ Index : in out Integer;
+ Max : Integer;
+ Value : out Uns;
+ Scale : out Integer;
+ Extra : out Char_As_Digit;
+ Base_Violation : in out Boolean;
+ Base : Unsigned;
+ Base_Specified : Boolean)
+ is
+ pragma Assert (Base in 2 .. 16);
+
+ Umax : constant Uns := (Precision_Limit - Uns (Base) + 1) / Uns (Base);
+ -- Max value which cannot overflow on accumulating next digit
+
+ UmaxB : constant Uns := Precision_Limit / Uns (Base);
+ -- Numbers bigger than UmaxB overflow if multiplied by base
+
+ Precision_Limit_Reached : Boolean := False;
+ -- Set to True if addition of a digit will cause Value to be superior
+ -- to Precision_Limit.
+
+ Precision_Limit_Just_Reached : Boolean := False;
+ -- Set to True if Precision_Limit_Reached was just set to True
+
+ Digit : Char_As_Digit;
+ -- The current digit
+
+ Temp : Uns;
+ -- Temporary
+
+ begin
+ -- Initialize Value, Scale and Extra
+
+ Value := 0;
+ Scale := 0;
+ Extra := 0;
+
+ -- The function precondition is that the first character is a valid
+ -- digit.
+
+ Digit := As_Digit (Str (Index));
+
+ loop
+ -- Check if base is correct. If the base is not specified, the digit
+ -- E or e cannot be considered as a base violation as it can be used
+ -- for exponentiation.
+
+ if Digit >= Base then
+ if Base_Specified then
+ Base_Violation := True;
+ elsif Digit = E_Digit then
+ return;
+ else
+ Base_Violation := True;
+ end if;
+ end if;
+
+ -- If precision limit has been reached, just ignore any remaining
+ -- digits for the computation of Value and Scale, but store the
+ -- first in Extra and use the second to round Extra if this is for
+ -- a fixed-point type (we skip the rounding for a floating-point
+ -- type to preserve backward compatibility). The scanning should
+ -- continue only to assess the validity of the string.
+
+ if Precision_Limit_Reached then
+ Scale := Scale + 1;
+
+ if Precision_Limit_Just_Reached and then not Floating then
+ if Digit >= Base / 2 then
+ if Extra = Base - 1 then
+ Extra := 0;
+ Value := Value + 1;
+ else
+ Extra := Extra + 1;
+ end if;
+ end if;
+
+ Precision_Limit_Just_Reached := False;
+ end if;
+
+ else
+ Temp := Value * Uns (Base) + Uns (Digit);
+
+ if Value <= Umax
+ or else (Value <= UmaxB and then Temp <= Precision_Limit)
+ then
+ Value := Temp;
+
+ else
+ Extra := Digit;
+ Precision_Limit_Reached := True;
+ Precision_Limit_Just_Reached := True;
+ Scale := Scale + 1;
+ end if;
+ end if;
+
+ -- Look for the next character
+
+ Index := Index + 1;
+ if Index > Max then
+ return;
+ end if;
+
+ Digit := As_Digit (Str (Index));
+
+ if Digit not in Valid_Digit then
+
+ -- Next character is not a digit. In that case stop scanning
+ -- unless the next chracter is an underscore followed by a digit.
+
+ if Digit = Underscore and Index + 1 <= Max then
+ Digit := As_Digit (Str (Index + 1));
+ if Digit in Valid_Digit then
+ Index := Index + 1;
+ else
+ return;
+ end if;
+ else
+ return;
+ end if;
+ end if;
+ end loop;
+
+ end Scan_Integral_Digits;
+
+ -------------------
+ -- Scan_Raw_Real --
+ -------------------
+
+ function Scan_Raw_Real
+ (Str : String;
+ Ptr : not null access Integer;
+ Max : Integer;
+ Base : out Unsigned;
+ Scale : out Integer;
+ Extra : out Unsigned;
+ Minus : out Boolean) return Uns
+ is
+ After_Point : Boolean;
+ -- True if a decimal should be parsed
+
+ Base_Char : Character := ASCII.NUL;
+ -- Character used to set the base. If Nul this means that default
+ -- base is used.
+
+ Base_Violation : Boolean := False;
+ -- If True some digits where not in the base. The real is still scanned
+ -- till the end even if an error will be raised.
+
+ Index : Integer;
+ -- Local copy of string pointer
+
+ Start : Positive;
+ -- Position of starting non-blank character
+
+ Value : Uns;
+ -- Mantissa as an Integer
+
+ begin
+ -- The default base is 10
+
+ Base := 10;
+
+ -- We do not tolerate strings with Str'Last = Positive'Last
+
+ if Str'Last = Positive'Last then
+ raise Program_Error with
+ "string upper bound is Positive'Last, not supported";
+ end if;
+
+ -- Scan the optional sign
+
+ Scan_Sign (Str, Ptr, Max, Minus, Start);
+ Index := Ptr.all;
+ Ptr.all := Start;
+
+ -- First character can be either a decimal digit or a dot
+
+ if Str (Index) in '0' .. '9' then
+ pragma Annotate
+ (CodePeer, False_Positive, "test always true", "defensive code");
+
+ After_Point := False;
+
+ -- If this is a digit it can indicates either the float decimal
+ -- part or the base to use.
+
+ Scan_Integral_Digits
+ (Str, Index, Max, Value, Scale, Char_As_Digit (Extra),
+ Base_Violation, Base, Base_Specified => False);
+
+ -- A dot is allowed only if followed by a digit (RM 3.5(47))
+
+ elsif Str (Index) = '.'
+ and then Index < Max
+ and then Str (Index + 1) in '0' .. '9'
+ then
+ After_Point := True;
+ Index := Index + 1;
+ Value := 0;
+ Scale := 0;
+ Extra := 0;
+
+ else
+ Bad_Value (Str);
+ end if;
+
+ -- Check if the first number encountered is a base
+
+ if Index < Max
+ and then (Str (Index) = '#' or else Str (Index) = ':')
+ then
+ Base_Char := Str (Index);
+ Base := Unsigned (Value);
+
+ if Base < 2 or else Base > 16 then
+ Base_Violation := True;
+ Base := 16;
+ end if;
+
+ Index := Index + 1;
+
+ if Str (Index) = '.'
+ and then Index < Max
+ and then As_Digit (Str (Index + 1)) in Valid_Digit
+ then
+ After_Point := True;
+ Index := Index + 1;
+ Value := 0;
+ end if;
+ end if;
+
+ -- Scan the integral part if still necessary
+
+ if Base_Char /= ASCII.NUL and then not After_Point then
+ if Index > Max or else As_Digit (Str (Index)) not in Valid_Digit then
+ Bad_Value (Str);
+ end if;
+
+ Scan_Integral_Digits
+ (Str, Index, Max, Value, Scale, Char_As_Digit (Extra),
+ Base_Violation, Base, Base_Specified => Base_Char /= ASCII.NUL);
+ end if;
+
+ -- Do we have a dot?
+
+ if not After_Point and then Index <= Max and then Str (Index) = '.' then
+
+ -- At this stage if After_Point was not set, this means that an
+ -- integral part has been found. Thus the dot is valid even if not
+ -- followed by a digit.
+
+ if Index < Max and then As_Digit (Str (Index + 1)) in Valid_Digit then
+ After_Point := True;
+ end if;
+
+ Index := Index + 1;
+ end if;
+
+ -- Scan the decimal part
+
+ if After_Point then
+ Scan_Decimal_Digits
+ (Str, Index, Max, Value, Scale, Char_As_Digit (Extra),
+ Base_Violation, Base, Base_Specified => Base_Char /= ASCII.NUL);
+ end if;
+
+ -- If an explicit base was specified ensure that the delimiter is found
+
+ if Base_Char /= ASCII.NUL then
+ if Index > Max or else Str (Index) /= Base_Char then
+ Bad_Value (Str);
+ else
+ Index := Index + 1;
+ end if;
+ end if;
+
+ -- Update pointer and scan exponent
+
+ Ptr.all := Index;
+ Scale := Scale + Scan_Exponent (Str, Ptr, Max, Real => True);
+
+ -- Here is where we check for a bad based number
+
+ if Base_Violation then
+ Bad_Value (Str);
+ else
+ return Value;
+ end if;
+
+ end Scan_Raw_Real;
+
+ --------------------
+ -- Value_Raw_Real --
+ --------------------
+
+ function Value_Raw_Real
+ (Str : String;
+ Base : out Unsigned;
+ Scale : out Integer;
+ Extra : out Unsigned;
+ Minus : out Boolean) return Uns
+ is
+ begin
+ -- We have to special case Str'Last = Positive'Last because the normal
+ -- circuit ends up setting P to Str'Last + 1 which is out of bounds. We
+ -- deal with this by converting to a subtype which fixes the bounds.
+
+ if Str'Last = Positive'Last then
+ declare
+ subtype NT is String (1 .. Str'Length);
+ begin
+ return Value_Raw_Real (NT (Str), Base, Scale, Extra, Minus);
+ end;
+
+ -- Normal case where Str'Last < Positive'Last
+
+ else
+ declare
+ V : Uns;
+ P : aliased Integer := Str'First;
+ begin
+ V := Scan_Raw_Real
+ (Str, P'Access, Str'Last, Base, Scale, Extra, Minus);
+ Scan_Trailing_Blanks (Str, P);
+ return V;
+ end;
+ end if;
+ end Value_Raw_Real;
+
+end System.Value_R;
diff --git a/gcc/ada/libgnat/s-valuer.ads b/gcc/ada/libgnat/s-valuer.ads
new file mode 100644
index 0000000..8d2f3fd
--- /dev/null
+++ b/gcc/ada/libgnat/s-valuer.ads
@@ -0,0 +1,99 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . V A L U E _ R --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2020, 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. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains routines for scanning real values for use in
+-- Text_IO.Decimal_IO, Fixed_IO, Float_IO and the Value attribute.
+
+with System.Unsigned_Types; use System.Unsigned_Types;
+
+generic
+
+ type Uns is mod <>;
+
+ Floating : Boolean;
+
+package System.Value_R is
+ pragma Preelaborate;
+
+ function Scan_Raw_Real
+ (Str : String;
+ Ptr : not null access Integer;
+ Max : Integer;
+ Base : out Unsigned;
+ Scale : out Integer;
+ Extra : out Unsigned;
+ Minus : out Boolean) return Uns;
+ -- This function scans the string starting at Str (Ptr.all) for a valid
+ -- real literal according to the syntax described in (RM 3.5(43)). The
+ -- substring scanned extends no further than Str (Max). There are three
+ -- cases for the return:
+ --
+ -- If a valid real is found after scanning past any initial spaces, then
+ -- Ptr.all is updated past the last character of the real (but trailing
+ -- spaces are not scanned out) and the Base, Scale, Extra and Minus out
+ -- parameters are set; if Val is the result of the call, then the real
+ -- represented by the literal is equal to
+ --
+ -- (Val * Base + Extra) * (Base ** (Scale - 1))
+ --
+ -- with the negative sign if Minus is true.
+ --
+ -- If no valid real is found, then Ptr.all points either to an initial
+ -- non-blank character, or to Max + 1 if the field is all spaces and the
+ -- exception Constraint_Error is raised.
+ --
+ -- If a syntactically valid real is scanned, but the value is out of
+ -- range, or, in the based case, the base value is out of range or there
+ -- is an out of range digit, then Ptr.all points past the real literal,
+ -- and Constraint_Error is raised.
+ --
+ -- Note: these rules correspond to the requirements for leaving the
+ -- pointer positioned in Text_Io.Get
+ --
+ -- Note: if Str is null, i.e. if Max is less than Ptr, then this is a
+ -- special case of an all-blank string, and Ptr is unchanged, and hence
+ -- is greater than Max as required in this case.
+ --
+ -- Note: this routine should not be called with Str'Last = Positive'Last.
+ -- If this occurs Program_Error is raised with a message noting that this
+ -- case is not supported. Most such cases are eliminated by the caller.
+
+ function Value_Raw_Real
+ (Str : String;
+ Base : out Unsigned;
+ Scale : out Integer;
+ Extra : out Unsigned;
+ Minus : out Boolean) return Uns;
+ -- Used in computing X'Value (Str) where X is a real type. Str is the
+ -- string argument of the attribute. Constraint_Error is raised if the
+ -- string is malformed.
+
+end System.Value_R;
diff --git a/gcc/ada/libgnat/system-aix.ads b/gcc/ada/libgnat/system-aix.ads
index 5bf603d..e346759 100644
--- a/gcc/ada/libgnat/system-aix.ads
+++ b/gcc/ada/libgnat/system-aix.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.01;
diff --git a/gcc/ada/libgnat/system-darwin-arm.ads b/gcc/ada/libgnat/system-darwin-arm.ads
index 70e02a1..e1af682 100644
--- a/gcc/ada/libgnat/system-darwin-arm.ads
+++ b/gcc/ada/libgnat/system-darwin-arm.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.01;
diff --git a/gcc/ada/libgnat/system-darwin-ppc.ads b/gcc/ada/libgnat/system-darwin-ppc.ads
index 4947c6c..0b746cc 100644
--- a/gcc/ada/libgnat/system-darwin-ppc.ads
+++ b/gcc/ada/libgnat/system-darwin-ppc.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.01;
diff --git a/gcc/ada/libgnat/system-darwin-x86.ads b/gcc/ada/libgnat/system-darwin-x86.ads
index 828b310..e27379e 100644
--- a/gcc/ada/libgnat/system-darwin-x86.ads
+++ b/gcc/ada/libgnat/system-darwin-x86.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.01;
diff --git a/gcc/ada/libgnat/system-djgpp.ads b/gcc/ada/libgnat/system-djgpp.ads
index 68fdb49..35d9381 100644
--- a/gcc/ada/libgnat/system-djgpp.ads
+++ b/gcc/ada/libgnat/system-djgpp.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.01;
diff --git a/gcc/ada/libgnat/system-dragonfly-x86_64.ads b/gcc/ada/libgnat/system-dragonfly-x86_64.ads
index 6bfb5c4..80da5af 100644
--- a/gcc/ada/libgnat/system-dragonfly-x86_64.ads
+++ b/gcc/ada/libgnat/system-dragonfly-x86_64.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.000_001;
diff --git a/gcc/ada/libgnat/system-freebsd.ads b/gcc/ada/libgnat/system-freebsd.ads
index d4fe60e..e8765b8 100644
--- a/gcc/ada/libgnat/system-freebsd.ads
+++ b/gcc/ada/libgnat/system-freebsd.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.000_001;
diff --git a/gcc/ada/libgnat/system-hpux-ia64.ads b/gcc/ada/libgnat/system-hpux-ia64.ads
index f11edc6..12252db 100644
--- a/gcc/ada/libgnat/system-hpux-ia64.ads
+++ b/gcc/ada/libgnat/system-hpux-ia64.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.01;
diff --git a/gcc/ada/libgnat/system-hpux.ads b/gcc/ada/libgnat/system-hpux.ads
index ddf6a82..71a1668 100644
--- a/gcc/ada/libgnat/system-hpux.ads
+++ b/gcc/ada/libgnat/system-hpux.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.01;
diff --git a/gcc/ada/libgnat/system-linux-alpha.ads b/gcc/ada/libgnat/system-linux-alpha.ads
index eebe93a..d639630 100644
--- a/gcc/ada/libgnat/system-linux-alpha.ads
+++ b/gcc/ada/libgnat/system-linux-alpha.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 1024.0;
diff --git a/gcc/ada/libgnat/system-linux-arm.ads b/gcc/ada/libgnat/system-linux-arm.ads
index 4d09d9e..6831aad 100644
--- a/gcc/ada/libgnat/system-linux-arm.ads
+++ b/gcc/ada/libgnat/system-linux-arm.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.000_001;
diff --git a/gcc/ada/libgnat/system-linux-hppa.ads b/gcc/ada/libgnat/system-linux-hppa.ads
index 6bc9541..669289d 100644
--- a/gcc/ada/libgnat/system-linux-hppa.ads
+++ b/gcc/ada/libgnat/system-linux-hppa.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.000_001;
diff --git a/gcc/ada/libgnat/system-linux-ia64.ads b/gcc/ada/libgnat/system-linux-ia64.ads
index ae9b49a..1dca30c 100644
--- a/gcc/ada/libgnat/system-linux-ia64.ads
+++ b/gcc/ada/libgnat/system-linux-ia64.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.01;
diff --git a/gcc/ada/libgnat/system-linux-m68k.ads b/gcc/ada/libgnat/system-linux-m68k.ads
index 3fbd781..6a98466 100644
--- a/gcc/ada/libgnat/system-linux-m68k.ads
+++ b/gcc/ada/libgnat/system-linux-m68k.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.000_001;
diff --git a/gcc/ada/libgnat/system-linux-mips.ads b/gcc/ada/libgnat/system-linux-mips.ads
index d760db8..8476f90 100644
--- a/gcc/ada/libgnat/system-linux-mips.ads
+++ b/gcc/ada/libgnat/system-linux-mips.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.000_001;
diff --git a/gcc/ada/libgnat/system-linux-ppc.ads b/gcc/ada/libgnat/system-linux-ppc.ads
index 0f39370..9785c9a 100644
--- a/gcc/ada/libgnat/system-linux-ppc.ads
+++ b/gcc/ada/libgnat/system-linux-ppc.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.000_001;
diff --git a/gcc/ada/libgnat/system-linux-riscv.ads b/gcc/ada/libgnat/system-linux-riscv.ads
index 91eddf2..a298bcd 100644
--- a/gcc/ada/libgnat/system-linux-riscv.ads
+++ b/gcc/ada/libgnat/system-linux-riscv.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.000_001;
diff --git a/gcc/ada/libgnat/system-linux-s390.ads b/gcc/ada/libgnat/system-linux-s390.ads
index 374b938..3d80ce7 100644
--- a/gcc/ada/libgnat/system-linux-s390.ads
+++ b/gcc/ada/libgnat/system-linux-s390.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.000_001;
diff --git a/gcc/ada/libgnat/system-linux-sh4.ads b/gcc/ada/libgnat/system-linux-sh4.ads
index cd811de..6227bdb 100644
--- a/gcc/ada/libgnat/system-linux-sh4.ads
+++ b/gcc/ada/libgnat/system-linux-sh4.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.000_001;
diff --git a/gcc/ada/libgnat/system-linux-sparc.ads b/gcc/ada/libgnat/system-linux-sparc.ads
index e74214b..0549a85 100644
--- a/gcc/ada/libgnat/system-linux-sparc.ads
+++ b/gcc/ada/libgnat/system-linux-sparc.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.000_001;
diff --git a/gcc/ada/libgnat/system-linux-x86.ads b/gcc/ada/libgnat/system-linux-x86.ads
index eb8b5dd..5b2b77f 100644
--- a/gcc/ada/libgnat/system-linux-x86.ads
+++ b/gcc/ada/libgnat/system-linux-x86.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.000_001;
diff --git a/gcc/ada/libgnat/system-lynxos178-ppc.ads b/gcc/ada/libgnat/system-lynxos178-ppc.ads
index cf516e1..70de803 100644
--- a/gcc/ada/libgnat/system-lynxos178-ppc.ads
+++ b/gcc/ada/libgnat/system-lynxos178-ppc.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.01;
diff --git a/gcc/ada/libgnat/system-lynxos178-x86.ads b/gcc/ada/libgnat/system-lynxos178-x86.ads
index c151472..b14f48b 100644
--- a/gcc/ada/libgnat/system-lynxos178-x86.ads
+++ b/gcc/ada/libgnat/system-lynxos178-x86.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.01;
diff --git a/gcc/ada/libgnat/system-mingw.ads b/gcc/ada/libgnat/system-mingw.ads
index cf960da..c05dee7e 100644
--- a/gcc/ada/libgnat/system-mingw.ads
+++ b/gcc/ada/libgnat/system-mingw.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.01;
diff --git a/gcc/ada/libgnat/system-qnx-aarch64.ads b/gcc/ada/libgnat/system-qnx-aarch64.ads
index 37b8fd1..f3316c3 100644
--- a/gcc/ada/libgnat/system-qnx-aarch64.ads
+++ b/gcc/ada/libgnat/system-qnx-aarch64.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.000_001;
diff --git a/gcc/ada/libgnat/system-rtems.ads b/gcc/ada/libgnat/system-rtems.ads
index 099c234..8907d9e 100644
--- a/gcc/ada/libgnat/system-rtems.ads
+++ b/gcc/ada/libgnat/system-rtems.ads
@@ -61,7 +61,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.01;
diff --git a/gcc/ada/libgnat/system-solaris-sparc.ads b/gcc/ada/libgnat/system-solaris-sparc.ads
index 0e1ce01..f211eed 100644
--- a/gcc/ada/libgnat/system-solaris-sparc.ads
+++ b/gcc/ada/libgnat/system-solaris-sparc.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.01;
diff --git a/gcc/ada/libgnat/system-solaris-x86.ads b/gcc/ada/libgnat/system-solaris-x86.ads
index 010ce5b..82fe656 100644
--- a/gcc/ada/libgnat/system-solaris-x86.ads
+++ b/gcc/ada/libgnat/system-solaris-x86.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 0.01;
diff --git a/gcc/ada/libgnat/system-vxworks-arm-rtp-smp.ads b/gcc/ada/libgnat/system-vxworks-arm-rtp-smp.ads
index 91806e5..7412611 100644
--- a/gcc/ada/libgnat/system-vxworks-arm-rtp-smp.ads
+++ b/gcc/ada/libgnat/system-vxworks-arm-rtp-smp.ads
@@ -59,7 +59,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks-arm-rtp.ads b/gcc/ada/libgnat/system-vxworks-arm-rtp.ads
index de13974..697f351 100644
--- a/gcc/ada/libgnat/system-vxworks-arm-rtp.ads
+++ b/gcc/ada/libgnat/system-vxworks-arm-rtp.ads
@@ -59,7 +59,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks-arm.ads b/gcc/ada/libgnat/system-vxworks-arm.ads
index fac4e72..5f767b2 100644
--- a/gcc/ada/libgnat/system-vxworks-arm.ads
+++ b/gcc/ada/libgnat/system-vxworks-arm.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks-e500-kernel.ads b/gcc/ada/libgnat/system-vxworks-e500-kernel.ads
index cf89c2d..2d64186 100644
--- a/gcc/ada/libgnat/system-vxworks-e500-kernel.ads
+++ b/gcc/ada/libgnat/system-vxworks-e500-kernel.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks-e500-rtp-smp.ads b/gcc/ada/libgnat/system-vxworks-e500-rtp-smp.ads
index 862f3f6..46cd6e7 100644
--- a/gcc/ada/libgnat/system-vxworks-e500-rtp-smp.ads
+++ b/gcc/ada/libgnat/system-vxworks-e500-rtp-smp.ads
@@ -59,7 +59,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks-e500-rtp.ads b/gcc/ada/libgnat/system-vxworks-e500-rtp.ads
index a3baecb..c232fe0 100644
--- a/gcc/ada/libgnat/system-vxworks-e500-rtp.ads
+++ b/gcc/ada/libgnat/system-vxworks-e500-rtp.ads
@@ -59,7 +59,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks-e500-vthread.ads b/gcc/ada/libgnat/system-vxworks-e500-vthread.ads
index fc92958..929a642 100644
--- a/gcc/ada/libgnat/system-vxworks-e500-vthread.ads
+++ b/gcc/ada/libgnat/system-vxworks-e500-vthread.ads
@@ -59,7 +59,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks-ppc-kernel.ads b/gcc/ada/libgnat/system-vxworks-ppc-kernel.ads
index 383c820..63cebb7 100644
--- a/gcc/ada/libgnat/system-vxworks-ppc-kernel.ads
+++ b/gcc/ada/libgnat/system-vxworks-ppc-kernel.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks-ppc-ravenscar.ads b/gcc/ada/libgnat/system-vxworks-ppc-ravenscar.ads
index 53a1f9e..4347a01 100644
--- a/gcc/ada/libgnat/system-vxworks-ppc-ravenscar.ads
+++ b/gcc/ada/libgnat/system-vxworks-ppc-ravenscar.ads
@@ -82,7 +82,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks-ppc-rtp-smp.ads b/gcc/ada/libgnat/system-vxworks-ppc-rtp-smp.ads
index aa99413..469c0f3 100644
--- a/gcc/ada/libgnat/system-vxworks-ppc-rtp-smp.ads
+++ b/gcc/ada/libgnat/system-vxworks-ppc-rtp-smp.ads
@@ -59,7 +59,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks-ppc-rtp.ads b/gcc/ada/libgnat/system-vxworks-ppc-rtp.ads
index acb20c4..8fba1b0 100644
--- a/gcc/ada/libgnat/system-vxworks-ppc-rtp.ads
+++ b/gcc/ada/libgnat/system-vxworks-ppc-rtp.ads
@@ -59,7 +59,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks-ppc-vthread.ads b/gcc/ada/libgnat/system-vxworks-ppc-vthread.ads
index aca420e..a4f4eb2 100644
--- a/gcc/ada/libgnat/system-vxworks-ppc-vthread.ads
+++ b/gcc/ada/libgnat/system-vxworks-ppc-vthread.ads
@@ -59,7 +59,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks-ppc.ads b/gcc/ada/libgnat/system-vxworks-ppc.ads
index 99644ee..67d936a 100644
--- a/gcc/ada/libgnat/system-vxworks-ppc.ads
+++ b/gcc/ada/libgnat/system-vxworks-ppc.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks-x86-kernel.ads b/gcc/ada/libgnat/system-vxworks-x86-kernel.ads
index 3781020..e4d0344 100644
--- a/gcc/ada/libgnat/system-vxworks-x86-kernel.ads
+++ b/gcc/ada/libgnat/system-vxworks-x86-kernel.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks-x86-rtp-smp.ads b/gcc/ada/libgnat/system-vxworks-x86-rtp-smp.ads
index 374041c..f2a4142 100644
--- a/gcc/ada/libgnat/system-vxworks-x86-rtp-smp.ads
+++ b/gcc/ada/libgnat/system-vxworks-x86-rtp-smp.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks-x86-rtp.ads b/gcc/ada/libgnat/system-vxworks-x86-rtp.ads
index cff7291..d597600 100644
--- a/gcc/ada/libgnat/system-vxworks-x86-rtp.ads
+++ b/gcc/ada/libgnat/system-vxworks-x86-rtp.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks-x86-vthread.ads b/gcc/ada/libgnat/system-vxworks-x86-vthread.ads
index 1867196..a1eb8f0 100644
--- a/gcc/ada/libgnat/system-vxworks-x86-vthread.ads
+++ b/gcc/ada/libgnat/system-vxworks-x86-vthread.ads
@@ -59,7 +59,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks-x86.ads b/gcc/ada/libgnat/system-vxworks-x86.ads
index c82a61f..226a3dc 100644
--- a/gcc/ada/libgnat/system-vxworks-x86.ads
+++ b/gcc/ada/libgnat/system-vxworks-x86.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks7-aarch64-rtp-smp.ads b/gcc/ada/libgnat/system-vxworks7-aarch64-rtp-smp.ads
index 37bf607..e2ed214 100644
--- a/gcc/ada/libgnat/system-vxworks7-aarch64-rtp-smp.ads
+++ b/gcc/ada/libgnat/system-vxworks7-aarch64-rtp-smp.ads
@@ -59,7 +59,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks7-aarch64.ads b/gcc/ada/libgnat/system-vxworks7-aarch64.ads
index c386500..ef1211b 100644
--- a/gcc/ada/libgnat/system-vxworks7-aarch64.ads
+++ b/gcc/ada/libgnat/system-vxworks7-aarch64.ads
@@ -59,7 +59,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks7-arm-rtp-smp.ads b/gcc/ada/libgnat/system-vxworks7-arm-rtp-smp.ads
index 7e2db7a..2b4c64e 100644
--- a/gcc/ada/libgnat/system-vxworks7-arm-rtp-smp.ads
+++ b/gcc/ada/libgnat/system-vxworks7-arm-rtp-smp.ads
@@ -59,7 +59,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks7-arm.ads b/gcc/ada/libgnat/system-vxworks7-arm.ads
index fac4e72..5f767b2 100644
--- a/gcc/ada/libgnat/system-vxworks7-arm.ads
+++ b/gcc/ada/libgnat/system-vxworks7-arm.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks7-e500-kernel.ads b/gcc/ada/libgnat/system-vxworks7-e500-kernel.ads
index e03264e..4182a1f 100644
--- a/gcc/ada/libgnat/system-vxworks7-e500-kernel.ads
+++ b/gcc/ada/libgnat/system-vxworks7-e500-kernel.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks7-e500-rtp-smp.ads b/gcc/ada/libgnat/system-vxworks7-e500-rtp-smp.ads
index a9b3317..d4a303b 100644
--- a/gcc/ada/libgnat/system-vxworks7-e500-rtp-smp.ads
+++ b/gcc/ada/libgnat/system-vxworks7-e500-rtp-smp.ads
@@ -59,7 +59,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks7-e500-rtp.ads b/gcc/ada/libgnat/system-vxworks7-e500-rtp.ads
index 3e963d0..c7acf95 100644
--- a/gcc/ada/libgnat/system-vxworks7-e500-rtp.ads
+++ b/gcc/ada/libgnat/system-vxworks7-e500-rtp.ads
@@ -59,7 +59,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks7-ppc-kernel.ads b/gcc/ada/libgnat/system-vxworks7-ppc-kernel.ads
index 93b3271..71d06b4 100644
--- a/gcc/ada/libgnat/system-vxworks7-ppc-kernel.ads
+++ b/gcc/ada/libgnat/system-vxworks7-ppc-kernel.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks7-ppc-rtp-smp.ads b/gcc/ada/libgnat/system-vxworks7-ppc-rtp-smp.ads
index e5d984b..3879614 100644
--- a/gcc/ada/libgnat/system-vxworks7-ppc-rtp-smp.ads
+++ b/gcc/ada/libgnat/system-vxworks7-ppc-rtp-smp.ads
@@ -59,7 +59,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks7-ppc-rtp.ads b/gcc/ada/libgnat/system-vxworks7-ppc-rtp.ads
index e96d303..b5393cd 100644
--- a/gcc/ada/libgnat/system-vxworks7-ppc-rtp.ads
+++ b/gcc/ada/libgnat/system-vxworks7-ppc-rtp.ads
@@ -59,7 +59,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks7-ppc64-kernel.ads b/gcc/ada/libgnat/system-vxworks7-ppc64-kernel.ads
index 90499f6..94f69ee 100644
--- a/gcc/ada/libgnat/system-vxworks7-ppc64-kernel.ads
+++ b/gcc/ada/libgnat/system-vxworks7-ppc64-kernel.ads
@@ -59,7 +59,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks7-ppc64-rtp-smp.ads b/gcc/ada/libgnat/system-vxworks7-ppc64-rtp-smp.ads
index 49b22b6..bafa41d 100644
--- a/gcc/ada/libgnat/system-vxworks7-ppc64-rtp-smp.ads
+++ b/gcc/ada/libgnat/system-vxworks7-ppc64-rtp-smp.ads
@@ -59,7 +59,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks7-x86-kernel.ads b/gcc/ada/libgnat/system-vxworks7-x86-kernel.ads
index d7b35dd..ae0c39f 100644
--- a/gcc/ada/libgnat/system-vxworks7-x86-kernel.ads
+++ b/gcc/ada/libgnat/system-vxworks7-x86-kernel.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks7-x86-rtp-smp.ads b/gcc/ada/libgnat/system-vxworks7-x86-rtp-smp.ads
index 293ede8..4681bba 100644
--- a/gcc/ada/libgnat/system-vxworks7-x86-rtp-smp.ads
+++ b/gcc/ada/libgnat/system-vxworks7-x86-rtp-smp.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks7-x86-rtp.ads b/gcc/ada/libgnat/system-vxworks7-x86-rtp.ads
index caf458f..6b176d1 100644
--- a/gcc/ada/libgnat/system-vxworks7-x86-rtp.ads
+++ b/gcc/ada/libgnat/system-vxworks7-x86-rtp.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks7-x86_64-kernel.ads b/gcc/ada/libgnat/system-vxworks7-x86_64-kernel.ads
index a5f00ff..eadf5ee 100644
--- a/gcc/ada/libgnat/system-vxworks7-x86_64-kernel.ads
+++ b/gcc/ada/libgnat/system-vxworks7-x86_64-kernel.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/libgnat/system-vxworks7-x86_64-rtp-smp.ads b/gcc/ada/libgnat/system-vxworks7-x86_64-rtp-smp.ads
index 05e69e5..a97b80a 100644
--- a/gcc/ada/libgnat/system-vxworks7-x86_64-rtp-smp.ads
+++ b/gcc/ada/libgnat/system-vxworks7-x86_64-rtp-smp.ads
@@ -57,7 +57,7 @@ package System is
Max_Base_Digits : constant := Long_Long_Float'Digits;
Max_Digits : constant := Long_Long_Float'Digits;
- Max_Mantissa : constant := 63;
+ Max_Mantissa : constant := Standard'Max_Integer_Size - 1;
Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
Tick : constant := 1.0 / 60.0;
diff --git a/gcc/ada/make.adb b/gcc/ada/make.adb
index 0034d1a..ede4c5a 100644
--- a/gcc/ada/make.adb
+++ b/gcc/ada/make.adb
@@ -464,7 +464,7 @@ package body Make is
Ada_Flag_1 : constant String_Access := new String'("-x");
Ada_Flag_2 : constant String_Access := new String'("ada");
AdaSCIL_Flag : constant String_Access := new String'("adascil");
- GNAT_Flag : constant String_Access := new String'("-gnatpg");
+ GNAT_Flag : constant String_Access := new String'("-gnatg");
Do_Not_Check_Flag : constant String_Access := new String'("-x");
Object_Suffix : constant String := Get_Target_Object_Suffix.all;
@@ -1677,7 +1677,7 @@ package body Make is
L : File_Name_Type;
Source_Index : Int;
Args : Argument_List) return Process_Id;
- -- Compiles S using Args. If S is a GNAT predefined source "-gnatpg" is
+ -- Compiles S using Args. If S is a GNAT predefined source "-gnatg" is
-- added to Args. Non blocking call. L corresponds to the expected
-- library file name. Process_Id of the process spawned to execute the
-- compilation.
@@ -2027,7 +2027,7 @@ package body Make is
end loop;
end;
- -- Set -gnatpg for predefined files (for this purpose the renamings
+ -- Set -gnatg for predefined files (for this purpose the renamings
-- such as Text_IO do not count as predefined). Note that we strip
-- the directory name from the source file name because the call to
-- Fname.Is_Predefined_File_Name cannot deal with directory prefixes.
@@ -4697,19 +4697,9 @@ package body Make is
pragma Assert (Argv'Last = 2);
Minimal_Recompilation := True;
- -- -u
+ -- -u and -U (they are differentiated elsewhere)
- elsif Argv (2) = 'u' and then Argv'Last = 2 then
- Unique_Compile := True;
- Compile_Only := True;
- Do_Bind_Step := False;
- Do_Link_Step := False;
-
- -- -U
-
- elsif Argv (2) = 'U'
- and then Argv'Last = 2
- then
+ elsif Argv (2) in 'u' | 'U' and then Argv'Last = 2 then
Unique_Compile := True;
Compile_Only := True;
Do_Bind_Step := False;
diff --git a/gcc/ada/opt.ads b/gcc/ada/opt.ads
index 3e9f36e..f55e9c6 100644
--- a/gcc/ada/opt.ads
+++ b/gcc/ada/opt.ads
@@ -364,6 +364,11 @@ package Opt is
-- GNAT
-- Names of configuration pragmas files (given by switches -gnatec)
+ Config_Files_Store_Basename : Boolean := False;
+ -- GNAT
+ -- Set True for -gnateb. Tells GNAT that config files should be referred to
+ -- by their basename and their checksums computed in ALI files.
+
Configurable_Run_Time_Mode : Boolean := False;
-- GNAT, GNATBIND
-- Set True if the compiler is operating in configurable run-time mode.
@@ -719,6 +724,10 @@ package Opt is
-- the name is of the form .xxx, then to name.xxx where name is the source
-- file name with extension stripped.
+ Generate_Asm : Boolean := False;
+ -- GNAT
+ -- True if generating assembly instead of an object file, via the -S switch
+
Generate_C_Code : Boolean := False;
-- GNAT, GNATBIND
-- If True, the Cprint circuitry to generate C code output is activated.
diff --git a/gcc/ada/osint-c.adb b/gcc/ada/osint-c.adb
index 0010a8d..4fc0998 100644
--- a/gcc/ada/osint-c.adb
+++ b/gcc/ada/osint-c.adb
@@ -475,14 +475,14 @@ package body Osint.C is
begin
-- Make sure that the object file has the expected extension
+ -- Allow for either .o or .c (for C code generation)
if NL <= EL
or else
- (Name (NL - EL + Name'First .. Name'Last) /= Ext
+ (not Generate_Asm
+ and then Name (NL - EL + Name'First .. Name'Last) /= Ext
and then Name (NL - 2 + Name'First .. Name'Last) /= ".o"
- and then
- (not Generate_C_Code
- or else Name (NL - 2 + Name'First .. Name'Last) /= ".c"))
+ and then Name (NL - 2 + Name'First .. Name'Last) /= ".c")
then
Fail ("incorrect object file extension");
end if;
diff --git a/gcc/ada/par-ch13.adb b/gcc/ada/par-ch13.adb
index 95223a1..8bee840 100644
--- a/gcc/ada/par-ch13.adb
+++ b/gcc/ada/par-ch13.adb
@@ -23,6 +23,8 @@
-- --
------------------------------------------------------------------------------
+with Rident; use Rident;
+with Restrict; use Restrict;
pragma Style_Checks (All_Checks);
-- Turn off subprogram body ordering check. Subprograms are in order
-- by RM section rather than alphabetical
@@ -264,20 +266,28 @@ package body Ch13 is
-- The aspect mark is not recognized
if A_Id = No_Aspect then
- Error_Msg_Warn := not Debug_Flag_2;
- Error_Msg_N ("<<& is not a valid aspect identifier", Token_Node);
- OK := False;
-
- -- Check bad spelling
-
- for J in Aspect_Id_Exclude_No_Aspect loop
- if Is_Bad_Spelling_Of (Token_Name, Aspect_Names (J)) then
- Error_Msg_Name_1 := Aspect_Names (J);
- Error_Msg_N -- CODEFIX
- ("\<<possible misspelling of%", Token_Node);
- exit;
+ declare
+ Msg_Issued : Boolean := False;
+ begin
+ Check_Restriction (Msg_Issued, No_Unrecognized_Aspects, Aspect);
+ if not Msg_Issued then
+ Error_Msg_Warn := not Debug_Flag_2;
+ Error_Msg_N
+ ("<<& is not a valid aspect identifier", Token_Node);
+ OK := False;
+
+ -- Check bad spelling
+
+ for J in Aspect_Id_Exclude_No_Aspect loop
+ if Is_Bad_Spelling_Of (Token_Name, Aspect_Names (J)) then
+ Error_Msg_Name_1 := Aspect_Names (J);
+ Error_Msg_N -- CODEFIX
+ ("\<<possible misspelling of%", Token_Node);
+ exit;
+ end if;
+ end loop;
end if;
- end loop;
+ end;
Scan; -- past incorrect identifier
diff --git a/gcc/ada/par-ch6.adb b/gcc/ada/par-ch6.adb
index c8f4d87..0fcd23a 100644
--- a/gcc/ada/par-ch6.adb
+++ b/gcc/ada/par-ch6.adb
@@ -1650,7 +1650,6 @@ package body Ch6 is
elsif Token = Tok_Comma then
T_Semicolon;
- Scan; -- past comma
-- Special check for omitted separator
diff --git a/gcc/ada/par-load.adb b/gcc/ada/par-load.adb
index a1857dc..ecd5404 100644
--- a/gcc/ada/par-load.adb
+++ b/gcc/ada/par-load.adb
@@ -318,7 +318,7 @@ begin
Spec_Name := Get_Parent_Spec_Name (Unit_Name (Cur_Unum));
- if Spec_Name /= No_Unit_Name then
+ if Present (Spec_Name) then
Unum :=
Load_Unit
(Load_Name => Spec_Name,
diff --git a/gcc/ada/par-prag.adb b/gcc/ada/par-prag.adb
index 5783c33..51409f2 100644
--- a/gcc/ada/par-prag.adb
+++ b/gcc/ada/par-prag.adb
@@ -105,6 +105,9 @@ function Prag (Pragma_Node : Node_Id; Semi : Source_Ptr) return Node_Id is
-- No_Dependence must be processed at parse time, since otherwise it gets
-- handled too late.
--
+ -- No_Unrecognized_Aspects must be processed at parse time, since
+ -- unrecognized aspects are ignored by the parser.
+ --
-- Note that we don't need to do full error checking for badly formed cases
-- of restrictions, since these will be caught during semantic analysis.
@@ -259,6 +262,12 @@ function Prag (Pragma_Node : Node_Id; Semi : Source_Ptr) return Node_Id is
("??% restriction is obsolete and ignored, consider " &
"using 'S'P'A'R'K_'Mode and gnatprove instead", Arg);
+ when Name_No_Unrecognized_Aspects =>
+ Set_Restriction
+ (No_Unrecognized_Aspects,
+ Pragma_Node,
+ Prag_Id = Pragma_Restriction_Warnings);
+
when others =>
null;
end case;
diff --git a/gcc/ada/par-tchk.adb b/gcc/ada/par-tchk.adb
index 65ff45a..7a3ed5c 100644
--- a/gcc/ada/par-tchk.adb
+++ b/gcc/ada/par-tchk.adb
@@ -436,7 +436,6 @@ package body Tchk is
procedure T_Semicolon is
begin
-
if Token = Tok_Semicolon then
Scan;
diff --git a/gcc/ada/par.adb b/gcc/ada/par.adb
index 4c3a154..95695d2 100644
--- a/gcc/ada/par.adb
+++ b/gcc/ada/par.adb
@@ -1546,6 +1546,10 @@ begin
end loop;
end;
+ if Config_Files_Store_Basename then
+ Complete_Source_File_Entry;
+ end if;
+
-- Normal case of compilation unit
else
diff --git a/gcc/ada/rtsfind.adb b/gcc/ada/rtsfind.adb
index 872ce01..6a0631f 100644
--- a/gcc/ada/rtsfind.adb
+++ b/gcc/ada/rtsfind.adb
@@ -423,7 +423,7 @@ package body Rtsfind is
(Unit_Name (Current_Sem_Unit));
begin
- if Parent_Name /= No_Unit_Name then
+ if Present (Parent_Name) then
Get_Name_String (Parent_Name);
declare
diff --git a/gcc/ada/rtsfind.ads b/gcc/ada/rtsfind.ads
index 42578db..665458f 100644
--- a/gcc/ada/rtsfind.ads
+++ b/gcc/ada/rtsfind.ads
@@ -249,14 +249,24 @@ package Rtsfind is
System_Fat_VAX_G_Float,
System_Finalization_Masters,
System_Finalization_Root,
- System_Fore,
+ System_Fore_Decimal_32,
+ System_Fore_Decimal_64,
+ System_Fore_Decimal_128,
+ System_Fore_Fixed_32,
+ System_Fore_Fixed_64,
+ System_Fore_Fixed_128,
+ System_Fore_Real,
System_Img_Bool,
System_Img_Char,
- System_Img_Dec,
+ System_Img_Decimal_32,
+ System_Img_Decimal_64,
+ System_Img_Decimal_128,
System_Img_Enum,
System_Img_Enum_New,
+ System_Img_Fixed_32,
+ System_Img_Fixed_64,
+ System_Img_Fixed_128,
System_Img_Int,
- System_Img_LLD,
System_Img_LLI,
System_Img_LLLI,
System_Img_LLU,
@@ -417,10 +427,14 @@ package Rtsfind is
System_Unsigned_Types,
System_Val_Bool,
System_Val_Char,
- System_Val_Dec,
+ System_Val_Decimal_32,
+ System_Val_Decimal_64,
+ System_Val_Decimal_128,
System_Val_Enum,
+ System_Val_Fixed_32,
+ System_Val_Fixed_64,
+ System_Val_Fixed_128,
System_Val_Int,
- System_Val_LLD,
System_Val_LLI,
System_Val_LLLI,
System_Val_LLU,
@@ -756,8 +770,10 @@ package Rtsfind is
RE_Subtract_With_Ovflo_Check64, -- System.Arith_64
RE_Add_With_Ovflo_Check128, -- System.Arith_128
+ RE_Double_Divide128, -- System.Arith_128
RE_Multiply_With_Ovflo_Check128, -- System.Arith_128
RE_Subtract_With_Ovflo_Check128, -- System.Arith_128
+ RE_Scaled_Divide128, -- System.Arith_128
RE_Create_AST_Handler, -- System.AST_Handling
@@ -943,14 +959,30 @@ package Rtsfind is
RE_Root_Controlled, -- System.Finalization_Root
RE_Root_Controlled_Ptr, -- System.Finalization_Root
- RE_Fore, -- System.Fore
+ RE_Fore_Decimal32, -- System.Fore_Decimal_32
+
+ RE_Fore_Decimal64, -- System.Fore_Decimal_64
+
+ RE_Fore_Decimal128, -- System.Fore_Decimal_128
+
+ RE_Fore_Fixed32, -- System.Fore_Fixed_32
+
+ RE_Fore_Fixed64, -- System.Fore_Fixed_64
+
+ RE_Fore_Fixed128, -- System.Fore_Fixed_128
+
+ RE_Fore_Real, -- System.Fore_Real
RE_Image_Boolean, -- System.Img_Bool
RE_Image_Character, -- System.Img_Char
RE_Image_Character_05, -- System.Img_Char
- RE_Image_Decimal, -- System.Img_Dec
+ RE_Image_Decimal32, -- System.Img_Decimal_32
+
+ RE_Image_Decimal64, -- System.Img_Decimal_64
+
+ RE_Image_Decimal128, -- System.Img_Decimal_128
RE_Image_Enumeration_8, -- System.Img_Enum_New
RE_Image_Enumeration_16, -- System.Img_Enum_New
@@ -958,8 +990,6 @@ package Rtsfind is
RE_Image_Integer, -- System.Img_Int
- RE_Image_Long_Long_Decimal, -- System.Img_LLD
-
RE_Image_Long_Long_Integer, -- System.Img_LLI
RE_Image_Long_Long_Long_Integer, -- System.Img_LLLI
@@ -968,6 +998,10 @@ package Rtsfind is
RE_Image_Long_Long_Long_Unsigned, -- System.Img_LLLU
+ RE_Image_Fixed32, -- System.Img_Fixed_32
+ RE_Image_Fixed64, -- System.Img_Fixed_64
+ RE_Image_Fixed128, -- System.Img_Fixed_128
+
RE_Image_Ordinary_Fixed_Point, -- System.Img_Real
RE_Image_Floating_Point, -- System.Img_Real
@@ -1835,6 +1869,8 @@ package Rtsfind is
RE_I_LI, -- System.Stream_Attributes
RE_I_LLF, -- System.Stream_Attributes
RE_I_LLI, -- System.Stream_Attributes
+ RE_I_LLLI, -- System.Stream_Attributes
+ RE_I_LLLU, -- System.Stream_Attributes
RE_I_LLU, -- System.Stream_Attributes
RE_I_LU, -- System.Stream_Attributes
RE_I_SF, -- System.Stream_Attributes
@@ -1858,6 +1894,8 @@ package Rtsfind is
RE_W_LI, -- System.Stream_Attributes
RE_W_LLF, -- System.Stream_Attributes
RE_W_LLI, -- System.Stream_Attributes
+ RE_W_LLLI, -- System.Stream_Attributes
+ RE_W_LLLU, -- System.Stream_Attributes
RE_W_LLU, -- System.Stream_Attributes
RE_W_LU, -- System.Stream_Attributes
RE_W_SF, -- System.Stream_Attributes
@@ -1991,15 +2029,23 @@ package Rtsfind is
RE_Value_Character, -- System.Val_Char
- RE_Value_Decimal, -- System.Val_Dec
+ RE_Value_Decimal32, -- System_Val_Decimal_32
+
+ RE_Value_Decimal64, -- System_Val_Decimal_64
+
+ RE_Value_Decimal128, -- System_Val_Decimal_128
RE_Value_Enumeration_8, -- System.Val_Enum
RE_Value_Enumeration_16, -- System.Val_Enum
RE_Value_Enumeration_32, -- System.Val_Enum
- RE_Value_Integer, -- System.Val_Int
+ RE_Value_Fixed32, -- System_Val_Fixed_32
+
+ RE_Value_Fixed64, -- System_Val_Fixed_64
- RE_Value_Long_Long_Decimal, -- System.Val_LLD
+ RE_Value_Fixed128, -- System_Val_Fixed_128
+
+ RE_Value_Integer, -- System.Val_Int
RE_Value_Long_Long_Integer, -- System.Val_LLI
@@ -2403,8 +2449,10 @@ package Rtsfind is
RE_Subtract_With_Ovflo_Check64 => System_Arith_64,
RE_Add_With_Ovflo_Check128 => System_Arith_128,
+ RE_Double_Divide128 => System_Arith_128,
RE_Multiply_With_Ovflo_Check128 => System_Arith_128,
RE_Subtract_With_Ovflo_Check128 => System_Arith_128,
+ RE_Scaled_Divide128 => System_Arith_128,
RE_Create_AST_Handler => System_AST_Handling,
@@ -2596,14 +2644,30 @@ package Rtsfind is
RE_Root_Controlled => System_Finalization_Root,
RE_Root_Controlled_Ptr => System_Finalization_Root,
- RE_Fore => System_Fore,
+ RE_Fore_Decimal32 => System_Fore_Decimal_32,
+
+ RE_Fore_Decimal64 => System_Fore_Decimal_64,
+
+ RE_Fore_Decimal128 => System_Fore_Decimal_128,
+
+ RE_Fore_Fixed32 => System_Fore_Fixed_32,
+
+ RE_Fore_Fixed64 => System_Fore_Fixed_64,
+
+ RE_Fore_Fixed128 => System_Fore_Fixed_128,
+
+ RE_Fore_Real => System_Fore_Real,
RE_Image_Boolean => System_Img_Bool,
RE_Image_Character => System_Img_Char,
RE_Image_Character_05 => System_Img_Char,
- RE_Image_Decimal => System_Img_Dec,
+ RE_Image_Decimal32 => System_Img_Decimal_32,
+
+ RE_Image_Decimal64 => System_Img_Decimal_64,
+
+ RE_Image_Decimal128 => System_Img_Decimal_128,
RE_Image_Enumeration_8 => System_Img_Enum_New,
RE_Image_Enumeration_16 => System_Img_Enum_New,
@@ -2611,8 +2675,6 @@ package Rtsfind is
RE_Image_Integer => System_Img_Int,
- RE_Image_Long_Long_Decimal => System_Img_LLD,
-
RE_Image_Long_Long_Integer => System_Img_LLI,
RE_Image_Long_Long_Long_Integer => System_Img_LLLI,
@@ -2621,6 +2683,10 @@ package Rtsfind is
RE_Image_Long_Long_Long_Unsigned => System_Img_LLLU,
+ RE_Image_Fixed32 => System_Img_Fixed_32,
+ RE_Image_Fixed64 => System_Img_Fixed_64,
+ RE_Image_Fixed128 => System_Img_Fixed_128,
+
RE_Image_Ordinary_Fixed_Point => System_Img_Real,
RE_Image_Floating_Point => System_Img_Real,
@@ -3488,6 +3554,8 @@ package Rtsfind is
RE_I_LI => System_Stream_Attributes,
RE_I_LLF => System_Stream_Attributes,
RE_I_LLI => System_Stream_Attributes,
+ RE_I_LLLI => System_Stream_Attributes,
+ RE_I_LLLU => System_Stream_Attributes,
RE_I_LLU => System_Stream_Attributes,
RE_I_LU => System_Stream_Attributes,
RE_I_SF => System_Stream_Attributes,
@@ -3511,6 +3579,8 @@ package Rtsfind is
RE_W_LI => System_Stream_Attributes,
RE_W_LLF => System_Stream_Attributes,
RE_W_LLI => System_Stream_Attributes,
+ RE_W_LLLI => System_Stream_Attributes,
+ RE_W_LLLU => System_Stream_Attributes,
RE_W_LLU => System_Stream_Attributes,
RE_W_LU => System_Stream_Attributes,
RE_W_SF => System_Stream_Attributes,
@@ -3644,15 +3714,23 @@ package Rtsfind is
RE_Value_Character => System_Val_Char,
- RE_Value_Decimal => System_Val_Dec,
+ RE_Value_Decimal32 => System_Val_Decimal_32,
+
+ RE_Value_Decimal64 => System_Val_Decimal_64,
+
+ RE_Value_Decimal128 => System_Val_Decimal_128,
RE_Value_Enumeration_8 => System_Val_Enum,
RE_Value_Enumeration_16 => System_Val_Enum,
RE_Value_Enumeration_32 => System_Val_Enum,
- RE_Value_Integer => System_Val_Int,
+ RE_Value_Fixed32 => System_Val_Fixed_32,
+
+ RE_Value_Fixed64 => System_Val_Fixed_64,
- RE_Value_Long_Long_Decimal => System_Val_LLD,
+ RE_Value_Fixed128 => System_Val_Fixed_128,
+
+ RE_Value_Integer => System_Val_Int,
RE_Value_Long_Long_Integer => System_Val_LLI,
diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb
index 90ddee2..3caa84f 100644
--- a/gcc/ada/sem_aggr.adb
+++ b/gcc/ada/sem_aggr.adb
@@ -1680,18 +1680,21 @@ package body Sem_Aggr is
Set_Ekind (Id, E_Variable);
Set_Scope (Id, Ent);
- -- Analyze the expression without expansion, to verify legality.
- -- After analysis we remove references to the index variable because
- -- the expression will be analyzed anew when the enclosing aggregate
- -- is expanded, and the construct is rewritten as a loop with a new
- -- index variable.
+ -- Analyze expression without expansion, to verify legality.
+ -- When generating code, we then remove references to the index
+ -- variable, because the expression will be analyzed anew after
+ -- rewritting as a loop with a new index variable; when not
+ -- generating code we leave the analyzed expression as it is.
Expr := Expression (N);
Expander_Mode_Save_And_Set (False);
Dummy := Resolve_Aggr_Expr (Expr, Single_Elmt => False);
Expander_Mode_Restore;
- Remove_References (Expr);
+
+ if Operating_Mode /= Check_Semantics then
+ Remove_References (Expr);
+ end if;
-- An iterated_component_association may appear in a nested
-- aggregate for a multidimensional structure: preserve the bounds
@@ -1867,10 +1870,15 @@ package body Sem_Aggr is
-- Test for the validity of an others choice if present
if Others_Present and then not Others_Allowed then
- Error_Msg_N
- ("OTHERS choice not allowed here",
- First (Choice_List (First (Component_Associations (N)))));
- return Failure;
+ declare
+ Others_N : constant Node_Id :=
+ First (Choice_List (First (Component_Associations (N))));
+ begin
+ Error_Msg_N ("OTHERS choice not allowed here", Others_N);
+ Error_Msg_N ("\qualify the aggregate with a constrained subtype "
+ & "to provide bounds for it", Others_N);
+ return Failure;
+ end;
end if;
-- Protect against cascaded errors
@@ -3069,6 +3077,10 @@ package body Sem_Aggr is
Error_Msg_N
("others not allowed in delta aggregate", Choice);
+ elsif Nkind (Choice) = N_Subtype_Indication then
+ Resolve_Discrete_Subtype_Indication
+ (Choice, Base_Type (Index_Type));
+
else
Analyze_And_Resolve (Choice, Index_Type);
end if;
@@ -3106,28 +3118,31 @@ package body Sem_Aggr is
else
Choice := First (Choice_List (Assoc));
while Present (Choice) loop
+ Analyze (Choice);
+
if Nkind (Choice) = N_Others_Choice then
Error_Msg_N
("others not allowed in delta aggregate", Choice);
- else
- Analyze (Choice);
+ elsif Is_Entity_Name (Choice)
+ and then Is_Type (Entity (Choice))
+ then
+ -- Choice covers a range of values
- if Is_Entity_Name (Choice)
- and then Is_Type (Entity (Choice))
+ if Base_Type (Entity (Choice)) /=
+ Base_Type (Index_Type)
then
- -- Choice covers a range of values
-
- if Base_Type (Entity (Choice)) /=
- Base_Type (Index_Type)
- then
- Error_Msg_NE
- ("choice does not match index type of &",
- Choice, Typ);
- end if;
- else
- Resolve (Choice, Index_Type);
+ Error_Msg_NE
+ ("choice does not match index type of &",
+ Choice, Typ);
end if;
+
+ elsif Nkind (Choice) = N_Subtype_Indication then
+ Resolve_Discrete_Subtype_Indication
+ (Choice, Base_Type (Index_Type));
+
+ else
+ Resolve (Choice, Index_Type);
end if;
Next (Choice);
@@ -3700,9 +3715,10 @@ package body Sem_Aggr is
--
-- This variable is updated as a side effect of function Get_Value.
- Box_Node : Node_Id := Empty;
- Is_Box_Present : Boolean := False;
- Others_Box : Natural := 0;
+ Box_Node : Node_Id := Empty;
+ Is_Box_Present : Boolean := False;
+ Is_Box_Init_By_Default : Boolean := False;
+ Others_Box : Natural := 0;
-- Ada 2005 (AI-287): Variables used in case of default initialization
-- to provide a functionality similar to Others_Etype. Box_Present
-- indicates that the component takes its default initialization;
@@ -3827,6 +3843,17 @@ package body Sem_Aggr is
Choices => Choice_List,
Expression => Expr,
Box_Present => Is_Box_Present));
+
+ -- If this association has a box for a component that is initialized
+ -- by default, then set flag on the new association to indicate that
+ -- the original association was for such a box-initialized component.
+
+ if Resolve_Record_Aggregate.Is_Box_Present
+ and then not Is_Box_Present
+ and then Is_Box_Init_By_Default -- ???
+ then
+ Set_Was_Default_Init_Box_Association (Last (Assoc_List));
+ end if;
end Add_Association;
-----------------------------
@@ -4044,6 +4071,7 @@ package body Sem_Aggr is
begin
Is_Box_Present := False;
+ Is_Box_Init_By_Default := False;
if No (From) then
return Empty;
@@ -5039,6 +5067,11 @@ package body Sem_Aggr is
Ctyp : constant Entity_Id := Etype (Component);
begin
+ -- Initially assume that the box is for a default-initialized
+ -- component and reset to False in cases where that's not true.
+
+ Is_Box_Init_By_Default := True;
+
-- If there is a default expression for the aggregate, copy
-- it into a new association. This copy must modify the scopes
-- of internal types that may be attached to the expression
@@ -5062,6 +5095,11 @@ package body Sem_Aggr is
and then Nkind (Parent (Component)) = N_Component_Declaration
and then Present (Expression (Parent (Component)))
then
+ -- If component declaration has an initialization expression
+ -- then this is not a case of default initialization.
+
+ Is_Box_Init_By_Default := False;
+
Expr :=
New_Copy_Tree_And_Copy_Dimensions
(Expression (Parent (Component)),
diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
index ee65185..504ca97 100644
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -420,9 +420,11 @@ package body Sem_Attr is
-- no arguments is used when the caller has already generated the
-- required error messages.
- procedure Error_Attr_P (Msg : String);
+ procedure Error_Attr_P (Msg : String; Msg_Cont : String := "");
pragma No_Return (Error_Attr_P);
- -- Like Error_Attr, but error is posted at the start of the prefix
+ -- Like Error_Attr, but error is posted at the start of the prefix. The
+ -- second message Msg_Cont is useful to issue a continuation message
+ -- before raising Bad_Attribute.
procedure Legal_Formal_Attribute;
-- Common processing for attributes Definite and Has_Discriminants.
@@ -2690,10 +2692,13 @@ package body Sem_Attr is
-- Error_Attr_P --
------------------
- procedure Error_Attr_P (Msg : String) is
+ procedure Error_Attr_P (Msg : String; Msg_Cont : String := "") is
begin
Error_Msg_Name_1 := Aname;
Error_Msg_F (Msg, P);
+ if Msg_Cont /= "" then
+ Error_Msg_F (Msg_Cont, P);
+ end if;
Error_Attr;
end Error_Attr_P;
@@ -2842,7 +2847,10 @@ package body Sem_Attr is
and then Attr_Id = Attribute_Old
then " or be eligible for conditional evaluation"
& " (RM 6.1.1 (27))"
- else ""));
+ else ""),
+ Msg_Cont =>
+ "\using pragma Unevaluated_Use_Of_Old (Allow) will make "
+ & "this legal");
when 'W' =>
Error_Msg_Name_1 := Aname;
@@ -3868,7 +3876,7 @@ package body Sem_Attr is
-- Elab_Spec --
---------------
- -- Shares processing with Elab_Body
+ -- Shares processing with Elab_Body attribute
----------------
-- Elaborated --
@@ -4118,7 +4126,9 @@ package body Sem_Attr is
-- Has_Access_Values --
-----------------------
- when Attribute_Has_Access_Values =>
+ when Attribute_Has_Access_Values
+ | Attribute_Has_Tagged_Values
+ =>
Check_Type;
Check_E0;
Set_Etype (N, Standard_Boolean);
@@ -4142,10 +4152,7 @@ package body Sem_Attr is
-- Has_Tagged_Values --
-----------------------
- when Attribute_Has_Tagged_Values =>
- Check_Type;
- Check_E0;
- Set_Etype (N, Standard_Boolean);
+ -- Shares processing with Has_Access_Values attribute
-----------------------
-- Has_Discriminants --
@@ -4375,7 +4382,8 @@ package body Sem_Attr is
-- within the related loop.
function Declared_Within (Nod : Node_Id) return Boolean;
- -- Determine whether Nod appears in the subtree of Loop_Decl
+ -- Determine whether Nod appears in the subtree of Loop_Decl but
+ -- not within the subtree of the prefix P itself.
---------------------
-- Check_Reference --
@@ -4411,6 +4419,9 @@ package body Sem_Attr is
if Stmt = Loop_Decl then
return True;
+ elsif Stmt = P then
+ return False;
+
-- Prevent the search from going too far
elsif Is_Body_Or_Package_Declaration (Stmt) then
@@ -6053,6 +6064,17 @@ package body Sem_Attr is
Check_Real_Type;
Set_Etype (N, Universal_Real);
+ ---------------------------------------
+ -- Small_Denominator/Small_Numerator --
+ ---------------------------------------
+
+ when Attribute_Small_Denominator
+ | Attribute_Small_Numerator
+ =>
+ Check_E0;
+ Check_Fixed_Point_Type;
+ Set_Etype (N, Universal_Integer);
+
------------------
-- Storage_Pool --
------------------
@@ -6632,7 +6654,7 @@ package body Sem_Attr is
Check_E0;
if not Is_Entity_Name (P)
- or else Ekind (Entity (P)) not in Named_Kind
+ or else not Is_Named_Number (Entity (P))
then
Error_Attr_P ("prefix for % attribute must be named number");
@@ -7789,7 +7811,7 @@ package body Sem_Attr is
-- we will do the folding right here (things get confused if we let this
-- case go through the normal circuitry).
- if Attribute_Name (N) = Name_Img
+ if Id = Attribute_Img
and then Is_Entity_Name (P)
and then Is_Enumeration_Type (Etype (Entity (P)))
and then Is_OK_Static_Expression (P)
@@ -8123,7 +8145,7 @@ package body Sem_Attr is
-- T'Descriptor_Size is never static, even if T is static.
if Is_Scalar_Type (P_Entity)
- and then (not Is_Generic_Type (P_Entity))
+ and then not Is_Generic_Type (P_Entity)
and then Is_Static_Subtype (P_Entity)
and then Is_Scalar_Type (Etype (N))
and then
@@ -8147,7 +8169,7 @@ package body Sem_Attr is
if Is_Type (P_Entity)
and then (Is_Scalar_Type (P_Entity) or Is_Array_Type (P_Entity))
- and then (not Is_Generic_Type (P_Entity))
+ and then not Is_Generic_Type (P_Entity)
then
P_Type := P_Entity;
@@ -8155,7 +8177,7 @@ package body Sem_Attr is
elsif Ekind (P_Entity) in E_Variable | E_Constant
and then Is_Array_Type (Etype (P_Entity))
- and then (not Is_Generic_Type (Etype (P_Entity)))
+ and then not Is_Generic_Type (Etype (P_Entity))
then
P_Type := Etype (P_Entity);
@@ -8204,7 +8226,7 @@ package body Sem_Attr is
elsif (Id = Attribute_Size or
Id = Attribute_Max_Size_In_Storage_Elements)
and then Is_Type (P_Entity)
- and then (not Is_Generic_Type (P_Entity))
+ and then not Is_Generic_Type (P_Entity)
and then Known_Static_RM_Size (P_Entity)
then
declare
@@ -8226,7 +8248,7 @@ package body Sem_Attr is
elsif Id = Attribute_Alignment
and then Is_Type (P_Entity)
- and then (not Is_Generic_Type (P_Entity))
+ and then not Is_Generic_Type (P_Entity)
and then Known_Alignment (P_Entity)
then
Compile_Time_Known_Attribute (N, Alignment (P_Entity));
@@ -8235,7 +8257,7 @@ package body Sem_Attr is
-- If this is an access attribute that is known to fail accessibility
-- check, rewrite accordingly.
- elsif Attribute_Name (N) = Name_Access
+ elsif Id = Attribute_Address
and then Raises_Constraint_Error (N)
then
Rewrite (N,
@@ -9894,6 +9916,20 @@ package body Sem_Attr is
Fold_Ureal (N, Small_Value (P_Type), True);
end if;
+ -----------------------
+ -- Small_Denominator --
+ -----------------------
+
+ when Attribute_Small_Denominator =>
+ Fold_Uint (N, Norm_Den (Small_Value (P_Type)), True);
+
+ ---------------------
+ -- Small_Numerator --
+ ---------------------
+
+ when Attribute_Small_Numerator =>
+ Fold_Uint (N, Norm_Num (Small_Value (P_Type)), True);
+
-----------------
-- Stream_Size --
-----------------
diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb
index 0bad136..2d1232e 100644
--- a/gcc/ada/sem_ch10.adb
+++ b/gcc/ada/sem_ch10.adb
@@ -768,7 +768,7 @@ package body Sem_Ch10 is
Unum := Get_Cunit_Unit_Number (N);
Par_Spec_Name := Get_Parent_Spec_Name (Unit_Name (Unum));
- if Par_Spec_Name /= No_Unit_Name then
+ if Present (Par_Spec_Name) then
Unum :=
Load_Unit
(Load_Name => Par_Spec_Name,
@@ -828,6 +828,7 @@ package body Sem_Ch10 is
-- of the child unit does not act as spec any longer.
Set_Acts_As_Spec (N, False);
+ Move_Aspects (From => Unit_Node, To => Unit (Lib_Unit));
Set_Is_Child_Unit (Defining_Entity (Unit_Node));
Set_Debug_Info_Needed (Defining_Entity (Unit (Lib_Unit)));
Set_Comes_From_Source_Default (SCS);
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index af77263..6a32bdc 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -1998,7 +1998,7 @@ package body Sem_Ch12 is
Gen_Par : Entity_Id;
Needs_Freezing : Boolean;
- S : Entity_Id;
+ P : Node_Id;
procedure Check_Generic_Parent;
-- The actual may be an instantiation of a unit
@@ -2102,18 +2102,15 @@ package body Sem_Ch12 is
Needs_Freezing := True;
- S := Current_Scope;
- while Present (S) loop
- if Ekind (S) in E_Block
- | E_Function
- | E_Loop
- | E_Procedure
+ P := Parent (I_Node);
+ while Nkind (P) /= N_Compilation_Unit loop
+ if Nkind (P) = N_Handled_Sequence_Of_Statements
then
Needs_Freezing := False;
exit;
end if;
- S := Scope (S);
+ P := Parent (P);
end loop;
if Needs_Freezing then
@@ -4309,7 +4306,7 @@ package body Sem_Ch12 is
elsif Contains_Instance_Of (Gen_Unit, Current_Scope, Gen_Id) then
Error_Msg_Node_2 := Current_Scope;
Error_Msg_NE
- ("circular Instantiation: & instantiated in &!", N, Gen_Unit);
+ ("circular instantiation: & instantiated in &!", N, Gen_Unit);
Circularity_Detected := True;
Restore_Env;
goto Leave;
@@ -5685,7 +5682,7 @@ package body Sem_Ch12 is
if Contains_Instance_Of (Gen_Unit, Current_Scope, Gen_Id) then
Error_Msg_Node_2 := Current_Scope;
Error_Msg_NE
- ("circular Instantiation: & instantiated in &!", N, Gen_Unit);
+ ("circular instantiation: & instantiated in &!", N, Gen_Unit);
Circularity_Detected := True;
Restore_Hidden_Primitives (Vis_Prims_List);
goto Leave;
@@ -7803,7 +7800,7 @@ package body Sem_Ch12 is
if Node (Elmt) = Scop then
Error_Msg_Node_2 := Inner;
Error_Msg_NE
- ("circular Instantiation: & instantiated within &!",
+ ("circular instantiation: & instantiated within &!",
N, Scop);
return True;
@@ -7813,7 +7810,7 @@ package body Sem_Ch12 is
elsif Contains_Instance_Of (Node (Elmt), Scop, N) then
Error_Msg_Node_2 := Inner;
Error_Msg_NE
- ("circular Instantiation: & instantiated within &!",
+ ("circular instantiation: & instantiated within &!",
N, Node (Elmt));
return True;
end if;
@@ -8805,7 +8802,7 @@ package body Sem_Ch12 is
while not Is_List_Member (P1)
or else not Is_List_Member (P2)
- or else List_Containing (P1) /= List_Containing (P2)
+ or else not In_Same_List (P1, P2)
loop
P1 := True_Parent (P1);
P2 := True_Parent (P2);
@@ -9084,7 +9081,7 @@ package body Sem_Ch12 is
--
-- procedure P ... -- this body freezes Parent_Inst
--
- -- package Inst is new ...
+ -- procedure Inst is new ...
--
-- In this particular scenario, the freeze node for Inst must be
-- inserted in the same manner as that of Parent_Inst - before the
@@ -9095,9 +9092,8 @@ package body Sem_Ch12 is
-- after that of Parent_Inst. This relation is established by
-- comparing the Slocs of Parent_Inst freeze node and Inst.
- elsif List_Containing (Get_Unit_Instantiation_Node (Par)) =
- List_Containing (Inst_Node)
- and then Sloc (Freeze_Node (Par)) < Sloc (Inst_Node)
+ elsif In_Same_List (Get_Unit_Instantiation_Node (Par), Inst_Node)
+ and then Sloc (Freeze_Node (Par)) <= Sloc (Inst_Node)
then
Insert_Freeze_Node_For_Instance (Inst_Node, F_Node);
@@ -9938,7 +9934,7 @@ package body Sem_Ch12 is
if Parent (List_Containing (Get_Unit_Instantiation_Node (Par)))
= Parent (List_Containing (N))
- and then Sloc (Freeze_Node (Par)) < Sloc (N)
+ and then Sloc (Freeze_Node (Par)) <= Sloc (N)
then
Insert_Freeze_Node_For_Instance (N, F_Node);
else
@@ -9992,8 +9988,7 @@ package body Sem_Ch12 is
-- the enclosing package, insert the freeze node after
-- the body.
- elsif List_Containing (Freeze_Node (Par)) =
- List_Containing (Parent (N))
+ elsif In_Same_List (Freeze_Node (Par), Parent (N))
and then Sloc (Freeze_Node (Par)) < Sloc (Parent (N))
then
Insert_Freeze_Node_For_Instance
@@ -10806,6 +10801,16 @@ package body Sem_Ch12 is
Next_Non_Pragma (Formal_Node);
Next (Actual_Of_Formal);
+ -- A formal subprogram may be overloaded, so advance in
+ -- the list of actuals to make sure we do not match two
+ -- successive formals to the same actual. This is only
+ -- relevant for overloadable entities, others have
+ -- distinct names.
+
+ if Is_Overloadable (Actual_Ent) then
+ Next_Entity (Actual_Ent);
+ end if;
+
else
-- No further formals to match, but the generic part may
-- contain inherited operation that are not hidden in the
@@ -11562,7 +11567,7 @@ package body Sem_Ch12 is
-- Use default to construct declaration
if Present (Subt_Mark) then
- Def := New_Copy (Subt_Mark);
+ Def := New_Copy_Tree (Subt_Mark);
else
pragma Assert (Present (Acc_Def));
Def := New_Copy_Tree (Acc_Def);
@@ -12650,10 +12655,10 @@ package body Sem_Ch12 is
Analyzed_Formal : Node_Id;
Actual_Decls : List_Id) return List_Id
is
- A_Gen_T : constant Entity_Id :=
+ A_Gen_T : constant Entity_Id :=
Defining_Identifier (Analyzed_Formal);
- Def : constant Node_Id := Formal_Type_Definition (Formal);
- Gen_T : constant Entity_Id := Defining_Identifier (Formal);
+ Def : constant Node_Id := Formal_Type_Definition (Formal);
+ Gen_T : constant Entity_Id := Defining_Identifier (Formal);
Act_T : Entity_Id;
Ancestor : Entity_Id := Empty;
Decl_Node : Node_Id;
@@ -12963,21 +12968,6 @@ package body Sem_Ch12 is
end if;
Abandon_Instantiation (Actual);
-
- elsif Is_Access_Type (Designated_Type (Act_T))
- and then Is_Constrained (Designated_Type (Designated_Type (Act_T)))
- /=
- Is_Constrained (Designated_Type (Desig_Type))
- then
- Error_Msg_NE
- ("designated type of actual does not match that of formal &",
- Actual, Gen_T);
-
- if not Predicates_Match (Desig_Type, Desig_Act) then
- Error_Msg_N ("\predicates do not match", Actual);
- end if;
-
- Abandon_Instantiation (Actual);
end if;
-- Ada 2005: null-exclusion indicators of the two types must agree
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index 7013094..b48aeb4 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -54,7 +54,6 @@ with Sem_Ch6; use Sem_Ch6;
with Sem_Ch7; use Sem_Ch7;
with Sem_Ch8; use Sem_Ch8;
with Sem_Dim; use Sem_Dim;
-with Sem_Disp; use Sem_Disp;
with Sem_Eval; use Sem_Eval;
with Sem_Prag; use Sem_Prag;
with Sem_Res; use Sem_Res;
@@ -252,6 +251,18 @@ package body Sem_Ch13 is
-- Resolve each one of the operations specified in the specification of
-- Aspect_Aggregate.
+ procedure Validate_Aspect_Stable_Properties
+ (E : Entity_Id; N : Node_Id; Class_Present : Boolean);
+ -- Check legality of functions given in the Ada 202x Stable_Properties
+ -- (or Stable_Properties'Class) aspect.
+
+ procedure Resolve_Aspect_Stable_Properties
+ (Typ_Or_Subp : Entity_Id;
+ Expr : Node_Id;
+ Class_Present : Boolean);
+ -- Resolve each one of the functions specified in the specification of
+ -- aspect Stable_Properties (or Stable_Properties'Class).
+
procedure Resolve_Iterable_Operation
(N : Node_Id;
Cursor : Entity_Id;
@@ -1439,9 +1450,9 @@ package body Sem_Ch13 is
-- Aspect Full_Access_Only must be analyzed last so that
-- aspects Volatile and Atomic, if any, are analyzed.
- if A_Id /= Aspect_Export
- and then A_Id /= Aspect_Import
- and then A_Id /= Aspect_Full_Access_Only
+ if A_Id not in Aspect_Export
+ | Aspect_Full_Access_Only
+ | Aspect_Import
then
Make_Pragma_From_Boolean_Aspect (ASN);
end if;
@@ -2800,9 +2811,7 @@ package body Sem_Ch13 is
Ent := New_Occurrence_Of (E, Sloc (Id));
- if A_Id = Aspect_Attach_Handler
- or else A_Id = Aspect_Interrupt_Handler
- then
+ if A_Id in Aspect_Attach_Handler | Aspect_Interrupt_Handler then
-- Treat the specification as a reference to the protected
-- operation, which might otherwise appear unreferenced and
@@ -2846,10 +2855,10 @@ package body Sem_Ch13 is
-- Check some general restrictions on language defined aspects
if not Implementation_Defined_Aspect (A_Id)
- or else A_Id = Aspect_Async_Readers
- or else A_Id = Aspect_Async_Writers
- or else A_Id = Aspect_Effective_Reads
- or else A_Id = Aspect_Effective_Reads
+ or else A_Id in Aspect_Async_Readers
+ | Aspect_Async_Writers
+ | Aspect_Effective_Reads
+ | Aspect_Effective_Writes
then
Error_Msg_Name_1 := Nam;
@@ -2873,16 +2882,16 @@ package body Sem_Ch13 is
("aspect % not allowed for formal type declaration",
Aspect);
- elsif A_Id /= Aspect_Atomic
- and then A_Id /= Aspect_Volatile
- and then A_Id /= Aspect_Independent
- and then A_Id /= Aspect_Atomic_Components
- and then A_Id /= Aspect_Independent_Components
- and then A_Id /= Aspect_Volatile_Components
- and then A_Id /= Aspect_Async_Readers
- and then A_Id /= Aspect_Async_Writers
- and then A_Id /= Aspect_Effective_Reads
- and then A_Id /= Aspect_Effective_Reads
+ elsif A_Id not in Aspect_Atomic
+ | Aspect_Volatile
+ | Aspect_Independent
+ | Aspect_Atomic_Components
+ | Aspect_Independent_Components
+ | Aspect_Volatile_Components
+ | Aspect_Async_Readers
+ | Aspect_Async_Writers
+ | Aspect_Effective_Reads
+ | Aspect_Effective_Writes
then
Error_Msg_N
("aspect % not allowed for formal type declaration",
@@ -2938,11 +2947,11 @@ package body Sem_Ch13 is
-- an attribute reference whose prefix is Standard, for
-- example Standard'Maximum_Alignment or Standard'Word_Size.
- elsif (A_Id = Aspect_Alignment
- or else A_Id = Aspect_Component_Size
- or else A_Id = Aspect_Object_Size
- or else A_Id = Aspect_Size
- or else A_Id = Aspect_Value_Size)
+ elsif A_Id in Aspect_Alignment
+ | Aspect_Component_Size
+ | Aspect_Object_Size
+ | Aspect_Size
+ | Aspect_Value_Size
and then Present (Expr)
and then Nkind (Expr) = N_Attribute_Reference
and then Nkind (Prefix (Expr)) = N_Identifier
@@ -2958,6 +2967,18 @@ package body Sem_Ch13 is
end if;
end case;
+ if Delay_Required
+
+ and then A_Id = Aspect_Stable_Properties
+ -- ??? It seems like we should do this for all aspects, not
+ -- just Stable_Properties, but that causes as-yet-undiagnosed
+ -- regressions.
+
+ then
+ Set_Has_Delayed_Aspects (E);
+ Set_Is_Delayed_Aspect (Aspect);
+ end if;
+
-- Check 13.1(9.2/5): A representation aspect of a subtype or type
-- shall not be specified (whether by a representation item or an
-- aspect_specification) before the type is completely defined
@@ -3011,9 +3032,8 @@ package body Sem_Ch13 is
=>
-- Indexing aspects apply only to tagged type
- if (A_Id = Aspect_Constant_Indexing
- or else
- A_Id = Aspect_Variable_Indexing)
+ if A_Id in Aspect_Constant_Indexing
+ | Aspect_Variable_Indexing
and then not (Is_Type (E)
and then Is_Tagged_Type (E))
then
@@ -3040,10 +3060,10 @@ package body Sem_Ch13 is
-- illegal specification of this aspect for a subtype now,
-- to prevent malformed rep_item chains.
- if A_Id = Aspect_Input or else
- A_Id = Aspect_Output or else
- A_Id = Aspect_Read or else
- A_Id = Aspect_Write
+ if A_Id in Aspect_Input
+ | Aspect_Output
+ | Aspect_Read
+ | Aspect_Write
then
if not Is_First_Subtype (E) then
Error_Msg_N
@@ -3070,7 +3090,7 @@ package body Sem_Ch13 is
Aitem :=
Make_Attribute_Definition_Clause (Loc,
Name => Ent,
- Chars => Chars (Id),
+ Chars => Nam,
Expression => Relocate_Node (Expr));
-- If the address is specified, then we treat the entity as
@@ -3099,7 +3119,7 @@ package body Sem_Ch13 is
Expression => New_Occurrence_Of (E, Loc)),
Make_Pragma_Argument_Association (Sloc (Expr),
Expression => Relocate_Node (Expr))),
- Pragma_Name => Chars (Id));
+ Pragma_Name => Name_Linker_Section);
-- Linker_Section does not need delaying, as its argument
-- must be a static string. Furthermore, if applied to
@@ -3409,7 +3429,7 @@ package body Sem_Ch13 is
Aitem :=
Make_Attribute_Definition_Clause (Loc,
Name => Ent,
- Chars => Chars (Id),
+ Chars => Nam,
Expression => Relocate_Node (Expr));
end if;
@@ -3424,7 +3444,7 @@ package body Sem_Ch13 is
Expression => Relocate_Node (Expr)),
Make_Pragma_Argument_Association (Sloc (Expr),
Expression => New_Occurrence_Of (E, Loc))),
- Pragma_Name => Chars (Id));
+ Pragma_Name => Nam);
Delay_Required := False;
@@ -3437,7 +3457,7 @@ package body Sem_Ch13 is
Expression => Relocate_Node (Expr)),
Make_Pragma_Argument_Association (Loc,
Expression => New_Occurrence_Of (E, Loc))),
- Pragma_Name => Chars (Id));
+ Pragma_Name => Name_Warnings);
Decorate (Aspect, Aitem);
Insert_Pragma (Aitem);
@@ -3586,11 +3606,17 @@ package body Sem_Ch13 is
-- wrapped inside of a procedure at the freeze point of the
-- private type's full view.
+ -- A type entity argument is appended to facilitate inheriting
+ -- the aspect from parent types (see Build_DIC_Procedure_Body),
+ -- though that extra argument isn't documented for the pragma.
+
when Aspect_Default_Initial_Condition =>
Aitem := Make_Aitem_Pragma
(Pragma_Argument_Associations => New_List (
Make_Pragma_Argument_Association (Loc,
- Expression => Relocate_Node (Expr))),
+ Expression => Relocate_Node (Expr)),
+ Make_Pragma_Argument_Association (Sloc (Ent),
+ Expression => Ent)),
Pragma_Name =>
Name_Default_Initial_Condition);
@@ -3879,7 +3905,7 @@ package body Sem_Ch13 is
Aitem := Make_Aitem_Pragma
(Pragma_Argument_Associations => Args,
- Pragma_Name => Chars (Id));
+ Pragma_Name => Name_Obsolescent);
end;
-- Part_Of
@@ -4165,7 +4191,7 @@ package body Sem_Ch13 is
-- pragmas/attributes but do require delayed analysis.
when Aspect_Default_Value | Aspect_Default_Component_Value =>
- Error_Msg_Name_1 := Chars (Id);
+ Error_Msg_Name_1 := Nam;
if not Is_Type (E) then
Error_Msg_N ("aspect% can only apply to a type", Id);
@@ -4201,6 +4227,12 @@ package body Sem_Ch13 is
Record_Rep_Item (E, Aspect);
goto Continue;
+ when Aspect_Stable_Properties =>
+ Validate_Aspect_Stable_Properties
+ (E, Expr, Class_Present => Class_Present (Aspect));
+ Record_Rep_Item (E, Aspect);
+ goto Continue;
+
when Aspect_Integer_Literal
| Aspect_Real_Literal
| Aspect_String_Literal
@@ -4262,7 +4294,7 @@ package body Sem_Ch13 is
Pname : Name_Id;
begin
- if A_Id = Aspect_Pre or else A_Id = Aspect_Precondition then
+ if A_Id in Aspect_Pre | Aspect_Precondition then
Pname := Name_Precondition;
else
Pname := Name_Postcondition;
@@ -4440,7 +4472,7 @@ package body Sem_Ch13 is
Aitem := Make_Aitem_Pragma
(Pragma_Argument_Associations => Args,
- Pragma_Name => Nam);
+ Pragma_Name => Name_Test_Case);
end Test_Case;
-- Contract_Cases
@@ -4450,7 +4482,7 @@ package body Sem_Ch13 is
(Pragma_Argument_Associations => New_List (
Make_Pragma_Argument_Association (Loc,
Expression => Relocate_Node (Expr))),
- Pragma_Name => Nam);
+ Pragma_Name => Name_Contract_Cases);
Decorate (Aspect, Aitem);
Insert_Pragma (Aitem);
@@ -4463,7 +4495,7 @@ package body Sem_Ch13 is
(Pragma_Argument_Associations => New_List (
Make_Pragma_Argument_Association (Loc,
Expression => Relocate_Node (Expr))),
- Pragma_Name => Nam);
+ Pragma_Name => Name_Subprogram_Variant);
Decorate (Aspect, Aitem);
Insert_Pragma (Aitem);
@@ -4509,7 +4541,7 @@ package body Sem_Ch13 is
goto Continue;
- elsif A_Id = Aspect_Export or else A_Id = Aspect_Import then
+ elsif A_Id in Aspect_Export | Aspect_Import then
Analyze_Aspect_Export_Import;
-- Disable_Controlled
@@ -4581,14 +4613,12 @@ package body Sem_Ch13 is
-- Exclude aspects Export and Import because their pragma
-- syntax does not map directly to a Boolean aspect.
- if A_Id /= Aspect_Export
- and then A_Id /= Aspect_Import
- then
+ if A_Id not in Aspect_Export | Aspect_Import then
Aitem := Make_Aitem_Pragma
(Pragma_Argument_Associations => New_List (
Make_Pragma_Argument_Association (Sloc (Ent),
Expression => Ent)),
- Pragma_Name => Chars (Id));
+ Pragma_Name => Nam);
end if;
-- In general cases, the corresponding pragma/attribute
@@ -4651,7 +4681,7 @@ package body Sem_Ch13 is
Aitem :=
Make_Attribute_Definition_Clause (Loc,
Name => Ent,
- Chars => Chars (Id),
+ Chars => Name_Storage_Size,
Expression => Relocate_Node (Expr));
end if;
end case;
@@ -4698,7 +4728,7 @@ package body Sem_Ch13 is
(Pragma_Argument_Associations => New_List (
Make_Pragma_Argument_Association (Sloc (Ent),
Expression => Ent)),
- Pragma_Name => Chars (Id));
+ Pragma_Name => Nam);
Set_From_Aspect_Specification (Aitem, True);
Set_Corresponding_Aspect (Aitem, Aspect);
@@ -10495,12 +10525,14 @@ package body Sem_Ch13 is
-- Expression from call to Check_Aspect_At_Freeze_Point.
T : constant Entity_Id :=
- (if Present (Freeze_Expr)
+ (if Present (Freeze_Expr) and (A_Id /= Aspect_Stable_Properties)
then Etype (Original_Node (Freeze_Expr))
else Empty);
-- Type required for preanalyze call. We use the original expression to
-- get the proper type, to prevent cascaded errors when the expression
- -- is constant-folded.
+ -- is constant-folded. For Stable_Properties, the aspect value is
+ -- not semantically an expression (although it is syntactically);
+ -- in particular, it has no type.
Err : Boolean;
-- Set False if error
@@ -10578,22 +10610,22 @@ package body Sem_Ch13 is
-- name, so we need to verify that one of these interpretations is
-- the one available at at the freeze point.
- elsif A_Id = Aspect_Input or else
- A_Id = Aspect_Output or else
- A_Id = Aspect_Read or else
- A_Id = Aspect_Write or else
- A_Id = Aspect_Put_Image
+ elsif A_Id in Aspect_Input
+ | Aspect_Output
+ | Aspect_Read
+ | Aspect_Write
+ | Aspect_Put_Image
then
Analyze (End_Decl_Expr);
Check_Overloaded_Name;
- elsif A_Id = Aspect_Variable_Indexing or else
- A_Id = Aspect_Constant_Indexing or else
- A_Id = Aspect_Default_Iterator or else
- A_Id = Aspect_Iterator_Element or else
- A_Id = Aspect_Integer_Literal or else
- A_Id = Aspect_Real_Literal or else
- A_Id = Aspect_String_Literal
+ elsif A_Id in Aspect_Variable_Indexing
+ | Aspect_Constant_Indexing
+ | Aspect_Default_Iterator
+ | Aspect_Iterator_Element
+ | Aspect_Integer_Literal
+ | Aspect_Real_Literal
+ | Aspect_String_Literal
then
-- Make type unfrozen before analysis, to prevent spurious errors
-- about late attributes.
@@ -10619,9 +10651,7 @@ package body Sem_Ch13 is
-- also make its potential components accessible.
if not Analyzed (Freeze_Expr) and then Inside_A_Generic then
- if A_Id = Aspect_Dynamic_Predicate
- or else A_Id = Aspect_Predicate
- then
+ if A_Id in Aspect_Dynamic_Predicate | Aspect_Predicate then
Push_Type (Ent);
Preanalyze_Spec_Expression (Freeze_Expr, Standard_Boolean);
Pop_Type (Ent);
@@ -10647,9 +10677,9 @@ package body Sem_Ch13 is
-- visible for aspects that may reference them.
if Present (Freeze_Expr) and then No (T) then
- if A_Id = Aspect_Dynamic_Predicate
- or else A_Id = Aspect_Predicate
- or else A_Id = Aspect_Priority
+ if A_Id in Aspect_Dynamic_Predicate
+ | Aspect_Predicate
+ | Aspect_Priority
then
Push_Type (Ent);
Check_Aspect_At_Freeze_Point (ASN);
@@ -10665,9 +10695,7 @@ package body Sem_Ch13 is
-- partial view is visible. The expression must be scalar, so use
-- the full view to resolve.
- elsif (A_Id = Aspect_Default_Value
- or else
- A_Id = Aspect_Default_Component_Value)
+ elsif A_Id in Aspect_Default_Component_Value | Aspect_Default_Value
and then Is_Private_Type (T)
then
Preanalyze_Spec_Expression (End_Decl_Expr, Full_View (T));
@@ -10675,10 +10703,10 @@ package body Sem_Ch13 is
-- The following aspect expressions may contain references to
-- components and discriminants of the type.
- elsif A_Id = Aspect_Dynamic_Predicate
- or else A_Id = Aspect_Predicate
- or else A_Id = Aspect_Priority
- or else A_Id = Aspect_CPU
+ elsif A_Id in Aspect_CPU
+ | Aspect_Dynamic_Predicate
+ | Aspect_Predicate
+ | Aspect_Priority
then
Push_Type (Ent);
Preanalyze_Spec_Expression (End_Decl_Expr, T);
@@ -10911,7 +10939,13 @@ package body Sem_Ch13 is
return;
when Aspect_Aggregate =>
- Resolve_Aspect_Aggregate (Entity (ASN), Expr);
+ Resolve_Aspect_Aggregate (Entity (ASN), Expression (ASN));
+ return;
+
+ when Aspect_Stable_Properties =>
+ Resolve_Aspect_Stable_Properties
+ (Entity (ASN), Expression (ASN),
+ Class_Present => Class_Present (ASN));
return;
-- Invariant/Predicate take boolean expressions
@@ -11129,9 +11163,7 @@ package body Sem_Ch13 is
-- Otherwise look at the identifier and see if it is OK
- if Ekind (Ent) in E_Named_Integer | E_Named_Real
- or else Is_Type (Ent)
- then
+ if Is_Named_Number (Ent) or else Is_Type (Ent) then
return;
elsif Ekind (Ent) in E_Constant | E_In_Parameter then
@@ -12700,7 +12732,6 @@ package body Sem_Ch13 is
and then Scope (E) = Current_Scope
then
declare
- A_Id : Aspect_Id;
Ritem : Node_Id;
begin
@@ -12712,12 +12743,10 @@ package body Sem_Ch13 is
and then Entity (Ritem) = E
and then Is_Delayed_Aspect (Ritem)
then
- A_Id := Get_Aspect_Id (Ritem);
-
- if A_Id = Aspect_Dynamic_Predicate
- or else A_Id = Aspect_Predicate
- or else A_Id = Aspect_Priority
- or else A_Id = Aspect_CPU
+ if Get_Aspect_Id (Ritem) in Aspect_CPU
+ | Aspect_Dynamic_Predicate
+ | Aspect_Predicate
+ | Aspect_Priority
then
-- Retrieve the visibility to components and discriminants
-- in order to properly analyze the aspects.
@@ -13463,31 +13492,23 @@ package body Sem_Ch13 is
function Is_Operational_Item (N : Node_Id) return Boolean is
begin
- if Nkind (N) /= N_Attribute_Definition_Clause then
- return False;
-
- else
- declare
- Id : constant Attribute_Id := Get_Attribute_Id (Chars (N));
- begin
-
- -- List of operational items is given in AARM 13.1(8.mm/1).
- -- It is clearly incomplete, as it does not include iterator
- -- aspects, among others.
-
- return Id = Attribute_Constant_Indexing
- or else Id = Attribute_Default_Iterator
- or else Id = Attribute_Implicit_Dereference
- or else Id = Attribute_Input
- or else Id = Attribute_Iterator_Element
- or else Id = Attribute_Iterable
- or else Id = Attribute_Output
- or else Id = Attribute_Read
- or else Id = Attribute_Variable_Indexing
- or else Id = Attribute_Write
- or else Id = Attribute_External_Tag;
- end;
- end if;
+ -- List of operational items is given in AARM 13.1(8.mm/1). It is
+ -- clearly incomplete, as it does not include iterator aspects, among
+ -- others.
+
+ return Nkind (N) = N_Attribute_Definition_Clause
+ and then
+ Get_Attribute_Id (Chars (N)) in Attribute_Constant_Indexing
+ | Attribute_External_Tag
+ | Attribute_Default_Iterator
+ | Attribute_Implicit_Dereference
+ | Attribute_Input
+ | Attribute_Iterable
+ | Attribute_Iterator_Element
+ | Attribute_Output
+ | Attribute_Read
+ | Attribute_Variable_Indexing
+ | Attribute_Write;
end Is_Operational_Item;
-------------------------
@@ -13695,17 +13716,13 @@ package body Sem_Ch13 is
begin
case Nkind (N) is
when N_Attribute_Definition_Clause =>
- declare
- Id : constant Attribute_Id := Get_Attribute_Id (Chars (N));
- -- See AARM 13.1(8.f-8.x) list items that end in "clause"
- -- ???: include any GNAT-defined attributes here?
- begin
- return Id = Attribute_Component_Size
- or else Id = Attribute_Bit_Order
- or else Id = Attribute_Storage_Pool
- or else Id = Attribute_Stream_Size
- or else Id = Attribute_Machine_Radix;
- end;
+ -- See AARM 13.1(8.f-8.x) list items that end in "clause"
+ -- ???: include any GNAT-defined attributes here?
+ return Get_Attribute_Id (Chars (N)) in Attribute_Bit_Order
+ | Attribute_Component_Size
+ | Attribute_Machine_Radix
+ | Attribute_Storage_Pool
+ | Attribute_Stream_Size;
when N_Pragma =>
case Get_Pragma_Id (N) is
@@ -14920,6 +14937,10 @@ package body Sem_Ch13 is
when Aspect_Aggregate =>
Resolve_Aspect_Aggregate (Entity (ASN), Expr);
+ when Aspect_Stable_Properties =>
+ Resolve_Aspect_Stable_Properties
+ (Entity (ASN), Expr, Class_Present (ASN));
+
-- For now we only deal with aspects that do not generate
-- subprograms, or that may mention current instances of
-- types. These will require special handling (???TBD).
@@ -15058,6 +15079,60 @@ package body Sem_Ch13 is
end loop;
end Parse_Aspect_Aggregate;
+ ------------------------------------
+ -- Parse_Aspect_Stable_Properties --
+ ------------------------------------
+
+ function Parse_Aspect_Stable_Properties
+ (Aspect_Spec : Node_Id; Negated : out Boolean) return Subprogram_List
+ is
+ L : List_Id;
+ Id : Node_Id;
+
+ function Extract_Entity (Expr : Node_Id) return Entity_Id;
+ -- Given an element of a Stable_Properties aspect spec,
+ -- return the associated entity.
+ -- This function updates the Negated flag as a side-effect.
+
+ function Extract_Entity (Expr : Node_Id) return Entity_Id is
+ Name : Node_Id := Expr;
+ begin
+ if Nkind (Expr) = N_Op_Not then
+ Negated := True;
+ Name := Right_Opnd (Expr);
+ end if;
+ if Nkind (Name) in N_Has_Entity then
+ return Entity (Name);
+ else
+ return Empty;
+ end if;
+ end Extract_Entity;
+ begin
+ Negated := False;
+
+ if Nkind (Aspect_Spec) /= N_Aggregate then
+ return (1 => Extract_Entity (Aspect_Spec));
+ else
+ L := Expressions (Aspect_Spec);
+ Id := First (L);
+
+ return Result : Subprogram_List (1 .. List_Length (L)) do
+ for I in Result'Range loop
+ Result (I) := Extract_Entity (Id);
+
+ if not Present (Result (I)) then
+ pragma Assert (Serious_Errors_Detected > 0);
+ goto Ignore_Aspect;
+ end if;
+
+ Next (Id);
+ end loop;
+ end return;
+ end if;
+
+ <<Ignore_Aspect>> return (1 .. 0 => <>);
+ end Parse_Aspect_Stable_Properties;
+
-------------------------------
-- Validate_Aspect_Aggregate --
-------------------------------
@@ -15104,6 +15179,135 @@ package body Sem_Ch13 is
end if;
end Validate_Aspect_Aggregate;
+ -------------------------------
+ -- Validate_Aspect_Stable_Properties --
+ -------------------------------
+
+ procedure Validate_Aspect_Stable_Properties
+ (E : Entity_Id; N : Node_Id; Class_Present : Boolean)
+ is
+ Is_Aspect_Of_Type : constant Boolean := Is_Type (E);
+
+ type Permission is (Forbidden, Optional, Required);
+ Modifier_Permission : Permission :=
+ (if Is_Aspect_Of_Type then Forbidden else Optional);
+ Modifier_Error_Called : Boolean := False;
+
+ procedure Check_Property_Function_Arg (PF_Arg : Node_Id);
+ -- Check syntax of a property function argument
+
+ ----------------------------------
+ -- Check_Property_Function_Arg --
+ ----------------------------------
+
+ procedure Check_Property_Function_Arg (PF_Arg : Node_Id) is
+ procedure Modifier_Error;
+ -- Generate message about bad "not" modifier if no message already
+ -- generated. Errors include specifying "not" for an aspect of
+ -- of a type and specifying "not" for some but not all of the
+ -- names in a list.
+
+ --------------------
+ -- Modifier_Error --
+ --------------------
+
+ procedure Modifier_Error is
+ begin
+ if Modifier_Error_Called then
+ return; -- error message already generated
+ end if;
+
+ Modifier_Error_Called := True;
+
+ if Is_Aspect_Of_Type then
+ Error_Msg_N
+ ("NOT modifier not allowed for Stable_Properties aspect"
+ & " of a type", PF_Arg);
+ else
+ Error_Msg_N ("Mixed use of NOT modifiers", PF_Arg);
+ end if;
+ end Modifier_Error;
+
+ PF_Name : Node_Id := PF_Arg;
+
+ -- Start of processing for Check_Property_Function_Arg
+ begin
+ if Nkind (PF_Arg) = N_Op_Not then
+ PF_Name := Right_Opnd (PF_Arg);
+
+ case Modifier_Permission is
+ when Forbidden =>
+ Modifier_Error;
+ when Optional =>
+ Modifier_Permission := Required;
+ when Required =>
+ null;
+ end case;
+ else
+ case Modifier_Permission is
+ when Forbidden =>
+ null;
+ when Optional =>
+ Modifier_Permission := Forbidden;
+ when Required =>
+ Modifier_Error;
+ end case;
+ end if;
+
+ if Nkind (PF_Name) not in
+ N_Identifier | N_Operator_Symbol | N_Selected_Component
+ then
+ Error_Msg_N ("Bad property function name", PF_Name);
+ end if;
+ end Check_Property_Function_Arg;
+
+ begin
+ if Ada_Version < Ada_2020 then
+ Error_Msg_N ("Aspect Stable_Properties is an Ada_2020 feature", N);
+ end if;
+
+ if (not Is_Aspect_Of_Type) and then (not Is_Subprogram (E)) then
+ Error_Msg_N ("Stable_Properties aspect can only be specified for "
+ & "a type or a subprogram", N);
+ elsif Class_Present then
+ if Is_Aspect_Of_Type then
+ if not Is_Tagged_Type (E) then
+ Error_Msg_N
+ ("Stable_Properties'Class aspect cannot be specified for "
+ & "an untagged type", N);
+ end if;
+ else
+ if not Is_Dispatching_Operation (E) then
+ Error_Msg_N
+ ("Stable_Properties'Class aspect cannot be specified for "
+ & "a subprogram that is not a primitive subprogram "
+ & "of a tagged type", N);
+ end if;
+ end if;
+ end if;
+
+ if Nkind (N) = N_Aggregate then
+ if Present (Component_Associations (N))
+ or else Null_Record_Present (N)
+ or else not Present (Expressions (N))
+ then
+ Error_Msg_N ("Bad Stable_Properties aspect specification", N);
+ return;
+ end if;
+
+ declare
+ PF_Arg : Node_Id := First (Expressions (N));
+ begin
+ while Present (PF_Arg) loop
+ Check_Property_Function_Arg (PF_Arg);
+ PF_Arg := Next (PF_Arg);
+ end loop;
+ end;
+ else
+ Check_Property_Function_Arg (N);
+ end if;
+ end Validate_Aspect_Stable_Properties;
+
--------------------------------
-- Resolve_Iterable_Operation --
--------------------------------
@@ -15135,7 +15339,7 @@ package body Sem_Ch13 is
Ent := Entity (N);
F1 := First_Formal (Ent);
- if Nam = Name_First or else Nam = Name_Last then
+ if Nam in Name_First | Name_Last then
-- First or Last (Container) => Cursor
@@ -15463,6 +15667,224 @@ package body Sem_Ch13 is
end loop;
end Resolve_Aspect_Aggregate;
+ --------------------------------------
+ -- Resolve_Aspect_Stable_Properties --
+ --------------------------------------
+
+ procedure Resolve_Aspect_Stable_Properties
+ (Typ_Or_Subp : Entity_Id; Expr : Node_Id; Class_Present : Boolean)
+ is
+ Is_Aspect_Of_Type : constant Boolean := Is_Type (Typ_Or_Subp);
+
+ Singleton : constant Boolean := Nkind (Expr) /= N_Aggregate;
+ Subp_Name : Node_Id := (if Singleton
+ then Expr
+ else First (Expressions (Expr)));
+ Has_Not : Boolean;
+ begin
+ if Is_Aspect_Of_Type
+ and then Has_Private_Declaration (Typ_Or_Subp)
+ and then not Is_Private_Type (Typ_Or_Subp)
+ then
+ Error_Msg_N
+ ("Stable_Properties aspect cannot be specified " &
+ "for the completion of a private type", Typ_Or_Subp);
+ end if;
+
+ -- Analogous checks that the aspect is not specified for a completion
+ -- in the subprogram case are not performed here because they are not
+ -- specific to this particular aspect. Right ???
+
+ loop
+ Has_Not := Nkind (Subp_Name) = N_Op_Not;
+ if Has_Not then
+ Set_Analyzed (Subp_Name); -- ???
+ Subp_Name := Right_Opnd (Subp_Name);
+ end if;
+
+ if No (Etype (Subp_Name)) then
+ Analyze (Subp_Name);
+ end if;
+
+ declare
+ Subp : Entity_Id := Empty;
+
+ I : Interp_Index;
+ It : Interp;
+
+ function Is_Property_Function (E : Entity_Id) return Boolean;
+ -- Implements RM 7.3.4 definition of "property function".
+
+ function Is_Property_Function (E : Entity_Id) return Boolean is
+ begin
+ if Ekind (E) not in E_Function | E_Operator
+ or else Number_Formals (E) /= 1
+ then
+ return False;
+ end if;
+
+ declare
+ Param_Type : constant Entity_Id :=
+ Base_Type (Etype (First_Formal (E)));
+
+ function Matches_Param_Type (Typ : Entity_Id)
+ return Boolean is
+ ((Base_Type (Typ) = Param_Type)
+ or else
+ (Is_Class_Wide_Type (Param_Type)
+ and then Is_Ancestor (Root_Type (Param_Type),
+ Base_Type (Typ))));
+ begin
+ if Is_Aspect_Of_Type then
+ if Matches_Param_Type (Typ_Or_Subp) then
+ return True;
+ end if;
+ elsif Is_Primitive (Typ_Or_Subp) then
+ declare
+ Formal : Entity_Id := First_Formal (Typ_Or_Subp);
+ begin
+ while Present (Formal) loop
+ if Matches_Param_Type (Etype (Formal)) then
+
+ -- Test whether Typ_Or_Subp (which is a subp
+ -- in this case) is primitive op of the type
+ -- of this parameter.
+ if Scope (Typ_Or_Subp) = Scope (Param_Type) then
+ return True;
+ end if;
+ end if;
+ Next_Formal (Formal);
+ end loop;
+ end;
+ end if;
+ end;
+
+ return False;
+ end Is_Property_Function;
+ begin
+ if not Is_Overloaded (Subp_Name) then
+ Subp := Entity (Subp_Name);
+ if not Is_Property_Function (Subp) then
+ Error_Msg_NE ("improper property function for&",
+ Subp_Name, Typ_Or_Subp);
+ return;
+ end if;
+ else
+ Set_Entity (Subp_Name, Empty);
+ Get_First_Interp (Subp_Name, I, It);
+ while Present (It.Nam) loop
+ if Is_Property_Function (It.Nam) then
+ if Present (Subp) then
+ Error_Msg_NE
+ ("ambiguous property function name for&",
+ Subp_Name, Typ_Or_Subp);
+ return;
+ end if;
+
+ Subp := It.Nam;
+ Set_Is_Overloaded (Subp_Name, False);
+ Set_Entity (Subp_Name, Subp);
+ end if;
+
+ Get_Next_Interp (I, It);
+ end loop;
+
+ if No (Subp) then
+ Error_Msg_NE ("improper property function for&",
+ Subp_Name, Typ_Or_Subp);
+ return;
+ end if;
+ end if;
+
+ -- perform legality (as opposed to name resolution) Subp checks
+
+ if Is_Limited_Type (Etype (Subp)) then
+ Error_Msg_NE
+ ("result type of property function for& is limited",
+ Subp_Name, Typ_Or_Subp);
+ end if;
+
+ if Ekind (First_Formal (Subp)) /= E_In_Parameter then
+ Error_Msg_NE
+ ("mode of parameter of property function for& is not IN",
+ Subp_Name, Typ_Or_Subp);
+ end if;
+
+ if Is_Class_Wide_Type (Etype (First_Formal (Subp))) then
+ if not Covers (Etype (First_Formal (Subp)), Typ_Or_Subp) then
+ Error_Msg_NE
+ ("class-wide parameter type of property function " &
+ "for& does not cover the type",
+ Subp_Name, Typ_Or_Subp);
+
+ -- ??? This test is slightly stricter than 7.3.4(12/5);
+ -- some legal corner cases may be incorrectly rejected.
+ elsif Scope (Subp) /= Scope (Etype (First_Formal (Subp)))
+ then
+ Error_Msg_NE
+ ("property function for& not declared in same scope " &
+ "as parameter type",
+ Subp_Name, Typ_Or_Subp);
+ end if;
+ elsif Is_Aspect_Of_Type and then
+ Scope (Subp) /= Scope (Typ_Or_Subp) and then
+ Scope (Subp) /= Standard_Standard -- e.g., derived type's "abs"
+ then
+ Error_Msg_NE
+ ("property function for& " &
+ "not a primitive function of the type",
+ Subp_Name, Typ_Or_Subp);
+ end if;
+
+ if Has_Not then
+ -- check that Subp was mentioned in param type's aspect spec
+ declare
+ Param_Type : constant Entity_Id :=
+ Base_Type (Etype (First_Formal (Subp)));
+ Aspect_Spec : constant Node_Id :=
+ Find_Value_Of_Aspect
+ (Param_Type, Aspect_Stable_Properties,
+ Class_Present => Class_Present);
+ Found : Boolean := False;
+ begin
+ if Present (Aspect_Spec) then
+ declare
+ Ignored : Boolean;
+ SPF_List : constant Subprogram_List :=
+ Parse_Aspect_Stable_Properties
+ (Aspect_Spec, Negated => Ignored);
+ begin
+ Found := (for some E of SPF_List => E = Subp);
+ -- look through renamings ???
+ end;
+ end if;
+ if not Found then
+ declare
+ CW_Modifier : constant String :=
+ (if Class_Present then "class-wide " else "");
+ begin
+ Error_Msg_NE
+ (CW_Modifier
+ & "property function for& mentioned after NOT "
+ & "but not a "
+ & CW_Modifier
+ & "stable property function of its parameter type",
+ Subp_Name, Typ_Or_Subp);
+ end;
+ end if;
+ end;
+ end if;
+ end;
+
+ exit when Singleton;
+ Subp_Name :=
+ Next ((if Has_Not then Parent (Subp_Name) else Subp_Name));
+ exit when No (Subp_Name);
+ end loop;
+
+ Set_Analyzed (Expr);
+ end Resolve_Aspect_Stable_Properties;
+
----------------
-- Set_Biased --
----------------
@@ -16026,7 +16448,7 @@ package body Sem_Ch13 is
-- Deal with component case
- if Ekind (E) = E_Discriminant or else Ekind (E) = E_Component then
+ if Ekind (E) in E_Component | E_Discriminant then
if not OK_Component (E) then
No_Independence;
Reason_Bad_Component (E);
@@ -16177,12 +16599,31 @@ package body Sem_Ch13 is
Func_Name : constant Node_Id := Expression (ASN);
Overloaded : Boolean := Is_Overloaded (Func_Name);
- I : Interp_Index;
- It : Interp;
- Param_Type : Entity_Id;
- Match_Found : Boolean := False;
- Is_Match : Boolean;
- Match : Interp;
+ I : Interp_Index;
+ It : Interp;
+ Param_Type : Entity_Id;
+ Match_Found : Boolean := False;
+ Match2_Found : Boolean := False;
+ Is_Match : Boolean;
+ Match : Interp;
+ Match2 : Entity_Id := Empty;
+
+ function Matching
+ (Param_Id : Entity_Id; Param_Type : Entity_Id) return Boolean;
+ -- Return True if Param_Id is a non aliased in parameter whose base type
+ -- is Param_Type.
+
+ --------------
+ -- Matching --
+ --------------
+
+ function Matching
+ (Param_Id : Entity_Id; Param_Type : Entity_Id) return Boolean is
+ begin
+ return Base_Type (Etype (Param_Id)) = Param_Type
+ and then Ekind (Param_Id) = E_In_Parameter
+ and then not Is_Aliased (Param_Id);
+ end Matching;
begin
if not Is_Type (Typ) then
@@ -16228,26 +16669,45 @@ package body Sem_Ch13 is
Is_Match := False;
if Ekind (It.Nam) = E_Function
- and then Base_Type (Etype (It.Nam)) = Typ
+ and then Base_Type (Etype (It.Nam)) = Base_Type (Typ)
then
declare
Params : constant List_Id :=
Parameter_Specifications (Parent (It.Nam));
Param_Spec : Node_Id;
- Param_Id : Entity_Id;
begin
if List_Length (Params) = 1 then
Param_Spec := First (Params);
+ Is_Match :=
+ Matching (Defining_Identifier (Param_Spec), Param_Type);
+
+ -- Look for the optional overloaded 2-param Real_Literal
+
+ elsif List_Length (Params) = 2
+ and then A_Id = Aspect_Real_Literal
+ then
+ Param_Spec := First (Params);
- if not More_Ids (Param_Spec) then
- Param_Id := Defining_Identifier (Param_Spec);
+ if Matching (Defining_Identifier (Param_Spec), Param_Type)
+ then
+ Param_Spec := Next (Param_Spec);
- if Base_Type (Etype (Param_Id)) = Param_Type
- and then Ekind (Param_Id) = E_In_Parameter
- and then not Is_Aliased (Param_Id)
+ if Matching (Defining_Identifier (Param_Spec), Param_Type)
then
- Is_Match := True;
+ if No (Match2) then
+ Match2 := It.Nam;
+ Match2_Found := True;
+ else
+ -- If we find more than one possible match then
+ -- do not take any into account here: since the
+ -- 2-parameter version of Real_Literal is optional
+ -- we cannot generate an error here, so let
+ -- standard resolution fail later if we do need to
+ -- call this variant.
+
+ Match2_Found := False;
+ end if;
end if;
end if;
end if;
@@ -16282,6 +16742,12 @@ package body Sem_Ch13 is
Set_Entity (Func_Name, Match.Nam);
Set_Etype (Func_Name, Etype (Match.Nam));
Set_Is_Overloaded (Func_Name, False);
+
+ -- Record the match for 2-parameter function if found
+
+ if Match2_Found then
+ Set_Related_Expression (Match.Nam, Match2);
+ end if;
end Validate_Literal_Aspect;
-----------------------------------
diff --git a/gcc/ada/sem_ch13.ads b/gcc/ada/sem_ch13.ads
index 7d9f38d..389bb41 100644
--- a/gcc/ada/sem_ch13.ads
+++ b/gcc/ada/sem_ch13.ads
@@ -25,6 +25,7 @@
with Table;
with Types; use Types;
+with Sem_Disp; use Sem_Disp;
with Uintp; use Uintp;
package Sem_Ch13 is
@@ -147,6 +148,11 @@ package Sem_Ch13 is
-- used to verify the structure of the aspect, and resolve and expand an
-- aggregate for a container type that carries the aspect.
+ function Parse_Aspect_Stable_Properties
+ (Aspect_Spec : Node_Id; Negated : out Boolean) return Subprogram_List;
+ -- Utility to unpack the subprograms in a Stable_Properties list;
+ -- in the case of the aspect of a type, Negated will always be False.
+
function Rep_Item_Too_Early (T : Entity_Id; N : Node_Id) return Boolean;
-- Called at start of processing a representation clause/pragma. Used to
-- check that the representation item is not being applied to an incomplete
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index 269818a..00834ce 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -1411,6 +1411,8 @@ package body Sem_Ch3 is
Set_Is_Tagged_Type (T, False);
end if;
+ Set_Etype (T, T);
+
-- For SPARK, check that the designated type is compatible with
-- respect to volatility with the access type.
@@ -1431,8 +1433,6 @@ package body Sem_Ch3 is
Srcpos_Bearer => T);
end if;
- Set_Etype (T, T);
-
-- If the type has appeared already in a with_type clause, it is frozen
-- and the pointer size is already set. Else, initialize.
@@ -2312,13 +2312,6 @@ package body Sem_Ch3 is
procedure Build_Assertion_Bodies_For_Type (Typ : Entity_Id) is
begin
- -- Preanalyze and resolve the Default_Initial_Condition assertion
- -- expression at the end of the declarations to catch any errors.
-
- if Has_DIC (Typ) then
- Build_DIC_Procedure_Body (Typ);
- end if;
-
if Nkind (Context) = N_Package_Specification then
-- Preanalyze and resolve the class-wide invariants of an
@@ -2341,32 +2334,57 @@ package body Sem_Ch3 is
Partial_Invariant => True);
end if;
- -- Preanalyze and resolve the invariants of a private type
- -- at the end of the visible declarations to catch potential
- -- errors. Inherited class-wide invariants are not included
- -- because they have already been resolved.
+ elsif Decls = Visible_Declarations (Context) then
+ -- Preanalyze and resolve the invariants of a private type
+ -- at the end of the visible declarations to catch potential
+ -- errors. Inherited class-wide invariants are not included
+ -- because they have already been resolved.
- elsif Decls = Visible_Declarations (Context)
- and then Ekind (Typ) in E_Limited_Private_Type
- | E_Private_Type
- | E_Record_Type_With_Private
- and then Has_Own_Invariants (Typ)
- then
- Build_Invariant_Procedure_Body
- (Typ => Typ,
- Partial_Invariant => True);
-
- -- Preanalyze and resolve the invariants of a private type's
- -- full view at the end of the private declarations to catch
- -- potential errors.
-
- elsif Decls = Private_Declarations (Context)
- and then (not Is_Private_Type (Typ)
- or else Present (Underlying_Full_View (Typ)))
- and then Has_Private_Declaration (Typ)
- and then Has_Invariants (Typ)
- then
- Build_Invariant_Procedure_Body (Typ);
+ if Ekind (Typ) in E_Limited_Private_Type
+ | E_Private_Type
+ | E_Record_Type_With_Private
+ and then Has_Own_Invariants (Typ)
+ then
+ Build_Invariant_Procedure_Body
+ (Typ => Typ,
+ Partial_Invariant => True);
+ end if;
+
+ -- Preanalyze and resolve the Default_Initial_Condition
+ -- assertion expression at the end of the declarations to
+ -- catch any errors.
+
+ if Ekind (Typ) in E_Limited_Private_Type
+ | E_Private_Type
+ | E_Record_Type_With_Private
+ and then Has_Own_DIC (Typ)
+ then
+ Build_DIC_Procedure_Body
+ (Typ => Typ,
+ Partial_DIC => True);
+ end if;
+
+ elsif Decls = Private_Declarations (Context) then
+
+ -- Preanalyze and resolve the invariants of a private type's
+ -- full view at the end of the private declarations to catch
+ -- potential errors.
+
+ if (not Is_Private_Type (Typ)
+ or else Present (Underlying_Full_View (Typ)))
+ and then Has_Private_Declaration (Typ)
+ and then Has_Invariants (Typ)
+ then
+ Build_Invariant_Procedure_Body (Typ);
+ end if;
+
+ if (not Is_Private_Type (Typ)
+ or else Present (Underlying_Full_View (Typ)))
+ and then Has_Private_Declaration (Typ)
+ and then Has_DIC (Typ)
+ then
+ Build_DIC_Procedure_Body (Typ);
+ end if;
end if;
end if;
end Build_Assertion_Bodies_For_Type;
@@ -14945,6 +14963,10 @@ package body Sem_Ch3 is
Loc : constant Source_Ptr := Sloc (Def);
Digs_Expr : constant Node_Id := Digits_Expression (Def);
Delta_Expr : constant Node_Id := Delta_Expression (Def);
+ Max_Digits : constant Nat :=
+ (if System_Max_Integer_Size = 128 then 38 else 18);
+ -- Maximum number of digits that can be represented in an integer
+
Implicit_Base : Entity_Id;
Digs_Val : Uint;
Delta_Val : Ureal;
@@ -14982,9 +15004,10 @@ package body Sem_Ch3 is
Scale_Val := Scale_Val + 1;
end loop;
- if Scale_Val > 18 then
- Error_Msg_N ("scale exceeds maximum value of 18", Def);
- Scale_Val := UI_From_Int (+18);
+ if Scale_Val > Max_Digits then
+ Error_Msg_Uint_1 := UI_From_Int (Max_Digits);
+ Error_Msg_N ("scale exceeds maximum value of ^", Def);
+ Scale_Val := UI_From_Int (Max_Digits);
end if;
else
@@ -14993,9 +15016,10 @@ package body Sem_Ch3 is
Scale_Val := Scale_Val - 1;
end loop;
- if Scale_Val < -18 then
- Error_Msg_N ("scale is less than minimum value of -18", Def);
- Scale_Val := UI_From_Int (-18);
+ if Scale_Val < -Max_Digits then
+ Error_Msg_Uint_1 := UI_From_Int (-Max_Digits);
+ Error_Msg_N ("scale is less than minimum value of ^", Def);
+ Scale_Val := UI_From_Int (-Max_Digits);
end if;
end if;
@@ -15017,9 +15041,10 @@ package body Sem_Ch3 is
Check_Digits_Expression (Digs_Expr);
Digs_Val := Expr_Value (Digs_Expr);
- if Digs_Val > 18 then
- Digs_Val := UI_From_Int (+18);
- Error_Msg_N ("digits value out of range, maximum is 18", Digs_Expr);
+ if Digs_Val > Max_Digits then
+ Error_Msg_Uint_1 := UI_From_Int (Max_Digits);
+ Error_Msg_N ("digits value out of range, maximum is ^", Digs_Expr);
+ Digs_Val := UI_From_Int (Max_Digits);
end if;
Set_Digits_Value (Implicit_Base, Digs_Val);
@@ -20093,7 +20118,7 @@ package body Sem_Ch3 is
-- Per-Object Expressions" in spec of package Sem).
if Present (Expression (Discr)) then
- Preanalyze_Spec_Expression (Expression (Discr), Discr_Type);
+ Preanalyze_Default_Expression (Expression (Discr), Discr_Type);
-- Legaity checks
diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index d06a4a8..7b358d4 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -3414,7 +3414,7 @@ package body Sem_Ch4 is
Success := True;
-- If the prefix of the call is a name, indicate the entity
- -- being called. If it is not a name, it is an expression that
+ -- being called. If it is not a name, it is an expression that
-- denotes an access to subprogram or else an entry or family. In
-- the latter case, the name is a selected component, and the entity
-- being called is noted on the selector.
diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
index 2afe18b..b136356 100644
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -192,9 +192,7 @@ package body Sem_Ch5 is
-- directly.
elsif (Is_Prival (Ent) and then Within_Function)
- or else
- (Ekind (Ent) = E_Component
- and then Is_Protected_Type (Scope (Ent)))
+ or else Is_Protected_Component (Ent)
then
Error_Msg_N
("protected function cannot modify protected object", N);
@@ -305,9 +303,9 @@ package body Sem_Ch5 is
-- also have an actual subtype.
if Is_Entity_Name (Opnd)
- and then (Ekind (Entity (Opnd)) = E_Out_Parameter
- or else Ekind (Entity (Opnd)) in
- E_In_Out_Parameter | E_Generic_In_Out_Parameter
+ and then (Ekind (Entity (Opnd)) in E_Out_Parameter
+ | E_In_Out_Parameter
+ | E_Generic_In_Out_Parameter
or else
(Ekind (Entity (Opnd)) = E_Variable
and then Nkind (Parent (Entity (Opnd))) =
@@ -351,8 +349,6 @@ package body Sem_Ch5 is
function Should_Transform_BIP_Assignment
(Typ : Entity_Id) return Boolean
is
- Result : Boolean;
-
begin
if Expander_Active
and then not Is_Limited_View (Typ)
@@ -366,37 +362,33 @@ package body Sem_Ch5 is
-- parameterless function call if it denotes a function.
-- Finally, an attribute reference can be a function call.
- case Nkind (Unqual_Conv (Rhs)) is
- when N_Function_Call
- | N_Op
- =>
- Result := True;
-
- when N_Expanded_Name
- | N_Identifier
- =>
- case Ekind (Entity (Unqual_Conv (Rhs))) is
- when E_Function
- | E_Operator
- =>
- Result := True;
-
- when others =>
- Result := False;
- end case;
-
- when N_Attribute_Reference =>
- Result := Attribute_Name (Unqual_Conv (Rhs)) = Name_Input;
+ declare
+ Unqual_Rhs : constant Node_Id := Unqual_Conv (Rhs);
+ begin
+ case Nkind (Unqual_Rhs) is
+ when N_Function_Call
+ | N_Op
+ =>
+ return True;
+
+ when N_Expanded_Name
+ | N_Identifier
+ =>
+ return
+ Ekind (Entity (Unqual_Rhs)) in E_Function | E_Operator;
+
-- T'Input will turn into a call whose result type is T
- when others =>
- Result := False;
- end case;
+ when N_Attribute_Reference =>
+ return Attribute_Name (Unqual_Rhs) = Name_Input;
+
+ when others =>
+ return False;
+ end case;
+ end;
else
- Result := False;
+ return False;
end if;
-
- return Result;
end Should_Transform_BIP_Assignment;
------------------------------
@@ -1474,8 +1466,7 @@ package body Sem_Ch5 is
if Is_Entity_Name (Exp) then
Ent := Entity (Exp);
- if Ekind (Ent) in E_Variable | E_In_Out_Parameter | E_Out_Parameter
- then
+ if Is_Assignable (Ent) then
if List_Length (Choices) = 1
and then Nkind (First (Choices)) in N_Subexpr
and then Compile_Time_Known_Value (First (Choices))
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index c476e45..35e13a5 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -784,13 +784,49 @@ package body Sem_Ch6 is
------------------------------------------
procedure Check_Return_Construct_Accessibility (Return_Stmt : Node_Id) is
- Return_Con : Node_Id;
- Assoc : Node_Id := Empty;
- Assoc_Expr : Node_Id;
- Disc : Entity_Id;
+
+ function First_Selector (Assoc : Node_Id) return Node_Id;
+ -- Obtain the first selector or choice from a given association
+
+ --------------------
+ -- First_Selector --
+ --------------------
+
+ function First_Selector (Assoc : Node_Id) return Node_Id is
+ begin
+ if Nkind (Assoc) = N_Component_Association then
+ return First (Choices (Assoc));
+
+ elsif Nkind (Assoc) = N_Discriminant_Association then
+ return (First (Selector_Names (Assoc)));
+
+ else
+ raise Program_Error;
+ end if;
+ end First_Selector;
+
+ -- Local declarations
+
+ Assoc : Node_Id := Empty;
+ -- Assoc should perhaps be renamed and declared as a
+ -- Node_Or_Entity_Id since it encompasses not only component and
+ -- discriminant associations, but also discriminant components within
+ -- a type declaration or subtype indication ???
+
+ Assoc_Expr : Node_Id;
+ Assoc_Present : Boolean := False;
+
+ Unseen_Disc_Count : Nat := 0;
+ Seen_Discs : Elist_Id;
+ Disc : Entity_Id;
+ First_Disc : Entity_Id;
+
Obj_Decl : Node_Id;
+ Return_Con : Node_Id;
Unqual : Node_Id;
+ -- Start of processing for Check_Return_Construct_Accessibility
+
begin
-- Only perform checks on record types with access discriminants and
-- non-internally generated functions.
@@ -845,7 +881,7 @@ package body Sem_Ch6 is
Unqual := Unqualify (Original_Node (Return_Con));
- -- Obtain the corresponding declaration based on the return object's
+ -- Get the corresponding declaration based on the return object's
-- identifier.
if Nkind (Unqual) = N_Identifier
@@ -982,30 +1018,175 @@ package body Sem_Ch6 is
(Etype (Defining_Identifier (Obj_Decl)));
end if;
+ -- Preserve the first discriminant for checking named associations
+
+ First_Disc := Disc;
+
+ -- Count the number of discriminants for processing an aggregate
+ -- which includes an others.
+
+ Disc := First_Disc;
+ while Present (Disc) loop
+ Unseen_Disc_Count := Unseen_Disc_Count + 1;
+
+ Next_Discriminant (Disc);
+ end loop;
+
+ Seen_Discs := New_Elmt_List;
+
-- Loop through each of the discriminants and check each expression
-- associated with an anonymous access discriminant.
- while Present (Assoc) and then Present (Disc) loop
- -- Unwrap the associated expression
+ -- When named associations occur in the return aggregate then
+ -- discriminants can be in any order, so we need to ensure we do
+ -- not continue to loop when all discriminants have been seen.
+
+ Disc := First_Disc;
+ while Present (Assoc)
+ and then (Present (Disc) or else Assoc_Present)
+ and then Unseen_Disc_Count > 0
+ loop
+ -- Handle named associations by searching through the names of
+ -- the relevant discriminant components.
if Nkind (Assoc)
in N_Component_Association | N_Discriminant_Association
then
- Assoc_Expr := Expression (Assoc);
+ Assoc_Expr := Expression (Assoc);
+ Assoc_Present := True;
+
+ -- We currently don't handle box initialized discriminants,
+ -- however, since default initialized anonymous access
+ -- discriminants are a corner case, this is ok for now ???
+
+ if Nkind (Assoc) = N_Component_Association
+ and then Box_Present (Assoc)
+ then
+ Assoc_Present := False;
+
+ if Nkind (First_Selector (Assoc)) = N_Others_Choice then
+ Unseen_Disc_Count := 0;
+ end if;
+
+ -- When others is present we must identify a discriminant we
+ -- haven't already seen so as to get the appropriate type for
+ -- the static accessibility check.
+
+ -- This works because all components within an others clause
+ -- must have the same type.
+
+ elsif Nkind (First_Selector (Assoc)) = N_Others_Choice then
+
+ Disc := First_Disc;
+ Outer : while Present (Disc) loop
+ declare
+ Current_Seen_Disc : Elmt_Id;
+ begin
+ -- Move through the list of identified discriminants
+
+ Current_Seen_Disc := First_Elmt (Seen_Discs);
+ while Present (Current_Seen_Disc) loop
+ -- Exit the loop when we found a match
+
+ exit when
+ Chars (Node (Current_Seen_Disc)) = Chars (Disc);
+
+ Next_Elmt (Current_Seen_Disc);
+ end loop;
+
+ -- When we have exited the above loop without finding
+ -- a match then we know that Disc has not been seen.
+
+ exit Outer when No (Current_Seen_Disc);
+ end;
+
+ Next_Discriminant (Disc);
+ end loop Outer;
+
+ -- If we got to an others clause with a non-zero
+ -- discriminant count there must be a discriminant left to
+ -- check.
+
+ pragma Assert (Present (Disc));
+
+ -- Set the unseen discriminant count to zero because we know
+ -- an others clause sets all remaining components of an
+ -- aggregate.
+
+ Unseen_Disc_Count := 0;
+
+ -- Move through each of the selectors in the named association
+ -- and obtain a discriminant for accessibility checking if one
+ -- is referenced in the list. Also track which discriminants
+ -- are referenced for the purpose of handling an others clause.
+
+ else
+ declare
+ Assoc_Choice : Node_Id;
+ Curr_Disc : Node_Id;
+ begin
+
+ Disc := Empty;
+ Curr_Disc := First_Disc;
+ while Present (Curr_Disc) loop
+ -- Check each of the choices in the associations for a
+ -- match to the name of the current discriminant.
+
+ Assoc_Choice := First_Selector (Assoc);
+ while Present (Assoc_Choice) loop
+ -- When the name matches we track that we have seen
+ -- the discriminant, but instead of exiting the
+ -- loop we continue iterating to make sure all the
+ -- discriminants within the named association get
+ -- tracked.
+
+ if Chars (Assoc_Choice) = Chars (Curr_Disc) then
+ Append_Elmt (Curr_Disc, Seen_Discs);
+
+ Disc := Curr_Disc;
+ Unseen_Disc_Count := Unseen_Disc_Count - 1;
+ end if;
+
+ Next (Assoc_Choice);
+ end loop;
+
+ Next_Discriminant (Curr_Disc);
+ end loop;
+ end;
+ end if;
+
+ -- Unwrap the associated expression if we are looking at a default
+ -- initialized type declaration. In this case Assoc is not really
+ -- an association, but a component declaration. Should Assoc be
+ -- renamed in some way to be more clear ???
+
+ -- This occurs when the return object does not initialize
+ -- discriminant and instead relies on the type declaration for
+ -- their supplied values.
elsif Nkind (Assoc) in N_Entity
and then Ekind (Assoc) = E_Discriminant
then
- Assoc_Expr := Discriminant_Default_Value (Assoc);
+ Append_Elmt (Disc, Seen_Discs);
+
+ Assoc_Expr := Discriminant_Default_Value (Assoc);
+ Unseen_Disc_Count := Unseen_Disc_Count - 1;
+
+ -- Otherwise, there is nothing to do because Assoc is an
+ -- expression within the return aggregate itself.
else
- Assoc_Expr := Assoc;
+ Append_Elmt (Disc, Seen_Discs);
+
+ Assoc_Expr := Assoc;
+ Unseen_Disc_Count := Unseen_Disc_Count - 1;
end if;
-- Check the accessibility level of the expression when the
-- discriminant is of an anonymous access type.
if Present (Assoc_Expr)
+ and then Present (Disc)
and then Ekind (Etype (Disc)) = E_Anonymous_Access_Type
then
-- Perform a static check first, if possible
@@ -1019,8 +1200,8 @@ package body Sem_Ch6 is
Error_Msg_N
("access discriminant in return object would be a dangling"
& " reference", Return_Stmt);
- exit;
+ exit;
end if;
-- Otherwise, generate a dynamic check based on the extra
@@ -1041,9 +1222,16 @@ package body Sem_Ch6 is
end if;
end if;
- -- Iterate over the discriminants
+ -- Iterate over the discriminants, except when we have encountered
+ -- a named association since the discriminant order becomes
+ -- irrelevant in that case.
+
+ if not Assoc_Present then
+ Next_Discriminant (Disc);
+ end if;
+
+ -- Iterate over associations
- Disc := Next_Discriminant (Disc);
if not Is_List_Member (Assoc) then
exit;
else
@@ -1921,12 +2109,18 @@ package body Sem_Ch6 is
-- is just a string, as in (conjunction = "or"). In these cases the parser
-- generates this node, and the semantics does the disambiguation. Other
-- such case are actuals in an instantiation, the generic unit in an
- -- instantiation, and pragma arguments.
+ -- instantiation, pragma arguments, and aspect specifications.
procedure Analyze_Operator_Symbol (N : Node_Id) is
Par : constant Node_Id := Parent (N);
+ Maybe_Aspect_Spec : Node_Id := Par;
begin
+ if Nkind (Maybe_Aspect_Spec) /= N_Aspect_Specification then
+ -- deal with N_Aggregate nodes
+ Maybe_Aspect_Spec := Parent (Maybe_Aspect_Spec);
+ end if;
+
if (Nkind (Par) = N_Function_Call and then N = Name (Par))
or else Nkind (Par) = N_Function_Instantiation
or else (Nkind (Par) = N_Indexed_Component and then N = Prefix (Par))
@@ -1935,6 +2129,10 @@ package body Sem_Ch6 is
or else Nkind (Par) = N_Subprogram_Renaming_Declaration
or else (Nkind (Par) = N_Attribute_Reference
and then Attribute_Name (Par) /= Name_Value)
+ or else (Nkind (Maybe_Aspect_Spec) = N_Aspect_Specification
+ and then Get_Aspect_Id (Maybe_Aspect_Spec)
+ -- include other aspects here ???
+ in Aspect_Stable_Properties | Aspect_Aggregate)
then
Find_Direct_Name (N);
@@ -2232,6 +2430,26 @@ package body Sem_Ch6 is
else
Error_Msg_N ("invalid procedure or entry call", N);
+
+ -- Specialize the error message in the case where both a primitive
+ -- operation and a record component are visible at the same time.
+
+ if Nkind (P) = N_Selected_Component
+ and then Is_Entity_Name (Selector_Name (P))
+ then
+ declare
+ Sel : constant Entity_Id := Entity (Selector_Name (P));
+ begin
+ if Ekind (Sel) = E_Component
+ and then Present (Homonym (Sel))
+ and then Ekind (Homonym (Sel)) = E_Procedure
+ then
+ Error_Msg_NE ("\component & conflicts with"
+ & " homonym procedure (RM 4.1.3 (9.2/3))",
+ Selector_Name (P), Sel);
+ end if;
+ end;
+ end if;
end if;
<<Leave>>
diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
index 69430a6..07484d5 100644
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -1038,6 +1038,22 @@ package body Sem_Ch8 is
Mark_Ghost_Renaming (N, Entity (Nam));
end if;
+ -- Check against AI12-0401 here before Resolve may rewrite Nam and
+ -- potentially generate spurious warnings.
+
+ if Nkind (Nam) = N_Qualified_Expression
+ and then Is_Variable (Expression (Nam))
+ and then not
+ (Subtypes_Statically_Match (T, Etype (Expression (Nam)))
+ or else
+ Subtypes_Statically_Match (Base_Type (T), Etype (Nam)))
+ then
+ Error_Msg_N
+ ("subtype of renamed qualified expression does not " &
+ "statically match", N);
+ return;
+ end if;
+
Resolve (Nam, T);
-- If the renamed object is a function call of a limited type,
@@ -5606,7 +5622,10 @@ package body Sem_Ch8 is
-- undefined reference. The entry is not added if we are ignoring
-- errors.
- if not All_Errors_Mode and then Ignore_Errors_Enable = 0 then
+ if not All_Errors_Mode
+ and then Ignore_Errors_Enable = 0
+ and then not Get_Ignore_Errors
+ then
Urefs.Append (
(Node => N,
Err => Emsg,
@@ -5659,8 +5678,7 @@ package body Sem_Ch8 is
-- happens for trees generated from Exp_Pakd, where expressions
-- can be deliberately "mis-typed" to the packed array type.
- if Is_Array_Type (Entyp)
- and then Is_Packed (Entyp)
+ if Is_Packed_Array (Entyp)
and then Present (Etype (N))
and then Etype (N) = Packed_Array_Impl_Type (Entyp)
then
@@ -5737,12 +5755,6 @@ package body Sem_Ch8 is
E := Homonym (E);
end loop;
- -- If we are ignoring errors, skip the error processing
-
- if Get_Ignore_Errors then
- return;
- end if;
-
-- If no entries on homonym chain that were potentially visible,
-- and no entities reasonably considered as non-visible, then
-- we have a plain undefined reference, with no additional
@@ -7520,7 +7532,7 @@ package body Sem_Ch8 is
-- Reference to type name in predicate/invariant expression
- elsif (Is_Task_Type (P_Type) or else Is_Protected_Type (P_Type))
+ elsif Is_Concurrent_Type (P_Type)
and then not In_Open_Scopes (P_Name)
and then (not Is_Concurrent_Type (Etype (P_Name))
or else not In_Open_Scopes (Etype (P_Name)))
@@ -8751,9 +8763,8 @@ package body Sem_Ch8 is
-- Mark primitives
- elsif (Ekind (Id) in Overloadable_Kind
- or else Ekind (Id) in
- E_Generic_Function | E_Generic_Procedure)
+ elsif (Is_Overloadable (Id)
+ or else Is_Generic_Subprogram (Id))
and then (Is_Potentially_Use_Visible (Id)
or else Is_Intrinsic_Subprogram (Id)
or else (Ekind (Id) in E_Function | E_Procedure
diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb
index 12f2822..198f72f 100644
--- a/gcc/ada/sem_eval.adb
+++ b/gcc/ada/sem_eval.adb
@@ -3731,83 +3731,81 @@ package body Sem_Eval is
Raises_Constraint_Error (Right)
then
return;
+ end if;
-- OK, we have the case where we may be able to do this fold
- else
- Left_Len := Static_Length (Left);
- Right_Len := Static_Length (Right);
+ Left_Len := Static_Length (Left);
+ Right_Len := Static_Length (Right);
- if Left_Len /= Uint_Minus_1
- and then Right_Len /= Uint_Minus_1
- and then Left_Len /= Right_Len
- then
- -- AI12-0201: comparison of string is static in Ada 202x
+ if Left_Len /= Uint_Minus_1
+ and then Right_Len /= Uint_Minus_1
+ and then Left_Len /= Right_Len
+ then
+ -- AI12-0201: comparison of string is static in Ada 202x
- Fold_Uint
- (N,
- Test (Nkind (N) = N_Op_Ne),
- Static => Ada_Version >= Ada_2020
- and then Is_String_Type (Left_Typ));
- Warn_On_Known_Condition (N);
- return;
- end if;
+ Fold_Uint
+ (N,
+ Test (Nkind (N) = N_Op_Ne),
+ Static => Ada_Version >= Ada_2020
+ and then Is_String_Type (Left_Typ));
+ Warn_On_Known_Condition (N);
+ return;
end if;
+ end if;
-- General case
- else
- -- Initialize the value of Is_Static_Expression. The value of Fold
- -- returned by Test_Expression_Is_Foldable is not needed since, even
- -- when some operand is a variable, we can still perform the static
- -- evaluation of the expression in some cases (for example, for a
- -- variable of a subtype of Integer we statically know that any value
- -- stored in such variable is smaller than Integer'Last).
-
- Test_Expression_Is_Foldable
- (N, Left, Right, Is_Static_Expression, Fold);
-
- -- Comparisons of scalars can give static results.
- -- In addition starting with Ada 202x (AI12-0201), comparison of
- -- strings can also give static results, and as noted above, we also
- -- allow for earlier Ada versions internally generated equality and
- -- inequality for strings.
- -- ??? The Comes_From_Source test below isn't correct and will accept
- -- some cases that are illegal in Ada 2012. and before. Now that
- -- Ada 202x has relaxed the rules, this doesn't really matter.
-
- if Is_String_Type (Left_Typ) then
- if Ada_Version < Ada_2020
- and then (Comes_From_Source (N)
- or else Nkind (N) not in N_Op_Eq | N_Op_Ne)
- then
- Is_Static_Expression := False;
- Set_Is_Static_Expression (N, False);
- end if;
+ -- Initialize the value of Is_Static_Expression. The value of Fold
+ -- returned by Test_Expression_Is_Foldable is not needed since, even
+ -- when some operand is a variable, we can still perform the static
+ -- evaluation of the expression in some cases (for example, for a
+ -- variable of a subtype of Integer we statically know that any value
+ -- stored in such variable is smaller than Integer'Last).
- elsif not Is_Scalar_Type (Left_Typ) then
+ Test_Expression_Is_Foldable
+ (N, Left, Right, Is_Static_Expression, Fold);
+
+ -- Comparisons of scalars can give static results.
+ -- In addition starting with Ada 202x (AI12-0201), comparison of strings
+ -- can also give static results, and as noted above, we also allow for
+ -- earlier Ada versions internally generated equality and inequality for
+ -- strings.
+ -- ??? The Comes_From_Source test below isn't correct and will accept
+ -- some cases that are illegal in Ada 2012. and before. Now that Ada
+ -- 202x has relaxed the rules, this doesn't really matter.
+
+ if Is_String_Type (Left_Typ) then
+ if Ada_Version < Ada_2020
+ and then (Comes_From_Source (N)
+ or else Nkind (N) not in N_Op_Eq | N_Op_Ne)
+ then
Is_Static_Expression := False;
Set_Is_Static_Expression (N, False);
end if;
- -- For operators on universal numeric types called as functions with
- -- an explicit scope, determine appropriate specific numeric type,
- -- and diagnose possible ambiguity.
+ elsif not Is_Scalar_Type (Left_Typ) then
+ Is_Static_Expression := False;
+ Set_Is_Static_Expression (N, False);
+ end if;
- if Is_Universal_Numeric_Type (Left_Typ)
- and then
- Is_Universal_Numeric_Type (Right_Typ)
- then
- Op_Typ := Find_Universal_Operator_Type (N);
- end if;
+ -- For operators on universal numeric types called as functions with an
+ -- explicit scope, determine appropriate specific numeric type, and
+ -- diagnose possible ambiguity.
- -- Attempt to fold the relational operator
+ if Is_Universal_Numeric_Type (Left_Typ)
+ and then
+ Is_Universal_Numeric_Type (Right_Typ)
+ then
+ Op_Typ := Find_Universal_Operator_Type (N);
+ end if;
- if Is_Static_Expression and then Is_Real_Type (Left_Typ) then
- Fold_Static_Real_Op;
- else
- Fold_General_Op (Is_Static_Expression);
- end if;
+ -- Attempt to fold the relational operator
+
+ if Is_Static_Expression and then Is_Real_Type (Left_Typ) then
+ Fold_Static_Real_Op;
+ else
+ Fold_General_Op (Is_Static_Expression);
end if;
-- For the case of a folded relational operator on a specific numeric
@@ -3944,6 +3942,7 @@ package body Sem_Eval is
procedure Eval_Slice (N : Node_Id) is
Drange : constant Node_Id := Discrete_Range (N);
+ Name : constant Node_Id := Prefix (N);
begin
if Nkind (Drange) = N_Range then
@@ -3955,13 +3954,13 @@ package body Sem_Eval is
-- the type of A, is redundant, the slice can be replaced with A, and
-- this is worth a warning.
- if Is_Entity_Name (Prefix (N)) then
+ if Is_Entity_Name (Name) then
declare
- E : constant Entity_Id := Entity (Prefix (N));
+ E : constant Entity_Id := Entity (Name);
T : constant Entity_Id := Etype (E);
begin
- if Ekind (E) = E_Constant
+ if Is_Object (E)
and then Is_Array_Type (T)
and then Is_Entity_Name (Drange)
then
@@ -4806,6 +4805,8 @@ package body Sem_Eval is
end if;
end Check_Elab_Call;
+ Modulus : Uint;
+
begin
if Compile_Time_Known_Value (Left)
and then Compile_Time_Known_Value (Right)
@@ -4815,30 +4816,55 @@ package body Sem_Eval is
if Op = N_Op_Shift_Left then
Check_Elab_Call;
- -- Fold Shift_Left (X, Y) by computing (X * 2**Y) rem modulus
+ declare
+ Modulus : Uint;
+ begin
+ if Is_Modular_Integer_Type (Typ) then
+ Modulus := Einfo.Modulus (Typ);
+ else
+ Modulus := Uint_2 ** RM_Size (Typ);
+ end if;
- Fold_Uint
- (N,
- (Expr_Value (Left) * (Uint_2 ** Expr_Value (Right)))
- rem Modulus (Typ),
- Static => Static);
+ -- Fold Shift_Left (X, Y) by computing (X * 2**Y) rem modulus
+
+ Fold_Uint
+ (N,
+ (Expr_Value (Left) * (Uint_2 ** Expr_Value (Right)))
+ rem Modulus,
+ Static => Static);
+ end;
elsif Op = N_Op_Shift_Right then
Check_Elab_Call;
- -- Fold Shift_Right (X, Y) by computing abs X / 2**Y
+ -- X >> 0 is a no-op
- Fold_Uint
- (N,
- abs Expr_Value (Left) / (Uint_2 ** Expr_Value (Right)),
- Static => Static);
+ if Expr_Value (Right) = Uint_0 then
+ Fold_Uint (N, Expr_Value (Left), Static => Static);
+ else
+ if Is_Modular_Integer_Type (Typ) then
+ Modulus := Einfo.Modulus (Typ);
+ else
+ Modulus := Uint_2 ** RM_Size (Typ);
+ end if;
+ -- Fold X >> Y by computing (X [+ Modulus]) / 2**Y
+ -- Note that after a Shift_Right operation (with Y > 0), the
+ -- result is always positive, even if the original operand was
+ -- negative.
+
+ Fold_Uint
+ (N,
+ (Expr_Value (Left) +
+ (if Expr_Value (Left) >= Uint_0 then Uint_0 else Modulus))
+ / (Uint_2 ** Expr_Value (Right)),
+ Static => Static);
+ end if;
elsif Op = N_Op_Shift_Right_Arithmetic then
Check_Elab_Call;
declare
Two_Y : constant Uint := Uint_2 ** Expr_Value (Right);
- Modulus : Uint;
begin
if Is_Modular_Integer_Type (Typ) then
Modulus := Einfo.Modulus (Typ);
@@ -6301,11 +6327,13 @@ package body Sem_Eval is
if Subtypes_Statically_Match (T1, T2) then
return True;
- -- If either subtype is nonstatic then they're not compatible
+ -- A scalar subtype S1 is compatible with S2 if their bounds
+ -- are static and compatible, even if S1 has dynamic predicates
+ -- and is thus non-static. Predicate compatibility has been
+ -- checked above.
- elsif not Is_OK_Static_Subtype (T1)
- or else
- not Is_OK_Static_Subtype (T2)
+ elsif not Is_Static_Range (Scalar_Range (T1))
+ or else not Is_Static_Range (Scalar_Range (T2))
then
return False;
@@ -6353,6 +6381,14 @@ package body Sem_Eval is
and then not (Can_Never_Be_Null (T2)
and then not Can_Never_Be_Null (T1));
+ -- Private types without discriminants can be handled specially.
+ -- Predicate matching has been checked above.
+
+ elsif Is_Private_Type (T1)
+ and then not Has_Discriminants (T1)
+ then
+ return not Has_Discriminants (T2);
+
-- All other cases
else
@@ -7318,7 +7354,7 @@ package body Sem_Eval is
elsif Ekind (E) = E_Constant then
- -- One case we can give a metter message is when we have a
+ -- One case we can give a better message is when we have a
-- string literal created by concatenating an aggregate with
-- an others expression.
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index 1e1a279..1bcbb25 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -2383,9 +2383,9 @@ package body Sem_Prag is
("global item must denote object, state or current "
& "instance of concurrent type", Item);
- if Ekind (Item_Id) in Named_Kind then
+ if Is_Named_Number (Item_Id) then
SPARK_Msg_NE
- ("\named number & is not an object", Item, Item);
+ ("\named number & is not an object", Item, Item_Id);
end if;
return;
@@ -2476,11 +2476,22 @@ package body Sem_Prag is
and then Ekind (Item_Id) = E_Variable
and then Is_Effectively_Volatile_For_Reading (Item_Id)
then
+ -- The current instance of a protected unit is not an
+ -- effectively volatile object, unless the protected unit
+ -- is already volatile for another reason (SPARK RM 7.1.2).
+
+ if Is_Single_Protected_Object (Item_Id)
+ and then Is_CCT_Instance (Etype (Item_Id), Spec_Id)
+ and then not Is_Effectively_Volatile_For_Reading
+ (Item_Id, Ignore_Protected => True)
+ then
+ null;
+
-- An effectively volatile object for reading cannot appear
-- as a global item of a nonvolatile function (SPARK RM
-- 7.1.3(8)).
- if Ekind (Spec_Id) in E_Function | E_Generic_Function
+ elsif Ekind (Spec_Id) in E_Function | E_Generic_Function
and then not Is_Volatile_Function (Spec_Id)
then
Error_Msg_NE
@@ -4062,7 +4073,8 @@ package body Sem_Prag is
-- than library level instantiations these can appear in contexts which
-- would normally be invalid (they only apply to the original template
-- and to library level instantiations), and they are simply ignored,
- -- which is implemented by rewriting them as null statements.
+ -- which is implemented by rewriting them as null statements and raising
+ -- exception to terminate analysis.
procedure Check_Variant (Variant : Node_Id; UU_Typ : Entity_Id);
-- Check an Unchecked_Union variant for lack of nested variants and
@@ -4437,7 +4449,17 @@ package body Sem_Prag is
-- Subprogram declaration
elsif Nkind (Subp_Decl) = N_Subprogram_Declaration then
- null;
+
+ -- Pragmas Global and Depends are forbidden on null procedures
+ -- (SPARK RM 6.1.2(2)).
+
+ if Nkind (Specification (Subp_Decl)) = N_Procedure_Specification
+ and then Null_Present (Specification (Subp_Decl))
+ then
+ Error_Msg_N (Fix_Error
+ ("pragma % cannot apply to null procedure"), N);
+ return;
+ end if;
-- Task type
@@ -6069,7 +6091,7 @@ package body Sem_Prag is
-- The group and the current pragma are not in the same
-- declarative or statement list.
- if List_Containing (Stmt) /= List_Containing (N) then
+ if not In_Same_List (Stmt, N) then
Grouping_Error (Stmt);
-- Try to reach the current pragma from the first pragma
@@ -6173,17 +6195,15 @@ package body Sem_Prag is
--------------------
function Is_Loop_Pragma (Stmt : Node_Id) return Boolean is
+ Original_Stmt : constant Node_Id := Original_Node (Stmt);
+
begin
-- Inspect the original node as Loop_Invariant and Loop_Variant
-- pragmas are rewritten to null when assertions are disabled.
- if Nkind (Original_Node (Stmt)) = N_Pragma then
- return
- Pragma_Name_Unmapped (Original_Node (Stmt))
+ return Nkind (Original_Stmt) = N_Pragma
+ and then Pragma_Name_Unmapped (Original_Stmt)
in Name_Loop_Invariant | Name_Loop_Variant;
- else
- return False;
- end if;
end Is_Loop_Pragma;
---------------------
@@ -6567,7 +6587,7 @@ package body Sem_Prag is
if Loc not in Source_First (Sindex) .. Source_Last (Sindex) then
Rewrite (N, Make_Null_Statement (Loc));
- return;
+ raise Pragma_Exit;
-- If before first declaration, the pragma applies to the
-- enclosing unit, and the name if present must be this name.
@@ -8100,7 +8120,7 @@ package body Sem_Prag is
-- Check that we are not applying this to a named constant
- if Ekind (E) in E_Named_Integer | E_Named_Real then
+ if Is_Named_Number (E) then
Error_Msg_Name_1 := Pname;
Error_Msg_N
("cannot apply pragma% to named constant!",
@@ -9866,7 +9886,7 @@ package body Sem_Prag is
-- the test will have been applied to the original generic.
elsif Nkind (Decl) in N_Formal_Subprogram_Declaration
- and then List_Containing (Decl) = List_Containing (N)
+ and then In_Same_List (Decl, N)
and then not In_Instance
then
Error_Msg_N
@@ -10418,10 +10438,13 @@ package body Sem_Prag is
Add_To_Config_Boolean_Restrictions (No_Elaboration_Code);
end if;
- -- Special processing for No_Tasking restriction placed in
- -- a configuration pragmas file.
+ -- Special processing for No_Tasking restriction (not just a
+ -- warning) when it appears as a configuration pragma.
- elsif R_Id = No_Tasking and then No (Cunit (Main_Unit)) then
+ elsif R_Id = No_Tasking
+ and then No (Cunit (Main_Unit))
+ and then not Warn
+ then
Set_Global_No_Tasking;
end if;
@@ -11343,19 +11366,26 @@ package body Sem_Prag is
-- Deal with unrecognized pragma
if not Is_Pragma_Name (Pname) then
- if Warn_On_Unrecognized_Pragma then
- Error_Msg_Name_1 := Pname;
- Error_Msg_N ("?g?unrecognized pragma%!", Pragma_Identifier (N));
-
- for PN in First_Pragma_Name .. Last_Pragma_Name loop
- if Is_Bad_Spelling_Of (Pname, PN) then
- Error_Msg_Name_1 := PN;
- Error_Msg_N -- CODEFIX
- ("\?g?possible misspelling of %!", Pragma_Identifier (N));
- exit;
- end if;
- end loop;
- end if;
+ declare
+ Msg_Issued : Boolean := False;
+ begin
+ Check_Restriction
+ (Msg_Issued, No_Unrecognized_Pragmas, Pragma_Identifier (N));
+ if not Msg_Issued and then Warn_On_Unrecognized_Pragma then
+ Error_Msg_Name_1 := Pname;
+ Error_Msg_N ("?g?unrecognized pragma%!", Pragma_Identifier (N));
+
+ for PN in First_Pragma_Name .. Last_Pragma_Name loop
+ if Is_Bad_Spelling_Of (Pname, PN) then
+ Error_Msg_Name_1 := PN;
+ Error_Msg_N -- CODEFIX
+ ("\?g?possible misspelling of %!",
+ Pragma_Identifier (N));
+ exit;
+ end if;
+ end loop;
+ end if;
+ end;
return;
end if;
@@ -11411,6 +11441,12 @@ package body Sem_Prag is
end if;
end if;
+ -- Mark assertion pragmas as Ghost depending on their enclosing context
+
+ if Assertion_Expression_Pragma (Prag_Id) then
+ Mark_Ghost_Pragma (N, Current_Scope);
+ end if;
+
-- Preset arguments
Arg_Count := 0;
@@ -12519,10 +12555,6 @@ package body Sem_Prag is
Check_Ada_83_Warning;
Check_Valid_Library_Unit_Pragma;
- if Nkind (N) = N_Null_Statement then
- return;
- end if;
-
Lib_Entity := Find_Lib_Unit_Name;
-- A pragma that applies to a Ghost entity becomes Ghost for the
@@ -15079,7 +15111,7 @@ package body Sem_Prag is
begin
GNAT_Pragma;
Check_No_Identifiers;
- Check_At_Most_N_Arguments (1);
+ Check_At_Most_N_Arguments (2); -- Accounts for implicit type arg
Typ := Empty;
Stmt := Prev (N);
@@ -15142,6 +15174,27 @@ package body Sem_Prag is
Set_Has_Own_DIC (Typ);
+ -- A type entity argument is appended to facilitate inheriting the
+ -- aspect/pragma from parent types (see Build_DIC_Procedure_Body),
+ -- though that extra argument isn't documented for the pragma.
+
+ if not Present (Arg2) then
+ -- When the pragma has no arguments, create an argument with
+ -- the value Empty, so the type name argument can be appended
+ -- following it (since it's expected as the second argument).
+
+ if not Present (Arg1) then
+ Set_Pragma_Argument_Associations (N, New_List (
+ Make_Pragma_Argument_Association (Sloc (Typ),
+ Expression => Empty)));
+ end if;
+
+ Append_To
+ (Pragma_Argument_Associations (N),
+ Make_Pragma_Argument_Association (Sloc (Typ),
+ Expression => New_Occurrence_Of (Typ, Sloc (Typ))));
+ end if;
+
-- Chain the pragma on the rep item chain for further processing
Discard := Rep_Item_Too_Late (Typ, N, FOnly => True);
@@ -15713,10 +15766,6 @@ package body Sem_Prag is
Check_Ada_83_Warning;
Check_Valid_Library_Unit_Pragma;
- if Nkind (N) = N_Null_Statement then
- return;
- end if;
-
Cunit_Node := Cunit (Current_Sem_Unit);
Cunit_Ent := Cunit_Entity (Current_Sem_Unit);
@@ -18508,7 +18557,7 @@ package body Sem_Prag is
-- The pragma defines a type-specific invariant, the type is said
-- to have invariants of its "own".
- Set_Has_Own_Invariants (Typ);
+ Set_Has_Own_Invariants (Base_Type (Typ));
-- If the invariant is class-wide, then it can be inherited by
-- derived or interface implementing types. The type is said to
@@ -19421,10 +19470,6 @@ package body Sem_Prag is
GNAT_Pragma;
Check_Valid_Library_Unit_Pragma;
- if Nkind (N) = N_Null_Statement then
- return;
- end if;
-
-- Must appear for a spec or generic spec
if Nkind (Unit (Cunit (Current_Sem_Unit))) not in
@@ -19646,7 +19691,53 @@ package body Sem_Prag is
-- pragma No_Return (procedure_LOCAL_NAME {, procedure_Local_Name});
- when Pragma_No_Return => No_Return : declare
+ when Pragma_No_Return => Prag_No_Return : declare
+
+ function Check_No_Return
+ (E : Entity_Id;
+ N : Node_Id) return Boolean;
+ -- Check rule 6.5.1(4/3) of the Ada RM. If the rule is violated,
+ -- emit an error message and return False, otherwise return True.
+ -- 6.5.1 Nonreturning procedures:
+ -- 4/3 "Aspect No_Return shall not be specified for a null
+ -- procedure nor an instance of a generic unit."
+
+ ---------------------
+ -- Check_No_Return --
+ ---------------------
+
+ function Check_No_Return
+ (E : Entity_Id;
+ N : Node_Id) return Boolean
+ is
+ begin
+ if Ekind (E) = E_Procedure then
+
+ -- If E is a generic instance, marking it with No_Return
+ -- is forbidden, but having it inherit the No_Return of
+ -- the generic is allowed. We check if E is inheriting its
+ -- No_Return flag from the generic by checking if No_Return
+ -- is already set.
+
+ if Is_Generic_Instance (E) and then not No_Return (E) then
+ Error_Msg_NE
+ ("generic instance & is marked as No_Return", N, E);
+ Error_Msg_NE
+ ("\generic procedure & must be marked No_Return",
+ N,
+ Generic_Parent (Parent (E)));
+ return False;
+
+ elsif Null_Present (Subprogram_Specification (E)) then
+ Error_Msg_NE
+ ("null procedure & cannot be marked No_Return", N, E);
+ return False;
+ end if;
+ end if;
+
+ return True;
+ end Check_No_Return;
+
Arg : Node_Id;
E : Entity_Id;
Found : Boolean;
@@ -19718,7 +19809,9 @@ package body Sem_Prag is
end if;
end if;
- Set_No_Return (E);
+ if Check_No_Return (E, N) then
+ Set_No_Return (E);
+ end if;
-- A pragma that applies to a Ghost entity becomes Ghost
-- for the purposes of legality checks and removal of
@@ -19757,7 +19850,10 @@ package body Sem_Prag is
-- Set flag on any alias as well
- if Is_Overloadable (E) and then Present (Alias (E)) then
+ if Is_Overloadable (E)
+ and then Present (Alias (E))
+ and then Check_No_Return (Alias (E), N)
+ then
Set_No_Return (Alias (E));
end if;
@@ -19774,6 +19870,7 @@ package body Sem_Prag is
if not Found then
if Entity (Id) = Current_Scope
and then From_Aspect_Specification (N)
+ and then Check_No_Return (Entity (Id), N)
then
Set_No_Return (Entity (Id));
@@ -19788,7 +19885,7 @@ package body Sem_Prag is
Next (Arg);
end loop;
- end No_Return;
+ end Prag_No_Return;
-----------------
-- No_Run_Time --
@@ -21158,10 +21255,6 @@ package body Sem_Prag is
Check_Ada_83_Warning;
Check_Valid_Library_Unit_Pragma;
- if Nkind (N) = N_Null_Statement then
- return;
- end if;
-
Ent := Find_Lib_Unit_Name;
-- A pragma that applies to a Ghost entity becomes Ghost for the
@@ -21462,7 +21555,11 @@ package body Sem_Prag is
Argx : constant Node_Id := Get_Pragma_Arg (Arg1);
begin
- if Chars (Argx) = Name_Ravenscar then
+ if Nkind (Argx) /= N_Identifier then
+ Error_Msg_N
+ ("argument of pragma Profile must be an identifier", N);
+
+ elsif Chars (Argx) = Name_Ravenscar then
Set_Ravenscar_Profile (Ravenscar, N);
elsif Chars (Argx) = Name_Jorvik then
@@ -21803,10 +21900,6 @@ package body Sem_Prag is
Check_Valid_Library_Unit_Pragma;
end if;
- if Nkind (N) = N_Null_Statement then
- return;
- end if;
-
Ent := Find_Lib_Unit_Name;
-- A pragma that applies to a Ghost entity becomes Ghost for the
@@ -22343,10 +22436,6 @@ package body Sem_Prag is
Check_Ada_83_Warning;
Check_Valid_Library_Unit_Pragma;
- if Nkind (N) = N_Null_Statement then
- return;
- end if;
-
Cunit_Node := Cunit (Current_Sem_Unit);
K := Nkind (Unit (Cunit_Node));
Cunit_Ent := Cunit_Entity (Current_Sem_Unit);
@@ -22386,10 +22475,6 @@ package body Sem_Prag is
Check_Ada_83_Warning;
Check_Valid_Library_Unit_Pragma;
- if Nkind (N) = N_Null_Statement then
- return;
- end if;
-
Cunit_Node := Cunit (Current_Sem_Unit);
Cunit_Ent := Cunit_Entity (Current_Sem_Unit);
@@ -22586,10 +22671,6 @@ package body Sem_Prag is
Check_Ada_83_Warning;
Check_Valid_Library_Unit_Pragma;
- if Nkind (N) = N_Null_Statement then
- return;
- end if;
-
Cunit_Node := Cunit (Current_Sem_Unit);
Cunit_Ent := Cunit_Entity (Current_Sem_Unit);
@@ -24773,18 +24854,15 @@ package body Sem_Prag is
-- body, not in the spec).
when Pragma_Unimplemented_Unit => Unimplemented_Unit : declare
- Cunitent : constant Entity_Id :=
+ Cunitent : constant Entity_Id :=
Cunit_Entity (Get_Source_Unit (Loc));
- Ent_Kind : constant Entity_Kind := Ekind (Cunitent);
begin
GNAT_Pragma;
Check_Arg_Count (0);
if Operating_Mode = Generate_Code
- or else Ent_Kind = E_Generic_Function
- or else Ent_Kind = E_Generic_Procedure
- or else Ent_Kind = E_Generic_Package
+ or else Is_Generic_Unit (Cunitent)
then
Get_Name_String (Chars (Cunitent));
Set_Casing (Mixed_Case);
@@ -31417,7 +31495,6 @@ package body Sem_Prag is
-- RM defined
Name_Assert
- | Name_Assertion_Policy
| Name_Static_Predicate
| Name_Dynamic_Predicate
| Name_Pre
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index a24c9c2..ed744ea 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -2155,6 +2155,10 @@ package body Sem_Res is
N_Real_Literal => Aspect_Real_Literal,
N_String_Literal => Aspect_String_Literal);
+ Named_Number_Aspect_Map : constant array (Named_Kind) of Aspect_Id :=
+ (E_Named_Integer => Aspect_Integer_Literal,
+ E_Named_Real => Aspect_Real_Literal);
+
-- Start of processing for Resolve
begin
@@ -2880,58 +2884,102 @@ package body Sem_Res is
-- Rewrite Literal as a call if the corresponding literal aspect
-- is set.
- if Nkind (N) in N_Numeric_Or_String_Literal
- and then Present
- (Find_Aspect (Typ, Literal_Aspect_Map (Nkind (N))))
+ if (Nkind (N) in N_Numeric_Or_String_Literal
+ and then
+ Present
+ (Find_Aspect (Typ, Literal_Aspect_Map (Nkind (N)))))
+ or else
+ (Nkind (N) = N_Identifier
+ and then Is_Named_Number (Entity (N))
+ and then
+ Present
+ (Find_Aspect
+ (Typ, Named_Number_Aspect_Map (Ekind (Entity (N))))))
then
declare
- function Literal_Text (N : Node_Id) return String_Id;
- -- Returns the text of a literal node
+ Lit_Aspect : constant Aspect_Id :=
+ (if Nkind (N) = N_Identifier
+ then Named_Number_Aspect_Map (Ekind (Entity (N)))
+ else Literal_Aspect_Map (Nkind (N)));
- -------------------
- -- Literal_Text --
- -------------------
+ Loc : constant Source_Ptr := Sloc (N);
- function Literal_Text (N : Node_Id) return String_Id is
- begin
- pragma Assert (Nkind (N) in N_Numeric_Or_String_Literal);
+ Callee : Entity_Id :=
+ Entity (Expression (Find_Aspect (Typ, Lit_Aspect)));
- if Nkind (N) = N_String_Literal then
- return Strval (N);
- else
- return String_From_Numeric_Literal (N);
- end if;
- end Literal_Text;
+ Name : constant Node_Id :=
+ Make_Identifier (Loc, Chars (Callee));
- Lit_Aspect : constant Aspect_Id :=
- Literal_Aspect_Map (Nkind (N));
+ Param1 : Node_Id;
+ Param2 : Node_Id;
+ Params : List_Id;
+ Call : Node_Id;
+ Expr : Node_Id;
- Callee : constant Entity_Id :=
- Entity (Expression (Find_Aspect (Typ, Lit_Aspect)));
+ begin
+ if Nkind (N) = N_Identifier then
+ Expr := Expression (Declaration_Node (Entity (N)));
- Loc : constant Source_Ptr := Sloc (N);
+ if Ekind (Entity (N)) = E_Named_Integer then
+ UI_Image (Expr_Value (Expr), Decimal);
+ Start_String;
+ Store_String_Chars
+ (UI_Image_Buffer (1 .. UI_Image_Length));
+ Param1 := Make_String_Literal (Loc, End_String);
+ Params := New_List (Param1);
- Name : constant Node_Id :=
- Make_Identifier (Loc, Chars (Callee));
+ else
+ UI_Image (Norm_Num (Expr_Value_R (Expr)), Decimal);
+ Start_String;
+ Store_String_Chars
+ (UI_Image_Buffer (1 .. UI_Image_Length));
+ Param1 := Make_String_Literal (Loc, End_String);
- Param : constant Node_Id :=
- Make_String_Literal (Loc, Literal_Text (N));
+ -- Note: Set_Etype is called below on Param1
- Params : constant List_Id := New_List (Param);
+ UI_Image (Norm_Den (Expr_Value_R (Expr)), Decimal);
+ Start_String;
+ Store_String_Chars
+ (UI_Image_Buffer (1 .. UI_Image_Length));
+ Param2 := Make_String_Literal (Loc, End_String);
+ Set_Etype (Param2, Standard_String);
- Call : Node_Id :=
+ Params := New_List (Param1, Param2);
+
+ if Present (Related_Expression (Callee)) then
+ Callee := Related_Expression (Callee);
+ else
+ Error_Msg_NE
+ ("cannot resolve & for a named real", N, Callee);
+ return;
+ end if;
+ end if;
+
+ elsif Nkind (N) = N_String_Literal then
+ Param1 := Make_String_Literal (Loc, Strval (N));
+ Params := New_List (Param1);
+ else
+ Param1 :=
+ Make_String_Literal
+ (Loc, String_From_Numeric_Literal (N));
+ Params := New_List (Param1);
+ end if;
+
+ Call :=
Make_Function_Call
(Sloc => Loc,
Name => Name,
Parameter_Associations => Params);
- begin
+
Set_Entity (Name, Callee);
Set_Is_Overloaded (Name, False);
+
if Lit_Aspect = Aspect_String_Literal then
- Set_Etype (Param, Standard_Wide_Wide_String);
+ Set_Etype (Param1, Standard_Wide_Wide_String);
else
- Set_Etype (Param, Standard_String);
+ Set_Etype (Param1, Standard_String);
end if;
+
Set_Etype (Call, Etype (Callee));
-- Conversion needed in case of an inherited aspect
@@ -2947,6 +2995,7 @@ package body Sem_Res is
Rewrite (N, Call);
end;
+
Analyze_And_Resolve (N, Typ);
return;
end if;
@@ -6244,7 +6293,7 @@ package body Sem_Res is
-- Normal subprogram call with name established in Resolve
- elsif not (Is_Type (Entity (Subp))) then
+ elsif not Is_Type (Entity (Subp)) then
Nam := Entity (Subp);
Set_Entity_With_Checks (Subp, Nam);
@@ -7408,21 +7457,7 @@ package body Sem_Res is
Analyze_Dimension (N);
- -- Evaluate the relation (note we do this after the above check since
- -- this Eval call may change N to True/False. Skip this evaluation
- -- inside assertions, in order to keep assertions as written by users
- -- for tools that rely on these, e.g. GNATprove for loop invariants.
- -- Except evaluation is still performed even inside assertions for
- -- comparisons between values of universal type, which are useless
- -- for static analysis tools, and not supported even by GNATprove.
-
- if In_Assertion_Expr = 0
- or else (Is_Universal_Numeric_Type (Etype (L))
- and then
- Is_Universal_Numeric_Type (Etype (R)))
- then
- Eval_Relational_Op (N);
- end if;
+ Eval_Relational_Op (N);
end Resolve_Comparison_Op;
--------------------------------
@@ -8369,6 +8404,11 @@ package body Sem_Res is
-- This is semantically dubious, and of no interest to any real code,
-- but c48008a makes it all worthwhile.
+ function Suspicious_Prio_For_Equality return Boolean;
+ -- Returns True iff the parent node is a and/or/xor operation that
+ -- could be the cause of confused priorities. Note that if the not is
+ -- in parens, then False is returned.
+
-------------------------
-- Check_If_Expression --
-------------------------
@@ -8498,6 +8538,47 @@ package body Sem_Res is
return Empty;
end Find_Unique_Access_Type;
+ ----------------------------------
+ -- Suspicious_Prio_For_Equality --
+ ----------------------------------
+
+ function Suspicious_Prio_For_Equality return Boolean is
+ Par : constant Node_Id := Parent (N);
+
+ begin
+ -- Check if parent node is one of and/or/xor, not parenthesized
+ -- explicitly, and its own parent is not of this kind. Otherwise,
+ -- it's a case of chained Boolean conditions which is likely well
+ -- parenthesized.
+
+ if Nkind (Par) in N_Op_And | N_Op_Or | N_Op_Xor
+ and then Paren_Count (N) = 0
+ and then Nkind (Parent (Par)) not in N_Op_And | N_Op_Or | N_Op_Xor
+ then
+ declare
+ Compar : Node_Id :=
+ (if Left_Opnd (Par) = N then
+ Right_Opnd (Par)
+ else
+ Left_Opnd (Par));
+ begin
+ -- Compar may have been rewritten, for example from (a /= b)
+ -- into not (a = b). Use the Original_Node instead.
+
+ Compar := Original_Node (Compar);
+
+ -- If the other argument of the and/or/xor is also a
+ -- comparison, or another and/or/xor then most likely
+ -- the priorities are correctly set.
+
+ return Nkind (Compar) not in N_Op_Boolean;
+ end;
+
+ else
+ return False;
+ end if;
+ end Suspicious_Prio_For_Equality;
+
-- Start of processing for Resolve_Equality_Op
begin
@@ -8578,6 +8659,24 @@ package body Sem_Res is
Explain_Redundancy (Original_Node (R));
end if;
+ -- Warn on a (in)equality between boolean values which is not
+ -- parenthesized when the parent expression is one of and/or/xor, as
+ -- this is interpreted as (a = b) op c where most likely a = (b op c)
+ -- was intended. Do not generate a warning in generic instances, as
+ -- the problematic expression may be implicitly parenthesized in
+ -- the generic itself if one of the operators is a generic formal.
+ -- Also do not generate a warning for generated equality, for
+ -- example from rewritting a membership test.
+
+ if Warn_On_Questionable_Missing_Parens
+ and then not In_Instance
+ and then Comes_From_Source (N)
+ and then Is_Boolean_Type (T)
+ and then Suspicious_Prio_For_Equality
+ then
+ Error_Msg_N ("?q?equality should be parenthesized here!", N);
+ end if;
+
-- If the equality is overloaded and the operands have resolved
-- properly, set the proper equality operator on the node. The
-- current setting is the first one found during analysis, which
@@ -8800,8 +8899,7 @@ package body Sem_Res is
-- actual subtype. We also exclude generated code (which builds actual
-- subtypes directly if they are needed).
- if Is_Array_Type (Etype (N))
- and then Is_Packed (Etype (N))
+ if Is_Packed_Array (Etype (N))
and then not Is_Constrained (Etype (N))
and then Nkind (Parent (N)) /= N_Attribute_Reference
and then Comes_From_Source (N)
@@ -9507,7 +9605,7 @@ package body Sem_Res is
-- universal types applies.
procedure Resolve_Membership_Op (N : Node_Id; Typ : Entity_Id) is
- pragma Warnings (Off, Typ);
+ pragma Assert (Is_Boolean_Type (Typ));
L : constant Node_Id := Left_Opnd (N);
R : constant Node_Id := Right_Opnd (N);
@@ -10130,8 +10228,6 @@ package body Sem_Res is
--------------------
procedure Resolve_Op_Not (N : Node_Id; Typ : Entity_Id) is
- B_Typ : Entity_Id;
-
function Parent_Is_Boolean return Boolean;
-- This function determines if the parent node is a boolean operator or
-- operation (comparison op, membership test, or short circuit form) and
@@ -10144,32 +10240,16 @@ package body Sem_Res is
function Parent_Is_Boolean return Boolean is
begin
- if Paren_Count (N) /= 0 then
- return False;
+ return Paren_Count (N) = 0
+ and then Nkind (Parent (N)) in N_Membership_Test
+ | N_Op_Boolean
+ | N_Short_Circuit
+ and then Left_Opnd (Parent (N)) = N;
+ end Parent_Is_Boolean;
- else
- case Nkind (Parent (N)) is
- when N_And_Then
- | N_In
- | N_Not_In
- | N_Op_And
- | N_Op_Eq
- | N_Op_Ge
- | N_Op_Gt
- | N_Op_Le
- | N_Op_Lt
- | N_Op_Ne
- | N_Op_Or
- | N_Op_Xor
- | N_Or_Else
- =>
- return Left_Opnd (Parent (N)) = N;
+ -- Local variables
- when others =>
- return False;
- end case;
- end if;
- end Parent_Is_Boolean;
+ B_Typ : Entity_Id;
-- Start of processing for Resolve_Op_Not
@@ -11635,16 +11715,14 @@ package body Sem_Res is
Simplify_Type_Conversion (N);
-- If after evaluation we still have a type conversion, then we may need
- -- to apply checks required for a subtype conversion.
-
- -- Skip these type conversion checks if universal fixed operands
- -- are involved, since range checks are handled separately for
- -- these cases (in the appropriate Expand routines in unit Exp_Fixd).
+ -- to apply checks required for a subtype conversion. But skip them if
+ -- universal fixed operands are involved, since range checks are handled
+ -- separately for these cases, after the expansion done by Exp_Fixd.
if Nkind (N) = N_Type_Conversion
and then not Is_Generic_Type (Root_Type (Target_Typ))
and then Target_Typ /= Universal_Fixed
- and then Operand_Typ /= Universal_Fixed
+ and then Etype (Operand) /= Universal_Fixed
then
Apply_Type_Conversion_Checks (N);
end if;
@@ -11883,11 +11961,12 @@ package body Sem_Res is
(N, Target_Typ, Static_Failure_Is_Error => True);
end if;
- -- If at this stage we have a fixed point to integer conversion, make
- -- sure that the Do_Range_Check flag is set which is not always done
- -- by exp_fixd.adb.
+ -- If at this stage we have a fixed to integer conversion, make sure the
+ -- Do_Range_Check flag is set, because such conversions in general need
+ -- a range check. We only need this if expansion is off, see above why.
if Nkind (N) = N_Type_Conversion
+ and then not Expander_Active
and then Is_Integer_Type (Target_Typ)
and then Is_Fixed_Point_Type (Operand_Typ)
and then not Range_Checks_Suppressed (Target_Typ)
@@ -12390,9 +12469,10 @@ package body Sem_Res is
-- the point where actions for the slice are analyzed). Note that this
-- is different from freezing the itype immediately, which might be
-- premature (e.g. if the slice is within a transient scope). This needs
- -- to be done only if expansion is enabled.
+ -- to be done only if expansion is enabled, or in GNATprove mode to
+ -- capture the associated run-time exceptions if any.
- elsif Expander_Active then
+ elsif Expander_Active or GNATprove_Mode then
Ensure_Defined (Typ => Slice_Subtype, N => N);
end if;
end Set_Slice_Subtype;
diff --git a/gcc/ada/sem_type.adb b/gcc/ada/sem_type.adb
index 3b1f48e..8dbfa18 100644
--- a/gcc/ada/sem_type.adb
+++ b/gcc/ada/sem_type.adb
@@ -326,8 +326,19 @@ package body Sem_Type is
return False;
elsif Nkind (N) in N_Binary_Op then
- return Present (Universal_Interpretation (Left_Opnd (N)))
- and then Present (Universal_Interpretation (Right_Opnd (N)));
+ if Present (Universal_Interpretation (Left_Opnd (N)))
+ and then Present (Universal_Interpretation (Right_Opnd (N)))
+ then
+ return True;
+ elsif Nkind (N) in N_Op_Eq | N_Op_Ne
+ and then
+ (Is_Anonymous_Access_Type (Etype (Left_Opnd (N)))
+ or else Is_Anonymous_Access_Type (Etype (Right_Opnd (N))))
+ then
+ return True;
+ else
+ return False;
+ end if;
elsif Nkind (N) in N_Unary_Op then
return Present (Universal_Interpretation (Right_Opnd (N)));
@@ -1156,16 +1167,14 @@ package body Sem_Type is
-- useless unchecked conversions, and since this can only arise in
-- (known correct) expanded code, no harm is done.
- elsif Is_Array_Type (T2)
- and then Is_Packed (T2)
+ elsif Is_Packed_Array (T2)
and then T1 = Packed_Array_Impl_Type (T2)
then
return True;
-- Similarly an array type covers its corresponding packed array type
- elsif Is_Array_Type (T1)
- and then Is_Packed (T1)
+ elsif Is_Packed_Array (T1)
and then T2 = Packed_Array_Impl_Type (T1)
then
return True;
@@ -1338,6 +1347,13 @@ package body Sem_Type is
-- for special handling of expressions with universal operands, see
-- comments to Has_Abstract_Interpretation below.
+ function Is_User_Defined_Anonymous_Access_Equality
+ (User_Subp, Predef_Subp : Entity_Id) return Boolean;
+ -- Check for Ada 2005, AI-020: If the context involves an anonymous
+ -- access operand, recognize a user-defined equality (User_Subp) with
+ -- the proper signature, declared in the same declarative list as the
+ -- type and not hiding a predefined equality Predef_Subp.
+
---------------------------
-- Inherited_From_Actual --
---------------------------
@@ -1743,6 +1759,37 @@ package body Sem_Type is
end if;
end Standard_Operator;
+ -----------------------------------------------
+ -- Is_User_Defined_Anonymous_Access_Equality --
+ -----------------------------------------------
+
+ function Is_User_Defined_Anonymous_Access_Equality
+ (User_Subp, Predef_Subp : Entity_Id) return Boolean is
+ begin
+ return Present (User_Subp)
+
+ -- Check for Ada 2005 and use of anonymous access
+
+ and then Ada_Version >= Ada_2005
+ and then Etype (User_Subp) = Standard_Boolean
+ and then Is_Anonymous_Access_Type (Operand_Type)
+
+ -- This check is only relevant if User_Subp is visible and not in
+ -- an instance
+
+ and then (In_Open_Scopes (Scope (User_Subp))
+ or else Is_Potentially_Use_Visible (User_Subp))
+ and then not In_Instance
+ and then not Hides_Op (User_Subp, Predef_Subp)
+
+ -- Is User_Subp declared in the same declarative list as the type?
+
+ and then
+ In_Same_Declaration_List
+ (Designated_Type (Operand_Type),
+ Unit_Declaration_Node (User_Subp));
+ end Is_User_Defined_Anonymous_Access_Equality;
+
-- Start of processing for Disambiguate
begin
@@ -1856,17 +1903,41 @@ package body Sem_Type is
Arg2 := Next_Actual (Arg1);
end if;
- if Present (Arg2)
- and then Present (Universal_Interpretation (Arg1))
- and then Universal_Interpretation (Arg2) =
- Universal_Interpretation (Arg1)
- then
- Get_First_Interp (N, I, It);
- while Scope (It.Nam) /= Standard_Standard loop
- Get_Next_Interp (I, It);
- end loop;
+ if Present (Arg2) then
+ if Ekind (Nam1) = E_Operator then
+ Predef_Subp := Nam1;
+ User_Subp := Nam2;
+ elsif Ekind (Nam2) = E_Operator then
+ Predef_Subp := Nam2;
+ User_Subp := Nam1;
+ else
+ Predef_Subp := Empty;
+ User_Subp := Empty;
+ end if;
- return It;
+ -- Take into account universal interpretation as well as
+ -- universal_access equality, as long as AI05-0020 does not
+ -- trigger.
+
+ if (Present (Universal_Interpretation (Arg1))
+ and then Universal_Interpretation (Arg2) =
+ Universal_Interpretation (Arg1))
+ or else
+ (Nkind (N) in N_Op_Eq | N_Op_Ne
+ and then (Is_Anonymous_Access_Type (Etype (Arg1))
+ or else
+ Is_Anonymous_Access_Type (Etype (Arg2)))
+ and then not
+ Is_User_Defined_Anonymous_Access_Equality
+ (User_Subp, Predef_Subp))
+ then
+ Get_First_Interp (N, I, It);
+ while Scope (It.Nam) /= Standard_Standard loop
+ Get_Next_Interp (I, It);
+ end loop;
+
+ return It;
+ end if;
end if;
end;
end if;
@@ -2117,20 +2188,11 @@ package body Sem_Type is
return It2;
end if;
- -- Ada 2005, AI-420: preference rule for "=" on Universal_Access
- -- states that the operator defined in Standard is not available
- -- if there is a user-defined equality with the proper signature,
- -- declared in the same declarative list as the type. The node
- -- may be an operator or a function call.
+ -- Check for AI05-020
elsif Chars (Nam1) in Name_Op_Eq | Name_Op_Ne
- and then Ada_Version >= Ada_2005
- and then Etype (User_Subp) = Standard_Boolean
- and then Is_Anonymous_Access_Type (Operand_Type)
- and then
- In_Same_Declaration_List
- (Designated_Type (Operand_Type),
- Unit_Declaration_Node (User_Subp))
+ and then Is_User_Defined_Anonymous_Access_Equality
+ (User_Subp, Predef_Subp)
then
if It2.Nam = Predef_Subp then
return It1;
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index 0eb4905..72dbc68 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -6454,11 +6454,7 @@ package body Sem_Util is
and then Etype (First_Formal (Id)) =
Etype (Next_Formal (First_Formal (Id)))
then
- if No (Eq_Prims_List) then
- Eq_Prims_List := New_Elmt_List;
- end if;
-
- Append_Elmt (Id, Eq_Prims_List);
+ Append_New_Elmt (Id, Eq_Prims_List);
end if;
end if;
end if;
@@ -7859,6 +7855,8 @@ package body Sem_Util is
or else
Nkind (Decl) in N_Later_Decl_Item
or else
+ Nkind (Decl) in N_Renaming_Declaration
+ or else
Nkind (Decl) = N_Number_Declaration)
loop
Decl := Parent (Decl);
@@ -8290,6 +8288,13 @@ package body Sem_Util is
else
Set_Name_Entity_Id (Chars (E), Homonym (E));
end if;
+
+ -- The inherited operation cannot be retrieved
+ -- by name, even though it may remain accesssible
+ -- in some cases involving subprogram bodies without
+ -- specs appearing in with_clauses..
+
+ Set_Is_Immediately_Visible (E, False);
end if;
end;
@@ -11394,7 +11399,7 @@ package body Sem_Util is
Comp : Entity_Id;
begin
- -- Loop to Check components
+ -- Loop to check components
Comp := First_Component_Or_Discriminant (Typ);
while Present (Comp) loop
@@ -12727,12 +12732,11 @@ package body Sem_Util is
----------------------------------
function Has_Non_Trivial_Precondition (Subp : Entity_Id) return Boolean is
- Pre : constant Node_Id := Find_Aspect (Subp, Aspect_Pre);
-
+ Pre : constant Node_Id := Find_Aspect (Subp, Aspect_Pre,
+ Class_Present => True);
begin
return
Present (Pre)
- and then Class_Present (Pre)
and then not Is_Entity_Name (Expression (Pre));
end Has_Non_Trivial_Precondition;
@@ -16582,7 +16586,9 @@ package body Sem_Util is
-- Is_Effectively_Volatile --
-----------------------------
- function Is_Effectively_Volatile (Id : Entity_Id) return Boolean is
+ function Is_Effectively_Volatile
+ (Id : Entity_Id;
+ Ignore_Protected : Boolean := False) return Boolean is
begin
if Is_Type (Id) then
@@ -16610,15 +16616,16 @@ package body Sem_Util is
-- Test for presence of ancestor, as the full view of a
-- private type may be missing in case of error.
- return
- Present (Anc)
- and then Is_Effectively_Volatile (Component_Type (Anc));
+ return Present (Anc)
+ and then Is_Effectively_Volatile
+ (Component_Type (Anc), Ignore_Protected);
end;
end if;
- -- A protected type is always volatile
+ -- A protected type is always volatile unless Ignore_Protected is
+ -- True.
- elsif Is_Protected_Type (Id) then
+ elsif Is_Protected_Type (Id) and then not Ignore_Protected then
return True;
-- A descendant of Ada.Synchronous_Task_Control.Suspension_Object is
@@ -16644,7 +16651,7 @@ package body Sem_Util is
and then not
(Ekind (Id) = E_Variable and then No_Caching_Enabled (Id)))
or else Has_Volatile_Components (Id)
- or else Is_Effectively_Volatile (Etype (Id));
+ or else Is_Effectively_Volatile (Etype (Id), Ignore_Protected);
end if;
end Is_Effectively_Volatile;
@@ -16653,15 +16660,19 @@ package body Sem_Util is
-----------------------------------------
function Is_Effectively_Volatile_For_Reading
- (Id : Entity_Id) return Boolean
+ (Id : Entity_Id;
+ Ignore_Protected : Boolean := False) return Boolean
is
begin
- -- A concurrent type is effectively volatile for reading
+ -- A concurrent type is effectively volatile for reading, except for a
+ -- protected type when Ignore_Protected is True.
- if Is_Concurrent_Type (Id) then
+ if Is_Task_Type (Id)
+ or else (Is_Protected_Type (Id) and then not Ignore_Protected)
+ then
return True;
- elsif Is_Effectively_Volatile (Id) then
+ elsif Is_Effectively_Volatile (Id, Ignore_Protected) then
-- Other volatile types and objects are effectively volatile for
-- reading when they have property Async_Writers or Effective_Reads
@@ -16689,10 +16700,9 @@ package body Sem_Util is
-- Test for presence of ancestor, as the full view of a
-- private type may be missing in case of error.
- return
- Present (Anc)
- and then Is_Effectively_Volatile_For_Reading
- (Component_Type (Anc));
+ return Present (Anc)
+ and then Is_Effectively_Volatile_For_Reading
+ (Component_Type (Anc), Ignore_Protected);
end;
end if;
end if;
@@ -16706,6 +16716,9 @@ package body Sem_Util is
------------------------------------
function Is_Effectively_Volatile_Object (N : Node_Id) return Boolean is
+ function Is_Effectively_Volatile (E : Entity_Id) return Boolean is
+ (Is_Effectively_Volatile (E, Ignore_Protected => False));
+
function Is_Effectively_Volatile_Object_Inst
is new Is_Effectively_Volatile_Object_Shared (Is_Effectively_Volatile);
begin
@@ -16719,6 +16732,10 @@ package body Sem_Util is
function Is_Effectively_Volatile_Object_For_Reading
(N : Node_Id) return Boolean
is
+ function Is_Effectively_Volatile_For_Reading
+ (E : Entity_Id) return Boolean
+ is (Is_Effectively_Volatile_For_Reading (E, Ignore_Protected => False));
+
function Is_Effectively_Volatile_Object_For_Reading_Inst
is new Is_Effectively_Volatile_Object_Shared
(Is_Effectively_Volatile_For_Reading);
@@ -18311,7 +18328,10 @@ package body Sem_Util is
-- In Ada 95 an aggregate is an object reference
- when N_Aggregate =>
+ when N_Aggregate
+ | N_Delta_Aggregate
+ | N_Extension_Aggregate
+ =>
return Ada_Version >= Ada_95;
-- A string literal is not an object reference, but it might come
@@ -20434,8 +20454,7 @@ package body Sem_Util is
elsif Nkind (P) = N_Type_Conversion
and then not Comes_From_Source (P)
- and then Is_Array_Type (Etype (P))
- and then Is_Packed (Etype (P))
+ and then Is_Packed_Array (Etype (P))
then
return Is_Variable (Expression (P));
@@ -22439,11 +22458,7 @@ package body Sem_Util is
function Search_Decl (N : Node_Id) return Traverse_Result is
begin
if Nkind (N) in N_Declaration then
- if No (Decls) then
- Decls := New_Elmt_List;
- end if;
-
- Append_Elmt (N, Decls);
+ Append_New_Elmt (N, Decls);
end if;
return OK;
@@ -25455,7 +25470,7 @@ package body Sem_Util is
-- All other cases do not require a transient scope
else
- pragma Assert (Is_Protected_Type (Typ) or else Is_Task_Type (Typ));
+ pragma Assert (Is_Concurrent_Type (Typ));
return False;
end if;
end Old_Requires_Transient_Scope;
@@ -25678,7 +25693,7 @@ package body Sem_Util is
end if;
end if;
- return (Empty);
+ return Empty;
end Param_Entity;
----------------------
@@ -26169,7 +26184,8 @@ package body Sem_Util is
(Typ : Entity_Id;
From_Typ : Entity_Id)
is
- DIC_Proc : Entity_Id;
+ DIC_Proc : Entity_Id;
+ Partial_DIC_Proc : Entity_Id;
begin
if Present (Typ) and then Present (From_Typ) then
@@ -26190,6 +26206,7 @@ package body Sem_Util is
end if;
DIC_Proc := DIC_Procedure (From_Typ);
+ Partial_DIC_Proc := Partial_DIC_Procedure (From_Typ);
-- The setting of the attributes is intentionally conservative. This
-- prevents accidental clobbering of enabled attributes.
@@ -26205,6 +26222,12 @@ package body Sem_Util is
if Present (DIC_Proc) and then No (DIC_Procedure (Typ)) then
Set_DIC_Procedure (Typ, DIC_Proc);
end if;
+
+ if Present (Partial_DIC_Proc)
+ and then No (Partial_DIC_Procedure (Typ))
+ then
+ Set_Partial_DIC_Procedure (Typ, Partial_DIC_Proc);
+ end if;
end if;
end Propagate_DIC_Attributes;
@@ -26245,7 +26268,7 @@ package body Sem_Util is
end if;
if Has_Own_Invariants (From_Typ) then
- Set_Has_Own_Invariants (Typ);
+ Set_Has_Own_Invariants (Base_Type (Typ));
end if;
if Present (Full_IP) and then No (Invariant_Procedure (Typ)) then
@@ -27583,8 +27606,6 @@ package body Sem_Util is
Style.Check_Identifier (Nod, Val_Actual);
end if;
end if;
-
- Set_Entity (N, Val);
end Set_Entity_With_Checks;
------------------------------
diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
index 1b993f9..b2af43a 100644
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -1503,9 +1503,7 @@ package Sem_Util is
function Has_Tagged_Component (Typ : Entity_Id) return Boolean;
-- Returns True if Typ is a composite type (array or record) that is either
-- a tagged type or has a subcomponent that is tagged. Returns False for a
- -- noncomposite type, or if no tagged subcomponents are present. This
- -- function is used to check if "=" has to be expanded into a bunch
- -- component comparisons.
+ -- noncomposite type, or if no tagged subcomponents are present.
function Has_Unconstrained_Access_Discriminants
(Subtyp : Entity_Id) return Boolean;
@@ -1879,7 +1877,9 @@ package Sem_Util is
-- . machine_emax = 2**10
-- . machine_emin = 3 - machine_emax
- function Is_Effectively_Volatile (Id : Entity_Id) return Boolean;
+ function Is_Effectively_Volatile
+ (Id : Entity_Id;
+ Ignore_Protected : Boolean := False) 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 without No_Caching
@@ -1887,9 +1887,14 @@ package Sem_Util is
-- * An array type whose component type is effectively volatile
-- * A protected type
-- * Descendant of type Ada.Synchronous_Task_Control.Suspension_Object
+ --
+ -- If Ignore_Protected is True, then a protected object/type is treated
+ -- like a non-protected record object/type for computing the result of
+ -- this query.
function Is_Effectively_Volatile_For_Reading
- (Id : Entity_Id) return Boolean;
+ (Id : Entity_Id;
+ Ignore_Protected : Boolean := False) return Boolean;
-- Determine whether a type or object denoted by entity Id is effectively
-- volatile for reading (SPARK RM 7.1.2). To qualify as such, the entity
-- must be either
@@ -1901,6 +1906,10 @@ package Sem_Util is
-- reading
-- * A protected type
-- * Descendant of type Ada.Synchronous_Task_Control.Suspension_Object
+ --
+ -- If Ignore_Protected is True, then a protected object/type is treated
+ -- like a non-protected record object/type for computing the result of
+ -- this query.
function Is_Effectively_Volatile_Object
(N : Node_Id) return Boolean;
diff --git a/gcc/ada/sinfo.adb b/gcc/ada/sinfo.adb
index c88d9a9..2d0a957 100644
--- a/gcc/ada/sinfo.adb
+++ b/gcc/ada/sinfo.adb
@@ -3535,6 +3535,14 @@ package body Sinfo is
return Flag2 (N);
end Was_Attribute_Reference;
+ function Was_Default_Init_Box_Association
+ (N : Node_Id) return Boolean is
+ begin
+ pragma Assert (False
+ or else NT (N).Nkind = N_Component_Association);
+ return Flag14 (N);
+ end Was_Default_Init_Box_Association;
+
function Was_Expression_Function
(N : Node_Id) return Boolean is
begin
@@ -7036,6 +7044,14 @@ package body Sinfo is
Set_Flag2 (N, Val);
end Set_Was_Attribute_Reference;
+ procedure Set_Was_Default_Init_Box_Association
+ (N : Node_Id; Val : Boolean := True) is
+ begin
+ pragma Assert (False
+ or else NT (N).Nkind = N_Component_Association);
+ Set_Flag14 (N, Val);
+ end Set_Was_Default_Init_Box_Association;
+
procedure Set_Was_Expression_Function
(N : Node_Id; Val : Boolean := True) is
begin
diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads
index 439eef4..f9b0667 100644
--- a/gcc/ada/sinfo.ads
+++ b/gcc/ada/sinfo.ads
@@ -2412,6 +2412,11 @@ package Sinfo is
-- instantiation prologue renames these attributes, and expansion later
-- converts them into subprogram bodies.
+ -- Was_Default_Init_Box_Association (Flag14-Sem)
+ -- Present in N_Component_Association. Set to True if the original source
+ -- is an aggregate component association with a box (<>) for a component
+ -- that is initialized by default.
+
-- Was_Expression_Function (Flag18-Sem)
-- Present in N_Subprogram_Body. True if the original source had an
-- N_Expression_Function, which was converted to the N_Subprogram_Body
@@ -4120,6 +4125,7 @@ package Sinfo is
-- Expression (Node3) (empty if Box_Present)
-- Loop_Actions (List5-Sem)
-- Box_Present (Flag15)
+ -- Was_Default_Init_Box_Association (Flag14)
-- Inherited_Discriminant (Flag13)
-- Note: this structure is used for both record component associations
@@ -4128,7 +4134,9 @@ package Sinfo is
-- list of selector names in the record aggregate case, or a list of
-- discrete choices in the array aggregate case or an N_Others_Choice
-- node (which appears as a singleton list). Box_Present gives support
- -- to Ada 2005 (AI-287).
+ -- to Ada 2005 (AI-287). Was_Default_Init_Box_Association is used for
+ -- determining the need for Default_Initial_Condition check on component
+ -- associations with a box.
----------------------------------
-- 4.3.1 Component Choice List --
@@ -10254,6 +10262,9 @@ package Sinfo is
function Was_Attribute_Reference
(N : Node_Id) return Boolean; -- Flag2
+ function Was_Default_Init_Box_Association
+ (N : Node_Id) return Boolean; -- Flag14
+
function Was_Expression_Function
(N : Node_Id) return Boolean; -- Flag18
@@ -11366,6 +11377,9 @@ package Sinfo is
procedure Set_Was_Attribute_Reference
(N : Node_Id; Val : Boolean := True); -- Flag2
+ procedure Set_Was_Default_Init_Box_Association
+ (N : Node_Id; Val : Boolean := True); -- Flag14
+
procedure Set_Was_Expression_Function
(N : Node_Id; Val : Boolean := True); -- Flag18
@@ -13477,6 +13491,7 @@ package Sinfo is
pragma Inline (Visible_Declarations);
pragma Inline (Used_Operations);
pragma Inline (Was_Attribute_Reference);
+ pragma Inline (Was_Default_Init_Box_Association);
pragma Inline (Was_Expression_Function);
pragma Inline (Was_Originally_Stub);
@@ -13842,6 +13857,7 @@ package Sinfo is
pragma Inline (Set_Variants);
pragma Inline (Set_Visible_Declarations);
pragma Inline (Set_Was_Attribute_Reference);
+ pragma Inline (Set_Was_Default_Init_Box_Association);
pragma Inline (Set_Was_Expression_Function);
pragma Inline (Set_Was_Originally_Stub);
diff --git a/gcc/ada/snames.ads-tmpl b/gcc/ada/snames.ads-tmpl
index a9fd7c5..647fb62 100644
--- a/gcc/ada/snames.ads-tmpl
+++ b/gcc/ada/snames.ads-tmpl
@@ -147,6 +147,7 @@ package Snames is
Name_Integer_Literal : constant Name_Id := N + $;
Name_Real_Literal : constant Name_Id := N + $;
Name_Relaxed_Initialization : constant Name_Id := N + $;
+ Name_Stable_Properties : constant Name_Id := N + $;
Name_Static_Predicate : constant Name_Id := N + $;
Name_String_Literal : constant Name_Id := N + $;
Name_Synchronization : constant Name_Id := N + $;
@@ -756,8 +757,9 @@ package Snames is
Name_DLL : constant Name_Id := N + $;
Name_Win32 : constant Name_Id := N + $;
- -- Other special names used in processing attributes and pragmas
+ -- Other special names used in processing attributes, aspects, and pragmas
+ Name_Aggregate : constant Name_Id := N + $;
Name_Allow : constant Name_Id := N + $;
Name_Amount : constant Name_Id := N + $;
Name_As_Is : constant Name_Id := N + $;
@@ -839,9 +841,12 @@ package Snames is
Name_No_Use_Of_Entity : constant Name_Id := N + $;
Name_No_Use_Of_Pragma : constant Name_Id := N + $;
Name_No_Unroll : constant Name_Id := N + $;
+ Name_No_Unrecognized_Aspects : constant Name_Id := N + $;
+ Name_No_Unrecognized_Pragmas : constant Name_Id := N + $;
Name_No_Vector : constant Name_Id := N + $;
Name_Nominal : constant Name_Id := N + $;
Name_Non_Volatile : constant Name_Id := N + $;
+ Name_None : constant Name_Id := N + $;
Name_On : constant Name_Id := N + $;
Name_Optional : constant Name_Id := N + $;
Name_Policy : constant Name_Id := N + $;
@@ -1019,6 +1024,8 @@ package Snames is
Name_Signed_Zeros : constant Name_Id := N + $;
Name_Size : constant Name_Id := N + $;
Name_Small : constant Name_Id := N + $; -- Ada 83
+ Name_Small_Denominator : constant Name_Id := N + $; -- GNAT
+ Name_Small_Numerator : constant Name_Id := N + $; -- GNAT
Name_Storage_Size : constant Name_Id := N + $;
Name_Storage_Unit : constant Name_Id := N + $; -- GNAT
Name_Stream_Size : constant Name_Id := N + $; -- Ada 05
@@ -1356,186 +1363,17 @@ package Snames is
Name_Raise_Exception : constant Name_Id := N + $;
- -- Additional reserved words and identifiers used in GNAT Project Files
- -- Note that Name_External is already previously declared.
-
- -- Names with a -- GB annotation are only used in gprbuild or gprclean
-
- Name_Active : constant Name_Id := N + $;
- Name_Aggregate : constant Name_Id := N + $;
- Name_Archive_Builder : constant Name_Id := N + $;
- Name_Archive_Builder_Append_Option : constant Name_Id := N + $;
- Name_Archive_Indexer : constant Name_Id := N + $;
- Name_Archive_Suffix : constant Name_Id := N + $;
- Name_Artifacts : constant Name_Id := N + $;
- Name_Artifacts_In_Exec_Dir : constant Name_Id := N + $; -- GB
- Name_Artifacts_In_Object_Dir : constant Name_Id := N + $; -- GB
- Name_Binder : constant Name_Id := N + $;
- Name_Body_Suffix : constant Name_Id := N + $;
- Name_Builder : constant Name_Id := N + $;
- Name_Clean : constant Name_Id := N + $;
- Name_Compiler : constant Name_Id := N + $;
- Name_Compiler_Command : constant Name_Id := N + $; -- GB
- Name_Config_Body_File_Name : constant Name_Id := N + $;
- Name_Config_Body_File_Name_Index : constant Name_Id := N + $;
- Name_Config_Body_File_Name_Pattern : constant Name_Id := N + $;
- Name_Config_File_Switches : constant Name_Id := N + $;
- Name_Config_File_Unique : constant Name_Id := N + $;
- Name_Config_Spec_File_Name : constant Name_Id := N + $;
- Name_Config_Spec_File_Name_Index : constant Name_Id := N + $;
- Name_Config_Spec_File_Name_Pattern : constant Name_Id := N + $;
- Name_Configuration : constant Name_Id := N + $;
- Name_Cross_Reference : constant Name_Id := N + $;
- Name_Default_Language : constant Name_Id := N + $;
- Name_Default_Switches : constant Name_Id := N + $;
- Name_Dependency_Driver : constant Name_Id := N + $;
- Name_Dependency_Kind : constant Name_Id := N + $;
- Name_Dependency_Switches : constant Name_Id := N + $;
- Name_Driver : constant Name_Id := N + $;
- Name_Excluded_Source_Dirs : constant Name_Id := N + $;
- Name_Excluded_Source_Files : constant Name_Id := N + $;
- Name_Excluded_Source_List_File : constant Name_Id := N + $;
- Name_Exec_Dir : constant Name_Id := N + $;
- Name_Exec_Subdir : constant Name_Id := N + $;
- Name_Excluded_Patterns : constant Name_Id := N + $;
- Name_Executable : constant Name_Id := N + $;
- Name_Executable_Suffix : constant Name_Id := N + $;
- Name_Extends : constant Name_Id := N + $;
- Name_External_As_List : constant Name_Id := N + $;
- Name_Externally_Built : constant Name_Id := N + $;
- Name_Finder : constant Name_Id := N + $;
- Name_Global_Compilation_Switches : constant Name_Id := N + $;
- Name_Global_Configuration_Pragmas : constant Name_Id := N + $;
- Name_Global_Config_File : constant Name_Id := N + $; -- GB
- Name_Gnatls : constant Name_Id := N + $;
- Name_Gnatstub : constant Name_Id := N + $;
- Name_Gnu : constant Name_Id := N + $;
- Name_Ide : constant Name_Id := N + $;
- Name_Ignore_Source_Sub_Dirs : constant Name_Id := N + $;
- Name_Implementation : constant Name_Id := N + $;
- Name_Implementation_Exceptions : constant Name_Id := N + $;
- Name_Implementation_Suffix : constant Name_Id := N + $;
- Name_Included_Artifact_Patterns : constant Name_Id := N + $;
- Name_Included_Patterns : constant Name_Id := N + $;
- Name_Include_Switches : constant Name_Id := N + $;
- Name_Include_Path : constant Name_Id := N + $;
- Name_Include_Path_File : constant Name_Id := N + $;
- Name_Inherit_Source_Path : constant Name_Id := N + $;
- Name_Install : constant Name_Id := N + $;
- Name_Install_Name : constant Name_Id := N + $;
- Name_Languages : constant Name_Id := N + $;
- Name_Language_Kind : constant Name_Id := N + $;
- Name_Leading_Library_Options : constant Name_Id := N + $;
- Name_Leading_Required_Switches : constant Name_Id := N + $;
- Name_Leading_Switches : constant Name_Id := N + $;
- Name_Lib_Subdir : constant Name_Id := N + $;
- Name_Link_Lib_Subdir : constant Name_Id := N + $;
- Name_Library : constant Name_Id := N + $;
- Name_Library_Ali_Dir : constant Name_Id := N + $;
- Name_Library_Auto_Init : constant Name_Id := N + $;
- Name_Library_Auto_Init_Supported : constant Name_Id := N + $;
- Name_Library_Builder : constant Name_Id := N + $;
- Name_Library_Dir : constant Name_Id := N + $;
- Name_Library_GCC : constant Name_Id := N + $;
- Name_Library_Install_Name_Option : constant Name_Id := N + $;
- Name_Library_Interface : constant Name_Id := N + $;
- Name_Library_Kind : constant Name_Id := N + $;
- Name_Library_Name : constant Name_Id := N + $;
- Name_Library_Major_Minor_Id_Supported : constant Name_Id := N + $;
- Name_Library_Options : constant Name_Id := N + $;
- Name_Library_Partial_Linker : constant Name_Id := N + $;
- Name_Library_Reference_Symbol_File : constant Name_Id := N + $;
- Name_Library_Rpath_Options : constant Name_Id := N + $; -- GB
- Name_Library_Standalone : constant Name_Id := N + $;
- Name_Library_Encapsulated_Options : constant Name_Id := N + $; -- GB
- Name_Library_Encapsulated_Supported : constant Name_Id := N + $; -- GB
- Name_Library_Src_Dir : constant Name_Id := N + $;
- Name_Library_Support : constant Name_Id := N + $;
- Name_Library_Symbol_File : constant Name_Id := N + $;
- Name_Library_Symbol_Policy : constant Name_Id := N + $;
- Name_Library_Version : constant Name_Id := N + $;
- Name_Library_Version_Switches : constant Name_Id := N + $;
- Name_Linker : constant Name_Id := N + $;
- Name_Linker_Executable_Option : constant Name_Id := N + $;
- Name_Linker_Lib_Dir_Option : constant Name_Id := N + $;
- Name_Linker_Lib_Name_Option : constant Name_Id := N + $;
- Name_Local_Config_File : constant Name_Id := N + $; -- GB
- Name_Local_Configuration_Pragmas : constant Name_Id := N + $;
- Name_Locally_Removed_Files : constant Name_Id := N + $;
- Name_Map_File_Option : constant Name_Id := N + $;
- Name_Mapping_File_Switches : constant Name_Id := N + $;
- Name_Mapping_Spec_Suffix : constant Name_Id := N + $;
- Name_Mapping_Body_Suffix : constant Name_Id := N + $;
- Name_Max_Command_Line_Length : constant Name_Id := N + $;
- Name_Metrics : constant Name_Id := N + $;
- Name_Multi_Unit_Object_Separator : constant Name_Id := N + $;
- Name_Multi_Unit_Switches : constant Name_Id := N + $;
- Name_Naming : constant Name_Id := N + $;
- Name_None : constant Name_Id := N + $;
- Name_Object_Artifact_Extensions : constant Name_Id := N + $;
- Name_Object_File_Suffix : constant Name_Id := N + $;
- Name_Object_File_Switches : constant Name_Id := N + $;
- Name_Object_Generated : constant Name_Id := N + $;
- Name_Object_List : constant Name_Id := N + $;
- Name_Object_Path_Switches : constant Name_Id := N + $;
- Name_Objects_Linked : constant Name_Id := N + $;
- Name_Objects_Path : constant Name_Id := N + $;
- Name_Objects_Path_File : constant Name_Id := N + $;
- Name_Object_Dir : constant Name_Id := N + $;
- Name_Option_List : constant Name_Id := N + $;
- Name_Path_Syntax : constant Name_Id := N + $;
- Name_Pic_Option : constant Name_Id := N + $;
- Name_Pretty_Printer : constant Name_Id := N + $;
- Name_Prefix : constant Name_Id := N + $;
- Name_Project : constant Name_Id := N + $;
- Name_Project_Dir : constant Name_Id := N + $;
- Name_Project_Files : constant Name_Id := N + $;
- Name_Project_Path : constant Name_Id := N + $;
- Name_Project_Subdir : constant Name_Id := N + $;
- Name_Remote : constant Name_Id := N + $;
- Name_Required_Artifacts : constant Name_Id := N + $;
- Name_Response_File_Format : constant Name_Id := N + $;
- Name_Response_File_Switches : constant Name_Id := N + $;
- Name_Root_Dir : constant Name_Id := N + $;
- Name_Roots : constant Name_Id := N + $; -- GB
- Name_Required_Switches : constant Name_Id := N + $;
- Name_Run_Path_Option : constant Name_Id := N + $;
- Name_Run_Path_Origin : constant Name_Id := N + $;
- Name_Separate_Run_Path_Options : constant Name_Id := N + $;
- Name_Shared_Library_Minimum_Switches : constant Name_Id := N + $;
- Name_Shared_Library_Prefix : constant Name_Id := N + $;
- Name_Shared_Library_Suffix : constant Name_Id := N + $;
- Name_Separate_Suffix : constant Name_Id := N + $;
- Name_Source_Artifact_Extensions : constant Name_Id := N + $;
- Name_Source_Dirs : constant Name_Id := N + $;
- Name_Source_File_Switches : constant Name_Id := N + $;
- Name_Source_Files : constant Name_Id := N + $;
- Name_Source_List_File : constant Name_Id := N + $;
- Name_Sources_Subdir : constant Name_Id := N + $;
- Name_Spec : constant Name_Id := N + $;
- Name_Spec_Suffix : constant Name_Id := N + $;
- Name_Specification : constant Name_Id := N + $;
- Name_Specification_Exceptions : constant Name_Id := N + $;
- Name_Specification_Suffix : constant Name_Id := N + $;
- Name_Stack : constant Name_Id := N + $;
- Name_Switches : constant Name_Id := N + $;
- Name_Symbolic_Link_Supported : constant Name_Id := N + $;
- Name_Synchronize : constant Name_Id := N + $;
- Name_Toolchain_Description : constant Name_Id := N + $;
- Name_Toolchain_Version : constant Name_Id := N + $;
- Name_Trailing_Required_Switches : constant Name_Id := N + $;
- Name_Trailing_Switches : constant Name_Id := N + $;
- Name_Runtime_Library_Dir : constant Name_Id := N + $;
- Name_Runtime_Source_Dir : constant Name_Id := N + $;
-
-- Additional names used by the Repinfo unit
Name_Discriminant : constant Name_Id := N + $;
Name_Operands : constant Name_Id := N + $;
-- Other miscellaneous names used in front end
+ -- Note that the UP_ prefix means use the rest of the name in uppercase,
+ -- e.g. Name_UP_RESULT corresponds to the name "RESULT".
Name_Unaligned_Valid : constant Name_Id := N + $;
+ Name_UP_RESULT : constant Name_Id := N + $;
Name_Suspension_Object : constant Name_Id := N + $;
Name_Synchronous_Task_Control : constant Name_Id := N + $;
@@ -1715,6 +1553,8 @@ package Snames is
Attribute_Signed_Zeros,
Attribute_Size,
Attribute_Small,
+ Attribute_Small_Denominator,
+ Attribute_Small_Numerator,
Attribute_Storage_Size,
Attribute_Storage_Unit,
Attribute_Stream_Size,
diff --git a/gcc/ada/spark_xrefs.ads b/gcc/ada/spark_xrefs.ads
index 88a34c5..ffd7268 100644
--- a/gcc/ada/spark_xrefs.ads
+++ b/gcc/ada/spark_xrefs.ads
@@ -57,7 +57,8 @@ package SPARK_Xrefs is
Heap : Entity_Id := Empty;
-- A special entity which denotes the heap object; it should be considered
-- constant, but needs to be variable, because it can only be initialized
- -- after the node tables are created.
+ -- after the node tables are created. Also, it is only created if there is
+ -- an actual need for it, and remains Empty otherwise.
-----------------
-- Subprograms --
diff --git a/gcc/ada/stand.ads b/gcc/ada/stand.ads
index 5742e51..848239f 100644
--- a/gcc/ada/stand.ads
+++ b/gcc/ada/stand.ads
@@ -451,10 +451,11 @@ package Stand is
-- universal integer and universal real, it is never used for runtime
-- calculations).
- Standard_Integer_8 : Entity_Id;
- Standard_Integer_16 : Entity_Id;
- Standard_Integer_32 : Entity_Id;
- Standard_Integer_64 : Entity_Id;
+ Standard_Integer_8 : Entity_Id;
+ Standard_Integer_16 : Entity_Id;
+ Standard_Integer_32 : Entity_Id;
+ Standard_Integer_64 : Entity_Id;
+ Standard_Integer_128 : Entity_Id;
-- These are signed integer types with the indicated sizes. Used for the
-- underlying implementation types for fixed-point and enumeration types.
diff --git a/gcc/ada/switch-c.adb b/gcc/ada/switch-c.adb
index e086a5d..c6eb063 100644
--- a/gcc/ada/switch-c.adb
+++ b/gcc/ada/switch-c.adb
@@ -486,6 +486,12 @@ package body Switch.C is
Ptr := Ptr + 1;
Check_Aliasing_Of_Parameters := True;
+ -- -gnateb (config file basenames and checksums in ALI)
+
+ when 'b' =>
+ Ptr := Ptr + 1;
+ Config_Files_Store_Basename := True;
+
-- -gnatec (configuration pragmas)
when 'c' =>
diff --git a/gcc/ada/terminals.c b/gcc/ada/terminals.c
index 81388a7..ec9db3a 100644
--- a/gcc/ada/terminals.c
+++ b/gcc/ada/terminals.c
@@ -1244,7 +1244,7 @@ allocate_pty_desc (pty_desc **desc) {
result->slave_fd = slave_fd;
/* the string returned by ptsname or _getpty is a static allocated string. So
we should make a copy */
- strncpy (result->slave_name, slave_name, sizeof (result->slave_name));
+ strncpy (result->slave_name, slave_name, sizeof (result->slave_name) - 1);
result->slave_name[sizeof (result->slave_name) - 1] = '\0';
result->child_pid = -1;
*desc=result;
diff --git a/gcc/ada/uintp.ads b/gcc/ada/uintp.ads
index 648ee31..5f1f759 100644
--- a/gcc/ada/uintp.ads
+++ b/gcc/ada/uintp.ads
@@ -63,6 +63,7 @@ package Uintp is
Uint_15 : constant Uint;
Uint_16 : constant Uint;
Uint_24 : constant Uint;
+ Uint_31 : constant Uint;
Uint_32 : constant Uint;
Uint_63 : constant Uint;
Uint_64 : constant Uint;
@@ -80,9 +81,13 @@ package Uintp is
Uint_Minus_8 : constant Uint;
Uint_Minus_9 : constant Uint;
Uint_Minus_12 : constant Uint;
+ Uint_Minus_18 : constant Uint;
+ Uint_Minus_31 : constant Uint;
Uint_Minus_36 : constant Uint;
Uint_Minus_63 : constant Uint;
+ Uint_Minus_76 : constant Uint;
Uint_Minus_80 : constant Uint;
+ Uint_Minus_127 : constant Uint;
Uint_Minus_128 : constant Uint;
type UI_Vector is array (Pos range <>) of Int;
@@ -281,7 +286,7 @@ package Uintp is
-- or decimal format. Auto, the default setting, lets the routine make a
-- decision based on the value.
- UI_Image_Max : constant := 48; -- Enough for a 128-bit number
+ UI_Image_Max : constant := 1024;
UI_Image_Buffer : String (1 .. UI_Image_Max);
UI_Image_Length : Natural;
-- Buffer used for UI_Image as described below
@@ -470,6 +475,7 @@ private
Uint_15 : constant Uint := Uint (Uint_Direct_Bias + 15);
Uint_16 : constant Uint := Uint (Uint_Direct_Bias + 16);
Uint_24 : constant Uint := Uint (Uint_Direct_Bias + 24);
+ Uint_31 : constant Uint := Uint (Uint_Direct_Bias + 31);
Uint_32 : constant Uint := Uint (Uint_Direct_Bias + 32);
Uint_63 : constant Uint := Uint (Uint_Direct_Bias + 63);
Uint_64 : constant Uint := Uint (Uint_Direct_Bias + 64);
@@ -487,9 +493,13 @@ private
Uint_Minus_8 : constant Uint := Uint (Uint_Direct_Bias - 8);
Uint_Minus_9 : constant Uint := Uint (Uint_Direct_Bias - 9);
Uint_Minus_12 : constant Uint := Uint (Uint_Direct_Bias - 12);
+ Uint_Minus_18 : constant Uint := Uint (Uint_Direct_Bias - 18);
+ Uint_Minus_31 : constant Uint := Uint (Uint_Direct_Bias - 31);
Uint_Minus_36 : constant Uint := Uint (Uint_Direct_Bias - 36);
Uint_Minus_63 : constant Uint := Uint (Uint_Direct_Bias - 63);
+ Uint_Minus_76 : constant Uint := Uint (Uint_Direct_Bias - 76);
Uint_Minus_80 : constant Uint := Uint (Uint_Direct_Bias - 80);
+ Uint_Minus_127 : constant Uint := Uint (Uint_Direct_Bias - 127);
Uint_Minus_128 : constant Uint := Uint (Uint_Direct_Bias - 128);
Uint_Max_Simple_Mul : constant := Uint_Direct_Bias + 2**15;
diff --git a/gcc/ada/urealp.adb b/gcc/ada/urealp.adb
index f45f261..88cb681 100644
--- a/gcc/ada/urealp.adb
+++ b/gcc/ada/urealp.adb
@@ -73,20 +73,28 @@ package body Urealp is
-- The following universal reals are the values returned by the constant
-- functions. They are initialized by the initialization procedure.
- UR_0 : Ureal;
- UR_M_0 : Ureal;
- UR_Tenth : Ureal;
- UR_Half : Ureal;
- UR_1 : Ureal;
- UR_2 : Ureal;
- UR_10 : Ureal;
- UR_10_36 : Ureal;
- UR_M_10_36 : Ureal;
- UR_100 : Ureal;
- UR_2_128 : Ureal;
- UR_2_80 : Ureal;
- UR_2_M_128 : Ureal;
- UR_2_M_80 : Ureal;
+ UR_0 : Ureal;
+ UR_M_0 : Ureal;
+ UR_Tenth : Ureal;
+ UR_Half : Ureal;
+ UR_1 : Ureal;
+ UR_2 : Ureal;
+ UR_10 : Ureal;
+ UR_2_10_18 : Ureal;
+ UR_9_10_36 : Ureal;
+ UR_10_76 : Ureal;
+ UR_M_2_10_18 : Ureal;
+ UR_M_9_10_36 : Ureal;
+ UR_M_10_76 : Ureal;
+ UR_100 : Ureal;
+ UR_2_127 : Ureal;
+ UR_2_128 : Ureal;
+ UR_2_31 : Ureal;
+ UR_2_63 : Ureal;
+ UR_2_80 : Ureal;
+ UR_2_M_127 : Ureal;
+ UR_2_M_128 : Ureal;
+ UR_2_M_80 : Ureal;
Normalized_Real : Ureal := No_Ureal;
-- Used to memoize Norm_Num and Norm_Den, if either of these functions
@@ -288,20 +296,28 @@ package body Urealp is
procedure Initialize is
begin
Ureals.Init;
- UR_0 := UR_From_Components (Uint_0, Uint_1, 0, False);
- UR_M_0 := UR_From_Components (Uint_0, Uint_1, 0, True);
- UR_Half := UR_From_Components (Uint_1, Uint_1, 2, False);
- UR_Tenth := UR_From_Components (Uint_1, Uint_1, 10, False);
- UR_1 := UR_From_Components (Uint_1, Uint_1, 0, False);
- UR_2 := UR_From_Components (Uint_1, Uint_Minus_1, 2, False);
- UR_10 := UR_From_Components (Uint_1, Uint_Minus_1, 10, False);
- UR_10_36 := UR_From_Components (Uint_1, Uint_Minus_36, 10, False);
- UR_M_10_36 := UR_From_Components (Uint_1, Uint_Minus_36, 10, True);
- UR_100 := UR_From_Components (Uint_1, Uint_Minus_2, 10, False);
- UR_2_128 := UR_From_Components (Uint_1, Uint_Minus_128, 2, False);
- UR_2_M_128 := UR_From_Components (Uint_1, Uint_128, 2, False);
- UR_2_80 := UR_From_Components (Uint_1, Uint_Minus_80, 2, False);
- UR_2_M_80 := UR_From_Components (Uint_1, Uint_80, 2, False);
+ UR_0 := UR_From_Components (Uint_0, Uint_1, 0, False);
+ UR_M_0 := UR_From_Components (Uint_0, Uint_1, 0, True);
+ UR_Half := UR_From_Components (Uint_1, Uint_1, 2, False);
+ UR_Tenth := UR_From_Components (Uint_1, Uint_1, 10, False);
+ UR_1 := UR_From_Components (Uint_1, Uint_1, 0, False);
+ UR_2 := UR_From_Components (Uint_1, Uint_Minus_1, 2, False);
+ UR_10 := UR_From_Components (Uint_1, Uint_Minus_1, 10, False);
+ UR_2_10_18 := UR_From_Components (Uint_2, Uint_Minus_18, 10, False);
+ UR_9_10_36 := UR_From_Components (Uint_9, Uint_Minus_36, 10, False);
+ UR_10_76 := UR_From_Components (Uint_1, Uint_Minus_76, 10, False);
+ UR_M_2_10_18 := UR_From_Components (Uint_2, Uint_Minus_18, 10, True);
+ UR_M_9_10_36 := UR_From_Components (Uint_9, Uint_Minus_36, 10, True);
+ UR_M_10_76 := UR_From_Components (Uint_1, Uint_Minus_76, 10, True);
+ UR_100 := UR_From_Components (Uint_1, Uint_Minus_2, 10, False);
+ UR_2_127 := UR_From_Components (Uint_1, Uint_Minus_127, 2, False);
+ UR_2_M_127 := UR_From_Components (Uint_1, Uint_127, 2, False);
+ UR_2_128 := UR_From_Components (Uint_1, Uint_Minus_128, 2, False);
+ UR_2_M_128 := UR_From_Components (Uint_1, Uint_128, 2, False);
+ UR_2_31 := UR_From_Components (Uint_1, Uint_Minus_31, 2, False);
+ UR_2_63 := UR_From_Components (Uint_1, Uint_Minus_63, 2, False);
+ UR_2_80 := UR_From_Components (Uint_1, Uint_Minus_80, 2, False);
+ UR_2_M_80 := UR_From_Components (Uint_1, Uint_80, 2, False);
end Initialize;
----------------
@@ -1408,14 +1424,6 @@ package body Urealp is
UI_Write (Int (UI_Image_Length - 1) - Val.Den, Decimal);
end if;
- -- Constants in a base other than 10 can still be easily written in
- -- normal Ada literal style if the numerator is one.
-
- elsif Val.Rbase /= 0 and then Val.Num = 1 then
- Write_Int (Val.Rbase);
- Write_Str ("#1.0#E");
- UI_Write (-Val.Den);
-
-- Other constants with a base other than 10 are written using one of
-- the following forms, depending on the sign of the number and the
-- sign of the exponent (= minus denominator value). See that we are
@@ -1525,14 +1533,50 @@ package body Urealp is
return UR_100;
end Ureal_100;
+ -------------------
+ -- Ureal_2_10_18 --
+ -------------------
+
+ function Ureal_2_10_18 return Ureal is
+ begin
+ return UR_2_10_18;
+ end Ureal_2_10_18;
+
+ -------------------
+ -- Ureal_9_10_36 --
+ -------------------
+
+ function Ureal_9_10_36 return Ureal is
+ begin
+ return UR_9_10_36;
+ end Ureal_9_10_36;
+
-----------------
- -- Ureal_10_36 --
+ -- Ureal_10_76 --
-----------------
- function Ureal_10_36 return Ureal is
+ function Ureal_10_76 return Ureal is
+ begin
+ return UR_10_76;
+ end Ureal_10_76;
+
+ ----------------
+ -- Ureal_2_31 --
+ ----------------
+
+ function Ureal_2_31 return Ureal is
+ begin
+ return UR_2_31;
+ end Ureal_2_31;
+
+ ----------------
+ -- Ureal_2_63 --
+ ----------------
+
+ function Ureal_2_63 return Ureal is
begin
- return UR_10_36;
- end Ureal_10_36;
+ return UR_2_63;
+ end Ureal_2_63;
----------------
-- Ureal_2_80 --
@@ -1544,6 +1588,15 @@ package body Urealp is
end Ureal_2_80;
-----------------
+ -- Ureal_2_127 --
+ -----------------
+
+ function Ureal_2_127 return Ureal is
+ begin
+ return UR_2_127;
+ end Ureal_2_127;
+
+ -----------------
-- Ureal_2_128 --
-----------------
@@ -1562,6 +1615,15 @@ package body Urealp is
end Ureal_2_M_80;
-------------------
+ -- Ureal_2_M_127 --
+ -------------------
+
+ function Ureal_2_M_127 return Ureal is
+ begin
+ return UR_2_M_127;
+ end Ureal_2_M_127;
+
+ -------------------
-- Ureal_2_M_128 --
-------------------
@@ -1588,14 +1650,32 @@ package body Urealp is
return UR_M_0;
end Ureal_M_0;
+ ---------------------
+ -- Ureal_M_2_10_18 --
+ ---------------------
+
+ function Ureal_M_2_10_18 return Ureal is
+ begin
+ return UR_M_2_10_18;
+ end Ureal_M_2_10_18;
+
+ ---------------------
+ -- Ureal_M_9_10_36 --
+ ---------------------
+
+ function Ureal_M_9_10_36 return Ureal is
+ begin
+ return UR_M_9_10_36;
+ end Ureal_M_9_10_36;
+
-------------------
- -- Ureal_M_10_36 --
+ -- Ureal_M_10_76 --
-------------------
- function Ureal_M_10_36 return Ureal is
+ function Ureal_M_10_76 return Ureal is
begin
- return UR_M_10_36;
- end Ureal_M_10_36;
+ return UR_M_10_76;
+ end Ureal_M_10_76;
-----------------
-- Ureal_Tenth --
diff --git a/gcc/ada/urealp.ads b/gcc/ada/urealp.ads
index 5c511ef..3f74735 100644
--- a/gcc/ada/urealp.ads
+++ b/gcc/ada/urealp.ads
@@ -106,23 +106,47 @@ package Urealp is
function Ureal_100 return Ureal;
-- Returns value 100.0
+ function Ureal_2_31 return Ureal;
+ -- Returns value 2.0 ** 31
+
+ function Ureal_2_63 return Ureal;
+ -- Returns value 2.0 ** 63
+
function Ureal_2_80 return Ureal;
-- Returns value 2.0 ** 80
function Ureal_2_M_80 return Ureal;
-- Returns value 2.0 ** (-80)
+ function Ureal_2_127 return Ureal;
+ -- Returns value 2.0 ** 127
+
+ function Ureal_2_M_127 return Ureal;
+ -- Returns value 2.0 ** (-127)
+
function Ureal_2_128 return Ureal;
-- Returns value 2.0 ** 128
function Ureal_2_M_128 return Ureal;
-- Returns value 2.0 ** (-128)
- function Ureal_10_36 return Ureal;
- -- Returns value 10.0 ** 36
+ function Ureal_2_10_18 return Ureal;
+ -- Returns value 2.0 * 10.0 ** 18
+
+ function Ureal_M_2_10_18 return Ureal;
+ -- Returns value -2.0 * 10.0 ** 18
+
+ function Ureal_9_10_36 return Ureal;
+ -- Returns value 9.0 * 10.0 ** 36
+
+ function Ureal_M_9_10_36 return Ureal;
+ -- Returns value -9.0 * 10.0 ** 36
+
+ function Ureal_10_76 return Ureal;
+ -- Returns value 10.0 ** 76
- function Ureal_M_10_36 return Ureal;
- -- Returns value -10.0 ** 36
+ function Ureal_M_10_76 return Ureal;
+ -- Returns value -10.0 ** 76
-----------------
-- Subprograms --
diff --git a/gcc/ada/xsnamest.adb b/gcc/ada/xsnamest.adb
index 834d3c4..941e2e8 100644
--- a/gcc/ada/xsnamest.adb
+++ b/gcc/ada/xsnamest.adb
@@ -260,11 +260,14 @@ begin
Replace (M, Translate (A, Xlate_U_Und));
Translate (Name0, Lower_Case_Map);
- elsif not Match (Name0, "Op_", "") then
- Translate (Name0, Lower_Case_Map);
+ elsif Match (Name0, "UP_", "") then
+ Translate (Name0, Upper_Case_Map);
- else
+ elsif Match (Name0, "Op_", "") then
Name0 := 'O' & Translate (Name0, Lower_Case_Map);
+
+ else
+ Translate (Name0, Lower_Case_Map);
end if;
if not Match (Name0, Chk_Low) then
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index 44847ed..971ed47 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,87 @@
+2020-11-30 David Malcolm <dmalcolm@redhat.com>
+
+ * analyzer-pass.cc: Include "analyzer/analyzer.h" for the
+ declaration of sorry_no_analyzer; include "tree.h" and
+ "function.h" as these are needed by it.
+
+2020-11-30 David Malcolm <dmalcolm@redhat.com>
+
+ * analyzer-pass.cc (pass_analyzer::execute): Move sorry call to...
+ (sorry_no_analyzer): New.
+ * analyzer.h (class state_machine): New forward decl.
+ (class logger): New forward decl.
+ (class plugin_analyzer_init_iface): New.
+ (sorry_no_analyzer): New decl.
+ * checker-path.cc (checker_path::fixup_locations): New.
+ * checker-path.h (checker_event::set_location): New.
+ (checker_path::fixup_locations): New decl.
+ * diagnostic-manager.cc
+ (diagnostic_manager::emit_saved_diagnostic): Call
+ checker_path::fixup_locations, and call fixup_location
+ on the primary location.
+ * engine.cc: Include "plugin.h".
+ (class plugin_analyzer_init_impl): New.
+ (impl_run_checkers): Invoke PLUGIN_ANALYZER_INIT callbacks.
+ * pending-diagnostic.h (pending_diagnostic::fixup_location): New
+ vfunc.
+
+2020-11-18 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/97893
+ * sm-malloc.cc (null_deref::emit): Use CWE-476 rather than
+ CWE-690, as this isn't due to an unchecked return value.
+ (null_arg::emit): Likewise.
+
+2020-11-12 David Malcolm <dmalcolm@redhat.com>
+
+ * checker-path.h (checker_event::get_id_ptr): New.
+ * diagnostic-manager.cc (path_builder::path_builder): Add "sd"
+ param and use it to initialize new field "m_sd".
+ (path_builder::get_pending_diagnostic): New.
+ (path_builder::m_sd): New field.
+ (diagnostic_manager::emit_saved_diagnostic): Pass sd to
+ path_builder ctor.
+ (diagnostic_manager::add_events_for_superedge): Call new
+ maybe_add_custom_events_for_superedge vfunc.
+ * engine.cc (stale_jmp_buf::stale_jmp_buf): Add "setjmp_point"
+ param and use it to initialize new field "m_setjmp_point".
+ Initialize new field "m_stack_pop_event".
+ (stale_jmp_buf::maybe_add_custom_events_for_superedge): New vfunc
+ implementation.
+ (stale_jmp_buf::describe_final_event): New vfunc implementation.
+ (stale_jmp_buf::m_setjmp_point): New field.
+ (stale_jmp_buf::m_stack_pop_event): New field.
+ (exploded_node::on_longjmp): Pass setjmp_point to stale_jmp_buf
+ ctor.
+ * pending-diagnostic.h
+ (pending_diagnostic::maybe_add_custom_events_for_superedge): New
+ vfunc.
+
+2020-11-12 David Malcolm <dmalcolm@redhat.com>
+
+ PR tree-optimization/97424
+ * analyzer.opt (Wanalyzer-shift-count-negative): New.
+ (Wanalyzer-shift-count-overflow): New.
+ * region-model.cc (class shift_count_negative_diagnostic): New.
+ (class shift_count_overflow_diagnostic): New.
+ (region_model::get_gassign_result): Complain about shift counts that
+ are negative or are >= the operand's type's width.
+
+2020-11-10 Martin Liska <mliska@suse.cz>
+
+ * constraint-manager.cc (constraint_manager::merge): Remove
+ unused code.
+ * constraint-manager.h: Likewise.
+ * program-state.cc (sm_state_map::sm_state_map): Likewise.
+ (program_state::program_state): Likewise.
+ (test_sm_state_map): Likewise.
+ * program-state.h: Likewise.
+ * region-model-reachability.cc (reachable_regions::reachable_regions): Likewise.
+ * region-model-reachability.h: Likewise.
+ * region-model.cc (region_model::handle_unrecognized_call): Likewise.
+ (region_model::get_reachable_svalues): Likewise.
+ (region_model::can_merge_with_p): Likewise.
+
2020-11-05 David Malcolm <dmalcolm@redhat.com>
PR analyzer/97668
diff --git a/gcc/analyzer/analyzer-pass.cc b/gcc/analyzer/analyzer-pass.cc
index a27421e..333f87b 100644
--- a/gcc/analyzer/analyzer-pass.cc
+++ b/gcc/analyzer/analyzer-pass.cc
@@ -25,6 +25,9 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "diagnostic.h"
#include "options.h"
+#include "tree.h"
+#include "function.h"
+#include "analyzer/analyzer.h"
#include "analyzer/engine.h"
namespace {
@@ -83,9 +86,7 @@ pass_analyzer::execute (function *)
#if ENABLE_ANALYZER
ana::run_checkers ();
#else
- sorry ("%qs was not enabled in this build of GCC"
- " (missing configure-time option %qs)",
- "-fanalyzer", "--enable-analyzer");
+ sorry_no_analyzer ();
#endif
return 0;
@@ -100,3 +101,17 @@ make_pass_analyzer (gcc::context *ctxt)
{
return new pass_analyzer (ctxt);
}
+
+#if !ENABLE_ANALYZER
+
+/* Issue a "sorry" diagnostic that the analyzer was not enabled. */
+
+void
+sorry_no_analyzer ()
+{
+ sorry ("%qs was not enabled in this build of GCC"
+ " (missing configure-time option %qs)",
+ "-fanalyzer", "--enable-analyzer");
+}
+
+#endif /* #if !ENABLE_ANALYZER */
diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index c84d7fd..cd46bfc 100644
--- a/gcc/analyzer/analyzer.h
+++ b/gcc/analyzer/analyzer.h
@@ -189,6 +189,15 @@ private:
extern location_t get_stmt_location (const gimple *stmt, function *fun);
+/* Passed by pointer to PLUGIN_ANALYZER_INIT callbacks. */
+
+class plugin_analyzer_init_iface
+{
+public:
+ virtual void register_state_machine (state_machine *) = 0;
+ virtual logger *get_logger () const = 0;
+};
+
} // namespace ana
extern bool is_special_named_call_p (const gcall *call, const char *funcname,
@@ -309,4 +318,8 @@ private:
#pragma GCC diagnostic ignored "-Wformat-diag"
#endif
+#if !ENABLE_ANALYZER
+extern void sorry_no_analyzer ();
+#endif /* #if !ENABLE_ANALYZER */
+
#endif /* GCC_ANALYZER_ANALYZER_H */
diff --git a/gcc/analyzer/analyzer.opt b/gcc/analyzer/analyzer.opt
index c9df6dc..bbf9e42 100644
--- a/gcc/analyzer/analyzer.opt
+++ b/gcc/analyzer/analyzer.opt
@@ -98,6 +98,14 @@ Wanalyzer-null-dereference
Common Var(warn_analyzer_null_dereference) Init(1) Warning
Warn about code paths in which a NULL pointer is dereferenced.
+Wanalyzer-shift-count-negative
+Common Var(warn_analyzer_shift_count_negative) Init(1) Warning
+Warn about code paths in which a shift with negative count is attempted.
+
+Wanalyzer-shift-count-overflow
+Common Var(warn_analyzer_shift_count_overflow) Init(1) Warning
+Warn about code paths in which a shift with count >= width of type is attempted.
+
Wanalyzer-stale-setjmp-buffer
Common Var(warn_analyzer_stale_setjmp_buffer) Init(1) Warning
Warn about code paths in which a longjmp rewinds to a jmp_buf saved in a stack frame that has returned.
diff --git a/gcc/analyzer/checker-path.cc b/gcc/analyzer/checker-path.cc
index 1f6d6a8..062730c 100644
--- a/gcc/analyzer/checker-path.cc
+++ b/gcc/analyzer/checker-path.cc
@@ -982,6 +982,15 @@ checker_path::add_final_event (const state_machine *sm,
add_event (end_of_path);
}
+void
+checker_path::fixup_locations (pending_diagnostic *pd)
+{
+ checker_event *e;
+ int i;
+ FOR_EACH_VEC_ELT (m_events, i, e)
+ e->set_location (pd->fixup_location (e->get_location ()));
+}
+
} // namespace ana
#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/checker-path.h b/gcc/analyzer/checker-path.h
index 7b86d48..79553ba 100644
--- a/gcc/analyzer/checker-path.h
+++ b/gcc/analyzer/checker-path.h
@@ -97,8 +97,16 @@ public:
virtual bool is_function_entry_p () const { return false; }
virtual bool is_return_p () const { return false; }
+ /* For use with %@. */
+ const diagnostic_event_id_t *get_id_ptr () const
+ {
+ return &m_emission_id;
+ }
+
void dump (pretty_printer *pp) const;
+ void set_location (location_t loc) { m_loc = loc; }
+
public:
const enum event_kind m_kind;
protected:
@@ -498,6 +506,8 @@ public:
e->prepare_for_emission (this, pd, diagnostic_event_id_t (i));
}
+ void fixup_locations (pending_diagnostic *pd);
+
void record_setjmp_event (const exploded_node *enode,
diagnostic_event_id_t setjmp_emission_id)
{
diff --git a/gcc/analyzer/constraint-manager.cc b/gcc/analyzer/constraint-manager.cc
index 2978f1b..590bf32 100644
--- a/gcc/analyzer/constraint-manager.cc
+++ b/gcc/analyzer/constraint-manager.cc
@@ -1790,9 +1790,8 @@ class merger_fact_visitor : public fact_visitor
{
public:
merger_fact_visitor (const constraint_manager *cm_b,
- constraint_manager *out,
- const model_merger &merger)
- : m_cm_b (cm_b), m_out (out), m_merger (merger)
+ constraint_manager *out)
+ : m_cm_b (cm_b), m_out (out)
{}
void on_fact (const svalue *lhs, enum tree_code code, const svalue *rhs)
@@ -1826,7 +1825,6 @@ public:
private:
const constraint_manager *m_cm_b;
constraint_manager *m_out;
- const model_merger &m_merger;
};
/* Use MERGER to merge CM_A and CM_B into *OUT.
@@ -1838,14 +1836,13 @@ private:
void
constraint_manager::merge (const constraint_manager &cm_a,
const constraint_manager &cm_b,
- constraint_manager *out,
- const model_merger &merger)
+ constraint_manager *out)
{
/* Merge the equivalence classes and constraints.
The easiest way to do this seems to be to enumerate all of the facts
in cm_a, see which are also true in cm_b,
and add those to *OUT. */
- merger_fact_visitor v (&cm_b, out, merger);
+ merger_fact_visitor v (&cm_b, out);
cm_a.for_each_fact (&v);
}
diff --git a/gcc/analyzer/constraint-manager.h b/gcc/analyzer/constraint-manager.h
index 98960ff..1142b1f 100644
--- a/gcc/analyzer/constraint-manager.h
+++ b/gcc/analyzer/constraint-manager.h
@@ -274,8 +274,7 @@ public:
static void merge (const constraint_manager &cm_a,
const constraint_manager &cm_b,
- constraint_manager *out,
- const model_merger &merger);
+ constraint_manager *out);
void for_each_fact (fact_visitor *) const;
diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc
index 93f270f..9739ca6 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -161,15 +161,22 @@ class path_builder
public:
path_builder (const exploded_graph &eg,
const exploded_path &epath,
- const feasibility_problem *problem)
+ const feasibility_problem *problem,
+ const saved_diagnostic &sd)
: m_eg (eg),
m_diag_enode (epath.get_final_enode ()),
+ m_sd (sd),
m_reachability (eg, m_diag_enode),
m_feasibility_problem (problem)
{}
const exploded_node *get_diag_node () const { return m_diag_enode; }
+ pending_diagnostic *get_pending_diagnostic () const
+ {
+ return m_sd.m_d;
+ }
+
bool reachable_from_p (const exploded_node *src_enode) const
{
return m_reachability.reachable_from_p (src_enode);
@@ -190,6 +197,8 @@ private:
/* The enode where the diagnostic occurs. */
const exploded_node *m_diag_enode;
+ const saved_diagnostic &m_sd;
+
/* Precompute all enodes from which the diagnostic is reachable. */
enode_reachability m_reachability;
@@ -629,7 +638,7 @@ diagnostic_manager::emit_saved_diagnostic (const exploded_graph &eg,
pretty_printer *pp = global_dc->printer->clone ();
/* Precompute all enodes from which the diagnostic is reachable. */
- path_builder pb (eg, epath, sd.get_feasibility_problem ());
+ path_builder pb (eg, epath, sd.get_feasibility_problem (), sd);
/* This is the diagnostic_path subclass that will be built for
the diagnostic. */
@@ -656,7 +665,14 @@ diagnostic_manager::emit_saved_diagnostic (const exploded_graph &eg,
emission_path.prepare_for_emission (sd.m_d);
- gcc_rich_location rich_loc (get_stmt_location (stmt, sd.m_snode->m_fun));
+ location_t loc = get_stmt_location (stmt, sd.m_snode->m_fun);
+
+ /* Allow the pending_diagnostic to fix up the primary location
+ and any locations for events. */
+ loc = sd.m_d->fixup_location (loc);
+ emission_path.fixup_locations (sd.m_d);
+
+ gcc_rich_location rich_loc (loc);
rich_loc.set_path (&emission_path);
auto_diagnostic_group d;
@@ -1175,6 +1191,11 @@ diagnostic_manager::add_events_for_superedge (const path_builder &pb,
{
gcc_assert (eedge.m_sedge);
+ /* Give diagnostics an opportunity to override this function. */
+ pending_diagnostic *pd = pb.get_pending_diagnostic ();
+ if (pd->maybe_add_custom_events_for_superedge (eedge, emission_path))
+ return;
+
/* Don't add events for insignificant edges at verbosity levels below 3. */
if (m_verbosity < 3)
if (!significant_edge_p (pb, eedge))
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index d247ebb..d022b3a 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -63,6 +63,7 @@ along with GCC; see the file COPYING3. If not see
#include "analyzer/state-purge.h"
#include "analyzer/bar-chart.h"
#include <zlib.h>
+#include "plugin.h"
/* For an overview, see gcc/doc/analyzer.texi. */
@@ -1277,8 +1278,10 @@ valid_longjmp_stack_p (const program_point &longjmp_point,
class stale_jmp_buf : public pending_diagnostic_subclass<dump_path_diagnostic>
{
public:
- stale_jmp_buf (const gcall *setjmp_call, const gcall *longjmp_call)
- : m_setjmp_call (setjmp_call), m_longjmp_call (longjmp_call)
+ stale_jmp_buf (const gcall *setjmp_call, const gcall *longjmp_call,
+ const program_point &setjmp_point)
+ : m_setjmp_call (setjmp_call), m_longjmp_call (longjmp_call),
+ m_setjmp_point (setjmp_point), m_stack_pop_event (NULL)
{}
bool emit (rich_location *richloc) FINAL OVERRIDE
@@ -1299,9 +1302,56 @@ public:
&& m_longjmp_call == other.m_longjmp_call);
}
+ bool
+ maybe_add_custom_events_for_superedge (const exploded_edge &eedge,
+ checker_path *emission_path)
+ FINAL OVERRIDE
+ {
+ /* Detect exactly when the stack first becomes invalid,
+ and issue an event then. */
+ if (m_stack_pop_event)
+ return false;
+ const exploded_node *src_node = eedge.m_src;
+ const program_point &src_point = src_node->get_point ();
+ const exploded_node *dst_node = eedge.m_dest;
+ const program_point &dst_point = dst_node->get_point ();
+ if (valid_longjmp_stack_p (src_point, m_setjmp_point)
+ && !valid_longjmp_stack_p (dst_point, m_setjmp_point))
+ {
+ /* Compare with diagnostic_manager::add_events_for_superedge. */
+ const int src_stack_depth = src_point.get_stack_depth ();
+ m_stack_pop_event = new custom_event
+ (src_point.get_location (),
+ src_point.get_fndecl (),
+ src_stack_depth,
+ "stack frame is popped here, invalidating saved environment");
+ emission_path->add_event (m_stack_pop_event);
+ return false;
+ }
+ return false;
+ }
+
+ label_text describe_final_event (const evdesc::final_event &ev)
+ {
+ if (m_stack_pop_event)
+ return ev.formatted_print
+ ("%qs called after enclosing function of %qs returned at %@",
+ get_user_facing_name (m_longjmp_call),
+ get_user_facing_name (m_setjmp_call),
+ m_stack_pop_event->get_id_ptr ());
+ else
+ return ev.formatted_print
+ ("%qs called after enclosing function of %qs has returned",
+ get_user_facing_name (m_longjmp_call),
+ get_user_facing_name (m_setjmp_call));;
+ }
+
+
private:
const gcall *m_setjmp_call;
const gcall *m_longjmp_call;
+ program_point m_setjmp_point;
+ custom_event *m_stack_pop_event;
};
/* Handle LONGJMP_CALL, a call to longjmp or siglongjmp.
@@ -1344,7 +1394,7 @@ exploded_node::on_longjmp (exploded_graph &eg,
/* Verify that the setjmp's call_stack hasn't been popped. */
if (!valid_longjmp_stack_p (longjmp_point, setjmp_point))
{
- ctxt->warn (new stale_jmp_buf (setjmp_call, longjmp_call));
+ ctxt->warn (new stale_jmp_buf (setjmp_call, longjmp_call, setjmp_point));
return;
}
@@ -4589,6 +4639,33 @@ dump_analyzer_json (const supergraph &sg,
free (filename);
}
+/* Concrete subclass of plugin_analyzer_init_iface, allowing plugins
+ to register new state machines. */
+
+class plugin_analyzer_init_impl : public plugin_analyzer_init_iface
+{
+public:
+ plugin_analyzer_init_impl (auto_delete_vec <state_machine> *checkers,
+ logger *logger)
+ : m_checkers (checkers),
+ m_logger (logger)
+ {}
+
+ void register_state_machine (state_machine *sm) FINAL OVERRIDE
+ {
+ m_checkers->safe_push (sm);
+ }
+
+ logger *get_logger () const FINAL OVERRIDE
+ {
+ return m_logger;
+ }
+
+private:
+ auto_delete_vec <state_machine> *m_checkers;
+ logger *m_logger;
+};
+
/* Run the analysis "engine". */
void
@@ -4634,6 +4711,9 @@ impl_run_checkers (logger *logger)
auto_delete_vec <state_machine> checkers;
make_checkers (checkers, logger);
+ plugin_analyzer_init_impl data (&checkers, logger);
+ invoke_plugin_callbacks (PLUGIN_ANALYZER_INIT, &data);
+
if (logger)
{
int i;
diff --git a/gcc/analyzer/pending-diagnostic.h b/gcc/analyzer/pending-diagnostic.h
index b1ff268..0cec27a 100644
--- a/gcc/analyzer/pending-diagnostic.h
+++ b/gcc/analyzer/pending-diagnostic.h
@@ -175,6 +175,14 @@ class pending_diagnostic
diagnostic deduplication. */
static bool same_tree_p (tree t1, tree t2);
+ /* A vfunc for fixing up locations (both the primary location for the
+ diagnostic, and for events in their paths), e.g. to avoid unwinding
+ inside specific macros. */
+ virtual location_t fixup_location (location_t loc) const
+ {
+ return loc;
+ }
+
/* For greatest precision-of-wording, the various following "describe_*"
virtual functions give the pending diagnostic a way to describe events
in a diagnostic_path in terms that make sense for that diagnostic.
@@ -246,6 +254,21 @@ class pending_diagnostic
}
/* End of precision-of-wording vfuncs. */
+
+ /* Vfunc for extending/overriding creation of the events for an
+ exploded_edge that corresponds to a superedge, allowing for custom
+ events to be created that are pertinent to a particular
+ pending_diagnostic subclass.
+
+ For example, the -Wanalyzer-stale-setjmp-buffer diagnostic adds a
+ custom event showing when the pertinent stack frame is popped
+ (and thus the point at which the jmp_buf becomes invalid). */
+
+ virtual bool maybe_add_custom_events_for_superedge (const exploded_edge &,
+ checker_path *)
+ {
+ return false;
+ }
};
/* A template to make it easier to make subclasses of pending_diagnostic.
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index b39e55a..5c59c09 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -154,8 +154,8 @@ sm_state_map::entry_t::cmp (const entry_t &entry_a, const entry_t &entry_b)
/* sm_state_map's ctor. */
-sm_state_map::sm_state_map (const state_machine &sm, int sm_idx)
-: m_sm (sm), m_sm_idx (sm_idx), m_map (), m_global_state (sm.get_start_state ())
+sm_state_map::sm_state_map (const state_machine &sm)
+: m_sm (sm), m_map (), m_global_state (sm.get_start_state ())
{
}
@@ -656,7 +656,7 @@ program_state::program_state (const extrinsic_state &ext_state)
const int num_states = ext_state.get_num_checkers ();
for (int i = 0; i < num_states; i++)
{
- sm_state_map *sm = new sm_state_map (ext_state.get_sm (i), i);
+ sm_state_map *sm = new sm_state_map (ext_state.get_sm (i));
m_checker_states.quick_push (sm);
}
}
@@ -1251,7 +1251,7 @@ test_sm_state_map ()
const svalue *y_sval = model.get_rvalue (y, NULL);
const svalue *z_sval = model.get_rvalue (z, NULL);
- sm_state_map map (*sm, 0);
+ sm_state_map map (*sm);
ASSERT_TRUE (map.is_empty_p ());
ASSERT_EQ (map.get_state (x_sval, ext_state), start);
@@ -1280,7 +1280,7 @@ test_sm_state_map ()
const svalue *y_sval = model.get_rvalue (y, NULL);
const svalue *z_sval = model.get_rvalue (z, NULL);
- sm_state_map map (*sm, 0);
+ sm_state_map map (*sm);
ASSERT_TRUE (map.is_empty_p ());
ASSERT_EQ (map.get_state (x_sval, ext_state), start);
ASSERT_EQ (map.get_state (y_sval, ext_state), start);
@@ -1303,9 +1303,9 @@ test_sm_state_map ()
const svalue *y_sval = model.get_rvalue (y, NULL);
const svalue *z_sval = model.get_rvalue (z, NULL);
- sm_state_map map0 (*sm, 0);
- sm_state_map map1 (*sm, 0);
- sm_state_map map2 (*sm, 0);
+ sm_state_map map0 (*sm);
+ sm_state_map map1 (*sm);
+ sm_state_map map2 (*sm);
ASSERT_EQ (map0.hash (), map1.hash ());
ASSERT_EQ (map0, map1);
@@ -1326,9 +1326,9 @@ test_sm_state_map ()
const state_machine::state_t TEST_STATE_2 = &test_state_2;
const state_machine::state test_state_3 ("test state 3", 3);
const state_machine::state_t TEST_STATE_3 = &test_state_3;
- sm_state_map map0 (*sm, 0);
- sm_state_map map1 (*sm, 0);
- sm_state_map map2 (*sm, 0);
+ sm_state_map map0 (*sm);
+ sm_state_map map1 (*sm);
+ sm_state_map map2 (*sm);
ASSERT_EQ (map0.hash (), map1.hash ());
ASSERT_EQ (map0, map1);
diff --git a/gcc/analyzer/program-state.h b/gcc/analyzer/program-state.h
index c44fc94..1532210 100644
--- a/gcc/analyzer/program-state.h
+++ b/gcc/analyzer/program-state.h
@@ -104,7 +104,7 @@ public:
typedef hash_map <const svalue *, entry_t> map_t;
typedef map_t::iterator iterator_t;
- sm_state_map (const state_machine &sm, int m_sm_idx);
+ sm_state_map (const state_machine &sm);
sm_state_map *clone () const;
@@ -168,7 +168,6 @@ public:
private:
const state_machine &m_sm;
- int m_sm_idx;
map_t m_map;
state_machine::state_t m_global_state;
};
diff --git a/gcc/analyzer/region-model-reachability.cc b/gcc/analyzer/region-model-reachability.cc
index 7fd8905..9fc70d2 100644
--- a/gcc/analyzer/region-model-reachability.cc
+++ b/gcc/analyzer/region-model-reachability.cc
@@ -58,9 +58,8 @@ along with GCC; see the file COPYING3. If not see
namespace ana {
-reachable_regions::reachable_regions (region_model *model,
- region_model_manager *mgr)
-: m_model (model), m_store (model->get_store ()), m_mgr (mgr),
+reachable_regions::reachable_regions (region_model *model)
+: m_model (model), m_store (model->get_store ()),
m_reachable_base_regs (), m_mutable_base_regs ()
{
}
diff --git a/gcc/analyzer/region-model-reachability.h b/gcc/analyzer/region-model-reachability.h
index fe305b0..4d30c1f 100644
--- a/gcc/analyzer/region-model-reachability.h
+++ b/gcc/analyzer/region-model-reachability.h
@@ -35,7 +35,7 @@ namespace ana {
class reachable_regions
{
public:
- reachable_regions (region_model *model, region_model_manager *mgr);
+ reachable_regions (region_model *model);
/* Callback called for each cluster when initializing this object. */
static void init_cluster_cb (const region *base_reg,
@@ -97,7 +97,6 @@ public:
private:
region_model *m_model;
store *m_store;
- region_model_manager *m_mgr;
/* The base regions already seen. */
hash_set<const region *> m_reachable_base_regs;
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index e5f027b..57c657b 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -363,6 +363,88 @@ private:
enum poison_kind m_pkind;
};
+/* A subclass of pending_diagnostic for complaining about shifts
+ by negative counts. */
+
+class shift_count_negative_diagnostic
+: public pending_diagnostic_subclass<shift_count_negative_diagnostic>
+{
+public:
+ shift_count_negative_diagnostic (const gassign *assign, tree count_cst)
+ : m_assign (assign), m_count_cst (count_cst)
+ {}
+
+ const char *get_kind () const FINAL OVERRIDE
+ {
+ return "shift_count_negative_diagnostic";
+ }
+
+ bool operator== (const shift_count_negative_diagnostic &other) const
+ {
+ return (m_assign == other.m_assign
+ && same_tree_p (m_count_cst, other.m_count_cst));
+ }
+
+ bool emit (rich_location *rich_loc) FINAL OVERRIDE
+ {
+ return warning_at (rich_loc, OPT_Wanalyzer_shift_count_negative,
+ "shift by negative count (%qE)", m_count_cst);
+ }
+
+ label_text describe_final_event (const evdesc::final_event &ev) FINAL OVERRIDE
+ {
+ return ev.formatted_print ("shift by negative amount here (%qE)", m_count_cst);
+ }
+
+private:
+ const gassign *m_assign;
+ tree m_count_cst;
+};
+
+/* A subclass of pending_diagnostic for complaining about shifts
+ by counts >= the width of the operand type. */
+
+class shift_count_overflow_diagnostic
+: public pending_diagnostic_subclass<shift_count_overflow_diagnostic>
+{
+public:
+ shift_count_overflow_diagnostic (const gassign *assign,
+ int operand_precision,
+ tree count_cst)
+ : m_assign (assign), m_operand_precision (operand_precision),
+ m_count_cst (count_cst)
+ {}
+
+ const char *get_kind () const FINAL OVERRIDE
+ {
+ return "shift_count_overflow_diagnostic";
+ }
+
+ bool operator== (const shift_count_overflow_diagnostic &other) const
+ {
+ return (m_assign == other.m_assign
+ && m_operand_precision == other.m_operand_precision
+ && same_tree_p (m_count_cst, other.m_count_cst));
+ }
+
+ bool emit (rich_location *rich_loc) FINAL OVERRIDE
+ {
+ return warning_at (rich_loc, OPT_Wanalyzer_shift_count_overflow,
+ "shift by count (%qE) >= precision of type (%qi)",
+ m_count_cst, m_operand_precision);
+ }
+
+ label_text describe_final_event (const evdesc::final_event &ev) FINAL OVERRIDE
+ {
+ return ev.formatted_print ("shift by count %qE here", m_count_cst);
+ }
+
+private:
+ const gassign *m_assign;
+ int m_operand_precision;
+ tree m_count_cst;
+};
+
/* If ASSIGN is a stmt that can be modelled via
set_value (lhs_reg, SVALUE, CTXT)
for some SVALUE, get the SVALUE.
@@ -514,6 +596,26 @@ region_model::get_gassign_result (const gassign *assign,
const svalue *rhs1_sval = get_rvalue (rhs1, ctxt);
const svalue *rhs2_sval = get_rvalue (rhs2, ctxt);
+ if (ctxt && (op == LSHIFT_EXPR || op == RSHIFT_EXPR))
+ {
+ /* "INT34-C. Do not shift an expression by a negative number of bits
+ or by greater than or equal to the number of bits that exist in
+ the operand." */
+ if (const tree rhs2_cst = rhs2_sval->maybe_get_constant ())
+ if (TREE_CODE (rhs2_cst) == INTEGER_CST)
+ {
+ if (tree_int_cst_sgn (rhs2_cst) < 0)
+ ctxt->warn (new shift_count_negative_diagnostic
+ (assign, rhs2_cst));
+ else if (compare_tree_int (rhs2_cst,
+ TYPE_PRECISION (TREE_TYPE (rhs1)))
+ >= 0)
+ ctxt->warn (new shift_count_overflow_diagnostic
+ (assign, TYPE_PRECISION (TREE_TYPE (rhs1)),
+ rhs2_cst));
+ }
+ }
+
const svalue *sval_binop
= m_mgr->get_or_create_binop (TREE_TYPE (lhs), op,
rhs1_sval, rhs2_sval);
@@ -836,7 +938,7 @@ region_model::handle_unrecognized_call (const gcall *call,
{
tree fndecl = get_fndecl_for_call (call, ctxt);
- reachable_regions reachable_regs (this, m_mgr);
+ reachable_regions reachable_regs (this);
/* Determine the reachable regions and their mutability. */
{
@@ -904,7 +1006,7 @@ void
region_model::get_reachable_svalues (svalue_set *out,
const svalue *extra_sval)
{
- reachable_regions reachable_regs (this, m_mgr);
+ reachable_regions reachable_regs (this);
/* Add globals and regions that already escaped in previous
unknown calls. */
@@ -2857,8 +2959,7 @@ region_model::can_merge_with_p (const region_model &other_model,
/* Merge constraints. */
constraint_manager::merge (*m_constraints,
*other_model.m_constraints,
- out_model->m_constraints,
- m);
+ out_model->m_constraints);
return true;
}
diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc
index fd12a35..4c38738 100644
--- a/gcc/analyzer/sm-malloc.cc
+++ b/gcc/analyzer/sm-malloc.cc
@@ -675,9 +675,9 @@ public:
bool emit (rich_location *rich_loc) FINAL OVERRIDE
{
- /* CWE-690: Unchecked Return Value to NULL Pointer Dereference. */
+ /* CWE-476: NULL Pointer Dereference. */
diagnostic_metadata m;
- m.add_cwe (690);
+ m.add_cwe (476);
return warning_meta (rich_loc, m,
OPT_Wanalyzer_null_dereference,
"dereference of NULL %qE", m_arg);
@@ -723,10 +723,10 @@ public:
bool emit (rich_location *rich_loc) FINAL OVERRIDE
{
- /* CWE-690: Unchecked Return Value to NULL Pointer Dereference. */
+ /* CWE-476: NULL Pointer Dereference. */
auto_diagnostic_group d;
diagnostic_metadata m;
- m.add_cwe (690);
+ m.add_cwe (476);
bool warned;
if (zerop (m_arg))
diff --git a/gcc/asan.c b/gcc/asan.c
index 0b471af..5968e12 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -257,6 +257,58 @@ hash_set<tree> *asan_handled_variables = NULL;
hash_set <tree> *asan_used_labels = NULL;
+/* Global variables for HWASAN stack tagging. */
+/* hwasan_frame_tag_offset records the offset from the frame base tag that the
+ next object should have. */
+static uint8_t hwasan_frame_tag_offset = 0;
+/* hwasan_frame_base_ptr is a pointer with the same address as
+ `virtual_stack_vars_rtx` for the current frame, and with the frame base tag
+ stored in it. N.b. this global RTX does not need to be marked GTY, but is
+ done so anyway. The need is not there since all uses are in just one pass
+ (cfgexpand) and there are no calls to ggc_collect between the uses. We mark
+ it GTY(()) anyway to allow the use of the variable later on if needed by
+ future features. */
+static GTY(()) rtx hwasan_frame_base_ptr = NULL_RTX;
+/* hwasan_frame_base_init_seq is the sequence of RTL insns that will initialize
+ the hwasan_frame_base_ptr. When the hwasan_frame_base_ptr is requested, we
+ generate this sequence but do not emit it. If the sequence was created it
+ is emitted once the function body has been expanded.
+
+ This delay is because the frame base pointer may be needed anywhere in the
+ function body, or needed by the expand_used_vars function. Emitting once in
+ a known place is simpler than requiring the emission of the instructions to
+ be know where it should go depending on the first place the hwasan frame
+ base is needed. */
+static GTY(()) rtx_insn *hwasan_frame_base_init_seq = NULL;
+
+/* Structure defining the extent of one object on the stack that HWASAN needs
+ to tag in the corresponding shadow stack space.
+
+ The range this object spans on the stack is between `untagged_base +
+ nearest_offset` and `untagged_base + farthest_offset`.
+ `tagged_base` is an rtx containing the same value as `untagged_base` but
+ with a random tag stored in the top byte. We record both `untagged_base`
+ and `tagged_base` so that `hwasan_emit_prologue` can use both without having
+ to emit RTL into the instruction stream to re-calculate one from the other.
+ (`hwasan_emit_prologue` needs to use both bases since the
+ __hwasan_tag_memory call it emits uses an untagged value, and it calculates
+ the tag to store in shadow memory based on the tag_offset plus the tag in
+ tagged_base). */
+struct hwasan_stack_var
+{
+ rtx untagged_base;
+ rtx tagged_base;
+ poly_int64 nearest_offset;
+ poly_int64 farthest_offset;
+ uint8_t tag_offset;
+};
+
+/* Variable recording all stack variables that HWASAN needs to tag.
+ Does not need to be marked as GTY(()) since every use is in the cfgexpand
+ pass and gcc_collect is not called in the middle of that pass. */
+static vec<hwasan_stack_var> hwasan_tagged_stack_vars;
+
+
/* Sets shadow offset to value in string VAL. */
bool
@@ -318,6 +370,25 @@ asan_sanitize_allocas_p (void)
return (asan_sanitize_stack_p () && param_asan_protect_allocas);
}
+bool
+asan_instrument_reads (void)
+{
+ return (sanitize_flags_p (SANITIZE_ADDRESS) && param_asan_instrument_reads);
+}
+
+bool
+asan_instrument_writes (void)
+{
+ return (sanitize_flags_p (SANITIZE_ADDRESS) && param_asan_instrument_writes);
+}
+
+bool
+asan_memintrin (void)
+{
+ return (sanitize_flags_p (SANITIZE_ADDRESS) && param_asan_memintrin);
+}
+
+
/* Checks whether section SEC should be sanitized. */
static bool
@@ -578,20 +649,47 @@ get_last_alloca_addr ()
To overcome the issue we use following trick: pass new_sp as a second
parameter to __asan_allocas_unpoison and rewrite it during expansion with
new_sp + (virtual_dynamic_stack_rtx - sp) later in
- expand_asan_emit_allocas_unpoison function. */
+ expand_asan_emit_allocas_unpoison function.
+
+ HWASAN needs to do very similar, the eventual pseudocode should be:
+ __hwasan_tag_memory (virtual_stack_dynamic_rtx,
+ 0,
+ new_sp - sp);
+ __builtin_stack_restore (new_sp)
+
+ Need to use the same trick to handle STACK_DYNAMIC_OFFSET as described
+ above. */
static void
handle_builtin_stack_restore (gcall *call, gimple_stmt_iterator *iter)
{
- if (!iter || !asan_sanitize_allocas_p ())
+ if (!iter
+ || !(asan_sanitize_allocas_p () || hwasan_sanitize_allocas_p ()))
return;
- tree last_alloca = get_last_alloca_addr ();
tree restored_stack = gimple_call_arg (call, 0);
- tree fn = builtin_decl_implicit (BUILT_IN_ASAN_ALLOCAS_UNPOISON);
- gimple *g = gimple_build_call (fn, 2, last_alloca, restored_stack);
- gsi_insert_before (iter, g, GSI_SAME_STMT);
- g = gimple_build_assign (last_alloca, restored_stack);
+
+ gimple *g;
+
+ if (hwasan_sanitize_allocas_p ())
+ {
+ enum internal_fn fn = IFN_HWASAN_ALLOCA_UNPOISON;
+ /* There is only one piece of information `expand_HWASAN_ALLOCA_UNPOISON`
+ needs to work. This is the length of the area that we're
+ deallocating. Since the stack pointer is known at expand time, the
+ position of the new stack pointer after deallocation is enough
+ information to calculate this length. */
+ g = gimple_build_call_internal (fn, 1, restored_stack);
+ }
+ else
+ {
+ tree last_alloca = get_last_alloca_addr ();
+ tree fn = builtin_decl_implicit (BUILT_IN_ASAN_ALLOCAS_UNPOISON);
+ g = gimple_build_call (fn, 2, last_alloca, restored_stack);
+ gsi_insert_before (iter, g, GSI_SAME_STMT);
+ g = gimple_build_assign (last_alloca, restored_stack);
+ }
+
gsi_insert_before (iter, g, GSI_SAME_STMT);
}
@@ -621,14 +719,12 @@ handle_builtin_stack_restore (gcall *call, gimple_stmt_iterator *iter)
static void
handle_builtin_alloca (gcall *call, gimple_stmt_iterator *iter)
{
- if (!iter || !asan_sanitize_allocas_p ())
+ if (!iter
+ || !(asan_sanitize_allocas_p () || hwasan_sanitize_allocas_p ()))
return;
gassign *g;
gcall *gg;
- const HOST_WIDE_INT redzone_mask = ASAN_RED_ZONE_SIZE - 1;
-
- tree last_alloca = get_last_alloca_addr ();
tree callee = gimple_call_fndecl (call);
tree old_size = gimple_call_arg (call, 0);
tree ptr_type = gimple_call_lhs (call) ? TREE_TYPE (gimple_call_lhs (call))
@@ -638,6 +734,68 @@ handle_builtin_alloca (gcall *call, gimple_stmt_iterator *iter)
= DECL_FUNCTION_CODE (callee) == BUILT_IN_ALLOCA
? 0 : tree_to_uhwi (gimple_call_arg (call, 1));
+ if (hwasan_sanitize_allocas_p ())
+ {
+ gimple_seq stmts = NULL;
+ location_t loc = gimple_location (gsi_stmt (*iter));
+ /*
+ HWASAN needs a different expansion.
+
+ addr = __builtin_alloca (size, align);
+
+ should be replaced by
+
+ new_size = size rounded up to HWASAN_TAG_GRANULE_SIZE byte alignment;
+ untagged_addr = __builtin_alloca (new_size, align);
+ tag = __hwasan_choose_alloca_tag ();
+ addr = ifn_HWASAN_SET_TAG (untagged_addr, tag);
+ __hwasan_tag_memory (untagged_addr, tag, new_size);
+ */
+ /* Ensure alignment at least HWASAN_TAG_GRANULE_SIZE bytes so we start on
+ a tag granule. */
+ align = align > HWASAN_TAG_GRANULE_SIZE ? align : HWASAN_TAG_GRANULE_SIZE;
+
+ tree old_size = gimple_call_arg (call, 0);
+ tree new_size = gimple_build_round_up (&stmts, loc, size_type_node,
+ old_size,
+ HWASAN_TAG_GRANULE_SIZE);
+
+ /* Make the alloca call */
+ tree untagged_addr
+ = gimple_build (&stmts, loc,
+ as_combined_fn (BUILT_IN_ALLOCA_WITH_ALIGN), ptr_type,
+ new_size, build_int_cst (size_type_node, align));
+
+ /* Choose the tag.
+ Here we use an internal function so we can choose the tag at expand
+ time. We need the decision to be made after stack variables have been
+ assigned their tag (i.e. once the hwasan_frame_tag_offset variable has
+ been set to one after the last stack variables tag). */
+ tree tag = gimple_build (&stmts, loc, CFN_HWASAN_CHOOSE_TAG,
+ unsigned_char_type_node);
+
+ /* Add tag to pointer. */
+ tree addr
+ = gimple_build (&stmts, loc, CFN_HWASAN_SET_TAG, ptr_type,
+ untagged_addr, tag);
+
+ /* Tag shadow memory.
+ NOTE: require using `untagged_addr` here for libhwasan API. */
+ gimple_build (&stmts, loc, as_combined_fn (BUILT_IN_HWASAN_TAG_MEM),
+ void_type_node, untagged_addr, tag, new_size);
+
+ /* Insert the built up code sequence into the original instruction stream
+ the iterator points to. */
+ gsi_insert_seq_before (iter, stmts, GSI_SAME_STMT);
+
+ /* Finally, replace old alloca ptr with NEW_ALLOCA. */
+ replace_call_with_value (iter, addr);
+ return;
+ }
+
+ tree last_alloca = get_last_alloca_addr ();
+ const HOST_WIDE_INT redzone_mask = ASAN_RED_ZONE_SIZE - 1;
+
/* If ALIGN > ASAN_RED_ZONE_SIZE, we embed left redzone into first ALIGN
bytes of allocated space. Otherwise, align alloca to ASAN_RED_ZONE_SIZE
manually. */
@@ -790,6 +948,31 @@ get_mem_refs_of_builtin_call (gcall *call,
break;
case BUILT_IN_STRLEN:
+ /* Special case strlen here since its length is taken from its return
+ value.
+
+ The approach taken by the sanitizers is to check a memory access
+ before it's taken. For ASAN strlen is intercepted by libasan, so no
+ check is inserted by the compiler.
+
+ This function still returns `true` and provides a length to the rest
+ of the ASAN pass in order to record what areas have been checked,
+ avoiding superfluous checks later on.
+
+ HWASAN does not intercept any of these internal functions.
+ This means that checks for memory accesses must be inserted by the
+ compiler.
+ strlen is a special case, because we can tell the length from the
+ return of the function, but that is not known until after the function
+ has returned.
+
+ Hence we can't check the memory access before it happens.
+ We could check the memory access after it has already happened, but
+ for now we choose to just ignore `strlen` calls.
+ This decision was simply made because that means the special case is
+ limited to this one case of this one function. */
+ if (hwasan_sanitize_p ())
+ return false;
source0 = gimple_call_arg (call, 0);
len = gimple_call_lhs (call);
break;
@@ -1359,6 +1542,199 @@ asan_redzone_buffer::flush_if_full (void)
flush_redzone_payload ();
}
+
+/* HWAddressSanitizer (hwasan) is a probabilistic method for detecting
+ out-of-bounds and use-after-free bugs.
+ Read more:
+ http://code.google.com/p/address-sanitizer/
+
+ Similar to AddressSanitizer (asan) it consists of two parts: the
+ instrumentation module in this file, and a run-time library.
+
+ The instrumentation module adds a run-time check before every memory insn in
+ the same manner as asan (see the block comment for AddressSanitizer above).
+ Currently, hwasan only adds out-of-line instrumentation, where each check is
+ implemented as a function call to the run-time library. Hence a check for a
+ load of N bytes from address X would be implemented with a function call to
+ __hwasan_loadN(X), and checking a store of N bytes from address X would be
+ implemented with a function call to __hwasan_storeN(X).
+
+ The main difference between hwasan and asan is in the information stored to
+ help this checking. Both sanitizers use a shadow memory area which stores
+ data recording the state of main memory at a corresponding address.
+
+ For hwasan, each 16 byte granule in main memory has a corresponding 1 byte
+ in shadow memory. This shadow address can be calculated with equation:
+ (addr >> log_2(HWASAN_TAG_GRANULE_SIZE))
+ + __hwasan_shadow_memory_dynamic_address;
+ The conversion between real and shadow memory for asan is given in the block
+ comment at the top of this file.
+ The description of how this shadow memory is laid out for asan is in the
+ block comment at the top of this file, here we describe how this shadow
+ memory is used for hwasan.
+
+ For hwasan, each variable is assigned a byte-sized 'tag'. The extent of
+ the shadow memory for that variable is filled with the assigned tag, and
+ every pointer referencing that variable has its top byte set to the same
+ tag. The run-time library redefines malloc so that every allocation returns
+ a tagged pointer and tags the corresponding shadow memory with the same tag.
+
+ On each pointer dereference the tag found in the pointer is compared to the
+ tag found in the shadow memory corresponding to the accessed memory address.
+ If these tags are found to differ then this memory access is judged to be
+ invalid and a report is generated.
+
+ This method of bug detection is not perfect -- it can not catch every bad
+ access -- but catches them probabilistically instead. There is always the
+ possibility that an invalid memory access will happen to access memory
+ tagged with the same tag as the pointer that this access used.
+ The chances of this are approx. 0.4% for any two uncorrelated objects.
+
+ Random tag generation can mitigate this problem by decreasing the
+ probability that an invalid access will be missed in the same manner over
+ multiple runs. i.e. if two objects are tagged the same in one run of the
+ binary they are unlikely to be tagged the same in the next run.
+ Both heap and stack allocated objects have random tags by default.
+
+ [16 byte granule implications]
+ Since the shadow memory only has a resolution on real memory of 16 bytes,
+ invalid accesses that are within the same 16 byte granule as a valid
+ address will not be caught.
+
+ There is a "short-granule" feature in the runtime library which does catch
+ such accesses, but this feature is not implemented for stack objects (since
+ stack objects are allocated and tagged by compiler instrumentation, and
+ this feature has not yet been implemented in GCC instrumentation).
+
+ Another outcome of this 16 byte resolution is that each tagged object must
+ be 16 byte aligned. If two objects were to share any 16 byte granule in
+ memory, then they both would have to be given the same tag, and invalid
+ accesses to one using a pointer to the other would be undetectable.
+
+ [Compiler instrumentation]
+ Compiler instrumentation ensures that two adjacent buffers on the stack are
+ given different tags, this means an access to one buffer using a pointer
+ generated from the other (e.g. through buffer overrun) will have mismatched
+ tags and be caught by hwasan.
+
+ We don't randomly tag every object on the stack, since that would require
+ keeping many registers to record each tag. Instead we randomly generate a
+ tag for each function frame, and each new stack object uses a tag offset
+ from that frame tag.
+ i.e. each object is tagged as RFT + offset, where RFT is the "random frame
+ tag" generated for this frame.
+ This means that randomisation does not peturb the difference between tags
+ on tagged stack objects within a frame, but this is mitigated by the fact
+ that objects with the same tag within a frame are very far apart
+ (approx. 2^HWASAN_TAG_SIZE objects apart).
+
+ As a demonstration, using the same example program as in the asan block
+ comment above:
+
+ int
+ foo ()
+ {
+ char a[23] = {0};
+ int b[2] = {0};
+
+ a[5] = 1;
+ b[1] = 2;
+
+ return a[5] + b[1];
+ }
+
+ On AArch64 the stack will be ordered as follows for the above function:
+
+ Slot 1/ [24 bytes for variable 'a']
+ Slot 2/ [8 bytes padding for alignment]
+ Slot 3/ [8 bytes for variable 'b']
+ Slot 4/ [8 bytes padding for alignment]
+
+ (The padding is there to ensure 16 byte alignment as described in the 16
+ byte granule implications).
+
+ While the shadow memory will be ordered as follows:
+
+ - 2 bytes (representing 32 bytes in real memory) tagged with RFT + 1.
+ - 1 byte (representing 16 bytes in real memory) tagged with RFT + 2.
+
+ And any pointer to "a" will have the tag RFT + 1, and any pointer to "b"
+ will have the tag RFT + 2.
+
+ [Top Byte Ignore requirements]
+ Hwasan requires the ability to store an 8 bit tag in every pointer. There
+ is no instrumentation done to remove this tag from pointers before
+ dereferencing, which means the hardware must ignore this tag during memory
+ accesses.
+
+ Architectures where this feature is available should indicate this using
+ the TARGET_MEMTAG_CAN_TAG_ADDRESSES hook.
+
+ [Stack requires cleanup on unwinding]
+ During normal operation of a hwasan sanitized program more space in the
+ shadow memory becomes tagged as the stack grows. As the stack shrinks this
+ shadow memory space must become untagged. If it is not untagged then when
+ the stack grows again (during other function calls later on in the program)
+ objects on the stack that are usually not tagged (e.g. parameters passed on
+ the stack) can be placed in memory whose shadow space is tagged with
+ something else, and accesses can cause false positive reports.
+
+ Hence we place untagging code on every epilogue of functions which tag some
+ stack objects.
+
+ Moreover, the run-time library intercepts longjmp & setjmp to untag when
+ the stack is unwound this way.
+
+ C++ exceptions are not yet handled, which means this sanitizer can not
+ handle C++ code that throws exceptions -- it will give false positives
+ after an exception has been thrown. The implementation that the hwasan
+ library has for handling these relies on the frame pointer being after any
+ local variables. This is not generally the case for GCC. */
+
+
+/* Returns whether we are tagging pointers and checking those tags on memory
+ access. */
+bool
+hwasan_sanitize_p ()
+{
+ return sanitize_flags_p (SANITIZE_HWADDRESS);
+}
+
+/* Are we tagging the stack? */
+bool
+hwasan_sanitize_stack_p ()
+{
+ return (hwasan_sanitize_p () && param_hwasan_instrument_stack);
+}
+
+/* Are we tagging alloca objects? */
+bool
+hwasan_sanitize_allocas_p (void)
+{
+ return (hwasan_sanitize_stack_p () && param_hwasan_instrument_allocas);
+}
+
+/* Should we instrument reads? */
+bool
+hwasan_instrument_reads (void)
+{
+ return (hwasan_sanitize_p () && param_hwasan_instrument_reads);
+}
+
+/* Should we instrument writes? */
+bool
+hwasan_instrument_writes (void)
+{
+ return (hwasan_sanitize_p () && param_hwasan_instrument_writes);
+}
+
+/* Should we instrument builtin calls? */
+bool
+hwasan_memintrin (void)
+{
+ return (hwasan_sanitize_p () && param_hwasan_instrument_mem_intrinsics);
+}
+
/* Insert code to protect stack vars. The prologue sequence should be emitted
directly, epilogue sequence returned. BASE is the register holding the
stack base, against which OFFSETS array offsets are relative to, OFFSETS
@@ -1854,6 +2230,8 @@ static tree
report_error_func (bool is_store, bool recover_p, HOST_WIDE_INT size_in_bytes,
int *nargs)
{
+ gcc_assert (!hwasan_sanitize_p ());
+
static enum built_in_function report[2][2][6]
= { { { BUILT_IN_ASAN_REPORT_LOAD1, BUILT_IN_ASAN_REPORT_LOAD2,
BUILT_IN_ASAN_REPORT_LOAD4, BUILT_IN_ASAN_REPORT_LOAD8,
@@ -2146,6 +2524,7 @@ build_check_stmt (location_t loc, tree base, tree len,
gimple *g;
gcc_assert (!(size_in_bytes > 0 && !is_non_zero_len));
+ gcc_assert (size_in_bytes == -1 || size_in_bytes >= 1);
gsi = *iter;
@@ -2190,7 +2569,11 @@ build_check_stmt (location_t loc, tree base, tree len,
if (is_scalar_access)
flags |= ASAN_CHECK_SCALAR_ACCESS;
- g = gimple_build_call_internal (IFN_ASAN_CHECK, 4,
+ enum internal_fn fn = hwasan_sanitize_p ()
+ ? IFN_HWASAN_CHECK
+ : IFN_ASAN_CHECK;
+
+ g = gimple_build_call_internal (fn, 4,
build_int_cst (integer_type_node, flags),
base, len,
build_int_cst (integer_type_node,
@@ -2214,9 +2597,9 @@ static void
instrument_derefs (gimple_stmt_iterator *iter, tree t,
location_t location, bool is_store)
{
- if (is_store && !param_asan_instrument_writes)
+ if (is_store && !(asan_instrument_writes () || hwasan_instrument_writes ()))
return;
- if (!is_store && !param_asan_instrument_reads)
+ if (!is_store && !(asan_instrument_reads () || hwasan_instrument_reads ()))
return;
tree type, base;
@@ -2277,7 +2660,12 @@ instrument_derefs (gimple_stmt_iterator *iter, tree t,
{
if (DECL_THREAD_LOCAL_P (inner))
return;
- if (!param_asan_globals && is_global_var (inner))
+ /* If we're not sanitizing globals and we can tell statically that this
+ access is inside a global variable, then there's no point adding
+ instrumentation to check the access. N.b. hwasan currently never
+ sanitizes globals. */
+ if ((hwasan_sanitize_p () || !param_asan_globals)
+ && is_global_var (inner))
return;
if (!TREE_STATIC (inner))
{
@@ -2370,7 +2758,7 @@ instrument_mem_region_access (tree base, tree len,
static bool
instrument_builtin_call (gimple_stmt_iterator *iter)
{
- if (!param_asan_memintrin)
+ if (!(asan_memintrin () || hwasan_memintrin ()))
return false;
bool iter_advanced_p = false;
@@ -2506,10 +2894,27 @@ maybe_instrument_call (gimple_stmt_iterator *iter)
break;
}
}
- tree decl = builtin_decl_implicit (BUILT_IN_ASAN_HANDLE_NO_RETURN);
- gimple *g = gimple_build_call (decl, 0);
- gimple_set_location (g, gimple_location (stmt));
- gsi_insert_before (iter, g, GSI_SAME_STMT);
+ /* If a function does not return, then we must handle clearing up the
+ shadow stack accordingly. For ASAN we can simply set the entire stack
+ to "valid" for accesses by setting the shadow space to 0 and all
+ accesses will pass checks. That means that some bad accesses may be
+ missed, but we will not report any false positives.
+
+ This is not possible for HWASAN. Since there is no "always valid" tag
+ we can not set any space to "always valid". If we were to clear the
+ entire shadow stack then code resuming from `longjmp` or a caught
+ exception would trigger false positives when correctly accessing
+ variables on the stack. Hence we need to handle things like
+ `longjmp`, thread exit, and exceptions in a different way. These
+ problems must be handled externally to the compiler, e.g. in the
+ language runtime. */
+ if (! hwasan_sanitize_p ())
+ {
+ tree decl = builtin_decl_implicit (BUILT_IN_ASAN_HANDLE_NO_RETURN);
+ gimple *g = gimple_build_call (decl, 0);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_insert_before (iter, g, GSI_SAME_STMT);
+ }
}
bool instrumented = false;
@@ -2908,6 +3313,14 @@ initialize_sanitizer_builtins (void)
= build_function_type_list (void_type_node, uint64_type_node,
ptr_type_node, NULL_TREE);
+ tree BT_FN_PTR_CONST_PTR_UINT8
+ = build_function_type_list (ptr_type_node, const_ptr_type_node,
+ unsigned_char_type_node, NULL_TREE);
+ tree BT_FN_VOID_PTR_UINT8_PTRMODE
+ = build_function_type_list (void_type_node, ptr_type_node,
+ unsigned_char_type_node,
+ pointer_sized_int_node, NULL_TREE);
+
tree BT_FN_BOOL_VPTR_PTR_IX_INT_INT[5];
tree BT_FN_IX_CONST_VPTR_INT[5];
tree BT_FN_IX_VPTR_IX_INT[5];
@@ -2958,6 +3371,8 @@ initialize_sanitizer_builtins (void)
#define BT_FN_I16_CONST_VPTR_INT BT_FN_IX_CONST_VPTR_INT[4]
#define BT_FN_I16_VPTR_I16_INT BT_FN_IX_VPTR_IX_INT[4]
#define BT_FN_VOID_VPTR_I16_INT BT_FN_VOID_VPTR_IX_INT[4]
+#undef ATTR_NOTHROW_LIST
+#define ATTR_NOTHROW_LIST ECF_NOTHROW
#undef ATTR_NOTHROW_LEAF_LIST
#define ATTR_NOTHROW_LEAF_LIST ECF_NOTHROW | ECF_LEAF
#undef ATTR_TMPURE_NOTHROW_LEAF_LIST
@@ -3224,6 +3639,31 @@ asan_expand_mark_ifn (gimple_stmt_iterator *iter)
gcc_checking_assert (TREE_CODE (decl) == VAR_DECL);
+ if (hwasan_sanitize_p ())
+ {
+ gcc_assert (param_hwasan_instrument_stack);
+ gimple_seq stmts = NULL;
+ /* Here we swap ASAN_MARK calls for HWASAN_MARK.
+ This is because we are using the approach of using ASAN_MARK as a
+ synonym until here.
+ That approach means we don't yet have to duplicate all the special
+ cases for ASAN_MARK and ASAN_POISON with the exact same handling but
+ called HWASAN_MARK etc.
+
+ N.b. __asan_poison_stack_memory (which implements ASAN_MARK for ASAN)
+ rounds the size up to its shadow memory granularity, while
+ __hwasan_tag_memory (which implements the same for HWASAN) does not.
+ Hence we emit HWASAN_MARK with an aligned size unlike ASAN_MARK. */
+ tree len = gimple_call_arg (g, 2);
+ tree new_len = gimple_build_round_up (&stmts, loc, size_type_node, len,
+ HWASAN_TAG_GRANULE_SIZE);
+ gimple_build (&stmts, loc, CFN_HWASAN_MARK,
+ void_type_node, gimple_call_arg (g, 0),
+ base, new_len);
+ gsi_replace_with_seq (iter, stmts, true);
+ return false;
+ }
+
if (is_poison)
{
if (asan_handled_variables == NULL)
@@ -3298,6 +3738,7 @@ asan_expand_mark_ifn (gimple_stmt_iterator *iter)
bool
asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls)
{
+ gcc_assert (!hwasan_sanitize_p ());
gimple *g = gsi_stmt (*iter);
location_t loc = gimple_location (g);
bool recover_p;
@@ -3571,11 +4012,61 @@ asan_expand_poison_ifn (gimple_stmt_iterator *iter,
int nargs;
bool store_p = gimple_call_internal_p (use, IFN_ASAN_POISON_USE);
- tree fun = report_error_func (store_p, recover_p, tree_to_uhwi (size),
- &nargs);
-
- gcall *call = gimple_build_call (fun, 1,
- build_fold_addr_expr (shadow_var));
+ gcall *call;
+ if (hwasan_sanitize_p ())
+ {
+ tree fun = builtin_decl_implicit (BUILT_IN_HWASAN_TAG_MISMATCH4);
+ /* NOTE: hwasan has no __hwasan_report_* functions like asan does.
+ We use __hwasan_tag_mismatch4 with arguments that tell it the
+ size of access and load to report all tag mismatches.
+
+ The arguments to this function are:
+ Address of invalid access.
+ Bitfield containing information about the access
+ (access_info)
+ Pointer to a frame of registers
+ (for use in printing the contents of registers in a dump)
+ Not used yet -- to be used by inline instrumentation.
+ Size of access.
+
+ The access_info bitfield encodes the following pieces of
+ information:
+ - Is this a store or load?
+ access_info & 0x10 => store
+ - Should the program continue after reporting the error?
+ access_info & 0x20 => recover
+ - What size access is this (not used here since we can always
+ pass the size in the last argument)
+
+ if (access_info & 0xf == 0xf)
+ size is taken from last argument.
+ else
+ size == 1 << (access_info & 0xf)
+
+ The last argument contains the size of the access iff the
+ access_info size indicator is 0xf (we always use this argument
+ rather than storing the size in the access_info bitfield).
+
+ See the function definition `__hwasan_tag_mismatch4` in
+ libsanitizer/hwasan for the full definition.
+ */
+ unsigned access_info = (0x20 * recover_p)
+ + (0x10 * store_p)
+ + (0xf);
+ call = gimple_build_call (fun, 4,
+ build_fold_addr_expr (shadow_var),
+ build_int_cst (pointer_sized_int_node,
+ access_info),
+ build_int_cst (pointer_sized_int_node, 0),
+ size);
+ }
+ else
+ {
+ tree fun = report_error_func (store_p, recover_p, tree_to_uhwi (size),
+ &nargs);
+ call = gimple_build_call (fun, 1,
+ build_fold_addr_expr (shadow_var));
+ }
gimple_set_location (call, gimple_location (use));
gimple *call_to_insert = call;
@@ -3623,6 +4114,12 @@ asan_expand_poison_ifn (gimple_stmt_iterator *iter,
static unsigned int
asan_instrument (void)
{
+ if (hwasan_sanitize_p ())
+ {
+ transform_statements ();
+ return 0;
+ }
+
if (shadow_ptr_types[0] == NULL_TREE)
asan_init_shadow_ptr_types ();
transform_statements ();
@@ -3660,7 +4157,7 @@ public:
/* opt_pass methods: */
opt_pass * clone () { return new pass_asan (m_ctxt); }
- virtual bool gate (function *) { return gate_asan (); }
+ virtual bool gate (function *) { return gate_asan () || gate_hwasan (); }
virtual unsigned int execute (function *) { return asan_instrument (); }
}; // class pass_asan
@@ -3696,7 +4193,10 @@ public:
{}
/* opt_pass methods: */
- virtual bool gate (function *) { return !optimize && gate_asan (); }
+ virtual bool gate (function *)
+ {
+ return !optimize && (gate_asan () || gate_hwasan ());
+ }
virtual unsigned int execute (function *) { return asan_instrument (); }
}; // class pass_asan_O0
@@ -3709,4 +4209,484 @@ make_pass_asan_O0 (gcc::context *ctxt)
return new pass_asan_O0 (ctxt);
}
+/* HWASAN */
+
+/* For stack tagging:
+
+ Return the offset from the frame base tag that the "next" expanded object
+ should have. */
+uint8_t
+hwasan_current_frame_tag ()
+{
+ return hwasan_frame_tag_offset;
+}
+
+/* For stack tagging:
+
+ Return the 'base pointer' for this function. If that base pointer has not
+ yet been created then we create a register to hold it and record the insns
+ to initialize the register in `hwasan_frame_base_init_seq` for later
+ emission. */
+rtx
+hwasan_frame_base ()
+{
+ if (! hwasan_frame_base_ptr)
+ {
+ start_sequence ();
+ hwasan_frame_base_ptr
+ = force_reg (Pmode,
+ targetm.memtag.insert_random_tag (virtual_stack_vars_rtx,
+ NULL_RTX));
+ hwasan_frame_base_init_seq = get_insns ();
+ end_sequence ();
+ }
+
+ return hwasan_frame_base_ptr;
+}
+
+/* For stack tagging:
+
+ Check whether this RTX is a standard pointer addressing the base of the
+ stack variables for this frame. Returns true if the RTX is either
+ virtual_stack_vars_rtx or hwasan_frame_base_ptr. */
+bool
+stack_vars_base_reg_p (rtx base)
+{
+ return base == virtual_stack_vars_rtx || base == hwasan_frame_base_ptr;
+}
+
+/* For stack tagging:
+
+ Emit frame base initialisation.
+ If hwasan_frame_base has been used before here then
+ hwasan_frame_base_init_seq contains the sequence of instructions to
+ initialize it. This must be put just before the hwasan prologue, so we emit
+ the insns before parm_birth_insn (which will point to the first instruction
+ of the hwasan prologue if it exists).
+
+ We update `parm_birth_insn` to point to the start of this initialisation
+ since that represents the end of the initialisation done by
+ expand_function_{start,end} functions and we want to maintain that. */
+void
+hwasan_maybe_emit_frame_base_init ()
+{
+ if (! hwasan_frame_base_init_seq)
+ return;
+ emit_insn_before (hwasan_frame_base_init_seq, parm_birth_insn);
+ parm_birth_insn = hwasan_frame_base_init_seq;
+}
+
+/* Record a compile-time constant size stack variable that HWASAN will need to
+ tag. This record of the range of a stack variable will be used by
+ `hwasan_emit_prologue` to emit the RTL at the start of each frame which will
+ set tags in the shadow memory according to the assigned tag for each object.
+
+ The range that the object spans in stack space should be described by the
+ bounds `untagged_base + nearest_offset` and
+ `untagged_base + farthest_offset`.
+ `tagged_base` is the base address which contains the "base frame tag" for
+ this frame, and from which the value to address this object with will be
+ calculated.
+
+ We record the `untagged_base` since the functions in the hwasan library we
+ use to tag memory take pointers without a tag. */
+void
+hwasan_record_stack_var (rtx untagged_base, rtx tagged_base,
+ poly_int64 nearest_offset, poly_int64 farthest_offset)
+{
+ hwasan_stack_var cur_var;
+ cur_var.untagged_base = untagged_base;
+ cur_var.tagged_base = tagged_base;
+ cur_var.nearest_offset = nearest_offset;
+ cur_var.farthest_offset = farthest_offset;
+ cur_var.tag_offset = hwasan_current_frame_tag ();
+
+ hwasan_tagged_stack_vars.safe_push (cur_var);
+}
+
+/* Return the RTX representing the farthest extent of the statically allocated
+ stack objects for this frame. If hwasan_frame_base_ptr has not been
+ initialized then we are not storing any static variables on the stack in
+ this frame. In this case we return NULL_RTX to represent that.
+
+ Otherwise simply return virtual_stack_vars_rtx + frame_offset. */
+rtx
+hwasan_get_frame_extent ()
+{
+ return (hwasan_frame_base_ptr
+ ? plus_constant (Pmode, virtual_stack_vars_rtx, frame_offset)
+ : NULL_RTX);
+}
+
+/* For stack tagging:
+
+ Increment the frame tag offset modulo the size a tag can represent. */
+void
+hwasan_increment_frame_tag ()
+{
+ uint8_t tag_bits = HWASAN_TAG_SIZE;
+ gcc_assert (HWASAN_TAG_SIZE
+ <= sizeof (hwasan_frame_tag_offset) * CHAR_BIT);
+ hwasan_frame_tag_offset = (hwasan_frame_tag_offset + 1) % (1 << tag_bits);
+ /* The "background tag" of the stack is zero by definition.
+ This is the tag that objects like parameters passed on the stack and
+ spilled registers are given. It is handy to avoid this tag for objects
+ whose tags we decide ourselves, partly to ensure that buffer overruns
+ can't affect these important variables (e.g. saved link register, saved
+ stack pointer etc) and partly to make debugging easier (everything with a
+ tag of zero is space allocated automatically by the compiler).
+
+ This is not feasible when using random frame tags (the default
+ configuration for hwasan) since the tag for the given frame is randomly
+ chosen at runtime. In order to avoid any tags matching the stack
+ background we would need to decide tag offsets at runtime instead of
+ compile time (and pay the resulting performance cost).
+
+ When not using random base tags for each frame (i.e. when compiled with
+ `--param hwasan-random-frame-tag=0`) the base tag for each frame is zero.
+ This means the tag that each object gets is equal to the
+ hwasan_frame_tag_offset used in determining it.
+ When this is the case we *can* ensure no object gets the tag of zero by
+ simply ensuring no object has the hwasan_frame_tag_offset of zero.
+
+ There is the extra complication that we only record the
+ hwasan_frame_tag_offset here (which is the offset from the tag stored in
+ the stack pointer). In the kernel, the tag in the stack pointer is 0xff
+ rather than zero. This does not cause problems since tags of 0xff are
+ never checked in the kernel. As mentioned at the beginning of this
+ comment the background tag of the stack is zero by definition, which means
+ that for the kernel we should skip offsets of both 0 and 1 from the stack
+ pointer. Avoiding the offset of 0 ensures we use a tag which will be
+ checked, avoiding the offset of 1 ensures we use a tag that is not the
+ same as the background. */
+ if (hwasan_frame_tag_offset == 0 && ! param_hwasan_random_frame_tag)
+ hwasan_frame_tag_offset += 1;
+ if (hwasan_frame_tag_offset == 1 && ! param_hwasan_random_frame_tag
+ && sanitize_flags_p (SANITIZE_KERNEL_HWADDRESS))
+ hwasan_frame_tag_offset += 1;
+}
+
+/* Clear internal state for the next function.
+ This function is called before variables on the stack get expanded, in
+ `init_vars_expansion`. */
+void
+hwasan_record_frame_init ()
+{
+ delete asan_used_labels;
+ asan_used_labels = NULL;
+
+ /* If this isn't the case then some stack variable was recorded *before*
+ hwasan_record_frame_init is called, yet *after* the hwasan prologue for
+ the previous frame was emitted. Such stack variables would not have
+ their shadow stack filled in. */
+ gcc_assert (hwasan_tagged_stack_vars.is_empty ());
+ hwasan_frame_base_ptr = NULL_RTX;
+ hwasan_frame_base_init_seq = NULL;
+
+ /* When not using a random frame tag we can avoid the background stack
+ color which gives the user a little better debug output upon a crash.
+ Meanwhile, when using a random frame tag it will be nice to avoid adding
+ tags for the first object since that is unnecessary extra work.
+ Hence set the initial hwasan_frame_tag_offset to be 0 if using a random
+ frame tag and 1 otherwise.
+
+ As described in hwasan_increment_frame_tag, in the kernel the stack
+ pointer has the tag 0xff. That means that to avoid 0xff and 0 (the tag
+ which the kernel does not check and the background tag respectively) we
+ start with a tag offset of 2. */
+ hwasan_frame_tag_offset = param_hwasan_random_frame_tag
+ ? 0
+ : sanitize_flags_p (SANITIZE_KERNEL_HWADDRESS) ? 2 : 1;
+}
+
+/* For stack tagging:
+ (Emits HWASAN equivalent of what is emitted by
+ `asan_emit_stack_protection`).
+
+ Emits the extra prologue code to set the shadow stack as required for HWASAN
+ stack instrumentation.
+
+ Uses the vector of recorded stack variables hwasan_tagged_stack_vars. When
+ this function has completed hwasan_tagged_stack_vars is empty and all
+ objects it had pointed to are deallocated. */
+void
+hwasan_emit_prologue ()
+{
+ /* We need untagged base pointers since libhwasan only accepts untagged
+ pointers in __hwasan_tag_memory. We need the tagged base pointer to obtain
+ the base tag for an offset. */
+
+ if (hwasan_tagged_stack_vars.is_empty ())
+ return;
+
+ poly_int64 bot = 0, top = 0;
+ for (hwasan_stack_var &cur : hwasan_tagged_stack_vars)
+ {
+ poly_int64 nearest = cur.nearest_offset;
+ poly_int64 farthest = cur.farthest_offset;
+
+ if (known_ge (nearest, farthest))
+ {
+ top = nearest;
+ bot = farthest;
+ }
+ else
+ {
+ /* Given how these values are calculated, one must be known greater
+ than the other. */
+ gcc_assert (known_le (nearest, farthest));
+ top = farthest;
+ bot = nearest;
+ }
+ poly_int64 size = (top - bot);
+
+ /* Assert the edge of each variable is aligned to the HWASAN tag granule
+ size. */
+ gcc_assert (multiple_p (top, HWASAN_TAG_GRANULE_SIZE));
+ gcc_assert (multiple_p (bot, HWASAN_TAG_GRANULE_SIZE));
+ gcc_assert (multiple_p (size, HWASAN_TAG_GRANULE_SIZE));
+
+ rtx fn = init_one_libfunc ("__hwasan_tag_memory");
+ rtx base_tag = targetm.memtag.extract_tag (cur.tagged_base, NULL_RTX);
+ rtx tag = plus_constant (QImode, base_tag, cur.tag_offset);
+ tag = hwasan_truncate_to_tag_size (tag, NULL_RTX);
+
+ rtx bottom = convert_memory_address (ptr_mode,
+ plus_constant (Pmode,
+ cur.untagged_base,
+ bot));
+ emit_library_call (fn, LCT_NORMAL, VOIDmode,
+ bottom, ptr_mode,
+ tag, QImode,
+ gen_int_mode (size, ptr_mode), ptr_mode);
+ }
+ /* Clear the stack vars, we've emitted the prologue for them all now. */
+ hwasan_tagged_stack_vars.truncate (0);
+}
+
+/* For stack tagging:
+
+ Return RTL insns to clear the tags between DYNAMIC and VARS pointers
+ into the stack. These instructions should be emitted at the end of
+ every function.
+
+ If `dynamic` is NULL_RTX then no insns are returned. */
+rtx_insn *
+hwasan_emit_untag_frame (rtx dynamic, rtx vars)
+{
+ if (! dynamic)
+ return NULL;
+
+ start_sequence ();
+
+ dynamic = convert_memory_address (ptr_mode, dynamic);
+ vars = convert_memory_address (ptr_mode, vars);
+
+ rtx top_rtx;
+ rtx bot_rtx;
+ if (FRAME_GROWS_DOWNWARD)
+ {
+ top_rtx = vars;
+ bot_rtx = dynamic;
+ }
+ else
+ {
+ top_rtx = dynamic;
+ bot_rtx = vars;
+ }
+
+ rtx size_rtx = expand_simple_binop (ptr_mode, MINUS, top_rtx, bot_rtx,
+ NULL_RTX, /* unsignedp = */0,
+ OPTAB_DIRECT);
+
+ rtx fn = init_one_libfunc ("__hwasan_tag_memory");
+ emit_library_call (fn, LCT_NORMAL, VOIDmode,
+ bot_rtx, ptr_mode,
+ HWASAN_STACK_BACKGROUND, QImode,
+ size_rtx, ptr_mode);
+
+ do_pending_stack_adjust ();
+ rtx_insn *insns = get_insns ();
+ end_sequence ();
+ return insns;
+}
+
+/* Needs to be GTY(()), because cgraph_build_static_cdtor may
+ invoke ggc_collect. */
+static GTY(()) tree hwasan_ctor_statements;
+
+/* Insert module initialization into this TU. This initialization calls the
+ initialization code for libhwasan. */
+void
+hwasan_finish_file (void)
+{
+ /* Do not emit constructor initialization for the kernel.
+ (the kernel has its own initialization already). */
+ if (flag_sanitize & SANITIZE_KERNEL_HWADDRESS)
+ return;
+
+ /* Avoid instrumenting code in the hwasan constructors/destructors. */
+ flag_sanitize &= ~SANITIZE_HWADDRESS;
+ int priority = MAX_RESERVED_INIT_PRIORITY - 1;
+ tree fn = builtin_decl_implicit (BUILT_IN_HWASAN_INIT);
+ append_to_statement_list (build_call_expr (fn, 0), &hwasan_ctor_statements);
+ cgraph_build_static_cdtor ('I', hwasan_ctor_statements, priority);
+ flag_sanitize |= SANITIZE_HWADDRESS;
+}
+
+/* For stack tagging:
+
+ Truncate `tag` to the number of bits that a tag uses (i.e. to
+ HWASAN_TAG_SIZE). Store the result in `target` if it's convenient. */
+rtx
+hwasan_truncate_to_tag_size (rtx tag, rtx target)
+{
+ gcc_assert (GET_MODE (tag) == QImode);
+ if (HWASAN_TAG_SIZE != GET_MODE_PRECISION (QImode))
+ {
+ gcc_assert (GET_MODE_PRECISION (QImode) > HWASAN_TAG_SIZE);
+ rtx mask = gen_int_mode ((HOST_WIDE_INT_1U << HWASAN_TAG_SIZE) - 1,
+ QImode);
+ tag = expand_simple_binop (QImode, AND, tag, mask, target,
+ /* unsignedp = */1, OPTAB_WIDEN);
+ gcc_assert (tag);
+ }
+ return tag;
+}
+
+/* Construct a function tree for __hwasan_{load,store}{1,2,4,8,16,_n}.
+ IS_STORE is either 1 (for a store) or 0 (for a load). */
+static combined_fn
+hwasan_check_func (bool is_store, bool recover_p, HOST_WIDE_INT size_in_bytes,
+ int *nargs)
+{
+ static enum built_in_function check[2][2][6]
+ = { { { BUILT_IN_HWASAN_LOAD1, BUILT_IN_HWASAN_LOAD2,
+ BUILT_IN_HWASAN_LOAD4, BUILT_IN_HWASAN_LOAD8,
+ BUILT_IN_HWASAN_LOAD16, BUILT_IN_HWASAN_LOADN },
+ { BUILT_IN_HWASAN_STORE1, BUILT_IN_HWASAN_STORE2,
+ BUILT_IN_HWASAN_STORE4, BUILT_IN_HWASAN_STORE8,
+ BUILT_IN_HWASAN_STORE16, BUILT_IN_HWASAN_STOREN } },
+ { { BUILT_IN_HWASAN_LOAD1_NOABORT,
+ BUILT_IN_HWASAN_LOAD2_NOABORT,
+ BUILT_IN_HWASAN_LOAD4_NOABORT,
+ BUILT_IN_HWASAN_LOAD8_NOABORT,
+ BUILT_IN_HWASAN_LOAD16_NOABORT,
+ BUILT_IN_HWASAN_LOADN_NOABORT },
+ { BUILT_IN_HWASAN_STORE1_NOABORT,
+ BUILT_IN_HWASAN_STORE2_NOABORT,
+ BUILT_IN_HWASAN_STORE4_NOABORT,
+ BUILT_IN_HWASAN_STORE8_NOABORT,
+ BUILT_IN_HWASAN_STORE16_NOABORT,
+ BUILT_IN_HWASAN_STOREN_NOABORT } } };
+ if (size_in_bytes == -1)
+ {
+ *nargs = 2;
+ return as_combined_fn (check[recover_p][is_store][5]);
+ }
+ *nargs = 1;
+ int size_log2 = exact_log2 (size_in_bytes);
+ gcc_assert (size_log2 >= 0 && size_log2 <= 5);
+ return as_combined_fn (check[recover_p][is_store][size_log2]);
+}
+
+/* Expand the HWASAN_{LOAD,STORE} builtins. */
+bool
+hwasan_expand_check_ifn (gimple_stmt_iterator *iter, bool)
+{
+ gimple *g = gsi_stmt (*iter);
+ location_t loc = gimple_location (g);
+ bool recover_p;
+ if (flag_sanitize & SANITIZE_USER_HWADDRESS)
+ recover_p = (flag_sanitize_recover & SANITIZE_USER_HWADDRESS) != 0;
+ else
+ recover_p = (flag_sanitize_recover & SANITIZE_KERNEL_HWADDRESS) != 0;
+
+ HOST_WIDE_INT flags = tree_to_shwi (gimple_call_arg (g, 0));
+ gcc_assert (flags < ASAN_CHECK_LAST);
+ bool is_scalar_access = (flags & ASAN_CHECK_SCALAR_ACCESS) != 0;
+ bool is_store = (flags & ASAN_CHECK_STORE) != 0;
+ bool is_non_zero_len = (flags & ASAN_CHECK_NON_ZERO_LEN) != 0;
+
+ tree base = gimple_call_arg (g, 1);
+ tree len = gimple_call_arg (g, 2);
+
+ /* `align` is unused for HWASAN_CHECK, but we pass the argument anyway
+ since that way the arguments match ASAN_CHECK. */
+ /* HOST_WIDE_INT align = tree_to_shwi (gimple_call_arg (g, 3)); */
+
+ unsigned HOST_WIDE_INT size_in_bytes
+ = is_scalar_access ? tree_to_shwi (len) : -1;
+
+ gimple_stmt_iterator gsi = *iter;
+
+ if (!is_non_zero_len)
+ {
+ /* So, the length of the memory area to hwasan-protect is
+ non-constant. Let's guard the generated instrumentation code
+ like:
+
+ if (len != 0)
+ {
+ // hwasan instrumentation code goes here.
+ }
+ // falltrough instructions, starting with *ITER. */
+
+ g = gimple_build_cond (NE_EXPR,
+ len,
+ build_int_cst (TREE_TYPE (len), 0),
+ NULL_TREE, NULL_TREE);
+ gimple_set_location (g, loc);
+
+ basic_block then_bb, fallthrough_bb;
+ insert_if_then_before_iter (as_a <gcond *> (g), iter,
+ /*then_more_likely_p=*/true,
+ &then_bb, &fallthrough_bb);
+ /* Note that fallthrough_bb starts with the statement that was
+ pointed to by ITER. */
+
+ /* The 'then block' of the 'if (len != 0) condition is where
+ we'll generate the hwasan instrumentation code now. */
+ gsi = gsi_last_bb (then_bb);
+ }
+
+ gimple_seq stmts = NULL;
+ tree base_addr = gimple_build (&stmts, loc, NOP_EXPR,
+ pointer_sized_int_node, base);
+
+ int nargs = 0;
+ combined_fn fn
+ = hwasan_check_func (is_store, recover_p, size_in_bytes, &nargs);
+ if (nargs == 1)
+ gimple_build (&stmts, loc, fn, void_type_node, base_addr);
+ else
+ {
+ gcc_assert (nargs == 2);
+ tree sz_arg = gimple_build (&stmts, loc, NOP_EXPR,
+ pointer_sized_int_node, len);
+ gimple_build (&stmts, loc, fn, void_type_node, base_addr, sz_arg);
+ }
+
+ gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
+ gsi_remove (iter, true);
+ *iter = gsi;
+ return false;
+}
+
+/* For stack tagging:
+
+ Dummy: the HWASAN_MARK internal function should only ever be in the code
+ after the sanopt pass. */
+bool
+hwasan_expand_mark_ifn (gimple_stmt_iterator *)
+{
+ gcc_unreachable ();
+}
+
+bool
+gate_hwasan ()
+{
+ return hwasan_sanitize_p ();
+}
+
#include "gt-asan.h"
diff --git a/gcc/asan.h b/gcc/asan.h
index 114b457..4b873d6 100644
--- a/gcc/asan.h
+++ b/gcc/asan.h
@@ -34,6 +34,25 @@ extern bool asan_expand_mark_ifn (gimple_stmt_iterator *);
extern bool asan_expand_poison_ifn (gimple_stmt_iterator *, bool *,
hash_map<tree, tree> &);
+extern void hwasan_record_frame_init ();
+extern void hwasan_record_stack_var (rtx, rtx, poly_int64, poly_int64);
+extern void hwasan_emit_prologue ();
+extern rtx_insn *hwasan_emit_untag_frame (rtx, rtx);
+extern rtx hwasan_get_frame_extent ();
+extern rtx hwasan_frame_base ();
+extern void hwasan_maybe_emit_frame_base_init (void);
+extern bool stack_vars_base_reg_p (rtx);
+extern uint8_t hwasan_current_frame_tag ();
+extern void hwasan_increment_frame_tag ();
+extern rtx hwasan_truncate_to_tag_size (rtx, rtx);
+extern void hwasan_finish_file (void);
+extern bool hwasan_sanitize_p (void);
+extern bool hwasan_sanitize_stack_p (void);
+extern bool hwasan_sanitize_allocas_p (void);
+extern bool hwasan_expand_check_ifn (gimple_stmt_iterator *, bool);
+extern bool hwasan_expand_mark_ifn (gimple_stmt_iterator *);
+extern bool gate_hwasan (void);
+
extern gimple_stmt_iterator create_cond_insert_point
(gimple_stmt_iterator *, bool, bool, bool, basic_block *, basic_block *);
@@ -75,6 +94,26 @@ extern hash_set <tree> *asan_used_labels;
#define ASAN_USE_AFTER_SCOPE_ATTRIBUTE "use after scope memory"
+/* NOTE: The values below and the hooks under targetm.memtag define an ABI and
+ are hard-coded to these values in libhwasan, hence they can't be changed
+ independently here. */
+/* How many bits are used to store a tag in a pointer.
+ The default version uses the entire top byte of a pointer (i.e. 8 bits). */
+#define HWASAN_TAG_SIZE targetm.memtag.tag_size ()
+/* Tag Granule of HWASAN shadow stack.
+ This is the size in real memory that each byte in the shadow memory refers
+ to. I.e. if a variable is X bytes long in memory then its tag in shadow
+ memory will span X / HWASAN_TAG_GRANULE_SIZE bytes.
+ Most variables will need to be aligned to this amount since two variables
+ that are neighbors in memory and share a tag granule would need to share the
+ same tag (the shared tag granule can only store one tag). */
+#define HWASAN_TAG_GRANULE_SIZE targetm.memtag.granule_size ()
+/* Define the tag for the stack background.
+ This defines what tag the stack pointer will be and hence what tag all
+ variables that are not given special tags are (e.g. spilled registers,
+ and parameters passed on the stack). */
+#define HWASAN_STACK_BACKGROUND gen_int_mode (0, QImode)
+
/* Various flags for Asan builtins. */
enum asan_check_flags
{
@@ -145,6 +184,9 @@ extern hash_set<tree> *asan_handled_variables;
static inline bool
asan_intercepted_p (enum built_in_function fcode)
{
+ if (hwasan_sanitize_p ())
+ return false;
+
return fcode == BUILT_IN_INDEX
|| fcode == BUILT_IN_MEMCHR
|| fcode == BUILT_IN_MEMCMP
@@ -173,7 +215,8 @@ asan_intercepted_p (enum built_in_function fcode)
static inline bool
asan_sanitize_use_after_scope (void)
{
- return (flag_sanitize_address_use_after_scope && asan_sanitize_stack_p ());
+ return (flag_sanitize_address_use_after_scope
+ && (asan_sanitize_stack_p () || hwasan_sanitize_stack_p ()));
}
/* Return true if DECL should be guarded on the stack. */
diff --git a/gcc/attr-fnspec.h b/gcc/attr-fnspec.h
index 28135328..ccc36e1 100644
--- a/gcc/attr-fnspec.h
+++ b/gcc/attr-fnspec.h
@@ -41,6 +41,9 @@
written and does not escape
'w' or 'W' specifies that the memory pointed to by the parameter does not
escape
+ '1'....'9' specifies that the memory pointed to by the parameter is
+ copied to memory pointed to by different parameter
+ (as in memcpy).
'.' specifies that nothing is known.
The uppercase letter in addition specifies that the memory pointed to
by the parameter is not dereferenced. For 'r' only read applies
@@ -51,8 +54,8 @@
' ' nothing is known
't' the size of value written/read corresponds to the size of
of the pointed-to type of the argument type
- '1'...'9' the size of value written/read is given by the specified
- argument
+ '1'...'9' specifies the size of value written/read is given by the
+ specified argument
*/
#ifndef ATTR_FNSPEC_H
@@ -122,7 +125,8 @@ public:
{
unsigned int idx = arg_idx (i);
gcc_checking_assert (arg_specified_p (i));
- return str[idx] == 'R' || str[idx] == 'O' || str[idx] == 'W';
+ return str[idx] == 'R' || str[idx] == 'O'
+ || str[idx] == 'W' || (str[idx] >= '1' && str[idx] <= '9');
}
/* True if argument is used. */
@@ -140,7 +144,7 @@ public:
{
unsigned int idx = arg_idx (i);
gcc_checking_assert (arg_specified_p (i));
- return str[idx] == 'r' || str[idx] == 'R';
+ return str[idx] == 'r' || str[idx] == 'R' || (str[idx] >= '1' && str[idx] <= '9');
}
/* True if memory reached by the argument is read (directly or indirectly) */
@@ -161,6 +165,7 @@ public:
unsigned int idx = arg_idx (i);
gcc_checking_assert (arg_specified_p (i));
return str[idx] != 'r' && str[idx] != 'R'
+ && (str[idx] < '1' || str[idx] > '9')
&& str[idx] != 'x' && str[idx] != 'X';
}
@@ -190,6 +195,21 @@ public:
return str[idx + 1] == 't';
}
+ /* Return true if memory pointer to by argument is copied to a memory
+ pointed to by a different argument (as in memcpy).
+ In this case set ARG. */
+ bool
+ arg_copied_to_arg_p (unsigned int i, unsigned int *arg)
+ {
+ unsigned int idx = arg_idx (i);
+ gcc_checking_assert (arg_specified_p (i));
+ if (str[idx] < '1' || str[idx] > '9')
+ return false;
+ *arg = str[idx] - '1';
+ return true;
+ }
+
+
/* True if the argument does not escape. */
bool
arg_noescape_p (unsigned int i)
@@ -230,7 +250,7 @@ public:
return str[1] != 'c' && str[1] != 'C';
}
- /* Return true if all memory written by the function
+ /* Return true if all memory written by the function
is specified by fnspec. */
bool
global_memory_written_p ()
diff --git a/gcc/bitmap.c b/gcc/bitmap.c
index 810b80b..c849b0d 100644
--- a/gcc/bitmap.c
+++ b/gcc/bitmap.c
@@ -678,6 +678,11 @@ bitmap_list_view (bitmap head)
}
head->tree_form = false;
+ if (!head->current)
+ {
+ head->current = head->first;
+ head->indx = head->current ? head->current->indx : 0;
+ }
}
/* Convert bitmap HEAD from linked-list view to splay-tree view.
diff --git a/gcc/brig/ChangeLog b/gcc/brig/ChangeLog
index b8fefa5..518b13a 100644
--- a/gcc/brig/ChangeLog
+++ b/gcc/brig/ChangeLog
@@ -1,3 +1,16 @@
+2020-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/97911
+ * Make-lang.in (brig.serial): Change from goal to a variable.
+ (.PHONY): Drop brig.serial and brig.prev.
+ (brig1$(exeext)): Depend on $(brig.serial) rather than brig.serial.
+
+2020-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ * Make-lang.in (brig.serial): New goal.
+ (.PHONY): Add brig.serial brig.prev.
+ (brig1$(exeext)): Depend on brig.prev. Call LINK_PROGRESS.
+
2020-08-03 Martin Jambor <mjambor@suse.cz>
* brigfrontend/brig-util.h (hsa_type_packed_p): Declared.
diff --git a/gcc/brig/Make-lang.in b/gcc/brig/Make-lang.in
index f553856..0141b982 100644
--- a/gcc/brig/Make-lang.in
+++ b/gcc/brig/Make-lang.in
@@ -29,6 +29,7 @@ GCCBRIG_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo gccbrig|sed \
# The name for selecting brig in LANGUAGES.
brig: brig1$(exeext)
+brig.serial = brig1$(exeext)
.PHONY: brig
@@ -81,15 +82,12 @@ BRIG_OBJS = \
brig_OBJS = $(BRIG_OBJS) brig/brigspec.o
-# brig1$(exeext): $(BRIG_OBJS) attribs.o $(BACKEND) $(LIBDEPS)
-# +$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
-# $(BRIG_OBJS) attribs.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
-
-
-brig1$(exeext): $(BRIG_OBJS) attribs.o $(BACKEND) $(LIBDEPS)
+brig1$(exeext): $(BRIG_OBJS) attribs.o $(BACKEND) $(LIBDEPS) $(brig.prev)
+ @$(call LINK_PROGRESS,$(INDEX.brig),start)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(BRIG_OBJS) attribs.o $(BACKEND) $(LIBS) \
$(BACKENDLIBS)
+ @$(call LINK_PROGRESS,$(INDEX.brig),end)
# Documentation.
diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def
index c46b1bc..770f357 100644
--- a/gcc/builtin-types.def
+++ b/gcc/builtin-types.def
@@ -503,6 +503,7 @@ DEF_FUNCTION_TYPE_2 (BT_FN_INT_FEXCEPT_T_PTR_INT, BT_INT, BT_FEXCEPT_T_PTR,
BT_INT)
DEF_FUNCTION_TYPE_2 (BT_FN_INT_CONST_FEXCEPT_T_PTR_INT, BT_INT,
BT_CONST_FEXCEPT_T_PTR, BT_INT)
+DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_UINT8, BT_PTR, BT_CONST_PTR, BT_UINT8)
DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR_PTR, BT_FN_VOID_PTR_PTR)
@@ -637,6 +638,10 @@ DEF_FUNCTION_TYPE_3 (BT_FN_VOID_SIZE_SIZE_PTR, BT_VOID, BT_SIZE, BT_SIZE,
DEF_FUNCTION_TYPE_3 (BT_FN_UINT_UINT_PTR_PTR, BT_UINT, BT_UINT, BT_PTR, BT_PTR)
DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_CONST_SIZE_BOOL,
BT_PTR, BT_PTR, BT_CONST_SIZE, BT_BOOL)
+DEF_FUNCTION_TYPE_3 (BT_FN_PTR_SIZE_SIZE_PTRMODE,
+ BT_PTR, BT_SIZE, BT_SIZE, BT_PTRMODE)
+DEF_FUNCTION_TYPE_3 (BT_FN_VOID_PTR_UINT8_PTRMODE, BT_VOID, BT_PTR, BT_UINT8,
+ BT_PTRMODE)
DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR,
BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_FILEPTR)
diff --git a/gcc/builtins.c b/gcc/builtins.c
index da25343..cd30de8 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -185,6 +185,8 @@ static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
static void maybe_emit_free_warning (tree);
static tree fold_builtin_object_size (tree, tree);
static bool check_read_access (tree, tree, tree = NULL_TREE, int = 1);
+static bool compute_objsize_r (tree, int, access_ref *, ssa_name_limit_t &,
+ pointer_query *);
unsigned HOST_WIDE_INT target_newline;
unsigned HOST_WIDE_INT target_percent;
@@ -199,7 +201,8 @@ static void expand_builtin_sync_synchronize (void);
access_ref::access_ref (tree bound /* = NULL_TREE */,
bool minaccess /* = false */)
-: ref (), eval ([](tree x){ return x; }), trail1special (true), base0 (true)
+: ref (), eval ([](tree x){ return x; }), trail1special (true), base0 (true),
+ parmarray ()
{
/* Set to valid. */
offrng[0] = offrng[1] = 0;
@@ -222,6 +225,181 @@ access_ref::access_ref (tree bound /* = NULL_TREE */,
}
}
+/* Return the PHI node REF refers to or null if it doesn't. */
+
+gphi *
+access_ref::phi () const
+{
+ if (!ref || TREE_CODE (ref) != SSA_NAME)
+ return NULL;
+
+ gimple *def_stmt = SSA_NAME_DEF_STMT (ref);
+ if (gimple_code (def_stmt) != GIMPLE_PHI)
+ return NULL;
+
+ return as_a <gphi *> (def_stmt);
+}
+
+/* Determine and return the largest object to which *THIS. If *THIS
+ refers to a PHI and PREF is nonnull, fill *PREF with the details
+ of the object determined by compute_objsize(ARG, OSTYPE) for each
+ PHI argument ARG. */
+
+tree
+access_ref::get_ref (vec<access_ref> *all_refs,
+ access_ref *pref /* = NULL */,
+ int ostype /* = 1 */,
+ ssa_name_limit_t *psnlim /* = NULL */,
+ pointer_query *qry /* = NULL */) const
+{
+ gphi *phi_stmt = this->phi ();
+ if (!phi_stmt)
+ return ref;
+
+ /* FIXME: Calling get_ref() with a null PSNLIM is dangerous and might
+ cause unbounded recursion. */
+ ssa_name_limit_t snlim_buf;
+ if (!psnlim)
+ psnlim = &snlim_buf;
+
+ if (!psnlim->visit_phi (ref))
+ return NULL_TREE;
+
+ /* Reflects the range of offsets of all PHI arguments refer to the same
+ object (i.e., have the same REF). */
+ access_ref same_ref;
+ /* The conservative result of the PHI reflecting the offset and size
+ of the largest PHI argument, regardless of whether or not they all
+ refer to the same object. */
+ pointer_query empty_qry;
+ if (!qry)
+ qry = &empty_qry;
+
+ access_ref phi_ref;
+ if (pref)
+ {
+ phi_ref = *pref;
+ same_ref = *pref;
+ }
+
+ /* Set if any argument is a function array (or VLA) parameter not
+ declared [static]. */
+ bool parmarray = false;
+ /* The size of the smallest object referenced by the PHI arguments. */
+ offset_int minsize = 0;
+ const offset_int maxobjsize = wi::to_offset (max_object_size ());
+ /* The offset of the PHI, not reflecting those of its arguments. */
+ const offset_int orng[2] = { phi_ref.offrng[0], phi_ref.offrng[1] };
+
+ const unsigned nargs = gimple_phi_num_args (phi_stmt);
+ for (unsigned i = 0; i < nargs; ++i)
+ {
+ access_ref phi_arg_ref;
+ tree arg = gimple_phi_arg_def (phi_stmt, i);
+ if (!compute_objsize_r (arg, ostype, &phi_arg_ref, *psnlim, qry)
+ || phi_arg_ref.sizrng[0] < 0)
+ /* A PHI with all null pointer arguments. */
+ return NULL_TREE;
+
+ /* Add PREF's offset to that of the argument. */
+ phi_arg_ref.add_offset (orng[0], orng[1]);
+ if (TREE_CODE (arg) == SSA_NAME)
+ qry->put_ref (arg, phi_arg_ref);
+
+ if (all_refs)
+ all_refs->safe_push (phi_arg_ref);
+
+ const bool arg_known_size = (phi_arg_ref.sizrng[0] != 0
+ || phi_arg_ref.sizrng[1] != maxobjsize);
+
+ parmarray |= phi_arg_ref.parmarray;
+
+ const bool nullp = integer_zerop (arg) && (i || i + 1 < nargs);
+
+ if (phi_ref.sizrng[0] < 0)
+ {
+ if (!nullp)
+ same_ref = phi_arg_ref;
+ phi_ref = phi_arg_ref;
+ if (arg_known_size)
+ minsize = phi_arg_ref.sizrng[0];
+ continue;
+ }
+
+ const bool phi_known_size = (phi_ref.sizrng[0] != 0
+ || phi_ref.sizrng[1] != maxobjsize);
+
+ if (phi_known_size && phi_arg_ref.sizrng[0] < minsize)
+ minsize = phi_arg_ref.sizrng[0];
+
+ /* Disregard null pointers in PHIs with two or more arguments.
+ TODO: Handle this better! */
+ if (nullp)
+ continue;
+
+ /* Determine the amount of remaining space in the argument. */
+ offset_int argrem[2];
+ argrem[1] = phi_arg_ref.size_remaining (argrem);
+
+ /* Determine the amount of remaining space computed so far and
+ if the remaining space in the argument is more use it instead. */
+ offset_int phirem[2];
+ phirem[1] = phi_ref.size_remaining (phirem);
+
+ if (phi_arg_ref.ref != same_ref.ref)
+ same_ref.ref = NULL_TREE;
+
+ if (phirem[1] < argrem[1]
+ || (phirem[1] == argrem[1]
+ && phi_ref.sizrng[1] < phi_arg_ref.sizrng[1]))
+ /* Use the argument with the most space remaining as the result,
+ or the larger one if the space is equal. */
+ phi_ref = phi_arg_ref;
+
+ /* Set SAME_REF.OFFRNG to the maximum range of all arguments. */
+ if (phi_arg_ref.offrng[0] < same_ref.offrng[0])
+ same_ref.offrng[0] = phi_arg_ref.offrng[0];
+ if (same_ref.offrng[1] < phi_arg_ref.offrng[1])
+ same_ref.offrng[1] = phi_arg_ref.offrng[1];
+ }
+
+ if (phi_ref.sizrng[0] < 0)
+ {
+ /* Fail if none of the PHI's arguments resulted in updating PHI_REF
+ (perhaps because they have all been already visited by prior
+ recursive calls). */
+ psnlim->leave_phi (ref);
+ return NULL_TREE;
+ }
+
+ if (!same_ref.ref && same_ref.offrng[0] != 0)
+ /* Clear BASE0 if not all the arguments refer to the same object and
+ if not all their offsets are zero-based. This allows the final
+ PHI offset to out of bounds for some arguments but not for others
+ (or negative even of all the arguments are BASE0), which is overly
+ permissive. */
+ phi_ref.base0 = false;
+
+ if (same_ref.ref)
+ phi_ref = same_ref;
+ else
+ {
+ /* Replace the lower bound of the largest argument with the size
+ of the smallest argument, and set PARMARRAY if any argument
+ was one. */
+ phi_ref.sizrng[0] = minsize;
+ phi_ref.parmarray = parmarray;
+ }
+
+ /* Avoid changing *THIS. */
+ if (pref && pref != this)
+ *pref = phi_ref;
+
+ psnlim->leave_phi (ref);
+
+ return phi_ref.ref;
+}
+
/* Return the maximum amount of space remaining and if non-null, set
argument to the minimum. */
@@ -318,7 +496,6 @@ void access_ref::add_offset (const offset_int &min, const offset_int &max)
return;
}
- offrng[1] = maxoff;
offset_int absmax = wi::abs (max);
if (offrng[0] < absmax)
{
@@ -353,6 +530,210 @@ void access_ref::add_offset (const offset_int &min, const offset_int &max)
}
}
+/* Set a bit for the PHI in VISITED and return true if it wasn't
+ already set. */
+
+bool
+ssa_name_limit_t::visit_phi (tree ssa_name)
+{
+ if (!visited)
+ visited = BITMAP_ALLOC (NULL);
+
+ /* Return false if SSA_NAME has already been visited. */
+ return bitmap_set_bit (visited, SSA_NAME_VERSION (ssa_name));
+}
+
+/* Clear a bit for the PHI in VISITED. */
+
+void
+ssa_name_limit_t::leave_phi (tree ssa_name)
+{
+ /* Return false if SSA_NAME has already been visited. */
+ bitmap_clear_bit (visited, SSA_NAME_VERSION (ssa_name));
+}
+
+/* Return false if the SSA_NAME chain length counter has reached
+ the limit, otherwise increment the counter and return true. */
+
+bool
+ssa_name_limit_t::next ()
+{
+ /* Return a negative value to let caller avoid recursing beyond
+ the specified limit. */
+ if (ssa_def_max == 0)
+ return false;
+
+ --ssa_def_max;
+ return true;
+}
+
+/* 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_phi (tree ssa_name)
+{
+ {
+ gimple *def_stmt = SSA_NAME_DEF_STMT (ssa_name);
+ /* Return a positive value if the PHI has already been visited. */
+ if (gimple_code (def_stmt) == GIMPLE_PHI
+ && !visit_phi (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;
+}
+
+ssa_name_limit_t::~ssa_name_limit_t ()
+{
+ if (visited)
+ BITMAP_FREE (visited);
+}
+
+/* Default ctor. Initialize object with pointers to the range_query
+ and cache_type instances to use or null. */
+
+pointer_query::pointer_query (range_query *qry /* = NULL */,
+ cache_type *cache /* = NULL */)
+: rvals (qry), var_cache (cache), hits (), misses (),
+ failures (), depth (), max_depth ()
+{
+ /* No op. */
+}
+
+/* Return a pointer to the cached access_ref instance for the SSA_NAME
+ PTR if it's there or null otherwise. */
+
+const access_ref *
+pointer_query::get_ref (tree ptr, int ostype /* = 1 */) const
+{
+ if (!var_cache)
+ {
+ ++misses;
+ return NULL;
+ }
+
+ unsigned version = SSA_NAME_VERSION (ptr);
+ unsigned idx = version << 1 | (ostype & 1);
+ if (var_cache->indices.length () <= idx)
+ {
+ ++misses;
+ return NULL;
+ }
+
+ unsigned cache_idx = var_cache->indices[idx];
+ if (var_cache->access_refs.length () <= cache_idx)
+ {
+ ++misses;
+ return NULL;
+ }
+
+ access_ref &cache_ref = var_cache->access_refs[cache_idx];
+ if (cache_ref.ref)
+ {
+ ++hits;
+ return &cache_ref;
+ }
+
+ ++misses;
+ return NULL;
+}
+
+/* Retrieve the access_ref instance for a variable from the cache if it's
+ there or compute it and insert it into the cache if it's nonnonull. */
+
+bool
+pointer_query::get_ref (tree ptr, access_ref *pref, int ostype /* = 1 */)
+{
+ const unsigned version
+ = TREE_CODE (ptr) == SSA_NAME ? SSA_NAME_VERSION (ptr) : 0;
+
+ if (var_cache && version)
+ {
+ unsigned idx = version << 1 | (ostype & 1);
+ if (idx < var_cache->indices.length ())
+ {
+ unsigned cache_idx = var_cache->indices[idx] - 1;
+ if (cache_idx < var_cache->access_refs.length ()
+ && var_cache->access_refs[cache_idx].ref)
+ {
+ ++hits;
+ *pref = var_cache->access_refs[cache_idx];
+ return true;
+ }
+ }
+
+ ++misses;
+ }
+
+ if (!compute_objsize (ptr, ostype, pref, this))
+ {
+ ++failures;
+ return false;
+ }
+
+ return true;
+}
+
+/* Add a copy of the access_ref REF for the SSA_NAME to the cache if it's
+ nonnull. */
+
+void
+pointer_query::put_ref (tree ptr, const access_ref &ref, int ostype /* = 1 */)
+{
+ /* Only add populated/valid entries. */
+ if (!var_cache || !ref.ref || ref.sizrng[0] < 0)
+ return;
+
+ /* Add REF to the two-level cache. */
+ unsigned version = SSA_NAME_VERSION (ptr);
+ unsigned idx = version << 1 | (ostype & 1);
+
+ /* Grow INDICES if necessary. An index is valid if it's nonzero.
+ Its value minus one is the index into ACCESS_REFS. Not all
+ entries are valid. */
+ if (var_cache->indices.length () <= idx)
+ var_cache->indices.safe_grow_cleared (idx + 1);
+
+ if (!var_cache->indices[idx])
+ var_cache->indices[idx] = var_cache->access_refs.length () + 1;
+
+ /* Grow ACCESS_REF cache if necessary. An entry is valid if its
+ REF member is nonnull. All entries except for the last two
+ are valid. Once nonnull, the REF value must stay unchanged. */
+ unsigned cache_idx = var_cache->indices[idx];
+ if (var_cache->access_refs.length () <= cache_idx)
+ var_cache->access_refs.safe_grow_cleared (cache_idx + 1);
+
+ access_ref cache_ref = var_cache->access_refs[cache_idx - 1];
+ if (cache_ref.ref)
+ {
+ gcc_checking_assert (cache_ref.ref == ref.ref);
+ return;
+ }
+
+ cache_ref = ref;
+}
+
+/* Flush the cache if it's nonnull. */
+
+void
+pointer_query::flush_cache ()
+{
+ if (!var_cache)
+ return;
+ var_cache->indices.release ();
+ var_cache->access_refs.release ();
+}
+
/* Return true if NAME starts with __builtin_ or __sync_. */
static bool
@@ -2228,6 +2609,7 @@ type_to_class (tree type)
case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
? string_type_class : array_type_class);
case LANG_TYPE: return lang_type_class;
+ case OPAQUE_TYPE: return opaque_type_class;
default: return no_type_class;
}
}
@@ -3560,28 +3942,42 @@ maybe_warn_for_bound (int opt, location_t loc, tree exp, tree func,
if (opt == OPT_Wstringop_overread)
{
+ bool maybe = pad && pad->src.phi ();
+
if (tree_int_cst_lt (maxobjsize, bndrng[0]))
{
if (bndrng[0] == bndrng[1])
warned = (func
? warning_at (loc, opt,
- "%K%qD specified bound %E "
- "exceeds maximum object size %E",
+ (maybe
+ ? G_("%K%qD specified bound %E may "
+ "exceed maximum object size %E")
+ : G_("%K%qD specified bound %E "
+ "exceeds maximum object size %E")),
exp, func, bndrng[0], maxobjsize)
: warning_at (loc, opt,
- "%Kspecified bound %E "
- "exceeds maximum object size %E",
+ (maybe
+ ? G_("%Kspecified bound %E may "
+ "exceed maximum object size %E")
+ : G_("%Kspecified bound %E "
+ "exceeds maximum object size %E")),
exp, bndrng[0], maxobjsize));
else
warned = (func
? warning_at (loc, opt,
- "%K%qD specified bound [%E, %E] "
- "exceeds maximum object size %E",
+ (maybe
+ ? G_("%K%qD specified bound [%E, %E] may "
+ "exceed maximum object size %E")
+ : G_("%K%qD specified bound [%E, %E] "
+ "exceeds maximum object size %E")),
exp, func,
bndrng[0], bndrng[1], maxobjsize)
: warning_at (loc, opt,
- "%Kspecified bound [%E, %E] "
- "exceeds maximum object size %E",
+ (maybe
+ ? G_("%Kspecified bound [%E, %E] may "
+ "exceed maximum object size %E")
+ : G_("%Kspecified bound [%E, %E] "
+ "exceeds maximum object size %E")),
exp, bndrng[0], bndrng[1], maxobjsize));
}
else if (!size || tree_int_cst_le (bndrng[0], size))
@@ -3589,22 +3985,34 @@ maybe_warn_for_bound (int opt, location_t loc, tree exp, tree func,
else if (tree_int_cst_equal (bndrng[0], bndrng[1]))
warned = (func
? warning_at (loc, opt,
- "%K%qD specified bound %E exceeds "
- "source size %E",
+ (maybe
+ ? G_("%K%qD specified bound %E may exceed "
+ "source size %E")
+ : G_("%K%qD specified bound %E exceeds "
+ "source size %E")),
exp, func, bndrng[0], size)
: warning_at (loc, opt,
- "%Kspecified bound %E exceeds "
- "source size %E",
+ (maybe
+ ? G_("%Kspecified bound %E may exceed "
+ "source size %E")
+ : G_("%Kspecified bound %E exceeds "
+ "source size %E")),
exp, bndrng[0], size));
else
warned = (func
? warning_at (loc, opt,
- "%K%qD specified bound [%E, %E] exceeds "
- "source size %E",
+ (maybe
+ ? G_("%K%qD specified bound [%E, %E] may "
+ "exceed source size %E")
+ : G_("%K%qD specified bound [%E, %E] exceeds "
+ "source size %E")),
exp, func, bndrng[0], bndrng[1], size)
: warning_at (loc, opt,
- "%Kspecified bound [%E, %E] exceeds "
- "source size %E",
+ (maybe
+ ? G_("%Kspecified bound [%E, %E] may exceed "
+ "source size %E")
+ : G_("%Kspecified bound [%E, %E] exceeds "
+ "source size %E")),
exp, bndrng[0], bndrng[1], size));
if (warned)
{
@@ -3623,28 +4031,41 @@ maybe_warn_for_bound (int opt, location_t loc, tree exp, tree func,
return warned;
}
+ bool maybe = pad && pad->dst.phi ();
if (tree_int_cst_lt (maxobjsize, bndrng[0]))
{
if (bndrng[0] == bndrng[1])
warned = (func
? warning_at (loc, opt,
- "%K%qD specified size %E "
- "exceeds maximum object size %E",
+ (maybe
+ ? G_("%K%qD specified size %E may "
+ "exceed maximum object size %E")
+ : G_("%K%qD specified size %E "
+ "exceeds maximum object size %E")),
exp, func, bndrng[0], maxobjsize)
: warning_at (loc, opt,
- "%Kspecified size %E "
- "exceeds maximum object size %E",
+ (maybe
+ ? G_("%Kspecified size %E may exceed "
+ "maximum object size %E")
+ : G_("%Kspecified size %E exceeds "
+ "maximum object size %E")),
exp, bndrng[0], maxobjsize));
else
warned = (func
? warning_at (loc, opt,
- "%K%qD specified size between %E and %E "
- "exceeds maximum object size %E",
+ (maybe
+ ? G_("%K%qD specified size between %E and %E "
+ "may exceed maximum object size %E")
+ : G_("%K%qD specified size between %E and %E "
+ "exceeds maximum object size %E")),
exp, func,
bndrng[0], bndrng[1], maxobjsize)
: warning_at (loc, opt,
- "%Kspecified size between %E and %E "
- "exceeds maximum object size %E",
+ (maybe
+ ? G_("%Kspecified size between %E and %E "
+ "may exceed maximum object size %E")
+ : G_("%Kspecified size between %E and %E "
+ "exceeds maximum object size %E")),
exp, bndrng[0], bndrng[1], maxobjsize));
}
else if (!size || tree_int_cst_le (bndrng[0], size))
@@ -3652,22 +4073,34 @@ maybe_warn_for_bound (int opt, location_t loc, tree exp, tree func,
else if (tree_int_cst_equal (bndrng[0], bndrng[1]))
warned = (func
? warning_at (loc, OPT_Wstringop_overflow_,
- "%K%qD specified bound %E exceeds "
- "destination size %E",
+ (maybe
+ ? G_("%K%qD specified bound %E may exceed "
+ "destination size %E")
+ : G_("%K%qD specified bound %E exceeds "
+ "destination size %E")),
exp, func, bndrng[0], size)
: warning_at (loc, OPT_Wstringop_overflow_,
- "%Kspecified bound %E exceeds "
- "destination size %E",
+ (maybe
+ ? G_("%Kspecified bound %E may exceed "
+ "destination size %E")
+ : G_("%Kspecified bound %E exceeds "
+ "destination size %E")),
exp, bndrng[0], size));
else
warned = (func
? warning_at (loc, OPT_Wstringop_overflow_,
- "%K%qD specified bound [%E, %E] exceeds "
- "destination size %E",
+ (maybe
+ ? G_("%K%qD specified bound [%E, %E] may exceed "
+ "destination size %E")
+ : G_("%K%qD specified bound [%E, %E] exceeds "
+ "destination size %E")),
exp, func, bndrng[0], bndrng[1], size)
: warning_at (loc, OPT_Wstringop_overflow_,
- "%Kspecified bound [%E, %E] exceeds "
- "destination size %E",
+ (maybe
+ ? G_("%Kspecified bound [%E, %E] exceeds "
+ "destination size %E")
+ : G_("%Kspecified bound [%E, %E] exceeds "
+ "destination size %E")),
exp, bndrng[0], bndrng[1], size));
if (warned)
@@ -3696,7 +4129,7 @@ maybe_warn_for_bound (int opt, location_t loc, tree exp, tree func,
static bool
warn_for_access (location_t loc, tree func, tree exp, int opt, tree range[2],
- tree size, bool write, bool read)
+ tree size, bool write, bool read, bool maybe)
{
bool warned = false;
@@ -3705,40 +4138,64 @@ warn_for_access (location_t loc, tree func, tree exp, int opt, tree range[2],
if (tree_int_cst_equal (range[0], range[1]))
warned = (func
? warning_n (loc, opt, tree_to_uhwi (range[0]),
- "%K%qD accessing %E byte in a region "
- "of size %E",
- "%K%qD accessing %E bytes in a region "
- "of size %E",
+ (maybe
+ ? G_("%K%qD may access %E byte in a region "
+ "of size %E")
+ : G_("%K%qD accessing %E byte in a region "
+ "of size %E")),
+ (maybe
+ ? G_ ("%K%qD may access %E bytes in a region "
+ "of size %E")
+ : G_ ("%K%qD accessing %E bytes in a region "
+ "of size %E")),
exp, func, range[0], size)
: warning_n (loc, opt, tree_to_uhwi (range[0]),
- "%Kaccessing %E byte in a region "
- "of size %E",
- "%Kaccessing %E bytes in a region "
- "of size %E",
+ (maybe
+ ? G_("%Kmay access %E byte in a region "
+ "of size %E")
+ : G_("%Kaccessing %E byte in a region "
+ "of size %E")),
+ (maybe
+ ? G_("%Kmay access %E bytes in a region "
+ "of size %E")
+ : G_("%Kaccessing %E bytes in a region "
+ "of size %E")),
exp, range[0], size));
else if (tree_int_cst_sign_bit (range[1]))
{
/* Avoid printing the upper bound if it's invalid. */
warned = (func
? warning_at (loc, opt,
- "%K%qD accessing %E or more bytes in "
- "a region of size %E",
+ (maybe
+ ? G_("%K%qD may access %E or more bytes "
+ "in a region of size %E")
+ : G_("%K%qD accessing %E or more bytes "
+ "in a region of size %E")),
exp, func, range[0], size)
: warning_at (loc, opt,
- "%Kaccessing %E or more bytes in "
- "a region of size %E",
+ (maybe
+ ? G_("%Kmay access %E or more bytes "
+ "in a region of size %E")
+ : G_("%Kaccessing %E or more bytes "
+ "in a region of size %E")),
exp, range[0], size));
}
else
warned = (func
? warning_at (loc, opt,
- "%K%qD accessing between %E and %E bytes "
- "in a region of size %E",
+ (maybe
+ ? G_("%K%qD may access between %E and %E "
+ "bytes in a region of size %E")
+ : G_("%K%qD accessing between %E and %E "
+ "bytes in a region of size %E")),
exp, func, range[0], range[1],
size)
: warning_at (loc, opt,
- "%Kaccessing between %E and %E bytes "
- "in a region of size %E",
+ (maybe
+ ? G_("%Kmay access between %E and %E bytes "
+ "in a region of size %E")
+ : G_("%Kaccessing between %E and %E bytes "
+ "in a region of size %E")),
exp, range[0], range[1],
size));
return warned;
@@ -3749,44 +4206,69 @@ warn_for_access (location_t loc, tree func, tree exp, int opt, tree range[2],
if (tree_int_cst_equal (range[0], range[1]))
warned = (func
? warning_n (loc, opt, tree_to_uhwi (range[0]),
- "%K%qD writing %E byte into a region "
- "of size %E overflows the destination",
- "%K%qD writing %E bytes into a region "
- "of size %E overflows the destination",
+ (maybe
+ ? G_("%K%qD may write %E byte into a region "
+ "of size %E")
+ : G_("%K%qD writing %E byte into a region "
+ "of size %E overflows the destination")),
+ (maybe
+ ? G_("%K%qD may write %E bytes into a region "
+ "of size %E")
+ : G_("%K%qD writing %E bytes into a region "
+ "of size %E overflows the destination")),
exp, func, range[0], size)
: warning_n (loc, opt, tree_to_uhwi (range[0]),
- "%Kwriting %E byte into a region "
- "of size %E overflows the destination",
- "%Kwriting %E bytes into a region "
- "of size %E overflows the destination",
+ (maybe
+ ? G_("%Kmay write %E byte into a region "
+ "of size %E")
+ : G_("%Kwriting %E byte into a region "
+ "of size %E overflows the destination")),
+ (maybe
+ ? G_("%Kmay write %E bytes into a region "
+ "of size %E")
+ : G_("%Kwriting %E bytes into a region "
+ "of size %E overflows the destination")),
exp, range[0], size));
else if (tree_int_cst_sign_bit (range[1]))
{
/* Avoid printing the upper bound if it's invalid. */
warned = (func
? warning_at (loc, opt,
- "%K%qD writing %E or more bytes into "
- "a region of size %E overflows "
- "the destination",
+ (maybe
+ ? G_("%K%qD may write %E or more bytes "
+ "into a region of size %E "
+ "the destination")
+ : G_("%K%qD writing %E or more bytes "
+ "into a region of size %E overflows "
+ "the destination")),
exp, func, range[0], size)
: warning_at (loc, opt,
- "%Kwriting %E or more bytes into "
- "a region of size %E overflows "
- "the destination",
+ (maybe
+ ? G_("%Kmay write %E or more bytes into "
+ "a region of size %E")
+ : G_("%Kwriting %E or more bytes into "
+ "a region of size %E overflows "
+ "the destination")),
exp, range[0], size));
}
else
warned = (func
? warning_at (loc, opt,
- "%K%qD writing between %E and %E bytes "
- "into a region of size %E overflows "
- "the destination",
+ (maybe
+ ? G_("%K%qD may write between %E and %E bytes "
+ "into a region of size %E")
+ : G_("%K%qD writing between %E and %E bytes "
+ "into a region of size %E overflows "
+ "the destination")),
exp, func, range[0], range[1],
size)
: warning_at (loc, opt,
- "%Kwriting between %E and %E bytes "
- "into a region of size %E overflows "
- "the destination",
+ (maybe
+ ? G_("%Kmay write between %E and %E bytes "
+ "into a region of size %E")
+ : G_("%Kwriting between %E and %E bytes "
+ "into a region of size %E overflows "
+ "the destination")),
exp, range[0], range[1],
size));
return warned;
@@ -3798,35 +4280,64 @@ warn_for_access (location_t loc, tree func, tree exp, int opt, tree range[2],
warned = (func
? warning_n (loc, OPT_Wstringop_overread,
tree_to_uhwi (range[0]),
- "%K%qD reading %E byte from a region of size %E",
- "%K%qD reading %E bytes from a region of size %E", exp, func, range[0], size)
+ (maybe
+ ? G_("%K%qD may reade %E byte from a region "
+ "of size %E")
+ : G_("%K%qD reading %E byte from a region "
+ "of size %E")),
+ (maybe
+ ? G_("%K%qD may read %E bytes from a region "
+ "of size %E")
+ : G_("%K%qD reading %E bytes from a region "
+ "of size %E")),
+ exp, func, range[0], size)
: warning_n (loc, OPT_Wstringop_overread,
tree_to_uhwi (range[0]),
- "%Kreading %E byte from a region of size %E",
- "%Kreading %E bytes from a region of size %E",
+ (maybe
+ ? G_("%Kmay read %E byte from a region "
+ "of size %E")
+ : G_("%Kreading %E byte from a region "
+ "of size %E")),
+ (maybe
+ ? G_("%Kmay read %E bytes from a region "
+ "of size %E")
+ : G_("%Kreading %E bytes from a region "
+ "of size %E")),
exp, range[0], size));
else if (tree_int_cst_sign_bit (range[1]))
{
/* Avoid printing the upper bound if it's invalid. */
warned = (func
? warning_at (loc, OPT_Wstringop_overread,
- "%K%qD reading %E or more bytes from "
- "a region of size %E",
+ (maybe
+ ? G_("%K%qD may read %E or more bytes "
+ "from a region of size %E")
+ : G_("%K%qD reading %E or more bytes "
+ "from a region of size %E")),
exp, func, range[0], size)
: warning_at (loc, OPT_Wstringop_overread,
- "%Kreading %E or more bytes from a region "
- "of size %E",
+ (maybe
+ ? G_("%Kmay read %E or more bytes "
+ "from a region of size %E")
+ : G_("%Kreading %E or more bytes "
+ "from a region of size %E")),
exp, range[0], size));
}
else
warned = (func
? warning_at (loc, OPT_Wstringop_overread,
- "%K%qD reading between %E and %E bytes from "
- "a region of size %E",
+ (maybe
+ ? G_("%K%qD may read between %E and %E bytes "
+ "from a region of size %E")
+ : G_("%K%qD reading between %E and %E bytes "
+ "from a region of size %E")),
exp, func, range[0], range[1], size)
: warning_at (loc, opt,
- "%K reading between %E and %E bytes from "
- "a region of size %E",
+ (maybe
+ ? G_("%Kmay read between %E and %E bytes "
+ "from a region of size %E")
+ : G_("%Kreading between %E and %E bytes "
+ "from a region of size %E")),
exp, range[0], range[1], size));
if (warned)
@@ -3878,28 +4389,61 @@ warn_for_access (location_t loc, tree func, tree exp, int opt, tree range[2],
return warned;
}
-/* Issue an inform message describing the target of an access REF.
+/* Issue one inform message describing each target of an access REF.
WRITE is set for a write access and clear for a read access. */
-static void
-inform_access (const access_ref &ref, access_mode mode)
+void
+access_ref::inform_access (access_mode mode) const
{
- if (!ref.ref)
+ const access_ref &aref = *this;
+ if (!aref.ref)
return;
+ if (aref.phi ())
+ {
+ /* Set MAXREF to refer to the largest object and fill ALL_REFS
+ with data for all objects referenced by the PHI arguments. */
+ access_ref maxref;
+ auto_vec<access_ref> all_refs;
+ if (!get_ref (&all_refs, &maxref))
+ return;
+
+ /* Except for MAXREF, the rest of the arguments' offsets need not
+ reflect one added to the PHI itself. Determine the latter from
+ MAXREF on which the result is based. */
+ const offset_int orng[] =
+ {
+ offrng[0] - maxref.offrng[0],
+ wi::smax (offrng[1] - maxref.offrng[1], offrng[0]),
+ };
+
+ /* Add the final PHI's offset to that of each of the arguments
+ and recurse to issue an inform message for it. */
+ for (unsigned i = 0; i != all_refs.length (); ++i)
+ {
+ /* Skip any PHIs; those could lead to infinite recursion. */
+ if (all_refs[i].phi ())
+ continue;
+
+ all_refs[i].add_offset (orng[0], orng[1]);
+ all_refs[i].inform_access (mode);
+ }
+ return;
+ }
+
/* Convert offset range and avoid including a zero range since it
isn't necessarily meaningful. */
HOST_WIDE_INT diff_min = tree_to_shwi (TYPE_MIN_VALUE (ptrdiff_type_node));
HOST_WIDE_INT diff_max = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node));
HOST_WIDE_INT minoff;
HOST_WIDE_INT maxoff = diff_max;
- if (wi::fits_shwi_p (ref.offrng[0]))
- minoff = ref.offrng[0].to_shwi ();
+ if (wi::fits_shwi_p (aref.offrng[0]))
+ minoff = aref.offrng[0].to_shwi ();
else
- minoff = ref.offrng[0] < 0 ? diff_min : diff_max;
+ minoff = aref.offrng[0] < 0 ? diff_min : diff_max;
- if (wi::fits_shwi_p (ref.offrng[1]))
- maxoff = ref.offrng[1].to_shwi ();
+ if (wi::fits_shwi_p (aref.offrng[1]))
+ maxoff = aref.offrng[1].to_shwi ();
if (maxoff <= diff_min || maxoff >= diff_max)
/* Avoid mentioning an upper bound that's equal to or in excess
@@ -3909,110 +4453,127 @@ inform_access (const access_ref &ref, access_mode mode)
/* Convert size range and always include it since all sizes are
meaningful. */
unsigned long long minsize = 0, maxsize = 0;
- if (wi::fits_shwi_p (ref.sizrng[0])
- && wi::fits_shwi_p (ref.sizrng[1]))
+ if (wi::fits_shwi_p (aref.sizrng[0])
+ && wi::fits_shwi_p (aref.sizrng[1]))
{
- minsize = ref.sizrng[0].to_shwi ();
- maxsize = ref.sizrng[1].to_shwi ();
+ minsize = aref.sizrng[0].to_shwi ();
+ maxsize = aref.sizrng[1].to_shwi ();
}
+ /* SIZRNG doesn't necessarily have the same range as the allocation
+ size determined by gimple_call_alloc_size (). */
char sizestr[80];
- location_t loc;
- tree allocfn = NULL_TREE;
- if (TREE_CODE (ref.ref) == SSA_NAME)
- {
- gimple *stmt = SSA_NAME_DEF_STMT (ref.ref);
- gcc_assert (is_gimple_call (stmt));
- loc = gimple_location (stmt);
- allocfn = gimple_call_fndecl (stmt);
- if (!allocfn)
- /* Handle calls through pointers to functions. */
- allocfn = gimple_call_fn (stmt);
-
- /* SIZRNG doesn't necessarily have the same range as the allocation
- size determined by gimple_call_alloc_size (). */
+ if (minsize == maxsize)
+ sprintf (sizestr, "%llu", minsize);
+ else
+ sprintf (sizestr, "[%llu, %llu]", minsize, maxsize);
+
+ char offstr[80];
+ if (minoff == 0
+ && (maxoff == 0 || aref.sizrng[1] <= maxoff))
+ offstr[0] = '\0';
+ else if (minoff == maxoff)
+ sprintf (offstr, "%lli", (long long) minoff);
+ else
+ sprintf (offstr, "[%lli, %lli]", (long long) minoff, (long long) maxoff);
- if (minsize == maxsize)
- sprintf (sizestr, "%llu", minsize);
- else
- sprintf (sizestr, "[%llu, %llu]", minsize, maxsize);
+ location_t loc = UNKNOWN_LOCATION;
+ tree ref = this->ref;
+ tree allocfn = NULL_TREE;
+ if (TREE_CODE (ref) == SSA_NAME)
+ {
+ gimple *stmt = SSA_NAME_DEF_STMT (ref);
+ if (is_gimple_call (stmt))
+ {
+ loc = gimple_location (stmt);
+ if (gimple_call_builtin_p (stmt, BUILT_IN_ALLOCA_WITH_ALIGN))
+ {
+ /* Strip the SSA_NAME suffix from the variable name and
+ recreate an identifier with the VLA's original name. */
+ ref = gimple_call_lhs (stmt);
+ ref = SSA_NAME_IDENTIFIER (ref);
+ const char *id = IDENTIFIER_POINTER (ref);
+ size_t len = strcspn (id, ".$");
+ if (!len)
+ len = strlen (id);
+ ref = get_identifier_with_length (id, len);
+ }
+ else
+ {
+ /* Except for VLAs, retrieve the allocation function. */
+ allocfn = gimple_call_fndecl (stmt);
+ if (!allocfn)
+ allocfn = gimple_call_fn (stmt);
+ if (TREE_CODE (allocfn) == SSA_NAME)
+ {
+ /* For an ALLOC_CALL via a function pointer make a small
+ effort to determine the destination of the pointer. */
+ gimple *def = SSA_NAME_DEF_STMT (allocfn);
+ if (gimple_assign_single_p (def))
+ {
+ tree rhs = gimple_assign_rhs1 (def);
+ if (DECL_P (rhs))
+ allocfn = rhs;
+ else if (TREE_CODE (rhs) == COMPONENT_REF)
+ allocfn = TREE_OPERAND (rhs, 1);
+ }
+ }
+ }
+ }
+ else if (gimple_nop_p (stmt))
+ /* Handle DECL_PARM below. */
+ ref = SSA_NAME_VAR (ref);
}
- else if (DECL_P (ref.ref))
- loc = DECL_SOURCE_LOCATION (ref.ref);
- else if (EXPR_P (ref.ref) && EXPR_HAS_LOCATION (ref.ref))
- loc = EXPR_LOCATION (ref.ref);
- else
+
+ if (DECL_P (ref))
+ loc = DECL_SOURCE_LOCATION (ref);
+ else if (EXPR_P (ref) && EXPR_HAS_LOCATION (ref))
+ loc = EXPR_LOCATION (ref);
+ else if (TREE_CODE (ref) != IDENTIFIER_NODE
+ && TREE_CODE (ref) != SSA_NAME)
return;
if (mode == access_read_write || mode == access_write_only)
{
if (allocfn == NULL_TREE)
{
- if (minoff == maxoff)
- {
- if (minoff == 0)
- inform (loc, "destination object %qE", ref.ref);
- else
- inform (loc, "at offset %wi into destination object %qE",
- minoff, ref.ref);
- }
+ if (*offstr)
+ inform (loc, "at offset %s into destination object %qE of size %s",
+ offstr, ref, sizestr);
else
- inform (loc, "at offset [%wi, %wi] into destination object %qE",
- minoff, maxoff, ref.ref);
+ inform (loc, "destination object %qE of size %s", ref, sizestr);
return;
}
- if (minoff == maxoff)
- {
- if (minoff == 0)
- inform (loc, "destination object of size %s allocated by %qE",
- sizestr, allocfn);
- else
- inform (loc,
- "at offset %wi into destination object of size %s "
- "allocated by %qE", minoff, sizestr, allocfn);
- }
- else
+ if (*offstr)
inform (loc,
- "at offset [%wi, %wi] into destination object of size %s "
- "allocated by %qE",
- minoff, maxoff, sizestr, allocfn);
-
+ "at offset %s into destination object of size %s "
+ "allocated by %qE", offstr, sizestr, allocfn);
+ else
+ inform (loc, "destination object of size %s allocated by %qE",
+ sizestr, allocfn);
return;
}
- if (DECL_P (ref.ref))
+ if (DECL_P (ref))
{
- if (minoff == maxoff)
- {
- if (minoff == 0)
- inform (loc, "source object %qD", ref.ref);
- else
- inform (loc, "at offset %wi into source object %qD",
- minoff, ref.ref);
- }
+ if (*offstr)
+ inform (loc, "at offset %s into source object %qD of size %s",
+ offstr, ref, sizestr);
else
- inform (loc, "at offset [%wi, %wi] into source object %qD",
- minoff, maxoff, ref.ref);
+ inform (loc, "source object %qD of size %s", ref, sizestr);
+
return;
}
- if (minoff == maxoff)
- {
- if (minoff == 0)
- inform (loc, "source object of size %s allocated by %qE",
- sizestr, allocfn);
- else
- inform (loc,
- "at offset %wi into source object of size %s "
- "allocated by %qE", minoff, sizestr, allocfn);
- }
- else
+ if (*offstr)
inform (loc,
- "at offset [%wi, %wi] into source object of size %s "
- "allocated by %qE",
- minoff, maxoff, sizestr, allocfn);
+ "at offset %s into source object of size %s allocated by %qE",
+ offstr, sizestr, allocfn);
+ else
+ inform (loc, "source object of size %s allocated by %qE",
+ sizestr, allocfn);
}
/* Helper to set RANGE to the range of BOUND if it's nonnull, bounded
@@ -4232,17 +4793,18 @@ check_access (tree exp, tree dstwrite,
= mode == access_read_only || mode == access_read_write;
const bool write
= mode == access_write_only || mode == access_read_write;
+ const bool maybe = pad && pad->dst.parmarray;
warned = warn_for_access (loc, func, exp,
OPT_Wstringop_overflow_,
range, dstsize,
- write, read && !builtin);
+ write, read && !builtin, maybe);
}
if (warned)
{
TREE_NO_WARNING (exp) = true;
if (pad)
- inform_access (pad->dst, pad->mode);
+ pad->dst.inform_access (pad->mode);
}
/* Return error when an overflow has been detected. */
@@ -4325,12 +4887,13 @@ check_access (tree exp, tree dstwrite,
const bool read
= mode == access_read_only || mode == access_read_write;
+ const bool maybe = pad && pad->dst.parmarray;
if (warn_for_access (loc, func, exp, OPT_Wstringop_overread, range,
- slen, false, read))
+ slen, false, read, maybe))
{
TREE_NO_WARNING (exp) = true;
if (pad)
- inform_access (pad->src, access_read_only);
+ pad->src.inform_access (access_read_only);
}
return false;
}
@@ -4462,11 +5025,12 @@ gimple_call_alloc_size (gimple *stmt, wide_int rng1[2] /* = NULL */,
/* For an access to an object referenced to by the function parameter PTR
of pointer type, and set RNG[] to the range of sizes of the object
obtainedfrom the attribute access specification for the current function.
+ Set STATIC_ARRAY if the array parameter has been declared [static].
Return the function parameter on success and null otherwise. */
tree
gimple_parm_array_size (tree ptr, wide_int rng[2],
- range_query * /* = NULL */)
+ bool *static_array /* = NULL */)
{
/* For a function argument try to determine the byte size of the array
from the current function declaratation (e.g., attribute access or
@@ -4498,6 +5062,9 @@ gimple_parm_array_size (tree ptr, wide_int rng[2],
if (warn_array_parameter < 2 && !access->static_p)
return NULL_TREE;
+ if (static_array)
+ *static_array = access->static_p;
+
rng[0] = wi::zero (prec);
rng[1] = wi::uhwi (access->minsize, prec);
/* Multiply the array bound encoded in the attribute by the size
@@ -4645,6 +5212,84 @@ gimple_call_return_array (gimple *stmt, offset_int offrng[2],
return NULL_TREE;
}
+/* A helper of compute_objsize() to determine the size from an assignment
+ statement STMT with the RHS of either MIN_EXPR or MAX_EXPR. */
+
+static bool
+handle_min_max_size (gimple *stmt, int ostype, access_ref *pref,
+ ssa_name_limit_t &snlim, pointer_query *qry)
+{
+ tree_code code = gimple_assign_rhs_code (stmt);
+
+ tree ptr = gimple_assign_rhs1 (stmt);
+
+ /* In a valid MAX_/MIN_EXPR both operands must refer to the same array.
+ Determine the size/offset of each and use the one with more or less
+ space remaining, respectively. If either fails, use the information
+ determined from the other instead, adjusted up or down as appropriate
+ for the expression. */
+ access_ref aref[2] = { *pref, *pref };
+ if (!compute_objsize_r (ptr, ostype, &aref[0], snlim, qry))
+ {
+ aref[0].base0 = false;
+ aref[0].offrng[0] = aref[0].offrng[1] = 0;
+ aref[0].add_max_offset ();
+ aref[0].set_max_size_range ();
+ }
+
+ ptr = gimple_assign_rhs2 (stmt);
+ if (!compute_objsize_r (ptr, ostype, &aref[1], snlim, qry))
+ {
+ aref[1].base0 = false;
+ aref[1].offrng[0] = aref[1].offrng[1] = 0;
+ aref[1].add_max_offset ();
+ aref[1].set_max_size_range ();
+ }
+
+ if (!aref[0].ref && !aref[1].ref)
+ /* Fail if the identity of neither argument could be determined. */
+ return false;
+
+ bool i0 = false;
+ if (aref[0].ref && aref[0].base0)
+ {
+ if (aref[1].ref && aref[1].base0)
+ {
+ /* If the object referenced by both arguments has been determined
+ set *PREF to the one with more or less space remainng, whichever
+ is appopriate for CODE.
+ TODO: Indicate when the objects are distinct so it can be
+ diagnosed. */
+ i0 = code == MAX_EXPR;
+ const bool i1 = !i0;
+
+ if (aref[i0].size_remaining () < aref[i1].size_remaining ())
+ *pref = aref[i1];
+ else
+ *pref = aref[i0];
+ return true;
+ }
+
+ /* If only the object referenced by one of the arguments could be
+ determined, use it and... */
+ *pref = aref[0];
+ i0 = true;
+ }
+ else
+ *pref = aref[1];
+
+ const bool i1 = !i0;
+ /* ...see if the offset obtained from the other pointer can be used
+ to tighten up the bound on the offset obtained from the first. */
+ if ((code == MAX_EXPR && aref[i1].offrng[1] < aref[i0].offrng[0])
+ || (code == MIN_EXPR && aref[i0].offrng[0] < aref[i1].offrng[1]))
+ {
+ pref->offrng[0] = aref[i0].offrng[0];
+ pref->offrng[1] = aref[i0].offrng[1];
+ }
+ return true;
+}
+
/* Helper to compute the size of the object referenced by the PTR
expression which must have pointer type, using Object Size type
OSTYPE (only the least significant 2 bits are used).
@@ -4652,7 +5297,7 @@ gimple_call_return_array (gimple *stmt, offset_int offrng[2],
if it's unique, otherwise to null, PREF->OFFRNG to the range of
offsets into it, and PREF->SIZRNG to the range of sizes of
the object(s).
- VISITED is used to avoid visiting the same PHI operand multiple
+ SNLIM is used to avoid visiting the same PHI operand multiple
times, and, when nonnull, RVALS to determine range information.
Returns true on success, false when a meaningful size (or range)
cannot be determined.
@@ -4661,8 +5306,8 @@ gimple_call_return_array (gimple *stmt, offset_int offrng[2],
to influence code generation or optimization. */
static bool
-compute_objsize (tree ptr, int ostype, access_ref *pref, bitmap *visited,
- range_query *rvals)
+compute_objsize_r (tree ptr, int ostype, access_ref *pref,
+ ssa_name_limit_t &snlim, pointer_query *qry)
{
STRIP_NOPS (ptr);
@@ -4694,11 +5339,12 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, bitmap *visited,
}
const tree_code code = TREE_CODE (ptr);
+ range_query *const rvals = qry ? qry->rvals : NULL;
if (code == BIT_FIELD_REF)
{
tree ref = TREE_OPERAND (ptr, 0);
- if (!compute_objsize (ref, ostype, pref, visited, rvals))
+ if (!compute_objsize_r (ref, ostype, pref, snlim, qry))
return false;
offset_int off = wi::to_offset (pref->eval (TREE_OPERAND (ptr, 2)));
@@ -4709,6 +5355,10 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, bitmap *visited,
if (code == COMPONENT_REF)
{
tree ref = TREE_OPERAND (ptr, 0);
+ if (TREE_CODE (TREE_TYPE (ref)) == UNION_TYPE)
+ /* In accesses through union types consider the entire unions
+ rather than just their members. */
+ ostype = 0;
tree field = TREE_OPERAND (ptr, 1);
if (ostype == 0)
@@ -4716,7 +5366,7 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, bitmap *visited,
/* In OSTYPE zero (for raw memory functions like memcpy), use
the maximum size instead if the identity of the enclosing
object cannot be determined. */
- if (!compute_objsize (ref, ostype, pref, visited, rvals))
+ if (!compute_objsize_r (ref, ostype, pref, snlim, qry))
return false;
/* Otherwise, use the size of the enclosing object and add
@@ -4726,9 +5376,17 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, bitmap *visited,
pref->add_offset (wi::to_offset (offset));
else
pref->add_max_offset ();
+
+ if (!pref->ref)
+ /* REF may have been already set to an SSA_NAME earlier
+ to provide better context for diagnostics. In that case,
+ leave it unchanged. */
+ pref->ref = ref;
return true;
}
+ pref->ref = field;
+
if (!addr && POINTER_TYPE_P (TREE_TYPE (field)))
{
/* Set maximum size if the reference is to the pointer member
@@ -4737,8 +5395,6 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, bitmap *visited,
return true;
}
- pref->ref = field;
-
/* SAM is set for array members that might need special treatment. */
special_array_member sam;
tree size = component_ref_size (ptr, &sam);
@@ -4767,7 +5423,7 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, bitmap *visited,
{
tree ref = TREE_OPERAND (ptr, 0);
tree reftype = TREE_TYPE (ref);
- if (code == ARRAY_REF
+ if (!addr && code == ARRAY_REF
&& TREE_CODE (TREE_TYPE (reftype)) == POINTER_TYPE)
/* Avoid arrays of pointers. FIXME: Hande pointers to arrays
of known bound. */
@@ -4785,7 +5441,7 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, bitmap *visited,
return false;
}
- if (!compute_objsize (ref, ostype, pref, visited, rvals))
+ if (!compute_objsize_r (ref, ostype, pref, snlim, qry))
return false;
offset_int orng[2];
@@ -4851,7 +5507,7 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, bitmap *visited,
if (code == TARGET_MEM_REF)
{
tree ref = TREE_OPERAND (ptr, 0);
- if (!compute_objsize (ref, ostype, pref, visited, rvals))
+ if (!compute_objsize_r (ref, ostype, pref, snlim, qry))
return false;
/* TODO: Handle remaining operands. Until then, add maximum offset. */
@@ -4878,13 +5534,14 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, bitmap *visited,
if (code == STRING_CST)
{
pref->sizrng[0] = pref->sizrng[1] = TREE_STRING_LENGTH (ptr);
+ pref->ref = ptr;
return true;
}
if (code == POINTER_PLUS_EXPR)
{
tree ref = TREE_OPERAND (ptr, 0);
- if (!compute_objsize (ref, ostype, pref, visited, rvals))
+ if (!compute_objsize_r (ref, ostype, pref, snlim, qry))
return false;
offset_int orng[2];
@@ -4899,11 +5556,29 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, bitmap *visited,
if (code == VIEW_CONVERT_EXPR)
{
ptr = TREE_OPERAND (ptr, 0);
- return compute_objsize (ptr, ostype, pref, visited, rvals);
+ return compute_objsize_r (ptr, ostype, pref, snlim, qry);
}
- if (TREE_CODE (ptr) == SSA_NAME)
+ if (code == SSA_NAME)
{
+ if (!snlim.next ())
+ return false;
+
+ /* Only process an SSA_NAME if the recursion limit has not yet
+ been reached. */
+ if (qry)
+ {
+ if (++qry->depth)
+ qry->max_depth = qry->depth;
+ if (const access_ref *cache_ref = qry->get_ref (ptr))
+ {
+ /* If the pointer is in the cache set *PREF to what it refers
+ to and return success. */
+ *pref = *cache_ref;
+ return true;
+ }
+ }
+
gimple *stmt = SSA_NAME_DEF_STMT (ptr);
if (is_gimple_call (stmt))
{
@@ -4932,7 +5607,7 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, bitmap *visited,
offset_int offrng[2];
if (tree ret = gimple_call_return_array (stmt, offrng, rvals))
{
- if (!compute_objsize (ret, ostype, pref, visited, rvals))
+ if (!compute_objsize_r (ret, ostype, pref, snlim, qry))
return false;
/* Cap OFFRNG[1] to at most the remaining size of
@@ -4954,6 +5629,7 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, bitmap *visited,
pref->ref = ptr;
}
}
+ qry->put_ref (ptr, *pref);
return true;
}
@@ -4963,25 +5639,35 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, bitmap *visited,
of the array from the current function declaratation
(e.g., attribute access or related). */
wide_int wr[2];
- if (tree ref = gimple_parm_array_size (ptr, wr, rvals))
+ bool static_array = false;
+ if (tree ref = gimple_parm_array_size (ptr, wr, &static_array))
{
+ pref->parmarray = !static_array;
pref->sizrng[0] = offset_int::from (wr[0], UNSIGNED);
pref->sizrng[1] = offset_int::from (wr[1], UNSIGNED);
pref->ref = ref;
+ qry->put_ref (ptr, *pref);
return true;
}
pref->set_max_size_range ();
pref->base0 = false;
pref->ref = ptr;
- if (tree var = SSA_NAME_VAR (ptr))
- if (TREE_CODE (var) == PARM_DECL)
- pref->ref = var;
-
+ qry->put_ref (ptr, *pref);
return true;
}
- /* TODO: Handle PHI. */
+ if (gimple_code (stmt) == GIMPLE_PHI)
+ {
+ pref->ref = ptr;
+ access_ref phi_ref = *pref;
+ if (!pref->get_ref (NULL, &phi_ref, ostype, &snlim, qry))
+ return false;
+ *pref = phi_ref;
+ pref->ref = ptr;
+ qry->put_ref (ptr, *pref);
+ return true;
+ }
if (!is_gimple_assign (stmt))
{
@@ -4991,21 +5677,27 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, bitmap *visited,
PREF->REF to it. */
pref->base0 = false;
pref->set_max_size_range ();
- if (tree var = SSA_NAME_VAR (ptr))
- if (TREE_CODE (var) == PARM_DECL)
- pref->ref = var;
+ pref->ref = ptr;
return true;
}
- ptr = gimple_assign_rhs1 (stmt);
-
tree_code code = gimple_assign_rhs_code (stmt);
+ if (code == MAX_EXPR || code == MIN_EXPR)
+ {
+ if (!handle_min_max_size (stmt, ostype, pref, snlim, qry))
+ return false;
+ qry->put_ref (ptr, *pref);
+ return true;
+ }
+
+ tree rhs = gimple_assign_rhs1 (stmt);
+
if (code == POINTER_PLUS_EXPR
- && TREE_CODE (TREE_TYPE (ptr)) == POINTER_TYPE)
+ && TREE_CODE (TREE_TYPE (rhs)) == POINTER_TYPE)
{
/* Compute the size of the object first. */
- if (!compute_objsize (ptr, ostype, pref, visited, rvals))
+ if (!compute_objsize_r (rhs, ostype, pref, snlim, qry))
return false;
offset_int orng[2];
@@ -5014,22 +5706,30 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, bitmap *visited,
pref->add_offset (orng[0], orng[1]);
else
pref->add_max_offset ();
+ qry->put_ref (ptr, *pref);
return true;
}
- if (code == ADDR_EXPR)
- return compute_objsize (ptr, ostype, pref, visited, rvals);
+ if (code == ADDR_EXPR
+ || code == SSA_NAME)
+ return compute_objsize_r (rhs, ostype, pref, snlim, qry);
- /* This could be an assignment from a nonlocal pointer. Save PTR
- to mention in diagnostics but otherwise treat it as a pointer
+ /* (This could also be an assignment from a nonlocal pointer.) Save
+ PTR to mention in diagnostics but otherwise treat it as a pointer
to an unknown object. */
- pref->ref = ptr;
+ pref->ref = rhs;
+ pref->base0 = false;
+ pref->set_max_size_range ();
+ return true;
}
/* Assume all other expressions point into an unknown object
of the maximum valid size. */
+ pref->ref = ptr;
pref->base0 = false;
pref->set_max_size_range ();
+ if (TREE_CODE (ptr) == SSA_NAME)
+ qry->put_ref (ptr, *pref);
return true;
}
@@ -5040,15 +5740,32 @@ tree
compute_objsize (tree ptr, int ostype, access_ref *pref,
range_query *rvals /* = NULL */)
{
- bitmap visited = NULL;
+ pointer_query qry;
+ qry.rvals = rvals;
+ ssa_name_limit_t snlim;
+ if (!compute_objsize_r (ptr, ostype, pref, snlim, &qry))
+ return NULL_TREE;
- bool success
- = compute_objsize (ptr, ostype, pref, &visited, rvals);
+ offset_int maxsize = pref->size_remaining ();
+ if (pref->base0 && pref->offrng[0] < 0 && pref->offrng[1] >= 0)
+ pref->offrng[0] = 0;
+ return wide_int_to_tree (sizetype, maxsize);
+}
- if (visited)
- BITMAP_FREE (visited);
+/* Transitional wrapper. The function should be removed once callers
+ transition to the pointer_query API. */
+
+tree
+compute_objsize (tree ptr, int ostype, access_ref *pref, pointer_query *ptr_qry)
+{
+ pointer_query qry;
+ if (ptr_qry)
+ ptr_qry->depth = 0;
+ else
+ ptr_qry = &qry;
- if (!success)
+ ssa_name_limit_t snlim;
+ if (!compute_objsize_r (ptr, ostype, pref, snlim, ptr_qry))
return NULL_TREE;
offset_int maxsize = pref->size_remaining ();
@@ -5057,7 +5774,7 @@ compute_objsize (tree ptr, int ostype, access_ref *pref,
return wide_int_to_tree (sizetype, maxsize);
}
-/* Transitional wrapper around the above. The function should be removed
+/* Legacy wrapper around the above. The function should be removed
once callers transition to one of the two above. */
tree
@@ -7053,26 +7770,64 @@ expand_builtin_copysign (tree exp, rtx target, rtx subtarget)
return expand_copysign (op0, op1, target);
}
-/* Expand a call to __builtin___clear_cache. */
+/* Emit a call to __builtin___clear_cache. */
-static rtx
-expand_builtin___clear_cache (tree exp)
+void
+default_emit_call_builtin___clear_cache (rtx begin, rtx end)
+{
+ rtx callee = gen_rtx_SYMBOL_REF (Pmode,
+ BUILTIN_ASM_NAME_PTR
+ (BUILT_IN_CLEAR_CACHE));
+
+ emit_library_call (callee,
+ LCT_NORMAL, VOIDmode,
+ begin, ptr_mode,
+ end, ptr_mode);
+}
+
+/* Emit a call to __builtin___clear_cache, unless the target specifies
+ it as do-nothing. This function can be used by trampoline
+ finalizers to duplicate the effects of expanding a call to the
+ clear_cache builtin. */
+
+void
+maybe_emit_call_builtin___clear_cache (rtx begin, rtx end)
{
- if (!targetm.code_for_clear_cache)
+ if ((GET_MODE (begin) != ptr_mode && GET_MODE (begin) != Pmode)
+ || (GET_MODE (end) != ptr_mode && GET_MODE (end) != Pmode))
{
-#ifdef CLEAR_INSN_CACHE
- /* There is no "clear_cache" insn, and __clear_cache() in libgcc
- does something. Just do the default expansion to a call to
- __clear_cache(). */
- return NULL_RTX;
-#else
+ error ("both arguments to %<__builtin___clear_cache%> must be pointers");
+ return;
+ }
+
+ if (targetm.have_clear_cache ())
+ {
+ /* We have a "clear_cache" insn, and it will handle everything. */
+ class expand_operand ops[2];
+
+ create_address_operand (&ops[0], begin);
+ create_address_operand (&ops[1], end);
+
+ if (maybe_expand_insn (targetm.code_for_clear_cache, 2, ops))
+ return;
+ }
+ else
+ {
+#ifndef CLEAR_INSN_CACHE
/* There is no "clear_cache" insn, and __clear_cache() in libgcc
does nothing. There is no need to call it. Do nothing. */
- return const0_rtx;
+ return;
#endif /* CLEAR_INSN_CACHE */
}
- /* We have a "clear_cache" insn, and it will handle everything. */
+ targetm.calls.emit_call_builtin___clear_cache (begin, end);
+}
+
+/* Expand a call to __builtin___clear_cache. */
+
+static void
+expand_builtin___clear_cache (tree exp)
+{
tree begin, end;
rtx begin_rtx, end_rtx;
@@ -7082,25 +7837,16 @@ expand_builtin___clear_cache (tree exp)
if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
{
error ("both arguments to %<__builtin___clear_cache%> must be pointers");
- return const0_rtx;
+ return;
}
- if (targetm.have_clear_cache ())
- {
- class expand_operand ops[2];
-
- begin = CALL_EXPR_ARG (exp, 0);
- begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
+ begin = CALL_EXPR_ARG (exp, 0);
+ begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
- end = CALL_EXPR_ARG (exp, 1);
- end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL);
+ end = CALL_EXPR_ARG (exp, 1);
+ end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL);
- create_address_operand (&ops[0], begin_rtx);
- create_address_operand (&ops[1], end_rtx);
- if (maybe_expand_insn (targetm.code_for_clear_cache, 2, ops))
- return const0_rtx;
- }
- return const0_rtx;
+ maybe_emit_call_builtin___clear_cache (begin_rtx, end_rtx);
}
/* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
@@ -8790,6 +9536,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode,
&& fcode != BUILT_IN_EXECLE
&& fcode != BUILT_IN_EXECVP
&& fcode != BUILT_IN_EXECVE
+ && fcode != BUILT_IN_CLEAR_CACHE
&& !ALLOCA_FUNCTION_CODE_P (fcode)
&& fcode != BUILT_IN_FREE)
return expand_call (exp, target, ignore);
@@ -8979,10 +9726,8 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode,
return expand_builtin_next_arg ();
case BUILT_IN_CLEAR_CACHE:
- target = expand_builtin___clear_cache (exp);
- if (target)
- return target;
- break;
+ expand_builtin___clear_cache (exp);
+ return const0_rtx;
case BUILT_IN_CLASSIFY_TYPE:
return expand_builtin_classify_type (exp);
@@ -10691,9 +11436,10 @@ fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index)
switch (builtin_index)
{
case BUILT_IN_ISINF:
- if (!HONOR_INFINITIES (arg))
+ if (tree_expr_infinite_p (arg))
+ return omit_one_operand_loc (loc, type, integer_one_node, arg);
+ if (!tree_expr_maybe_infinite_p (arg))
return omit_one_operand_loc (loc, type, integer_zero_node, arg);
-
return NULL_TREE;
case BUILT_IN_ISINF_SIGN:
@@ -10729,14 +11475,16 @@ fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index)
}
case BUILT_IN_ISFINITE:
- if (!HONOR_NANS (arg)
- && !HONOR_INFINITIES (arg))
+ if (tree_expr_finite_p (arg))
return omit_one_operand_loc (loc, type, integer_one_node, arg);
-
+ if (tree_expr_nan_p (arg) || tree_expr_infinite_p (arg))
+ return omit_one_operand_loc (loc, type, integer_zero_node, arg);
return NULL_TREE;
case BUILT_IN_ISNAN:
- if (!HONOR_NANS (arg))
+ if (tree_expr_nan_p (arg))
+ return omit_one_operand_loc (loc, type, integer_one_node, arg);
+ if (!tree_expr_maybe_nan_p (arg))
return omit_one_operand_loc (loc, type, integer_zero_node, arg);
{
@@ -10810,7 +11558,7 @@ fold_builtin_fpclassify (location_t loc, tree *args, int nargs)
arg, build_real (type, r));
res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, fp_normal, res);
- if (HONOR_INFINITIES (mode))
+ if (tree_expr_maybe_infinite_p (arg))
{
real_inf (&r);
tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
@@ -10819,7 +11567,7 @@ fold_builtin_fpclassify (location_t loc, tree *args, int nargs)
fp_infinite, res);
}
- if (HONOR_NANS (mode))
+ if (tree_expr_maybe_nan_p (arg))
{
tmp = fold_build2_loc (loc, ORDERED_EXPR, integer_type_node, arg, arg);
res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, res, fp_nan);
@@ -10867,12 +11615,15 @@ fold_builtin_unordered_cmp (location_t loc, tree fndecl, tree arg0, tree arg1,
if (unordered_code == UNORDERED_EXPR)
{
- if (!HONOR_NANS (arg0))
+ if (tree_expr_nan_p (arg0) || tree_expr_nan_p (arg1))
+ return omit_two_operands_loc (loc, type, integer_one_node, arg0, arg1);
+ if (!tree_expr_maybe_nan_p (arg0) && !tree_expr_maybe_nan_p (arg1))
return omit_two_operands_loc (loc, type, integer_zero_node, arg0, arg1);
return fold_build2_loc (loc, UNORDERED_EXPR, type, arg0, arg1);
}
- code = HONOR_NANS (arg0) ? unordered_code : ordered_code;
+ code = (tree_expr_maybe_nan_p (arg0) || tree_expr_maybe_nan_p (arg1))
+ ? unordered_code : ordered_code;
return fold_build1_loc (loc, TRUTH_NOT_EXPR, type,
fold_build2_loc (loc, code, type, arg0, arg1));
}
@@ -12939,16 +13690,16 @@ builtin_fnspec (tree callee)
argument. */
case BUILT_IN_STRCAT:
case BUILT_IN_STRCAT_CHK:
- return "1cW R ";
+ return "1cW 1 ";
case BUILT_IN_STRNCAT:
case BUILT_IN_STRNCAT_CHK:
- return "1cW R3";
+ return "1cW 13";
case BUILT_IN_STRCPY:
case BUILT_IN_STRCPY_CHK:
- return "1cO R ";
+ return "1cO 1 ";
case BUILT_IN_STPCPY:
case BUILT_IN_STPCPY_CHK:
- return ".cO R ";
+ return ".cO 1 ";
case BUILT_IN_STRNCPY:
case BUILT_IN_MEMCPY:
case BUILT_IN_MEMMOVE:
@@ -12957,15 +13708,15 @@ builtin_fnspec (tree callee)
case BUILT_IN_STRNCPY_CHK:
case BUILT_IN_MEMCPY_CHK:
case BUILT_IN_MEMMOVE_CHK:
- return "1cO3R3";
+ return "1cO313";
case BUILT_IN_MEMPCPY:
case BUILT_IN_MEMPCPY_CHK:
- return ".cO3R3";
+ return ".cO313";
case BUILT_IN_STPNCPY:
case BUILT_IN_STPNCPY_CHK:
- return ".cO3R3";
+ return ".cO313";
case BUILT_IN_BCOPY:
- return ".cR3O3";
+ return ".c23O3";
case BUILT_IN_BZERO:
return ".cO2";
case BUILT_IN_MEMCMP:
@@ -13023,6 +13774,7 @@ builtin_fnspec (tree callee)
case BUILT_IN_MALLOC:
case BUILT_IN_ALIGNED_ALLOC:
case BUILT_IN_CALLOC:
+ case BUILT_IN_GOMP_ALLOC:
return "mC";
CASE_BUILT_IN_ALLOCA:
return "mc";
@@ -13044,12 +13796,13 @@ builtin_fnspec (tree callee)
across it. */
case BUILT_IN_STACK_RESTORE:
case BUILT_IN_FREE:
+ case BUILT_IN_GOMP_FREE:
return ".co ";
case BUILT_IN_VA_END:
return ".cO ";
/* Realloc serves both as allocation point and deallocation point. */
case BUILT_IN_REALLOC:
- return ".cw ";
+ return ".Cw ";
case BUILT_IN_GAMMA_R:
case BUILT_IN_GAMMAF_R:
case BUILT_IN_GAMMAL_R:
diff --git a/gcc/builtins.def b/gcc/builtins.def
index b4494c7..aec43ca 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -245,6 +245,7 @@ along with GCC; see the file COPYING3. If not see
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
true, true, true, ATTRS, true, \
(flag_sanitize & (SANITIZE_ADDRESS | SANITIZE_THREAD \
+ | SANITIZE_HWADDRESS \
| SANITIZE_UNDEFINED \
| SANITIZE_UNDEFINED_NONDEFAULT) \
|| flag_sanitize_coverage))
@@ -839,6 +840,7 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_CLEAR_CACHE, "__clear_cache", BT_FN_VOID_PTR_PT
/* [trans-mem]: Adjust BUILT_IN_TM_CALLOC if BUILT_IN_CALLOC is changed. */
DEF_LIB_BUILTIN (BUILT_IN_CALLOC, "calloc", BT_FN_PTR_SIZE_SIZE, ATTR_MALLOC_WARN_UNUSED_RESULT_SIZE_1_2_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_CLASSIFY_TYPE, "classify_type", BT_FN_INT_VAR, ATTR_LEAF_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_CLEAR_PADDING, "clear_padding", BT_FN_VOID_VAR, ATTR_NOTHROW_NONNULL_TYPEGENERIC_LEAF)
DEF_GCC_BUILTIN (BUILT_IN_CLZ, "clz", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_CLZIMAX, "clzimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_CLZL, "clzl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST)
diff --git a/gcc/builtins.h b/gcc/builtins.h
index c09f36d..09379e8 100644
--- a/gcc/builtins.h
+++ b/gcc/builtins.h
@@ -128,6 +128,7 @@ extern tree fold_call_expr (location_t, tree, bool);
extern tree fold_builtin_call_array (location_t, tree, tree, int, tree *);
extern bool validate_gimple_arglist (const gcall *, ...);
extern rtx default_expand_builtin (tree, rtx, rtx, machine_mode, int);
+extern void maybe_emit_call_builtin___clear_cache (rtx, rtx);
extern bool fold_builtin_next_arg (tree, bool);
extern tree do_mpc_arg2 (tree, tree, tree, int, int (*)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t));
extern tree fold_call_stmt (gcall *, bool);
@@ -153,6 +154,42 @@ extern void warn_string_no_nul (location_t, tree, const char *, tree,
extern tree unterminated_array (tree, tree * = NULL, bool * = NULL);
extern bool builtin_with_linkage_p (tree);
+/* Describes recursion limits used by functions that follow use-def
+ chains of SSA_NAMEs. */
+
+class ssa_name_limit_t
+{
+ bitmap visited; /* Bitmap of visited SSA_NAMEs. */
+ unsigned ssa_def_max; /* Longest chain of SSA_NAMEs to follow. */
+
+ /* Not copyable or assignable. */
+ DISABLE_COPY_AND_ASSIGN (ssa_name_limit_t);
+
+public:
+
+ ssa_name_limit_t ()
+ : visited (),
+ ssa_def_max (param_ssa_name_def_chain_limit) { }
+
+ /* Set a bit for the PHI in VISITED and return true if it wasn't
+ already set. */
+ bool visit_phi (tree);
+ /* Clear a bit for the PHI in VISITED. */
+ void leave_phi (tree);
+ /* Return false if the SSA_NAME chain length counter has reached
+ the limit, otherwise increment the counter and return true. */
+ bool next ();
+
+ /* 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 next_phi (tree);
+
+ ~ssa_name_limit_t ();
+};
+
+class pointer_query;
+
/* Describes a reference to an object used in an access. */
struct access_ref
{
@@ -162,17 +199,12 @@ struct access_ref
is a constant zero. */
access_ref (tree = NULL_TREE, bool = false);
- /* Reference to the accessed object(s). */
- tree ref;
+ /* Return the PHI node REF refers to or null if it doesn't. */
+ gphi *phi () const;
- /* Range of byte offsets into and sizes of the object(s). */
- offset_int offrng[2];
- offset_int sizrng[2];
- /* Range of the bound of the access: denotes that the access
- is at least BNDRNG[0] bytes but no more than BNDRNG[1].
- For string functions the size of the actual access is
- further constrained by the length of the string. */
- offset_int bndrng[2];
+ /* Return the object to which REF refers. */
+ tree get_ref (vec<access_ref> *, access_ref * = NULL, int = 1,
+ ssa_name_limit_t * = NULL, pointer_query * = NULL) const;
/* Return true if OFFRNG is the constant zero. */
bool offset_zero () const
@@ -211,6 +243,22 @@ struct access_ref
add_offset (-maxoff - 1, maxoff);
}
+ /* Issue an informational message describing the target of an access
+ with the given mode. */
+ void inform_access (access_mode) const;
+
+ /* Reference to the accessed object(s). */
+ tree ref;
+
+ /* Range of byte offsets into and sizes of the object(s). */
+ offset_int offrng[2];
+ offset_int sizrng[2];
+ /* Range of the bound of the access: denotes that the access
+ is at least BNDRNG[0] bytes but no more than BNDRNG[1].
+ For string functions the size of the actual access is
+ further constrained by the length of the string. */
+ offset_int bndrng[2];
+
/* Used to fold integer expressions when called from front ends. */
tree (*eval)(tree);
/* Set if trailing one-element arrays should be treated as flexible
@@ -219,6 +267,55 @@ struct access_ref
/* Set if valid offsets must start at zero (for declared and allocated
objects but not for others referenced by pointers). */
bool base0;
+ /* Set if REF refers to a function array parameter not declared
+ static. */
+ bool parmarray;
+};
+
+class range_query;
+
+/* Queries and caches compute_objsize results. */
+class pointer_query
+{
+ DISABLE_COPY_AND_ASSIGN (pointer_query);
+
+public:
+ /* Type of the two-level cache object defined by clients of the class
+ to have pointer SSA_NAMEs cached for speedy access. */
+ struct cache_type
+ {
+ /* 1-based indices into cache. */
+ vec<unsigned> indices;
+ /* The cache itself. */
+ vec<access_ref> access_refs;
+ };
+
+ /* Construct an object with the given Ranger instance and cache. */
+ explicit pointer_query (range_query * = NULL, cache_type * = NULL);
+
+ /* Retrieve the access_ref for a variable from cache if it's there. */
+ const access_ref* get_ref (tree, int = 1) const;
+
+ /* Retrieve the access_ref for a variable from cache or compute it. */
+ bool get_ref (tree, access_ref*, int = 1);
+
+ /* Add an access_ref for the SSA_NAME to the cache. */
+ void put_ref (tree, const access_ref&, int = 1);
+
+ /* Flush the cache. */
+ void flush_cache ();
+
+ /* A Ranger instance. May be null to use global ranges. */
+ range_query *rvals;
+ /* Cache of SSA_NAMEs. May be null to disable caching. */
+ cache_type *var_cache;
+
+ /* Cache performance counters. */
+ mutable unsigned hits;
+ mutable unsigned misses;
+ mutable unsigned failures;
+ mutable unsigned depth;
+ mutable unsigned max_depth;
};
/* Describes a pair of references used in an access by built-in
@@ -242,11 +339,13 @@ struct access_data
access_mode mode;
};
-class range_query;
extern tree gimple_call_alloc_size (gimple *, wide_int[2] = NULL,
range_query * = NULL);
-extern tree gimple_parm_array_size (tree, wide_int[2], range_query * = NULL);
+extern tree gimple_parm_array_size (tree, wide_int[2], bool * = NULL);
+
extern tree compute_objsize (tree, int, access_ref *, range_query * = NULL);
+/* Legacy/transitional API. Should not be used in new code. */
+extern tree compute_objsize (tree, int, access_ref *, pointer_query *);
extern tree compute_objsize (tree, int, tree * = NULL, tree * = NULL,
range_query * = NULL);
extern bool check_access (tree, tree, tree, tree, tree,
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index d2ad058..0421c98 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,218 @@
+2020-12-01 JeanHeyd Meneide <phdofthehouse@gmail.com>
+
+ * c-cppbuiltin.c (c_cpp_builtins): Add predefined
+ {__GNUC_EXECUTION_CHARSET_NAME} and
+ _WIDE_EXECUTION_CHARSET_NAME} macros.
+
+2020-12-01 Nathan Sidwell <nathan@acm.org>
+
+ * c-common.c (module, import, export): New internal tokens (with
+ trailing space).
+ * c-common.h (RID__MODULE, RID__IMPORT & RID__EXPORT): Enumerate
+ them.
+ (D_CXX_MODULES, D_CXX_MODULES_FLAGS): Enable them.
+ * c-cppbuiltin.c (c_cpp_builtins): Feature macro.
+
+2020-12-01 Nathan Sidwell <nathan@acm.org>
+
+ * c-opts.c (c_common_init_options): Ask for module dependencies.
+ (c_common_handle_option): Handle -Mmodules -Mno-modules.
+ * c-pch.c (c_common_valid_pch): ... does not play with C++
+ modules.
+ * c.opt (Mmodules, Mno-modules): New preprocessor dependency
+ options.
+ (fmodules-ts, fmodule-header, fmodule-implicit-inline)
+ (fmodule-only, fmodule-mapper, fmodule-lazy)
+ (fmodule-version-ignore, Winvalid-imported-macros)
+ (flang-info-include-translate, flang-info-include-translate-not):
+ New options
+
+2020-11-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * c-ada-spec.c (dump_nested_type) <RECORD_TYPE>: Remove obsolete code.
+ (dump_ada_structure): Also deal with convention, unchecked union and
+ bit-field for nested types. In the latter case, print an Alignment
+ aspect along with the Pack aspect.
+
+2020-11-25 Martin Sebor <msebor@redhat.com>
+
+ PR bootstrap/94982
+ * c-attribs.c (handle_patchable_function_entry_attribute): Avoid
+ -Wformat-diag.
+
+2020-11-24 Martin Sebor <msebor@redhat.com>
+
+ * c-warn.c (warn_parm_array_mismatch): Avoid invalid redeclarations.
+
+2020-11-23 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * c-attribs.c (handle_special_var_sec_attribute): New.
+ (handle_noinit_attribute): Remove.
+ (attr_noinit_exclusions): Rename to...
+ (attr_section_exclusions): ...this, and add "persistent" attribute
+ exclusion.
+ (c_common_attribute_table): Add "persistent" attribute.
+
+2020-11-21 Aaron Sawdey <acsawdey@linux.ibm.com>
+
+ * c-pretty-print.c (c_pretty_printer::simple_type_specifier):
+ Treat opaque types like other types.
+ (c_pretty_printer::direct_abstract_declarator): Opaque types are
+ supported types.
+
+2020-11-20 Martin Sebor <msebor@redhat.com>
+
+ * c-warn.c (warn_parm_array_mismatch): Bail on invalid redeclarations
+ with fewer arguments.
+
+2020-11-20 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/97879
+ * c-attribs.c (handle_access_attribute): Handle ATTR_FLAG_INTERNAL.
+ Error out on invalid modes.
+
+2020-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR libstdc++/88101
+ * c-common.c (check_builtin_function_arguments): Handle
+ BUILT_IN_CLEAR_PADDING.
+
+2020-11-18 Nathan Sidwell <nathan@acm.org>
+
+ * c-lex.c (c_lex_with_flags): CPP_HEADER_NAMEs can now be seen.
+
+2020-11-17 Nathan Sidwell <nathan@acm.org>
+
+ * c-common.h (enum c_tree_index): Reorder to place lazy fields
+ after newly-added CTI_MODULE_HWM.
+
+2020-11-17 Joseph Myers <joseph@codesourcery.com>
+
+ * c-cppbuiltin.c (builtin_define_float_constants): Define
+ "*_IS_IEC_60559__" macros.
+
+2020-11-17 Nathan Sidwell <nathan@acm.org>
+
+ * c-lex.c: #include "langhooks.h".
+ (cb_undef): Maybe call preprocess_undef lang hook.
+ * c-opts.c (c_common_post_options): Maybe call preprocess_options
+ lang hook.
+ (push_command_line_include): Maybe call preprocess_main_file lang
+ hook.
+ (cb_file_change): Likewise.
+ * c-ppoutput.c: #include "langhooks.h.
+ (scan_translation_unit): Maybe call preprocess_token lang hook.
+ (class do_streamer): New, derive from token_streamer.
+ (directives_only_cb): Data pointer is do_streamer, call
+ preprocess_token lang hook.
+ (scan_translation_unit_directives_only): Use do_streamer.
+ (print_line_1): Move src_line recording to after string output.
+ (cb_undef): Maybe call preprocess_undef lang hook.
+
+2020-11-17 Nathan Sidwell <nathan@acm.org>
+
+ * c-ppoutput.c (scan_translation_unit): Use token_streamer, remove
+ code duplicating that functionality.
+
+2020-11-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/90628
+ * c-common.c (check_builtin_function_arguments)
+ <case BUILT_IN_ADD_OVERFLOW>: Diagnose when last argument is pointer
+ to _Atomic. For the TYPE_READONLY case, adjust message to be usable
+ for more builtins and argument positions.
+
+2020-11-16 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR objc/97854
+ * stub-objc.c: Include c-common.h to declare enum rid.
+
+2020-11-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/63287
+ * c-cppbuiltin.c: Include configargs.h.
+ (c_cpp_builtins): For C++11 and later if THREAD_MODEL_SPEC is not
+ defined, predefine __STDCPP_THREADS__ to 1 unless thread_model is
+ "single".
+
+2020-11-13 Gergö Barany <gergo@codesourcery.com>
+ Thomas Schwinge <thomas@codesourcery.com>
+
+ * c.opt (fopenacc-kernels): Add.
+
+2020-11-13 Jason Merrill <jason@redhat.com>
+
+ * c-cppbuiltin.c (c_cpp_builtins): Define __cpp_using_enum.
+
+2020-11-13 Piotr H. Dabrowski <phd@phd.re>
+
+ PR c++/91318
+ * c-cppbuiltin.c: c_cpp_builtins_optimize_pragma(): use cpp_define_unused()
+
+2020-11-13 Martin Liska <mliska@suse.cz>
+
+ * c-attribs.c (build_attr_access_from_parms): Format properly.
+
+2020-11-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR objc/90707
+ * c-common.c (c_common_reswords): null_unspecified, nullable,
+ nonnull, null_resettable: New keywords.
+ * c-common.h (enum rid): RID_NULL_UNSPECIFIED, RID_NULLABLE,
+ RID_NONNULL, RID_NULL_RESETTABLE: New.
+ (OBJC_IS_PATTR_KEYWORD): Include nullability keywords in the
+ ranges accepted for property attributes.
+ * c-attribs.c (handle_objc_nullability_attribute): New.
+ * c-objc.h (enum objc_property_attribute_group): Add
+ OBJC_PROPATTR_GROUP_NULLABLE.
+ (enum objc_property_attribute_kind):Add
+ OBJC_PROPERTY_ATTR_NULL_UNSPECIFIED, OBJC_PROPERTY_ATTR_NULLABLE,
+ OBJC_PROPERTY_ATTR_NONNULL, OBJC_PROPERTY_ATTR_NULL_RESETTABLE.
+
+2020-11-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR objc/77404
+ * c-attribs.c (handle_objc_root_class_attribute): New
+ * c-objc.h (objc_start_class_interface): Add a location
+ value for the position of the class name.
+ * c.opt: Add Wobjc-root-class.
+ * stub-objc.c (objc_start_class_interface): Add a location
+ value for the position of the class name.
+
+2020-11-12 Joseph Myers <joseph@codesourcery.com>
+
+ * c-lex.c (c_common_has_attribute): Take argument std_syntax.
+ Allow scope for C. Handle standard attributes for C. Do not
+ accept unscoped attributes if std_syntax and not handled as
+ standard attributes.
+ * c-common.h (c_common_has_attribute): Update prototype.
+
+2020-11-12 Nicholas Guriev <guriev-ns@ya.ru>
+
+ PR pch/86674
+ * c-pch.c (c_common_valid_pch): Use cpp_warning with CPP_W_INVALID_PCH
+ reason to fix -Werror=invalid-pch and -Wno-error=invalid-pch switches.
+
+2020-11-11 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/88115
+ * c-opts.c (c_common_post_options): Update latest_abi_version.
+
+2020-11-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/97748
+ * c-common.h (warn_if_unused_value): Add quiet argument defaulted
+ to false.
+ * c-warn.c (warn_if_unused_value): Likewise. Pass it down
+ recursively and just return true instead of warning if it is true.
+ Handle COMPLEX_EXPR.
+
+2020-11-10 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * c-common.h (c_omp_adjust_map_clauses): New declaration.
+ * c-omp.c (struct map_clause): Helper type for c_omp_adjust_map_clauses.
+ (c_omp_adjust_map_clauses): New function.
+
2020-11-09 Marek Polacek <polacek@redhat.com>
DR 1914
diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c
index 266a7fe..883036f 100644
--- a/gcc/c-family/c-ada-spec.c
+++ b/gcc/c-family/c-ada-spec.c
@@ -2598,16 +2598,6 @@ dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent,
pp_string (buffer, " is ");
dump_ada_structure (buffer, field_type, t, true, spc);
-
- pp_string (buffer, "with Convention => C_Pass_By_Copy");
-
- if (TREE_CODE (field_type) == UNION_TYPE)
- {
- pp_comma (buffer);
- newline_and_indent (buffer, spc + 5);
- pp_string (buffer, "Unchecked_Union => True");
- }
-
pp_semicolon (buffer);
newline_and_indent (buffer, spc);
break;
@@ -3318,10 +3308,7 @@ dump_ada_structure (pretty_printer *buffer, tree node, tree type, bool nested,
newline_and_indent (buffer, spc);
/* We disregard the methods for anonymous nested types. */
- if (nested)
- return;
-
- if (has_nontrivial_methods (node))
+ if (has_nontrivial_methods (node) && !nested)
{
pp_string (buffer, "with Import => True,");
newline_and_indent (buffer, spc + 5);
@@ -3339,12 +3326,20 @@ dump_ada_structure (pretty_printer *buffer, tree node, tree type, bool nested,
if (bitfield_used)
{
+ char buf[32];
pp_comma (buffer);
newline_and_indent (buffer, spc + 5);
pp_string (buffer, "Pack => True");
+ pp_comma (buffer);
+ newline_and_indent (buffer, spc + 5);
+ sprintf (buf, "Alignment => %d", TYPE_ALIGN (node) / BITS_PER_UNIT);
+ pp_string (buffer, buf);
bitfield_used = false;
}
+ if (nested)
+ return;
+
need_semicolon = !dump_ada_methods (buffer, node, spc);
/* Print the static fields of the structure, if any. */
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index f168082..99b6630 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -94,10 +94,10 @@ static tree handle_constructor_attribute (tree *, tree, tree, int, bool *);
static tree handle_destructor_attribute (tree *, tree, tree, int, bool *);
static tree handle_mode_attribute (tree *, tree, tree, int, bool *);
static tree handle_section_attribute (tree *, tree, tree, int, bool *);
+static tree handle_special_var_sec_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 *);
@@ -158,6 +158,8 @@ static tree handle_patchable_function_entry_attribute (tree *, tree, tree,
int, bool *);
static tree handle_copy_attribute (tree *, tree, tree, int, bool *);
static tree handle_nsobject_attribute (tree *, tree, tree, int, bool *);
+static tree handle_objc_root_class_attribute (tree *, tree, tree, int, bool *);
+static tree handle_objc_nullability_attribute (tree *, tree, tree, int, bool *);
/* Helper to define attribute exclusions. */
#define ATTR_EXCL(name, function, type, variable) \
@@ -246,9 +248,12 @@ 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[] =
+/* Exclusions that apply to attributes that put declarations in specific
+ sections. */
+static const struct attribute_spec::exclusions attr_section_exclusions[] =
{
ATTR_EXCL ("noinit", true, true, true),
+ ATTR_EXCL ("persistent", true, true, true),
ATTR_EXCL ("section", true, true, true),
ATTR_EXCL (NULL, false, false, false),
};
@@ -337,7 +342,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, attr_noinit_exclusions },
+ handle_section_attribute, attr_section_exclusions },
{ "aligned", 0, 1, false, false, false, false,
handle_aligned_attribute,
attr_aligned_exclusions },
@@ -507,12 +512,18 @@ const struct attribute_spec c_common_attribute_table[] =
{ "copy", 1, 1, false, false, false, false,
handle_copy_attribute, NULL },
{ "noinit", 0, 0, true, false, false, false,
- handle_noinit_attribute, attr_noinit_exclusions },
+ handle_special_var_sec_attribute, attr_section_exclusions },
+ { "persistent", 0, 0, true, false, false, false,
+ handle_special_var_sec_attribute, attr_section_exclusions },
{ "access", 1, 3, false, true, true, false,
handle_access_attribute, NULL },
/* Attributes used by Objective-C. */
{ "NSObject", 0, 0, true, false, false, false,
handle_nsobject_attribute, NULL },
+ { "objc_root_class", 0, 0, true, false, false, false,
+ handle_objc_root_class_attribute, NULL },
+ { "objc_nullability", 1, 1, true, false, false, false,
+ handle_objc_nullability_attribute, NULL },
{ NULL, 0, 0, false, false, false, false, NULL, NULL }
};
@@ -2381,64 +2392,112 @@ 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. */
-
+/* Handle a "noinit" or "persistent" attribute; arguments as in
+ struct attribute_spec.handler.
+ This generic handler is used for "special variable sections" that allow the
+ section name to be set using a dedicated attribute. Additional validation
+ is performed for the specific properties of the section corresponding to the
+ attribute.
+ The ".noinit" section *is not* loaded by the program loader, and is not
+ initialized by the runtime startup code.
+ The ".persistent" section *is* loaded by the program loader, but is not
+ initialized by the runtime startup code. */
static tree
-handle_noinit_attribute (tree * node,
- tree name,
- tree args,
- int flags ATTRIBUTE_UNUSED,
- bool *no_add_attrs)
+handle_special_var_sec_attribute (tree *node, tree name, tree args,
+ int flags, bool *no_add_attrs)
{
- const char *message = NULL;
+ tree decl = *node;
tree res = NULL_TREE;
- gcc_assert (DECL_P (*node));
- gcc_assert (args == NULL);
+ /* First perform generic validation common to "noinit" and "persistent"
+ attributes. */
+ if (!targetm_common.have_named_sections)
+ {
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "section attributes are not supported for this target");
+ goto fail;
+ }
+
+ if (!VAR_P (decl))
+ {
+ warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
+ "ignoring %qE attribute not set on a variable",
+ name);
+ goto fail;
+ }
+
+ if (VAR_P (decl)
+ && current_function_decl != NULL_TREE
+ && !TREE_STATIC (decl))
+ {
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "%qE attribute cannot be specified for local variables",
+ name);
+ goto fail;
+ }
- if (TREE_CODE (*node) != VAR_DECL)
- message = G_("%qE attribute only applies to variables");
+ if (VAR_P (decl)
+ && !targetm.have_tls && targetm.emutls.tmpl_section
+ && DECL_THREAD_LOCAL_P (decl))
+ {
+ error ("section of %q+D cannot be overridden", decl);
+ goto fail;
+ }
- /* 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");
+ if (!targetm.have_switchable_bss_sections)
+ {
+ error ("%qE attribute is specific to ELF targets", name);
+ goto fail;
+ }
- else if (!targetm.have_switchable_bss_sections)
- message = G_("%qE attribute is specific to ELF targets");
+ if (TREE_READONLY (decl))
+ {
+ warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
+ "ignoring %qE attribute set on const variable",
+ name);
+ goto fail;
+ }
- if (message)
+ /* Now validate noinit/persistent individually. */
+ if (strcmp (IDENTIFIER_POINTER (name), "noinit") == 0)
{
- warning (OPT_Wattributes, message, name);
- *no_add_attrs = true;
+ if (DECL_INITIAL (decl))
+ {
+ warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
+ "ignoring %qE attribute set on initialized variable",
+ name);
+ goto fail;
+ }
+ /* If this var is thought to be common, then change this. "noinit"
+ variables must be placed in an explicit ".noinit" section. */
+ DECL_COMMON (decl) = 0;
}
- else
+ else if (strcmp (IDENTIFIER_POINTER (name), "persistent") == 0)
{
- res = targetm.handle_generic_attribute (node, name, args, flags,
- no_add_attrs);
- /* If the back end confirms the attribute can be added then continue onto
- final processing. */
- if (!(*no_add_attrs))
+ if (DECL_COMMON (decl) || DECL_INITIAL (decl) == NULL_TREE)
{
- /* 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;
+ warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
+ "ignoring %qE attribute set on uninitialized variable",
+ name);
+ goto fail;
}
}
+ else
+ gcc_unreachable ();
+ res = targetm.handle_generic_attribute (node, name, args, flags,
+ no_add_attrs);
+
+ /* If the back end confirms the attribute can be added then continue onto
+ final processing. */
+ if (!(*no_add_attrs))
+ return res;
+
+fail:
+ *no_add_attrs = true;
return res;
}
-
/* Handle a "noplt" attribute; arguments as in
struct attribute_spec.handler. */
@@ -2804,9 +2863,11 @@ handle_copy_attribute (tree *node, tree name, tree args,
tree attrs = TYPE_ATTRIBUTES (reftype);
/* Copy type attributes from REF to DECL. Pass in REF if it's a DECL
- or a type but not if it's an expression. */
+ or a type but not if it's an expression. Set ATTR_FLAG_INTERNAL
+ since the attributes' arguments may be in their internal form. */
for (tree at = attrs; at; at = TREE_CHAIN (at))
- decl_attributes (node, at, flags, EXPR_P (ref) ? NULL_TREE : ref);
+ decl_attributes (node, at, flags | ATTR_FLAG_INTERNAL,
+ EXPR_P (ref) ? NULL_TREE : ref);
return NULL_TREE;
}
@@ -4283,8 +4344,8 @@ append_access_attr (tree node[3], tree attrs, const char *attrstr,
the attribute and its arguments into a string. */
static tree
-handle_access_attribute (tree node[3], tree name, tree args,
- int ARG_UNUSED (flags), bool *no_add_attrs)
+handle_access_attribute (tree node[3], tree name, tree args, int flags,
+ bool *no_add_attrs)
{
tree attrs = TYPE_ATTRIBUTES (*node);
tree type = *node;
@@ -4330,15 +4391,19 @@ handle_access_attribute (tree node[3], tree name, tree args,
/* Recursively call self to "replace" the documented/external
form of the attribute with the condensend internal form. */
- decl_attributes (node, axsat, flags);
+ decl_attributes (node, axsat, flags | ATTR_FLAG_INTERNAL);
return NULL_TREE;
}
- /* This is a recursive call to handle the condensed internal form
- of the attribute (see below). Since all validation has been
- done simply return here, accepting the attribute as is. */
- *no_add_attrs = false;
- return NULL_TREE;
+ if (flags & ATTR_FLAG_INTERNAL)
+ {
+ /* This is a recursive call to handle the condensed internal
+ form of the attribute (see below). Since all validation
+ has been done simply return here, accepting the attribute
+ as is. */
+ *no_add_attrs = false;
+ return NULL_TREE;
+ }
}
/* Set to true when the access mode has the form of a function call
@@ -4357,6 +4422,13 @@ handle_access_attribute (tree node[3], tree name, tree args,
access_mode = DECL_NAME (access_mode);
funcall = true;
}
+ else if (TREE_CODE (access_mode) != IDENTIFIER_NODE)
+ {
+ error ("attribute %qE mode %qE is not an identifier; expected one of "
+ "%qs, %qs, %qs, or %qs", name, access_mode,
+ "read_only", "read_write", "write_only", "none");
+ return NULL_TREE;
+ }
const char* const access_str = IDENTIFIER_POINTER (access_mode);
const char *ps = access_str;
@@ -4567,7 +4639,7 @@ handle_access_attribute (tree node[3], tree name, tree args,
/* Recursively call self to "replace" the documented/external form
of the attribute with the condensed internal form. */
- decl_attributes (node, new_attrs, flags);
+ decl_attributes (node, new_attrs, flags | ATTR_FLAG_INTERNAL);
return NULL_TREE;
}
@@ -4695,7 +4767,7 @@ build_attr_access_from_parms (tree parms, bool skip_voidptr)
/* Attribute access takes a two or three arguments. Wrap VBLIST in
another list in case it has more nodes than would otherwise fit. */
- vblist = build_tree_list (NULL_TREE, vblist);
+ vblist = build_tree_list (NULL_TREE, vblist);
/* Build a single attribute access with the string describing all
array arguments and an optional list of any non-parameter VLA
@@ -5119,8 +5191,8 @@ handle_patchable_function_entry_attribute (tree *, tree name, tree args,
if (tree_to_uhwi (val) > USHRT_MAX)
{
warning (OPT_Wattributes,
- "%qE attribute argument %qE is out of range (> 65535)",
- name, val);
+ "%qE attribute argument %qE exceeds %u",
+ name, val, USHRT_MAX);
*no_add_attrs = true;
return NULL_TREE;
}
@@ -5163,6 +5235,68 @@ handle_nsobject_attribute (tree *node, tree name, tree args,
return NULL_TREE;
}
+/* Handle a "objc_root_class" attributes; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_objc_root_class_attribute (tree */*node*/, tree name, tree /*args*/,
+ int /*flags*/, bool *no_add_attrs)
+{
+ /* This has no meaning outside Objective-C. */
+ if (!c_dialect_objc())
+ warning (OPT_Wattributes, "%qE is only applicable to Objective-C"
+ " class interfaces, attribute ignored", name);
+
+ *no_add_attrs = true;
+ return NULL_TREE;
+}
+
+/* Handle an "objc_nullability" attribute; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_objc_nullability_attribute (tree *node, tree name, tree args,
+ int /*flags*/,
+ bool *no_add_attrs)
+{
+ *no_add_attrs = true;
+
+ tree type = TREE_TYPE (*node);
+ if (TREE_CODE (*node) == FUNCTION_DECL)
+ type = TREE_TYPE (type);
+
+ if (type && !POINTER_TYPE_P (type))
+ {
+ error ("%qE cannot be applied to non-pointer type %qT", name, type);
+ return NULL_TREE;
+ }
+
+ /* We accept objc_nullability() with a single argument.
+ string: "unspecified", "nullable", "nonnull" or "resettable"
+ integer: 0 and 3 where the values have the same meaning as
+ the strings. */
+ tree val = TREE_VALUE (args);
+ if (TREE_CODE (val) == INTEGER_CST)
+ {
+ val = default_conversion (val);
+ if (!tree_fits_uhwi_p (val) || tree_to_uhwi (val) > 3)
+ error ("%qE attribute argument %qE is not an integer constant"
+ " between 0 and 3", name, val);
+ else
+ *no_add_attrs = false; /* OK */
+ }
+ else if (TREE_CODE (val) == STRING_CST
+ && (strcmp (TREE_STRING_POINTER (val), "nullable") == 0
+ || strcmp (TREE_STRING_POINTER (val), "nonnull") == 0
+ || strcmp (TREE_STRING_POINTER (val), "unspecified") == 0
+ || strcmp (TREE_STRING_POINTER (val), "resettable") == 0))
+ *no_add_attrs = false; /* OK */
+ else if (val != error_mark_node)
+ error ("%qE attribute argument %qE is not recognised", name, val);
+
+ return NULL_TREE;
+}
+
/* Attempt to partially validate a single attribute ATTR as if
it were to be applied to an entity OPER. */
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 29508bc..dda2352 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -374,6 +374,7 @@ const struct c_common_resword c_common_reswords[] =
{ "__auto_type", RID_AUTO_TYPE, D_CONLY },
{ "__bases", RID_BASES, D_CXXONLY },
{ "__builtin_addressof", RID_ADDRESSOF, D_CXXONLY },
+ { "__builtin_bit_cast", RID_BUILTIN_BIT_CAST, D_CXXONLY },
{ "__builtin_call_with_static_chain",
RID_BUILTIN_CALL_WITH_STATIC_CHAIN, D_CONLY },
{ "__builtin_choose_expr", RID_CHOOSE_EXPR, D_CONLY },
@@ -540,6 +541,12 @@ const struct c_common_resword c_common_reswords[] =
{ "concept", RID_CONCEPT, D_CXX_CONCEPTS_FLAGS | D_CXXWARN },
{ "requires", RID_REQUIRES, D_CXX_CONCEPTS_FLAGS | D_CXXWARN },
+ /* Modules-related keywords, these are internal unspellable tokens,
+ created by the preprocessor. */
+ { "module ", RID__MODULE, D_CXX_MODULES_FLAGS | D_CXXWARN },
+ { "import ", RID__IMPORT, D_CXX_MODULES_FLAGS | D_CXXWARN },
+ { "export ", RID__EXPORT, D_CXX_MODULES_FLAGS | D_CXXWARN },
+
/* Coroutines-related keywords */
{ "co_await", RID_CO_AWAIT, D_CXX_COROUTINES_FLAGS | D_CXXWARN },
{ "co_yield", RID_CO_YIELD, D_CXX_COROUTINES_FLAGS | D_CXXWARN },
@@ -580,6 +587,12 @@ const struct c_common_resword c_common_reswords[] =
{ "readwrite", RID_READWRITE, D_OBJC },
{ "retain", RID_RETAIN, D_OBJC },
{ "setter", RID_SETTER, D_OBJC },
+ /* These are Objective C implementation of nullability, accepted only in
+ specific contexts. */
+ { "null_unspecified", RID_NULL_UNSPECIFIED, D_OBJC },
+ { "nullable", RID_NULLABLE, D_OBJC },
+ { "nonnull", RID_NONNULL, D_OBJC },
+ { "null_resettable", RID_NULL_RESETTABLE, D_OBJC },
};
const unsigned int num_c_common_reswords =
@@ -6127,11 +6140,18 @@ check_builtin_function_arguments (location_t loc, vec<location_t> arg_loc,
}
else if (TYPE_READONLY (TREE_TYPE (TREE_TYPE (args[2]))))
{
- error_at (ARG_LOCATION (2), "argument 3 in call to function %qE "
- "has pointer to %<const%> type (%qT)", fndecl,
+ error_at (ARG_LOCATION (2), "argument %u in call to function %qE "
+ "has pointer to %qs type (%qT)", 3, fndecl, "const",
TREE_TYPE (args[2]));
return false;
}
+ else if (TYPE_ATOMIC (TREE_TYPE (TREE_TYPE (args[2]))))
+ {
+ error_at (ARG_LOCATION (2), "argument %u in call to function %qE "
+ "has pointer to %qs type (%qT)", 3, fndecl,
+ "_Atomic", TREE_TYPE (args[2]));
+ return false;
+ }
return true;
}
return false;
@@ -6165,6 +6185,39 @@ check_builtin_function_arguments (location_t loc, vec<location_t> arg_loc,
}
return false;
+ case BUILT_IN_CLEAR_PADDING:
+ if (builtin_function_validate_nargs (loc, fndecl, nargs, 1))
+ {
+ if (!POINTER_TYPE_P (TREE_TYPE (args[0])))
+ {
+ error_at (ARG_LOCATION (0), "argument %u in call to function "
+ "%qE does not have pointer type", 1, fndecl);
+ return false;
+ }
+ else if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (args[0]))))
+ {
+ error_at (ARG_LOCATION (0), "argument %u in call to function "
+ "%qE points to incomplete type", 1, fndecl);
+ return false;
+ }
+ else if (TYPE_READONLY (TREE_TYPE (TREE_TYPE (args[0]))))
+ {
+ error_at (ARG_LOCATION (0), "argument %u in call to function %qE "
+ "has pointer to %qs type (%qT)", 1, fndecl, "const",
+ TREE_TYPE (args[0]));
+ return false;
+ }
+ else if (TYPE_ATOMIC (TREE_TYPE (TREE_TYPE (args[0]))))
+ {
+ error_at (ARG_LOCATION (0), "argument %u in call to function %qE "
+ "has pointer to %qs type (%qT)", 1, fndecl,
+ "_Atomic", TREE_TYPE (args[0]));
+ return false;
+ }
+ return true;
+ }
+ return false;
+
default:
return true;
}
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 94f4868..80830d8 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -87,6 +87,11 @@ enum rid
RID_ASSIGN, RID_RETAIN, RID_COPY,
RID_PROPATOMIC, RID_NONATOMIC,
+ /* ObjC nullability support keywords that also can appear in the
+ property attribute context. These values should remain contiguous
+ with the other property attributes. */
+ RID_NULL_UNSPECIFIED, RID_NULLABLE, RID_NONNULL, RID_NULL_RESETTABLE,
+
/* C (reserved and imaginary types not implemented, so any use is a
syntax error) */
RID_IMAGINARY,
@@ -164,7 +169,7 @@ enum rid
RID_HAS_NOTHROW_COPY, RID_HAS_TRIVIAL_ASSIGN,
RID_HAS_TRIVIAL_CONSTRUCTOR, RID_HAS_TRIVIAL_COPY,
RID_HAS_TRIVIAL_DESTRUCTOR, RID_HAS_UNIQUE_OBJ_REPRESENTATIONS,
- RID_HAS_VIRTUAL_DESTRUCTOR,
+ RID_HAS_VIRTUAL_DESTRUCTOR, RID_BUILTIN_BIT_CAST,
RID_IS_ABSTRACT, RID_IS_AGGREGATE,
RID_IS_BASE_OF, RID_IS_CLASS,
RID_IS_EMPTY, RID_IS_ENUM,
@@ -190,6 +195,9 @@ enum rid
/* C++ concepts */
RID_CONCEPT, RID_REQUIRES,
+ /* C++ modules. */
+ RID__MODULE, RID__IMPORT, RID__EXPORT, /* Internal tokens. */
+
/* C++ coroutines */
RID_CO_AWAIT, RID_CO_YIELD, RID_CO_RETURN,
@@ -264,7 +272,7 @@ enum rid
RID_FIRST_PQ = RID_IN,
RID_LAST_PQ = RID_ONEWAY,
RID_FIRST_PATTR = RID_GETTER,
- RID_LAST_PATTR = RID_NONATOMIC
+ RID_LAST_PATTR = RID_NULL_RESETTABLE
};
#define OBJC_IS_AT_KEYWORD(rid) \
@@ -359,13 +367,17 @@ enum c_tree_index
CTI_DEFAULT_FUNCTION_TYPE,
+ CTI_NULL,
+
/* These are not types, but we have to look them up all the time. */
CTI_FUNCTION_NAME_DECL,
CTI_PRETTY_FUNCTION_NAME_DECL,
CTI_C99_FUNCTION_NAME_DECL,
- CTI_SAVED_FUNCTION_NAME_DECLS,
- CTI_NULL,
+ CTI_MODULE_HWM,
+ /* Below here entities change during compilation. */
+
+ CTI_SAVED_FUNCTION_NAME_DECLS,
CTI_MAX
};
@@ -440,9 +452,11 @@ extern machine_mode c_default_pointer_mode;
#define D_CXX_CHAR8_T 0X1000 /* In C++, only with -fchar8_t. */
#define D_CXX20 0x2000 /* In C++, C++20 only. */
#define D_CXX_COROUTINES 0x4000 /* In C++, only with coroutines. */
+#define D_CXX_MODULES 0x8000 /* In C++, only with modules. */
#define D_CXX_CONCEPTS_FLAGS D_CXXONLY | D_CXX_CONCEPTS
#define D_CXX_CHAR8_T_FLAGS D_CXXONLY | D_CXX_CHAR8_T
+#define D_CXX_MODULES_FLAGS (D_CXXONLY | D_CXX_MODULES)
#define D_CXX_COROUTINES_FLAGS (D_CXXONLY | D_CXX_COROUTINES)
/* The reserved keyword table. */
@@ -1042,7 +1056,7 @@ extern bool c_cpp_diagnostic (cpp_reader *, enum cpp_diagnostic_level,
enum cpp_warning_reason, rich_location *,
const char *, va_list *)
ATTRIBUTE_GCC_DIAG(5,0);
-extern int c_common_has_attribute (cpp_reader *);
+extern int c_common_has_attribute (cpp_reader *, bool);
extern int c_common_has_builtin (cpp_reader *);
extern bool parse_optimize_options (tree, bool);
diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index e5ebb79..7b7b07d 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "debug.h" /* For dwarf2out_do_cfi_asm. */
#include "common/common-target.h"
#include "cppbuiltin.h"
+#include "configargs.h"
#ifndef TARGET_OS_CPP_BUILTINS
# define TARGET_OS_CPP_BUILTINS()
@@ -316,6 +317,16 @@ builtin_define_float_constants (const char *name_prefix,
sprintf (name, "__FP_FAST_FMA%s", fma_suffix);
builtin_define_with_int_value (name, 1);
}
+
+ /* For C2x *_IS_IEC_60559. 0 means the type does not match an IEC
+ 60559 format, 1 that it matches a format but not operations and 2
+ that it matches a format and operations (but may not conform to
+ Annex F; we take this as meaning exceptions and rounding modes
+ need not be supported). */
+ sprintf (name, "__%s_IS_IEC_60559__", name_prefix);
+ builtin_define_with_int_value (name,
+ (fmt->ieee_bits == 0
+ ? 0 : (fmt->round_towards_zero ? 1 : 2)));
}
/* Define __DECx__ constants for TYPE using NAME_PREFIX and SUFFIX. */
@@ -581,41 +592,41 @@ c_cpp_builtins_optimize_pragma (cpp_reader *pfile, tree prev_tree,
/* Other target-independent built-ins determined by command-line
options. */
if (!prev->x_optimize_size && cur->x_optimize_size)
- cpp_define (pfile, "__OPTIMIZE_SIZE__");
+ cpp_define_unused (pfile, "__OPTIMIZE_SIZE__");
else if (prev->x_optimize_size && !cur->x_optimize_size)
cpp_undef (pfile, "__OPTIMIZE_SIZE__");
if (!prev->x_optimize && cur->x_optimize)
- cpp_define (pfile, "__OPTIMIZE__");
+ cpp_define_unused (pfile, "__OPTIMIZE__");
else if (prev->x_optimize && !cur->x_optimize)
cpp_undef (pfile, "__OPTIMIZE__");
prev_fast_math = fast_math_flags_struct_set_p (prev);
cur_fast_math = fast_math_flags_struct_set_p (cur);
if (!prev_fast_math && cur_fast_math)
- cpp_define (pfile, "__FAST_MATH__");
+ cpp_define_unused (pfile, "__FAST_MATH__");
else if (prev_fast_math && !cur_fast_math)
cpp_undef (pfile, "__FAST_MATH__");
if (!prev->x_flag_signaling_nans && cur->x_flag_signaling_nans)
- cpp_define (pfile, "__SUPPORT_SNAN__");
+ cpp_define_unused (pfile, "__SUPPORT_SNAN__");
else if (prev->x_flag_signaling_nans && !cur->x_flag_signaling_nans)
cpp_undef (pfile, "__SUPPORT_SNAN__");
if (!prev->x_flag_errno_math && cur->x_flag_errno_math)
cpp_undef (pfile, "__NO_MATH_ERRNO__");
else if (prev->x_flag_errno_math && !cur->x_flag_errno_math)
- cpp_define (pfile, "__NO_MATH_ERRNO__");
+ cpp_define_unused (pfile, "__NO_MATH_ERRNO__");
if (!prev->x_flag_finite_math_only && cur->x_flag_finite_math_only)
{
cpp_undef (pfile, "__FINITE_MATH_ONLY__");
- cpp_define (pfile, "__FINITE_MATH_ONLY__=1");
+ cpp_define_unused (pfile, "__FINITE_MATH_ONLY__=1");
}
else if (prev->x_flag_finite_math_only && !cur->x_flag_finite_math_only)
{
cpp_undef (pfile, "__FINITE_MATH_ONLY__");
- cpp_define (pfile, "__FINITE_MATH_ONLY__=0");
+ cpp_define_unused (pfile, "__FINITE_MATH_ONLY__=0");
}
}
@@ -866,6 +877,13 @@ c_cpp_builtins (cpp_reader *pfile)
define_language_independent_builtin_macros (pfile);
+ /* encoding definitions used by users and libraries */
+ builtin_define_with_value ("__GNUC_EXECUTION_CHARSET_NAME",
+ cpp_get_narrow_charset_name (pfile), 1);
+ builtin_define_with_value ("__GNUC_WIDE_EXECUTION_CHARSET_NAME",
+ cpp_get_wide_charset_name (pfile), 1);
+
+
if (c_dialect_cxx ())
{
int major;
@@ -1005,6 +1023,7 @@ c_cpp_builtins (cpp_reader *pfile)
cpp_define (pfile, "__cpp_constexpr_dynamic_alloc=201907L");
cpp_define (pfile, "__cpp_impl_three_way_comparison=201907L");
cpp_define (pfile, "__cpp_aggregate_paren_init=201902L");
+ cpp_define (pfile, "__cpp_using_enum=201907L");
}
if (flag_concepts)
{
@@ -1013,6 +1032,10 @@ c_cpp_builtins (cpp_reader *pfile)
else
cpp_define (pfile, "__cpp_concepts=201507L");
}
+ if (flag_modules)
+ /* The std-defined value is 201907L, but I don't think we can
+ claim victory yet. 201810 is the p1103 date. */
+ cpp_define (pfile, "__cpp_modules=201810L");
if (flag_coroutines)
cpp_define (pfile, "__cpp_impl_coroutine=201902L"); /* n4861, DIS */
if (flag_tm)
@@ -1033,6 +1056,12 @@ c_cpp_builtins (cpp_reader *pfile)
cpp_define (pfile, "__cpp_threadsafe_static_init=200806L");
if (flag_char8_t)
cpp_define (pfile, "__cpp_char8_t=201811L");
+#ifndef THREAD_MODEL_SPEC
+ /* Targets that define THREAD_MODEL_SPEC need to define
+ __STDCPP_THREADS__ in their config/XXX/XXX-c.c themselves. */
+ if (cxx_dialect >= cxx11 && strcmp (thread_model, "single") != 0)
+ cpp_define (pfile, "__STDCPP_THREADS__=1");
+#endif
}
/* Note that we define this for C as well, so that we know if
__attribute__((cleanup)) will interface with EH. */
diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c
index e81e16d..c8d33d0 100644
--- a/gcc/c-family/c-lex.c
+++ b/gcc/c-family/c-lex.c
@@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "c-pragma.h"
#include "debug.h"
#include "file-prefix-map.h" /* remap_macro_filename() */
-
+#include "langhooks.h"
#include "attribs.h"
/* We may keep statistics about how long which files took to compile. */
@@ -274,9 +274,11 @@ cb_define (cpp_reader *pfile, location_t loc, cpp_hashnode *node)
/* #undef callback for DWARF and DWARF2 debug info. */
static void
-cb_undef (cpp_reader * ARG_UNUSED (pfile), location_t loc,
- cpp_hashnode *node)
+cb_undef (cpp_reader *pfile, location_t loc, cpp_hashnode *node)
{
+ if (lang_hooks.preprocess_undef)
+ lang_hooks.preprocess_undef (pfile, loc, node);
+
const struct line_map *map = linemap_lookup (line_table, loc);
(*debug_hooks->undef) (SOURCE_LINE (linemap_check_ordinary (map), loc),
(const char *) NODE_NAME (node));
@@ -300,7 +302,7 @@ get_token_no_padding (cpp_reader *pfile)
/* Callback for has_attribute. */
int
-c_common_has_attribute (cpp_reader *pfile)
+c_common_has_attribute (cpp_reader *pfile, bool std_syntax)
{
int result = 0;
tree attr_name = NULL_TREE;
@@ -319,35 +321,37 @@ c_common_has_attribute (cpp_reader *pfile)
attr_name = get_identifier ((const char *)
cpp_token_as_text (pfile, token));
attr_name = canonicalize_attr_name (attr_name);
- if (c_dialect_cxx ())
+ bool have_scope = false;
+ int idx = 0;
+ const cpp_token *nxt_token;
+ do
+ nxt_token = cpp_peek_token (pfile, idx++);
+ while (nxt_token->type == CPP_PADDING);
+ if (nxt_token->type == CPP_SCOPE)
{
- int idx = 0;
- const cpp_token *nxt_token;
- do
- nxt_token = cpp_peek_token (pfile, idx++);
- while (nxt_token->type == CPP_PADDING);
- if (nxt_token->type == CPP_SCOPE)
+ have_scope = true;
+ get_token_no_padding (pfile); // Eat scope.
+ nxt_token = get_token_no_padding (pfile);
+ if (nxt_token->type == CPP_NAME)
{
- get_token_no_padding (pfile); // Eat scope.
- nxt_token = get_token_no_padding (pfile);
- if (nxt_token->type == CPP_NAME)
- {
- tree attr_ns = attr_name;
- tree attr_id
- = get_identifier ((const char *)
- cpp_token_as_text (pfile, nxt_token));
- attr_name = build_tree_list (attr_ns, attr_id);
- }
- else
- {
- cpp_error (pfile, CPP_DL_ERROR,
- "attribute identifier required after scope");
- attr_name = NULL_TREE;
- }
+ tree attr_ns = attr_name;
+ tree attr_id
+ = get_identifier ((const char *)
+ cpp_token_as_text (pfile, nxt_token));
+ attr_name = build_tree_list (attr_ns, attr_id);
}
else
{
- /* Some standard attributes need special handling. */
+ cpp_error (pfile, CPP_DL_ERROR,
+ "attribute identifier required after scope");
+ attr_name = NULL_TREE;
+ }
+ }
+ else
+ {
+ /* Some standard attributes need special handling. */
+ if (c_dialect_cxx ())
+ {
if (is_attribute_p ("noreturn", attr_name))
result = 200809;
else if (is_attribute_p ("deprecated", attr_name))
@@ -361,11 +365,20 @@ c_common_has_attribute (cpp_reader *pfile)
result = 201803;
else if (is_attribute_p ("nodiscard", attr_name))
result = 201907;
- if (result)
- attr_name = NULL_TREE;
}
+ else
+ {
+ if (is_attribute_p ("deprecated", attr_name)
+ || is_attribute_p ("maybe_unused", attr_name)
+ || is_attribute_p ("fallthrough", attr_name))
+ result = 201904;
+ else if (is_attribute_p ("nodiscard", attr_name))
+ result = 202003;
+ }
+ if (result)
+ attr_name = NULL_TREE;
}
- if (attr_name)
+ if (attr_name && (have_scope || !std_syntax))
{
init_attributes ();
const struct attribute_spec *attr = lookup_attribute_spec (attr_name);
@@ -654,8 +667,11 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
*value = build_int_cst (integer_type_node, tok->val.pragma);
break;
- /* These tokens should not be visible outside cpplib. */
case CPP_HEADER_NAME:
+ *value = build_string (tok->val.str.len, (const char *)tok->val.str.text);
+ break;
+
+ /* This token should not be visible outside cpplib. */
case CPP_MACRO_ARG:
gcc_unreachable ();
diff --git a/gcc/c-family/c-objc.h b/gcc/c-family/c-objc.h
index 6e96731..4b50260 100644
--- a/gcc/c-family/c-objc.h
+++ b/gcc/c-family/c-objc.h
@@ -44,6 +44,7 @@ enum objc_property_attribute_group
OBJC_PROPATTR_GROUP_READWRITE,
OBJC_PROPATTR_GROUP_ASSIGN,
OBJC_PROPATTR_GROUP_ATOMIC,
+ OBJC_PROPATTR_GROUP_NULLABLE,
OBJC_PROPATTR_GROUP_CLASS,
OBJC_PROPATTR_GROUP_MAX
};
@@ -60,6 +61,10 @@ enum objc_property_attribute_kind
OBJC_PROPERTY_ATTR_COPY = ( 7 << 8)|OBJC_PROPATTR_GROUP_ASSIGN,
OBJC_PROPERTY_ATTR_ATOMIC = ( 8 << 8)|OBJC_PROPATTR_GROUP_ATOMIC,
OBJC_PROPERTY_ATTR_NONATOMIC = ( 9 << 8)|OBJC_PROPATTR_GROUP_ATOMIC,
+ OBJC_PROPERTY_ATTR_NULL_UNSPECIFIED = (12 << 8)|OBJC_PROPATTR_GROUP_NULLABLE,
+ OBJC_PROPERTY_ATTR_NULLABLE = (13 << 8)|OBJC_PROPATTR_GROUP_NULLABLE,
+ OBJC_PROPERTY_ATTR_NONNULL = (14 << 8)|OBJC_PROPATTR_GROUP_NULLABLE,
+ OBJC_PROPERTY_ATTR_NULL_RESETTABLE = (15 << 8)|OBJC_PROPATTR_GROUP_NULLABLE,
OBJC_PROPERTY_ATTR_CLASS = (16 << 8)|OBJC_PROPATTR_GROUP_CLASS,
OBJC_PROPERTY_ATTR_MAX = (255 << 8|OBJC_PROPATTR_GROUP_MAX)
};
@@ -124,7 +129,7 @@ extern tree objc_get_protocol_qualified_type (tree, tree);
extern tree objc_get_class_reference (tree);
extern tree objc_get_class_ivars (tree);
extern bool objc_detect_field_duplicates (bool);
-extern void objc_start_class_interface (tree, tree, tree, tree);
+extern void objc_start_class_interface (tree, location_t, tree, tree, tree);
extern void objc_start_category_interface (tree, tree, tree, tree);
extern void objc_start_protocol (tree, tree, tree);
extern void objc_continue_interface (void);
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 0698e58..59cabd1 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -234,6 +234,7 @@ c_common_init_options (unsigned int decoded_options_count,
cpp_opts = cpp_get_options (parse_in);
cpp_opts->dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
cpp_opts->objc = c_dialect_objc ();
+ cpp_opts->deps.modules = true;
/* Reset to avoid warnings on internal definitions. We set it just
before passing on command-line options to cpplib. */
@@ -367,6 +368,18 @@ c_common_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
cpp_opts->deps.phony_targets = true;
break;
+ case OPT_Mmodules:
+ /* Do not set deps_seen, so the user can unconditionally turn
+ this on or off. */
+ cpp_opts->deps.modules = true;
+ break;
+
+ case OPT_Mno_modules:
+ /* Do not set deps_seen, so the user can unconditionally turn
+ this on or off. */
+ cpp_opts->deps.modules = false;
+ break;
+
case OPT_MQ:
case OPT_MT:
deps_seen = true;
@@ -945,7 +958,7 @@ c_common_post_options (const char **pfilename)
/* Change flag_abi_version to be the actual current ABI level, for the
benefit of c_cpp_builtins, and to make comparison simpler. */
- const int latest_abi_version = 14;
+ const int latest_abi_version = 15;
/* Generate compatibility aliases for ABI v11 (7.1) by default. */
const int abi_compat_default = 11;
@@ -1106,6 +1119,8 @@ c_common_post_options (const char **pfilename)
struct cpp_callbacks *cb = cpp_get_callbacks (parse_in);
cb->file_change = cb_file_change;
cb->dir_change = cb_dir_change;
+ if (lang_hooks.preprocess_options)
+ lang_hooks.preprocess_options (parse_in);
cpp_post_options (parse_in);
init_global_opts_from_cpp (&global_options, cpp_get_options (parse_in));
@@ -1548,7 +1563,13 @@ push_command_line_include (void)
cpp_opts->warn_unused_macros = cpp_warn_unused_macros;
/* Restore the line map back to the main file. */
if (!cpp_opts->preprocessed)
- cpp_change_file (parse_in, LC_RENAME, this_input_filename);
+ {
+ cpp_change_file (parse_in, LC_RENAME, this_input_filename);
+ if (lang_hooks.preprocess_main_file)
+ /* We're starting the main file. Inform the FE of that. */
+ lang_hooks.preprocess_main_file
+ (parse_in, line_table, LINEMAPS_LAST_ORDINARY_MAP (line_table));
+ }
/* Set this here so the client can change the option if it wishes,
and after stacking the main file so we don't trace the main file. */
@@ -1558,14 +1579,19 @@ push_command_line_include (void)
/* File change callback. Has to handle -include files. */
static void
-cb_file_change (cpp_reader * ARG_UNUSED (pfile),
- const line_map_ordinary *new_map)
+cb_file_change (cpp_reader *reader, const line_map_ordinary *new_map)
{
if (flag_preprocess_only)
pp_file_change (new_map);
else
fe_file_change (new_map);
+ if (new_map && cpp_opts->preprocessed
+ && lang_hooks.preprocess_main_file && MAIN_FILE_P (new_map)
+ && ORDINARY_MAP_STARTING_LINE_NUMBER (new_map))
+ /* We're starting the main file. Inform the FE of that. */
+ lang_hooks.preprocess_main_file (reader, line_table, new_map);
+
if (new_map
&& (new_map->reason == LC_ENTER || new_map->reason == LC_RENAME))
{
diff --git a/gcc/c-family/c-pch.c b/gcc/c-family/c-pch.c
index a2292f4..fdeb860 100644
--- a/gcc/c-family/c-pch.c
+++ b/gcc/c-family/c-pch.c
@@ -206,13 +206,16 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
/* Perform a quick test of whether this is a valid
precompiled header for the current language. */
+ /* C++ modules and PCH don't play together. */
+ if (flag_modules)
+ return 2;
+
sizeread = read (fd, ident, IDENT_LENGTH + 16);
if (sizeread == -1)
fatal_error (input_location, "cannot read %s: %m", name);
else if (sizeread != IDENT_LENGTH + 16)
{
- if (cpp_get_options (pfile)->warn_invalid_pch)
- cpp_error (pfile, CPP_DL_WARNING, "%s: too short to be a PCH file",
+ cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: too short to be a PCH file",
name);
return 2;
}
@@ -220,27 +223,22 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
pch_ident = get_ident();
if (memcmp (ident, pch_ident, IDENT_LENGTH) != 0)
{
- if (cpp_get_options (pfile)->warn_invalid_pch)
- {
- if (memcmp (ident, pch_ident, 5) == 0)
- /* It's a PCH, for the right language, but has the wrong version.
- */
- cpp_error (pfile, CPP_DL_WARNING,
+ if (memcmp (ident, pch_ident, 5) == 0)
+ /* It's a PCH, for the right language, but has the wrong version. */
+ cpp_warning (pfile, CPP_W_INVALID_PCH,
"%s: not compatible with this GCC version", name);
- else if (memcmp (ident, pch_ident, 4) == 0)
- /* It's a PCH for the wrong language. */
- cpp_error (pfile, CPP_DL_WARNING, "%s: not for %s", name,
+ else if (memcmp (ident, pch_ident, 4) == 0)
+ /* It's a PCH for the wrong language. */
+ cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: not for %s", name,
lang_hooks.name);
- else
- /* Not any kind of PCH. */
- cpp_error (pfile, CPP_DL_WARNING, "%s: not a PCH file", name);
- }
+ else
+ /* Not any kind of PCH. */
+ cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: not a PCH file", name);
return 2;
}
if (memcmp (ident + IDENT_LENGTH, executable_checksum, 16) != 0)
{
- if (cpp_get_options (pfile)->warn_invalid_pch)
- cpp_error (pfile, CPP_DL_WARNING,
+ cpp_warning (pfile, CPP_W_INVALID_PCH,
"%s: created by a different GCC executable", name);
return 2;
}
@@ -257,8 +255,7 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
if (v.debug_info_type != write_symbols
&& write_symbols != NO_DEBUG)
{
- if (cpp_get_options (pfile)->warn_invalid_pch)
- cpp_error (pfile, CPP_DL_WARNING,
+ cpp_warning (pfile, CPP_W_INVALID_PCH,
"%s: created with -g%s, but used with -g%s", name,
debug_type_names[v.debug_info_type],
debug_type_names[write_symbols]);
@@ -271,8 +268,7 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
for (i = 0; i < MATCH_SIZE; i++)
if (*pch_matching[i].flag_var != v.match[i])
{
- if (cpp_get_options (pfile)->warn_invalid_pch)
- cpp_error (pfile, CPP_DL_WARNING,
+ cpp_warning (pfile, CPP_W_INVALID_PCH,
"%s: settings for %s do not match", name,
pch_matching[i].flag_name);
return 2;
@@ -287,8 +283,7 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
check one function. */
if (v.pch_init != &pch_init)
{
- if (cpp_get_options (pfile)->warn_invalid_pch)
- cpp_error (pfile, CPP_DL_WARNING,
+ cpp_warning (pfile, CPP_W_INVALID_PCH,
"%s: had text segment at different address", name);
return 2;
}
@@ -305,8 +300,7 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
free (this_file_data);
if (msg != NULL)
{
- if (cpp_get_options (pfile)->warn_invalid_pch)
- cpp_error (pfile, CPP_DL_WARNING, "%s: %s", name, msg);
+ cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: %s", name, msg);
return 2;
}
}
diff --git a/gcc/c-family/c-ppoutput.c b/gcc/c-family/c-ppoutput.c
index 44c6f30..e3e0e59 100644
--- a/gcc/c-family/c-ppoutput.c
+++ b/gcc/c-family/c-ppoutput.c
@@ -21,6 +21,7 @@
#include "coretypes.h"
#include "c-common.h" /* For flags. */
#include "../libcpp/internal.h"
+#include "langhooks.h"
#include "c-pragma.h" /* For parse_in. */
#include "file-prefix-map.h" /* remap_macro_filename() */
@@ -301,125 +302,48 @@ token_streamer::stream (cpp_reader *pfile, const cpp_token *token,
/* Writes out the preprocessed file, handling spacing and paste
avoidance issues. */
+
static void
scan_translation_unit (cpp_reader *pfile)
{
- bool avoid_paste = false;
- bool do_line_adjustments
- = cpp_get_options (parse_in)->lang != CLK_ASM
- && !flag_no_line_commands;
- bool in_pragma = false;
- bool line_marker_emitted = false;
+ token_streamer streamer (pfile);
+ uintptr_t filter = 0;
+
+ if (lang_hooks.preprocess_token)
+ filter = lang_hooks.preprocess_token (pfile, NULL, filter);
print.source = NULL;
for (;;)
{
- location_t loc;
- const cpp_token *token = cpp_get_token_with_location (pfile, &loc);
+ location_t spelling_loc;
+ const cpp_token *token
+ = cpp_get_token_with_location (pfile, &spelling_loc);
- if (token->type == CPP_PADDING)
+ streamer.stream (pfile, token, spelling_loc);
+ if (filter)
{
- avoid_paste = true;
- if (print.source == NULL
- || (!(print.source->flags & PREV_WHITE)
- && token->val.source == NULL))
- print.source = token->val.source;
- continue;
+ unsigned flags = lang_hooks.preprocess_token (pfile, token, filter);
+ if (flags & lang_hooks::PT_begin_pragma)
+ streamer.begin_pragma ();
}
-
if (token->type == CPP_EOF)
break;
+ }
- /* Subtle logic to output a space if and only if necessary. */
- if (avoid_paste)
- {
- int src_line = LOCATION_LINE (loc);
-
- if (print.source == NULL)
- print.source = token;
-
- if (src_line != print.src_line
- && do_line_adjustments
- && !in_pragma)
- {
- line_marker_emitted = do_line_change (pfile, token, loc, false);
- putc (' ', print.outf);
- print.printed = true;
- }
- else if (print.source->flags & PREV_WHITE
- || (print.prev
- && cpp_avoid_paste (pfile, print.prev, token))
- || (print.prev == NULL && token->type == CPP_HASH))
- {
- putc (' ', print.outf);
- print.printed = true;
- }
- }
- else if (token->flags & PREV_WHITE)
- {
- int src_line = LOCATION_LINE (loc);
-
- if (src_line != print.src_line
- && do_line_adjustments
- && !in_pragma)
- line_marker_emitted = do_line_change (pfile, token, loc, false);
- putc (' ', print.outf);
- print.printed = true;
- }
+ if (filter)
+ lang_hooks.preprocess_token (pfile, NULL, filter);
+}
- avoid_paste = false;
- print.source = NULL;
- print.prev = token;
- if (token->type == CPP_PRAGMA)
- {
- const char *space;
- const char *name;
-
- line_marker_emitted = maybe_print_line (token->src_loc);
- fputs ("#pragma ", print.outf);
- c_pp_lookup_pragma (token->val.pragma, &space, &name);
- if (space)
- fprintf (print.outf, "%s %s", space, name);
- else
- fprintf (print.outf, "%s", name);
- print.printed = true;
- in_pragma = true;
- }
- else if (token->type == CPP_PRAGMA_EOL)
- {
- maybe_print_line (token->src_loc);
- in_pragma = false;
- }
- else
- {
- if (cpp_get_options (parse_in)->debug)
- linemap_dump_location (line_table, token->src_loc, print.outf);
-
- if (do_line_adjustments
- && !in_pragma
- && !line_marker_emitted
- && print.prev_was_system_token != !!in_system_header_at (loc)
- && !is_location_from_builtin_token (loc))
- /* The system-ness of this token is different from the one
- of the previous token. Let's emit a line change to
- mark the new system-ness before we emit the token. */
- {
- do_line_change (pfile, token, loc, false);
- print.prev_was_system_token = !!in_system_header_at (loc);
- }
- cpp_output_token (token, print.outf);
- line_marker_emitted = false;
- print.printed = true;
- }
+class do_streamer : public token_streamer
+{
+ public:
+ uintptr_t filter;
- /* CPP_COMMENT tokens and raw-string literal tokens can
- have embedded new-line characters. Rather than enumerating
- all the possible token types just check if token uses
- val.str union member. */
- if (cpp_token_val_index (token) == CPP_TOKEN_FLD_STR)
- account_for_newlines (token->val.str.text, token->val.str.len);
+ do_streamer (cpp_reader *pfile, uintptr_t filter)
+ :token_streamer (pfile), filter (filter)
+ {
}
-}
+};
static void
directives_only_cb (cpp_reader *pfile, CPP_DO_task task, void *data_, ...)
@@ -427,7 +351,7 @@ directives_only_cb (cpp_reader *pfile, CPP_DO_task task, void *data_, ...)
va_list args;
va_start (args, data_);
- token_streamer *streamer = reinterpret_cast <token_streamer *> (data_);
+ do_streamer *streamer = reinterpret_cast <do_streamer *> (data_);
switch (task)
{
default:
@@ -452,6 +376,13 @@ directives_only_cb (cpp_reader *pfile, CPP_DO_task task, void *data_, ...)
const cpp_token *token = va_arg (args, const cpp_token *);
location_t spelling_loc = va_arg (args, location_t);
streamer->stream (pfile, token, spelling_loc);
+ if (streamer->filter)
+ {
+ unsigned flags = lang_hooks.preprocess_token
+ (pfile, token, streamer->filter);
+ if (flags & lang_hooks::PT_begin_pragma)
+ streamer->begin_pragma ();
+ }
}
break;
}
@@ -464,8 +395,13 @@ directives_only_cb (cpp_reader *pfile, CPP_DO_task task, void *data_, ...)
static void
scan_translation_unit_directives_only (cpp_reader *pfile)
{
- token_streamer streamer (pfile);
+ uintptr_t filter = 0;
+ if (lang_hooks.preprocess_token)
+ filter = lang_hooks.preprocess_token (pfile, NULL, filter);
+ do_streamer streamer (pfile, filter);
cpp_directive_only_process (pfile, &streamer, directives_only_cb);
+ if (streamer.filter)
+ lang_hooks.preprocess_token (pfile, NULL, streamer.filter);
}
/* Adjust print.src_line for newlines embedded in output. */
@@ -564,15 +500,16 @@ print_line_1 (location_t src_loc, const char *special_flags, FILE *stream)
unsigned char *to_file_quoted =
(unsigned char *) alloca (to_file_len * 4 + 1);
- print.src_line = LOCATION_LINE (src_loc);
- print.src_file = file_path;
-
/* cpp_quote_string does not nul-terminate, so we have to do it
ourselves. */
unsigned char *p = cpp_quote_string (to_file_quoted,
(const unsigned char *) file_path,
to_file_len);
*p = '\0';
+
+ print.src_line = LOCATION_LINE (src_loc);
+ print.src_file = file_path;
+
fprintf (stream, "# %u \"%s\"%s",
print.src_line, to_file_quoted, special_flags);
@@ -678,9 +615,10 @@ cb_define (cpp_reader *pfile, location_t line, cpp_hashnode *node)
}
static void
-cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, location_t line,
- cpp_hashnode *node)
+cb_undef (cpp_reader *pfile, location_t line, cpp_hashnode *node)
{
+ if (lang_hooks.preprocess_undef)
+ lang_hooks.preprocess_undef (pfile, line, node);
maybe_print_line (line);
fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
print.src_line++;
diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c
index 8953e3b..3027703 100644
--- a/gcc/c-family/c-pretty-print.c
+++ b/gcc/c-family/c-pretty-print.c
@@ -342,6 +342,7 @@ c_pretty_printer::simple_type_specifier (tree t)
break;
case VOID_TYPE:
+ case OPAQUE_TYPE:
case BOOLEAN_TYPE:
case INTEGER_TYPE:
case REAL_TYPE:
@@ -662,6 +663,7 @@ c_pretty_printer::direct_abstract_declarator (tree t)
case IDENTIFIER_NODE:
case VOID_TYPE:
+ case OPAQUE_TYPE:
case BOOLEAN_TYPE:
case INTEGER_TYPE:
case REAL_TYPE:
diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c
index 6d1f9a7..91abafe 100644
--- a/gcc/c-family/c-warn.c
+++ b/gcc/c-family/c-warn.c
@@ -3374,18 +3374,21 @@ warn_parm_array_mismatch (location_t origloc, tree fndecl, tree newparms)
for (tree curp = curparms, newp = newparms; curp;
curp = TREE_CHAIN (curp), newp = TREE_CHAIN (newp), ++parmpos)
{
+ if (!newp)
+ /* Bail on invalid redeclarations with fewer arguments. */
+ return;
+
/* Only check pointers and C++ references. */
+ tree curptype = TREE_TYPE (curp);
tree newptype = TREE_TYPE (newp);
- if (!POINTER_TYPE_P (newptype))
+ if (!POINTER_TYPE_P (curptype) || !POINTER_TYPE_P (newptype))
continue;
- {
- /* Skip mismatches in __builtin_va_list that is commonly
- an array but that in declarations of built-ins decays
- to a pointer. */
- if (builtin && TREE_TYPE (newptype) == TREE_TYPE (va_list_type_node))
- continue;
- }
+ /* Skip mismatches in __builtin_va_list that is commonly
+ an array but that in declarations of built-ins decays
+ to a pointer. */
+ if (builtin && TREE_TYPE (newptype) == TREE_TYPE (va_list_type_node))
+ continue;
/* Access specs for the argument on the current (previous) and
new (to replace the current) declarations. Either may be null,
@@ -3428,7 +3431,6 @@ warn_parm_array_mismatch (location_t origloc, tree fndecl, tree newparms)
if (origloc == UNKNOWN_LOCATION)
origloc = newloc;
- tree curptype = TREE_TYPE (curp);
const std::string newparmstr = newa->array_as_string (newptype);
const std::string curparmstr = cura->array_as_string (curptype);
if (new_vla_p && !cur_vla_p)
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index fe16357..059f6c3 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -236,6 +236,14 @@ MMD
C ObjC C++ ObjC++ NoDriverArg Separate MissingArgError(missing filename after %qs)
Like -MD but ignore system header files.
+Mmodules
+C++
+Generate C++ Module dependency information.
+
+Mno-modules
+C++
+; undocumented
+
MP
C ObjC C++ ObjC++
Generate phony targets for all headers.
@@ -1002,6 +1010,11 @@ Enum(cpp_normalize_level) String(id) Value(normalized_identifier_C)
EnumValue
Enum(cpp_normalize_level) String(nfc) Value(normalized_C)
+Wobjc-root-class
+ObjC ObjC++ Var(warn_objc_root_class) Warning Init(1)
+Warn if a class interface has no superclass. Root classes may use an attribute
+to suppress this warning.
+
Wold-style-cast
C++ ObjC++ Var(warn_old_style_cast) Warning
Warn if a C-style cast is used in a program.
@@ -1678,6 +1691,57 @@ flax-vector-conversions
C ObjC C++ ObjC++ Var(flag_lax_vector_conversions)
Allow implicit conversions between vectors with differing numbers of subparts and/or differing element types.
+fmodules-ts
+C++ ObjC++ Var(flag_modules) Integer Init(0)
+Enable C++ modules-ts (experimental).
+
+fno-modules
+C++ ObjC++ Undocumented RejectNegative Var(flag_modules,0) Integer
+;; undocumented
+
+fmodule-header
+C++ ObjC RejectNegative Var(flag_header_unit,0) Integer
+Enable C++ header module (experimental).
+
+fmodule-header=
+C++ ObjC++ Joined RejectNegative Undocumented
+
+fmodule-implicit-inline
+C++ ObjC++ Var(flag_module_implicit_inline,0) Integer
+Member functions defined within their class are inline in module purview.
+
+fmodule-only
+C++ ObjC RejectNegative Var(flag_module_only) Integer
+Only emit Compiled Module Interface.
+
+fmodule-mapper=
+C++ ObjC++ Joined RejectNegative MissingArgError(missing mapper)
+Mapper for module to CMI files.
+
+fmodule-lazy
+C++ ObjC++ Var(flag_module_lazy) Init(1)
+Enable lazy module importing.
+
+fmodule-version-ignore
+C++ ObjC Var(flag_module_version_ignore) Integer
+; undocumented, Very dangerous, but occasionally useful
+
+Winvalid-imported-macros
+C++ ObjC++ Var(warn_imported_macros)
+Warn about macros that have conflicting header units definitions.
+
+flang-info-include-translate
+C++ Var(note_include_translate_yes)
+Note #include directives translated to import declarations.
+
+flang-info-include-translate-not
+C++ Var(note_include_translate_no)
+Note #include directives not translated to import declarations, and not known to be textual.
+
+flang-info-include-translate=
+C++ Joined RejectNegative MissingArgError(missing header name)
+Note a #include translation of a specific header.
+
fmax-include-depth=
C ObjC C++ ObjC++ Joined RejectNegative UInteger
fmax-include-depth=<number> Set the maximum depth of the nested #include.
@@ -1791,6 +1855,19 @@ fopenacc-dim=
C ObjC C++ ObjC++ LTO Joined Var(flag_openacc_dims)
Specify default OpenACC compute dimensions.
+fopenacc-kernels=
+C ObjC C++ ObjC++ RejectNegative Joined Enum(openacc_kernels) Var(flag_openacc_kernels) Init(OPENACC_KERNELS_PARLOOPS)
+-fopenacc-kernels=[decompose|parloops] Specify mode of OpenACC 'kernels' constructs handling.
+
+Enum
+Name(openacc_kernels) Type(enum openacc_kernels)
+
+EnumValue
+Enum(openacc_kernels) String(decompose) Value(OPENACC_KERNELS_DECOMPOSE)
+
+EnumValue
+Enum(openacc_kernels) String(parloops) Value(OPENACC_KERNELS_PARLOOPS)
+
fopenmp
C ObjC C++ ObjC++ LTO Var(flag_openmp)
Enable OpenMP (implies -frecursive in Fortran).
diff --git a/gcc/c-family/stub-objc.c b/gcc/c-family/stub-objc.c
index 2f53557..1914432 100644
--- a/gcc/c-family/stub-objc.c
+++ b/gcc/c-family/stub-objc.c
@@ -25,10 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "vec.h"
-/* Provide a dummy type for the RID enum used as an argument to
- objc_prop_attr_kind_for_rid () */
-enum rid { DUMMY };
-
+#include "c-common.h" /* for enum rid. */
#include "c-objc.h"
tree
@@ -137,6 +134,7 @@ objc_set_method_opt (bool ARG_UNUSED (optional))
void
objc_start_class_interface (tree ARG_UNUSED (name),
+ location_t /*name_loc*/,
tree ARG_UNUSED (super),
tree ARG_UNUSED (protos),
tree ARG_UNUSED (attribs))
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 5b0d42c..b97fb74 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,92 @@
+2020-11-26 Martin Uecker <muecker@gwdg.de>
+
+ PR c/65455
+ PR c/92935
+ * c-parser.c (c_parser_declaration_or_fndef): Remove
+ redundant code to drop qualifiers of _Atomic types for __auto_type.
+ (c_parser_typeof_specifier): Do not drop qualifiers of _Atomic
+ types for __typeof__.
+
+2020-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/97958
+ * c-parser.c (c_parser_binary_expression): For omp atomic binary
+ expressions, use make_node instead of build2 to avoid checking build2
+ performs.
+
+2020-11-23 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/95630
+ * c-typeck.c (build_binary_op): Use pedwarn_c99 with OPT_Wpedantic
+ for comparisons of complete and incomplete pointers.
+
+2020-11-21 Aaron Sawdey <acsawdey@linux.ibm.com>
+
+ * c-aux-info.c (gen_type): Support opaque types.
+
+2020-11-20 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/97879
+ * c-decl.c (start_function): Set ATTR_FLAG_INTERNAL in flags.
+
+2020-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/97911
+ * Make-lang.in (c.serial): Change from goal to a variable.
+ (.PHONY): Drop c.serial.
+
+2020-11-20 Martin Uecker <muecker@gwdg.de>
+
+ * c-typeck.c (convert_lvalue_to_rvalue): Drop qualifiers.
+
+2020-11-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/97860
+ * c-decl.c (get_parm_array_spec): Bail out of nelts is
+ error_operand_p.
+
+2020-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ * Make-lang.in (c.serial): New goal.
+ (.PHONY): Add c.serial c.prev.
+ (cc1$(exeext)): Call LINK_PROGRESS.
+
+2020-11-13 Vladimir N. Makarov <vmakarov@redhat.com>
+
+ * c-parser.c (c_parser_asm_statement): Parse outputs for asm
+ goto too.
+ * c-typeck.c (build_asm_expr): Remove an assert checking output
+ absence for asm goto.
+
+2020-11-13 Jakub Jelinek <jakub@redhat.com>
+
+ * c-typeck.c (c_finish_omp_clauses): Don't clear
+ OMP_CLAUSE_REDUCTION_INSCAN unless reduction_seen == -2.
+
+2020-11-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR objc/77404
+ * c-parser.c (c_parser_objc_class_definition): Pass the
+ location of the class name to the interface declaration.
+
+2020-11-10 Strager Neds <strager.nds@gmail.com>
+
+ * c-decl.c (merge_decls): Use new overload of
+ set_decl_section_name.
+
+2020-11-10 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * c-parser.c (c_parser_omp_target_data): Add use of
+ new c_omp_adjust_map_clauses function. Add GOMP_MAP_ATTACH_DETACH as
+ handled map clause kind.
+ (c_parser_omp_target_enter_data): Likewise.
+ (c_parser_omp_target_exit_data): Likewise.
+ (c_parser_omp_target): Likewise.
+ * c-typeck.c (handle_omp_array_sections): Adjust COMPONENT_REF case to
+ use GOMP_MAP_ATTACH_DETACH map kind for C_ORT_OMP region type.
+ (c_finish_omp_clauses): Adjust bitmap checks to allow struct decl and
+ same struct field access to co-exist on OpenMP construct.
+
2020-11-07 Martin Uecker <muecker@gwdg.de>
* c-parser.c (c_parser_label): Implement mixing of labels and code.
diff --git a/gcc/c/Make-lang.in b/gcc/c/Make-lang.in
index 7efc7c2..4b2e616 100644
--- a/gcc/c/Make-lang.in
+++ b/gcc/c/Make-lang.in
@@ -37,6 +37,7 @@
#
# Define the names for selecting c in LANGUAGES.
c: cc1$(exeext)
+c.serial = cc1$(exeext)
# Tell GNU make to ignore these if they exist.
.PHONY: c gcc
@@ -82,8 +83,10 @@ cc1-checksum.c : build/genchecksum$(build_exeext) checksum-options \
fi
cc1$(exeext): $(C_OBJS) cc1-checksum.o $(BACKEND) $(LIBDEPS)
+ @$(call LINK_PROGRESS,$(INDEX.c),start)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) \
cc1-checksum.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
+ @$(call LINK_PROGRESS,$(INDEX.c),end)
cc1.fda: ../stage1-gcc/cc1$(exeext) ../prev-gcc/$(PERF_DATA)
$(CREATE_GCOV) -binary ../stage1-gcc/cc1$(exeext) -gcov cc1.fda -profile ../prev-gcc/$(PERF_DATA) -gcov_version 1
diff --git a/gcc/c/c-aux-info.c b/gcc/c/c-aux-info.c
index ffc8099..bdeef52 100644
--- a/gcc/c/c-aux-info.c
+++ b/gcc/c/c-aux-info.c
@@ -409,6 +409,7 @@ gen_type (const char *ret_val, tree t, formals_style style)
data_type = concat ("unsigned ", data_type, NULL);
break;
+ case OPAQUE_TYPE:
case REAL_TYPE:
data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
break;
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index f19c82c..27f7722 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -2884,7 +2884,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
|| TREE_PUBLIC (olddecl)
|| TREE_STATIC (olddecl))
&& DECL_SECTION_NAME (newdecl) != NULL)
- set_decl_section_name (olddecl, DECL_SECTION_NAME (newdecl));
+ set_decl_section_name (olddecl, newdecl);
/* This isn't quite correct for something like
int __thread x attribute ((tls_model ("local-exec")));
@@ -5775,6 +5775,8 @@ get_parm_array_spec (const struct c_parm *parm, tree attrs)
type = TREE_TYPE (type))
{
tree nelts = array_type_nelts (type);
+ if (error_operand_p (nelts))
+ return attrs;
if (TREE_CODE (nelts) != INTEGER_CST)
{
/* Each variable VLA bound is represented by the dollar
@@ -9596,7 +9598,8 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
current_function_decl = pushdecl (decl1);
if (tree access = build_attr_access_from_parms (parms, false))
- decl_attributes (&current_function_decl, access, 0, old_decl);
+ decl_attributes (&current_function_decl, access, ATTR_FLAG_INTERNAL,
+ old_decl);
push_scope ();
declare_parm_level ();
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 377914c..87ee8f4 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -2224,10 +2224,6 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
" initializer");
init = convert_lvalue_to_rvalue (init_loc, init, true, true);
tree init_type = TREE_TYPE (init.value);
- /* As with typeof, remove all qualifiers from atomic types. */
- if (init_type != error_mark_node && TYPE_ATOMIC (init_type))
- init_type
- = c_build_qualified_type (init_type, TYPE_UNQUALIFIED);
bool vm_type = variably_modified_type_p (init_type,
NULL_TREE);
if (vm_type)
@@ -3743,11 +3739,6 @@ c_parser_typeof_specifier (c_parser *parser)
if (was_vm)
ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
pop_maybe_used (was_vm);
- /* For use in macros such as those in <stdatomic.h>, remove all
- qualifiers from atomic types. (const can be an issue for more macros
- using typeof than just the <stdatomic.h> ones.) */
- if (ret.spec != error_mark_node && TYPE_ATOMIC (ret.spec))
- ret.spec = c_build_qualified_type (ret.spec, TYPE_UNQUALIFIED);
}
parens.skip_until_found_close (parser);
return ret;
@@ -7144,10 +7135,7 @@ c_parser_asm_statement (c_parser *parser)
switch (section)
{
case 0:
- /* For asm goto, we don't allow output operands, but reserve
- the slot for a future extension that does allow them. */
- if (!is_goto)
- outputs = c_parser_asm_operands (parser);
+ outputs = c_parser_asm_operands (parser);
break;
case 1:
inputs = c_parser_asm_operands (parser);
@@ -7868,9 +7856,13 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after,
&& stack[1].expr.value != error_mark_node \
&& (c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
|| c_tree_equal (stack[1].expr.value, omp_atomic_lhs))) \
- stack[0].expr.value \
- = build2 (stack[1].op, TREE_TYPE (stack[0].expr.value), \
- stack[0].expr.value, stack[1].expr.value); \
+ { \
+ tree t = make_node (stack[1].op); \
+ TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
+ TREE_OPERAND (t, 0) = stack[0].expr.value; \
+ TREE_OPERAND (t, 1) = stack[1].expr.value; \
+ stack[0].expr.value = t; \
+ } \
else \
stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
stack[sp].op, \
@@ -10801,6 +10793,7 @@ c_parser_objc_class_definition (c_parser *parser, tree attributes)
return;
}
id1 = c_parser_peek_token (parser)->value;
+ location_t loc1 = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
{
@@ -10860,7 +10853,7 @@ c_parser_objc_class_definition (c_parser *parser, tree attributes)
tree proto = NULL_TREE;
if (c_parser_next_token_is (parser, CPP_LESS))
proto = c_parser_objc_protocol_refs (parser);
- objc_start_class_interface (id1, superclass, proto, attributes);
+ objc_start_class_interface (id1, loc1, superclass, proto, attributes);
}
else
objc_start_class_implementation (id1, superclass);
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index df1dad4..cdc491a 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -2080,6 +2080,9 @@ convert_lvalue_to_rvalue (location_t loc, struct c_expr exp,
exp = default_function_array_conversion (loc, exp);
if (!VOID_TYPE_P (TREE_TYPE (exp.value)))
exp.value = require_complete_type (loc, exp.value);
+ if (convert_p && !error_operand_p (exp.value)
+ && (TREE_CODE (TREE_TYPE (exp.value)) != ARRAY_TYPE))
+ exp.value = convert (build_qualified_type (TREE_TYPE (exp.value), TYPE_UNQUALIFIED), exp.value);
if (really_atomic_lvalue (exp.value))
{
vec<tree, va_gc> *params;
@@ -10666,10 +10669,6 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
TREE_VALUE (tail) = input;
}
- /* ASMs with labels cannot have outputs. This should have been
- enforced by the parser. */
- gcc_assert (outputs == NULL || labels == NULL);
-
args = build_stmt (loc, ASM_EXPR, string, outputs, inputs, clobbers, labels);
/* asm statements without outputs, including simple ones, are treated
@@ -12267,8 +12266,8 @@ build_binary_op (location_t location, enum tree_code code,
result_type = common_pointer_type (type0, type1);
if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
!= !COMPLETE_TYPE_P (TREE_TYPE (type1)))
- pedwarn (location, 0,
- "comparison of complete and incomplete pointers");
+ pedwarn_c99 (location, OPT_Wpedantic,
+ "comparison of complete and incomplete pointers");
else if (TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
pedwarn (location, OPT_Wpedantic, "ISO C forbids "
"ordered comparisons of pointers to functions");
@@ -15199,7 +15198,8 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
OMP_CLAUSE_LINEAR_STEP (c));
remove = true;
}
- else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
+ else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
+ && reduction_seen == -2)
OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
if (remove)
diff --git a/gcc/cfg.c b/gcc/cfg.c
index de0e71d..529b6ed 100644
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -25,7 +25,7 @@ along with GCC; see the file COPYING3. If not see
Available functionality:
- Initialization/deallocation
- init_flow, clear_edges
+ init_flow, free_cfg
- Low level basic block manipulation
alloc_block, expunge_block
- Edge manipulation
@@ -83,7 +83,7 @@ init_flow (struct function *the_fun)
the_fun->cfg->bb_flags_allocated = BB_ALL_FLAGS;
}
-/* Helper function for remove_edge and clear_edges. Frees edge structure
+/* Helper function for remove_edge and free_cffg. Frees edge structure
without actually removing it from the pred/succ arrays. */
static void
@@ -93,29 +93,44 @@ free_edge (function *fn, edge e)
ggc_free (e);
}
-/* Free the memory associated with the edge structures. */
+/* Free basic block BB. */
+
+static void
+free_block (basic_block bb)
+{
+ vec_free (bb->succs);
+ bb->succs = NULL;
+ vec_free (bb->preds);
+ bb->preds = NULL;
+ /* Do not free BB itself yet since we leak pointers to dead statements
+ that points to dead basic blocks. */
+}
+
+/* Free the memory associated with the CFG in FN. */
void
-clear_edges (struct function *fn)
+free_cfg (struct function *fn)
{
- basic_block bb;
edge e;
edge_iterator ei;
+ basic_block next;
- FOR_EACH_BB_FN (bb, fn)
+ for (basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (fn); bb; bb = next)
{
+ next = bb->next_bb;
FOR_EACH_EDGE (e, ei, bb->succs)
free_edge (fn, e);
- vec_safe_truncate (bb->succs, 0);
- vec_safe_truncate (bb->preds, 0);
+ free_block (bb);
}
- FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (fn)->succs)
- free_edge (fn, e);
- vec_safe_truncate (EXIT_BLOCK_PTR_FOR_FN (fn)->preds, 0);
- vec_safe_truncate (ENTRY_BLOCK_PTR_FOR_FN (fn)->succs, 0);
-
gcc_assert (!n_edges_for_fn (fn));
+ /* Sanity check that dominance tree is freed. */
+ gcc_assert (!fn->cfg->x_dom_computed[0] && !fn->cfg->x_dom_computed[1]);
+
+ vec_free (fn->cfg->x_label_to_block_map);
+ vec_free (basic_block_info_for_fn (fn));
+ ggc_free (fn->cfg);
+ fn->cfg = NULL;
}
/* Allocate memory for basic_block. */
@@ -190,8 +205,8 @@ expunge_block (basic_block b)
/* We should be able to ggc_free here, but we are not.
The dead SSA_NAMES are left pointing to dead statements that are pointing
to dead basic blocks making garbage collector to die.
- We should be able to release all dead SSA_NAMES and at the same time we should
- clear out BB pointer of dead statements consistently. */
+ We should be able to release all dead SSA_NAMES and at the same time we
+ should clear out BB pointer of dead statements consistently. */
}
/* Connect E to E->src. */
diff --git a/gcc/cfg.h b/gcc/cfg.h
index 93fde6df..a9c8300 100644
--- a/gcc/cfg.h
+++ b/gcc/cfg.h
@@ -82,7 +82,7 @@ struct GTY(()) control_flow_graph {
extern void init_flow (function *);
-extern void clear_edges (function *);
+extern void free_cfg (function *);
extern basic_block alloc_block (void);
extern void link_block (basic_block, basic_block);
extern void unlink_block (basic_block);
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index b2d8685..7e0bdd5 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -103,7 +103,7 @@ tree
gimple_assign_rhs_to_tree (gimple *stmt)
{
tree t;
- switch (get_gimple_rhs_class (gimple_expr_code (stmt)))
+ switch (gimple_assign_rhs_class (stmt))
{
case GIMPLE_TERNARY_RHS:
t = build3 (gimple_assign_rhs_code (stmt),
@@ -376,15 +376,18 @@ align_local_variable (tree decl, bool really_expand)
align = GET_MODE_ALIGNMENT (mode);
}
else
- {
- align = LOCAL_DECL_ALIGNMENT (decl);
- /* Don't change DECL_ALIGN when called from estimated_stack_frame_size.
- That is done before IPA and could bump alignment based on host
- backend even for offloaded code which wants different
- LOCAL_DECL_ALIGNMENT. */
- if (really_expand)
- SET_DECL_ALIGN (decl, align);
- }
+ align = LOCAL_DECL_ALIGNMENT (decl);
+
+ if (hwasan_sanitize_stack_p ())
+ align = MAX (align, (unsigned) HWASAN_TAG_GRANULE_SIZE * BITS_PER_UNIT);
+
+ if (TREE_CODE (decl) != SSA_NAME && really_expand)
+ /* Don't change DECL_ALIGN when called from estimated_stack_frame_size.
+ That is done before IPA and could bump alignment based on host
+ backend even for offloaded code which wants different
+ LOCAL_DECL_ALIGNMENT. */
+ SET_DECL_ALIGN (decl, align);
+
return align / BITS_PER_UNIT;
}
@@ -428,6 +431,14 @@ alloc_stack_frame_space (poly_int64 size, unsigned HOST_WIDE_INT align)
return offset;
}
+/* Ensure that the stack is aligned to ALIGN bytes.
+ Return the new frame offset. */
+static poly_int64
+align_frame_offset (unsigned HOST_WIDE_INT align)
+{
+ return alloc_stack_frame_space (0, align);
+}
+
/* Accumulate DECL into STACK_VARS. */
static void
@@ -1004,7 +1015,12 @@ expand_one_stack_var_at (tree decl, rtx base, unsigned base_align,
/* If this fails, we've overflowed the stack frame. Error nicely? */
gcc_assert (known_eq (offset, trunc_int_for_mode (offset, Pmode)));
- x = plus_constant (Pmode, base, offset);
+ if (hwasan_sanitize_stack_p ())
+ x = targetm.memtag.add_tag (base, offset,
+ hwasan_current_frame_tag ());
+ else
+ x = plus_constant (Pmode, base, offset);
+
x = gen_rtx_MEM (TREE_CODE (decl) == SSA_NAME
? TYPE_MODE (TREE_TYPE (decl))
: DECL_MODE (decl), x);
@@ -1013,7 +1029,7 @@ expand_one_stack_var_at (tree decl, rtx base, unsigned base_align,
If it is we generate stack slots only accidentally so it isn't as
important, we'll simply set the alignment directly on the MEM. */
- if (base == virtual_stack_vars_rtx)
+ if (stack_vars_base_reg_p (base))
offset -= frame_phase;
align = known_alignment (offset);
align *= BITS_PER_UNIT;
@@ -1056,13 +1072,13 @@ public:
/* A subroutine of expand_used_vars. Give each partition representative
a unique location within the stack frame. Update each partition member
with that location. */
-
static void
expand_stack_vars (bool (*pred) (size_t), class stack_vars_data *data)
{
size_t si, i, j, n = stack_vars_num;
poly_uint64 large_size = 0, large_alloc = 0;
rtx large_base = NULL;
+ rtx large_untagged_base = NULL;
unsigned large_align = 0;
bool large_allocation_done = false;
tree decl;
@@ -1113,7 +1129,7 @@ expand_stack_vars (bool (*pred) (size_t), class stack_vars_data *data)
{
rtx base;
unsigned base_align, alignb;
- poly_int64 offset;
+ poly_int64 offset = 0;
i = stack_vars_sorted[si];
@@ -1134,10 +1150,33 @@ expand_stack_vars (bool (*pred) (size_t), class stack_vars_data *data)
if (pred && !pred (i))
continue;
+ base = (hwasan_sanitize_stack_p ()
+ ? hwasan_frame_base ()
+ : virtual_stack_vars_rtx);
alignb = stack_vars[i].alignb;
if (alignb * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT)
{
- base = virtual_stack_vars_rtx;
+ poly_int64 hwasan_orig_offset;
+ if (hwasan_sanitize_stack_p ())
+ {
+ /* There must be no tag granule "shared" between different
+ objects. This means that no HWASAN_TAG_GRANULE_SIZE byte
+ chunk can have more than one object in it.
+
+ We ensure this by forcing the end of the last bit of data to
+ be aligned to HWASAN_TAG_GRANULE_SIZE bytes here, and setting
+ the start of each variable to be aligned to
+ HWASAN_TAG_GRANULE_SIZE bytes in `align_local_variable`.
+
+ We can't align just one of the start or end, since there are
+ untagged things stored on the stack which we do not align to
+ HWASAN_TAG_GRANULE_SIZE bytes. If we only aligned the start
+ or the end of tagged objects then untagged objects could end
+ up sharing the first granule of a tagged object or sharing the
+ last granule of a tagged object respectively. */
+ hwasan_orig_offset = align_frame_offset (HWASAN_TAG_GRANULE_SIZE);
+ gcc_assert (stack_vars[i].alignb >= HWASAN_TAG_GRANULE_SIZE);
+ }
/* ASAN description strings don't yet have a syntax for expressing
polynomial offsets. */
HOST_WIDE_INT prev_offset;
@@ -1148,7 +1187,7 @@ expand_stack_vars (bool (*pred) (size_t), class stack_vars_data *data)
{
if (data->asan_vec.is_empty ())
{
- alloc_stack_frame_space (0, ASAN_RED_ZONE_SIZE);
+ align_frame_offset (ASAN_RED_ZONE_SIZE);
prev_offset = frame_offset.to_constant ();
}
prev_offset = align_base (prev_offset,
@@ -1216,6 +1255,24 @@ expand_stack_vars (bool (*pred) (size_t), class stack_vars_data *data)
{
offset = alloc_stack_frame_space (stack_vars[i].size, alignb);
base_align = crtl->max_used_stack_slot_alignment;
+
+ if (hwasan_sanitize_stack_p ())
+ {
+ /* Align again since the point of this alignment is to handle
+ the "end" of the object (i.e. smallest address after the
+ stack object). For FRAME_GROWS_DOWNWARD that requires
+ aligning the stack before allocating, but for a frame that
+ grows upwards that requires aligning the stack after
+ allocation.
+
+ Use `frame_offset` to record the offset value rather than
+ `offset` since the `frame_offset` describes the extent
+ allocated for this particular variable while `offset`
+ describes the address that this variable starts at. */
+ align_frame_offset (HWASAN_TAG_GRANULE_SIZE);
+ hwasan_record_stack_var (virtual_stack_vars_rtx, base,
+ hwasan_orig_offset, frame_offset);
+ }
}
}
else
@@ -1236,14 +1293,33 @@ expand_stack_vars (bool (*pred) (size_t), class stack_vars_data *data)
loffset = alloc_stack_frame_space
(rtx_to_poly_int64 (large_allocsize),
PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT);
- large_base = get_dynamic_stack_base (loffset, large_align);
+ large_base = get_dynamic_stack_base (loffset, large_align, base);
large_allocation_done = true;
}
- gcc_assert (large_base != NULL);
+ gcc_assert (large_base != NULL);
large_alloc = aligned_upper_bound (large_alloc, alignb);
offset = large_alloc;
large_alloc += stack_vars[i].size;
+ if (hwasan_sanitize_stack_p ())
+ {
+ /* An object with a large alignment requirement means that the
+ alignment requirement is greater than the required alignment
+ for tags. */
+ if (!large_untagged_base)
+ large_untagged_base
+ = targetm.memtag.untagged_pointer (large_base, NULL_RTX);
+ /* Ensure the end of the variable is also aligned correctly. */
+ poly_int64 align_again
+ = aligned_upper_bound (large_alloc, HWASAN_TAG_GRANULE_SIZE);
+ /* For large allocations we always allocate a chunk of space
+ (which is addressed by large_untagged_base/large_base) and
+ then use positive offsets from that. Hence the farthest
+ offset is `align_again` and the nearest offset from the base
+ is `offset`. */
+ hwasan_record_stack_var (large_untagged_base, large_base,
+ offset, align_again);
+ }
base = large_base;
base_align = large_align;
@@ -1254,9 +1330,10 @@ expand_stack_vars (bool (*pred) (size_t), class stack_vars_data *data)
for (j = i; j != EOC; j = stack_vars[j].next)
{
expand_one_stack_var_at (stack_vars[j].decl,
- base, base_align,
- offset);
+ base, base_align, offset);
}
+ if (hwasan_sanitize_stack_p ())
+ hwasan_increment_frame_tag ();
}
gcc_assert (known_eq (large_alloc, large_size));
@@ -1347,10 +1424,37 @@ expand_one_stack_var_1 (tree var)
/* We handle highly aligned variables in expand_stack_vars. */
gcc_assert (byte_align * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT);
- offset = alloc_stack_frame_space (size, byte_align);
+ rtx base;
+ if (hwasan_sanitize_stack_p ())
+ {
+ /* Allocate zero bytes to align the stack. */
+ poly_int64 hwasan_orig_offset
+ = align_frame_offset (HWASAN_TAG_GRANULE_SIZE);
+ offset = alloc_stack_frame_space (size, byte_align);
+ align_frame_offset (HWASAN_TAG_GRANULE_SIZE);
+ base = hwasan_frame_base ();
+ /* Use `frame_offset` to automatically account for machines where the
+ frame grows upwards.
+
+ `offset` will always point to the "start" of the stack object, which
+ will be the smallest address, for ! FRAME_GROWS_DOWNWARD this is *not*
+ the "furthest" offset from the base delimiting the current stack
+ object. `frame_offset` will always delimit the extent that the frame.
+ */
+ hwasan_record_stack_var (virtual_stack_vars_rtx, base,
+ hwasan_orig_offset, frame_offset);
+ }
+ else
+ {
+ offset = alloc_stack_frame_space (size, byte_align);
+ base = virtual_stack_vars_rtx;
+ }
- expand_one_stack_var_at (var, virtual_stack_vars_rtx,
+ expand_one_stack_var_at (var, base,
crtl->max_used_stack_slot_alignment, offset);
+
+ if (hwasan_sanitize_stack_p ())
+ hwasan_increment_frame_tag ();
}
/* Wrapper for expand_one_stack_var_1 that checks SSA_NAMEs are
@@ -1950,6 +2054,8 @@ init_vars_expansion (void)
/* Initialize local stack smashing state. */
has_protected_decls = false;
has_short_buffer = false;
+ if (hwasan_sanitize_stack_p ())
+ hwasan_record_frame_init ();
}
/* Free up stack variable graph data. */
@@ -2277,10 +2383,26 @@ expand_used_vars (void)
expand_stack_vars (NULL, &data);
}
+ if (hwasan_sanitize_stack_p ())
+ hwasan_emit_prologue ();
if (asan_sanitize_allocas_p () && cfun->calls_alloca)
var_end_seq = asan_emit_allocas_unpoison (virtual_stack_dynamic_rtx,
virtual_stack_vars_rtx,
var_end_seq);
+ else if (hwasan_sanitize_allocas_p () && cfun->calls_alloca)
+ /* When using out-of-line instrumentation we only want to emit one function
+ call for clearing the tags in a region of shadow stack. When there are
+ alloca calls in this frame we want to emit a call using the
+ virtual_stack_dynamic_rtx, but when not we use the hwasan_frame_extent
+ rtx we created in expand_stack_vars. */
+ var_end_seq = hwasan_emit_untag_frame (virtual_stack_dynamic_rtx,
+ virtual_stack_vars_rtx);
+ else if (hwasan_sanitize_stack_p ())
+ /* If no variables were stored on the stack, `hwasan_get_frame_extent`
+ will return NULL_RTX and hence `hwasan_emit_untag_frame` will return
+ NULL (i.e. an empty sequence). */
+ var_end_seq = hwasan_emit_untag_frame (hwasan_get_frame_extent (),
+ virtual_stack_vars_rtx);
fini_vars_expansion ();
@@ -3371,20 +3493,21 @@ expand_asm_stmt (gasm *stmt)
ARGVEC CONSTRAINTS OPNAMES))
If there is more than one, put them inside a PARALLEL. */
- if (nlabels > 0 && nclobbers == 0)
- {
- gcc_assert (noutputs == 0);
- emit_jump_insn (body);
- }
- else if (noutputs == 0 && nclobbers == 0)
+ if (noutputs == 0 && nclobbers == 0)
{
/* No output operands: put in a raw ASM_OPERANDS rtx. */
- emit_insn (body);
+ if (nlabels > 0)
+ emit_jump_insn (body);
+ else
+ emit_insn (body);
}
else if (noutputs == 1 && nclobbers == 0)
{
ASM_OPERANDS_OUTPUT_CONSTRAINT (body) = constraints[0];
- emit_insn (gen_rtx_SET (output_rvec[0], body));
+ if (nlabels > 0)
+ emit_jump_insn (gen_rtx_SET (output_rvec[0], body));
+ else
+ emit_insn (gen_rtx_SET (output_rvec[0], body));
}
else
{
@@ -3461,7 +3584,27 @@ expand_asm_stmt (gasm *stmt)
if (after_md_seq)
emit_insn (after_md_seq);
if (after_rtl_seq)
- emit_insn (after_rtl_seq);
+ {
+ if (nlabels == 0)
+ emit_insn (after_rtl_seq);
+ else
+ {
+ edge e;
+ edge_iterator ei;
+
+ FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
+ {
+ start_sequence ();
+ for (rtx_insn *curr = after_rtl_seq;
+ curr != NULL_RTX;
+ curr = NEXT_INSN (curr))
+ emit_insn (copy_insn (PATTERN (curr)));
+ rtx_insn *copy = get_insns ();
+ end_sequence ();
+ insert_insn_on_edge (copy, e);
+ }
+ }
+ }
free_temp_slots ();
crtl->has_asm_statement = 1;
@@ -3741,11 +3884,10 @@ expand_gimple_stmt_1 (gimple *stmt)
of binary assigns must be a gimple reg. */
if (TREE_CODE (lhs) != SSA_NAME
- || get_gimple_rhs_class (gimple_expr_code (stmt))
- == GIMPLE_SINGLE_RHS)
+ || gimple_assign_rhs_class (assign_stmt) == GIMPLE_SINGLE_RHS)
{
tree rhs = gimple_assign_rhs1 (assign_stmt);
- gcc_assert (get_gimple_rhs_class (gimple_expr_code (stmt))
+ gcc_assert (gimple_assign_rhs_class (assign_stmt)
== GIMPLE_SINGLE_RHS);
if (gimple_has_location (stmt) && CAN_HAVE_LOCATION_P (rhs)
/* Do not put locations on possibly shared trees. */
@@ -6621,6 +6763,9 @@ pass_expand::execute (function *fun)
emit_insn_after (var_ret_seq, after);
}
+ if (hwasan_sanitize_stack_p ())
+ hwasan_maybe_emit_frame_base_init ();
+
/* Zap the tree EH table. */
set_eh_throw_stmt_table (fun, NULL);
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index d14689d..438b1f7 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -824,7 +824,7 @@ extern void init_set_costs (void);
/* Loop optimizer initialization. */
extern void loop_optimizer_init (unsigned);
-extern void loop_optimizer_finalize (function *);
+extern void loop_optimizer_finalize (function *, bool = false);
inline void
loop_optimizer_finalize ()
{
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 45d84d3..5e909e2 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -97,6 +97,7 @@ static basic_block rtl_split_block (basic_block, void *);
static void rtl_dump_bb (FILE *, basic_block, int, dump_flags_t);
static int rtl_verify_flow_info_1 (void);
static void rtl_make_forwarder_block (edge);
+static bool rtl_bb_info_initialized_p (basic_block bb);
/* Return true if NOTE is not one of the ones that must be kept paired,
so that we may simply delete it. */
@@ -2149,7 +2150,8 @@ rtl_dump_bb (FILE *outf, basic_block bb, int indent, dump_flags_t flags)
putc ('\n', outf);
}
- if (bb->index != ENTRY_BLOCK && bb->index != EXIT_BLOCK)
+ if (bb->index != ENTRY_BLOCK && bb->index != EXIT_BLOCK
+ && rtl_bb_info_initialized_p (bb))
{
rtx_insn *last = BB_END (bb);
if (last)
@@ -5135,6 +5137,12 @@ init_rtl_bb_info (basic_block bb)
bb->il.x.rtl = ggc_cleared_alloc<rtl_bb_info> ();
}
+static bool
+rtl_bb_info_initialized_p (basic_block bb)
+{
+ return bb->il.x.rtl;
+}
+
/* Returns true if it is possible to remove edge E by redirecting
it to the destination of the other edge from E->src. */
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 19dfe2b..cb59a5a 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1811,7 +1811,7 @@ release_function_body (tree decl)
gcc_assert (!dom_info_available_p (fn, CDI_DOMINATORS));
gcc_assert (!dom_info_available_p (fn, CDI_POST_DOMINATORS));
delete_tree_cfg_annotations (fn);
- clear_edges (fn);
+ free_cfg (fn);
fn->cfg = NULL;
}
if (fn->value_histograms)
@@ -2190,6 +2190,8 @@ cgraph_node::dump (FILE *f)
fprintf (f, " optimize_size");
if (parallelized_function)
fprintf (f, " parallelized_function");
+ if (DECL_IS_MALLOC (decl))
+ fprintf (f, " decl_is_malloc");
if (DECL_IS_OPERATOR_NEW_P (decl))
fprintf (f, " %soperator_new",
DECL_IS_REPLACEABLE_OPERATOR (decl) ? "replaceable_" : "");
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 73c37d8..97287bd 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -263,7 +263,7 @@ public:
}
/* Return section as string. */
- const char * get_section ()
+ const char * get_section () const
{
if (!x_section)
return NULL;
@@ -322,11 +322,18 @@ public:
/* Set section for symbol and its aliases. */
void set_section (const char *section);
+ /* Like set_section, but copying the section name from another node. */
+ void set_section (const symtab_node &other);
+
/* Set section, do not recurse into aliases.
When one wants to change section of symbol and its aliases,
use set_section. */
void set_section_for_node (const char *section);
+ /* Like set_section_for_node, but copying the section name from another
+ node. */
+ void set_section_for_node (const symtab_node &other);
+
/* Set initialization priority to PRIORITY. */
void set_init_priority (priority_type priority);
@@ -643,8 +650,9 @@ protected:
void *data,
bool include_overwrite);
private:
- /* Worker for set_section. */
- static bool set_section (symtab_node *n, void *s);
+ /* Workers for set_section. */
+ static bool set_section_from_string (symtab_node *n, void *s);
+ static bool set_section_from_node (symtab_node *n, void *o);
/* Worker for symtab_resolve_alias. */
static bool set_implicit_section (symtab_node *n, void *);
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index bc59081..2bf9baf 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -626,7 +626,7 @@ cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers,
if (tree_map)
clone_info::get_create (new_node)->tree_map = tree_map;
if (!implicit_section)
- new_node->set_section (get_section ());
+ new_node->set_section (*this);
/* Clones of global symbols or symbols with unique names are unique. */
if ((TREE_PUBLIC (old_decl)
@@ -1060,7 +1060,7 @@ cgraph_node::create_version_clone_with_body
new_version_node->local = 1;
new_version_node->lowered = true;
if (!implicit_section)
- new_version_node->set_section (get_section ());
+ new_version_node->set_section (*this);
/* Clones of global symbols or symbols with unique names are unique. */
if ((TREE_PUBLIC (old_decl)
&& !DECL_EXTERNAL (old_decl)
@@ -1107,7 +1107,7 @@ cgraph_node::materialize_clone ()
fprintf (symtab->dump_file, "cloning %s to %s\n",
clone_of->dump_name (),
dump_name ());
- if (info->tree_map)
+ if (info && info->tree_map)
{
fprintf (symtab->dump_file, " replace map:");
for (unsigned int i = 0;
@@ -1123,7 +1123,7 @@ cgraph_node::materialize_clone ()
}
fprintf (symtab->dump_file, "\n");
}
- if (info->param_adjustments)
+ if (info && info->param_adjustments)
info->param_adjustments->dump (symtab->dump_file);
}
clear_stmts_in_references ();
diff --git a/gcc/common.opt b/gcc/common.opt
index 7d0e0d9..582e2aa 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -218,7 +218,7 @@ unsigned int flag_sanitize
; What sanitizers should recover from errors
Variable
-unsigned int flag_sanitize_recover = (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT | SANITIZE_KERNEL_ADDRESS) & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN)
+unsigned int flag_sanitize_recover = (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT | SANITIZE_KERNEL_ADDRESS | SANITIZE_KERNEL_HWADDRESS) & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN)
; What the coverage sanitizers should instrument
Variable
@@ -960,9 +960,13 @@ Driver Undocumented
; 13: Fixes the accidental change in 12 to the calling convention for classes
; with deleted copy constructor and trivial move constructor.
; Default in G++ 8.2.
+;
; 14: Corrects the mangling of nullptr expression.
; Default in G++ 10.
;
+; 15: Changes the mangling of __alignof__ to be distinct from that of alignof.
+; Default in G++ 11.
+;
; Additional positive integers will be assigned as new versions of
; the ABI become the default version of the ABI.
fabi-version=
@@ -2268,6 +2272,14 @@ fprofile-generate=
Common Joined RejectNegative
Enable common options for generating profile info for profile feedback directed optimizations, and set -fprofile-dir=.
+fprofile-info-section
+Common RejectNegative
+Register the profile information in the .gcov_info section instead of using a constructor/destructor.
+
+fprofile-info-section=
+Common Joined RejectNegative Var(profile_info_section)
+Register the profile information in the specified section instead of using a constructor/destructor.
+
fprofile-partial-training
Common Report Var(flag_profile_partial_training) Optimization
Do not assume that functions never executed during the train run are cold.
@@ -3008,11 +3020,11 @@ Enable basic block vectorization (SLP) on trees.
fvect-cost-model=
Common Joined RejectNegative Enum(vect_cost_model) Var(flag_vect_cost_model) Init(VECT_COST_MODEL_DEFAULT) Optimization
--fvect-cost-model=[unlimited|dynamic|cheap] Specifies the cost model for vectorization.
+-fvect-cost-model=[unlimited|dynamic|cheap|very-cheap] Specifies the cost model for vectorization.
fsimd-cost-model=
Common Joined RejectNegative Enum(vect_cost_model) Var(flag_simd_cost_model) Init(VECT_COST_MODEL_UNLIMITED) Optimization
--fsimd-cost-model=[unlimited|dynamic|cheap] Specifies the vectorization cost model for code marked with a simd directive.
+-fsimd-cost-model=[unlimited|dynamic|cheap|very-cheap] Specifies the vectorization cost model for code marked with a simd directive.
Enum
Name(vect_cost_model) Type(enum vect_cost_model) UnknownError(unknown vectorizer cost model %qs)
@@ -3026,6 +3038,9 @@ Enum(vect_cost_model) String(dynamic) Value(VECT_COST_MODEL_DYNAMIC)
EnumValue
Enum(vect_cost_model) String(cheap) Value(VECT_COST_MODEL_CHEAP)
+EnumValue
+Enum(vect_cost_model) String(very-cheap) Value(VECT_COST_MODEL_VERY_CHEAP)
+
fvect-cost-model
Common Alias(fvect-cost-model=,dynamic,unlimited)
Enables the dynamic vectorizer cost model. Preserved for backward compatibility.
@@ -3433,6 +3448,9 @@ Driver
static-libasan
Driver
+static-libhwasan
+Driver
+
static-libtsan
Driver
diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h
index 7a93e17..41728a2 100644
--- a/gcc/common/config/i386/cpuinfo.h
+++ b/gcc/common/config/i386/cpuinfo.h
@@ -713,6 +713,8 @@ get_available_features (struct __processor_model *cpu_model,
set_feature (FEATURE_AVX512BF16);
if (eax & bit_HRESET)
set_feature (FEATURE_HRESET);
+ if (eax & bit_AVXVNNI)
+ set_feature (FEATURE_AVXVNNI);
}
}
diff --git a/gcc/common/config/i386/i386-common.c b/gcc/common/config/i386/i386-common.c
index e29320d..8f809c1 100644
--- a/gcc/common/config/i386/i386-common.c
+++ b/gcc/common/config/i386/i386-common.c
@@ -84,6 +84,7 @@ along with GCC; see the file COPYING3. If not see
(OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512F_SET)
#define OPTION_MASK_ISA_AVX512VNNI_SET \
(OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512F_SET)
+#define OPTION_MASK_ISA2_AVXVNNI_SET OPTION_MASK_ISA2_AVXVNNI
#define OPTION_MASK_ISA_AVX512VPOPCNTDQ_SET \
(OPTION_MASK_ISA_AVX512VPOPCNTDQ | OPTION_MASK_ISA_AVX512F_SET)
#define OPTION_MASK_ISA_AVX512BITALG_SET \
@@ -206,6 +207,8 @@ along with GCC; see the file COPYING3. If not see
#define OPTION_MASK_ISA_XSAVEOPT_UNSET OPTION_MASK_ISA_XSAVEOPT
#define OPTION_MASK_ISA_AVX2_UNSET \
(OPTION_MASK_ISA_AVX2 | OPTION_MASK_ISA_AVX512F_UNSET)
+#define OPTION_MASK_ISA2_AVX2_UNSET \
+ (OPTION_MASK_ISA2_AVXVNNI_UNSET | OPTION_MASK_ISA2_AVX512F_UNSET)
#define OPTION_MASK_ISA_AVX512F_UNSET \
(OPTION_MASK_ISA_AVX512F | OPTION_MASK_ISA_AVX512CD_UNSET \
| OPTION_MASK_ISA_AVX512PF_UNSET | OPTION_MASK_ISA_AVX512ER_UNSET \
@@ -228,6 +231,7 @@ along with GCC; see the file COPYING3. If not see
#define OPTION_MASK_ISA2_AVX5124VNNIW_UNSET OPTION_MASK_ISA2_AVX5124VNNIW
#define OPTION_MASK_ISA_AVX512VBMI2_UNSET OPTION_MASK_ISA_AVX512VBMI2
#define OPTION_MASK_ISA_AVX512VNNI_UNSET OPTION_MASK_ISA_AVX512VNNI
+#define OPTION_MASK_ISA2_AVXVNNI_UNSET OPTION_MASK_ISA2_AVXVNNI
#define OPTION_MASK_ISA_AVX512VPOPCNTDQ_UNSET OPTION_MASK_ISA_AVX512VPOPCNTDQ
#define OPTION_MASK_ISA_AVX512BITALG_UNSET OPTION_MASK_ISA_AVX512BITALG
#define OPTION_MASK_ISA2_AVX512BF16_UNSET OPTION_MASK_ISA2_AVX512BF16
@@ -310,7 +314,6 @@ along with GCC; see the file COPYING3. If not see
| OPTION_MASK_ISA2_AVX512VP2INTERSECT_UNSET)
#define OPTION_MASK_ISA2_GENERAL_REGS_ONLY_UNSET \
(OPTION_MASK_ISA2_AVX512F_UNSET)
-#define OPTION_MASK_ISA2_AVX2_UNSET OPTION_MASK_ISA2_AVX512F_UNSET
#define OPTION_MASK_ISA2_AVX_UNSET OPTION_MASK_ISA2_AVX2_UNSET
#define OPTION_MASK_ISA2_SSE4_2_UNSET OPTION_MASK_ISA2_AVX_UNSET
#define OPTION_MASK_ISA2_SSE4_1_UNSET OPTION_MASK_ISA2_SSE4_2_UNSET
@@ -882,6 +885,21 @@ ix86_handle_option (struct gcc_options *opts,
}
return true;
+ case OPT_mavxvnni:
+ if (value)
+ {
+ opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_AVXVNNI_SET;
+ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVXVNNI_SET;
+ opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX2_SET;
+ opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX2_SET;
+ }
+ else
+ {
+ opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_AVXVNNI_UNSET;
+ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_AVXVNNI_UNSET;
+ }
+ return true;
+
case OPT_msgx:
if (value)
{
diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h
index 2138220..af02be5 100644
--- a/gcc/common/config/i386/i386-cpuinfo.h
+++ b/gcc/common/config/i386/i386-cpuinfo.h
@@ -224,6 +224,7 @@ enum processor_features
FEATURE_KL,
FEATURE_AESKLE,
FEATURE_WIDEKL,
+ FEATURE_AVXVNNI,
CPU_FEATURE_MAX
};
diff --git a/gcc/common/config/i386/i386-isas.h b/gcc/common/config/i386/i386-isas.h
index 921db06..c4fd036 100644
--- a/gcc/common/config/i386/i386-isas.h
+++ b/gcc/common/config/i386/i386-isas.h
@@ -168,4 +168,5 @@ ISA_NAMES_TABLE_START
ISA_NAMES_TABLE_ENTRY("kl", FEATURE_KL, P_NONE, "-mkl")
ISA_NAMES_TABLE_ENTRY("aeskle", FEATURE_AESKLE, P_NONE, NULL)
ISA_NAMES_TABLE_ENTRY("widekl", FEATURE_WIDEKL, P_NONE, "-mwidekl")
+ ISA_NAMES_TABLE_ENTRY("avxvnni", FEATURE_AVXVNNI, P_NONE, "-mavxvnni")
ISA_NAMES_TABLE_END
diff --git a/gcc/common/config/riscv/riscv-common.c b/gcc/common/config/riscv/riscv-common.c
index 9a576eb..5e3ddcf 100644
--- a/gcc/common/config/riscv/riscv-common.c
+++ b/gcc/common/config/riscv/riscv-common.c
@@ -44,6 +44,7 @@ struct riscv_subset_t
struct riscv_subset_t *next;
bool explicit_version_p;
+ bool implied_p;
};
/* Type for implied ISA info. */
@@ -57,9 +58,63 @@ struct riscv_implied_info_t
static const riscv_implied_info_t riscv_implied_info[] =
{
{"d", "f"},
+ {"f", "zicsr"},
+ {"d", "zicsr"},
{NULL, NULL}
};
+/* This structure holds version information for specific ISA version. */
+
+struct riscv_ext_version
+{
+ const char *name;
+ enum riscv_isa_spec_class isa_spec_class;
+ int major_version;
+ int minor_version;
+};
+
+/* All standard extensions defined in all supported ISA spec. */
+static const struct riscv_ext_version riscv_ext_version_table[] =
+{
+ /* name, ISA spec, major version, minor_version. */
+ {"e", ISA_SPEC_CLASS_20191213, 1, 9},
+ {"e", ISA_SPEC_CLASS_20190608, 1, 9},
+ {"e", ISA_SPEC_CLASS_2P2, 1, 9},
+
+ {"i", ISA_SPEC_CLASS_20191213, 2, 1},
+ {"i", ISA_SPEC_CLASS_20190608, 2, 1},
+ {"i", ISA_SPEC_CLASS_2P2, 2, 0},
+
+ {"m", ISA_SPEC_CLASS_20191213, 2, 0},
+ {"m", ISA_SPEC_CLASS_20190608, 2, 0},
+ {"m", ISA_SPEC_CLASS_2P2, 2, 0},
+
+ {"a", ISA_SPEC_CLASS_20191213, 2, 1},
+ {"a", ISA_SPEC_CLASS_20190608, 2, 0},
+ {"a", ISA_SPEC_CLASS_2P2, 2, 0},
+
+ {"f", ISA_SPEC_CLASS_20191213, 2, 2},
+ {"f", ISA_SPEC_CLASS_20190608, 2, 2},
+ {"f", ISA_SPEC_CLASS_2P2, 2, 0},
+
+ {"d", ISA_SPEC_CLASS_20191213, 2, 2},
+ {"d", ISA_SPEC_CLASS_20190608, 2, 2},
+ {"d", ISA_SPEC_CLASS_2P2, 2, 0},
+
+ {"c", ISA_SPEC_CLASS_20191213, 2, 0},
+ {"c", ISA_SPEC_CLASS_20190608, 2, 0},
+ {"c", ISA_SPEC_CLASS_2P2, 2, 0},
+
+ {"zicsr", ISA_SPEC_CLASS_20191213, 2, 0},
+ {"zicsr", ISA_SPEC_CLASS_20190608, 2, 0},
+
+ {"zifencei", ISA_SPEC_CLASS_20191213, 2, 0},
+ {"zifencei", ISA_SPEC_CLASS_20190608, 2, 0},
+
+ /* Terminate the list. */
+ {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
+};
+
static const riscv_cpu_info riscv_cpu_tables[] =
{
#define RISCV_CORE(CORE_NAME, ARCH, TUNE) \
@@ -89,20 +144,22 @@ private:
riscv_subset_list (const char *, location_t);
- const char *parsing_subset_version (const char *, unsigned *, unsigned *,
- unsigned, unsigned, bool, bool *);
+ const char *parsing_subset_version (const char *, const char *, unsigned *,
+ unsigned *, bool, bool *);
const char *parse_std_ext (const char *);
const char *parse_multiletter_ext (const char *, const char *,
const char *);
- void handle_implied_ext (const char *, int, int, bool);
+ void handle_implied_ext (riscv_subset_t *);
public:
~riscv_subset_list ();
- void add (const char *, int, int, bool);
+ void add (const char *, int, int, bool, bool);
+
+ void add (const char *, bool);
riscv_subset_t *lookup (const char *,
int major_version = RISCV_DONT_CARE_VERSION,
@@ -122,7 +179,7 @@ static riscv_subset_list *current_subset_list = NULL;
riscv_subset_t::riscv_subset_t ()
: name (), major_version (0), minor_version (0), next (NULL),
- explicit_version_p (false)
+ explicit_version_p (false), implied_p (false)
{
}
@@ -145,13 +202,160 @@ riscv_subset_list::~riscv_subset_list ()
}
}
+/* Get the rank for single-letter subsets, lower value meaning higher
+ priority. */
+
+static int
+single_letter_subset_rank (char ext)
+{
+ int rank;
+
+ switch (ext)
+ {
+ case 'i':
+ return 0;
+ case 'e':
+ return 1;
+ default:
+ break;
+ }
+
+ const char *all_ext = riscv_supported_std_ext ();
+ const char *ext_pos = strchr (all_ext, ext);
+ if (ext_pos == NULL)
+ /* If got an unknown extension letter, then give it an alphabetical
+ order, but after all known standard extension. */
+ rank = strlen (all_ext) + ext - 'a';
+ else
+ rank = (int)(ext_pos - all_ext) + 2 /* e and i has higher rank. */;
+
+ return rank;
+}
+
+/* Get the rank for multi-letter subsets, lower value meaning higher
+ priority. */
+
+static int
+multi_letter_subset_rank (const std::string &subset)
+{
+ gcc_assert (subset.length () >= 2);
+ int high_order = -1;
+ int low_order = 0;
+ /* The order between multi-char extensions: s -> h -> z -> x. */
+ char multiletter_class = subset[0];
+ switch (multiletter_class)
+ {
+ case 's':
+ high_order = 0;
+ break;
+ case 'h':
+ high_order = 1;
+ break;
+ case 'z':
+ gcc_assert (subset.length () > 2);
+ high_order = 2;
+ break;
+ case 'x':
+ high_order = 3;
+ break;
+ default:
+ gcc_unreachable ();
+ return -1;
+ }
+
+ if (multiletter_class == 'z')
+ /* Order for z extension on spec: If multiple "Z" extensions are named, they
+ should be ordered first by category, then alphabetically within a
+ category - for example, "Zicsr_Zifencei_Zam". */
+ low_order = single_letter_subset_rank (subset[1]);
+ else
+ low_order = 0;
+
+ return (high_order << 8) + low_order;
+}
+
+/* subset compare
+
+ Returns an integral value indicating the relationship between the subsets:
+ Return value indicates
+ -1 B has higher order than A.
+ 0 A and B are same subset.
+ 1 A has higher order than B.
+
+*/
+
+static int
+subset_cmp (const std::string &a, const std::string &b)
+{
+ if (a == b)
+ return 0;
+
+ size_t a_len = a.length ();
+ size_t b_len = b.length ();
+
+ /* Single-letter extension always get higher order than
+ multi-letter extension. */
+ if (a_len == 1 && b_len != 1)
+ return 1;
+
+ if (a_len != 1 && b_len == 1)
+ return -1;
+
+ if (a_len == 1 && b_len == 1)
+ {
+ int rank_a = single_letter_subset_rank (a[0]);
+ int rank_b = single_letter_subset_rank (b[0]);
+
+ if (rank_a < rank_b)
+ return 1;
+ else
+ return -1;
+ }
+ else
+ {
+ int rank_a = multi_letter_subset_rank(a);
+ int rank_b = multi_letter_subset_rank(b);
+
+ /* Using alphabetical/lexicographical order if they have same rank. */
+ if (rank_a == rank_b)
+ /* The return value of strcmp has opposite meaning. */
+ return -strcmp (a.c_str (), b.c_str ());
+ else
+ return (rank_a < rank_b) ? 1 : -1;
+ }
+}
+
/* Add new subset to list. */
void
riscv_subset_list::add (const char *subset, int major_version,
- int minor_version, bool explicit_version_p)
+ int minor_version, bool explicit_version_p,
+ bool implied_p)
{
+ riscv_subset_t *ext = lookup (subset);
+
+ if (ext)
+ {
+ if (ext->implied_p)
+ {
+ /* We won't add impiled `ext` if it already in list. */
+ gcc_assert (!implied_p);
+ ext->implied_p = implied_p;
+ ext->major_version = major_version;
+ ext->minor_version = minor_version;
+ }
+ else
+ error_at (
+ m_loc,
+ "%<-march=%s%>: Extension `%s' appear more than one time.",
+ m_arch,
+ subset);
+
+ return;
+ }
+
riscv_subset_t *s = new riscv_subset_t ();
+ riscv_subset_t *itr;
if (m_head == NULL)
m_head = s;
@@ -160,14 +364,88 @@ riscv_subset_list::add (const char *subset, int major_version,
s->major_version = major_version;
s->minor_version = minor_version;
s->explicit_version_p = explicit_version_p;
+ s->implied_p = implied_p;
s->next = NULL;
- if (m_tail != NULL)
- m_tail->next = s;
+ if (m_tail == NULL)
+ {
+ m_tail = s;
+ return;
+ }
+
+ /* e, i or g should be first subext, never come here. */
+ gcc_assert (subset[0] != 'e'
+ && subset[0] != 'i'
+ && subset[0] != 'g');
+
+ if (m_tail == m_head)
+ {
+ gcc_assert (m_head->next == NULL);
+ m_head->next = s;
+ m_tail = s;
+ return;
+ }
+
+ gcc_assert (m_head->next != NULL);
+
+ /* Subset list must in canonical order, but implied subset won't
+ add in canonical order. */
+ for (itr = m_head; itr->next != NULL; itr = itr->next)
+ {
+ riscv_subset_t *next = itr->next;
+ int cmp = subset_cmp (s->name, next->name);
+ gcc_assert (cmp != 0);
+
+ if (cmp > 0)
+ {
+ s->next = next;
+ itr->next = s;
+ return;
+ }
+ }
+ /* Insert at tail of the list. */
+ itr->next = s;
m_tail = s;
}
+static void
+get_default_version (const char *ext,
+ unsigned int *major_version,
+ unsigned int *minor_version)
+{
+ const riscv_ext_version *ext_ver;
+ for (ext_ver = &riscv_ext_version_table[0];
+ ext_ver->name != NULL;
+ ++ext_ver)
+ if (strcmp (ext, ext_ver->name) == 0)
+ {
+ if ((ext_ver->isa_spec_class == riscv_isa_spec) ||
+ (ext_ver->isa_spec_class == ISA_SPEC_CLASS_NONE))
+ {
+ *major_version = ext_ver->major_version;
+ *minor_version = ext_ver->minor_version;
+ return;
+ }
+ }
+
+ /* Not found version info. */
+ *major_version = 0;
+ *minor_version = 0;
+}
+
+/* Add new subset to list, but using default version from ISA spec version. */
+
+void
+riscv_subset_list::add (const char *subset, bool implied_p)
+{
+ unsigned int major_version = 0, minor_version = 0;
+
+ get_default_version (subset, &major_version, &minor_version);
+
+ add (subset, major_version, minor_version, false, implied_p);
+}
+
/* Convert subset info to string with explicit version info,
VERSION_P to determine append version info or not. */
@@ -178,10 +456,37 @@ riscv_subset_list::to_string (bool version_p) const
oss << "rv" << m_xlen;
bool first = true;
- riscv_subset_t *subset = m_head;
+ riscv_subset_t *subset;
+
+ bool skip_zifencei = false;
+ bool skip_zicsr = false;
+
+ /* For RISC-V ISA version 2.2 or earlier version, zicsr and zifencei is
+ included in the base ISA. */
+ if (riscv_isa_spec == ISA_SPEC_CLASS_2P2)
+ {
+ skip_zifencei = true;
+ skip_zicsr = true;
+ }
- while (subset != NULL)
+#ifndef HAVE_AS_MISA_SPEC
+ /* Skip since older binutils doesn't recognize zicsr. */
+ skip_zicsr = true;
+#endif
+#ifndef HAVE_AS_MARCH_ZIFENCE
+ /* Skip since older binutils doesn't recognize zifencei, we made
+ a mistake in that binutils 2.35 supports zicsr but not zifencei. */
+ skip_zifencei = true;
+#endif
+
+ for (subset = m_head; subset != NULL; subset = subset->next)
{
+ if (subset->implied_p && skip_zifencei && subset->name == "zifencei")
+ continue;
+
+ if (subset->implied_p && skip_zicsr && subset->name == "zicsr")
+ continue;
+
/* For !version_p, we only separate extension with underline for
multi-letter extension. */
if (!first &&
@@ -193,12 +498,12 @@ riscv_subset_list::to_string (bool version_p) const
oss << subset->name;
- if (version_p || subset->explicit_version_p)
+ /* Let binutils decide the extension version if we don't know. */
+ if ((version_p || subset->explicit_version_p) &&
+ (subset->major_version != 0 || subset->minor_version != 0))
oss << subset->major_version
<< 'p'
<< subset->minor_version;
-
- subset = subset->next;
}
return oss.str ();
@@ -246,23 +551,21 @@ riscv_supported_std_ext (void)
Points to the end of version
Arguments:
+ `ext`: This extension.
`p`: Current parsing position.
`major_version`: Parsing result of major version, using
default_major_version if version is not present in arch string.
`minor_version`: Parsing result of minor version, set to 0 if version is
not present in arch string, but set to `default_minor_version` if
`major_version` using default_major_version.
- `default_major_version`: Default major version.
- `default_minor_version`: Default minor version.
`std_ext_p`: True if parsing std extension.
`explicit_version_p`: True if this subset is not using default version. */
const char *
-riscv_subset_list::parsing_subset_version (const char *p,
+riscv_subset_list::parsing_subset_version (const char *ext,
+ const char *p,
unsigned *major_version,
unsigned *minor_version,
- unsigned default_major_version,
- unsigned default_minor_version,
bool std_ext_p,
bool *explicit_version_p)
{
@@ -313,11 +616,7 @@ riscv_subset_list::parsing_subset_version (const char *p,
minor = version;
if (major == 0 && minor == 0)
- {
- /* We didn't find any version string, use default version. */
- *major_version = default_major_version;
- *minor_version = default_minor_version;
- }
+ get_default_version (ext, major_version, minor_version);
else
{
*explicit_version_p = true;
@@ -351,23 +650,17 @@ riscv_subset_list::parse_std_ext (const char *p)
{
case 'i':
p++;
- p = parsing_subset_version (p, &major_version, &minor_version,
- /* default_major_version= */ 2,
- /* default_minor_version= */ 0,
- /* std_ext_p= */ true,
- &explicit_version_p);
- add ("i", major_version, minor_version, explicit_version_p);
+ p = parsing_subset_version ("i", p, &major_version, &minor_version,
+ /* std_ext_p= */ true, &explicit_version_p);
+ add ("i", major_version, minor_version, explicit_version_p, false);
break;
case 'e':
p++;
- p = parsing_subset_version (p, &major_version, &minor_version,
- /* default_major_version= */ 1,
- /* default_minor_version= */ 9,
- /* std_ext_p= */ true,
- &explicit_version_p);
+ p = parsing_subset_version ("e", p, &major_version, &minor_version,
+ /* std_ext_p= */ true, &explicit_version_p);
- add ("e", major_version, minor_version, explicit_version_p);
+ add ("e", major_version, minor_version, explicit_version_p, false);
if (m_xlen > 32)
{
@@ -379,18 +672,26 @@ riscv_subset_list::parse_std_ext (const char *p)
case 'g':
p++;
- p = parsing_subset_version (p, &major_version, &minor_version,
- /* default_major_version= */ 2,
- /* default_minor_version= */ 0,
- /* std_ext_p= */ true,
- &explicit_version_p);
- add ("i", major_version, minor_version, explicit_version_p);
-
- for (; *std_exts != 'q'; std_exts++)
+ p = parsing_subset_version ("g", p, &major_version, &minor_version,
+ /* std_ext_p= */ true, &explicit_version_p);
+ if (major_version != 0 || minor_version != 0)
{
- const char subset[] = {*std_exts, '\0'};
- add (subset, major_version, minor_version, explicit_version_p);
+ warning_at (m_loc, 0, "version of `g` will be omitted, please "
+ "specify version for individual extension.");
}
+
+ /* We have special rule for G, we disallow rv32gm2p but allow rv32g_zicsr
+ here, basically we treating G expand to imafd and implied zicsr and
+ zifencei. */
+
+ add ("i", false);
+ add ("m", false);
+ add ("a", false);
+ add ("f", false);
+ add ("d", false);
+ add ("zicsr", true);
+ add ("zifencei", true);
+
break;
default:
@@ -433,47 +734,47 @@ riscv_subset_list::parse_std_ext (const char *p)
std_exts++;
p++;
- p = parsing_subset_version (p, &major_version, &minor_version,
- /* default_major_version= */ 2,
- /* default_minor_version= */ 0,
- /* std_ext_p= */ true,
- &explicit_version_p);
-
subset[0] = std_ext;
- handle_implied_ext (subset, major_version,
- minor_version, explicit_version_p);
+ p = parsing_subset_version (subset, p, &major_version, &minor_version,
+ /* std_ext_p= */ true, &explicit_version_p);
- add (subset, major_version, minor_version, explicit_version_p);
+ add (subset, major_version, minor_version, explicit_version_p, false);
}
return p;
}
-/* Check any implied extensions for EXT with version
- MAJOR_VERSION.MINOR_VERSION, EXPLICIT_VERSION_P indicate the version is
- explicitly given by user or not. */
+/* Check any implied extensions for EXT. */
void
-riscv_subset_list::handle_implied_ext (const char *ext,
- int major_version,
- int minor_version,
- bool explicit_version_p)
+riscv_subset_list::handle_implied_ext (riscv_subset_t *ext)
{
const riscv_implied_info_t *implied_info;
for (implied_info = &riscv_implied_info[0];
implied_info->ext;
++implied_info)
{
- if (strcmp (ext, implied_info->ext) != 0)
+ if (strcmp (ext->name.c_str (), implied_info->ext) != 0)
continue;
/* Skip if implied extension already present. */
if (lookup (implied_info->implied_ext))
continue;
- /* TODO: Implied extension might use different version. */
- add (implied_info->implied_ext, major_version, minor_version,
- explicit_version_p);
+ /* Version of implied extension will get from current ISA spec
+ version. */
+ add (implied_info->implied_ext, true);
+ }
+
+ /* For RISC-V ISA version 2.2 or earlier version, zicsr and zifence is
+ included in the base ISA. */
+ if (riscv_isa_spec == ISA_SPEC_CLASS_2P2)
+ {
+ if (lookup ("zicsr") == NULL)
+ add ("zicsr", true);
+
+ if (lookup ("zifencei") == NULL)
+ add ("zifencei", true);
}
}
@@ -511,16 +812,21 @@ riscv_subset_list::parse_multiletter_ext (const char *p,
char *q = subset;
const char *end_of_version;
bool explicit_version_p = false;
+ char *ext;
+ char backup;
while (*++q != '\0' && *q != '_' && !ISDIGIT (*q))
;
+ backup = *q;
+ *q = '\0';
+ ext = xstrdup (subset);
+ *q = backup;
+
end_of_version
- = parsing_subset_version (q, &major_version, &minor_version,
- /* default_major_version= */ 2,
- /* default_minor_version= */ 0,
- /* std_ext_p= */ FALSE,
- &explicit_version_p);
+ = parsing_subset_version (ext, q, &major_version, &minor_version,
+ /* std_ext_p= */ false, &explicit_version_p);
+ free (ext);
*q = '\0';
@@ -532,7 +838,7 @@ riscv_subset_list::parse_multiletter_ext (const char *p,
return NULL;
}
- add (subset, major_version, minor_version, explicit_version_p);
+ add (subset, major_version, minor_version, explicit_version_p, false);
free (subset);
p += end_of_version - subset;
@@ -553,6 +859,7 @@ riscv_subset_list *
riscv_subset_list::parse (const char *arch, location_t loc)
{
riscv_subset_list *subset_list = new riscv_subset_list (arch, loc);
+ riscv_subset_t *itr;
const char *p = arch;
if (strncmp (p, "rv32", 4) == 0)
{
@@ -608,6 +915,11 @@ riscv_subset_list::parse (const char *arch, location_t loc)
goto fail;
}
+ for (itr = subset_list->m_head; itr != NULL; itr = itr->next)
+ {
+ subset_list->handle_implied_ext (itr);
+ }
+
return subset_list;
fail:
@@ -645,6 +957,10 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
{"f", &gcc_options::x_target_flags, MASK_HARD_FLOAT},
{"d", &gcc_options::x_target_flags, MASK_DOUBLE_FLOAT},
{"c", &gcc_options::x_target_flags, MASK_RVC},
+
+ {"zicsr", &gcc_options::x_riscv_zi_subext, MASK_ZICSR},
+ {"zifencei", &gcc_options::x_riscv_zi_subext, MASK_ZIFENCEI},
+
{NULL, NULL, 0}
};
diff --git a/gcc/config.gcc b/gcc/config.gcc
index dc6d68b..7b138d1 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -414,7 +414,7 @@ i[34567]86-*-*)
avx512vp2intersectintrin.h avx512vp2intersectvlintrin.h
tsxldtrkintrin.h amxtileintrin.h amxint8intrin.h
amxbf16intrin.h x86gprintrin.h uintrintrin.h
- hresetintrin.h keylockerintrin.h"
+ hresetintrin.h keylockerintrin.h avxvnniintrin.h"
;;
x86_64-*-*)
cpu_type=i386
@@ -451,7 +451,7 @@ x86_64-*-*)
avx512vp2intersectintrin.h avx512vp2intersectvlintrin.h
tsxldtrkintrin.h amxtileintrin.h amxint8intrin.h
amxbf16intrin.h x86gprintrin.h uintrintrin.h
- hresetintrin.h keylockerintrin.h"
+ hresetintrin.h keylockerintrin.h avxvnniintrin.h"
;;
ia64-*-*)
extra_headers=ia64intrin.h
@@ -702,8 +702,10 @@ case ${target} in
extra_options="${extra_options} darwin.opt"
c_target_objs="${c_target_objs} darwin-c.o"
cxx_target_objs="${cxx_target_objs} darwin-c.o"
+ d_target_objs="${d_target_objs} darwin-d.o"
fortran_target_objs="darwin-f.o"
target_has_targetcm=yes
+ target_has_targetdm=yes
extra_objs="${extra_objs} darwin.o"
extra_gcc_objs="darwin-driver.o"
default_use_cxa_atexit=yes
@@ -731,6 +733,9 @@ case ${target} in
extra_options="$extra_options rpath.opt dragonfly.opt"
default_use_cxa_atexit=yes
use_gcc_stdint=wrap
+ d_target_objs="${d_target_objs} dragonfly-d.o"
+ tmake_file="${tmake_file} t-dragonfly"
+ target_has_targetdm=yes
;;
*-*-freebsd*)
# This is the generic ELF configuration of FreeBSD. Later
@@ -779,6 +784,9 @@ case ${target} in
default_use_cxa_atexit=yes;;
esac
use_gcc_stdint=wrap
+ d_target_objs="${d_target_objs} freebsd-d.o"
+ tmake_file="${tmake_file} t-freebsd"
+ target_has_targetdm=yes
;;
*-*-fuchsia*)
native_system_header_dir=/include
@@ -4083,9 +4091,26 @@ fi
supported_defaults=
case "${target}" in
aarch64*-*-*)
- supported_defaults="abi cpu arch"
- for which in cpu arch; do
-
+ supported_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64"
+ if test x$with_cpu_64 != x && test x$with_cpu = x; then
+ with_cpu=$with_cpu_64
+ fi
+ if test x$with_cpu_32 != x && test x$with_cpu = x; then
+ with_cpu=$with_cpu_32
+ fi
+ if test x$with_arch_64 != x && test x$with_arch = x; then
+ with_arch=$with_arch_64
+ fi
+ if test x$with_arch_32 != x && test x$with_arch = x; then
+ with_arch=$with_arch_32
+ fi
+ if test x$with_tune_64 != x && test x$with_tune = x; then
+ with_tune=$with_tune_64
+ fi
+ if test x$with_tune_32 != x && test x$with_tune = x; then
+ with_tune=$with_tune_32
+ fi
+ for which in cpu arch tune; do
eval "val=\$with_$which"
base_val=`echo $val | sed -e 's/\+.*//'`
ext_val=`echo $val | sed -e 's/[a-z0-9.-]\+//'`
@@ -4524,7 +4549,7 @@ case "${target}" in
;;
riscv*-*-*)
- supported_defaults="abi arch tune riscv_attribute"
+ supported_defaults="abi arch tune riscv_attribute isa_spec"
case "${target}" in
riscv-* | riscv32*) xlen=32 ;;
@@ -4532,6 +4557,21 @@ case "${target}" in
*) echo "Unsupported RISC-V target ${target}" 1>&2; exit 1 ;;
esac
+ case "${with_isa_spec}" in
+ ""|default|2.2)
+ tm_defines="${tm_defines} TARGET_DEFAULT_ISA_SPEC=ISA_SPEC_CLASS_2P2"
+ ;;
+ 20191213 | 201912)
+ tm_defines="${tm_defines} TARGET_DEFAULT_ISA_SPEC=ISA_SPEC_CLASS_20191213"
+ ;;
+ 20190608 | 201906)
+ tm_defines="${tm_defines} TARGET_DEFAULT_ISA_SPEC=ISA_SPEC_CLASS_20190608"
+ ;;
+ *)
+ echo "--with-isa-spec only accept 2.2, 20191213, 201912, 20190608 or 201906" 1>&2
+ exit 1
+ esac
+
case "${with_riscv_attribute}" in
yes)
tm_defines="${tm_defines} TARGET_RISCV_ATTRIBUTE=1"
@@ -4575,6 +4615,8 @@ case "${target}" in
exit 1
;;
esac
+ with_arch=`${srcdir}/config/riscv/arch-canonicalize ${with_arch}`
+ tm_defines="${tm_defines} TARGET_RISCV_DEFAULT_ARCH=${with_arch}"
# Make sure --with-abi is valid. If it was not specified,
# pick a default based on the ISA, preferring soft-float
@@ -4596,6 +4638,7 @@ case "${target}" in
exit 1
;;
esac
+ tm_defines="${tm_defines} TARGET_RISCV_DEFAULT_ABI=${with_abi}"
# Make sure ABI and ISA are compatible.
case "${with_abi},${with_arch}" in
@@ -4638,7 +4681,6 @@ case "${target}" in
# Handle --with-multilib-list.
if test "x${with_multilib_list}" != xdefault; then
- tm_file="${tm_file} riscv/withmultilib.h"
tmake_file="${tmake_file} riscv/t-withmultilib"
case ${with_multilib_list} in
@@ -4650,42 +4692,6 @@ case "${target}" in
echo "--with-multilib-list=${with_multilib_list} not supported."
exit 1
esac
-
- # Define macros to select the default multilib.
- case ${with_arch} in
- rv32gc)
- tm_defines="${tm_defines} TARGET_MLIB_ARCH=1"
- ;;
- rv64gc)
- tm_defines="${tm_defines} TARGET_MLIB_ARCH=2"
- ;;
- *)
- echo "unsupported --with-arch for --with-multilib-list"
- exit 1
- esac
- case ${with_abi} in
- ilp32)
- tm_defines="${tm_defines} TARGET_MLIB_ABI=1"
- ;;
- ilp32f)
- tm_defines="${tm_defines} TARGET_MLIB_ABI=2"
- ;;
- ilp32d)
- tm_defines="${tm_defines} TARGET_MLIB_ABI=3"
- ;;
- lp64)
- tm_defines="${tm_defines} TARGET_MLIB_ABI=4"
- ;;
- lp64f)
- tm_defines="${tm_defines} TARGET_MLIB_ABI=5"
- ;;
- lp64d)
- tm_defines="${tm_defines} TARGET_MLIB_ABI=6"
- ;;
- *)
- echo "unsupported --with-abi for --with-multilib"
- exit 1
- esac
fi
;;
@@ -5226,8 +5232,8 @@ case ${target} in
i[34567]86-*-darwin* | x86_64-*-darwin*)
;;
i[34567]86-*-linux* | x86_64-*-linux*)
- extra_objs="${extra_objs} cet.o"
- tmake_file="$tmake_file i386/t-linux i386/t-cet"
+ extra_objs="${extra_objs} gnu-property.o"
+ tmake_file="$tmake_file i386/t-linux i386/t-gnu-property"
;;
i[34567]86-*-kfreebsd*-gnu | x86_64-*-kfreebsd*-gnu)
tmake_file="$tmake_file i386/t-kfreebsd"
diff --git a/gcc/config.in b/gcc/config.in
index b7c3107..216505a 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -236,6 +236,10 @@
/* Define if you want runtime assertions enabled. This is a cheap check. */
#undef ENABLE_RUNTIME_CHECKING
+/* Define to enable evaluating float expressions with double precision in
+ standards-compatible mode on s390 targets. */
+#undef ENABLE_S390_EXCESS_FLOAT_PRECISION
+
/* Define if you want all operations on trees (the basic data structure of the
front ends) to be checked for dynamic type safety at runtime. This is
moderately expensive. */
@@ -302,6 +306,18 @@
#endif
+/* Define if AF_INET6 supported. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AF_INET6
+#endif
+
+
+/* Define if AF_UNIX supported. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AF_UNIX
+#endif
+
+
/* Define if your assembler supports architecture modifiers. */
#ifndef USED_FOR_TARGET
#undef HAVE_AS_ARCHITECTURE_MODIFIERS
@@ -564,12 +580,24 @@
#endif
+/* Define if the assembler understands -march=rv*_zifencei. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_MARCH_ZIFENCEI
+#endif
+
+
/* Define if your assembler supports mfcr field. */
#ifndef USED_FOR_TARGET
#undef HAVE_AS_MFCRF
#endif
+/* Define if the assembler understands -misa-spec=. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_MISA_SPEC
+#endif
+
+
/* Define if your Mac OS X assembler supports the -mmacos-version-min option.
*/
#ifndef USED_FOR_TARGET
@@ -1253,6 +1281,12 @@
#endif
+/* Define to 1 if you have the `fstatat' function. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_FSTATAT
+#endif
+
+
/* Define to 1 if you have the <ftw.h> header file. */
#ifndef USED_FOR_TARGET
#undef HAVE_FTW_H
@@ -1352,6 +1386,19 @@
#endif
+/* Define 0/1 if your assembler supports 'o' flag in .section directive. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_GAS_SECTION_LINK_ORDER
+#endif
+
+
+/* Define 0/1 if your assembler supports marking sections with SHF_GNU_RETAIN
+ flag. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_GAS_SHF_GNU_RETAIN
+#endif
+
+
/* Define 0/1 if your assembler supports marking sections with SHF_MERGE flag.
*/
#ifndef USED_FOR_TARGET
@@ -1758,6 +1805,12 @@
#endif
+/* Define to 1 if you have the `posix_fallocate' function. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_POSIX_FALLOCATE
+#endif
+
+
/* Define to 1 if you have the `putchar_unlocked' function. */
#ifndef USED_FOR_TARGET
#undef HAVE_PUTCHAR_UNLOCKED
@@ -1782,6 +1835,12 @@
#endif
+/* Define if <sys/signal.h> defines sighandler_t */
+#ifndef USED_FOR_TARGET
+#undef HAVE_SIGHANDLER_T
+#endif
+
+
/* Define if the system-provided CRTs are present on Solaris. */
#ifndef USED_FOR_TARGET
#undef HAVE_SOLARIS_CRTS
@@ -2021,6 +2080,12 @@
#endif
+/* Define if O_CLOEXEC supported by fcntl. */
+#ifndef USED_FOR_TARGET
+#undef HOST_HAS_O_CLOEXEC
+#endif
+
+
/* Define as const if the declaration of iconv() needs const. */
#ifndef USED_FOR_TARGET
#undef ICONV_CONST
diff --git a/gcc/config/aarch64/aarch64-option-extensions.def b/gcc/config/aarch64/aarch64-option-extensions.def
index ca08642..ec45301 100644
--- a/gcc/config/aarch64/aarch64-option-extensions.def
+++ b/gcc/config/aarch64/aarch64-option-extensions.def
@@ -226,4 +226,7 @@ AARCH64_OPT_EXTENSION("f64mm", AARCH64_FL_F64MM, \
AARCH64_OPT_EXTENSION("bf16", AARCH64_FL_BF16, \
AARCH64_FL_SIMD | AARCH64_FL_FP, 0, false, "bf16")
+/* Enabling/Disabling "flagm" only changes "flagm". */
+AARCH64_OPT_EXTENSION("flagm", AARCH64_FL_FLAGM, 0, 0, false, "flagm")
+
#undef AARCH64_OPT_EXTENSION
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 7a34c84..2aa3f1f 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -510,6 +510,7 @@ bool aarch64_emit_approx_div (rtx, rtx, rtx);
bool aarch64_emit_approx_sqrt (rtx, rtx, bool);
void aarch64_expand_call (rtx, rtx, rtx, bool);
bool aarch64_expand_cpymem (rtx *);
+bool aarch64_expand_setmem (rtx *);
bool aarch64_float_const_zero_rtx_p (rtx);
bool aarch64_float_const_rtx_p (rtx);
bool aarch64_function_arg_regno_p (unsigned);
diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def
index cb05aad..b70056a 100644
--- a/gcc/config/aarch64/aarch64-simd-builtins.def
+++ b/gcc/config/aarch64/aarch64-simd-builtins.def
@@ -47,7 +47,7 @@
VAR1 (COMBINEP, combine, 0, ALL, di)
BUILTIN_VB (BINOP, pmul, 0, NONE)
BUILTIN_VHSDF_HSDF (BINOP, fmulx, 0, FP)
- BUILTIN_VHSDF_DF (UNOP, sqrt, 2, ALL)
+ BUILTIN_VHSDF_DF (UNOP, sqrt, 2, FP)
BUILTIN_VD_BHSI (BINOP, addp, 0, NONE)
VAR1 (UNOP, addp, 0, NONE, di)
BUILTIN_VDQ_BHSI (UNOP, clrsb, 2, ALL)
@@ -229,9 +229,9 @@
BUILTIN_VSDQ_I_DI (BINOP_UUS, urshl, 0, ALL)
/* Implemented by aarch64_<sur><dotprod>{_lane}{q}<dot_mode>. */
- BUILTIN_VB (TERNOP, sdot, 0, ALL)
- BUILTIN_VB (TERNOPU, udot, 0, ALL)
- BUILTIN_VB (TERNOP_SSUS, usdot, 0, ALL)
+ BUILTIN_VB (TERNOP, sdot, 0, NONE)
+ BUILTIN_VB (TERNOPU, udot, 0, NONE)
+ BUILTIN_VB (TERNOP_SSUS, usdot, 0, NONE)
BUILTIN_VB (QUADOP_LANE, sdot_lane, 0, ALL)
BUILTIN_VB (QUADOPU_LANE, udot_lane, 0, ALL)
BUILTIN_VB (QUADOP_LANE, sdot_laneq, 0, ALL)
@@ -304,7 +304,7 @@
BUILTIN_VSDQ_I (USHIFTIMM, uqshl_n, 0, ALL)
/* Implemented by aarch64_reduc_plus_<mode>. */
- BUILTIN_VALL (UNOP, reduc_plus_scal_, 10, ALL)
+ BUILTIN_VALL (UNOP, reduc_plus_scal_, 10, NONE)
/* Implemented by reduc_<maxmin_uns>_scal_<mode> (producing scalar). */
BUILTIN_VDQIF_F16 (UNOP, reduc_smax_scal_, 10, NONE)
@@ -462,19 +462,19 @@
BUILTIN_VALL (BINOP, trn1, 0, ALL)
BUILTIN_VALL (BINOP, trn2, 0, ALL)
- BUILTIN_GPF_F16 (UNOP, frecpe, 0, ALL)
- BUILTIN_GPF_F16 (UNOP, frecpx, 0, ALL)
+ BUILTIN_GPF_F16 (UNOP, frecpe, 0, FP)
+ BUILTIN_GPF_F16 (UNOP, frecpx, 0, FP)
- BUILTIN_VDQ_SI (UNOP, urecpe, 0, ALL)
+ BUILTIN_VDQ_SI (UNOP, urecpe, 0, NONE)
- BUILTIN_VHSDF (UNOP, frecpe, 0, ALL)
- BUILTIN_VHSDF_HSDF (BINOP, frecps, 0, ALL)
+ BUILTIN_VHSDF (UNOP, frecpe, 0, FP)
+ BUILTIN_VHSDF_HSDF (BINOP, frecps, 0, FP)
/* Implemented by a mixture of abs2 patterns. Note the DImode builtin is
only ever used for the int64x1_t intrinsic, there is no scalar version. */
- BUILTIN_VSDQ_I_DI (UNOP, abs, 0, ALL)
- BUILTIN_VHSDF (UNOP, abs, 2, ALL)
- VAR1 (UNOP, abs, 2, ALL, hf)
+ BUILTIN_VSDQ_I_DI (UNOP, abs, 0, AUTO_FP)
+ BUILTIN_VHSDF (UNOP, abs, 2, AUTO_FP)
+ VAR1 (UNOP, abs, 2, AUTO_FP, hf)
BUILTIN_VQ_HSF (UNOP, vec_unpacks_hi_, 10, FP)
VAR1 (BINOP, float_truncate_hi_, 0, FP, v4sf)
@@ -508,11 +508,11 @@
BUILTIN_VALLDIF (STORESTRUCT, st1x4, 0, STORE)
/* Implemented by fma<mode>4. */
- BUILTIN_VHSDF (TERNOP, fma, 4, ALL)
- VAR1 (TERNOP, fma, 4, ALL, hf)
+ BUILTIN_VHSDF (TERNOP, fma, 4, FP)
+ VAR1 (TERNOP, fma, 4, FP, hf)
/* Implemented by fnma<mode>4. */
- BUILTIN_VHSDF (TERNOP, fnma, 4, ALL)
- VAR1 (TERNOP, fnma, 4, ALL, hf)
+ BUILTIN_VHSDF (TERNOP, fnma, 4, FP)
+ VAR1 (TERNOP, fnma, 4, FP, hf)
/* Implemented by aarch64_simd_bsl<mode>. */
BUILTIN_VDQQH (BSL_P, simd_bsl, 0, ALL)
@@ -595,13 +595,13 @@
BUILTIN_GPI (SHIFTIMM_USS, fcvtzuhf, 3, ALL)
/* Implemented by aarch64_rsqrte<mode>. */
- BUILTIN_VHSDF_HSDF (UNOP, rsqrte, 0, ALL)
+ BUILTIN_VHSDF_HSDF (UNOP, rsqrte, 0, FP)
/* Implemented by aarch64_rsqrts<mode>. */
- BUILTIN_VHSDF_HSDF (BINOP, rsqrts, 0, ALL)
+ BUILTIN_VHSDF_HSDF (BINOP, rsqrts, 0, FP)
/* Implemented by fabd<mode>3. */
- BUILTIN_VHSDF_HSDF (BINOP, fabd, 3, ALL)
+ BUILTIN_VHSDF_HSDF (BINOP, fabd, 3, FP)
/* Implemented by aarch64_faddp<mode>. */
BUILTIN_VHSDF (BINOP, faddp, 0, FP)
@@ -623,7 +623,7 @@
BUILTIN_VHSDF_HSDF (BINOP_USS, facge, 0, FP)
/* Implemented by sqrt<mode>2. */
- VAR1 (UNOP, sqrt, 2, ALL, hf)
+ VAR1 (UNOP, sqrt, 2, FP, hf)
/* Implemented by <optab><mode>hf2. */
VAR1 (UNOP, floatdi, 2, FP, hf)
@@ -714,7 +714,7 @@
BUILTIN_VSFDF (UNOP, frint64x, 0, FP)
/* Implemented by aarch64_bfdot{_lane}{q}<mode>. */
- VAR2 (TERNOP, bfdot, 0, ALL, v2sf, v4sf)
+ VAR2 (TERNOP, bfdot, 0, AUTO_FP, v2sf, v4sf)
VAR2 (QUADOP_LANE_PAIR, bfdot_lane, 0, ALL, v2sf, v4sf)
VAR2 (QUADOP_LANE_PAIR, bfdot_laneq, 0, ALL, v2sf, v4sf)
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 2cf6fe9..68baf41 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -3382,6 +3382,53 @@
[(set_attr "type" "neon_<ADDSUB:optab>_long")]
)
+(define_expand "vec_widen_<su>addl_lo_<mode>"
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand"))
+ (ANY_EXTEND:<VWIDE> (match_operand:VQW 2 "register_operand"))]
+ "TARGET_SIMD"
+{
+ rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, false);
+ emit_insn (gen_aarch64_<su>addl<mode>_lo_internal (operands[0], operands[1],
+ operands[2], p));
+ DONE;
+})
+
+(define_expand "vec_widen_<su>addl_hi_<mode>"
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand"))
+ (ANY_EXTEND:<VWIDE> (match_operand:VQW 2 "register_operand"))]
+ "TARGET_SIMD"
+{
+ rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
+ emit_insn (gen_aarch64_<su>addl<mode>_hi_internal (operands[0], operands[1],
+ operands[2], p));
+ DONE;
+})
+
+(define_expand "vec_widen_<su>subl_lo_<mode>"
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand"))
+ (ANY_EXTEND:<VWIDE> (match_operand:VQW 2 "register_operand"))]
+ "TARGET_SIMD"
+{
+ rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, false);
+ emit_insn (gen_aarch64_<su>subl<mode>_lo_internal (operands[0], operands[1],
+ operands[2], p));
+ DONE;
+})
+
+(define_expand "vec_widen_<su>subl_hi_<mode>"
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand"))
+ (ANY_EXTEND:<VWIDE> (match_operand:VQW 2 "register_operand"))]
+ "TARGET_SIMD"
+{
+ rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
+ emit_insn (gen_aarch64_<su>subl<mode>_hi_internal (operands[0], operands[1],
+ operands[2], p));
+ DONE;
+})
(define_expand "aarch64_saddl2<mode>"
[(match_operand:<VWIDE> 0 "register_operand")
@@ -4617,8 +4664,74 @@
[(set_attr "type" "neon_sat_shift_reg<q>")]
)
+(define_expand "vec_widen_<sur>shiftl_lo_<mode>"
+ [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
+ (unspec:<VWIDE> [(match_operand:VQW 1 "register_operand" "w")
+ (match_operand:SI 2
+ "aarch64_simd_shift_imm_bitsize_<ve_mode>" "i")]
+ VSHLL))]
+ "TARGET_SIMD"
+ {
+ rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, false);
+ emit_insn (gen_aarch64_<sur>shll<mode>_internal (operands[0], operands[1],
+ p, operands[2]));
+ DONE;
+ }
+)
+
+(define_expand "vec_widen_<sur>shiftl_hi_<mode>"
+ [(set (match_operand:<VWIDE> 0 "register_operand")
+ (unspec:<VWIDE> [(match_operand:VQW 1 "register_operand" "w")
+ (match_operand:SI 2
+ "immediate_operand" "i")]
+ VSHLL))]
+ "TARGET_SIMD"
+ {
+ rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
+ emit_insn (gen_aarch64_<sur>shll2<mode>_internal (operands[0], operands[1],
+ p, operands[2]));
+ DONE;
+ }
+)
+
;; vshll_n
+(define_insn "aarch64_<sur>shll<mode>_internal"
+ [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
+ (unspec:<VWIDE> [(vec_select:<VHALF>
+ (match_operand:VQW 1 "register_operand" "w")
+ (match_operand:VQW 2 "vect_par_cnst_lo_half" ""))
+ (match_operand:SI 3
+ "aarch64_simd_shift_imm_bitsize_<ve_mode>" "i")]
+ VSHLL))]
+ "TARGET_SIMD"
+ {
+ if (INTVAL (operands[3]) == GET_MODE_UNIT_BITSIZE (<MODE>mode))
+ return "shll\\t%0.<Vwtype>, %1.<Vhalftype>, %3";
+ else
+ return "<sur>shll\\t%0.<Vwtype>, %1.<Vhalftype>, %3";
+ }
+ [(set_attr "type" "neon_shift_imm_long")]
+)
+
+(define_insn "aarch64_<sur>shll2<mode>_internal"
+ [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
+ (unspec:<VWIDE> [(vec_select:<VHALF>
+ (match_operand:VQW 1 "register_operand" "w")
+ (match_operand:VQW 2 "vect_par_cnst_hi_half" ""))
+ (match_operand:SI 3
+ "aarch64_simd_shift_imm_bitsize_<ve_mode>" "i")]
+ VSHLL))]
+ "TARGET_SIMD"
+ {
+ if (INTVAL (operands[3]) == GET_MODE_UNIT_BITSIZE (<MODE>mode))
+ return "shll2\\t%0.<Vwtype>, %1.<Vtype>, %3";
+ else
+ return "<sur>shll2\\t%0.<Vwtype>, %1.<Vtype>, %3";
+ }
+ [(set_attr "type" "neon_shift_imm_long")]
+)
+
(define_insn "aarch64_<sur>shll_n<mode>"
[(set (match_operand:<VWIDE> 0 "register_operand" "=w")
(unspec:<VWIDE> [(match_operand:VD_BHSI 1 "register_operand" "w")
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
index 9b63ea7..4223125 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
@@ -2295,17 +2295,6 @@ public:
CONSTEXPR svundef_impl (unsigned int vectors_per_tuple)
: quiet<multi_vector_function> (vectors_per_tuple) {}
- gimple *
- fold (gimple_folder &f) const OVERRIDE
- {
- /* Don't fold svundef at the gimple level. There's no exact
- correspondence for SSA_NAMEs, and we explicitly don't want
- to generate a specific value (like an all-zeros vector). */
- if (vectors_per_tuple () == 1)
- return NULL;
- return gimple_build_assign (f.lhs, build_clobber (TREE_TYPE (f.lhs)));
- }
-
rtx
expand (function_expander &e) const OVERRIDE
{
diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md
index 4b0a1eb..6359c40 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -2925,14 +2925,17 @@
;; Integer unary arithmetic predicated with a PTRUE.
(define_insn "@aarch64_pred_<optab><mode>"
- [(set (match_operand:SVE_I 0 "register_operand" "=w")
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
(unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
(SVE_INT_UNARY:SVE_I
- (match_operand:SVE_I 2 "register_operand" "w"))]
+ (match_operand:SVE_I 2 "register_operand" "0, w"))]
UNSPEC_PRED_X))]
"TARGET_SVE"
- "<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ "@
+ <sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
+ movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; Predicated integer unary arithmetic with merging.
@@ -2998,15 +3001,18 @@
;; Predicated integer unary operations.
(define_insn "@aarch64_pred_<optab><mode>"
- [(set (match_operand:SVE_FULL_I 0 "register_operand" "=w")
+ [(set (match_operand:SVE_FULL_I 0 "register_operand" "=w, ?&w")
(unspec:SVE_FULL_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
(unspec:SVE_FULL_I
- [(match_operand:SVE_FULL_I 2 "register_operand" "w")]
+ [(match_operand:SVE_FULL_I 2 "register_operand" "0, w")]
SVE_INT_UNARY)]
UNSPEC_PRED_X))]
"TARGET_SVE && <elem_bits> >= <min_elem_bits>"
- "<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ "@
+ <sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
+ movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; Another way of expressing the REVB, REVH and REVW patterns, with this
@@ -3014,15 +3020,18 @@
;; of lanes and the data mode decides the granularity of the reversal within
;; each lane.
(define_insn "@aarch64_sve_revbhw_<SVE_ALL:mode><PRED_HSD:mode>"
- [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
+ [(set (match_operand:SVE_ALL 0 "register_operand" "=w, ?&w")
(unspec:SVE_ALL
- [(match_operand:PRED_HSD 1 "register_operand" "Upl")
+ [(match_operand:PRED_HSD 1 "register_operand" "Upl, Upl")
(unspec:SVE_ALL
- [(match_operand:SVE_ALL 2 "register_operand" "w")]
+ [(match_operand:SVE_ALL 2 "register_operand" "0, w")]
UNSPEC_REVBHW)]
UNSPEC_PRED_X))]
"TARGET_SVE && <PRED_HSD:elem_bits> > <SVE_ALL:container_bits>"
- "rev<SVE_ALL:Vcwtype>\t%0.<PRED_HSD:Vetype>, %1/m, %2.<PRED_HSD:Vetype>"
+ "@
+ rev<SVE_ALL:Vcwtype>\t%0.<PRED_HSD:Vetype>, %1/m, %2.<PRED_HSD:Vetype>
+ movprfx\t%0, %2\;rev<SVE_ALL:Vcwtype>\t%0.<PRED_HSD:Vetype>, %1/m, %2.<PRED_HSD:Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; Predicated integer unary operations with merging.
@@ -3071,28 +3080,34 @@
;; Predicated sign and zero extension from a narrower mode.
(define_insn "*<optab><SVE_PARTIAL_I:mode><SVE_HSDI:mode>2"
- [(set (match_operand:SVE_HSDI 0 "register_operand" "=w")
+ [(set (match_operand:SVE_HSDI 0 "register_operand" "=w, ?&w")
(unspec:SVE_HSDI
- [(match_operand:<SVE_HSDI:VPRED> 1 "register_operand" "Upl")
+ [(match_operand:<SVE_HSDI:VPRED> 1 "register_operand" "Upl, Upl")
(ANY_EXTEND:SVE_HSDI
- (match_operand:SVE_PARTIAL_I 2 "register_operand" "w"))]
+ (match_operand:SVE_PARTIAL_I 2 "register_operand" "0, w"))]
UNSPEC_PRED_X))]
"TARGET_SVE && (~<SVE_HSDI:narrower_mask> & <SVE_PARTIAL_I:self_mask>) == 0"
- "<su>xt<SVE_PARTIAL_I:Vesize>\t%0.<SVE_HSDI:Vetype>, %1/m, %2.<SVE_HSDI:Vetype>"
+ "@
+ <su>xt<SVE_PARTIAL_I:Vesize>\t%0.<SVE_HSDI:Vetype>, %1/m, %2.<SVE_HSDI:Vetype>
+ movprfx\t%0, %2\;<su>xt<SVE_PARTIAL_I:Vesize>\t%0.<SVE_HSDI:Vetype>, %1/m, %2.<SVE_HSDI:Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; Predicated truncate-and-sign-extend operations.
(define_insn "@aarch64_pred_sxt<SVE_FULL_HSDI:mode><SVE_PARTIAL_I:mode>"
- [(set (match_operand:SVE_FULL_HSDI 0 "register_operand" "=w")
+ [(set (match_operand:SVE_FULL_HSDI 0 "register_operand" "=w, ?&w")
(unspec:SVE_FULL_HSDI
- [(match_operand:<SVE_FULL_HSDI:VPRED> 1 "register_operand" "Upl")
+ [(match_operand:<SVE_FULL_HSDI:VPRED> 1 "register_operand" "Upl, Upl")
(sign_extend:SVE_FULL_HSDI
(truncate:SVE_PARTIAL_I
- (match_operand:SVE_FULL_HSDI 2 "register_operand" "w")))]
+ (match_operand:SVE_FULL_HSDI 2 "register_operand" "0, w")))]
UNSPEC_PRED_X))]
"TARGET_SVE
&& (~<SVE_FULL_HSDI:narrower_mask> & <SVE_PARTIAL_I:self_mask>) == 0"
- "sxt<SVE_PARTIAL_I:Vesize>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>"
+ "@
+ sxt<SVE_PARTIAL_I:Vesize>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>
+ movprfx\t%0, %2\;sxt<SVE_PARTIAL_I:Vesize>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; Predicated truncate-and-sign-extend operations with merging.
@@ -3212,20 +3227,23 @@
)
(define_insn "*cnot<mode>"
- [(set (match_operand:SVE_FULL_I 0 "register_operand" "=w")
+ [(set (match_operand:SVE_FULL_I 0 "register_operand" "=w, ?&w")
(unspec:SVE_FULL_I
[(unspec:<VPRED>
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
(match_operand:SI 5 "aarch64_sve_ptrue_flag")
(eq:<VPRED>
- (match_operand:SVE_FULL_I 2 "register_operand" "w")
+ (match_operand:SVE_FULL_I 2 "register_operand" "0, w")
(match_operand:SVE_FULL_I 3 "aarch64_simd_imm_zero"))]
UNSPEC_PRED_Z)
(match_operand:SVE_FULL_I 4 "aarch64_simd_imm_one")
(match_dup 3)]
UNSPEC_SEL))]
"TARGET_SVE"
- "cnot\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ "@
+ cnot\t%0.<Vetype>, %1/m, %2.<Vetype>
+ movprfx\t%0, %2\;cnot\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; Predicated logical inverse with merging.
@@ -3383,14 +3401,17 @@
;; Predicated floating-point unary operations.
(define_insn "@aarch64_pred_<optab><mode>"
- [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w")
+ [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
(unspec:SVE_FULL_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
(match_operand:SI 3 "aarch64_sve_gp_strictness")
- (match_operand:SVE_FULL_F 2 "register_operand" "w")]
+ (match_operand:SVE_FULL_F 2 "register_operand" "0, w")]
SVE_COND_FP_UNARY))]
"TARGET_SVE"
- "<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ "@
+ <sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
+ movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; Predicated floating-point unary arithmetic with merging.
@@ -7379,11 +7400,11 @@
;; UNSPEC_SEL operand order: mask, true, false (as for VEC_COND_EXPR)
;; SEL operand order: mask, true, false
(define_expand "@vcond_mask_<mode><vpred>"
- [(set (match_operand:SVE_FULL 0 "register_operand")
- (unspec:SVE_FULL
+ [(set (match_operand:SVE_ALL 0 "register_operand")
+ (unspec:SVE_ALL
[(match_operand:<VPRED> 3 "register_operand")
- (match_operand:SVE_FULL 1 "aarch64_sve_reg_or_dup_imm")
- (match_operand:SVE_FULL 2 "aarch64_simd_reg_or_zero")]
+ (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"
{
@@ -7396,12 +7417,25 @@
;; - two registers
;; - a duplicated immediate and a register
;; - a duplicated immediate and zero
+;;
+;; For unpacked vectors, it doesn't really matter whether SEL uses the
+;; the container size or the element size. If SEL used the container size,
+;; it would ignore undefined bits of the predicate but would copy the
+;; upper (undefined) bits of each container along with the defined bits.
+;; If SEL used the element size, it would use undefined bits of the predicate
+;; to select between undefined elements in each input vector. Thus the only
+;; difference is whether the undefined bits in a container always come from
+;; the same input as the defined bits, or whether the choice can vary
+;; independently of the defined bits.
+;;
+;; For the other instructions, using the element size is more natural,
+;; so we do that for SEL as well.
(define_insn "*vcond_mask_<mode><vpred>"
- [(set (match_operand:SVE_FULL 0 "register_operand" "=w, w, w, w, ?w, ?&w, ?&w")
- (unspec:SVE_FULL
+ [(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_FULL 1 "aarch64_sve_reg_or_dup_imm" "w, vss, vss, Ufc, Ufc, vss, Ufc")
- (match_operand:SVE_FULL 2 "aarch64_simd_reg_or_zero" "w, 0, Dz, 0, Dz, w, w")]
+ (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)
@@ -7422,12 +7456,12 @@
;; 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_FULL 0 "register_operand" "=?w, w, ??w, ?&w, ??&w, ?&w")
- (unspec:SVE_FULL
+ [(set (match_operand:SVE_ALL 0 "register_operand" "=?w, w, ??w, ?&w, ??&w, ?&w")
+ (unspec:SVE_ALL
[(match_operand:<VPRED> 3 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
- (vec_duplicate:SVE_FULL
+ (vec_duplicate:SVE_ALL
(match_operand:<VEL> 1 "register_operand" "r, w, r, w, r, w"))
- (match_operand:SVE_FULL 2 "aarch64_simd_reg_or_zero" "0, 0, Dz, Dz, w, w")]
+ (match_operand:SVE_ALL 2 "aarch64_simd_reg_or_zero" "0, 0, Dz, Dz, w, w")]
UNSPEC_SEL))]
"TARGET_SVE"
"@
@@ -7448,34 +7482,34 @@
;; 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>"
- [(set (match_operand:SVE_FULL 0 "register_operand")
- (if_then_else:SVE_FULL
+(define_expand "vcond<SVE_ALL:mode><SVE_I:mode>"
+ [(set (match_operand:SVE_ALL 0 "register_operand")
+ (if_then_else:SVE_ALL
(match_operator 3 "comparison_operator"
- [(match_operand:<V_INT_EQUIV> 4 "register_operand")
- (match_operand:<V_INT_EQUIV> 5 "nonmemory_operand")])
- (match_operand:SVE_FULL 1 "nonmemory_operand")
- (match_operand:SVE_FULL 2 "nonmemory_operand")))]
- "TARGET_SVE"
+ [(match_operand:SVE_I 4 "register_operand")
+ (match_operand:SVE_I 5 "nonmemory_operand")])
+ (match_operand:SVE_ALL 1 "nonmemory_operand")
+ (match_operand:SVE_ALL 2 "nonmemory_operand")))]
+ "TARGET_SVE && <SVE_ALL:container_bits> == <SVE_I:container_bits>"
{
- aarch64_expand_sve_vcond (<MODE>mode, <V_INT_EQUIV>mode, operands);
+ aarch64_expand_sve_vcond (<SVE_ALL:MODE>mode, <SVE_I:MODE>mode, operands);
DONE;
}
)
;; Integer vcondu. Don't enforce an immediate range here, since it
;; depends on the comparison; leave it to aarch64_expand_sve_vcond instead.
-(define_expand "vcondu<mode><v_int_equiv>"
- [(set (match_operand:SVE_FULL 0 "register_operand")
- (if_then_else:SVE_FULL
+(define_expand "vcondu<SVE_ALL:mode><SVE_I:mode>"
+ [(set (match_operand:SVE_ALL 0 "register_operand")
+ (if_then_else:SVE_ALL
(match_operator 3 "comparison_operator"
- [(match_operand:<V_INT_EQUIV> 4 "register_operand")
- (match_operand:<V_INT_EQUIV> 5 "nonmemory_operand")])
- (match_operand:SVE_FULL 1 "nonmemory_operand")
- (match_operand:SVE_FULL 2 "nonmemory_operand")))]
- "TARGET_SVE"
+ [(match_operand:SVE_I 4 "register_operand")
+ (match_operand:SVE_I 5 "nonmemory_operand")])
+ (match_operand:SVE_ALL 1 "nonmemory_operand")
+ (match_operand:SVE_ALL 2 "nonmemory_operand")))]
+ "TARGET_SVE && <SVE_ALL:container_bits> == <SVE_I:container_bits>"
{
- aarch64_expand_sve_vcond (<MODE>mode, <V_INT_EQUIV>mode, operands);
+ aarch64_expand_sve_vcond (<SVE_ALL:MODE>mode, <SVE_I:MODE>mode, operands);
DONE;
}
)
@@ -7520,8 +7554,8 @@
[(parallel
[(set (match_operand:<VPRED> 0 "register_operand")
(match_operator:<VPRED> 1 "comparison_operator"
- [(match_operand:SVE_FULL_I 2 "register_operand")
- (match_operand:SVE_FULL_I 3 "nonmemory_operand")]))
+ [(match_operand:SVE_I 2 "register_operand")
+ (match_operand:SVE_I 3 "nonmemory_operand")]))
(clobber (reg:CC_NZC CC_REGNUM))])]
"TARGET_SVE"
{
@@ -7538,8 +7572,8 @@
[(parallel
[(set (match_operand:<VPRED> 0 "register_operand")
(match_operator:<VPRED> 1 "comparison_operator"
- [(match_operand:SVE_FULL_I 2 "register_operand")
- (match_operand:SVE_FULL_I 3 "nonmemory_operand")]))
+ [(match_operand:SVE_I 2 "register_operand")
+ (match_operand:SVE_I 3 "nonmemory_operand")]))
(clobber (reg:CC_NZC CC_REGNUM))])]
"TARGET_SVE"
{
@@ -7550,14 +7584,38 @@
)
;; Predicated integer comparisons.
+;;
+;; For unpacked vectors, only the lowpart element in each input container
+;; has a defined value, and only the predicate bits associated with
+;; those elements are defined. For example, when comparing two VNx2SIs:
+;;
+;; - The VNx2SIs can be seem as VNx2DIs in which the low halves of each
+;; DI container store an SI element. The upper bits of each DI container
+;; are undefined.
+;;
+;; - Alternatively, the VNx2SIs can be seen as VNx4SIs in which the
+;; even elements are defined and the odd elements are undefined.
+;;
+;; - The associated predicate mode is VNx2BI. This means that only the
+;; low bit in each predicate byte is defined (on input and on output).
+;;
+;; - We use a .s comparison to compare VNx2SIs, under the control of a
+;; VNx2BI governing predicate, to produce a VNx2BI result. If we view
+;; the .s operation as operating on VNx4SIs then for odd lanes:
+;;
+;; - the input governing predicate bit is undefined
+;; - the SI elements being compared are undefined
+;; - the predicate result bit is therefore undefined, but
+;; - the predicate result bit is in the undefined part of a VNx2BI,
+;; so its value doesn't matter anyway.
(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_FULL_I 3 "register_operand" "w, w")
- (match_operand:SVE_FULL_I 4 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
+ (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"
@@ -7578,8 +7636,8 @@
[(match_operand 6)
(match_operand:SI 7 "aarch64_sve_ptrue_flag")
(SVE_INT_CMP:<VPRED>
- (match_operand:SVE_FULL_I 2 "register_operand" "w, w")
- (match_operand:SVE_FULL_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
+ (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")
@@ -7614,8 +7672,8 @@
[(match_operand 6)
(match_operand:SI 7 "aarch64_sve_ptrue_flag")
(SVE_INT_CMP:<VPRED>
- (match_operand:SVE_FULL_I 2 "register_operand" "w, w")
- (match_operand:SVE_FULL_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
+ (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"))]
@@ -7642,8 +7700,8 @@
[(match_operand 4)
(const_int SVE_KNOWN_PTRUE)
(SVE_INT_CMP:<VPRED>
- (match_operand:SVE_FULL_I 2 "register_operand" "w, w")
- (match_operand:SVE_FULL_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
+ (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))]
@@ -8538,26 +8596,32 @@
;; Predicated float-to-integer conversion, either to the same width or wider.
(define_insn "@aarch64_sve_<optab>_nontrunc<SVE_FULL_F:mode><SVE_FULL_HSDI:mode>"
- [(set (match_operand:SVE_FULL_HSDI 0 "register_operand" "=w")
+ [(set (match_operand:SVE_FULL_HSDI 0 "register_operand" "=w, ?&w")
(unspec:SVE_FULL_HSDI
- [(match_operand:<SVE_FULL_HSDI:VPRED> 1 "register_operand" "Upl")
+ [(match_operand:<SVE_FULL_HSDI:VPRED> 1 "register_operand" "Upl, Upl")
(match_operand:SI 3 "aarch64_sve_gp_strictness")
- (match_operand:SVE_FULL_F 2 "register_operand" "w")]
+ (match_operand:SVE_FULL_F 2 "register_operand" "0, w")]
SVE_COND_FCVTI))]
"TARGET_SVE && <SVE_FULL_HSDI:elem_bits> >= <SVE_FULL_F:elem_bits>"
- "fcvtz<su>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_F:Vetype>"
+ "@
+ fcvtz<su>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_F:Vetype>
+ movprfx\t%0, %2\;fcvtz<su>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_F:Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; 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")
+ [(set (match_operand:VNx4SI_ONLY 0 "register_operand" "=w, ?&w")
(unspec:VNx4SI_ONLY
- [(match_operand:VNx2BI 1 "register_operand" "Upl")
+ [(match_operand:VNx2BI 1 "register_operand" "Upl, Upl")
(match_operand:SI 3 "aarch64_sve_gp_strictness")
- (match_operand:VNx2DF_ONLY 2 "register_operand" "w")]
+ (match_operand:VNx2DF_ONLY 2 "register_operand" "0, w")]
SVE_COND_FCVTI))]
"TARGET_SVE"
- "fcvtz<su>\t%0.<VNx4SI_ONLY:Vetype>, %1/m, %2.<VNx2DF_ONLY:Vetype>"
+ "@
+ fcvtz<su>\t%0.<VNx4SI_ONLY:Vetype>, %1/m, %2.<VNx2DF_ONLY:Vetype>
+ movprfx\t%0, %2\;fcvtz<su>\t%0.<VNx4SI_ONLY:Vetype>, %1/m, %2.<VNx2DF_ONLY:Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; Predicated float-to-integer conversion with merging, either to the same
@@ -8719,26 +8783,32 @@
;; Predicated integer-to-float conversion, either to the same width or
;; narrower.
(define_insn "@aarch64_sve_<optab>_nonextend<SVE_FULL_HSDI:mode><SVE_FULL_F:mode>"
- [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w")
+ [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
(unspec:SVE_FULL_F
- [(match_operand:<SVE_FULL_HSDI:VPRED> 1 "register_operand" "Upl")
+ [(match_operand:<SVE_FULL_HSDI:VPRED> 1 "register_operand" "Upl, Upl")
(match_operand:SI 3 "aarch64_sve_gp_strictness")
- (match_operand:SVE_FULL_HSDI 2 "register_operand" "w")]
+ (match_operand:SVE_FULL_HSDI 2 "register_operand" "0, w")]
SVE_COND_ICVTF))]
"TARGET_SVE && <SVE_FULL_HSDI:elem_bits> >= <SVE_FULL_F:elem_bits>"
- "<su>cvtf\t%0.<SVE_FULL_F:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>"
+ "@
+ <su>cvtf\t%0.<SVE_FULL_F:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>
+ movprfx\t%0, %2\;<su>cvtf\t%0.<SVE_FULL_F:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; 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")
+ [(set (match_operand:VNx2DF_ONLY 0 "register_operand" "=w, ?&w")
(unspec:VNx2DF_ONLY
- [(match_operand:VNx2BI 1 "register_operand" "Upl")
+ [(match_operand:VNx2BI 1 "register_operand" "Upl, Upl")
(match_operand:SI 3 "aarch64_sve_gp_strictness")
- (match_operand:VNx4SI_ONLY 2 "register_operand" "w")]
+ (match_operand:VNx4SI_ONLY 2 "register_operand" "0, w")]
SVE_COND_ICVTF))]
"TARGET_SVE"
- "<su>cvtf\t%0.<VNx2DF_ONLY:Vetype>, %1/m, %2.<VNx4SI_ONLY:Vetype>"
+ "@
+ <su>cvtf\t%0.<VNx2DF_ONLY:Vetype>, %1/m, %2.<VNx4SI_ONLY:Vetype>
+ movprfx\t%0, %2\;<su>cvtf\t%0.<VNx2DF_ONLY:Vetype>, %1/m, %2.<VNx4SI_ONLY:Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; Predicated integer-to-float conversion with merging, either to the same
@@ -8911,14 +8981,17 @@
;; Predicated float-to-float truncation.
(define_insn "@aarch64_sve_<optab>_trunc<SVE_FULL_SDF:mode><SVE_FULL_HSF:mode>"
- [(set (match_operand:SVE_FULL_HSF 0 "register_operand" "=w")
+ [(set (match_operand:SVE_FULL_HSF 0 "register_operand" "=w, ?&w")
(unspec:SVE_FULL_HSF
- [(match_operand:<SVE_FULL_SDF:VPRED> 1 "register_operand" "Upl")
+ [(match_operand:<SVE_FULL_SDF:VPRED> 1 "register_operand" "Upl, Upl")
(match_operand:SI 3 "aarch64_sve_gp_strictness")
- (match_operand:SVE_FULL_SDF 2 "register_operand" "w")]
+ (match_operand:SVE_FULL_SDF 2 "register_operand" "0, w")]
SVE_COND_FCVT))]
"TARGET_SVE && <SVE_FULL_SDF:elem_bits> > <SVE_FULL_HSF:elem_bits>"
- "fcvt\t%0.<SVE_FULL_HSF:Vetype>, %1/m, %2.<SVE_FULL_SDF:Vetype>"
+ "@
+ fcvt\t%0.<SVE_FULL_HSF:Vetype>, %1/m, %2.<SVE_FULL_SDF:Vetype>
+ movprfx\t%0, %2\;fcvt\t%0.<SVE_FULL_HSF:Vetype>, %1/m, %2.<SVE_FULL_SDF:Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; Predicated float-to-float truncation with merging.
@@ -8965,14 +9038,17 @@
;; Predicated BFCVT.
(define_insn "@aarch64_sve_<optab>_trunc<VNx4SF_ONLY:mode><VNx8BF_ONLY:mode>"
- [(set (match_operand:VNx8BF_ONLY 0 "register_operand" "=w")
+ [(set (match_operand:VNx8BF_ONLY 0 "register_operand" "=w, ?&w")
(unspec:VNx8BF_ONLY
- [(match_operand:VNx4BI 1 "register_operand" "Upl")
+ [(match_operand:VNx4BI 1 "register_operand" "Upl, Upl")
(match_operand:SI 3 "aarch64_sve_gp_strictness")
- (match_operand:VNx4SF_ONLY 2 "register_operand" "w")]
+ (match_operand:VNx4SF_ONLY 2 "register_operand" "0, w")]
SVE_COND_FCVT))]
"TARGET_SVE_BF16"
- "bfcvt\t%0.h, %1/m, %2.s"
+ "@
+ bfcvt\t%0.h, %1/m, %2.s
+ movprfx\t%0, %2\;bfcvt\t%0.h, %1/m, %2.s"
+ [(set_attr "movprfx" "*,yes")]
)
;; Predicated BFCVT with merging.
@@ -9062,14 +9138,17 @@
;; Predicated float-to-float extension.
(define_insn "@aarch64_sve_<optab>_nontrunc<SVE_FULL_HSF:mode><SVE_FULL_SDF:mode>"
- [(set (match_operand:SVE_FULL_SDF 0 "register_operand" "=w")
+ [(set (match_operand:SVE_FULL_SDF 0 "register_operand" "=w, ?&w")
(unspec:SVE_FULL_SDF
- [(match_operand:<SVE_FULL_SDF:VPRED> 1 "register_operand" "Upl")
+ [(match_operand:<SVE_FULL_SDF:VPRED> 1 "register_operand" "Upl, Upl")
(match_operand:SI 3 "aarch64_sve_gp_strictness")
- (match_operand:SVE_FULL_HSF 2 "register_operand" "w")]
+ (match_operand:SVE_FULL_HSF 2 "register_operand" "0, w")]
SVE_COND_FCVT))]
"TARGET_SVE && <SVE_FULL_SDF:elem_bits> > <SVE_FULL_HSF:elem_bits>"
- "fcvt\t%0.<SVE_FULL_SDF:Vetype>, %1/m, %2.<SVE_FULL_HSF:Vetype>"
+ "@
+ fcvt\t%0.<SVE_FULL_SDF:Vetype>, %1/m, %2.<SVE_FULL_HSF:Vetype>
+ movprfx\t%0, %2\;fcvt\t%0.<SVE_FULL_SDF:Vetype>, %1/m, %2.<SVE_FULL_HSF:Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; Predicated float-to-float extension with merging.
diff --git a/gcc/config/aarch64/aarch64-sve2.md b/gcc/config/aarch64/aarch64-sve2.md
index 0cafd0b..772c350 100644
--- a/gcc/config/aarch64/aarch64-sve2.md
+++ b/gcc/config/aarch64/aarch64-sve2.md
@@ -786,17 +786,42 @@
;; -------------------------------------------------------------------------
;; Unpredicated exclusive OR of AND.
-(define_insn "@aarch64_sve2_bcax<mode>"
+(define_expand "@aarch64_sve2_bcax<mode>"
+ [(set (match_operand:SVE_FULL_I 0 "register_operand")
+ (xor:SVE_FULL_I
+ (and:SVE_FULL_I
+ (unspec:SVE_FULL_I
+ [(match_dup 4)
+ (not:SVE_FULL_I
+ (match_operand:SVE_FULL_I 3 "register_operand"))]
+ UNSPEC_PRED_X)
+ (match_operand:SVE_FULL_I 2 "register_operand"))
+ (match_operand:SVE_FULL_I 1 "register_operand")))]
+ "TARGET_SVE2"
+ {
+ operands[4] = CONSTM1_RTX (<VPRED>mode);
+ }
+)
+
+(define_insn_and_rewrite "*aarch64_sve2_bcax<mode>"
[(set (match_operand:SVE_FULL_I 0 "register_operand" "=w, ?&w")
(xor:SVE_FULL_I
(and:SVE_FULL_I
- (match_operand:SVE_FULL_I 2 "register_operand" "w, w")
- (match_operand:SVE_FULL_I 3 "register_operand" "w, w"))
+ (unspec:SVE_FULL_I
+ [(match_operand 4)
+ (not:SVE_FULL_I
+ (match_operand:SVE_FULL_I 3 "register_operand" "w, w"))]
+ UNSPEC_PRED_X)
+ (match_operand:SVE_FULL_I 2 "register_operand" "w, w"))
(match_operand:SVE_FULL_I 1 "register_operand" "0, w")))]
"TARGET_SVE2"
"@
bcax\t%0.d, %0.d, %2.d, %3.d
movprfx\t%0, %1\;bcax\t%0.d, %0.d, %2.d, %3.d"
+ "&& !CONSTANT_P (operands[4])"
+ {
+ operands[4] = CONSTM1_RTX (<VPRED>mode);
+ }
[(set_attr "movprfx" "*,yes")]
)
@@ -1868,10 +1893,10 @@
(unspec:SVE_FULL_SDF
[(match_operand:<VPRED> 1 "register_operand" "Upl")
(match_operand:SI 3 "aarch64_sve_gp_strictness")
- (match_operand:<VNARROW> 2 "register_operand" "w")]
+ (match_operand:<VNARROW> 2 "register_operand" "0")]
SVE2_COND_FP_UNARY_LONG))]
"TARGET_SVE2"
- "<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Ventype>"
+ "<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Ventype>"
)
;; Predicated convert long top with merging.
@@ -1953,14 +1978,17 @@
;; Predicated FCVTX (equivalent to what would be FCVTXNB, except that
;; it supports MOVPRFX).
(define_insn "@aarch64_pred_<sve_fp_op><mode>"
- [(set (match_operand:VNx4SF_ONLY 0 "register_operand" "=w")
+ [(set (match_operand:VNx4SF_ONLY 0 "register_operand" "=w, ?&w")
(unspec:VNx4SF_ONLY
- [(match_operand:<VWIDE_PRED> 1 "register_operand" "Upl")
+ [(match_operand:<VWIDE_PRED> 1 "register_operand" "Upl, Upl")
(match_operand:SI 3 "aarch64_sve_gp_strictness")
- (match_operand:<VWIDE> 2 "register_operand" "w")]
+ (match_operand:<VWIDE> 2 "register_operand" "0, w")]
SVE2_COND_FP_UNARY_NARROWB))]
"TARGET_SVE2"
- "<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vewtype>"
+ "@
+ <sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vewtype>
+ movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vewtype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; Predicated FCVTX with merging.
@@ -2051,15 +2079,18 @@
;; Predicated integer unary operations.
(define_insn "@aarch64_pred_<sve_int_op><mode>"
- [(set (match_operand:VNx4SI_ONLY 0 "register_operand" "=w")
+ [(set (match_operand:VNx4SI_ONLY 0 "register_operand" "=w, ?&w")
(unspec:VNx4SI_ONLY
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
(unspec:VNx4SI_ONLY
- [(match_operand:VNx4SI_ONLY 2 "register_operand" "w")]
+ [(match_operand:VNx4SI_ONLY 2 "register_operand" "0, w")]
SVE2_U32_UNARY)]
UNSPEC_PRED_X))]
"TARGET_SVE2"
- "<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ "@
+ <sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
+ movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; Predicated integer unary operations with merging.
@@ -2114,14 +2145,17 @@
;; Predicated FLOGB.
(define_insn "@aarch64_pred_<sve_fp_op><mode>"
- [(set (match_operand:<V_INT_EQUIV> 0 "register_operand" "=w")
+ [(set (match_operand:<V_INT_EQUIV> 0 "register_operand" "=w, ?&w")
(unspec:<V_INT_EQUIV>
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
(match_operand:SI 3 "aarch64_sve_gp_strictness")
- (match_operand:SVE_FULL_F 2 "register_operand" "w")]
+ (match_operand:SVE_FULL_F 2 "register_operand" "0, w")]
SVE2_COND_INT_UNARY_FP))]
"TARGET_SVE2"
- "<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ "@
+ <sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
+ movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; Predicated FLOGB with merging.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 97cb689..67ffba0 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1312,7 +1312,7 @@ static const struct tune_params thunderx3t110_tunings =
static const struct tune_params neoversen1_tunings =
{
- &cortexa57_extra_costs,
+ &cortexa76_extra_costs,
&generic_addrcost_table,
&generic_regmove_cost,
&cortexa57_vector_cost,
@@ -1338,7 +1338,7 @@ static const struct tune_params neoversen1_tunings =
static const struct tune_params neoversev1_tunings =
{
- &cortexa57_extra_costs,
+ &cortexa76_extra_costs,
&generic_addrcost_table,
&generic_regmove_cost,
&cortexa57_vector_cost,
@@ -1364,7 +1364,7 @@ static const struct tune_params neoversev1_tunings =
static const struct tune_params neoversen2_tunings =
{
- &cortexa57_extra_costs,
+ &cortexa76_extra_costs,
&generic_addrcost_table,
&generic_regmove_cost,
&cortexa57_vector_cost,
@@ -2985,7 +2985,7 @@ tls_symbolic_operand_type (rtx addr)
enum tls_model tls_kind = TLS_MODEL_NONE;
poly_int64 offset;
addr = strip_offset_and_salt (addr, &offset);
- if (GET_CODE (addr) == SYMBOL_REF)
+ if (SYMBOL_REF_P (addr))
tls_kind = SYMBOL_REF_TLS_MODEL (addr);
return tls_kind;
@@ -3126,7 +3126,7 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
/* The operand is expected to be MEM. Whenever the related insn
pattern changed, above code which calculate mem should be
updated. */
- gcc_assert (GET_CODE (mem) == MEM);
+ gcc_assert (MEM_P (mem));
MEM_READONLY_P (mem) = 1;
MEM_NOTRAP_P (mem) = 1;
emit_insn (insn);
@@ -3169,7 +3169,7 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
mem = XVECEXP (XEXP (SET_SRC (insn), 0), 0, 0);
}
- gcc_assert (GET_CODE (mem) == MEM);
+ gcc_assert (MEM_P (mem));
MEM_READONLY_P (mem) = 1;
MEM_NOTRAP_P (mem) = 1;
emit_insn (insn);
@@ -4235,7 +4235,7 @@ aarch64_internal_mov_immediate (rtx dest, rtx imm, bool generate,
bool
aarch64_mov128_immediate (rtx imm)
{
- if (GET_CODE (imm) == CONST_INT)
+ if (CONST_INT_P (imm))
return true;
gcc_assert (CONST_WIDE_INT_NUNITS (imm) == 2);
@@ -5099,8 +5099,8 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
/* Check on what type of symbol it is. */
scalar_int_mode int_mode;
- if ((GET_CODE (imm) == SYMBOL_REF
- || GET_CODE (imm) == LABEL_REF
+ if ((SYMBOL_REF_P (imm)
+ || LABEL_REF_P (imm)
|| GET_CODE (imm) == CONST
|| GET_CODE (imm) == CONST_POLY_INT)
&& is_a <scalar_int_mode> (mode, &int_mode))
@@ -5390,9 +5390,35 @@ bool
aarch64_maybe_expand_sve_subreg_move (rtx dest, rtx src)
{
gcc_assert (BYTES_BIG_ENDIAN);
- if (GET_CODE (dest) == SUBREG)
+
+ /* Do not try to optimize subregs that LRA has created for matched
+ reloads. These subregs only exist as a temporary measure to make
+ the RTL well-formed, but they are exempt from the usual
+ TARGET_CAN_CHANGE_MODE_CLASS rules.
+
+ For example, if we have:
+
+ (set (reg:VNx8HI R1) (foo:VNx8HI (reg:VNx4SI R2)))
+
+ and the constraints require R1 and R2 to be in the same register,
+ LRA may need to create RTL such as:
+
+ (set (subreg:VNx4SI (reg:VNx8HI TMP) 0) (reg:VNx4SI R2))
+ (set (reg:VNx8HI TMP) (foo:VNx8HI (subreg:VNx4SI (reg:VNx8HI TMP) 0)))
+ (set (reg:VNx8HI R1) (reg:VNx8HI TMP))
+
+ which forces both the input and output of the original instruction
+ to use the same hard register. But for this to work, the normal
+ rules have to be suppressed on the subreg input, otherwise LRA
+ would need to reload that input too, meaning that the process
+ would never terminate. To compensate for this, the normal rules
+ are also suppressed for the subreg output of the first move.
+ Ignoring the special case and handling the first move normally
+ would therefore generate wrong code: we would reverse the elements
+ for the first subreg but not reverse them back for the second subreg. */
+ if (SUBREG_P (dest) && !LRA_SUBREG_P (dest))
dest = SUBREG_REG (dest);
- if (GET_CODE (src) == SUBREG)
+ if (SUBREG_P (src) && !LRA_SUBREG_P (src))
src = SUBREG_REG (src);
/* The optimization handles two single SVE REGs with different element
@@ -7030,6 +7056,9 @@ aarch64_gen_store_pair (machine_mode mode, rtx mem1, rtx reg1, rtx mem2,
case E_V4SImode:
return gen_vec_store_pairv4siv4si (mem1, reg1, mem2, reg2);
+ case E_V16QImode:
+ return gen_vec_store_pairv16qiv16qi (mem1, reg1, mem2, reg2);
+
default:
gcc_unreachable ();
}
@@ -8533,7 +8562,7 @@ aarch64_tls_referenced_p (rtx x)
FOR_EACH_SUBRTX (iter, array, x, ALL)
{
const_rtx x = *iter;
- if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0)
+ if (SYMBOL_REF_P (x) && SYMBOL_REF_TLS_MODEL (x) != 0)
return true;
/* Don't recurse into UNSPEC_TLS looking for TLS symbols; these are
TLS offsets, not real symbol references. */
@@ -8759,7 +8788,7 @@ aarch64_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
poly_int64 offset;
rtx base = strip_offset_and_salt (x, &offset);
- if (GET_CODE (base) == SYMBOL_REF || GET_CODE (base) == LABEL_REF)
+ if (SYMBOL_REF_P (base) || LABEL_REF_P (base))
{
/* We checked for POLY_INT_CST offsets above. */
if (aarch64_classify_symbol (base, offset.to_constant ())
@@ -8845,7 +8874,7 @@ static bool
aarch64_base_register_rtx_p (rtx x, bool strict_p)
{
if (!strict_p
- && GET_CODE (x) == SUBREG
+ && SUBREG_P (x)
&& contains_reg_of_mode[GENERAL_REGS][GET_MODE (SUBREG_REG (x))])
x = SUBREG_REG (x);
@@ -8864,7 +8893,7 @@ aarch64_classify_index (struct aarch64_address_info *info, rtx x,
int shift;
/* (reg:P) */
- if ((REG_P (x) || GET_CODE (x) == SUBREG)
+ if ((REG_P (x) || SUBREG_P (x))
&& GET_MODE (x) == Pmode)
{
type = ADDRESS_REG_REG;
@@ -8962,7 +8991,7 @@ aarch64_classify_index (struct aarch64_address_info *info, rtx x,
return false;
if (!strict_p
- && GET_CODE (index) == SUBREG
+ && SUBREG_P (index)
&& contains_reg_of_mode[GENERAL_REGS][GET_MODE (SUBREG_REG (index))])
index = SUBREG_REG (index);
@@ -9258,8 +9287,8 @@ aarch64_classify_address (struct aarch64_address_info *info,
{
poly_int64 offset;
rtx sym = strip_offset_and_salt (x, &offset);
- return ((GET_CODE (sym) == LABEL_REF
- || (GET_CODE (sym) == SYMBOL_REF
+ return ((LABEL_REF_P (sym)
+ || (SYMBOL_REF_P (sym)
&& CONSTANT_POOL_ADDRESS_P (sym)
&& aarch64_pcrelative_literal_loads)));
}
@@ -9275,7 +9304,7 @@ aarch64_classify_address (struct aarch64_address_info *info,
poly_int64 offset;
HOST_WIDE_INT const_offset;
rtx sym = strip_offset_and_salt (info->offset, &offset);
- if (GET_CODE (sym) == SYMBOL_REF
+ if (SYMBOL_REF_P (sym)
&& offset.is_constant (&const_offset)
&& (aarch64_classify_symbol (sym, const_offset)
== SYMBOL_SMALL_ABSOLUTE))
@@ -9337,7 +9366,7 @@ aarch64_symbolic_address_p (rtx x)
{
poly_int64 offset;
x = strip_offset_and_salt (x, &offset);
- return GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF;
+ return SYMBOL_REF_P (x) || LABEL_REF_P (x);
}
/* Classify the base of symbolic expression X. */
@@ -9462,7 +9491,7 @@ aarch64_reinterpret_float_as_int (rtx value, unsigned HOST_WIDE_INT *intval)
}
scalar_float_mode mode;
- if (GET_CODE (value) != CONST_DOUBLE
+ if (!CONST_DOUBLE_P (value)
|| !is_a <scalar_float_mode> (GET_MODE (value), &mode)
|| GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT
/* Only support up to DF mode. */
@@ -9502,7 +9531,7 @@ aarch64_float_const_rtx_p (rtx x)
mov/movk pairs over ldr/adrp pairs. */
unsigned HOST_WIDE_INT ival;
- if (GET_CODE (x) == CONST_DOUBLE
+ if (CONST_DOUBLE_P (x)
&& SCALAR_FLOAT_MODE_P (mode)
&& aarch64_reinterpret_float_as_int (x, &ival))
{
@@ -9541,7 +9570,7 @@ aarch64_can_const_movi_rtx_p (rtx x, machine_mode mode)
scalar_int_mode imode;
unsigned HOST_WIDE_INT ival;
- if (GET_CODE (x) == CONST_DOUBLE
+ if (CONST_DOUBLE_P (x)
&& SCALAR_FLOAT_MODE_P (mode))
{
if (!aarch64_reinterpret_float_as_int (x, &ival))
@@ -9553,7 +9582,7 @@ aarch64_can_const_movi_rtx_p (rtx x, machine_mode mode)
imode = int_mode_for_mode (mode).require ();
}
- else if (GET_CODE (x) == CONST_INT
+ else if (CONST_INT_P (x)
&& is_a <scalar_int_mode> (mode, &imode))
ival = INTVAL (x);
else
@@ -9704,7 +9733,7 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y)
the comparison will have to be swapped when we emit the assembly
code. */
if ((mode_x == SImode || mode_x == DImode)
- && (REG_P (y) || GET_CODE (y) == SUBREG || y == const0_rtx)
+ && (REG_P (y) || SUBREG_P (y) || y == const0_rtx)
&& (code_x == ASHIFT || code_x == ASHIFTRT
|| code_x == LSHIFTRT
|| code_x == ZERO_EXTEND || code_x == SIGN_EXTEND))
@@ -9713,7 +9742,7 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y)
/* Similarly for a negated operand, but we can only do this for
equalities. */
if ((mode_x == SImode || mode_x == DImode)
- && (REG_P (y) || GET_CODE (y) == SUBREG)
+ && (REG_P (y) || SUBREG_P (y))
&& (code == EQ || code == NE)
&& code_x == NEG)
return CC_Zmode;
@@ -10507,7 +10536,7 @@ aarch64_print_operand (FILE *f, rtx x, int code)
{
machine_mode mode = GET_MODE (x);
- if (GET_CODE (x) != MEM
+ if (!MEM_P (x)
|| (code == 'y' && maybe_ne (GET_MODE_SIZE (mode), 16)))
{
output_operand_lossage ("invalid operand for '%%%c'", code);
@@ -10670,7 +10699,7 @@ aarch64_label_mentioned_p (rtx x)
const char *fmt;
int i;
- if (GET_CODE (x) == LABEL_REF)
+ if (LABEL_REF_P (x))
return true;
/* UNSPEC_TLS entries for a symbol include a LABEL_REF for the
@@ -10852,7 +10881,7 @@ aarch64_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x,
/* If we have to disable direct literal pool loads and stores because the
function is too big, then we need a scratch register. */
- if (MEM_P (x) && GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x)
+ if (MEM_P (x) && SYMBOL_REF_P (x) && CONSTANT_POOL_ADDRESS_P (x)
&& (SCALAR_FLOAT_MODE_P (GET_MODE (x))
|| targetm.vector_mode_supported_p (GET_MODE (x)))
&& !aarch64_pcrelative_literal_loads)
@@ -11008,10 +11037,10 @@ aarch64_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
/* XXX We should really define a "clear_cache" pattern and use
gen_clear_cache(). */
a_tramp = XEXP (m_tramp, 0);
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"),
- LCT_NORMAL, VOIDmode, a_tramp, ptr_mode,
- plus_constant (ptr_mode, a_tramp, TRAMPOLINE_SIZE),
- ptr_mode);
+ maybe_emit_call_builtin___clear_cache (a_tramp,
+ plus_constant (ptr_mode,
+ a_tramp,
+ TRAMPOLINE_SIZE));
}
static unsigned char
@@ -11083,7 +11112,7 @@ aarch64_preferred_reload_class (rtx x, reg_class_t regclass)
rtx lhs = XEXP (x, 0);
/* Look through a possible SUBREG introduced by ILP32. */
- if (GET_CODE (lhs) == SUBREG)
+ if (SUBREG_P (lhs))
lhs = SUBREG_REG (lhs);
gcc_assert (REG_P (lhs));
@@ -11543,7 +11572,7 @@ aarch64_address_cost (rtx x,
if (!aarch64_classify_address (&info, x, mode, false))
{
- if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF)
+ if (GET_CODE (x) == CONST || SYMBOL_REF_P (x))
{
/* This is a CONST or SYMBOL ref which will be split
in a different way depending on the code model in use.
@@ -14413,6 +14442,12 @@ aarch64_override_options_internal (struct gcc_options *opts)
SET_OPTION_IF_UNSET (opts, &global_options_set,
param_sched_autopref_queue_depth, queue_depth);
+ /* If using Advanced SIMD only for autovectorization disable SVE vector costs
+ comparison. */
+ if (aarch64_autovec_preference == 1)
+ SET_OPTION_IF_UNSET (opts, &global_options_set,
+ aarch64_sve_compare_costs, 0);
+
/* Set up parameters to be used in prefetching algorithm. Do not
override the defaults unless we are tuning for a core we have
researched values for. */
@@ -15944,7 +15979,7 @@ aarch64_tls_symbol_p (rtx x)
return false;
x = strip_salt (x);
- if (GET_CODE (x) != SYMBOL_REF)
+ if (!SYMBOL_REF_P (x))
return false;
return SYMBOL_REF_TLS_MODEL (x) != 0;
@@ -16001,7 +16036,7 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset)
{
x = strip_salt (x);
- if (GET_CODE (x) == LABEL_REF)
+ if (LABEL_REF_P (x))
{
switch (aarch64_cmodel)
{
@@ -16022,7 +16057,7 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset)
}
}
- if (GET_CODE (x) == SYMBOL_REF)
+ if (SYMBOL_REF_P (x))
{
if (aarch64_tls_symbol_p (x))
return aarch64_classify_tls_symbol (x);
@@ -16102,7 +16137,7 @@ aarch64_legitimate_pic_operand_p (rtx x)
{
poly_int64 offset;
x = strip_offset_and_salt (x, &offset);
- if (GET_CODE (x) == SYMBOL_REF)
+ if (SYMBOL_REF_P (x))
return false;
return true;
@@ -16163,7 +16198,7 @@ aarch64_legitimate_constant_p (machine_mode mode, rtx x)
return true;
/* Label references are always constant. */
- if (GET_CODE (x) == LABEL_REF)
+ if (LABEL_REF_P (x))
return true;
return false;
@@ -17253,11 +17288,65 @@ aarch64_simd_container_mode (scalar_mode mode, poly_int64 width)
return word_mode;
}
+static HOST_WIDE_INT aarch64_estimated_poly_value (poly_int64);
+
+/* Compare an SVE mode SVE_M and an Advanced SIMD mode ASIMD_M
+ and return whether the SVE mode should be preferred over the
+ Advanced SIMD one in aarch64_autovectorize_vector_modes. */
+static bool
+aarch64_cmp_autovec_modes (machine_mode sve_m, machine_mode asimd_m)
+{
+ /* Take into account the aarch64-autovec-preference param if non-zero. */
+ bool only_asimd_p = aarch64_autovec_preference == 1;
+ bool only_sve_p = aarch64_autovec_preference == 2;
+
+ if (only_asimd_p)
+ return false;
+ if (only_sve_p)
+ return true;
+
+ /* The preference in case of a tie in costs. */
+ bool prefer_asimd = aarch64_autovec_preference == 3;
+ bool prefer_sve = aarch64_autovec_preference == 4;
+
+ aarch64_sve_vector_bits_enum tune_width = aarch64_tune_params.sve_width;
+
+ poly_int64 nunits_sve = GET_MODE_NUNITS (sve_m);
+ poly_int64 nunits_asimd = GET_MODE_NUNITS (asimd_m);
+ /* If the CPU information does not have an SVE width registered use the
+ generic poly_int comparison that prefers SVE. If a preference is
+ explicitly requested avoid this path. */
+ if (tune_width == SVE_SCALABLE
+ && !prefer_asimd
+ && !prefer_sve)
+ return maybe_gt (nunits_sve, nunits_asimd);
+
+ /* Otherwise estimate the runtime width of the modes involved. */
+ HOST_WIDE_INT est_sve = aarch64_estimated_poly_value (nunits_sve);
+ HOST_WIDE_INT est_asimd = aarch64_estimated_poly_value (nunits_asimd);
+
+ /* Preferring SVE means picking it first unless the Advanced SIMD mode
+ is clearly wider. */
+ if (prefer_sve)
+ return est_sve >= est_asimd;
+ /* Conversely, preferring Advanced SIMD means picking SVE only if SVE
+ is clearly wider. */
+ if (prefer_asimd)
+ return est_sve > est_asimd;
+
+ /* In the default case prefer Advanced SIMD over SVE in case of a tie. */
+ return est_sve > est_asimd;
+}
+
/* Return 128-bit container as the preferred SIMD mode for MODE. */
static machine_mode
aarch64_preferred_simd_mode (scalar_mode mode)
{
- poly_int64 bits = TARGET_SVE ? BITS_PER_SVE_VECTOR : 128;
+ /* Take into account explicit auto-vectorization ISA preferences through
+ aarch64_cmp_autovec_modes. */
+ poly_int64 bits
+ = (TARGET_SVE && aarch64_cmp_autovec_modes (VNx16QImode, V16QImode))
+ ? BITS_PER_SVE_VECTOR : 128;
return aarch64_simd_container_mode (mode, bits);
}
@@ -17319,19 +17408,24 @@ aarch64_autovectorize_vector_modes (vector_modes *modes, bool)
- If an Advanced SIMD main loop with N bytes ends up being cheaper
than an SVE main loop with N bytes then by default we'll try to
use the SVE loop to vectorize the epilogue instead. */
- unsigned int sve_i = TARGET_SVE ? 0 : ARRAY_SIZE (sve_modes);
+
+ bool only_asimd_p = aarch64_autovec_preference == 1;
+ bool only_sve_p = aarch64_autovec_preference == 2;
+
+ unsigned int sve_i = (TARGET_SVE && !only_asimd_p) ? 0 : ARRAY_SIZE (sve_modes);
unsigned int advsimd_i = 0;
- while (advsimd_i < ARRAY_SIZE (advsimd_modes))
+
+ while (!only_sve_p && advsimd_i < ARRAY_SIZE (advsimd_modes))
{
if (sve_i < ARRAY_SIZE (sve_modes)
- && maybe_gt (GET_MODE_NUNITS (sve_modes[sve_i]),
- GET_MODE_NUNITS (advsimd_modes[advsimd_i])))
+ && aarch64_cmp_autovec_modes (sve_modes[sve_i],
+ advsimd_modes[advsimd_i]))
modes->safe_push (sve_modes[sve_i++]);
else
modes->safe_push (advsimd_modes[advsimd_i++]);
}
while (sve_i < ARRAY_SIZE (sve_modes))
- modes->safe_push (sve_modes[sve_i++]);
+ modes->safe_push (sve_modes[sve_i++]);
unsigned int flags = 0;
/* Consider enabling VECT_COMPARE_COSTS for SVE, both so that we
@@ -17606,7 +17700,7 @@ aarch64_sve_float_arith_immediate_p (rtx x, bool negate_p)
REAL_VALUE_TYPE r;
if (!const_vec_duplicate_p (x, &elt)
- || GET_CODE (elt) != CONST_DOUBLE)
+ || !CONST_DOUBLE_P (elt))
return false;
r = *CONST_DOUBLE_REAL_VALUE (elt);
@@ -17630,7 +17724,7 @@ aarch64_sve_float_mul_immediate_p (rtx x)
rtx elt;
return (const_vec_duplicate_p (x, &elt)
- && GET_CODE (elt) == CONST_DOUBLE
+ && CONST_DOUBLE_P (elt)
&& (real_equal (CONST_DOUBLE_REAL_VALUE (elt), &dconsthalf)
|| real_equal (CONST_DOUBLE_REAL_VALUE (elt), &dconst2)));
}
@@ -18049,7 +18143,7 @@ aarch64_mov_operand_p (rtx x, machine_mode mode)
}
x = strip_salt (x);
- if (GET_CODE (x) == SYMBOL_REF && mode == DImode && CONSTANT_ADDRESS_P (x))
+ if (SYMBOL_REF_P (x) && mode == DImode && CONSTANT_ADDRESS_P (x))
return true;
if (TARGET_SVE && aarch64_sve_cnt_immediate_p (x))
@@ -21197,35 +21291,39 @@ aarch64_copy_one_block_and_progress_pointers (rtx *src, rtx *dst,
bool
aarch64_expand_cpymem (rtx *operands)
{
- /* These need to be signed as we need to perform arithmetic on n as
- signed operations. */
- int n, mode_bits;
+ int mode_bits;
rtx dst = operands[0];
rtx src = operands[1];
rtx base;
- machine_mode cur_mode = BLKmode, next_mode;
- bool speed_p = !optimize_function_for_size_p (cfun);
-
- /* When optimizing for size, give a better estimate of the length of a
- memcpy call, but use the default otherwise. Moves larger than 8 bytes
- will always require an even number of instructions to do now. And each
- operation requires both a load+store, so divide the max number by 2. */
- unsigned int max_num_moves = (speed_p ? 16 : AARCH64_CALL_RATIO) / 2;
+ machine_mode cur_mode = BLKmode;
- /* We can't do anything smart if the amount to copy is not constant. */
+ /* Only expand fixed-size copies. */
if (!CONST_INT_P (operands[2]))
return false;
- unsigned HOST_WIDE_INT tmp = INTVAL (operands[2]);
+ unsigned HOST_WIDE_INT size = INTVAL (operands[2]);
- /* Try to keep the number of instructions low. For all cases we will do at
- most two moves for the residual amount, since we'll always overlap the
- remainder. */
- if (((tmp / 16) + (tmp % 16 ? 2 : 0)) > max_num_moves)
- return false;
+ /* Inline up to 256 bytes when optimizing for speed. */
+ unsigned HOST_WIDE_INT max_copy_size = 256;
+
+ if (optimize_function_for_size_p (cfun))
+ max_copy_size = 128;
+
+ int copy_bits = 256;
+
+ /* Default to 256-bit LDP/STP on large copies, however small copies, no SIMD
+ support or slow 256-bit LDP/STP fall back to 128-bit chunks. */
+ if (size <= 24
+ || !TARGET_SIMD
+ || (aarch64_tune_params.extra_tuning_flags
+ & AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS))
+ {
+ copy_bits = 128;
+ max_copy_size = max_copy_size / 2;
+ }
- /* At this point tmp is known to have to fit inside an int. */
- n = tmp;
+ if (size > max_copy_size)
+ return false;
base = copy_to_mode_reg (Pmode, XEXP (dst, 0));
dst = adjust_automodify_address (dst, VOIDmode, base, 0);
@@ -21233,15 +21331,8 @@ aarch64_expand_cpymem (rtx *operands)
base = copy_to_mode_reg (Pmode, XEXP (src, 0));
src = adjust_automodify_address (src, VOIDmode, base, 0);
- /* Convert n to bits to make the rest of the code simpler. */
- n = n * BITS_PER_UNIT;
-
- /* Maximum amount to copy in one go. We allow 256-bit chunks based on the
- AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS tuning parameter and TARGET_SIMD. */
- const int copy_limit = ((aarch64_tune_params.extra_tuning_flags
- & AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS)
- || !TARGET_SIMD)
- ? GET_MODE_BITSIZE (TImode) : 256;
+ /* Convert size to bits to make the rest of the code simpler. */
+ int n = size * BITS_PER_UNIT;
while (n > 0)
{
@@ -21249,25 +21340,157 @@ aarch64_expand_cpymem (rtx *operands)
or writing. */
opt_scalar_int_mode mode_iter;
FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
- if (GET_MODE_BITSIZE (mode_iter.require ()) <= MIN (n, copy_limit))
+ if (GET_MODE_BITSIZE (mode_iter.require ()) <= MIN (n, copy_bits))
cur_mode = mode_iter.require ();
gcc_assert (cur_mode != BLKmode);
mode_bits = GET_MODE_BITSIZE (cur_mode).to_constant ();
+
+ /* Prefer Q-register accesses for the last bytes. */
+ if (mode_bits == 128 && copy_bits == 256)
+ cur_mode = V4SImode;
+
aarch64_copy_one_block_and_progress_pointers (&src, &dst, cur_mode);
n -= mode_bits;
+ /* Emit trailing copies using overlapping unaligned accesses - this is
+ smaller and faster. */
+ if (n > 0 && n < copy_bits / 2)
+ {
+ machine_mode next_mode = smallest_mode_for_size (n, MODE_INT);
+ int n_bits = GET_MODE_BITSIZE (next_mode).to_constant ();
+ gcc_assert (n_bits <= mode_bits);
+ src = aarch64_move_pointer (src, (n - n_bits) / BITS_PER_UNIT);
+ dst = aarch64_move_pointer (dst, (n - n_bits) / BITS_PER_UNIT);
+ n = n_bits;
+ }
+ }
+
+ return true;
+}
+
+/* Like aarch64_copy_one_block_and_progress_pointers, except for memset where
+ SRC is a register we have created with the duplicated value to be set. */
+static void
+aarch64_set_one_block_and_progress_pointer (rtx src, rtx *dst,
+ machine_mode mode)
+{
+ /* If we are copying 128bits or 256bits, we can do that straight from
+ the SIMD register we prepared. */
+ if (known_eq (GET_MODE_BITSIZE (mode), 256))
+ {
+ mode = GET_MODE (src);
+ /* "Cast" the *dst to the correct mode. */
+ *dst = adjust_address (*dst, mode, 0);
+ /* Emit the memset. */
+ emit_insn (aarch64_gen_store_pair (mode, *dst, src,
+ aarch64_progress_pointer (*dst), src));
+
+ /* Move the pointers forward. */
+ *dst = aarch64_move_pointer (*dst, 32);
+ return;
+ }
+ if (known_eq (GET_MODE_BITSIZE (mode), 128))
+ {
+ /* "Cast" the *dst to the correct mode. */
+ *dst = adjust_address (*dst, GET_MODE (src), 0);
+ /* Emit the memset. */
+ emit_move_insn (*dst, src);
+ /* Move the pointers forward. */
+ *dst = aarch64_move_pointer (*dst, 16);
+ return;
+ }
+ /* For copying less, we have to extract the right amount from src. */
+ rtx reg = lowpart_subreg (mode, src, GET_MODE (src));
+
+ /* "Cast" the *dst to the correct mode. */
+ *dst = adjust_address (*dst, mode, 0);
+ /* Emit the memset. */
+ emit_move_insn (*dst, reg);
+ /* Move the pointer forward. */
+ *dst = aarch64_progress_pointer (*dst);
+}
+
+/* Expand setmem, as if from a __builtin_memset. Return true if
+ we succeed, otherwise return false. */
+
+bool
+aarch64_expand_setmem (rtx *operands)
+{
+ int n, mode_bits;
+ unsigned HOST_WIDE_INT len;
+ rtx dst = operands[0];
+ rtx val = operands[2], src;
+ rtx base;
+ machine_mode cur_mode = BLKmode, next_mode;
+
+ /* We can't do anything smart if the amount to copy is not constant. */
+ if (!CONST_INT_P (operands[1]))
+ return false;
+
+ bool speed_p = !optimize_function_for_size_p (cfun);
+
+ /* Default the maximum to 256-bytes. */
+ unsigned max_set_size = 256;
+
+ /* In case we are optimizing for size or if the core does not
+ want to use STP Q regs, lower the max_set_size. */
+ max_set_size = (!speed_p
+ || (aarch64_tune_params.extra_tuning_flags
+ & AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS))
+ ? max_set_size / 2 : max_set_size;
+
+ len = INTVAL (operands[1]);
+
+ /* Upper bound check. */
+ if (len > max_set_size)
+ return false;
+
+ base = copy_to_mode_reg (Pmode, XEXP (dst, 0));
+ dst = adjust_automodify_address (dst, VOIDmode, base, 0);
+
+ /* Prepare the val using a DUP/MOVI v0.16B, val. */
+ src = expand_vector_broadcast (V16QImode, val);
+ src = force_reg (V16QImode, src);
+
+ /* Convert len to bits to make the rest of the code simpler. */
+ n = len * BITS_PER_UNIT;
+
+ /* Maximum amount to copy in one go. We allow 256-bit chunks based on the
+ AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS tuning parameter. setmem expand
+ pattern is only turned on for TARGET_SIMD. */
+ const int copy_limit = (speed_p
+ && (aarch64_tune_params.extra_tuning_flags
+ & AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS))
+ ? GET_MODE_BITSIZE (TImode) : 256;
+
+ while (n > 0)
+ {
+ /* Find the largest mode in which to do the copy without
+ over writing. */
+ opt_scalar_int_mode mode_iter;
+ FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
+ if (GET_MODE_BITSIZE (mode_iter.require ()) <= MIN (n, copy_limit))
+ cur_mode = mode_iter.require ();
+
+ gcc_assert (cur_mode != BLKmode);
+
+ mode_bits = GET_MODE_BITSIZE (cur_mode).to_constant ();
+ aarch64_set_one_block_and_progress_pointer (src, &dst, cur_mode);
+
+ n -= mode_bits;
+
/* Do certain trailing copies as overlapping if it's going to be
cheaper. i.e. less instructions to do so. For instance doing a 15
byte copy it's more efficient to do two overlapping 8 byte copies than
- 8 + 6 + 1. */
- if (n > 0 && n <= 8 * BITS_PER_UNIT)
+ 8 + 4 + 2 + 1. */
+ if (n > 0 && n < copy_limit / 2)
{
next_mode = smallest_mode_for_size (n, MODE_INT);
int n_bits = GET_MODE_BITSIZE (next_mode).to_constant ();
- src = aarch64_move_pointer (src, (n - n_bits) / BITS_PER_UNIT);
+ gcc_assert (n_bits <= mode_bits);
dst = aarch64_move_pointer (dst, (n - n_bits) / BITS_PER_UNIT);
n = n_bits;
}
@@ -21276,6 +21499,7 @@ aarch64_expand_cpymem (rtx *operands)
return true;
}
+
/* Split a DImode store of a CONST_INT SRC to MEM DST as two
SImode stores. Handle the case when the constant has identical
bottom and top halves. This is beneficial when the two stores can be
@@ -21951,20 +22175,20 @@ fusion_load_store (rtx_insn *insn, rtx *base, rtx *offset)
{
fusion = SCHED_FUSION_LD_SIGN_EXTEND;
src = XEXP (src, 0);
- if (GET_CODE (src) != MEM || GET_MODE (src) != SImode)
+ if (!MEM_P (src) || GET_MODE (src) != SImode)
return SCHED_FUSION_NONE;
}
else if (GET_CODE (src) == ZERO_EXTEND)
{
fusion = SCHED_FUSION_LD_ZERO_EXTEND;
src = XEXP (src, 0);
- if (GET_CODE (src) != MEM || GET_MODE (src) != SImode)
+ if (!MEM_P (src) || GET_MODE (src) != SImode)
return SCHED_FUSION_NONE;
}
- if (GET_CODE (src) == MEM && REG_P (dest))
+ if (MEM_P (src) && REG_P (dest))
extract_base_offset_in_addr (src, base, offset);
- else if (GET_CODE (dest) == MEM && (REG_P (src) || src == const0_rtx))
+ else if (MEM_P (dest) && (REG_P (src) || src == const0_rtx))
{
fusion = SCHED_FUSION_ST;
extract_base_offset_in_addr (dest, base, offset);
@@ -23162,6 +23386,15 @@ aarch64_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1,
return NULL;
}
+/* Implement TARGET_MEMTAG_CAN_TAG_ADDRESSES. Here we tell the rest of the
+ compiler that we automatically ignore the top byte of our pointers, which
+ allows using -fsanitize=hwaddress. */
+bool
+aarch64_can_tag_addresses ()
+{
+ return !TARGET_ILP32;
+}
+
/* Implement TARGET_ASM_FILE_END for AArch64. This adds the AArch64 GNU NOTE
section at the end if needed. */
#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000
@@ -23981,6 +24214,9 @@ aarch64_libgcc_floating_mode_supported_p
#undef TARGET_FNTYPE_ABI
#define TARGET_FNTYPE_ABI aarch64_fntype_abi
+#undef TARGET_MEMTAG_CAN_TAG_ADDRESSES
+#define TARGET_MEMTAG_CAN_TAG_ADDRESSES aarch64_can_tag_addresses
+
#if CHECKING_P
#undef TARGET_RUN_TARGET_SELFTESTS
#define TARGET_RUN_TARGET_SELFTESTS selftest::aarch64_run_selftests
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 00b5f84..0bdcc74 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -224,6 +224,9 @@ extern unsigned aarch64_architecture_version;
/* 64-bit Floating-point Matrix Multiply (F64MM) extensions. */
#define AARCH64_FL_F64MM (1ULL << 38)
+/* Flag Manipulation Instructions (FLAGM) extension. */
+#define AARCH64_FL_FLAGM (1ULL << 39)
+
/* Has FP and SIMD. */
#define AARCH64_FL_FPSIMD (AARCH64_FL_FP | AARCH64_FL_SIMD)
@@ -241,7 +244,7 @@ extern unsigned aarch64_architecture_version;
(AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_V8_3)
#define AARCH64_FL_FOR_ARCH8_4 \
(AARCH64_FL_FOR_ARCH8_3 | AARCH64_FL_V8_4 | AARCH64_FL_F16FML \
- | AARCH64_FL_DOTPROD | AARCH64_FL_RCPC8_4)
+ | AARCH64_FL_DOTPROD | AARCH64_FL_RCPC8_4 | AARCH64_FL_FLAGM)
#define AARCH64_FL_FOR_ARCH8_5 \
(AARCH64_FL_FOR_ARCH8_4 | AARCH64_FL_V8_5 \
| AARCH64_FL_SB | AARCH64_FL_SSBS | AARCH64_FL_PREDRES)
@@ -1024,16 +1027,19 @@ typedef struct
#define MOVE_RATIO(speed) \
(!STRICT_ALIGNMENT ? 2 : (((speed) ? 15 : AARCH64_CALL_RATIO) / 2))
-/* For CLEAR_RATIO, when optimizing for size, give a better estimate
- of the length of a memset call, but use the default otherwise. */
+/* Like MOVE_RATIO, without -mstrict-align, make decisions in "setmem" when
+ we would use more than 3 scalar instructions.
+ Otherwise follow a sensible default: when optimizing for size, give a better
+ estimate of the length of a memset call, but use the default otherwise. */
#define CLEAR_RATIO(speed) \
- ((speed) ? 15 : AARCH64_CALL_RATIO)
+ (!STRICT_ALIGNMENT ? 4 : (speed) ? 15 : AARCH64_CALL_RATIO)
-/* SET_RATIO is similar to CLEAR_RATIO, but for a non-zero constant, so when
- optimizing for size adjust the ratio to account for the overhead of loading
- the constant. */
+/* SET_RATIO is similar to CLEAR_RATIO, but for a non-zero constant. Without
+ -mstrict-align, make decisions in "setmem". Otherwise follow a sensible
+ default: when optimizing for size adjust the ratio to account for the
+ overhead of loading the constant. */
#define SET_RATIO(speed) \
- ((speed) ? 15 : AARCH64_CALL_RATIO - 2)
+ (!STRICT_ALIGNMENT ? 0 : (speed) ? 15 : AARCH64_CALL_RATIO - 2)
/* Disable auto-increment in move_by_pieces et al. Use of auto-increment is
rarely a good idea in straight-line code since it adds an extra address
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 11e0f46..eed06de 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -1571,6 +1571,24 @@
}
)
+;; 0 is dst
+;; 1 is val
+;; 2 is size of copy in bytes
+;; 3 is alignment
+
+(define_expand "setmemdi"
+ [(set (match_operand:BLK 0 "memory_operand") ;; Dest
+ (match_operand:QI 2 "nonmemory_operand")) ;; Value
+ (use (match_operand:DI 1 "immediate_operand")) ;; Length
+ (match_operand 3 "immediate_operand")] ;; Align
+ "TARGET_SIMD"
+{
+ if (aarch64_expand_setmem (operands))
+ DONE;
+
+ FAIL;
+})
+
;; Operands 1 and 3 are tied together by the final condition; so we allow
;; fairly lax checking on the second memory operation.
(define_insn "load_pair_sw_<SX:mode><SX2:mode>"
diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
index 5170361..1b3d942 100644
--- a/gcc/config/aarch64/aarch64.opt
+++ b/gcc/config/aarch64/aarch64.opt
@@ -275,3 +275,5 @@ The number of Newton iterations for calculating the reciprocal for float type.
Target Joined UInteger Var(aarch64_double_recp_precision) Init(2) IntegerRange(1, 5) Param
The number of Newton iterations for calculating the reciprocal for double type. The precision of division is proportional to this param when division approximation is enabled. The default value is 2.
+-param=aarch64-autovec-preference=
+Target Joined UInteger Var(aarch64_autovec_preference) Init(0) IntegerRange(0, 4) Param
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 2a7b1fb..eabc122 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -4418,10 +4418,10 @@ arc_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
emit_move_insn (adjust_address (tramp, SImode, 8), fnaddr);
emit_move_insn (adjust_address (tramp, SImode, 12), cxt);
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"),
- LCT_NORMAL, VOIDmode, XEXP (tramp, 0), Pmode,
- plus_constant (Pmode, XEXP (tramp, 0), TRAMPOLINE_SIZE),
- Pmode);
+ maybe_emit_call_builtin___clear_cache (XEXP (tramp, 0),
+ plus_constant (Pmode,
+ XEXP (tramp, 0),
+ TRAMPOLINE_SIZE));
}
/* Add the given function declaration to emit code in JLI section. */
diff --git a/gcc/config/arm/aarch-common.c b/gcc/config/arm/aarch-common.c
index 6bc6ccf..e7b13f0 100644
--- a/gcc/config/arm/aarch-common.c
+++ b/gcc/config/arm/aarch-common.c
@@ -485,7 +485,7 @@ aarch_accumulator_forwarding (rtx_insn *producer, rtx_insn *consumer)
return 0;
}
- if (GET_CODE (accumulator) == SUBREG)
+ if (SUBREG_P (accumulator))
accumulator = SUBREG_REG (accumulator);
if (!REG_P (accumulator))
diff --git a/gcc/config/arm/aarch-cost-tables.h b/gcc/config/arm/aarch-cost-tables.h
index cf81865..1b9d53d 100644
--- a/gcc/config/arm/aarch-cost-tables.h
+++ b/gcc/config/arm/aarch-cost-tables.h
@@ -331,6 +331,109 @@ const struct cpu_cost_table cortexa57_extra_costs =
}
};
+const struct cpu_cost_table cortexa76_extra_costs =
+{
+ /* ALU */
+ {
+ 0, /* arith. */
+ 0, /* logical. */
+ 0, /* shift. */
+ 0, /* shift_reg. */
+ COSTS_N_INSNS (1), /* arith_shift. */
+ COSTS_N_INSNS (1), /* arith_shift_reg. */
+ 0, /* log_shift. */
+ COSTS_N_INSNS (1), /* log_shift_reg. */
+ 0, /* extend. */
+ COSTS_N_INSNS (1), /* extend_arith. */
+ COSTS_N_INSNS (1), /* bfi. */
+ 0, /* bfx. */
+ 0, /* clz. */
+ 0, /* rev. */
+ 0, /* non_exec. */
+ true /* non_exec_costs_exec. */
+ },
+ {
+ /* MULT SImode */
+ {
+ COSTS_N_INSNS (1), /* simple. */
+ COSTS_N_INSNS (2), /* flag_setting. */
+ COSTS_N_INSNS (1), /* extend. */
+ COSTS_N_INSNS (1), /* add. */
+ COSTS_N_INSNS (1), /* extend_add. */
+ COSTS_N_INSNS (6) /* idiv. */
+ },
+ /* MULT DImode */
+ {
+ COSTS_N_INSNS (3), /* simple. */
+ 0, /* flag_setting (N/A). */
+ COSTS_N_INSNS (1), /* extend. */
+ COSTS_N_INSNS (3), /* add. */
+ COSTS_N_INSNS (1), /* extend_add. */
+ COSTS_N_INSNS (10) /* idiv. */
+ }
+ },
+ /* LD/ST */
+ {
+ COSTS_N_INSNS (3), /* load. */
+ COSTS_N_INSNS (3), /* load_sign_extend. */
+ COSTS_N_INSNS (3), /* ldrd. */
+ COSTS_N_INSNS (2), /* ldm_1st. */
+ 1, /* ldm_regs_per_insn_1st. */
+ 2, /* ldm_regs_per_insn_subsequent. */
+ COSTS_N_INSNS (4), /* loadf. */
+ COSTS_N_INSNS (4), /* loadd. */
+ COSTS_N_INSNS (5), /* load_unaligned. */
+ 0, /* store. */
+ 0, /* strd. */
+ 0, /* stm_1st. */
+ 1, /* stm_regs_per_insn_1st. */
+ 2, /* stm_regs_per_insn_subsequent. */
+ 0, /* storef. */
+ 0, /* stored. */
+ COSTS_N_INSNS (1), /* store_unaligned. */
+ COSTS_N_INSNS (1), /* loadv. */
+ COSTS_N_INSNS (1) /* storev. */
+ },
+ {
+ /* FP SFmode */
+ {
+ COSTS_N_INSNS (10), /* div. */
+ COSTS_N_INSNS (2), /* mult. */
+ COSTS_N_INSNS (3), /* mult_addsub. */
+ COSTS_N_INSNS (3), /* fma. */
+ COSTS_N_INSNS (1), /* addsub. */
+ 0, /* fpconst. */
+ 0, /* neg. */
+ 0, /* compare. */
+ COSTS_N_INSNS (1), /* widen. */
+ COSTS_N_INSNS (1), /* narrow. */
+ COSTS_N_INSNS (1), /* toint. */
+ COSTS_N_INSNS (1), /* fromint. */
+ COSTS_N_INSNS (1) /* roundint. */
+ },
+ /* FP DFmode */
+ {
+ COSTS_N_INSNS (15), /* div. */
+ COSTS_N_INSNS (2), /* mult. */
+ COSTS_N_INSNS (3), /* mult_addsub. */
+ COSTS_N_INSNS (3), /* fma. */
+ COSTS_N_INSNS (1), /* addsub. */
+ 0, /* fpconst. */
+ 0, /* neg. */
+ 0, /* compare. */
+ COSTS_N_INSNS (1), /* widen. */
+ COSTS_N_INSNS (1), /* narrow. */
+ COSTS_N_INSNS (1), /* toint. */
+ COSTS_N_INSNS (1), /* fromint. */
+ COSTS_N_INSNS (1) /* roundint. */
+ }
+ },
+ /* Vector */
+ {
+ COSTS_N_INSNS (1) /* alu. */
+ }
+};
+
const struct cpu_cost_table exynosm1_extra_costs =
{
/* ALU */
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 5612d1e..2f0ef3b 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -4170,9 +4170,10 @@ arm_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
}
a_tramp = XEXP (m_tramp, 0);
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"),
- LCT_NORMAL, VOIDmode, a_tramp, Pmode,
- plus_constant (Pmode, a_tramp, TRAMPOLINE_SIZE), Pmode);
+ maybe_emit_call_builtin___clear_cache (a_tramp,
+ plus_constant (ptr_mode,
+ a_tramp,
+ TRAMPOLINE_SIZE));
}
/* Thumb trampolines should be entered in thumb mode, so set
@@ -7775,7 +7776,7 @@ arm_function_ok_for_sibcall (tree decl, tree exp)
int
legitimate_pic_operand_p (rtx x)
{
- if (GET_CODE (x) == SYMBOL_REF
+ if (SYMBOL_REF_P (x)
|| (GET_CODE (x) == CONST
&& GET_CODE (XEXP (x, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF))
@@ -7904,8 +7905,8 @@ legitimize_pic_address (rtx orig, machine_mode mode, rtx reg, rtx pic_reg,
{
gcc_assert (compute_now == (pic_reg != NULL_RTX));
- if (GET_CODE (orig) == SYMBOL_REF
- || GET_CODE (orig) == LABEL_REF)
+ if (SYMBOL_REF_P (orig)
+ || LABEL_REF_P (orig))
{
if (reg == 0)
{
@@ -7922,8 +7923,8 @@ legitimize_pic_address (rtx orig, machine_mode mode, rtx reg, rtx pic_reg,
/* References to weak symbols cannot be resolved locally: they
may be overridden by a non-weak definition at link time. */
rtx_insn *insn;
- if ((GET_CODE (orig) == LABEL_REF
- || (GET_CODE (orig) == SYMBOL_REF
+ if ((LABEL_REF_P (orig)
+ || (SYMBOL_REF_P (orig)
&& SYMBOL_REF_LOCAL_P (orig)
&& (SYMBOL_REF_DECL (orig)
? !DECL_WEAK (SYMBOL_REF_DECL (orig)) : 1)
@@ -8177,7 +8178,7 @@ arm_is_segment_info_known (rtx orig, bool *is_readonly)
{
*is_readonly = false;
- if (GET_CODE (orig) == LABEL_REF)
+ if (LABEL_REF_P (orig))
{
*is_readonly = true;
return true;
@@ -8437,7 +8438,7 @@ can_avoid_literal_pool_for_label_p (rtx x)
(set (reg r0) (mem (reg r0))).
No extra register is required, and (mem (reg r0)) won't cause the use
of literal pools. */
- if (arm_disable_literal_pool && GET_CODE (x) == SYMBOL_REF
+ if (arm_disable_literal_pool && SYMBOL_REF_P (x)
&& CONSTANT_POOL_ADDRESS_P (x))
return 1;
return 0;
@@ -8816,7 +8817,7 @@ thumb1_legitimate_address_p (machine_mode mode, rtx x, int strict_p)
/* This is PC relative data before arm_reorg runs. */
else if (GET_MODE_SIZE (mode) >= 4 && CONSTANT_P (x)
- && GET_CODE (x) == SYMBOL_REF
+ && SYMBOL_REF_P (x)
&& CONSTANT_POOL_ADDRESS_P (x) && !flag_pic
&& !arm_disable_literal_pool)
return 1;
@@ -8824,7 +8825,7 @@ thumb1_legitimate_address_p (machine_mode mode, rtx x, int strict_p)
/* This is PC relative data after arm_reorg runs. */
else if ((GET_MODE_SIZE (mode) >= 4 || mode == HFmode)
&& reload_completed
- && (GET_CODE (x) == LABEL_REF
+ && (LABEL_REF_P (x)
|| (GET_CODE (x) == CONST
&& GET_CODE (XEXP (x, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF
@@ -8884,7 +8885,7 @@ thumb1_legitimate_address_p (machine_mode mode, rtx x, int strict_p)
else if (GET_MODE_CLASS (mode) != MODE_FLOAT
&& GET_MODE_SIZE (mode) == 4
- && GET_CODE (x) == SYMBOL_REF
+ && SYMBOL_REF_P (x)
&& CONSTANT_POOL_ADDRESS_P (x)
&& !arm_disable_literal_pool
&& ! (flag_pic
@@ -9212,7 +9213,7 @@ arm_legitimize_address (rtx x, rtx orig_x, machine_mode mode)
x = XEXP (XEXP (x, 0), 0);
}
- if (GET_CODE (x) != SYMBOL_REF)
+ if (!SYMBOL_REF_P (x))
return x;
gcc_assert (SYMBOL_REF_TLS_MODEL (x) != 0);
@@ -9421,7 +9422,7 @@ arm_tls_referenced_p (rtx x)
FOR_EACH_SUBRTX (iter, array, x, ALL)
{
const_rtx x = *iter;
- if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0)
+ if (SYMBOL_REF_P (x) && SYMBOL_REF_TLS_MODEL (x) != 0)
{
/* ARM currently does not provide relocations to encode TLS variables
into AArch32 instructions, only data, so there is no way to
@@ -9467,7 +9468,7 @@ thumb_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
return (CONST_INT_P (x)
|| CONST_DOUBLE_P (x)
|| CONSTANT_ADDRESS_P (x)
- || (TARGET_HAVE_MOVT && GET_CODE (x) == SYMBOL_REF)
+ || (TARGET_HAVE_MOVT && SYMBOL_REF_P (x))
/* On Thumb-1 without MOVT/MOVW and literal pool disabled,
we build the symbol address with upper/lower
relocations. */
@@ -9511,7 +9512,7 @@ arm_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
#define REG_OR_SUBREG_REG(X) \
(REG_P (X) \
- || (GET_CODE (X) == SUBREG && REG_P (SUBREG_REG (X))))
+ || (SUBREG_P (X) && REG_P (SUBREG_REG (X))))
#define REG_OR_SUBREG_RTX(X) \
(REG_P (X) ? (X) : SUBREG_REG (X))
@@ -9622,7 +9623,7 @@ thumb1_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
/* Memory costs quite a lot for the first word, but subsequent words
load at the equivalent of a single insn each. */
return (10 + 4 * ((GET_MODE_SIZE (mode) - 1) / UNITS_PER_WORD)
- + ((GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
+ + ((SYMBOL_REF_P (x) && CONSTANT_POOL_ADDRESS_P (x))
? 4 : 0));
case IF_THEN_ELSE:
@@ -9779,7 +9780,7 @@ thumb1_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
return (COSTS_N_INSNS (1)
+ COSTS_N_INSNS (1)
* ((GET_MODE_SIZE (mode) - 1) / UNITS_PER_WORD)
- + ((GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
+ + ((SYMBOL_REF_P (x) && CONSTANT_POOL_ADDRESS_P (x))
? COSTS_N_INSNS (1) : 0));
case IF_THEN_ELSE:
@@ -12399,7 +12400,7 @@ arm_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep, int cost,
constant pool are cached, and that others will miss. This is a
hack. */
- if ((GET_CODE (src_mem) == SYMBOL_REF
+ if ((SYMBOL_REF_P (src_mem)
&& CONSTANT_POOL_ADDRESS_P (src_mem))
|| reg_mentioned_p (stack_pointer_rtx, src_mem)
|| reg_mentioned_p (frame_pointer_rtx, src_mem)
@@ -13234,7 +13235,7 @@ arm_coproc_mem_operand_wb (rtx op, int wb_level)
ind = XEXP (op, 0);
if (reload_completed
- && (GET_CODE (ind) == LABEL_REF
+ && (LABEL_REF_P (ind)
|| (GET_CODE (ind) == CONST
&& GET_CODE (XEXP (ind, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (ind, 0), 0)) == LABEL_REF
@@ -13410,7 +13411,7 @@ neon_vector_mem_operand (rtx op, int type, bool strict)
ind = XEXP (op, 0);
if (reload_completed
- && (GET_CODE (ind) == LABEL_REF
+ && (LABEL_REF_P (ind)
|| (GET_CODE (ind) == CONST
&& GET_CODE (XEXP (ind, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (ind, 0), 0)) == LABEL_REF
@@ -13429,7 +13430,9 @@ neon_vector_mem_operand (rtx op, int type, bool strict)
/* Allow post-increment by register for VLDn */
if (type == 2 && GET_CODE (ind) == POST_MODIFY
&& GET_CODE (XEXP (ind, 1)) == PLUS
- && REG_P (XEXP (XEXP (ind, 1), 1)))
+ && REG_P (XEXP (XEXP (ind, 1), 1))
+ && REG_P (XEXP (ind, 0))
+ && rtx_equal_p (XEXP (ind, 0), XEXP (XEXP (ind, 1), 0)))
return true;
/* Match:
@@ -13476,7 +13479,7 @@ neon_struct_mem_operand (rtx op)
ind = XEXP (op, 0);
if (reload_completed
- && (GET_CODE (ind) == LABEL_REF
+ && (LABEL_REF_P (ind)
|| (GET_CODE (ind) == CONST
&& GET_CODE (XEXP (ind, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (ind, 0), 0)) == LABEL_REF
@@ -13592,7 +13595,7 @@ symbol_mentioned_p (rtx x)
const char * fmt;
int i;
- if (GET_CODE (x) == SYMBOL_REF)
+ if (SYMBOL_REF_P (x))
return 1;
/* UNSPEC_TLS entries for a symbol include the SYMBOL_REF, but they
@@ -13626,7 +13629,7 @@ label_mentioned_p (rtx x)
const char * fmt;
int i;
- if (GET_CODE (x) == LABEL_REF)
+ if (LABEL_REF_P (x))
return 1;
/* UNSPEC_TLS entries for a symbol include a LABEL_REF for the referencing
@@ -14264,11 +14267,11 @@ load_multiple_sequence (rtx *operands, int nops, int *regs, int *saved_order,
offset = const0_rtx;
if ((REG_P (reg = XEXP (operands[nops + i], 0))
- || (GET_CODE (reg) == SUBREG
+ || (SUBREG_P (reg)
&& REG_P (reg = SUBREG_REG (reg))))
|| (GET_CODE (XEXP (operands[nops + i], 0)) == PLUS
&& ((REG_P (reg = XEXP (XEXP (operands[nops + i], 0), 0)))
- || (GET_CODE (reg) == SUBREG
+ || (SUBREG_P (reg)
&& REG_P (reg = SUBREG_REG (reg))))
&& (CONST_INT_P (offset
= XEXP (XEXP (operands[nops + i], 0), 1)))))
@@ -14418,11 +14421,11 @@ store_multiple_sequence (rtx *operands, int nops, int nops_total,
offset = const0_rtx;
if ((REG_P (reg = XEXP (operands[nops + i], 0))
- || (GET_CODE (reg) == SUBREG
+ || (SUBREG_P (reg)
&& REG_P (reg = SUBREG_REG (reg))))
|| (GET_CODE (XEXP (operands[nops + i], 0)) == PLUS
&& ((REG_P (reg = XEXP (XEXP (operands[nops + i], 0), 0)))
- || (GET_CODE (reg) == SUBREG
+ || (SUBREG_P (reg)
&& REG_P (reg = SUBREG_REG (reg))))
&& (CONST_INT_P (offset
= XEXP (XEXP (operands[nops + i], 0), 1)))))
@@ -15752,7 +15755,7 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y)
/* A compare with a shifted operand. Because of canonicalization, the
comparison will have to be swapped when we emit the assembler. */
if (GET_MODE (y) == SImode
- && (REG_P (y) || (GET_CODE (y) == SUBREG))
+ && (REG_P (y) || (SUBREG_P (y)))
&& (GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT
|| GET_CODE (x) == LSHIFTRT || GET_CODE (x) == ROTATE
|| GET_CODE (x) == ROTATERT))
@@ -15776,14 +15779,14 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y)
non-canonical, but arm_gen_compare_reg uses this to generate the
correct canonical form. */
if (GET_MODE (y) == SImode
- && (REG_P (y) || GET_CODE (y) == SUBREG)
+ && (REG_P (y) || SUBREG_P (y))
&& CONST_INT_P (x))
return CC_RSBmode;
/* This operation is performed swapped, but since we only rely on the Z
flag we don't need an additional mode. */
if (GET_MODE (y) == SImode
- && (REG_P (y) || (GET_CODE (y) == SUBREG))
+ && (REG_P (y) || (SUBREG_P (y)))
&& GET_CODE (x) == NEG
&& (op == EQ || op == NE))
return CC_Zmode;
@@ -16175,7 +16178,7 @@ arm_reload_in_hi (rtx *operands)
rtx base, scratch;
HOST_WIDE_INT offset = 0;
- if (GET_CODE (ref) == SUBREG)
+ if (SUBREG_P (ref))
{
offset = SUBREG_BYTE (ref);
ref = SUBREG_REG (ref);
@@ -16303,7 +16306,7 @@ arm_reload_out_hi (rtx *operands)
rtx base, scratch;
HOST_WIDE_INT offset = 0;
- if (GET_CODE (ref) == SUBREG)
+ if (SUBREG_P (ref))
{
offset = SUBREG_BYTE (ref);
ref = SUBREG_REG (ref);
@@ -16634,7 +16637,7 @@ mem_ok_for_ldrd_strd (rtx mem, rtx *base, rtx *offset, HOST_WIDE_INT *align)
return false;
/* Can't deal with subregs. */
- if (GET_CODE (mem) == SUBREG)
+ if (SUBREG_P (mem))
return false;
gcc_assert (MEM_P (mem));
@@ -19534,7 +19537,7 @@ arm_emit_call_insn (rtx pat, rtx addr, bool sibcall)
if (TARGET_VXWORKS_RTP
&& flag_pic
&& !sibcall
- && GET_CODE (addr) == SYMBOL_REF
+ && SYMBOL_REF_P (addr)
&& (SYMBOL_REF_DECL (addr)
? !targetm.binds_local_p (SYMBOL_REF_DECL (addr))
: !SYMBOL_REF_LOCAL_P (addr)))
@@ -20381,7 +20384,7 @@ output_move_neon (rtx *operands)
}
else
{
- if (TARGET_HAVE_MVE && GET_CODE (addr) == LABEL_REF)
+ if (TARGET_HAVE_MVE && LABEL_REF_P (addr))
sprintf (buff, "v%sr.64\t%%P0, %%1", load ? "ld" : "st");
else
sprintf (buff, "v%sr%%?\t%%P0, %%1", load ? "ld" : "st");
@@ -20392,7 +20395,7 @@ output_move_neon (rtx *operands)
{
ops[0] = gen_rtx_REG (DImode, REGNO (reg) + 2 * overlap);
ops[1] = adjust_address (mem, SImode, 8 * overlap);
- if (TARGET_HAVE_MVE && GET_CODE (addr) == LABEL_REF)
+ if (TARGET_HAVE_MVE && LABEL_REF_P (addr))
sprintf (buff, "v%sr.32\t%%P0, %%1", load ? "ld" : "st");
else
sprintf (buff, "v%sr%%?\t%%P0, %%1", load ? "ld" : "st");
@@ -20452,7 +20455,7 @@ arm_attr_length_move_neon (rtx_insn *insn)
if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS)
addr = XEXP (addr, 0);
- if (GET_CODE (addr) == LABEL_REF || GET_CODE (addr) == PLUS)
+ if (LABEL_REF_P (addr) || GET_CODE (addr) == PLUS)
{
int insns = REG_NREGS (reg) / 2;
return insns * 4;
@@ -24446,7 +24449,7 @@ arm_assemble_integer (rtx x, unsigned int size, int aligned_p)
/* Mark symbols as position independent. We only do this in the
.text segment, not in the .data segment. */
if (NEED_GOT_RELOC && flag_pic && making_const_table &&
- (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF))
+ (SYMBOL_REF_P (x) || LABEL_REF_P (x)))
{
/* See legitimize_pic_address for an explanation of the
TARGET_VXWORKS_RTP check. */
@@ -24454,7 +24457,7 @@ arm_assemble_integer (rtx x, unsigned int size, int aligned_p)
they may be overridden by a non-weak definition at link
time. */
if (!arm_pic_data_is_text_relative
- || (GET_CODE (x) == SYMBOL_REF
+ || (SYMBOL_REF_P (x)
&& (!SYMBOL_REF_LOCAL_P (x)
|| (SYMBOL_REF_DECL (x)
? DECL_WEAK (SYMBOL_REF_DECL (x)) : 0)
@@ -30822,7 +30825,7 @@ arm_split_atomic_op (enum rtx_code code, rtx old_out, rtx new_out, rtx mem,
case MINUS:
if (CONST_INT_P (value))
{
- value = GEN_INT (-INTVAL (value));
+ value = gen_int_mode (-INTVAL (value), wmode);
code = PLUS;
}
/* FALLTHRU */
@@ -31620,13 +31623,13 @@ arm_emit_coreregs_64bit_shift (enum rtx_code code, rtx out, rtx in,
gcc_assert (code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT);
gcc_assert (out
- && (REG_P (out) || GET_CODE (out) == SUBREG)
+ && (REG_P (out) || SUBREG_P (out))
&& GET_MODE (out) == DImode);
gcc_assert (in
- && (REG_P (in) || GET_CODE (in) == SUBREG)
+ && (REG_P (in) || SUBREG_P (in))
&& GET_MODE (in) == DImode);
gcc_assert (amount
- && (((REG_P (amount) || GET_CODE (amount) == SUBREG)
+ && (((REG_P (amount) || SUBREG_P (amount))
&& GET_MODE (amount) == SImode)
|| CONST_INT_P (amount)));
gcc_assert (scratch1 == NULL
@@ -31860,7 +31863,7 @@ arm_valid_symbolic_address_p (rtx addr)
if (target_word_relocations)
return false;
- if (GET_CODE (tmp) == SYMBOL_REF || GET_CODE (tmp) == LABEL_REF)
+ if (SYMBOL_REF_P (tmp) || LABEL_REF_P (tmp))
return true;
/* (const (plus: symbol_ref const_int)) */
@@ -33143,7 +33146,7 @@ extract_base_offset_in_addr (rtx mem, rtx *base, rtx *offset)
if (GET_CODE (addr) == CONST)
addr = XEXP (addr, 0);
- if (GET_CODE (addr) == REG)
+ if (REG_P (addr))
{
*base = addr;
*offset = const0_rtx;
@@ -33182,12 +33185,12 @@ fusion_load_store (rtx_insn *insn, rtx *base, rtx *offset, bool *is_load)
src = SET_SRC (x);
dest = SET_DEST (x);
- if (GET_CODE (src) == REG && GET_CODE (dest) == MEM)
+ if (REG_P (src) && MEM_P (dest))
{
*is_load = false;
extract_base_offset_in_addr (dest, base, offset);
}
- else if (GET_CODE (src) == MEM && GET_CODE (dest) == REG)
+ else if (MEM_P (src) && REG_P (dest))
{
*is_load = true;
extract_base_offset_in_addr (src, base, offset);
diff --git a/gcc/config/arm/t-rtems b/gcc/config/arm/t-rtems
index 94a2eb7..b2fcf57 100644
--- a/gcc/config/arm/t-rtems
+++ b/gcc/config/arm/t-rtems
@@ -17,8 +17,8 @@ MULTILIB_DIRNAMES += eb
MULTILIB_OPTIONS += mthumb
MULTILIB_DIRNAMES += thumb
-MULTILIB_OPTIONS += march=armv5te+fp/march=armv6-m/march=armv7-a/march=armv7-a+simd/march=armv7-r/march=armv7-r+fp/mcpu=cortex-m3/mcpu=cortex-m4/mcpu=cortex-m4+nofp/mcpu=cortex-m7
-MULTILIB_DIRNAMES += armv5te+fp armv6-m armv7-a armv7-a+simd armv7-r armv7-r+fp cortex-m3 cortex-m4 cortex-m4+nofp cortex-m7
+MULTILIB_OPTIONS += march=armv5te+fp/march=armv6-m/march=armv7-a/march=armv7-a+simd/march=armv7-r/march=armv7-r+fp/mcpu=cortex-r52/mcpu=cortex-m3/mcpu=cortex-m4/mcpu=cortex-m4+nofp/mcpu=cortex-m7
+MULTILIB_DIRNAMES += armv5te+fp armv6-m armv7-a armv7-a+simd armv7-r armv7-r+fp cortex-r52 cortex-m3 cortex-m4 cortex-m4+nofp cortex-m7
MULTILIB_OPTIONS += mfloat-abi=hard
MULTILIB_DIRNAMES += hard
@@ -31,6 +31,7 @@ MULTILIB_REQUIRED += mthumb/march=armv7-a+simd/mfloat-abi=hard
MULTILIB_REQUIRED += mthumb/march=armv7-a
MULTILIB_REQUIRED += mthumb/march=armv7-r+fp/mfloat-abi=hard
MULTILIB_REQUIRED += mthumb/march=armv7-r
+MULTILIB_REQUIRED += mthumb/mcpu=cortex-r52/mfloat-abi=hard
MULTILIB_REQUIRED += mthumb/mcpu=cortex-m3
MULTILIB_REQUIRED += mthumb/mcpu=cortex-m4/mfloat-abi=hard
MULTILIB_REQUIRED += mthumb/mcpu=cortex-m4+nofp
diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c
index 9aa7ef0..78b2bff 100644
--- a/gcc/config/c6x/c6x.c
+++ b/gcc/config/c6x/c6x.c
@@ -725,9 +725,10 @@ c6x_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
}
#ifdef CLEAR_INSN_CACHE
tramp = XEXP (tramp, 0);
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__gnu_clear_cache"),
- LCT_NORMAL, VOIDmode, tramp, Pmode,
- plus_constant (Pmode, tramp, TRAMPOLINE_SIZE), Pmode);
+ maybe_emit_call_builtin___clear_cache (tramp,
+ plus_constant (Pmode,
+ tramp,
+ TRAMPOLINE_SIZE));
#endif
}
diff --git a/gcc/config/csky/csky.c b/gcc/config/csky/csky.c
index 5aa2336..3b03f3f 100644
--- a/gcc/config/csky/csky.c
+++ b/gcc/config/csky/csky.c
@@ -5917,9 +5917,10 @@ csky_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
emit_move_insn (mem, fnaddr);
a_tramp = XEXP (m_tramp, 0);
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"),
- LCT_NORMAL, VOIDmode, a_tramp, Pmode,
- plus_constant (Pmode, a_tramp, TRAMPOLINE_SIZE), Pmode);
+ maybe_emit_call_builtin___clear_cache (a_tramp,
+ plus_constant (Pmode,
+ a_tramp,
+ TRAMPOLINE_SIZE));
}
diff --git a/gcc/config/darwin-c.c b/gcc/config/darwin-c.c
index 9034f49..9617230 100644
--- a/gcc/config/darwin-c.c
+++ b/gcc/config/darwin-c.c
@@ -44,13 +44,12 @@ static bool using_frameworks = false;
static const char *find_subframework_header (cpp_reader *pfile, const char *header,
cpp_dir **dirp);
-typedef struct align_stack
-{
- int alignment;
- struct align_stack * prev;
-} align_stack;
+struct fld_align_stack {
+ int alignment;
+ struct fld_align_stack * prev;
+};
-static struct align_stack * field_align_stack = NULL;
+static struct fld_align_stack * field_align_stack;
/* Maintain a small stack of alignments. This is similar to pragma
pack's stack, but simpler. */
@@ -58,7 +57,7 @@ static struct align_stack * field_align_stack = NULL;
static void
push_field_alignment (int bit_alignment)
{
- align_stack *entry = XNEW (align_stack);
+ fld_align_stack *entry = XNEW (fld_align_stack);
entry->alignment = maximum_field_alignment;
entry->prev = field_align_stack;
@@ -72,7 +71,7 @@ pop_field_alignment (void)
{
if (field_align_stack)
{
- align_stack *entry = field_align_stack;
+ fld_align_stack *entry = field_align_stack;
maximum_field_alignment = entry->alignment;
field_align_stack = entry->prev;
diff --git a/gcc/config/darwin-d.c b/gcc/config/darwin-d.c
new file mode 100644
index 0000000..ced07ce
--- /dev/null
+++ b/gcc/config/darwin-d.c
@@ -0,0 +1,49 @@
+/* Darwin support needed only by D front-end.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+
+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 "tm_d.h"
+#include "d/d-target.h"
+#include "d/d-target-def.h"
+
+/* Implement TARGET_D_OS_VERSIONS for Darwin targets. */
+
+static void
+darwin_d_os_builtins (void)
+{
+ d_add_builtin_version ("Posix");
+ d_add_builtin_version ("OSX");
+ d_add_builtin_version ("darwin");
+}
+
+#undef TARGET_D_OS_VERSIONS
+#define TARGET_D_OS_VERSIONS darwin_d_os_builtins
+
+/* Define TARGET_D_MINFO_SECTION for Darwin targets. */
+
+#undef TARGET_D_MINFO_SECTION
+#define TARGET_D_MINFO_SECTION "__DATA,__minfodata"
+
+#undef TARGET_D_MINFO_START_NAME
+#define TARGET_D_MINFO_START_NAME "*section$start$__DATA$__minfodata"
+
+#undef TARGET_D_MINFO_END_NAME
+#define TARGET_D_MINFO_END_NAME "*section$end$__DATA$__minfodata"
+
+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h
index 49c540f..3f222c3 100644
--- a/gcc/config/darwin-protos.h
+++ b/gcc/config/darwin-protos.h
@@ -69,6 +69,7 @@ extern void darwin_non_lazy_pcrel (FILE *, rtx);
extern void darwin_emit_unwind_label (FILE *, tree, int, int);
extern void darwin_emit_except_table_label (FILE *);
+extern rtx darwin_make_eh_symbol_indirect (rtx, bool);
extern void darwin_pragma_ignore (struct cpp_reader *);
extern void darwin_pragma_options (struct cpp_reader *);
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index dd4857f..3265e3e 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -2225,6 +2225,17 @@ darwin_emit_except_table_label (FILE *file)
ASM_OUTPUT_LABEL (file, section_start_label);
}
+rtx
+darwin_make_eh_symbol_indirect (rtx orig, bool ARG_UNUSED (pubvis))
+{
+ if (DARWIN_PPC == 0 && TARGET_64BIT)
+ return orig;
+
+ return gen_rtx_SYMBOL_REF (Pmode,
+ machopic_indirection_name (orig,
+ /*stub_p=*/false));
+}
+
/* Return, and mark as used, the name of the stub for the mcount function.
Currently, this is only called by X86 code in the expansion of the
FUNCTION_PROFILER macro, when stubs are enabled. */
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index f9d4fec..da40a08 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -135,7 +135,7 @@ extern GTY(()) int darwin_ms_struct;
"%{shared:-Zdynamiclib} %<shared", \
"%{static:%{Zdynamic:%e conflicting code gen style switches are used}}",\
"%{y*:%nthe y option is obsolete and ignored} %<y*", \
-"%<Mach %<X"
+"%<Mach "
#if LD64_HAS_EXPORT_DYNAMIC
#define DARWIN_RDYNAMIC "%{rdynamic:-export_dynamic}"
@@ -237,7 +237,7 @@ extern GTY(()) int darwin_ms_struct;
DARWIN_NOPIE_SPEC \
DARWIN_RDYNAMIC \
DARWIN_NOCOMPACT_UNWIND \
- "}}}}}}} %<pie %<no-pie %<rdynamic "
+ "}}}}}}} %<pie %<no-pie %<rdynamic %<X "
#define DSYMUTIL "\ndsymutil"
@@ -591,6 +591,9 @@ extern GTY(()) int darwin_ms_struct;
/* Emit a label to separate the exception table. */
#define TARGET_ASM_EMIT_EXCEPT_TABLE_LABEL darwin_emit_except_table_label
+/* Make an EH (personality or LDSA) symbol indirect as needed. */
+#define TARGET_ASM_MAKE_EH_SYMBOL_INDIRECT darwin_make_eh_symbol_indirect
+
/* Our profiling scheme doesn't LP labels and counter words. */
#define NO_PROFILE_COUNTERS 1
diff --git a/gcc/config/dragonfly-d.c b/gcc/config/dragonfly-d.c
new file mode 100644
index 0000000..70ec820
--- /dev/null
+++ b/gcc/config/dragonfly-d.c
@@ -0,0 +1,37 @@
+/* DragonFly support needed only by D front-end.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+
+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 "tm_d.h"
+#include "d/d-target.h"
+#include "d/d-target-def.h"
+
+/* Implement TARGET_D_OS_VERSIONS for DragonFly targets. */
+
+static void
+dragonfly_d_os_builtins (void)
+{
+ d_add_builtin_version ("DragonFlyBSD");
+ d_add_builtin_version ("Posix");
+}
+
+#undef TARGET_D_OS_VERSIONS
+#define TARGET_D_OS_VERSIONS dragonfly_d_os_builtins
+
+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/elfos.h b/gcc/config/elfos.h
index 74a3eaf..d8f169f 100644
--- a/gcc/config/elfos.h
+++ b/gcc/config/elfos.h
@@ -474,3 +474,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#undef TARGET_LIBC_HAS_FUNCTION
#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
+/* ELF support needed only by D front-end. */
+
+#define TARGET_D_MINFO_SECTION "minfo"
+#define TARGET_D_MINFO_START_NAME "__start_minfo"
+#define TARGET_D_MINFO_END_NAME "__stop_minfo"
diff --git a/gcc/config/freebsd-d.c b/gcc/config/freebsd-d.c
new file mode 100644
index 0000000..d79d82b
--- /dev/null
+++ b/gcc/config/freebsd-d.c
@@ -0,0 +1,42 @@
+/* FreeBSD support needed only by D front-end.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+
+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 "tm.h"
+#include "tm_p.h"
+#include "d/d-target.h"
+#include "d/d-target-def.h"
+
+/* Implement TARGET_D_OS_VERSIONS for FreeBSD targets. */
+
+static void
+freebsd_d_os_builtins (void)
+{
+ char buf[16];
+ snprintf (buf, sizeof (buf), "FreeBSD_%d", FBSD_MAJOR);
+
+ d_add_builtin_version ("FreeBSD");
+ d_add_builtin_version (xstrdup (buf));
+ d_add_builtin_version ("Posix");
+}
+
+#undef TARGET_D_OS_VERSIONS
+#define TARGET_D_OS_VERSIONS freebsd_d_os_builtins
+
+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/ft32/ft32.md b/gcc/config/ft32/ft32.md
index 8918bb7..1a2380f 100644
--- a/gcc/config/ft32/ft32.md
+++ b/gcc/config/ft32/ft32.md
@@ -89,9 +89,9 @@
"mul.l %0,%1,%2")
(define_insn "umulsidi3"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
- (zero_extend:DI (match_operand:SI 2 "ft32_rimm_operand" "r,KA"))))
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
+ (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
(clobber (reg:CC CC_REG))]
""
"mul.l $cc,%1,%2\;muluh.l %h0,%1,%2\;move.l %0,$cc")
diff --git a/gcc/config/gcn/mkoffload.c b/gcc/config/gcn/mkoffload.c
index f7589a5..fad0fb3 100644
--- a/gcc/config/gcn/mkoffload.c
+++ b/gcc/config/gcn/mkoffload.c
@@ -336,19 +336,24 @@ copy_early_debug_info (const char *infile, const char *outfile)
{
case R_X86_64_32:
case R_X86_64_32S:
- reloc->r_info = R_AMDGPU_ABS32;
+ reloc->r_info = ELF32_R_INFO(ELF32_R_SYM(reloc->r_info),
+ R_AMDGPU_ABS32);
break;
case R_X86_64_PC32:
- reloc->r_info = R_AMDGPU_REL32;
+ reloc->r_info = ELF32_R_INFO(ELF32_R_SYM(reloc->r_info),
+ R_AMDGPU_REL32);
break;
case R_X86_64_PC64:
- reloc->r_info = R_AMDGPU_REL64;
+ reloc->r_info = ELF32_R_INFO(ELF32_R_SYM(reloc->r_info),
+ R_AMDGPU_REL64);
break;
case R_X86_64_64:
- reloc->r_info = R_AMDGPU_ABS64;
+ reloc->r_info = ELF32_R_INFO(ELF32_R_SYM(reloc->r_info),
+ R_AMDGPU_ABS64);
break;
case R_X86_64_RELATIVE:
- reloc->r_info = R_AMDGPU_RELATIVE64;
+ reloc->r_info = ELF32_R_INFO(ELF32_R_SYM(reloc->r_info),
+ R_AMDGPU_RELATIVE64);
break;
default:
gcc_unreachable ();
diff --git a/gcc/config/gnu-user.h b/gcc/config/gnu-user.h
index ff2e880..9295024 100644
--- a/gcc/config/gnu-user.h
+++ b/gcc/config/gnu-user.h
@@ -129,14 +129,18 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
/* Link -lasan early on the command line. For -static-libasan, don't link
it for -shared link, the executable should be compiled with -static-libasan
in that case, and for executable link with --{,no-}whole-archive around
- it to force everything into the executable. And similarly for -ltsan
- and -llsan. */
+ it to force everything into the executable. And similarly for -ltsan,
+ -lhwasan, and -llsan. */
#if defined(HAVE_LD_STATIC_DYNAMIC)
#undef LIBASAN_EARLY_SPEC
#define LIBASAN_EARLY_SPEC "%{!shared:libasan_preinit%O%s} " \
"%{static-libasan:%{!shared:" \
LD_STATIC_OPTION " --whole-archive -lasan --no-whole-archive " \
LD_DYNAMIC_OPTION "}}%{!static-libasan:-lasan}"
+#undef LIBHWASAN_EARLY_SPEC
+#define LIBHWASAN_EARLY_SPEC "%{static-libhwasan:%{!shared:" \
+ LD_STATIC_OPTION " --whole-archive -lhwasan --no-whole-archive " \
+ LD_DYNAMIC_OPTION "}}%{!static-libhwasan:-lhwasan}"
#undef LIBTSAN_EARLY_SPEC
#define LIBTSAN_EARLY_SPEC "%{!shared:libtsan_preinit%O%s} " \
"%{static-libtsan:%{!shared:" \
diff --git a/gcc/config/h8300/addsub.md b/gcc/config/h8300/addsub.md
index f339285..3585bff 100644
--- a/gcc/config/h8300/addsub.md
+++ b/gcc/config/h8300/addsub.md
@@ -9,64 +9,101 @@
""
"")
-(define_insn "*addqi3"
+(define_insn_and_split "*addqi3"
[(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
(plus:QI (match_operand:QI 1 "h8300_dst_operand" "%0")
(match_operand:QI 2 "h8300_src_operand" "rQi")))]
"h8300_operands_match_p (operands)"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (plus:QI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*addqi3_flags<cczn>"
+ [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
+ (plus:QI (match_operand:QI 1 "h8300_dst_operand" "%0")
+ (match_operand:QI 2 "h8300_src_operand" "rQi")))
+ (clobber (reg:CC CC_REG))]
+ "reload_completed && h8300_operands_match_p (operands)"
"add.b %X2,%X0"
- [(set_attr "length_table" "add")
- (set_attr "cc" "set_zn")])
+ [(set_attr "length_table" "add")])
-(define_insn "*addhi3_h8300hs"
+(define_insn_and_split "*addhi"
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
(plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
(match_operand:HI 2 "h8300_src_operand" "L,N,J,n,r")))]
"!TARGET_H8300SX"
- "@
- adds %2,%S0
- subs %G2,%S0
- add.b %t2,%t0
- add.w %T2,%T0
- add.w %T2,%T0"
- [(set_attr "length" "2,2,2,4,2")
- (set_attr "cc" "none_0hit,none_0hit,clobber,set_zn,set_zn")])
-
-(define_insn "*add<mode>3_incdec"
- [(set (match_operand:HSI 0 "register_operand" "=r,r")
- (unspec:HSI [(match_operand:HSI 1 "register_operand" "0,0")
- (match_operand:HSI 2 "incdec_operand" "M,O")]
- UNSPEC_INCDEC))]
- ""
- {
- if (which_alternative == 0)
- return <MODE>mode == HImode ? "inc.w\t%2,%T0" : "inc.l\t%2,%S0";
- else if (which_alternative == 1)
- return <MODE>mode == HImode ? "dec.w\t%G2,%T0" : "dec.l\t%G2,%S0";
- gcc_unreachable ();
- }
- [(set_attr "length" "2,2")
- (set_attr "cc" "set_zn,set_zn")])
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (plus:HI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
-(define_insn "*addhi3_h8sx"
+(define_insn "*addhi3_flags<cczn>"
+ [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
+ (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
+ (match_operand:HI 2 "h8300_src_operand" "M,O,J,n,r")))
+ (clobber (reg:CC CC_REG))]
+ "reload_completed && !TARGET_H8300SX"
+ "*
+ {
+ switch (which_alternative)
+ {
+ case 0:
+ return \"inc %T2,%T0\";
+ case 1:
+ return \"dec %G2,%T0\";
+ case 2:
+ return \"add.b %t2,%t0\";
+ case 3:
+ {
+ /* If the constant is 4 or -4 and we do not need the
+ flags, then we can use adds/subs which is two bytes
+ shorter. */
+ rtx x = XVECEXP (PATTERN (insn), 0, 1);
+ bool clobber = GET_CODE (x) == CLOBBER;
+ if (clobber && INTVAL (operands[2]) == 4)
+ return \"adds %2,%S0\";
+ if (clobber && INTVAL (operands[2]) == -4)
+ return \"subs %G2,%S0\";
+ return \"add.w %T2,%T0\";
+ }
+ case 4:
+ return \"add.w %T2,%T0\";
+ default:
+ gcc_unreachable ();
+ }
+ }"
+ [(set_attr "length" "2,2,2,4,2")])
+
+(define_insn_and_split "*addhi3_h8sx"
[(set (match_operand:HI 0 "h8300_dst_operand" "=rU,rU,r,rQ")
(plus:HI (match_operand:HI 1 "h8300_dst_operand" "%0,0,0,0")
(match_operand:HI 2 "h8300_src_operand" "P3>X,P3<X,J,rQi")))]
"TARGET_H8300SX && h8300_operands_match_p (operands)"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (plus:HI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*addhi3_h8sx_flags<cczn>"
+ [(set (match_operand:HI 0 "h8300_dst_operand" "=rU,rU,r,rQ")
+ (plus:HI (match_operand:HI 1 "h8300_dst_operand" "%0,0,0,0")
+ (match_operand:HI 2 "h8300_src_operand" "P3>X,P3<X,J,rQi")))
+ (clobber (reg:CC CC_REG))]
+ "reload_completed && TARGET_H8300SX && h8300_operands_match_p (operands)"
"@
add.w %T2:3,%T0
sub.w %G2:3,%T0
add.b %t2,%t0
add.w %T2,%T0"
[(set_attr "length_table" "short_immediate,short_immediate,*,add")
- (set_attr "length" "*,*,2,*")
- (set_attr "cc" "set_zn")])
+ (set_attr "length" "*,*,2,*")])
(define_split
[(set (match_operand:HSI 0 "register_operand" "")
(plus:HSI (match_dup 0)
(match_operand:HSI 1 "two_insn_adds_subs_operand" "")))]
- ""
+ "!reload_completed"
[(const_int 0)]
{
split_adds_subs (<MODE>mode, operands);
@@ -74,18 +111,28 @@
})
-(define_insn "*addsi_h8300hs"
+(define_insn_and_split "*addsi"
[(set (match_operand:SI 0 "h8300_dst_operand" "=rQ,rQ")
(plus:SI (match_operand:SI 1 "h8300_dst_operand" "%0,0")
(match_operand:SI 2 "h8300_src_operand" "i,rQ")))]
"h8300_operands_match_p (operands)"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*addsi_flags<cczn>"
+ [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ,rQ")
+ (plus:SI (match_operand:SI 1 "h8300_dst_operand" "%0,0")
+ (match_operand:SI 2 "h8300_src_operand" "i,rQ")))
+ (clobber (reg:CC CC_REG))]
+ "reload_completed && h8300_operands_match_p (operands)"
{
- return output_plussi (operands);
+ rtx x = XVECEXP (PATTERN (insn), 0, 1);
+ return output_plussi (operands, GET_CODE (x) != CLOBBER);
}
[(set (attr "length")
- (symbol_ref "compute_plussi_length (operands)"))
- (set (attr "cc")
- (symbol_ref "compute_plussi_cc (operands)"))])
+ (symbol_ref "compute_plussi_length (operands, false)"))])
;; ----------------------------------------------------------------------
;; SUBTRACT INSTRUCTIONS
@@ -95,24 +142,43 @@
[(set (match_operand:QHSI 0 "register_operand" "")
(minus:QHSI (match_operand:QHSI 1 "register_operand" "")
(match_operand:QHSI 2 "h8300_src_operand" "")))]
- ""
- {
- })
+ "")
-(define_insn "*subqi3"
+(define_insn_and_split "*subqi3"
[(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
(minus:QI (match_operand:QI 1 "h8300_dst_operand" "0")
(match_operand:QI 2 "h8300_dst_operand" "rQ")))]
"h8300_operands_match_p (operands)"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (minus:QI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*subqi3_flags<cczn>"
+ [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
+ (minus:QI (match_operand:QI 1 "h8300_dst_operand" "0")
+ (match_operand:QI 2 "h8300_dst_operand" "rQ")))
+ (clobber (reg:CC CC_REG))]
+ "reload_completed && h8300_operands_match_p (operands)"
"sub.b %X2,%X0"
- [(set_attr "length_table" "add")
- (set_attr "cc" "set_zn")])
+ [(set_attr "length_table" "add")])
-(define_insn "*sub<mode>3_h8300hs"
+(define_insn_and_split "*sub<mode>3"
[(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ,rQ")
(minus:HSI (match_operand:HSI 1 "h8300_dst_operand" "0,0")
(match_operand:HSI 2 "h8300_src_operand" "rQ,i")))]
"h8300_operands_match_p (operands)"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (minus:HSI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*sub<mode>3_flags<cczn>"
+ [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ,rQ")
+ (minus:HSI (match_operand:HSI 1 "h8300_dst_operand" "0,0")
+ (match_operand:HSI 2 "h8300_src_operand" "rQ,i")))
+ (clobber (reg:CC CC_REG))]
+ "reload_completed && h8300_operands_match_p (operands)"
{
if (<MODE>mode == HImode)
return "sub.w %T2,%T0";
@@ -120,8 +186,7 @@
return "sub.l %S2,%S0";
gcc_unreachable ();
}
- [(set_attr "length_table" "add")
- (set_attr "cc" "set_zn")])
+ [(set_attr "length_table" "add")])
;; ----------------------------------------------------------------------
;; NEGATION INSTRUCTIONS
@@ -133,10 +198,20 @@
""
"")
-(define_insn "*neg<mode>2"
+(define_insn_and_split "*neg<mode>2"
[(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
(neg:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (neg:QHSI (match_dup 1)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*neg<mode>2_flags<cczn>"
+ [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
+ (neg:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ "reload_completed"
{
if (<MODE>mode == E_QImode)
return "neg %X0";
@@ -146,14 +221,21 @@
return "neg.l %S0";
gcc_unreachable ();
}
- [(set_attr "length_table" "unary")
- (set_attr "cc" "set_zn")])
-
+ [(set_attr "length_table" "unary")])
-(define_insn "*negsf2_h8300hs"
+(define_insn_and_split "*negsf2"
[(set (match_operand:SF 0 "register_operand" "=r")
- (neg:SF (match_operand:SF 1 "register_operand" "0")))]
+ (neg:SF (match_operand:SF 1 "register_operand" "0")))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (neg:SF (match_dup 1)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*negsf2_clobber_flags"
+ [(set (match_operand:SF 0 "register_operand" "=r")
+ (neg:SF (match_operand:SF 1 "register_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ "reload_completed"
"xor.w\\t#32768,%e0"
[(set_attr "length" "4")])
-
diff --git a/gcc/config/h8300/bitfield.md b/gcc/config/h8300/bitfield.md
index bed712d..722c147 100644
--- a/gcc/config/h8300/bitfield.md
+++ b/gcc/config/h8300/bitfield.md
@@ -15,7 +15,7 @@
;; Inverted loads with a 16bit destination.
;;
-(define_insn ""
+(define_insn_and_split ""
[(set (match_operand:HI 0 "register_operand" "=&r")
(zero_extract:HI (xor:HI (match_operand:HI 1 "register_operand" "r")
(match_operand:HI 3 "const_int_operand" "n"))
@@ -23,6 +23,23 @@
(match_operand:HI 2 "const_int_operand" "n")))]
"(TARGET_H8300SX)
&& (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (zero_extract:HI (xor:HI (match_dup 1) (match_dup 3))
+ (const_int 1)
+ (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=&r")
+ (zero_extract:HI (xor:HI (match_operand:HI 1 "register_operand" "r")
+ (match_operand:HI 3 "const_int_operand" "n"))
+ (const_int 1)
+ (match_operand:HI 2 "const_int_operand" "n")))
+ (clobber (reg:CC CC_REG))]
+ "(TARGET_H8300SX)
+ && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
"sub.w %0,%0\;bild %Z2,%Y1\;bst #0,%X0"
[(set_attr "length" "8")])
@@ -30,23 +47,35 @@
;; Normal loads with a 32bit destination.
;;
-(define_insn "*extzv_1_r_h8300hs"
+(define_insn_and_split "*extzv_1_r"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
(const_int 1)
(match_operand 2 "const_int_operand" "n,n")))]
"INTVAL (operands[2]) < 16"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*extzv_1_r_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
+ (const_int 1)
+ (match_operand 2 "const_int_operand" "n,n")))
+ (clobber (reg:CC CC_REG))]
+ "INTVAL (operands[2]) < 16"
{
return output_simode_bld (0, operands);
}
- [(set_attr "cc" "set_znv,set_znv")
- (set_attr "length" "8,6")])
+ [(set_attr "length" "8,6")])
;;
;; Inverted loads with a 32bit destination.
;;
-(define_insn "*extzv_1_r_inv_h8300hs"
+(define_insn_and_split "*extzv_1_r_inv"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(zero_extract:SI (xor:SI (match_operand:SI 1 "register_operand" "?0,r")
(match_operand 3 "const_int_operand" "n,n"))
@@ -54,11 +83,27 @@
(match_operand 2 "const_int_operand" "n,n")))]
"INTVAL (operands[2]) < 16
&& (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (zero_extract:SI (xor:SI (match_dup 1) (match_dup 3))
+ (const_int 1)
+ (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*extzv_1_r_inv_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (zero_extract:SI (xor:SI (match_operand:SI 1 "register_operand" "?0,r")
+ (match_operand 3 "const_int_operand" "n,n"))
+ (const_int 1)
+ (match_operand 2 "const_int_operand" "n,n")))
+ (clobber (reg:CC CC_REG))]
+ "INTVAL (operands[2]) < 16
+ && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
{
return output_simode_bld (1, operands);
}
- [(set_attr "cc" "set_znv,set_znv")
- (set_attr "length" "8,6")])
+ [(set_attr "length" "8,6")])
(define_expand "insv"
[(set (zero_extract:HI (match_operand:HI 0 "general_operand" "")
@@ -107,12 +152,25 @@
FAIL;
})
-(define_insn ""
+(define_insn_and_split ""
[(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r")
(const_int 1)
(match_operand:HI 1 "immediate_operand" "n"))
(match_operand:HI 2 "register_operand" "r"))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (zero_extract:HI (match_dup 0) (const_int 1) (match_dup 1))
+ (match_dup 2))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn ""
+ [(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r")
+ (const_int 1)
+ (match_operand:HI 1 "immediate_operand" "n"))
+ (match_operand:HI 2 "register_operand" "r"))
+ (clobber (reg:CC CC_REG))]
+ ""
"bld #0,%R2\;bst %Z1,%Y0 ; i1"
[(set_attr "length" "4")])
@@ -164,7 +222,7 @@
;; BAND, BOR, and BXOR patterns
-(define_insn ""
+(define_insn_and_split ""
[(set (match_operand:HI 0 "bit_operand" "=Ur")
(match_operator:HI 4 "bit_operator"
[(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
@@ -172,10 +230,28 @@
(match_operand:HI 2 "immediate_operand" "n"))
(match_operand:HI 3 "bit_operand" "0")]))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (match_op_dup 4 [(zero_extract:HI (match_dup 1)
+ (const_int 1)
+ (match_dup 2))
+ (match_dup 3)]))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "bit_operand" "=Ur")
+ (match_operator:HI 4 "bit_operator"
+ [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
+ (const_int 1)
+ (match_operand:HI 2 "immediate_operand" "n"))
+ (match_operand:HI 3 "bit_operand" "0")]))
+ (clobber (reg:CC CC_REG))]
+ ""
"bld %Z2,%Y1\;b%c4 #0,%R0\;bst #0,%R0; bl1"
[(set_attr "length" "6")])
-(define_insn ""
+(define_insn_and_split ""
[(set (match_operand:HI 0 "bit_operand" "=Ur")
(match_operator:HI 5 "bit_operator"
[(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
@@ -185,256 +261,268 @@
(const_int 1)
(match_operand:HI 4 "immediate_operand" "n"))]))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (match_op_dup 5 [(zero_extract:HI (match_dup 1)
+ (const_int 1)
+ (match_dup 2))
+ (zero_extract:HI (match_dup 3)
+ (const_int 1)
+ (match_dup 4))]))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "bit_operand" "=Ur")
+ (match_operator:HI 5 "bit_operator"
+ [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
+ (const_int 1)
+ (match_operand:HI 2 "immediate_operand" "n"))
+ (zero_extract:HI (match_operand:HI 3 "register_operand" "r")
+ (const_int 1)
+ (match_operand:HI 4 "immediate_operand" "n"))]))
+ (clobber (reg:CC CC_REG))]
+ ""
"bld %Z2,%Y1\;b%c5 %Z4,%Y3\;bst #0,%R0; bl3"
[(set_attr "length" "6")])
-(define_insn "bfld"
+(define_insn_and_split "bfld"
[(set (match_operand:QI 0 "register_operand" "=r")
(zero_extract:QI (match_operand:QI 1 "bit_memory_operand" "WU")
(match_operand:QI 2 "immediate_operand" "n")
(match_operand:QI 3 "immediate_operand" "n")))]
"TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (zero_extract:QI (match_dup 1) (match_dup 2) (match_dup 3)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "bfld_clobber_flags"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (zero_extract:QI (match_operand:QI 1 "bit_memory_operand" "WU")
+ (match_operand:QI 2 "immediate_operand" "n")
+ (match_operand:QI 3 "immediate_operand" "n")))
+ (clobber (reg:CC CC_REG))]
+ "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
{
operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
- (1 << INTVAL (operands[3])));
return "bfld %2,%1,%R0";
}
- [(set_attr "cc" "none_0hit")
- (set_attr "length_table" "bitfield")])
+ [(set_attr "length_table" "bitfield")])
-(define_insn "bfst"
+(define_insn_and_split "bfst"
[(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
(match_operand:QI 2 "immediate_operand" "n")
(match_operand:QI 3 "immediate_operand" "n"))
(match_operand:QI 1 "register_operand" "r"))]
"TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
+ "#"
+ "reload_completed"
+ [(parallel [(set (zero_extract:QI (match_dup 0) (match_dup 2) (match_dup 3))
+ (match_dup 1))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "bfst_clobber_flags"
+ [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
+ (match_operand:QI 2 "immediate_operand" "n")
+ (match_operand:QI 3 "immediate_operand" "n"))
+ (match_operand:QI 1 "register_operand" "r"))
+ (clobber (reg:CC CC_REG))]
+ "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
{
operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
- (1 << INTVAL (operands[3])));
return "bfst %R1,%2,%0";
}
- [(set_attr "cc" "none_0hit")
- (set_attr "length_table" "bitfield")])
-
-(define_expand "cstoreqi4"
- [(use (match_operator 1 "eqne_operator"
- [(match_operand:QI 2 "h8300_dst_operand" "")
- (match_operand:QI 3 "h8300_src_operand" "")]))
- (clobber (match_operand:HI 0 "register_operand"))]
- "TARGET_H8300SX"
- {
- h8300_expand_store (operands);
- DONE;
- })
-
-(define_expand "cstorehi4"
- [(use (match_operator 1 "eqne_operator"
- [(match_operand:HI 2 "h8300_dst_operand" "")
- (match_operand:HI 3 "h8300_src_operand" "")]))
- (clobber (match_operand:HI 0 "register_operand"))]
- "TARGET_H8300SX"
- {
- h8300_expand_store (operands);
- DONE;
- })
-
-(define_expand "cstoresi4"
- [(use (match_operator 1 "eqne_operator"
- [(match_operand:SI 2 "h8300_dst_operand" "")
- (match_operand:SI 3 "h8300_src_operand" "")]))
- (clobber (match_operand:HI 0 "register_operand"))]
- "TARGET_H8300SX"
- {
- h8300_expand_store (operands);
- DONE;
- })
-
-(define_insn "*bstzhireg"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (match_operator:HI 1 "eqne_operator" [(cc0) (const_int 0)]))]
- "TARGET_H8300SX"
- "mulu.w #0,%T0\;b%k1 .Lh8BR%=\;inc.w #1,%T0\\n.Lh8BR%=:"
- [(set_attr "cc" "clobber")])
-
-(define_insn_and_split "*cmpstz"
- [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU,WU")
- (const_int 1)
- (match_operand:QI 1 "immediate_operand" "n,n"))
- (match_operator:QI 2 "eqne_operator"
- [(match_operand 3 "h8300_dst_operand" "r,rQ")
- (match_operand 4 "h8300_src_operand" "I,rQi")]))]
- "TARGET_H8300SX
- && (GET_MODE (operands[3]) == GET_MODE (operands[4])
- || GET_CODE (operands[4]) == CONST_INT)
- && GET_MODE_CLASS (GET_MODE (operands[3])) == MODE_INT
- && GET_MODE_SIZE (GET_MODE (operands[3])) <= 4"
- "#"
- "reload_completed"
- [(set (cc0) (match_dup 5))
- (set (zero_extract:QI (match_dup 0) (const_int 1) (match_dup 1))
- (match_op_dup:QI 2 [(cc0) (const_int 0)]))]
- {
- operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]);
- }
- [(set_attr "cc" "set_znv,compare")])
-
-(define_insn "*bstz"
- [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
- (const_int 1)
- (match_operand:QI 1 "immediate_operand" "n"))
- (eq:QI (cc0) (const_int 0)))]
- "TARGET_H8300SX && reload_completed"
- "bstz %1,%0"
- [(set_attr "cc" "none_0hit")
- (set_attr "length_table" "unary")])
-
-(define_insn "*bistz"
- [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
- (const_int 1)
- (match_operand:QI 1 "immediate_operand" "n"))
- (ne:QI (cc0) (const_int 0)))]
- "TARGET_H8300SX && reload_completed"
- "bistz %1,%0"
- [(set_attr "cc" "none_0hit")
- (set_attr "length_table" "unary")])
-
-(define_insn_and_split "*cmpcondbset"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
- (if_then_else:QI (match_operator 1 "eqne_operator"
- [(match_operand 2 "h8300_dst_operand" "r,rQ")
- (match_operand 3 "h8300_src_operand" "I,rQi")])
- (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
- (match_operand:QI 5 "single_one_operand" "n,n"))
- (match_dup 4)))]
- "TARGET_H8300SX"
- "#"
- "reload_completed"
- [(set (cc0) (match_dup 6))
- (set (match_dup 0)
- (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
- (ior:QI (match_dup 4) (match_dup 5))
- (match_dup 4)))]
- {
- operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
- }
- [(set_attr "cc" "set_znv,compare")])
-
-(define_insn "*condbset"
- [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
- (if_then_else:QI (match_operator:QI 2 "eqne_operator"
- [(cc0) (const_int 0)])
- (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
- (match_operand:QI 1 "single_one_operand" "n"))
- (match_dup 3)))]
- "TARGET_H8300SX && reload_completed"
- "bset/%j2\t%V1,%0"
- [(set_attr "cc" "none_0hit")
- (set_attr "length_table" "logicb")])
-
-(define_insn_and_split "*cmpcondbclr"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
- (if_then_else:QI (match_operator 1 "eqne_operator"
- [(match_operand 2 "h8300_dst_operand" "r,rQ")
- (match_operand 3 "h8300_src_operand" "I,rQi")])
- (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
- (match_operand:QI 5 "single_zero_operand" "n,n"))
- (match_dup 4)))]
- "TARGET_H8300SX"
- "#"
- "reload_completed"
- [(set (cc0) (match_dup 6))
- (set (match_dup 0)
- (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
- (and:QI (match_dup 4) (match_dup 5))
- (match_dup 4)))]
- {
- operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
- }
- [(set_attr "cc" "set_znv,compare")])
-
-(define_insn "*condbclr"
- [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
- (if_then_else:QI (match_operator:QI 2 "eqne_operator"
- [(cc0) (const_int 0)])
- (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
- (match_operand:QI 1 "single_zero_operand" "n"))
- (match_dup 3)))]
- "TARGET_H8300SX && reload_completed"
- "bclr/%j2\t%W1,%0"
- [(set_attr "cc" "none_0hit")
- (set_attr "length_table" "logicb")])
-
-(define_insn_and_split "*cmpcondbsetreg"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
- (if_then_else:QI (match_operator 1 "eqne_operator"
- [(match_operand 2 "h8300_dst_operand" "r,rQ")
- (match_operand 3 "h8300_src_operand" "I,rQi")])
- (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
- (ashift:QI (const_int 1)
- (match_operand:QI 5 "register_operand" "r,r")))
- (match_dup 4)))]
- "TARGET_H8300SX"
- "#"
- "reload_completed"
- [(set (cc0) (match_dup 6))
- (set (match_dup 0)
- (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
- (ior:QI (match_dup 4)
- (ashift:QI (const_int 1)
- (match_operand:QI 5 "register_operand" "r,r")))
- (match_dup 4)))]
- {
- operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
- }
- [(set_attr "cc" "set_znv,compare")])
-
-(define_insn "*condbsetreg"
- [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
- (if_then_else:QI (match_operator:QI 2 "eqne_operator"
- [(cc0) (const_int 0)])
- (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
- (ashift:QI (const_int 1)
- (match_operand:QI 1 "register_operand" "r")))
- (match_dup 3)))]
- "TARGET_H8300SX && reload_completed"
- "bset/%j2\t%R1,%0"
- [(set_attr "cc" "none_0hit")
- (set_attr "length_table" "logicb")])
-
-(define_insn_and_split "*cmpcondbclrreg"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
- (if_then_else:QI (match_operator 1 "eqne_operator"
- [(match_operand 2 "h8300_dst_operand" "r,rQ")
- (match_operand 3 "h8300_src_operand" "I,rQi")])
- (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
- (ashift:QI (const_int 1)
- (match_operand:QI 5 "register_operand" "r,r")))
- (match_dup 4)))]
- "TARGET_H8300SX"
- "#"
- "reload_completed"
- [(set (cc0) (match_dup 6))
- (set (match_dup 0)
- (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
- (and:QI (match_dup 4)
- (ashift:QI (const_int 1)
- (match_operand:QI 5 "register_operand" "r,r")))
- (match_dup 4)))]
- {
- operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
- }
- [(set_attr "cc" "set_znv,compare")])
-
-(define_insn "*condbclrreg"
- [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
- (if_then_else:QI (match_operator:QI 2 "eqne_operator"
- [(cc0) (const_int 0)])
- (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
- (ashift:QI (const_int 1)
- (match_operand:QI 1 "register_operand" "r")))
- (match_dup 3)))]
- "TARGET_H8300SX && reload_completed"
- "bclr/%j2\t%R1,%0"
- [(set_attr "cc" "none_0hit")
- (set_attr "length_table" "logicb")])
+ [(set_attr "length_table" "bitfield")])
+
+;;(define_expand "cstore<mode>4"
+;; [(use (match_operator 1 "eqne_operator"
+;; [(match_operand:QHSI 2 "h8300_dst_operand" "")
+;; (match_operand:QHSI 3 "h8300_src_operand" "")]))
+;; (clobber (match_operand:QHSI 0 "register_operand"))]
+;; "TARGET_H8300SX"
+;; {
+;; h8300_expand_store (operands);
+;; DONE;
+;; })
+
+;;(define_insn "*bstzhireg"
+;; [(set (match_operand:HI 0 "register_operand" "=r")
+;; (match_operator:HI 1 "eqne_operator" [(cc0) (const_int 0)]))]
+;; "TARGET_H8300SX"
+;; "mulu.w #0,%T0\;b%k1 .Lh8BR%=\;inc.w #1,%T0\\n.Lh8BR%=:")
+
+;;(define_insn_and_split "*cmpstz"
+;; [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU,WU")
+;; (const_int 1)
+;; (match_operand:QI 1 "immediate_operand" "n,n"))
+;; (match_operator:QI 2 "eqne_operator"
+;; [(match_operand 3 "h8300_dst_operand" "r,rQ")
+;; (match_operand 4 "h8300_src_operand" "I,rQi")]))]
+;; "TARGET_H8300SX
+;; && (GET_MODE (operands[3]) == GET_MODE (operands[4])
+;; || GET_CODE (operands[4]) == CONST_INT)
+;; && GET_MODE_CLASS (GET_MODE (operands[3])) == MODE_INT
+;; && GET_MODE_SIZE (GET_MODE (operands[3])) <= 4"
+;; "#"
+;; "reload_completed"
+;; [(set (cc0) (match_dup 5))
+;; (set (zero_extract:QI (match_dup 0) (const_int 1) (match_dup 1))
+;; (match_op_dup:QI 2 [(cc0) (const_int 0)]))]
+;; {
+;; operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]);
+;; })
+
+;;(define_insn "*bstz"
+;; [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
+;; (const_int 1)
+;; (match_operand:QI 1 "immediate_operand" "n"))
+;; (eq:QI (cc0) (const_int 0)))]
+;; "TARGET_H8300SX && reload_completed"
+;; "bstz %1,%0"
+;; [(set_attr "length_table" "unary")])
+
+;;(define_insn "*bistz"
+;; [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
+;; (const_int 1)
+;; (match_operand:QI 1 "immediate_operand" "n"))
+;; (ne:QI (cc0) (const_int 0)))]
+;; "TARGET_H8300SX && reload_completed"
+;; "bistz %1,%0"
+;; [(set_attr "length_table" "unary")])
+
+;;(define_insn_and_split "*cmpcondbset"
+;; [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
+;; (if_then_else:QI (match_operator 1 "eqne_operator"
+;; [(match_operand 2 "h8300_dst_operand" "r,rQ")
+;; (match_operand 3 "h8300_src_operand" "I,rQi")])
+;; (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
+;; (match_operand:QI 5 "single_one_operand" "n,n"))
+;; (match_dup 4)))]
+;; "TARGET_H8300SX"
+;; "#"
+;; "reload_completed"
+;; [(set (cc0) (match_dup 6))
+;; (set (match_dup 0)
+;; (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
+;; (ior:QI (match_dup 4) (match_dup 5))
+;; (match_dup 4)))]
+;; {
+;; operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
+;; })
+
+;;(define_insn "*condbset"
+;; [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
+;; (if_then_else:QI (match_operator:QI 2 "eqne_operator"
+;; [(cc0) (const_int 0)])
+;; (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
+;; (match_operand:QI 1 "single_one_operand" "n"))
+;; (match_dup 3)))]
+;; "TARGET_H8300SX && reload_completed"
+;; "bset/%j2\t%V1,%0"
+;; [(set_attr "length_table" "logicb")])
+
+;;(define_insn_and_split "*cmpcondbclr"
+;; [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
+;; (if_then_else:QI (match_operator 1 "eqne_operator"
+;; [(match_operand 2 "h8300_dst_operand" "r,rQ")
+;; (match_operand 3 "h8300_src_operand" "I,rQi")])
+;; (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
+;; (match_operand:QI 5 "single_zero_operand" "n,n"))
+;; (match_dup 4)))]
+;; "TARGET_H8300SX"
+;; "#"
+;; "reload_completed"
+;; [(set (cc0) (match_dup 6))
+;; (set (match_dup 0)
+;; (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
+;; (and:QI (match_dup 4) (match_dup 5))
+;; (match_dup 4)))]
+;; {
+;; operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
+;; })
+
+;;(define_insn "*condbclr"
+;; [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
+;; (if_then_else:QI (match_operator:QI 2 "eqne_operator"
+;; [(cc0) (const_int 0)])
+;; (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
+;; (match_operand:QI 1 "single_zero_operand" "n"))
+;; (match_dup 3)))]
+;; "TARGET_H8300SX && reload_completed"
+;; "bclr/%j2\t%W1,%0"
+;; [(set_attr "length_table" "logicb")])
+
+;;(define_insn_and_split "*cmpcondbsetreg"
+;; [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
+;; (if_then_else:QI (match_operator 1 "eqne_operator"
+;; [(match_operand 2 "h8300_dst_operand" "r,rQ")
+;; (match_operand 3 "h8300_src_operand" "I,rQi")])
+;; (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
+;; (ashift:QI (const_int 1)
+;; (match_operand:QI 5 "register_operand" "r,r")))
+;; (match_dup 4)))]
+;; "TARGET_H8300SX"
+;; "#"
+;; "reload_completed"
+;; [(set (cc0) (match_dup 6))
+;; (set (match_dup 0)
+;; (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
+;; (ior:QI (match_dup 4)
+;; (ashift:QI (const_int 1)
+;; (match_operand:QI 5 "register_operand" "r,r")))
+;; (match_dup 4)))]
+;; {
+;; operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
+;; })
+
+;;(define_insn "*condbsetreg"
+;; [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
+;; (if_then_else:QI (match_operator:QI 2 "eqne_operator"
+;; [(cc0) (const_int 0)])
+;; (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
+;; (ashift:QI (const_int 1)
+;; (match_operand:QI 1 "register_operand" "r")))
+;; (match_dup 3)))]
+;; "TARGET_H8300SX && reload_completed"
+;; "bset/%j2\t%R1,%0"
+;; [(set_attr "length_table" "logicb")])
+
+;;(define_insn_and_split "*cmpcondbclrreg"
+;; [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
+;; (if_then_else:QI (match_operator 1 "eqne_operator"
+;; [(match_operand 2 "h8300_dst_operand" "r,rQ")
+;; (match_operand 3 "h8300_src_operand" "I,rQi")])
+;; (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
+;; (ashift:QI (const_int 1)
+;; (match_operand:QI 5 "register_operand" "r,r")))
+;; (match_dup 4)))]
+;; "TARGET_H8300SX"
+;; "#"
+;; "reload_completed"
+;; [(set (cc0) (match_dup 6))
+;; (set (match_dup 0)
+;; (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
+;; (and:QI (match_dup 4)
+;; (ashift:QI (const_int 1)
+;; (match_operand:QI 5 "register_operand" "r,r")))
+;; (match_dup 4)))]
+;; {
+;; operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
+;; })
+
+;;(define_insn "*condbclrreg"
+;; [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
+;; (if_then_else:QI (match_operator:QI 2 "eqne_operator"
+;; [(cc0) (const_int 0)])
+;; (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
+;; (ashift:QI (const_int 1)
+;; (match_operand:QI 1 "register_operand" "r")))
+;; (match_dup 3)))]
+;; "TARGET_H8300SX && reload_completed"
+;; "bclr/%j2\t%R1,%0"
+;; [(set_attr "length_table" "logicb")])
diff --git a/gcc/config/h8300/combiner.md b/gcc/config/h8300/combiner.md
index 4f49c7f..20e19da 100644
--- a/gcc/config/h8300/combiner.md
+++ b/gcc/config/h8300/combiner.md
@@ -4,88 +4,193 @@
;; insv:SI
-(define_insn "*insv_si_1_n"
+(define_insn_and_split "*insv_si_1_n"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
(const_int 1)
(match_operand:SI 1 "const_int_operand" "n"))
(match_operand:SI 2 "register_operand" "r"))]
"INTVAL (operands[1]) < 16"
+ "#"
+ "reload_completed"
+ [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1))
+ (match_dup 2))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*insv_si_1_n_clobber_flags"
+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
+ (const_int 1)
+ (match_operand:SI 1 "const_int_operand" "n"))
+ (match_operand:SI 2 "register_operand" "r"))
+ (clobber (reg:CC CC_REG))]
+ "INTVAL (operands[1]) < 16"
"bld\\t#0,%w2\;bst\\t%Z1,%Y0"
[(set_attr "length" "4")])
-(define_insn "*insv_si_1_n_lshiftrt"
+(define_insn_and_split "*insv_si_1_n_lshiftrt"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
(const_int 1)
(match_operand:SI 1 "const_int_operand" "n"))
(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
(match_operand:SI 3 "const_int_operand" "n")))]
"INTVAL (operands[1]) < 16 && INTVAL (operands[3]) < 16"
+ "#"
+ "reload_completed"
+ [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1))
+ (lshiftrt:SI (match_dup 2) (match_dup 3)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*insv_si_1_n_lshiftrt_clobber_flags"
+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
+ (const_int 1)
+ (match_operand:SI 1 "const_int_operand" "n"))
+ (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+ (match_operand:SI 3 "const_int_operand" "n")))
+ (clobber (reg:CC CC_REG))]
+ "INTVAL (operands[1]) < 16 && INTVAL (operands[3]) < 16"
"bld\\t%Z3,%Y2\;bst\\t%Z1,%Y0"
[(set_attr "length" "4")])
-(define_insn "*insv_si_1_n_lshiftrt_16"
+(define_insn_and_split "*insv_si_1_n_lshiftrt_16"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
(const_int 1)
(match_operand:SI 1 "const_int_operand" "n"))
(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
(const_int 16)))]
"INTVAL (operands[1]) < 16"
+ "#"
+ "reload_completed"
+ [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1))
+ (lshiftrt:SI (match_dup 2) (const_int 16)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*insv_si_1_n_lshiftrt_16_clobber_flags"
+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
+ (const_int 1)
+ (match_operand:SI 1 "const_int_operand" "n"))
+ (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+ (const_int 16)))
+ (clobber (reg:CC CC_REG))]
+ "INTVAL (operands[1]) < 16"
"rotr.w\\t%e2\;rotl.w\\t%e2\;bst\\t%Z1,%Y0"
[(set_attr "length" "6")])
-(define_insn "*insv_si_8_8"
+(define_insn_and_split "*insv_si_8_8"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
(const_int 8)
(const_int 8))
(match_operand:SI 1 "register_operand" "r"))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
+ (match_dup 1))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*insv_si_8_8_clobber_flags"
+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
+ (const_int 8)
+ (const_int 8))
+ (match_operand:SI 1 "register_operand" "r"))
+ (clobber (reg:CC CC_REG))]
+ ""
"mov.b\\t%w1,%x0"
[(set_attr "length" "2")])
-(define_insn "*insv_si_8_8_lshiftrt_8"
+(define_insn_and_split "*insv_si_8_8_lshiftrt_8"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
(const_int 8)
(const_int 8))
(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
(const_int 8)))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
+ (lshiftrt:SI (match_dup 1) (const_int 8)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*insv_si_8_8_lshiftrt_8_clobber_flags"
+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
+ (const_int 8)
+ (const_int 8))
+ (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 8)))
+ (clobber (reg:CC CC_REG))]
+ ""
"mov.b\\t%x1,%x0"
[(set_attr "length" "2")])
;; extzv:SI
-(define_insn "*extzv_8_8"
+(define_insn_and_split "*extzv_8_8"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
(const_int 8)
(const_int 8)))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*extzv_8_8_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
+ (const_int 8)
+ (const_int 8)))
+ (clobber (reg:CC CC_REG))]
+ ""
"@
mov.b\\t%x1,%w0\;extu.w\\t%f0\;extu.l\\t%S0
sub.l\\t%S0,%S0\;mov.b\\t%x1,%w0"
- [(set_attr "cc" "set_znv,clobber")
- (set_attr "length" "6,4")])
+ [(set_attr "length" "6,4")])
-(define_insn "*extzv_8_16"
+(define_insn_and_split "*extzv_8_16"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
(const_int 8)
(const_int 16)))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (zero_extract:SI (match_dup 1) (const_int 8) (const_int 16)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*extzv_8_16_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 8)
+ (const_int 16)))
+ (clobber (reg:CC CC_REG))]
+ ""
"mov.w\\t%e1,%f0\;extu.w\\t%f0\;extu.l\\t%S0"
- [(set_attr "cc" "set_znv")
- (set_attr "length" "6")])
+ [(set_attr "length" "6")])
-(define_insn "*extzv_16_8"
+(define_insn_and_split "*extzv_16_8"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
(const_int 16)
(const_int 8)))
(clobber (match_scratch:SI 2 "=&r"))]
"TARGET_H8300H"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (zero_extract:SI (match_dup 1) (const_int 16) (const_int 8)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*extzv_16_8_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 16)
+ (const_int 8)))
+ (clobber (match_scratch:SI 2 "=&r"))
+ (clobber (reg:CC CC_REG))]
+ "TARGET_H8300H"
"mov.w\\t%e1,%f2\;mov.b\\t%x1,%w0\;mov.b\\t%w2,%x0\;extu.l\\t%S0"
- [(set_attr "length" "8")
- (set_attr "cc" "set_znv")])
+ [(set_attr "length" "8")])
;; Extract the exponent of a float.
@@ -100,12 +205,13 @@
[(parallel [(set (match_dup 0)
(ashift:SI (match_dup 0)
(const_int 1)))
- (clobber (scratch:QI))])
+ (clobber (scratch:QI))
+ (clobber (reg:CC CC_REG))])
(parallel [(set (match_dup 0)
(lshiftrt:SI (match_dup 0)
(const_int 24)))
- (clobber (scratch:QI))])]
- "")
+ (clobber (scratch:QI))
+ (clobber (reg:CC CC_REG))])])
;; and:SI
@@ -122,12 +228,13 @@
[(parallel [(set (match_dup 0)
(ashift:SI (match_dup 0)
(const_int 16)))
- (clobber (scratch:QI))])
+ (clobber (scratch:QI))
+ (clobber (reg:CC CC_REG))])
(parallel [(set (match_dup 0)
(lshiftrt:SI (match_dup 0)
(const_int 1)))
- (clobber (scratch:QI))])]
- "")
+ (clobber (scratch:QI))
+ (clobber (reg:CC CC_REG))])])
;; Transform (SImode << B) & 0xffff into (SImode) (HImode << B).
@@ -145,22 +252,39 @@
[(parallel [(set (match_dup 5)
(ashift:HI (match_dup 5)
(match_dup 2)))
- (clobber (match_dup 4))])
- (set (match_dup 0)
- (zero_extend:SI (match_dup 5)))]
+ (clobber (match_dup 4))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (match_dup 0)
+ (zero_extend:SI (match_dup 5)))
+ (clobber (reg:CC CC_REG))])]
{
operands[5] = gen_rtx_REG (HImode, REGNO (operands[0]));
})
;; Accept (A >> 30) & 2 and the like.
-(define_insn "*andsi3_lshiftrt_n_sb"
+(define_insn_and_split "*andsi3_lshiftrt_n_sb"
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_int_operand" "n"))
(match_operand:SI 3 "single_one_operand" "n")))]
"exact_log2 (INTVAL (operands[3])) < 16
&& INTVAL (operands[2]) + exact_log2 (INTVAL (operands[3])) == 31"
+ "#"
+ ""
+ [(parallel [(set (match_dup 0)
+ (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
+ (match_dup 3)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*andsi3_lshiftrt_n_sb"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "const_int_operand" "n"))
+ (match_operand:SI 3 "single_one_operand" "n")))
+ (clobber (reg:CC CC_REG))]
+ "exact_log2 (INTVAL (operands[3])) < 16
+ && INTVAL (operands[2]) + exact_log2 (INTVAL (operands[3])) == 31"
{
operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
return "shll.l\\t%S0\;xor.l\\t%S0,%S0\;bst\\t%Z3,%Y0";
@@ -175,172 +299,330 @@
""
"#"
"&& reload_completed"
- [(set (match_dup 0)
- (and:SI (lshiftrt:SI (match_dup 0)
- (const_int 25))
- (const_int 64)))
+ [(parallel [(set (match_dup 0)
+ (and:SI (lshiftrt:SI (match_dup 0) (const_int 25))
+ (const_int 64)))
+ (clobber (reg:CC CC_REG))])
(parallel [(set (match_dup 0)
(ashift:SI (match_dup 0)
(const_int 16)))
- (clobber (scratch:QI))])]
- "")
+ (clobber (scratch:QI))
+ (clobber (reg:CC CC_REG))])])
;; plus:SI
-(define_insn "*addsi3_upper"
+(define_insn_and_split "*addsi3_upper"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
(const_int 65536))
(match_operand:SI 2 "register_operand" "0")))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (plus:SI (mult:SI (match_dup 1) (const_int 65536))
+ (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*addsi3_upper_clobber_regs"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 65536))
+ (match_operand:SI 2 "register_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ ""
"add.w\\t%f1,%e0"
[(set_attr "length" "2")])
-(define_insn "*addsi3_lshiftrt_16_zexthi"
+(define_insn_and_split "*addsi3_lshiftrt_16_zexthi"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
(const_int 16))
(zero_extend:SI (match_operand:HI 2 "register_operand" "0"))))]
""
- "add.w\\t%e1,%f0\;xor.w\\t%e0,%e0\;rotxl.w\\t%e0"
- [(set_attr "length" "6")])
-
-(define_insn_and_split "*addsi3_and_r_1"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (and:SI (match_operand:SI 1 "register_operand" "r")
- (const_int 1))
- (match_operand:SI 2 "register_operand" "0")))]
- ""
"#"
- "&& reload_completed"
- [(set (cc0) (compare (zero_extract:SI (match_dup 1)
- (const_int 1)
- (const_int 0))
- (const_int 0)))
- (set (pc)
- (if_then_else (eq (cc0)
- (const_int 0))
- (label_ref (match_dup 3))
- (pc)))
- (set (match_dup 2)
- (plus:SI (match_dup 2)
- (const_int 1)))
- (match_dup 3)]
- {
- operands[3] = gen_label_rtx ();
- })
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (plus:SI (lshiftrt:SI (match_dup 1) (const_int 16))
+ (zero_extend:SI (match_dup 2))))
+ (clobber (reg:CC CC_REG))])])
-(define_insn_and_split "*addsi3_and_not_r_1"
+(define_insn "*addsi3_lshiftrt_16_zexthi_clobber_flags"
[(set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
- (const_int 1))
- (match_operand:SI 2 "register_operand" "0")))]
+ (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 16))
+ (zero_extend:SI (match_operand:HI 2 "register_operand" "0"))))
+ (clobber (reg:CC CC_REG))]
""
- "#"
- "&& reload_completed"
- [(set (cc0) (compare (zero_extract:SI (match_dup 1)
- (const_int 1)
- (const_int 0))
- (const_int 0)))
- (set (pc)
- (if_then_else (ne (cc0)
- (const_int 0))
- (label_ref (match_dup 3))
- (pc)))
- (set (match_dup 2)
- (plus:SI (match_dup 2)
- (const_int 1)))
- (match_dup 3)]
- {
- operands[3] = gen_label_rtx ();
- })
+ "add.w\\t%e1,%f0\;xor.w\\t%e0,%e0\;rotxl.w\\t%e0"
+ [(set_attr "length" "6")])
+
+;;(define_insn_and_split "*addsi3_and_r_1"
+;; [(set (match_operand:SI 0 "register_operand" "=r")
+;; (plus:SI (and:SI (match_operand:SI 1 "register_operand" "r")
+;; (const_int 1))
+;; (match_operand:SI 2 "register_operand" "0")))]
+;; ""
+;; "#"
+;; "&& reload_completed"
+;; [(set (cc0) (compare (zero_extract:SI (match_dup 1)
+;; (const_int 1)
+;; (const_int 0))
+;; (const_int 0)))
+;; (set (pc)
+;; (if_then_else (eq (cc0)
+;; (const_int 0))
+;; (label_ref (match_dup 3))
+;; (pc)))
+;; (set (match_dup 2)
+;; (plus:SI (match_dup 2)
+;; (const_int 1)))
+;; (match_dup 3)]
+;; {
+;; operands[3] = gen_label_rtx ();
+;; })
+
+;;(define_insn_and_split "*addsi3_and_not_r_1"
+;; [(set (match_operand:SI 0 "register_operand" "=r")
+;; (plus:SI (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
+;; (const_int 1))
+;; (match_operand:SI 2 "register_operand" "0")))]
+;; ""
+;; "#"
+;; "&& reload_completed"
+;; [(set (cc0) (compare (zero_extract:SI (match_dup 1)
+;; (const_int 1)
+;; (const_int 0))
+;; (const_int 0)))
+;; (set (pc)
+;; (if_then_else (ne (cc0)
+;; (const_int 0))
+;; (label_ref (match_dup 3))
+;; (pc)))
+;; (set (match_dup 2)
+;; (plus:SI (match_dup 2)
+;; (const_int 1)))
+;; (match_dup 3)]
+;; {
+;; operands[3] = gen_label_rtx ();
+;; })
;; [ix]or:HI
-(define_insn "*ixorhi3_zext"
+(define_insn_and_split "*ixorhi3_zext"
[(set (match_operand:HI 0 "register_operand" "=r")
(match_operator:HI 1 "iorxor_operator"
[(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))
(match_operand:HI 3 "register_operand" "0")]))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (match_op_dup 1 [(zero_extend:HI (match_dup 2))
+ (match_dup 3)]))
+ (clobber (reg:CC CC_REG))])])
+
+
+(define_insn "*ixorhi3_zext_clobber_flags"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (match_operator:HI 1 "iorxor_operator"
+ [(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))
+ (match_operand:HI 3 "register_operand" "0")]))
+ (clobber (reg:CC CC_REG))]
+ ""
"%c1.b\\t%X2,%s0"
[(set_attr "length" "2")])
;; [ix]or:SI
-(define_insn "*ixorsi3_zext_qi"
+(define_insn_and_split "*ixorsi3_zext_qi"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operator:SI 1 "iorxor_operator"
[(zero_extend:SI (match_operand:QI 2 "register_operand" "r"))
(match_operand:SI 3 "register_operand" "0")]))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (match_op_dup 1 [(zero_extend:SI (match_dup 2))
+ (match_dup 3)]))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*ixorsi3_zext_qi_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (match_operator:SI 1 "iorxor_operator"
+ [(zero_extend:SI (match_operand:QI 2 "register_operand" "r"))
+ (match_operand:SI 3 "register_operand" "0")]))
+ (clobber (reg:CC CC_REG))]
+ ""
"%c1.b\\t%X2,%w0"
[(set_attr "length" "2")])
-(define_insn "*ixorsi3_zext_hi"
+(define_insn_and_split "*ixorsi3_zext_hi"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operator:SI 1 "iorxor_operator"
[(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))
(match_operand:SI 3 "register_operand" "0")]))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (match_op_dup 1 [(zero_extend:SI (match_dup 2))
+ (match_dup 3)]))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*ixorsi3_zext_hi_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (match_operator:SI 1 "iorxor_operator"
+ [(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))
+ (match_operand:SI 3 "register_operand" "0")]))
+ (clobber (reg:CC CC_REG))]
+ ""
"%c1.w\\t%T2,%f0"
[(set_attr "length" "2")])
-(define_insn "*ixorsi3_ashift_16"
+(define_insn_and_split "*ixorsi3_ashift_16"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operator:SI 1 "iorxor_operator"
[(ashift:SI (match_operand:SI 2 "register_operand" "r")
(const_int 16))
(match_operand:SI 3 "register_operand" "0")]))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (match_op_dup 1 [(ashift:SI (match_dup 2) (const_int 16))
+ (match_dup 3)]))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*ixorsi3_ashift_16_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (match_operator:SI 1 "iorxor_operator"
+ [(ashift:SI (match_operand:SI 2 "register_operand" "r")
+ (const_int 16))
+ (match_operand:SI 3 "register_operand" "0")]))
+ (clobber (reg:CC CC_REG))]
+ ""
"%c1.w\\t%f2,%e0"
[(set_attr "length" "2")])
-(define_insn "*ixorsi3_lshiftrt_16"
+(define_insn_and_split "*ixorsi3_lshiftrt_16"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operator:SI 1 "iorxor_operator"
[(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
(const_int 16))
(match_operand:SI 3 "register_operand" "0")]))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (match_op_dup 1 [(lshiftrt:SI (match_dup 2) (const_int 16))
+ (match_dup 3)]))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*ixorsi3_lshiftrt_16_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (match_operator:SI 1 "iorxor_operator"
+ [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+ (const_int 16))
+ (match_operand:SI 3 "register_operand" "0")]))
+ (clobber (reg:CC CC_REG))]
+ ""
"%c1.w\\t%e2,%f0"
[(set_attr "length" "2")])
;; ior:HI
-(define_insn "*iorhi3_ashift_8"
+(define_insn_and_split "*iorhi3_ashift_8"
[(set (match_operand:HI 0 "register_operand" "=r")
(ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r")
(const_int 8))
(match_operand:HI 2 "register_operand" "0")))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (ior:HI (ashift:HI (match_dup 1) (const_int 8))
+ (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorhi3_ashift_8_clobber_flags"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r")
+ (const_int 8))
+ (match_operand:HI 2 "register_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ ""
"or.b\\t%s1,%t0"
[(set_attr "length" "2")])
-(define_insn "*iorhi3_lshiftrt_8"
+(define_insn_and_split "*iorhi3_lshiftrt_8"
[(set (match_operand:HI 0 "register_operand" "=r")
(ior:HI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
(const_int 8))
(match_operand:HI 2 "register_operand" "0")))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (ior:HI (lshiftrt:HI (match_dup 1) (const_int 8))
+ (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorhi3_lshiftrt_8_clobber_flags"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (ior:HI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
+ (const_int 8))
+ (match_operand:HI 2 "register_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ ""
"or.b\\t%t1,%s0"
[(set_attr "length" "2")])
-(define_insn "*iorhi3_two_qi"
+(define_insn_and_split "*iorhi3_two_qi"
[(set (match_operand:HI 0 "register_operand" "=r")
(ior:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
(ashift:HI (match_operand:HI 2 "register_operand" "r")
(const_int 8))))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (ior:HI (zero_extend:HI (match_dup 1))
+ (ashift:HI (match_dup 2) (const_int 8))))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorhi3_two_qi_clobber_flags"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (ior:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
+ (ashift:HI (match_operand:HI 2 "register_operand" "r")
+ (const_int 8))))
+ (clobber (reg:CC CC_REG))]
+ ""
"mov.b\\t%s2,%t0"
[(set_attr "length" "2")])
-(define_insn "*iorhi3_two_qi_mem"
+(define_insn_and_split "*iorhi3_two_qi_mem"
[(set (match_operand:HI 0 "register_operand" "=&r")
(ior:HI (zero_extend:HI (match_operand:QI 1 "memory_operand" "m"))
(ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "m") 0)
(const_int 8))))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (ior:HI (zero_extend:HI (match_dup 1))
+ (ashift:HI (subreg:HI (match_dup 2) 0)
+ (const_int 8))))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorhi3_two_qi_mem_clobber_flags"
+ [(set (match_operand:HI 0 "register_operand" "=&r")
+ (ior:HI (zero_extend:HI (match_operand:QI 1 "memory_operand" "m"))
+ (ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "m") 0)
+ (const_int 8))))
+ (clobber (reg:CC CC_REG))]
+ ""
"mov.b\\t%X2,%t0\;mov.b\\t%X1,%s0"
[(set_attr "length" "16")])
@@ -351,20 +633,34 @@
(const_int 8))))]
"reload_completed
&& byte_accesses_mergeable_p (XEXP (operands[2], 0), XEXP (operands[1], 0))"
- [(set (match_dup 0)
- (match_dup 3))]
+ [(parallel [(set (match_dup 0) (match_dup 3))
+ (clobber (reg:CC CC_REG))])]
{
operands[3] = gen_rtx_MEM (HImode, XEXP (operands[2], 0));
})
;; ior:SI
-(define_insn "*iorsi3_two_hi"
+(define_insn_and_split "*iorsi3_two_hi"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))
(ashift:SI (match_operand:SI 2 "register_operand" "r")
(const_int 16))))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (ior:SI (zero_extend:SI (match_dup 1))
+ (ashift:SI (match_dup 2) (const_int 16))))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorsi3_two_hi_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))
+ (ashift:SI (match_operand:SI 2 "register_operand" "r")
+ (const_int 16))))
+ (clobber (reg:CC CC_REG))]
+ ""
"mov.w\\t%f2,%e0"
[(set_attr "length" "2")])
@@ -377,23 +673,39 @@
""
"#"
"&& reload_completed"
- [(set (match_dup 3)
- (ior:HI (zero_extend:HI (match_dup 1))
- (ashift:HI (subreg:HI (match_dup 2) 0)
- (const_int 8))))
- (set (match_dup 0)
- (zero_extend:SI (match_dup 3)))]
+ [(parallel [(set (match_dup 3)
+ (ior:HI (zero_extend:HI (match_dup 1))
+ (ashift:HI (subreg:HI (match_dup 2) 0)
+ (const_int 8))))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 3)))
+ (clobber (reg:CC CC_REG))])]
{
operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
})
-(define_insn "*iorsi3_e2f"
+(define_insn_and_split "*iorsi3_e2f"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
(const_int -65536))
(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
(const_int 16))))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (ior:SI (and:SI (match_dup 1) (const_int -65536))
+ (lshiftrt:SI (match_dup 2) (const_int 16))))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorsi3_e2f_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int -65536))
+ (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+ (const_int 16))))
+ (clobber (reg:CC CC_REG))]
+ ""
"mov.w\\t%e2,%f0"
[(set_attr "length" "2")])
@@ -405,43 +717,86 @@
""
"#"
"&& reload_completed"
- [(set (match_dup 3)
- (ior:HI (zero_extend:HI (match_dup 1))
- (ashift:HI (match_dup 4)
- (const_int 8))))
- (set (match_dup 0)
- (sign_extend:SI (match_dup 3)))]
+ [(parallel [(set (match_dup 3)
+ (ior:HI (zero_extend:HI (match_dup 1))
+ (ashift:HI (match_dup 4) (const_int 8))))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (match_dup 0) (sign_extend:SI (match_dup 3)))
+ (clobber (reg:CC CC_REG))])]
{
operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
})
-(define_insn "*iorsi3_w"
+(define_insn_and_split "*iorsi3_w"
[(set (match_operand:SI 0 "register_operand" "=r,&r")
(ior:SI (and:SI (match_operand:SI 1 "register_operand" "0,0")
(const_int -256))
(zero_extend:SI (match_operand:QI 2 "general_operand_src" "r,g>"))))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (ior:SI (and:SI (match_dup 1) (const_int -256))
+ (zero_extend:SI (match_dup 2))))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorsi3_w_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r,&r")
+ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0,0")
+ (const_int -256))
+ (zero_extend:SI (match_operand:QI 2 "general_operand_src" "r,g>"))))
+ (clobber (reg:CC CC_REG))]
+ ""
"mov.b\\t%X2,%w0"
[(set_attr "length" "2,8")])
-(define_insn "*iorsi3_ashift_31"
+(define_insn_and_split "*iorsi3_ashift_31"
[(set (match_operand:SI 0 "register_operand" "=&r")
(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
(const_int 31))
(match_operand:SI 2 "register_operand" "0")))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (ior:SI (ashift:SI (match_dup 1) (const_int 31))
+ (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorsi3_ashift_31_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=&r")
+ (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 31))
+ (match_operand:SI 2 "register_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ ""
"rotxl.l\\t%S0\;bor\\t#0,%w1\;rotxr.l\\t%S0"
- [(set_attr "length" "6")
- (set_attr "cc" "set_znv")])
+ [(set_attr "length" "6")])
-(define_insn "*iorsi3_and_ashift"
+(define_insn_and_split "*iorsi3_and_ashift"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "const_int_operand" "n"))
(match_operand:SI 3 "single_one_operand" "n"))
(match_operand:SI 4 "register_operand" "0")))]
"(INTVAL (operands[3]) & ~0xffff) == 0"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (ior:SI (and:SI (ashift:SI (match_dup 1) (match_dup 2))
+ (match_dup 3))
+ (match_dup 4)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorsi3_and_ashift_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "const_int_operand" "n"))
+ (match_operand:SI 3 "single_one_operand" "n"))
+ (match_operand:SI 4 "register_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ "(INTVAL (operands[3]) & ~0xffff) == 0"
{
rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
- INTVAL (operands[2]));
@@ -452,13 +807,29 @@
}
[(set_attr "length" "6")])
-(define_insn "*iorsi3_and_lshiftrt"
+(define_insn_and_split "*iorsi3_and_lshiftrt"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "const_int_operand" "n"))
(match_operand:SI 3 "single_one_operand" "n"))
(match_operand:SI 4 "register_operand" "0")))]
"((INTVAL (operands[3]) << INTVAL (operands[2])) & ~0xffff) == 0"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (ior:SI (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
+ (match_dup 3))
+ (match_dup 4)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorsi3_and_lshiftrt_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "const_int_operand" "n"))
+ (match_operand:SI 3 "single_one_operand" "n"))
+ (match_operand:SI 4 "register_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ "((INTVAL (operands[3]) << INTVAL (operands[2])) & ~0xffff) == 0"
{
rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
+ INTVAL (operands[2]));
@@ -469,27 +840,60 @@
}
[(set_attr "length" "6")])
-(define_insn "*iorsi3_zero_extract"
+(define_insn_and_split "*iorsi3_zero_extract"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
(const_int 1)
(match_operand:SI 2 "const_int_operand" "n"))
(match_operand:SI 3 "register_operand" "0")))]
"INTVAL (operands[2]) < 16"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (ior:SI (zero_extract:SI (match_dup 1)
+ (const_int 1)
+ (match_dup 2))
+ (match_dup 3)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorsi3_zero_extract_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 1)
+ (match_operand:SI 2 "const_int_operand" "n"))
+ (match_operand:SI 3 "register_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ "INTVAL (operands[2]) < 16"
"bld\\t%Z2,%Y1\;bor\\t#0,%w0\;bst\\t#0,%w0"
[(set_attr "length" "6")])
-(define_insn "*iorsi3_and_lshiftrt_n_sb"
+(define_insn_and_split "*iorsi3_and_lshiftrt_n_sb"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
(const_int 30))
(const_int 2))
(match_operand:SI 2 "register_operand" "0")))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (ior:SI (and:SI (lshiftrt:SI (match_dup 1) (const_int 30))
+ (const_int 2))
+ (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorsi3_and_lshiftrt_n_sb_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 30))
+ (const_int 2))
+ (match_operand:SI 2 "register_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ ""
"rotl.l\\t%S1\;rotr.l\\t%S1\;bor\\t#1,%w0\;bst\\t#1,%w0"
[(set_attr "length" "8")])
-(define_insn "*iorsi3_and_lshiftrt_9_sb"
+(define_insn_and_split "*iorsi3_and_lshiftrt_9_sb"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
(const_int 9))
@@ -497,6 +901,25 @@
(match_operand:SI 2 "register_operand" "0")))
(clobber (match_scratch:HI 3 "=&r"))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (ior:SI (and:SI (lshiftrt:SI (match_dup 1) (const_int 9))
+ (const_int 4194304))
+ (match_dup 2)))
+ (clobber (match_dup 3))
+ (clobber (reg:CC CC_REG))])])
+
+
+(define_insn "*iorsi3_and_lshiftrt_9_sb_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 9))
+ (const_int 4194304))
+ (match_operand:SI 2 "register_operand" "0")))
+ (clobber (match_scratch:HI 3 "=&r"))
+ (clobber (reg:CC CC_REG))]
+ ""
{
if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
return "shll.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0";
@@ -528,11 +951,12 @@
[(parallel [(set (match_dup 3)
(ashift:HI (match_dup 3)
(const_int 7)))
- (clobber (scratch:QI))])
- (set (match_dup 0)
- (ior:SI (ashift:SI (match_dup 1)
- (const_int 16))
- (match_dup 0)))]
+ (clobber (scratch:QI))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (match_dup 0)
+ (ior:SI (ashift:SI (match_dup 1) (const_int 16))
+ (match_dup 0)))
+ (clobber (reg:CC CC_REG))])]
{
operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));
})
@@ -546,27 +970,43 @@
"epilogue_completed
&& !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
&& REGNO (operands[0]) != REGNO (operands[1]))"
- [(set (match_dup 2)
- (match_dup 1))
+ [(parallel [(set (match_dup 2) (match_dup 1))
+ (clobber (reg:CC CC_REG))])
(parallel [(set (match_dup 3)
(ashift:HI (match_dup 3)
(const_int 7)))
- (clobber (scratch:QI))])
- (set (match_dup 0)
- (ior:SI (ashift:SI (match_dup 2)
- (const_int 16))
- (match_dup 0)))]
+ (clobber (scratch:QI))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (match_dup 0)
+ (ior:SI (ashift:SI (match_dup 2) (const_int 16))
+ (match_dup 0)))
+ (clobber (reg:CC CC_REG))])]
{
operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));
})
-(define_insn "*iorsi2_and_1_lshiftrt_1"
+(define_insn_and_split "*iorsi2_and_1_lshiftrt_1"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
(const_int 1))
(lshiftrt:SI (match_dup 1)
(const_int 1))))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (ior:SI (and:SI (match_dup 1) (const_int 1))
+ (lshiftrt:SI (match_dup 1) (const_int 1))))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorsi2_and_1_lshiftrt_1_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 1))
+ (lshiftrt:SI (match_dup 1)
+ (const_int 1))))
+ (clobber (reg:CC CC_REG))]
+ ""
"shlr.l\\t%S0\;bor\\t#0,%w0\;bst\\t#0,%w0"
[(set_attr "length" "6")])
@@ -579,14 +1019,15 @@
""
"#"
"&& reload_completed"
- [(set (match_dup 3)
- (ior:HI (ashift:HI (match_dup 4)
- (const_int 8))
- (match_dup 3)))
+ [(parallel [(set (match_dup 3)
+ (ior:HI (ashift:HI (match_dup 4) (const_int 8))
+ (match_dup 3)))
+ (clobber (reg:CC CC_REG))])
(parallel [(set (match_dup 0)
(ashift:SI (match_dup 0)
(const_int 16)))
- (clobber (scratch:QI))])]
+ (clobber (scratch:QI))
+ (clobber (reg:CC CC_REG))])]
{
operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
@@ -602,14 +1043,16 @@
""
"#"
"&& reload_completed"
- [(set (match_dup 3)
- (ior:HI (zero_extend:HI (match_dup 1))
- (ashift:HI (subreg:HI (match_dup 2) 0)
- (const_int 8))))
+ [(parallel [(set (match_dup 3)
+ (ior:HI (zero_extend:HI (match_dup 1))
+ (ashift:HI (subreg:HI (match_dup 2) 0)
+ (const_int 8))))
+ (clobber (reg:CC CC_REG))])
(parallel [(set (match_dup 0)
(ashift:SI (match_dup 0)
(const_int 16)))
- (clobber (scratch:QI))])]
+ (clobber (scratch:QI))
+ (clobber (reg:CC CC_REG))])]
{
operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
})
@@ -637,11 +1080,12 @@
[(parallel [(set (match_dup 3)
(ashift:HI (match_dup 3)
(const_int 7)))
- (clobber (scratch:QI))])
- (set (match_dup 0)
- (plus:SI (mult:SI (match_dup 1)
- (const_int 65536))
- (match_dup 0)))]
+ (clobber (scratch:QI))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (match_dup 0)
+ (plus:SI (mult:SI (match_dup 1) (const_int 65536))
+ (match_dup 0)))
+ (clobber (reg:CC CC_REG))])]
{
operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));
})
@@ -655,16 +1099,17 @@
"epilogue_completed
&& !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
&& REGNO (operands[0]) != REGNO (operands[1]))"
- [(set (match_dup 2)
- (match_dup 1))
+ [(parallel [(set (match_dup 2) (match_dup 1))
+ (clobber (reg:CC CC_REG))])
(parallel [(set (match_dup 3)
(ashift:HI (match_dup 3)
(const_int 7)))
- (clobber (scratch:QI))])
- (set (match_dup 0)
- (plus:SI (mult:SI (match_dup 2)
- (const_int 65536))
- (match_dup 0)))]
+ (clobber (scratch:QI))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (match_dup 0)
+ (plus:SI (mult:SI (match_dup 2) (const_int 65536))
+ (match_dup 0)))
+ (clobber (reg:CC CC_REG))])]
{
operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));
})
@@ -681,93 +1126,145 @@
[(parallel [(set (match_dup 2)
(ashift:HI (match_dup 2)
(const_int 8)))
- (clobber (scratch:QI))])
- (set (match_dup 0)
- (sign_extend:SI (match_dup 2)))
+ (clobber (scratch:QI))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (match_dup 0) (sign_extend:SI (match_dup 2)))
+ (clobber (reg:CC CC_REG))])
(parallel [(set (match_dup 0)
(ashiftrt:SI (match_dup 0)
(const_int 1)))
- (clobber (scratch:QI))])]
+ (clobber (scratch:QI))
+ (clobber (reg:CC CC_REG))])]
{
operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
})
;; Storing a part of HImode to QImode.
-(define_insn ""
+(define_insn_and_split ""
[(set (match_operand:QI 0 "general_operand_dst" "=rm<")
(subreg:QI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
(const_int 8)) 1))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (subreg:QI (lshiftrt:HI (match_dup 1)
+ (const_int 8)) 1))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
+ (subreg:QI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
+ (const_int 8)) 1))
+ (clobber (reg:CC CC_REG))]
+ ""
"mov.b\\t%t1,%R0"
- [(set_attr "cc" "set_znv")
- (set_attr "length" "8")])
+ [(set_attr "length" "8")])
;; Storing a part of SImode to QImode.
-(define_insn ""
+(define_insn_and_split ""
[(set (match_operand:QI 0 "general_operand_dst" "=rm<")
(subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
(const_int 8)) 3))]
""
- "mov.b\\t%x1,%R0"
- [(set_attr "cc" "set_znv")
- (set_attr "length" "8")])
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (subreg:QI (lshiftrt:SI (match_dup 1) (const_int 8)) 3))
+ (clobber (reg:CC CC_REG))])])
(define_insn ""
[(set (match_operand:QI 0 "general_operand_dst" "=rm<")
(subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 8)) 3))
+ (clobber (reg:CC CC_REG))]
+ ""
+ "mov.b\\t%x1,%R0"
+ [(set_attr "length" "8")])
+
+(define_insn_and_split ""
+ [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
+ (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
(const_int 16)) 3))
(clobber (match_scratch:SI 2 "=&r"))]
""
- "mov.w\\t%e1,%f2\;mov.b\\t%w2,%R0"
- [(set_attr "cc" "set_znv")
- (set_attr "length" "10")])
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (subreg:QI (lshiftrt:SI (match_dup 1) (const_int 16)) 3))
+ (clobber (match_dup 2))
+ (clobber (reg:CC CC_REG))])])
(define_insn ""
[(set (match_operand:QI 0 "general_operand_dst" "=rm<")
(subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 16)) 3))
+ (clobber (match_scratch:SI 2 "=&r"))
+ (clobber (reg:CC CC_REG))]
+ ""
+ "mov.w\\t%e1,%f2\;mov.b\\t%w2,%R0"
+ [(set_attr "length" "10")])
+
+(define_insn_and_split ""
+ [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
+ (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
(const_int 24)) 3))
(clobber (match_scratch:SI 2 "=&r"))]
""
- "mov.w\\t%e1,%f2\;mov.b\\t%x2,%R0"
- [(set_attr "cc" "set_znv")
- (set_attr "length" "10")])
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (subreg:QI (lshiftrt:SI (match_dup 1) (const_int 24)) 3))
+ (clobber (match_dup 2))
+ (clobber (reg:CC CC_REG))])])
-(define_insn_and_split ""
- [(set (pc)
- (if_then_else (eq (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
- (const_int 1)
- (const_int 7))
- (const_int 0))
- (match_operand 1 "pc_or_label_operand" "")
- (match_operand 2 "pc_or_label_operand" "")))]
- "operands[1] == pc_rtx || operands[2] == pc_rtx"
- "#"
- ""
- [(set (cc0) (compare (match_dup 0)
- (const_int 0)))
- (set (pc)
- (if_then_else (ge (cc0)
- (const_int 0))
- (match_dup 1)
- (match_dup 2)))])
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
+ (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 24)) 3))
+ (clobber (match_scratch:SI 2 "=&r"))
+ (clobber (reg:CC CC_REG))]
+ ""
+ "mov.w\\t%e1,%f2\;mov.b\\t%x2,%R0"
+ [(set_attr "length" "10")])
-(define_insn_and_split ""
- [(set (pc)
- (if_then_else (ne (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
- (const_int 1)
- (const_int 7))
- (const_int 0))
- (match_operand 1 "pc_or_label_operand" "")
- (match_operand 2 "pc_or_label_operand" "")))]
- "operands[1] == pc_rtx || operands[2] == pc_rtx"
- "#"
- ""
- [(set (cc0) (compare (match_dup 0)
- (const_int 0)))
- (set (pc)
- (if_then_else (lt (cc0)
- (const_int 0))
- (match_dup 1)
- (match_dup 2)))])
+;;(define_insn_and_split ""
+;; [(set (pc)
+;; (if_then_else (eq (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
+;; (const_int 1)
+;; (const_int 7))
+;; (const_int 0))
+;; (label_ref (match_operand 1 "" ""))
+;; (pc)))]
+;; ""
+;; "#"
+;; ""
+;; [(set (cc0) (compare (match_dup 0)
+;; (const_int 0)))
+;; (set (pc)
+;; (if_then_else (ge (cc0)
+;; (const_int 0))
+;; (label_ref (match_dup 1))
+;; (pc)))]
+;; "")
+;;
+;; (define_insn_and_split ""
+;; [(set (pc)
+;; (if_then_else (ne (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
+;; (const_int 1)
+;; (const_int 7))
+;; (const_int 0))
+;; (label_ref (match_operand 1 "" ""))
+;; (pc)))]
+;; ""
+;; "#"
+;; ""
+;; [(set (cc0) (compare (match_dup 0)
+;; (const_int 0)))
+;; (set (pc)
+;; (if_then_else (lt (cc0)
+;; (const_int 0))
+;; (label_ref (match_dup 1))
+;; (pc)))]
+;; "")
diff --git a/gcc/config/h8300/constraints.md b/gcc/config/h8300/constraints.md
index d245182..1d80152 100644
--- a/gcc/config/h8300/constraints.md
+++ b/gcc/config/h8300/constraints.md
@@ -152,7 +152,7 @@
(define_constraint "R"
"@internal"
(and (match_code "const_int")
- (match_test "!h8300_shift_needs_scratch_p (ival, QImode)")))
+ (match_test "!h8300_shift_needs_scratch_p (ival, QImode, CLOBBER)")))
(define_constraint "C"
"@internal"
@@ -161,12 +161,12 @@
(define_constraint "S"
"@internal"
(and (match_code "const_int")
- (match_test "!h8300_shift_needs_scratch_p (ival, HImode)")))
+ (match_test "!h8300_shift_needs_scratch_p (ival, HImode, CLOBBER)")))
(define_constraint "T"
"@internal"
(and (match_code "const_int")
- (match_test "!h8300_shift_needs_scratch_p (ival, SImode)")))
+ (match_test "!h8300_shift_needs_scratch_p (ival, SImode, CLOBBER)")))
(define_constraint "U"
"An operand valid for a bset destination."
diff --git a/gcc/config/h8300/divmod.md b/gcc/config/h8300/divmod.md
index 7e0d7f0..b5ab6b7 100644
--- a/gcc/config/h8300/divmod.md
+++ b/gcc/config/h8300/divmod.md
@@ -2,23 +2,45 @@
;; DIVIDE/MOD INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_insn "udiv<mode>3"
+(define_insn_and_split "udiv<mode>3"
[(set (match_operand:HSI 0 "register_operand" "=r")
(udiv:HSI (match_operand:HSI 1 "register_operand" "0")
(match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
"TARGET_H8300SX"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (udiv:HSI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "udiv<mode>3_clobber_flags"
+ [(set (match_operand:HSI 0 "register_operand" "=r")
+ (udiv:HSI (match_operand:HSI 1 "register_operand" "0")
+ (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))
+ (clobber (reg:CC CC_REG))]
+ "TARGET_H8300SX"
{ return <MODE>mode == HImode ? "divu.w\\t%T2,%T0" : "divu.l\\t%S2,%S0"; }
[(set_attr "length" "4")])
-(define_insn "div<mode>3"
+(define_insn_and_split "div<mode>3"
[(set (match_operand:HSI 0 "register_operand" "=r")
(div:HSI (match_operand:HSI 1 "register_operand" "0")
(match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
"TARGET_H8300SX"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (div:HSI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "div<mode>3_clobber_flags"
+ [(set (match_operand:HSI 0 "register_operand" "=r")
+ (div:HSI (match_operand:HSI 1 "register_operand" "0")
+ (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))
+ (clobber (reg:CC CC_REG))]
+ "TARGET_H8300SX"
{ return <MODE>mode == HImode ? "divs.w\\t%T2,%T0" : "divs.l\\t%S2,%S0"; }
[(set_attr "length" "4")])
-(define_insn "udivmodqi4"
+(define_insn_and_split "udivmodqi4"
[(set (match_operand:QI 0 "register_operand" "=r")
(truncate:QI
(udiv:HI
@@ -30,6 +52,30 @@
(match_dup 1)
(zero_extend:HI (match_dup 2)))))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (truncate:QI
+ (udiv:HI (match_dup 1)
+ (zero_extend:HI (match_dup 2)))))
+ (set (match_dup 3) (truncate:QI
+ (umod:HI (match_dup 1)
+ (zero_extend:HI (match_dup 2)))))
+ (clobber (reg:CC CC_REG))])])
+
+
+(define_insn "udivmodqi4_clobber_flags"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (truncate:QI
+ (udiv:HI
+ (match_operand:HI 1 "register_operand" "0")
+ (zero_extend:HI (match_operand:QI 2 "register_operand" "r")))))
+ (set (match_operand:QI 3 "register_operand" "=r")
+ (truncate:QI
+ (umod:HI
+ (match_dup 1)
+ (zero_extend:HI (match_dup 2)))))
+ (clobber (reg:CC CC_REG))]
+ ""
{
if (find_reg_note (insn, REG_UNUSED, operands[3]))
return "divxu.b\\t%X2,%T0";
@@ -38,7 +84,7 @@
}
[(set_attr "length" "4")])
-(define_insn "divmodqi4"
+(define_insn_and_split "divmodqi4"
[(set (match_operand:QI 0 "register_operand" "=r")
(truncate:QI
(div:HI
@@ -50,6 +96,29 @@
(match_dup 1)
(sign_extend:HI (match_dup 2)))))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (truncate:QI
+ (div:HI (match_dup 1)
+ (sign_extend:HI (match_dup 2)))))
+ (set (match_dup 3) (truncate:QI
+ (mod:HI (match_dup 1)
+ (sign_extend:HI (match_dup 2)))))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "divmodqi4_clobber_flags"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (truncate:QI
+ (div:HI
+ (match_operand:HI 1 "register_operand" "0")
+ (sign_extend:HI (match_operand:QI 2 "register_operand" "r")))))
+ (set (match_operand:QI 3 "register_operand" "=r")
+ (truncate:QI
+ (mod:HI
+ (match_dup 1)
+ (sign_extend:HI (match_dup 2)))))
+ (clobber (reg:CC CC_REG))]
+ ""
{
if (find_reg_note (insn, REG_UNUSED, operands[3]))
return "divxs.b\\t%X2,%T0";
@@ -58,7 +127,7 @@
}
[(set_attr "length" "6")])
-(define_insn "udivmodhi4"
+(define_insn_and_split "udivmodhi4"
[(set (match_operand:HI 0 "register_operand" "=r")
(truncate:HI
(udiv:SI
@@ -70,6 +139,29 @@
(match_dup 1)
(zero_extend:SI (match_dup 2)))))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (truncate:HI
+ (udiv:SI (match_dup 1)
+ (zero_extend:SI (match_dup 2)))))
+ (set (match_dup 3) (truncate:HI
+ (umod:SI (match_dup 1)
+ (zero_extend:SI (match_dup 2)))))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "udivmodhi4_clobber_flags"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (truncate:HI
+ (udiv:SI
+ (match_operand:SI 1 "register_operand" "0")
+ (zero_extend:SI (match_operand:HI 2 "register_operand" "r")))))
+ (set (match_operand:HI 3 "register_operand" "=r")
+ (truncate:HI
+ (umod:SI
+ (match_dup 1)
+ (zero_extend:SI (match_dup 2)))))
+ (clobber (reg:CC CC_REG))]
+ ""
{
if (find_reg_note (insn, REG_UNUSED, operands[3]))
return "divxu.w\\t%T2,%S0";
@@ -78,7 +170,7 @@
}
[(set_attr "length" "4")])
-(define_insn "divmodhi4"
+(define_insn_and_split "divmodhi4"
[(set (match_operand:HI 0 "register_operand" "=r")
(truncate:HI
(div:SI
@@ -90,6 +182,29 @@
(match_dup 1)
(sign_extend:SI (match_dup 2)))))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (truncate:HI
+ (div:SI (match_dup 1)
+ (sign_extend:SI (match_dup 2)))))
+ (set (match_dup 3) (truncate:HI
+ (mod:SI (match_dup 1)
+ (sign_extend:SI (match_dup 2)))))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "divmodhi4_clobber_flags"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (truncate:HI
+ (div:SI
+ (match_operand:SI 1 "register_operand" "0")
+ (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))))
+ (set (match_operand:HI 3 "register_operand" "=r")
+ (truncate:HI
+ (mod:SI
+ (match_dup 1)
+ (sign_extend:SI (match_dup 2)))))
+ (clobber (reg:CC CC_REG))]
+ ""
{
if (find_reg_note (insn, REG_UNUSED, operands[3]))
return "divxs.w\\t%T2,%S0";
diff --git a/gcc/config/h8300/extensions.md b/gcc/config/h8300/extensions.md
index cf6fb6d1..7631230 100644
--- a/gcc/config/h8300/extensions.md
+++ b/gcc/config/h8300/extensions.md
@@ -11,15 +11,24 @@
operands[1] = force_reg (QImode, operands[1]);
})
-(define_insn "*zero_extendqihi2_h8300hs"
+(define_insn_and_split "*zero_extendqihi2"
[(set (match_operand:HI 0 "register_operand" "=r,r")
(zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (zero_extend:HI (match_dup 1)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*zero_extendqihi2_clobber_flags"
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))
+ (clobber (reg:CC CC_REG))]
+ ""
"@
extu.w %T0
#"
- [(set_attr "length" "2,10")
- (set_attr "cc" "set_znv,set_znv")])
+ [(set_attr "length" "2,10")])
;; Split the zero extension of a general operand (actually a memory
;; operand) into a load of the operand and the actual zero extension
@@ -28,34 +37,36 @@
(define_split
[(set (match_operand:HI 0 "register_operand" "")
- (zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))]
+ (zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))
+ (clobber (reg:CC CC_REG))]
"reload_completed"
- [(set (match_dup 2)
- (match_dup 1))
- (set (match_dup 0)
- (zero_extend:HI (match_dup 2)))]
+ [(set (match_dup 2) (match_dup 1))
+ (parallel [(set (match_dup 0) (zero_extend:HI (match_dup 2)))
+ (clobber (reg:CC CC_REG))])]
{
operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));
})
-(define_insn "*zero_extendqisi2_h8300hs"
+(define_insn "*zero_extendqisi2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
- "!TARGET_H8300SX"
+ "!reload_completed && !TARGET_H8300SX"
"#")
+;; Two cases for the !H8/SX target. One where there is an overlap
+;; between the source and destination, one where there is no overlap
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
"!TARGET_H8300SX
&& reg_overlap_mentioned_p (operands[0], operands[1])
&& reload_completed"
- [(set (match_dup 2)
- (match_dup 1))
- (set (match_dup 3)
- (zero_extend:HI (match_dup 2)))
- (set (match_dup 0)
- (zero_extend:SI (match_dup 3)))]
+ [(parallel [(set (match_dup 2) (match_dup 1))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (match_dup 3) (zero_extend:HI (match_dup 2)))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 3)))
+ (clobber (reg:CC CC_REG))])]
{
operands[2] = gen_lowpart (QImode, operands[0]);
operands[3] = gen_lowpart (HImode, operands[0]);
@@ -67,21 +78,30 @@
"!TARGET_H8300SX
&& !reg_overlap_mentioned_p (operands[0], operands[1])
&& reload_completed"
- [(set (match_dup 0)
- (const_int 0))
- (set (strict_low_part (match_dup 2))
- (match_dup 1))]
+ [(parallel [(set (match_dup 0) (const_int 0))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (strict_low_part (match_dup 2)) (match_dup 1))
+ (clobber (reg:CC CC_REG))])]
{
operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));
})
-(define_insn "*zero_extendqisi2_h8sx"
+(define_insn_and_split "*zero_extendqisi2_h8sx"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (match_operand:QI 1 "register_operand" "0")))]
"TARGET_H8300SX"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*zero_extendqisi2_h8sx_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (match_operand:QI 1 "register_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ "TARGET_H8300SX"
"extu.l\t#2,%0"
- [(set_attr "length" "2")
- (set_attr "cc" "set_znv")])
+ [(set_attr "length" "2")])
(define_expand "zero_extendhisi2"
[(set (match_operand:SI 0 "register_operand" "")
@@ -89,13 +109,22 @@
""
"")
-(define_insn "*zero_extendhisi2_h8300hs"
+(define_insn_and_split "*zero_extendhisi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*zero_extendhisi2_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ ""
"extu.l %S0"
- [(set_attr "length" "2")
- (set_attr "cc" "set_znv")])
+ [(set_attr "length" "2")])
(define_expand "extendqi<mode>2"
[(set (match_operand:HSI 0 "register_operand" "")
@@ -103,39 +132,57 @@
""
"")
-(define_insn "*extendqihi2_h8300hs"
+(define_insn_and_split "*extendqihi2"
[(set (match_operand:HI 0 "register_operand" "=r")
(sign_extend:HI (match_operand:QI 1 "register_operand" "0")))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (sign_extend:HI (match_dup 1)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*extendqihi2_clobber_flags"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (sign_extend:HI (match_operand:QI 1 "register_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ ""
"exts.w %T0"
- [(set_attr "length" "2")
- (set_attr "cc" "set_znv")])
+ [(set_attr "length" "2")])
;; The following pattern is needed because without the pattern, the
;; combiner would split (sign_extend:SI (reg:QI)) into two 24-bit
;; shifts, one ashift and one ashiftrt.
-(define_insn_and_split "*extendqisi2_h8300hs"
+(define_insn_and_split "*extendqisi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
"!TARGET_H8300SX"
"#"
"&& reload_completed"
- [(set (match_dup 2)
- (sign_extend:HI (match_dup 1)))
- (set (match_dup 0)
- (sign_extend:SI (match_dup 2)))]
+ [(parallel [(set (match_dup 2) (sign_extend:HI (match_dup 1)))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (match_dup 0) (sign_extend:SI (match_dup 2)))
+ (clobber (reg:CC CC_REG))])]
{
operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
})
-(define_insn "*extendqisi2_h8sx"
+(define_insn_and_split "*extendqisi2_h8sx"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
"TARGET_H8300SX"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*extendqisi2_h8sx_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (match_operand:QI 1 "register_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ "TARGET_H8300SX"
"exts.l\t#2,%0"
- [(set_attr "length" "2")
- (set_attr "cc" "set_znv")])
+ [(set_attr "length" "2")])
(define_expand "extendhisi2"
[(set (match_operand:SI 0 "register_operand" "")
@@ -143,10 +190,19 @@
""
"")
-(define_insn "*extendhisi2_h8300hs"
+(define_insn_and_split "*extendhisi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI (match_operand:HI 1 "register_operand" "0")))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*extendhisi2_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (match_operand:HI 1 "register_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ ""
"exts.l %S0"
- [(set_attr "length" "2")
- (set_attr "cc" "set_znv")])
+ [(set_attr "length" "2")])
diff --git a/gcc/config/h8300/genmova.sh b/gcc/config/h8300/genmova.sh
index 22b01cc..8ab018f 100644
--- a/gcc/config/h8300/genmova.sh
+++ b/gcc/config/h8300/genmova.sh
@@ -71,8 +71,7 @@ for s in QI HI; do
(match_operand:$d 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/b.l @(%o2%C2,$src),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
EOF
;;
@@ -115,8 +114,7 @@ EOF
(match_operand:$d 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/$opsize.l @(%o2%C2,$src),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
EOF
;;
@@ -134,8 +132,7 @@ EOF
(const_int $amount)))]
"TARGET_H8300SX"
"mova/$opsize.l @(0,$src),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:$d 0 "register_operand" "=r,r")
@@ -144,8 +141,7 @@ EOF
(match_operand:$d 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/$opsize.l @(%o2%C2,$src),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
EOF
@@ -174,8 +170,7 @@ EOF
(const_int $mask)))]
"TARGET_H8300SX"
"mova/$opsize.l @(0,$src),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:$d 0 "register_operand" "=r")
@@ -185,8 +180,7 @@ EOF
(match_operand:$d 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/$opsize.l @(%o2%C2,$src),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
EOF
done
diff --git a/gcc/config/h8300/h8300-modes.def b/gcc/config/h8300/h8300-modes.def
new file mode 100644
index 0000000..2f36c7e
--- /dev/null
+++ b/gcc/config/h8300/h8300-modes.def
@@ -0,0 +1,21 @@
+/* Definitions of target machine for GNU compiler.
+ Copyright (C) 2020 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/>. */
+
+CC_MODE (CCZN);
+CC_MODE (CCZNV);
diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h
index 2416741..2d90036 100644
--- a/gcc/config/h8300/h8300-protos.h
+++ b/gcc/config/h8300/h8300-protos.h
@@ -26,8 +26,8 @@ along with GCC; see the file COPYING3. If not see
/* Declarations for functions used in insn-output.c. */
#ifdef RTX_CODE
extern unsigned int compute_mov_length (rtx *);
-extern const char *output_plussi (rtx *);
-extern unsigned int compute_plussi_length (rtx *);
+extern const char *output_plussi (rtx *, bool);
+extern unsigned int compute_plussi_length (rtx *, bool);
extern const char *output_a_shift (rtx *);
extern unsigned int compute_a_shift_length (rtx, rtx *);
extern const char *output_a_rotate (enum rtx_code, rtx *);
@@ -35,19 +35,21 @@ extern unsigned int compute_a_rotate_length (rtx *);
extern const char *output_simode_bld (int, rtx[]);
extern void final_prescan_insn (rtx_insn *, rtx *, int);
extern int h8300_expand_movsi (rtx[]);
+extern machine_mode h8300_select_cc_mode (RTX_CODE, rtx, rtx);
extern void notice_update_cc (rtx, rtx_insn *);
extern const char *output_logical_op (machine_mode, rtx *);
extern unsigned int compute_logical_op_length (machine_mode,
rtx *);
+
+extern int compute_logical_op_cc (machine_mode, rtx *);
+extern int compute_a_shift_cc (rtx, rtx *);
#ifdef HAVE_ATTR_cc
extern enum attr_cc compute_plussi_cc (rtx *);
-extern enum attr_cc compute_a_shift_cc (rtx, rtx *);
-extern enum attr_cc compute_logical_op_cc (machine_mode, rtx *);
#endif
extern void h8300_expand_branch (rtx[]);
extern void h8300_expand_store (rtx[]);
extern bool expand_a_shift (machine_mode, enum rtx_code, rtx[]);
-extern int h8300_shift_needs_scratch_p (int, machine_mode);
+extern int h8300_shift_needs_scratch_p (int, machine_mode, rtx_code);
extern int expand_a_rotate (rtx[]);
extern int fix_bit_operand (rtx *, enum rtx_code);
extern int h8300_adjust_insn_length (rtx, int);
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 6875cd9..31e23b2 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -132,13 +132,13 @@ static int pragma_interrupt;
static int pragma_saveall;
static const char *const names_big[] =
-{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" };
+{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "cc" };
static const char *const names_extended[] =
-{ "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7" };
+{ "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7", "cc" };
static const char *const names_upper_extended[] =
-{ "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7" };
+{ "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "cc" };
/* Points to one of the above. */
/* ??? The above could be put in an array indexed by CPU_TYPE. */
@@ -469,11 +469,11 @@ h8300_emit_stack_adjustment (int sign, HOST_WIDE_INT size, bool in_prologue)
stack_pointer_rtx,
GEN_INT (sign * size)));
if (size < 4)
- F (x, in_prologue);
+ F (x, 0);
}
else
F (emit_insn (gen_addsi3 (stack_pointer_rtx,
- stack_pointer_rtx, GEN_INT (sign * size))), in_prologue);
+ stack_pointer_rtx, GEN_INT (sign * size))), 0);
}
/* Round up frame size SIZE. */
@@ -520,7 +520,7 @@ push (int rn, bool in_prologue)
x = gen_push_h8300hs_advanced (reg);
else
x = gen_push_h8300hs_normal (reg);
- x = F (emit_insn (x), in_prologue);
+ x = F (emit_insn (x), 0);
add_reg_note (x, REG_INC, stack_pointer_rtx);
return x;
}
@@ -756,7 +756,7 @@ h8300_expand_prologue (void)
{
/* Push fp. */
push (HARD_FRAME_POINTER_REGNUM, true);
- F (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx), true);
+ F (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx), 0);
}
/* Push the rest of the registers in ascending order. */
@@ -1199,6 +1199,16 @@ h8300_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED, int outer_code,
return true;
case COMPARE:
+ case NE:
+ case EQ:
+ case GE:
+ case GT:
+ case LE:
+ case LT:
+ case GEU:
+ case GTU:
+ case LEU:
+ case LTU:
if (XEXP (x, 1) == const0_rtx)
*total = 0;
return false;
@@ -1508,10 +1518,20 @@ h8300_print_operand (FILE *file, rtx x, int code)
}
break;
case 'j':
- fputs (cond_string (GET_CODE (x)), file);
+ if (GET_CODE (x) == LT && GET_MODE (XEXP (x, 0)) == E_CCZNmode)
+ fputs ("mi", file);
+ else if (GET_CODE (x) == GE && GET_MODE (XEXP (x, 0)) == E_CCZNmode)
+ fputs ("pl", file);
+ else
+ fputs (cond_string (GET_CODE (x)), file);
break;
case 'k':
- fputs (cond_string (reverse_condition (GET_CODE (x))), file);
+ if (GET_CODE (x) == LT && GET_MODE (XEXP (x, 0)) == E_CCZNmode)
+ fputs ("pl", file);
+ else if (GET_CODE (x) == GE && GET_MODE (XEXP (x, 0)) == E_CCZNmode)
+ fputs ("mi", file);
+ else
+ fputs (cond_string (reverse_condition (GET_CODE (x))), file);
break;
case 'm':
gcc_assert (GET_CODE (x) == CONST_INT);
@@ -1920,72 +1940,22 @@ h8300_return_addr_rtx (int count, rtx frame)
return ret;
}
-/* Update the condition code from the insn. */
-void
-notice_update_cc (rtx body, rtx_insn *insn)
+machine_mode
+h8300_select_cc_mode (enum rtx_code cond, rtx op0, rtx op1)
{
- rtx set;
+ if (op1 == const0_rtx
+ && (cond == EQ || cond == NE || cond == LT || cond == GE)
+ && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
+ || GET_CODE (op0) == NEG || GET_CODE (op0) == AND
+ || GET_CODE (op0) == IOR || GET_CODE (op0) == XOR
+ || GET_CODE (op0) == NOT || GET_CODE (op0) == ASHIFT
+ || GET_CODE (op0) == REG || GET_CODE (op0) == MULT))
+ return CCZNmode;
- switch (get_attr_cc (insn))
- {
- case CC_NONE:
- /* Insn does not affect CC at all. */
- break;
-
- case CC_NONE_0HIT:
- /* Insn does not change CC, but the 0'th operand has been changed. */
- if (cc_status.value1 != 0
- && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))
- cc_status.value1 = 0;
- if (cc_status.value2 != 0
- && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value2))
- cc_status.value2 = 0;
- break;
-
- case CC_SET_ZN:
- /* Insn sets the Z,N flags of CC to recog_data.operand[0].
- The V flag is unusable. The C flag may or may not be known but
- that's ok because alter_cond will change tests to use EQ/NE. */
- CC_STATUS_INIT;
- cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
- set = single_set (insn);
- cc_status.value1 = SET_SRC (set);
- if (SET_DEST (set) != cc0_rtx)
- cc_status.value2 = SET_DEST (set);
- break;
-
- case CC_SET_ZNV:
- /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
- The C flag may or may not be known but that's ok because
- alter_cond will change tests to use EQ/NE. */
- CC_STATUS_INIT;
- cc_status.flags |= CC_NO_CARRY;
- set = single_set (insn);
- cc_status.value1 = SET_SRC (set);
- if (SET_DEST (set) != cc0_rtx)
- {
- /* If the destination is STRICT_LOW_PART, strip off
- STRICT_LOW_PART. */
- if (GET_CODE (SET_DEST (set)) == STRICT_LOW_PART)
- cc_status.value2 = XEXP (SET_DEST (set), 0);
- else
- cc_status.value2 = SET_DEST (set);
- }
- break;
-
- case CC_COMPARE:
- /* The insn is a compare instruction. */
- CC_STATUS_INIT;
- cc_status.value1 = SET_SRC (body);
- break;
-
- case CC_CLOBBER:
- /* Insn doesn't leave CC in a usable state. */
- CC_STATUS_INIT;
- break;
- }
+ return CCmode;
}
+
/* Given that X occurs in an address of the form (plus X constant),
return the part of X that is expected to be a register. There are
@@ -2344,8 +2314,18 @@ static unsigned int
h8300_binary_length (rtx_insn *insn, const h8300_length_table *table)
{
rtx set;
+ rtx pattern;
- set = single_set (insn);
+ if (GET_CODE (insn) != INSN)
+ gcc_unreachable ();
+
+ pattern = PATTERN (insn);
+ if (GET_CODE (pattern) == PARALLEL
+ && GET_CODE (XVECEXP (pattern, 0, 0)) == SET
+ && GET_CODE (SET_SRC (XVECEXP (pattern, 0, 0))) == COMPARE)
+ set = XVECEXP (pattern, 0, 1);
+ else
+ set = single_set (insn);
gcc_assert (set);
if (BINARY_P (SET_SRC (set)))
@@ -2678,7 +2658,7 @@ compute_mov_length (rtx *operands)
/* Output an addition insn. */
const char *
-output_plussi (rtx *operands)
+output_plussi (rtx *operands, bool need_flags)
{
machine_mode mode = GET_MODE (operands[0]);
@@ -2698,25 +2678,54 @@ output_plussi (rtx *operands)
switch ((unsigned int) intval & 0xffffffff)
{
+ /* INC/DEC set the flags, but adds/subs do not. So if we
+ need flags, use the former and not the latter. */
case 0x00000001:
+ if (need_flags)
+ return "inc.l\t#1,%S0";
+ else
+ return "adds\t%2,%S0";
case 0x00000002:
- case 0x00000004:
- return "adds\t%2,%S0";
-
+ if (need_flags)
+ return "inc.l\t#2,%S0";
+ else
+ return "adds\t%2,%S0";
case 0xffffffff:
+ if (need_flags)
+ return "dec.l\t#1,%S0";
+ else
+ return "subs\t%G2,%S0";
case 0xfffffffe:
+ if (need_flags)
+ return "dec.l\t#2,%S0";
+ else
+ return "subs\t%G2,%S0";
+
+ /* These six cases have optimized paths when we do not
+ need flags. Otherwise we let them fallthru. */
+ case 0x00000004:
+ if (!need_flags)
+ return "adds\t%2,%S0";
+
case 0xfffffffc:
- return "subs\t%G2,%S0";
+ if (!need_flags)
+ return "subs\t%G2,%S0";
case 0x00010000:
case 0x00020000:
- operands[2] = GEN_INT (intval >> 16);
- return "inc.w\t%2,%e0";
+ if (!need_flags)
+ {
+ operands[2] = GEN_INT (intval >> 16);
+ return "inc.w\t%2,%e0";
+ }
case 0xffff0000:
case 0xfffe0000:
- operands[2] = GEN_INT (intval >> 16);
- return "dec.w\t%G2,%e0";
+ if (!need_flags)
+ {
+ operands[2] = GEN_INT (intval >> 16);
+ return "dec.w\t%G2,%e0";
+ }
}
/* See if we can finish with 4 bytes. */
@@ -2740,7 +2749,7 @@ output_plussi (rtx *operands)
/* Compute the length of an addition insn. */
unsigned int
-compute_plussi_length (rtx *operands)
+compute_plussi_length (rtx *operands, bool need_flags)
{
machine_mode mode = GET_MODE (operands[0]);
@@ -2762,21 +2771,31 @@ compute_plussi_length (rtx *operands)
{
case 0x00000001:
case 0x00000002:
- case 0x00000004:
return 2;
+ case 0x00000004:
+ if (need_flags)
+ return 6;
+ else
+ return 2;
case 0xffffffff:
case 0xfffffffe:
- case 0xfffffffc:
return 2;
+ case 0xfffffffc:
+ if (need_flags)
+ return 6;
+ else
+ return 2;
case 0x00010000:
case 0x00020000:
- return 2;
+ if (!need_flags)
+ return 2;
case 0xffff0000:
case 0xfffe0000:
- return 2;
+ if (!need_flags)
+ return 2;
}
/* See if we can finish with 4 bytes. */
@@ -2795,7 +2814,7 @@ compute_plussi_length (rtx *operands)
/* Compute which flag bits are valid after an addition insn. */
-enum attr_cc
+enum attr_old_cc
compute_plussi_cc (rtx *operands)
{
machine_mode mode = GET_MODE (operands[0]);
@@ -2808,9 +2827,9 @@ compute_plussi_cc (rtx *operands)
HOST_WIDE_INT intval = INTVAL (operands[2]);
if (TARGET_H8300SX && (intval >= 1 && intval <= 7))
- return CC_SET_ZN;
+ return OLD_CC_SET_ZN;
if (TARGET_H8300SX && (intval >= -7 && intval <= -1))
- return CC_SET_ZN;
+ return OLD_CC_SET_ZN;
/* See if we can finish with 2 bytes. */
@@ -2819,28 +2838,28 @@ compute_plussi_cc (rtx *operands)
case 0x00000001:
case 0x00000002:
case 0x00000004:
- return CC_NONE_0HIT;
+ return OLD_CC_NONE_0HIT;
case 0xffffffff:
case 0xfffffffe:
case 0xfffffffc:
- return CC_NONE_0HIT;
+ return OLD_CC_NONE_0HIT;
case 0x00010000:
case 0x00020000:
- return CC_CLOBBER;
+ return OLD_CC_CLOBBER;
case 0xffff0000:
case 0xfffe0000:
- return CC_CLOBBER;
+ return OLD_CC_CLOBBER;
}
/* See if we can finish with 4 bytes. */
if ((intval & 0xffff) == 0)
- return CC_CLOBBER;
+ return OLD_CC_CLOBBER;
}
- return CC_SET_ZN;
+ return OLD_CC_SET_ZN;
}
/* Output a logical insn. */
@@ -3122,7 +3141,7 @@ compute_logical_op_length (machine_mode mode, rtx *operands)
/* Compute which flag bits are valid after a logical insn. */
-enum attr_cc
+int
compute_logical_op_cc (machine_mode mode, rtx *operands)
{
/* Figure out the logical op that we need to perform. */
@@ -3147,7 +3166,7 @@ compute_logical_op_cc (machine_mode mode, rtx *operands)
int lower_half_easy_p = 0;
int upper_half_easy_p = 0;
/* Condition code. */
- enum attr_cc cc = CC_CLOBBER;
+ enum attr_old_cc cc = OLD_CC_CLOBBER;
switch (mode)
{
@@ -3155,7 +3174,7 @@ compute_logical_op_cc (machine_mode mode, rtx *operands)
/* First, see if we can finish with one insn. */
if (b0 != 0 && b1 != 0)
{
- cc = CC_SET_ZNV;
+ cc = OLD_CC_SET_ZNV;
}
break;
case E_SImode:
@@ -3177,7 +3196,7 @@ compute_logical_op_cc (machine_mode mode, rtx *operands)
&& !(code == IOR && w1 == 0xffff
&& (w0 & 0x8000) != 0 && lower_half_easy_p))
{
- cc = CC_SET_ZNV;
+ cc = OLD_CC_SET_ZNV;
}
else
{
@@ -3185,7 +3204,7 @@ compute_logical_op_cc (machine_mode mode, rtx *operands)
&& w1 == 0xffff
&& (w0 & 0x8000) != 0)
{
- cc = CC_SET_ZNV;
+ cc = OLD_CC_SET_ZNV;
}
}
break;
@@ -3195,6 +3214,7 @@ compute_logical_op_cc (machine_mode mode, rtx *operands)
return cc;
}
+#if 0
/* Expand a conditional branch. */
void
@@ -3234,6 +3254,7 @@ h8300_expand_store (rtx operands[])
tmp = gen_rtx_fmt_ee (code, GET_MODE (dest), cc0_rtx, const0_rtx);
emit_insn (gen_rtx_SET (dest, tmp));
}
+#endif
/* Shifts.
@@ -3381,19 +3402,25 @@ expand_a_shift (machine_mode mode, enum rtx_code code, rtx operands[])
break;
}
- emit_move_insn (copy_rtx (operands[0]), operands[1]);
-
/* Need a loop to get all the bits we want - we generate the
code at emit time, but need to allocate a scratch reg now. */
-
- emit_insn (gen_rtx_PARALLEL
- (VOIDmode,
- gen_rtvec (2,
- gen_rtx_SET (copy_rtx (operands[0]),
- gen_rtx_fmt_ee (code, mode,
- copy_rtx (operands[0]), operands[2])),
- gen_rtx_CLOBBER (VOIDmode,
- gen_rtx_SCRATCH (QImode)))));
+ emit_move_insn (copy_rtx (operands[0]), operands[1]);
+ if (operands[2] == CONST0_RTX (QImode))
+ ;
+ else if (GET_CODE (operands[2]) == CONST_INT
+ && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), mode, code))
+ emit_insn (gen_rtx_SET (copy_rtx (operands[0]),
+ gen_rtx_fmt_ee (code, mode,
+ copy_rtx (operands[1]), operands[2])));
+ else
+ emit_insn (gen_rtx_PARALLEL
+ (VOIDmode,
+ gen_rtvec (2,
+ gen_rtx_SET (copy_rtx (operands[0]),
+ gen_rtx_fmt_ee (code, mode,
+ copy_rtx (operands[0]), operands[2])),
+ gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_SCRATCH (QImode)))));
return true;
}
@@ -3405,13 +3432,13 @@ enum shift_mode
};
/* For single bit shift insns, record assembler and what bits of the
- condition code are valid afterwards (represented as various CC_FOO
+ condition code are valid afterwards (represented as various OLD_CC_FOO
bits, 0 means CC isn't left in a usable state). */
struct shift_insn
{
const char *const assembler;
- const enum attr_cc cc_valid;
+ const enum attr_old_cc cc_valid;
};
/* Assembler instruction shift table.
@@ -3425,42 +3452,42 @@ static const struct shift_insn shift_one[2][3][3] =
{
/* SHIFT_ASHIFT */
{
- { "shll\t%X0", CC_SET_ZNV },
- { "add.w\t%T0,%T0", CC_SET_ZN },
- { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", CC_CLOBBER }
+ { "shll\t%X0", OLD_CC_SET_ZNV },
+ { "add.w\t%T0,%T0", OLD_CC_SET_ZN },
+ { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", OLD_CC_CLOBBER }
},
/* SHIFT_LSHIFTRT */
{
- { "shlr\t%X0", CC_SET_ZNV },
- { "shlr\t%t0\n\trotxr\t%s0", CC_CLOBBER },
- { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", CC_CLOBBER }
+ { "shlr\t%X0", OLD_CC_SET_ZNV },
+ { "shlr\t%t0\n\trotxr\t%s0", OLD_CC_CLOBBER },
+ { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", OLD_CC_CLOBBER }
},
/* SHIFT_ASHIFTRT */
{
- { "shar\t%X0", CC_SET_ZNV },
- { "shar\t%t0\n\trotxr\t%s0", CC_CLOBBER },
- { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", CC_CLOBBER }
+ { "shar\t%X0", OLD_CC_SET_ZNV },
+ { "shar\t%t0\n\trotxr\t%s0", OLD_CC_CLOBBER },
+ { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", OLD_CC_CLOBBER }
}
},
/* H8/300H */
{
/* SHIFT_ASHIFT */
{
- { "shll.b\t%X0", CC_SET_ZNV },
- { "shll.w\t%T0", CC_SET_ZNV },
- { "shll.l\t%S0", CC_SET_ZNV }
+ { "shll.b\t%X0", OLD_CC_SET_ZNV },
+ { "shll.w\t%T0", OLD_CC_SET_ZNV },
+ { "shll.l\t%S0", OLD_CC_SET_ZNV }
},
/* SHIFT_LSHIFTRT */
{
- { "shlr.b\t%X0", CC_SET_ZNV },
- { "shlr.w\t%T0", CC_SET_ZNV },
- { "shlr.l\t%S0", CC_SET_ZNV }
+ { "shlr.b\t%X0", OLD_CC_SET_ZNV },
+ { "shlr.w\t%T0", OLD_CC_SET_ZNV },
+ { "shlr.l\t%S0", OLD_CC_SET_ZNV }
},
/* SHIFT_ASHIFTRT */
{
- { "shar.b\t%X0", CC_SET_ZNV },
- { "shar.w\t%T0", CC_SET_ZNV },
- { "shar.l\t%S0", CC_SET_ZNV }
+ { "shar.b\t%X0", OLD_CC_SET_ZNV },
+ { "shar.w\t%T0", OLD_CC_SET_ZNV },
+ { "shar.l\t%S0", OLD_CC_SET_ZNV }
}
}
};
@@ -3469,21 +3496,21 @@ static const struct shift_insn shift_two[3][3] =
{
/* SHIFT_ASHIFT */
{
- { "shll.b\t#2,%X0", CC_SET_ZNV },
- { "shll.w\t#2,%T0", CC_SET_ZNV },
- { "shll.l\t#2,%S0", CC_SET_ZNV }
+ { "shll.b\t#2,%X0", OLD_CC_SET_ZNV },
+ { "shll.w\t#2,%T0", OLD_CC_SET_ZNV },
+ { "shll.l\t#2,%S0", OLD_CC_SET_ZNV }
},
/* SHIFT_LSHIFTRT */
{
- { "shlr.b\t#2,%X0", CC_SET_ZNV },
- { "shlr.w\t#2,%T0", CC_SET_ZNV },
- { "shlr.l\t#2,%S0", CC_SET_ZNV }
+ { "shlr.b\t#2,%X0", OLD_CC_SET_ZNV },
+ { "shlr.w\t#2,%T0", OLD_CC_SET_ZNV },
+ { "shlr.l\t#2,%S0", OLD_CC_SET_ZNV }
},
/* SHIFT_ASHIFTRT */
{
- { "shar.b\t#2,%X0", CC_SET_ZNV },
- { "shar.w\t#2,%T0", CC_SET_ZNV },
- { "shar.l\t#2,%S0", CC_SET_ZNV }
+ { "shar.b\t#2,%X0", OLD_CC_SET_ZNV },
+ { "shar.w\t#2,%T0", OLD_CC_SET_ZNV },
+ { "shar.l\t#2,%S0", OLD_CC_SET_ZNV }
}
};
@@ -3579,10 +3606,10 @@ struct shift_info {
const char *shift2;
/* CC status for SHIFT_INLINE. */
- enum attr_cc cc_inline;
+ enum attr_old_cc cc_inline;
/* CC status for SHIFT_SPECIAL. */
- enum attr_cc cc_special;
+ enum attr_old_cc cc_special;
};
static void get_shift_alg (enum shift_type,
@@ -3651,7 +3678,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
case SHIFT_ROT_AND:
info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
info->shift2 = rotate_two[shift_type][shift_mode];
- info->cc_inline = CC_CLOBBER;
+ info->cc_inline = OLD_CC_CLOBBER;
goto end;
case SHIFT_SPECIAL:
@@ -3660,7 +3687,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
info->shift2 = shift_two[shift_type][shift_mode].assembler;
info->cc_inline = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
- info->cc_special = CC_CLOBBER;
+ info->cc_special = OLD_CC_CLOBBER;
break;
}
@@ -3702,11 +3729,11 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
goto end;
case SHIFT_LSHIFTRT:
info->special = "mov.b\t%t0,%s0\n\textu.w\t%T0";
- info->cc_special = CC_SET_ZNV;
+ info->cc_special = OLD_CC_SET_ZNV;
goto end;
case SHIFT_ASHIFTRT:
info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0";
- info->cc_special = CC_SET_ZNV;
+ info->cc_special = OLD_CC_SET_ZNV;
goto end;
}
}
@@ -3722,7 +3749,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
if (TARGET_H8300H)
{
info->special = "shll.b\t%t0\n\tsubx.b\t%s0,%s0\n\tshll.b\t%t0\n\trotxl.b\t%s0\n\texts.w\t%T0";
- info->cc_special = CC_SET_ZNV;
+ info->cc_special = OLD_CC_SET_ZNV;
}
else /* TARGET_H8300S */
gcc_unreachable ();
@@ -3768,11 +3795,11 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
{
case SHIFT_ASHIFT:
info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
- info->cc_special = CC_SET_ZNV;
+ info->cc_special = OLD_CC_SET_ZNV;
goto end;
case SHIFT_LSHIFTRT:
info->special = "shll.w\t%f0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
- info->cc_special = CC_SET_ZNV;
+ info->cc_special = OLD_CC_SET_ZNV;
goto end;
case SHIFT_ASHIFTRT:
gcc_unreachable ();
@@ -3790,11 +3817,11 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
goto end;
case SHIFT_LSHIFTRT:
info->special = "mov.w\t%e0,%f0\n\textu.l\t%S0";
- info->cc_special = CC_SET_ZNV;
+ info->cc_special = OLD_CC_SET_ZNV;
goto end;
case SHIFT_ASHIFTRT:
info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0";
- info->cc_special = CC_SET_ZNV;
+ info->cc_special = OLD_CC_SET_ZNV;
goto end;
}
}
@@ -3810,11 +3837,11 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
goto end;
case SHIFT_LSHIFTRT:
info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
- info->cc_special = CC_SET_ZNV;
+ info->cc_special = OLD_CC_SET_ZNV;
goto end;
case SHIFT_ASHIFTRT:
info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
- info->cc_special = CC_SET_ZNV;
+ info->cc_special = OLD_CC_SET_ZNV;
goto end;
}
}
@@ -3832,7 +3859,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
if (TARGET_H8300H)
{
info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\textu.l\t%S0";
- info->cc_special = CC_SET_ZNV;
+ info->cc_special = OLD_CC_SET_ZNV;
}
else
info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\trotl.l\t#2,%S0\n\textu.l\t%S0";
@@ -3855,12 +3882,12 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
if (TARGET_H8300H)
{
info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\textu.l\t%S0";
- info->cc_special = CC_SET_ZNV;
+ info->cc_special = OLD_CC_SET_ZNV;
}
else
{
info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\trotl.l\t%S0\n\textu.l\t%S0";
- info->cc_special = CC_SET_ZNV;
+ info->cc_special = OLD_CC_SET_ZNV;
}
goto end;
case SHIFT_ASHIFTRT:
@@ -3893,15 +3920,15 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
{
case SHIFT_ASHIFT:
info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0";
- info->cc_special = CC_SET_ZNV;
+ info->cc_special = OLD_CC_SET_ZNV;
goto end;
case SHIFT_LSHIFTRT:
info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0";
- info->cc_special = CC_SET_ZNV;
+ info->cc_special = OLD_CC_SET_ZNV;
goto end;
case SHIFT_ASHIFTRT:
info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\texts.w\t%T0\n\texts.l\t%S0";
- info->cc_special = CC_SET_ZNV;
+ info->cc_special = OLD_CC_SET_ZNV;
goto end;
}
}
@@ -3920,7 +3947,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
needed for some shift with COUNT and MODE. Return 0 otherwise. */
int
-h8300_shift_needs_scratch_p (int count, machine_mode mode)
+h8300_shift_needs_scratch_p (int count, machine_mode mode, enum rtx_code type)
{
enum h8_cpu cpu;
int a, lr, ar;
@@ -3960,8 +3987,18 @@ h8300_shift_needs_scratch_p (int count, machine_mode mode)
}
/* On H8/300H, count == 8 uses a scratch register. */
- return (a == SHIFT_LOOP || lr == SHIFT_LOOP || ar == SHIFT_LOOP
- || (TARGET_H8300H && mode == SImode && count == 8));
+ if (type == CLOBBER)
+ return (a == SHIFT_LOOP || lr == SHIFT_LOOP || ar == SHIFT_LOOP
+ || (TARGET_H8300H && mode == SImode && count == 8));
+ else if (type == ASHIFT)
+ return (a == SHIFT_LOOP
+ || (TARGET_H8300H && mode == SImode && count == 8));
+ else if (type == LSHIFTRT)
+ return (lr == SHIFT_LOOP
+ || (TARGET_H8300H && mode == SImode && count == 8));
+ else if (type == ASHIFTRT)
+ return (ar == SHIFT_LOOP
+ || (TARGET_H8300H && mode == SImode && count == 8));
}
/* Output the assembler code for doing shifts. */
@@ -4283,7 +4320,7 @@ compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
/* Compute which flag bits are valid after a shift insn. */
-enum attr_cc
+int
compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
{
rtx shift = operands[3];
@@ -4354,7 +4391,7 @@ compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
case SHIFT_ROT_AND:
/* This case always ends with an and instruction. */
- return CC_SET_ZNV;
+ return OLD_CC_SET_ZNV;
case SHIFT_LOOP:
/* A loop to shift by a "large" constant value.
@@ -4364,7 +4401,7 @@ compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
if (n % 2)
return info.cc_inline;
}
- return CC_CLOBBER;
+ return OLD_CC_CLOBBER;
default:
gcc_unreachable ();
@@ -5517,4 +5554,7 @@ h8300_push_rounding (poly_int64 bytes)
#undef TARGET_HAVE_SPECULATION_SAFE_VALUE
#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
+#undef TARGET_FLAGS_REGNUM
+#define TARGET_FLAGS_REGNUM 12
+
struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h
index bf20ce2..99d85ff 100644
--- a/gcc/config/h8300/h8300.h
+++ b/gcc/config/h8300/h8300.h
@@ -195,14 +195,14 @@ extern const char * const *h8_reg_names;
eliminated during reloading in favor of either the stack or frame
pointer. */
-#define FIRST_PSEUDO_REGISTER 12
+#define FIRST_PSEUDO_REGISTER 13
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator. */
#define FIXED_REGISTERS \
-/* r0 r1 r2 r3 r4 r5 r6 r7 mac ap rap fp */ \
- { 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1 }
+/* r0 r1 r2 r3 r4 r5 r6 r7 mac ap rap fp cc */ \
+ { 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1 }
/* 1 for registers not available across function calls.
These must include the FIXED_REGISTERS and also any
@@ -216,11 +216,11 @@ extern const char * const *h8_reg_names;
#define CALL_USED_REGISTERS \
/* r0 r1 r2 r3 r4 r5 r6 r7 mac ap rap fp */ \
- { 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1 }
+ { 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 }
#define REG_ALLOC_ORDER \
/* r0 r1 r2 r3 r4 r5 r6 r7 mac ap rap fp */ \
- { 2, 3, 0, 1, 4, 5, 6, 8, 7, 9, 10, 11 }
+ { 2, 3, 0, 1, 4, 5, 6, 8, 7, 9, 10, 11, 12 }
/* A C expression that is nonzero if hard register NEW_REG can be
considered for use as a rename register for OLD_REG register */
@@ -521,6 +521,8 @@ struct cum_arg
#define MOVE_MAX 4
#define MAX_MOVE_MAX 4
+#define SELECT_CC_MODE(OP, X, Y) h8300_select_cc_mode (OP, X, Y)
+
/* Nonzero if access to memory by bytes is slow and undesirable. */
#define SLOW_BYTE_ACCESS TARGET_SLOWBYTE
@@ -633,7 +635,7 @@ struct cum_arg
This sequence is indexed by compiler's hard-register-number (see above). */
#define REGISTER_NAMES \
-{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "sp", "mac", "ap", "rap", "fp" }
+{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "sp", "mac", "ap", "rap", "fp", "cc" }
#define ADDITIONAL_REGISTER_NAMES \
{ {"er0", 0}, {"er1", 1}, {"er2", 2}, {"er3", 3}, {"er4", 4}, \
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index 46ab244..932f74e 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -65,7 +65,8 @@
(MAC_REG 8)
(AP_REG 9)
(RAP_REG 10)
- (FP_REG 11)])
+ (FP_REG 11)
+ (CC_REG 12)])
;; ----------------------------------------------------------------------
;; ATTRIBUTES
@@ -130,9 +131,42 @@
;; compare - compare instruction
;; clobber - value of cc is unknown
-(define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
+(define_attr "old_cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
(const_string "clobber"))
+;; So the idea here is to define iterators and substitutions so that we
+;; can easily modify the patterns with CC clobbers into a pattern
+;; which sets appropriate condition codes
+
+;; The modes we're supporting. This is used when we want to generate
+;; multiple patterns where only the mode differs from a single template
+(define_mode_iterator H8cc [CC CCZN])
+
+;; This is used to generate multiple define_substs from a single
+;; template for the different variants we might have.
+(define_mode_attr cc [(CC "cc") (CCZN "cczn")])
+
+;; The primary substitution pattern. <cc> is used to create multiple
+;; substitutions based on the CC bits that are set.
+;;
+;; The mode iterator sets the actual mode on the condition code
+;; REG expression.
+(define_subst "subst_<cc>"
+ [(set (match_operand 0 "")
+ (match_operand 1 ""))
+ (clobber (reg:CC CC_REG))]
+ ""
+ [(set (reg:H8cc CC_REG)
+ (compare:H8cc (match_dup 1) (const_int 0)))
+ (set (match_dup 0) (match_dup 1))])
+
+
+;; So when we see <cc> or <cczn> in a define_insn pattern, we'll
+;; apply the subst_cczn or subset_cc define_subst to generate a
+;; new pattern that compare-elim can use
+(define_subst_attr "cczn" "subst_cczn" "" "_cczn")
+(define_subst_attr "cc" "subst_cc" "" "_cc")
+
;; Type of delay slot. NONE means the instruction has no delay slot.
;; JUMP means it is an unconditional jump that (if short enough)
;; could be implemented using bra/s.
@@ -211,4 +245,4 @@
(include "shiftrotate.md")
(include "bitfield.md")
(include "combiner.md")
-(include "peepholes.md")
+;;(include "peepholes.md")
diff --git a/gcc/config/h8300/jumpcall.md b/gcc/config/h8300/jumpcall.md
index 3917cf1..49d1e43 100644
--- a/gcc/config/h8300/jumpcall.md
+++ b/gcc/config/h8300/jumpcall.md
@@ -4,78 +4,67 @@
;; Conditional jump instructions
-(define_expand "cbranchqi4"
- [(use (match_operator 0 "ordered_comparison_operator"
- [(match_operand:QI 1 "h8300_dst_operand" "")
- (match_operand:QI 2 "h8300_src_operand" "")]))
- (use (match_operand 3 ""))]
- ""
- {
- h8300_expand_branch (operands);
- DONE;
- })
-
-(define_expand "cbranchhi4"
- [(use (match_operator 0 "ordered_comparison_operator"
- [(match_operand:HI 1 "h8300_dst_operand" "")
- (match_operand:HI 2 "h8300_src_operand" "")]))
- (use (match_operand 3 ""))]
- ""
- {
- h8300_expand_branch (operands);
- DONE;
- })
+(define_expand "cbranch<mode>4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:QHSI 1 "h8300_dst_operand")
+ (match_operand:QHSI 2 "h8300_src_operand")])
+ (label_ref (match_operand 3 ""))
+ (pc)))]
+ "")
-(define_expand "cbranchsi4"
- [(use (match_operator 0 "ordered_comparison_operator"
- [(match_operand:SI 1 "h8300_dst_operand" "")
- (match_operand:SI 2 "h8300_src_operand" "")]))
- (use (match_operand 3 ""))]
+(define_insn_and_split "*branch"
+ [(set (pc)
+ (if_then_else (match_operator 0 "comparison_operator"
+ [(match_operand:QHSI 1 "h8300_dst_operand" "rQ")
+ (match_operand:QHSI 2 "h8300_src_operand" "rQi")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
""
- {
- h8300_expand_branch (operands);
- DONE;
- })
+ "#"
+ "reload_completed"
+ [(set (reg:H8cc CC_REG)
+ (compare:H8cc (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (match_op_dup 0
+ [(reg:H8cc CC_REG) (const_int 0)])
+ (label_ref (match_dup 3)) (pc)))]
+ "")
-(define_insn "branch"
+(define_insn "*branch_1"
[(set (pc)
- (if_then_else (match_operator 2 "comparison_operator"
- [(cc0) (const_int 0)])
- (match_operand 0 "pc_or_label_operand" "")
- (match_operand 1 "pc_or_label_operand" "")))]
- "operands[0] == pc_rtx || operands[1] == pc_rtx"
+ (if_then_else (match_operator 1 "comparison_operator"
+ [(reg:H8cc CC_REG) (const_int 0)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ "reload_completed"
{
- if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
- && (GET_CODE (operands[2]) == GT
- || GET_CODE (operands[2]) == GE
- || GET_CODE (operands[2]) == LE
- || GET_CODE (operands[2]) == LT))
- {
- cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
- return 0;
- }
+ if (get_attr_length (insn) == 2)
+ return "b%j1 %l0";
+ else if (get_attr_length (insn) == 4)
+ return "b%j1 %l0:16";
+ else
+ return "b%k1 .Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:";
+}
+ [(set_attr "type" "branch")])
- if (operands[0] != pc_rtx)
- {
- if (get_attr_length (insn) == 2)
- return "b%j2 %l0";
- else if (get_attr_length (insn) == 4)
- return "b%j2 %l0:16";
- else
- return "b%k2 .Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:";
- }
+
+(define_insn "*branch_1_false"
+ [(set (pc)
+ (if_then_else (match_operator 1 "comparison_operator"
+ [(reg:H8cc CC_REG) (const_int 0)])
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ "reload_completed"
+{
+ if (get_attr_length (insn) == 2)
+ return "b%k1 %l0";
+ else if (get_attr_length (insn) == 4)
+ return "b%k1 %l0:16";
else
- {
- if (get_attr_length (insn) == 2)
- return "b%k2 %l1";
- else if (get_attr_length (insn) == 4)
- return "b%k2 %l1:16";
- else
- return "b%j2 .Lh8BR%=\;jmp @%l1\\n.Lh8BR%=:";
- }
+ return "b%j1 .Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:";
}
- [(set_attr "type" "branch")
- (set_attr "cc" "none")])
+ [(set_attr "type" "branch")])
;; The brabc/brabs patterns have been disabled because their length computation
;; is horribly broken. When we call out to a function via a SYMBOL_REF we get
@@ -109,8 +98,7 @@
}
}
[(set_attr "type" "bitbranch")
- (set_attr "length_table" "bitbranch")
- (set_attr "cc" "none")])
+ (set_attr "length_table" "bitbranch")])
(define_insn "*brabs"
[(set (pc)
@@ -134,8 +122,7 @@
}
}
[(set_attr "type" "bitbranch")
- (set_attr "length_table" "bitbranch")
- (set_attr "cc" "none")])
+ (set_attr "length_table" "bitbranch")])
;; Unconditional and other jump instructions.
@@ -179,8 +166,7 @@
(set (attr "delay_slot")
(if_then_else (match_test "TARGET_H8300SX")
(const_string "jump")
- (const_string "none")))
- (set_attr "cc" "none")])
+ (const_string "none")))])
;; This is a define expand, because pointers may be either 16 or 32 bits.
@@ -201,8 +187,7 @@
return "jmp @%S0";
abort ();
}
- [(set_attr "cc" "none")
- (set_attr "length" "2")])
+ [(set_attr "length" "2")])
;; This is a define expand, because pointers may be either 16 or 32 bits.
@@ -221,8 +206,7 @@
return "jmp @%S0";
abort ();
}
- [(set_attr "cc" "none")
- (set_attr "length" "2")])
+ [(set_attr "length" "2")])
;; Call subroutine with no return value.
diff --git a/gcc/config/h8300/logical.md b/gcc/config/h8300/logical.md
index 7d24fad..eb99c20 100644
--- a/gcc/config/h8300/logical.md
+++ b/gcc/config/h8300/logical.md
@@ -24,30 +24,59 @@
operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8);
})
-(define_insn "*andqi3_2"
+(define_insn "bclrhi_msx"
+ [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
+ (and:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
+ (match_operand:HI 2 "single_zero_operand" "Y0")))]
+ "TARGET_H8300SX"
+ "bclr\\t%W2,%0"
+ [(set_attr "length" "8")])
+
+(define_insn_and_split "*andqi3_2"
[(set (match_operand:QI 0 "bit_operand" "=U,rQ,r")
(and:QI (match_operand:QI 1 "bit_operand" "%0,0,WU")
(match_operand:QI 2 "h8300_src_operand" "Y0,rQi,IP1>X")))]
"TARGET_H8300SX"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (and:QI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*andqi3_2_clobber_flags"
+ [(set (match_operand:QI 0 "bit_operand" "=U,rQ,r")
+ (and:QI (match_operand:QI 1 "bit_operand" "%0,0,WU")
+ (match_operand:QI 2 "h8300_src_operand" "Y0,rQi,IP1>X")))
+ (clobber (reg:CC CC_REG))]
+ "TARGET_H8300SX"
"@
bclr\\t %W2,%R0
and %X2,%X0
bfld %2,%1,%R0"
[(set_attr "length" "8,*,8")
- (set_attr "length_table" "*,logicb,*")
- (set_attr "cc" "none_0hit,set_znv,none_0hit")])
+ (set_attr "length_table" "*,logicb,*")])
-(define_insn "andqi3_1"
+(define_insn_and_split "andqi3_1"
[(set (match_operand:QI 0 "bit_operand" "=U,r")
(and:QI (match_operand:QI 1 "bit_operand" "%0,0")
(match_operand:QI 2 "h8300_src_operand" "Y0,rn")))]
"register_operand (operands[0], QImode)
|| single_zero_operand (operands[2], QImode)"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (and:QI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "andqi3_1_clobber_flags"
+ [(set (match_operand:QI 0 "bit_operand" "=U,r")
+ (and:QI (match_operand:QI 1 "bit_operand" "%0,0")
+ (match_operand:QI 2 "h8300_src_operand" "Y0,rn")))
+ (clobber (reg:CC CC_REG))]
+ "register_operand (operands[0], QImode)
+ || single_zero_operand (operands[2], QImode)"
"@
bclr %W2,%R0
and %X2,%X0"
- [(set_attr "length" "2,8")
- (set_attr "cc" "none_0hit,set_znv")])
+ [(set_attr "length" "2,8")])
(define_expand "and<mode>3"
[(set (match_operand:QHSI 0 "register_operand" "")
@@ -56,7 +85,7 @@
""
"")
-(define_insn "*andor<mode>3"
+(define_insn_and_split "*andor<mode>3"
[(set (match_operand:QHSI 0 "register_operand" "=r")
(ior:QHSI (and:QHSI (match_operand:QHSI 2 "register_operand" "r")
(match_operand:QHSI 3 "single_one_operand" "n"))
@@ -65,6 +94,23 @@
|| <MODE>mode == HImode
|| (<MODE>mode == SImode
&& (INTVAL (operands[3]) & 0xffff) != 0))"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (ior:QHSI (and:QHSI (match_dup 2)
+ (match_dup 3))
+ (match_dup 1)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*andor<mode>3_clobber_flags"
+ [(set (match_operand:QHSI 0 "register_operand" "=r")
+ (ior:QHSI (and:QHSI (match_operand:QHSI 2 "register_operand" "r")
+ (match_operand:QHSI 3 "single_one_operand" "n"))
+ (match_operand:QHSI 1 "register_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ "(<MODE>mode == QImode
+ || <MODE>mode == HImode
+ || (<MODE>mode == SImode
+ && (INTVAL (operands[3]) & 0xffff) != 0))"
{
if (<MODE>mode == QImode)
return "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0";
@@ -96,13 +142,29 @@
}
[(set_attr "length" "6")])
-(define_insn "*andorsi3_shift_8"
+(define_insn_and_split "*andorsi3_shift_8"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
(const_int 8))
(const_int 65280))
(match_operand:SI 1 "register_operand" "0")))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (ior:SI (and:SI (ashift:SI (match_dup 2)
+ (const_int 8))
+ (const_int 65280))
+ (match_dup 1)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*andorsi3_shift_8_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
+ (const_int 8))
+ (const_int 65280))
+ (match_operand:SI 1 "register_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ ""
"or.b\\t%w2,%x0"
[(set_attr "length" "2")])
@@ -118,36 +180,41 @@
{ return <CODE> == IOR ? "bset\\t%V2,%0" : "bnot\\t%V2,%0"; }
[(set_attr "length" "8")])
-(define_split
- [(set (match_operand:HI 0 "bit_register_indirect_operand")
- (ors:HI (match_operand:HI 1 "bit_register_indirect_operand")
- (match_operand:HI 2 "single_one_operand")))]
- "TARGET_H8300SX && abs (INTVAL (operands[2])) > 0xff"
- [(set (match_dup 0)
- (and:QI (match_dup 1)
- (match_dup 2)))]
- {
- operands[0] = adjust_address (operands[0], QImode, 0);
- operands[1] = adjust_address (operands[1], QImode, 0);
- operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8);
- })
+(define_insn "b<code>hi_msx"
+ [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
+ (ors:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
+ (match_operand:HI 2 "single_one_operand" "Y2")))]
+ "TARGET_H8300SX"
+ { return <CODE> == IOR ? "bset\\t%V2,%0" : "bnot\\t%V2,%0"; }
+ [(set_attr "length" "8")])
-(define_insn "<code>qi3_1"
+(define_insn_and_split "<code>qi3_1"
[(set (match_operand:QI 0 "bit_operand" "=U,rQ")
(ors:QI (match_operand:QI 1 "bit_operand" "%0,0")
(match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))]
"TARGET_H8300SX || register_operand (operands[0], QImode)
|| single_one_operand (operands[2], QImode)"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (ors:QI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "<code>qi3_1_clobber_flags"
+ [(set (match_operand:QI 0 "bit_operand" "=U,rQ")
+ (ors:QI (match_operand:QI 1 "bit_operand" "%0,0")
+ (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))
+ (clobber (reg:CC CC_REG))]
+ "TARGET_H8300SX || register_operand (operands[0], QImode)
+ || single_one_operand (operands[2], QImode)"
{
if (which_alternative == 0)
- return <CODE> == IOR ? "bset\\t%V2,%R0" : "bnot\\t%V2,%R0";
+ return <CODE> == IOR ? "bset\\t%V2,%R0" : "bnot\\t%V2,%R0";
else if (which_alternative == 1)
return <CODE> == IOR ? "or\\t%X2,%X0" : "xor\\t%X2,%X0";
gcc_unreachable ();
}
[(set_attr "length" "8,*")
- (set_attr "length_table" "*,logicb")
- (set_attr "cc" "none_0hit,set_znv")])
+ (set_attr "length_table" "*,logicb")])
(define_expand "<code><mode>3"
[(set (match_operand:QHSI 0 "register_operand" "")
@@ -160,27 +227,48 @@
;; {AND,IOR,XOR}{HI3,SI3} PATTERNS
;; ----------------------------------------------------------------------
-(define_insn "*logical<mode>3"
+(define_insn_and_split "*logical<mode>3"
[(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ")
(match_operator:HSI 3 "bit_operator"
[(match_operand:HSI 1 "h8300_dst_operand" "%0")
(match_operand:HSI 2 "h8300_src_operand" "rQi")]))]
"h8300_operands_match_p (operands)"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*logical<mode>3_clobber_flags"
+ [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ")
+ (match_operator:HSI 3 "bit_operator"
+ [(match_operand:HSI 1 "h8300_dst_operand" "%0")
+ (match_operand:HSI 2 "h8300_src_operand" "rQi")]))
+ (clobber (reg:CC CC_REG))]
+ "h8300_operands_match_p (operands)"
{ return output_logical_op (<MODE>mode, operands); }
[(set (attr "length")
- (symbol_ref "compute_logical_op_length (<MODE>mode, operands)"))
- (set (attr "cc")
- (symbol_ref "compute_logical_op_cc (<MODE>mode, operands)"))])
+ (symbol_ref "compute_logical_op_length (<MODE>mode, operands)"))])
;; ----------------------------------------------------------------------
;; NOT INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_insn "one_cmpl<mode>2"
+(define_insn_and_split "one_cmpl<mode>2"
[(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
(not:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (not:QHSI (match_dup 1)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "one_cmpl<mode>2_clobber_flags"
+ [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
+ (not:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ ""
{
if (<MODE>mode == E_QImode)
return "not %X0";
@@ -190,5 +278,93 @@
return "not.l %S0";
gcc_unreachable ();
}
- [(set_attr "length_table" "unary")
- (set_attr "cc" "set_znv")])
+ [(set_attr "length_table" "unary")])
+
+;; The next four peephole2's will try to transform
+;;
+;; mov.b A,r0l (or mov.l A,er0)
+;; and.l #CST,er0
+;;
+;; into
+;;
+;; sub.l er0
+;; mov.b A,r0l
+;; and.b #CST,r0l (if CST is not 255)
+
+(define_peephole2
+ [(parallel [(set (match_operand:QI 0 "register_operand" "")
+ (match_operand:QI 1 "general_operand" ""))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (match_operand:SI 2 "register_operand" "")
+ (and:SI (match_dup 2) (const_int 255)))
+ (clobber (reg:CC CC_REG))])]
+ "!reg_overlap_mentioned_p (operands[2], operands[1])
+ && REGNO (operands[0]) == REGNO (operands[2])"
+ [(parallel [(set (match_dup 2) (const_int 0))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
+ (clobber (reg:CC CC_REG))])])
+
+(define_peephole2
+ [(parallel [(set (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "nonimmediate_operand" ""))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (match_dup 0)
+ (and:SI (match_dup 0) (const_int 255)))
+ (clobber (reg:CC CC_REG))])]
+ "!reg_overlap_mentioned_p (operands[0], operands[1])
+ && !(GET_CODE (operands[1]) == MEM && !offsettable_memref_p (operands[1]))
+ && !(GET_CODE (operands[1]) == MEM && MEM_VOLATILE_P (operands[1]))"
+ [(parallel [(set (match_dup 0) (const_int 0))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (strict_low_part (match_dup 2)) (match_dup 3))
+ (clobber (reg:CC CC_REG))])]
+ {
+ operands[2] = gen_lowpart (QImode, operands[0]);
+ operands[3] = gen_lowpart (QImode, operands[1]);
+ })
+
+(define_peephole2
+ [(parallel [(set (match_operand 0 "register_operand" "")
+ (match_operand 1 "nonimmediate_operand" ""))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (match_operand:SI 2 "register_operand" "")
+ (and:SI (match_dup 2)
+ (match_operand:SI 3 "const_int_qi_operand" "")))
+ (clobber (reg:CC CC_REG))])]
+ "(GET_MODE (operands[0]) == QImode
+ || GET_MODE (operands[0]) == HImode
+ || GET_MODE (operands[0]) == SImode)
+ && GET_MODE (operands[0]) == GET_MODE (operands[1])
+ && REGNO (operands[0]) == REGNO (operands[2])
+ && !reg_overlap_mentioned_p (operands[2], operands[1])
+ && !(GET_MODE (operands[1]) != QImode
+ && GET_CODE (operands[1]) == MEM
+ && !offsettable_memref_p (operands[1]))
+ && !(GET_MODE (operands[1]) != QImode
+ && GET_CODE (operands[1]) == MEM
+ && MEM_VOLATILE_P (operands[1]))"
+ [(parallel [(set (match_dup 2) (const_int 0))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (strict_low_part (match_dup 4)) (match_dup 5))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (match_dup 2) (and:SI (match_dup 2) (match_dup 6)))
+ (clobber (reg:CC CC_REG))])]
+ {
+ operands[4] = gen_lowpart (QImode, operands[0]);
+ operands[5] = gen_lowpart (QImode, operands[1]);
+ operands[6] = GEN_INT (~0xff | INTVAL (operands[3]));
+ })
+
+(define_peephole2
+ [(parallel [(set (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" ""))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65280)))
+ (clobber (reg:CC CC_REG))])]
+ "!reg_overlap_mentioned_p (operands[0], operands[1])"
+ [(parallel [(set (match_dup 0) (const_int 0))
+ (clobber (reg:CC CC_REG))])
+ (parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
+ (lshiftrt:SI (match_dup 1) (const_int 8)))
+ (clobber (reg:CC CC_REG))])])
diff --git a/gcc/config/h8300/mova.md b/gcc/config/h8300/mova.md
index 926edbb..cdcd4b8 100644
--- a/gcc/config/h8300/mova.md
+++ b/gcc/config/h8300/mova.md
@@ -24,8 +24,7 @@
(match_operand:QI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=r,r")
@@ -34,8 +33,7 @@
(match_operand:QI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=r,r")
@@ -44,8 +42,7 @@
(match_operand:QI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=r,r")
@@ -54,8 +51,7 @@
(match_operand:QI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -63,8 +59,7 @@
(match_operand:HI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/b.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -72,8 +67,7 @@
(const_int 2)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -82,8 +76,7 @@
(match_operand:HI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -92,8 +85,7 @@
(const_int 510)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -103,8 +95,7 @@
(match_operand:HI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -113,8 +104,7 @@
(const_int 510)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -124,8 +114,7 @@
(match_operand:HI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -133,8 +122,7 @@
(const_int 1)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -143,8 +131,7 @@
(match_operand:HI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -153,8 +140,7 @@
(const_int 510)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -164,8 +150,7 @@
(match_operand:HI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -174,8 +159,7 @@
(const_int 510)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -185,8 +169,7 @@
(match_operand:HI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -194,8 +177,7 @@
(const_int 4)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -204,8 +186,7 @@
(match_operand:HI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -214,8 +195,7 @@
(const_int 1020)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -225,8 +205,7 @@
(match_operand:HI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -235,8 +214,7 @@
(const_int 1020)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -246,8 +224,7 @@
(match_operand:HI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -255,8 +232,7 @@
(const_int 2)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -265,8 +241,7 @@
(match_operand:HI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -275,8 +250,7 @@
(const_int 1020)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -286,8 +260,7 @@
(match_operand:HI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -296,8 +269,7 @@
(const_int 1020)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -307,8 +279,7 @@
(match_operand:HI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -316,8 +287,7 @@
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/b.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -325,8 +295,7 @@
(const_int 2)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -335,8 +304,7 @@
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -345,8 +313,7 @@
(const_int 510)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -356,8 +323,7 @@
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -366,8 +332,7 @@
(const_int 510)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -377,8 +342,7 @@
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -386,8 +350,7 @@
(const_int 1)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -396,8 +359,7 @@
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -406,8 +368,7 @@
(const_int 510)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -417,8 +378,7 @@
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -427,8 +387,7 @@
(const_int 510)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -438,8 +397,7 @@
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -447,8 +405,7 @@
(const_int 4)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -457,8 +414,7 @@
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -467,8 +423,7 @@
(const_int 1020)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -478,8 +433,7 @@
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -488,8 +442,7 @@
(const_int 1020)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -499,8 +452,7 @@
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -508,8 +460,7 @@
(const_int 2)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -518,8 +469,7 @@
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -528,8 +478,7 @@
(const_int 1020)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -539,8 +488,7 @@
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -549,8 +497,7 @@
(const_int 1020)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -560,8 +507,7 @@
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%X1.b),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -570,8 +516,7 @@
(match_operand:HI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%T1.w),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -580,8 +525,7 @@
(match_operand:HI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%T1.w),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -590,8 +534,7 @@
(match_operand:HI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%T1.w),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -600,8 +543,7 @@
(match_operand:HI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%T1.w),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -609,8 +551,7 @@
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/b.l @(%o2%C2,%T1.w),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -618,8 +559,7 @@
(const_int 2)))]
"TARGET_H8300SX"
"mova/w.l @(0,%T1.w),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -628,8 +568,7 @@
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%T1.w),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -638,8 +577,7 @@
(const_int 131070)))]
"TARGET_H8300SX"
"mova/w.l @(0,%T1.w),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -649,8 +587,7 @@
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%T1.w),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -659,8 +596,7 @@
(const_int 131070)))]
"TARGET_H8300SX"
"mova/w.l @(0,%T1.w),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -670,8 +606,7 @@
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%T1.w),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -679,8 +614,7 @@
(const_int 1)))]
"TARGET_H8300SX"
"mova/w.l @(0,%T1.w),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -689,8 +623,7 @@
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%T1.w),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -699,8 +632,7 @@
(const_int 131070)))]
"TARGET_H8300SX"
"mova/w.l @(0,%T1.w),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -710,8 +642,7 @@
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%T1.w),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -720,8 +651,7 @@
(const_int 131070)))]
"TARGET_H8300SX"
"mova/w.l @(0,%T1.w),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -731,8 +661,7 @@
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2%C2,%T1.w),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -740,8 +669,7 @@
(const_int 4)))]
"TARGET_H8300SX"
"mova/l.l @(0,%T1.w),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -750,8 +678,7 @@
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%T1.w),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -760,8 +687,7 @@
(const_int 262140)))]
"TARGET_H8300SX"
"mova/l.l @(0,%T1.w),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -771,8 +697,7 @@
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%T1.w),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -781,8 +706,7 @@
(const_int 262140)))]
"TARGET_H8300SX"
"mova/l.l @(0,%T1.w),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -792,8 +716,7 @@
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%T1.w),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -801,8 +724,7 @@
(const_int 2)))]
"TARGET_H8300SX"
"mova/l.l @(0,%T1.w),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -811,8 +733,7 @@
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%T1.w),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -821,8 +742,7 @@
(const_int 262140)))]
"TARGET_H8300SX"
"mova/l.l @(0,%T1.w),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -832,8 +752,7 @@
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%T1.w),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -842,8 +761,7 @@
(const_int 262140)))]
"TARGET_H8300SX"
"mova/l.l @(0,%T1.w),%S0"
- [(set_attr "length_table" "mova_zero")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova_zero")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -853,6 +771,5 @@
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2%C2,%T1.w),%S0"
- [(set_attr "length_table" "mova")
- (set_attr "cc" "none")])
+ [(set_attr "length_table" "mova")])
diff --git a/gcc/config/h8300/movepush.md b/gcc/config/h8300/movepush.md
index a8241b9..b106cd5 100644
--- a/gcc/config/h8300/movepush.md
+++ b/gcc/config/h8300/movepush.md
@@ -4,11 +4,20 @@
;; movqi
-(define_insn "*movqi_h8nosx"
+(define_insn_and_split "*movqi"
[(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
(match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
- "!TARGET_H8300SX
- && h8300_move_ok (operands[0], operands[1])"
+ "!TARGET_H8300SX && h8300_move_ok (operands[0], operands[1])"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (match_dup 1))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*movqi_clobber_flags"
+ [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
+ (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))
+ (clobber (reg:CC CC_REG))]
+ "!TARGET_H8300SX && h8300_move_ok (operands[0], operands[1])"
"@
sub.b %X0,%X0
mov.b %R1,%X0
@@ -16,19 +25,26 @@
mov.b %R1,%X0
mov.b %R1,%X0
mov.b %X1,%R0"
- [(set (attr "length")
- (symbol_ref "compute_mov_length (operands)"))
- (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
+ [(set (attr "length") (symbol_ref "compute_mov_length (operands)"))])
-(define_insn "*movqi_h8sx"
+(define_insn_and_split "*movqi_h8sx"
[(set (match_operand:QI 0 "general_operand_dst" "=Z,rQ")
(match_operand:QI 1 "general_operand_src" "P4>X,rQi"))]
"TARGET_H8300SX"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (match_dup 1))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*movqi_h8sx_clobber_flags"
+ [(set (match_operand:QI 0 "general_operand_dst" "=Z,rQ")
+ (match_operand:QI 1 "general_operand_src" "P4>X,rQi"))
+ (clobber (reg:CC CC_REG))]
+ "TARGET_H8300SX"
"@
mov.b %X1:4,%X0
mov.b %X1,%X0"
- [(set_attr "length_table" "mov_imm4,movb")
- (set_attr "cc" "set_znv")])
+ [(set_attr "length_table" "mov_imm4,movb")])
(define_expand "mov<mode>"
[(set (match_operand:QHSIF 0 "general_operand_dst" "")
@@ -48,24 +64,45 @@
}
})
-(define_insn "movstrictqi"
+(define_insn_and_split "movstrictqi"
[(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "+r,r"))
(match_operand:QI 1 "general_operand_src" "I,rmi>"))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
+ (clobber (reg:CC CC_REG))])])
+
+
+(define_insn "movstrictqi_clobber_flags"
+ [(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "+r,r"))
+ (match_operand:QI 1 "general_operand_src" "I,rmi>"))
+ (clobber (reg:CC CC_REG))]
+ ""
"@
sub.b %X0,%X0
mov.b %X1,%X0"
[(set_attr "length" "2,*")
- (set_attr "length_table" "*,movb")
- (set_attr "cc" "set_zn,set_znv")])
+ (set_attr "length_table" "*,movb")])
;; movhi
-(define_insn "*movhi_h8nosx"
+(define_insn_and_split "*movhi"
[(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
(match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
"!TARGET_H8300SX
&& h8300_move_ok (operands[0], operands[1])"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (match_dup 1))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*movhi_clobber_flags"
+ [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
+ (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))
+ (clobber (reg:CC CC_REG))]
+ "!TARGET_H8300SX
+ && h8300_move_ok (operands[0], operands[1])"
"@
sub.w %T0,%T0
mov.w %T1,%T0
@@ -73,14 +110,22 @@
mov.w %T1,%T0
mov.w %T1,%T0
mov.w %T1,%T0"
- [(set (attr "length")
- (symbol_ref "compute_mov_length (operands)"))
- (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
+ [(set (attr "length") (symbol_ref "compute_mov_length (operands)"))])
-(define_insn "*movhi_h8sx"
+(define_insn_and_split "*movhi_h8sx"
[(set (match_operand:HI 0 "general_operand_dst" "=r,r,Z,Q,rQ")
(match_operand:HI 1 "general_operand_src" "I,P3>X,P4>X,IP8>X,rQi"))]
"TARGET_H8300SX"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (match_dup 1))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*movhi_h8sx_clobber_flags"
+ [(set (match_operand:HI 0 "general_operand_dst" "=r,r,Z,Q,rQ")
+ (match_operand:HI 1 "general_operand_src" "I,P3>X,P4>X,IP8>X,rQi"))
+ (clobber (reg:CC CC_REG))]
+ "TARGET_H8300SX"
"@
sub.w %T0,%T0
mov.w %T1:3,%T0
@@ -88,27 +133,46 @@
mov.w %T1,%T0
mov.w %T1,%T0"
[(set_attr "length_table" "*,*,mov_imm4,short_immediate,movw")
- (set_attr "length" "2,2,*,*,*")
- (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv")])
+ (set_attr "length" "2,2,*,*,*")])
-(define_insn "movstricthi"
+(define_insn_and_split "movstricthi"
[(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "+r,r,r"))
(match_operand:HI 1 "general_operand_src" "I,P3>X,rmi"))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "movstricthi_clobber_flags"
+ [(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "+r,r,r"))
+ (match_operand:HI 1 "general_operand_src" "I,P3>X,rmi"))
+ (clobber (reg:CC CC_REG))]
+ ""
"@
sub.w %T0,%T0
mov.w %T1,%T0
mov.w %T1,%T0"
[(set_attr "length" "2,2,*")
- (set_attr "length_table" "*,*,movw")
- (set_attr "cc" "set_zn,set_znv,set_znv")])
+ (set_attr "length_table" "*,*,movw")])
;; movsi
-(define_insn "*movsi_h8300hs"
+(define_insn_and_split "*movsi"
[(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,<,r,r,m,*a,*a,r")
(match_operand:SI 1 "general_operand_src" "I,r,i,r,>,m,r,I,r,*a"))]
"(TARGET_H8300S || TARGET_H8300H) && !TARGET_H8300SX
&& h8300_move_ok (operands[0], operands[1])"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (match_dup 1))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*movsi_clobber_flags"
+ [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,<,r,r,m,*a,*a,r")
+ (match_operand:SI 1 "general_operand_src" "I,r,i,r,>,m,r,I,r,*a"))
+ (clobber (reg:CC CC_REG))]
+ "(TARGET_H8300S || TARGET_H8300H) && !TARGET_H8300SX
+ && h8300_move_ok (operands[0], operands[1])"
{
switch (which_alternative)
{
@@ -169,14 +233,22 @@
}
return "mov.l %S1,%S0";
}
- [(set (attr "length")
- (symbol_ref "compute_mov_length (operands)"))
- (set_attr "cc" "set_zn,set_znv,clobber,set_znv,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")])
+ [(set (attr "length") (symbol_ref "compute_mov_length (operands)"))])
-(define_insn "*movsi_h8sx"
+(define_insn_and_split "*movsi_h8sx"
[(set (match_operand:SI 0 "general_operand_dst" "=r,r,Q,rQ,*a,*a,r")
(match_operand:SI 1 "general_operand_src" "I,P3>X,IP8>X,rQi,I,r,*a"))]
"TARGET_H8300SX"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (match_dup 1))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*movsi_h8sx_clobber_flags"
+ [(set (match_operand:SI 0 "general_operand_dst" "=r,r,Q,rQ,*a,*a,r")
+ (match_operand:SI 1 "general_operand_src" "I,P3>X,IP8>X,rQi,I,r,*a"))
+ (clobber (reg:CC CC_REG))]
+ "TARGET_H8300SX"
"@
sub.l %S0,%S0
mov.l %S1:3,%S0
@@ -186,26 +258,46 @@
clrmac\;ldmac %1,macl
stmac macl,%0"
[(set_attr "length_table" "*,*,short_immediate,movl,*,*,*")
- (set_attr "length" "2,2,*,*,2,6,4")
- (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")])
+ (set_attr "length" "2,2,*,*,2,6,4")])
-(define_insn "*movsf_h8sx"
+(define_insn_and_split "*movsf_h8sx"
[(set (match_operand:SF 0 "general_operand_dst" "=r,rQ")
(match_operand:SF 1 "general_operand_src" "G,rQi"))]
"TARGET_H8300SX"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (match_dup 1))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*movsf_h8sx_clobber_flags"
+ [(set (match_operand:SF 0 "general_operand_dst" "=r,rQ")
+ (match_operand:SF 1 "general_operand_src" "G,rQi"))
+ (clobber (reg:CC CC_REG))]
+ "TARGET_H8300SX"
"@
sub.l %S0,%S0
mov.l %S1,%S0"
[(set_attr "length" "2,*")
- (set_attr "length_table" "*,movl")
- (set_attr "cc" "set_zn,set_znv")])
+ (set_attr "length_table" "*,movl")])
-(define_insn "*movsf_h8300hs"
+(define_insn_and_split "*movsf"
[(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,m,<,r")
(match_operand:SF 1 "general_operand_src" "G,r,im,r,r,>"))]
"!TARGET_H8300SX
&& (register_operand (operands[0], SFmode)
|| register_operand (operands[1], SFmode))"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (match_dup 1))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*movsf_clobber_flags"
+ [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,m,<,r")
+ (match_operand:SF 1 "general_operand_src" "G,r,im,r,r,>"))
+ (clobber (reg:CC CC_REG))]
+ "!TARGET_H8300SX
+ && (register_operand (operands[0], SFmode)
+ || register_operand (operands[1], SFmode))"
"@
sub.l %S0,%S0
mov.l %S1,%S0
@@ -213,21 +305,35 @@
mov.l %S1,%S0
mov.l %S1,%S0
mov.l %S1,%S0"
- [(set (attr "length")
- (symbol_ref "compute_mov_length (operands)"))
- (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
+ [(set (attr "length") (symbol_ref "compute_mov_length (operands)"))])
;; ----------------------------------------------------------------------
;; PUSH INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_insn "*push1_h8300hs_<QHI:mode>"
+(define_insn_and_split "*push1_<QHI:mode>"
[(set (mem:QHI
(pre_modify:P
(reg:P SP_REG)
(plus:P (reg:P SP_REG) (const_int -4))))
(match_operand:QHI 0 "register_no_sp_elim_operand" "r"))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (mem:QHI
+ (pre_modify:P (reg:P SP_REG)
+ (plus:P (reg:P SP_REG) (const_int -4))))
+ (match_dup 0))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*push1_<QHI:mode>_clobber_flags"
+ [(set (mem:QHI
+ (pre_modify:P
+ (reg:P SP_REG)
+ (plus:P (reg:P SP_REG) (const_int -4))))
+ (match_operand:QHI 0 "register_no_sp_elim_operand" "r"))
+ (clobber (reg:CC CC_REG))]
+ ""
"mov.l\\t%S0,@-er7"
[(set_attr "length" "4")])
diff --git a/gcc/config/h8300/multiply.md b/gcc/config/h8300/multiply.md
index 4e9112f..56f2b6f 100644
--- a/gcc/config/h8300/multiply.md
+++ b/gcc/config/h8300/multiply.md
@@ -15,23 +15,46 @@
operands[2] = gen_rtx_SIGN_EXTEND (HImode, operands[2]);
})
-(define_insn "*mulqihi3_const"
+(define_insn_and_split "*mulqihi3_const"
[(set (match_operand:HI 0 "register_operand" "=r")
(mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
(match_operand:QI 2 "nibble_operand" "IP4>X")))]
"TARGET_H8300SX"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (mult:HI (sign_extend:HI (match_dup 1)) (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*mulqihi3_const_clobber_flags"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
+ (match_operand:QI 2 "nibble_operand" "IP4>X")))
+ (clobber (reg:CC CC_REG))]
+ "TARGET_H8300SX"
"mulxs.b %X2,%T0"
- [(set_attr "length" "4")
- (set_attr "cc" "set_zn")])
+ [(set_attr "length" "4")])
-(define_insn "*mulqihi3"
+(define_insn_and_split "*mulqihi3"
[(set (match_operand:HI 0 "register_operand" "=r")
(mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
(sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (mult:HI (sign_extend:HI (match_dup 1))
+ (sign_extend:HI (match_dup 2))))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*mulqihi3_clobber_flags"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
+ (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))
+ (clobber (reg:CC CC_REG))]
+ ""
"mulxs.b %X2,%T0"
- [(set_attr "length" "4")
- (set_attr "cc" "set_zn")])
+ [(set_attr "length" "4")])
(define_expand "mulhisi3"
[(set (match_operand:SI 0 "register_operand" "")
@@ -44,23 +67,46 @@
operands[2] = gen_rtx_SIGN_EXTEND (SImode, operands[2]);
})
-(define_insn "*mulhisi3_const"
+(define_insn_and_split "*mulhisi3_const"
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
(match_operand:SI 2 "nibble_operand" "IP4>X")))]
"TARGET_H8300SX"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (mult:SI (sign_extend:SI (match_dup 1)) (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*mulhisi3_const_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
+ (match_operand:SI 2 "nibble_operand" "IP4>X")))
+ (clobber (reg:CC CC_REG))]
+ "TARGET_H8300SX"
"mulxs.w %T2,%S0"
- [(set_attr "length" "4")
- (set_attr "cc" "set_zn")])
+ [(set_attr "length" "4")])
-(define_insn "*mulhisi3"
+(define_insn_and_split "*mulhisi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
(sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (mult:SI (sign_extend:SI (match_dup 1))
+ (sign_extend:SI (match_dup 2))))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*mulhisi3_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
+ (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))
+ (clobber (reg:CC CC_REG))]
+ ""
"mulxs.w %T2,%S0"
- [(set_attr "length" "4")
- (set_attr "cc" "set_zn")])
+ [(set_attr "length" "4")])
(define_expand "umulqihi3"
[(set (match_operand:HI 0 "register_operand" "")
@@ -79,8 +125,7 @@
(match_operand:QI 2 "nibble_operand" "IP4>X")))]
"TARGET_H8300SX"
"mulxu.b %X2,%T0"
- [(set_attr "length" "4")
- (set_attr "cc" "set_zn")])
+ [(set_attr "length" "4")])
(define_insn "*umulqihi3"
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -88,8 +133,7 @@
(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
""
"mulxu.b %X2,%T0"
- [(set_attr "length" "2")
- (set_attr "cc" "none_0hit")])
+ [(set_attr "length" "2")])
(define_expand "umulhisi3"
[(set (match_operand:SI 0 "register_operand" "")
@@ -108,8 +152,7 @@
(match_operand:SI 2 "nibble_operand" "IP4>X")))]
"TARGET_H8300SX"
"mulxu.w %T2,%S0"
- [(set_attr "length" "4")
- (set_attr "cc" "set_zn")])
+ [(set_attr "length" "4")])
(define_insn "*umulhisi3"
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -117,23 +160,32 @@
(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
""
"mulxu.w %T2,%S0"
- [(set_attr "length" "2")
- (set_attr "cc" "none_0hit")])
+ [(set_attr "length" "2")])
;; We could have used mulu.[wl] here, but mulu.[lw] is only available
;; on a H8SX with a multiplier, whereas muls.w seems to be available
;; on all H8SX variants.
-(define_insn "mul<mode>3"
+(define_insn_and_split "mul<mode>3"
[(set (match_operand:HSI 0 "register_operand" "=r")
(mult:HSI (match_operand:HSI 1 "register_operand" "%0")
(match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
"TARGET_H8300SX"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (mult:HSI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "mul<mode>3_clobber_flags"
+ [(set (match_operand:HSI 0 "register_operand" "=r")
+ (mult:HSI (match_operand:HSI 1 "register_operand" "%0")
+ (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))
+ (clobber (reg:CC CC_REG))]
+ "TARGET_H8300SX"
{ return <MODE>mode == HImode ? "muls.w\\t%T2,%T0" : "muls.l\\t%S2,%S0"; }
- [(set_attr "length" "4")
- (set_attr "cc" "set_zn")])
+ [(set_attr "length" "4")])
-(define_insn "smulsi3_highpart"
+(define_insn_and_split "smulsi3_highpart"
[(set (match_operand:SI 0 "register_operand" "=r")
(truncate:SI
(lshiftrt:DI
@@ -142,9 +194,27 @@
(sign_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))
(const_int 32))))]
"TARGET_H8300SXMUL"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0)
+ (truncate:SI (lshiftrt:DI (mult:DI
+ (sign_extend:DI (match_dup 1))
+ (sign_extend:DI (match_dup 2)))
+ (const_int 32))))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "smulsi3_highpart_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (truncate:SI
+ (lshiftrt:DI
+ (mult:DI
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
+ (sign_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))
+ (const_int 32))))
+ (clobber (reg:CC CC_REG))]
+ "TARGET_H8300SXMUL"
"muls/u.l\\t%S2,%S0"
- [(set_attr "length" "4")
- (set_attr "cc" "set_zn")])
+ [(set_attr "length" "4")])
(define_insn "umulsi3_highpart"
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -156,8 +226,7 @@
(const_int 32))))]
"TARGET_H8300SX"
"mulu/u.l\\t%S2,%S0"
- [(set_attr "length" "4")
- (set_attr "cc" "none_0hit")])
+ [(set_attr "length" "4")])
;; This is a "bridge" instruction. Combine can't cram enough insns
;; together to crate a MAC instruction directly, but it can create
@@ -176,8 +245,7 @@
(mem:HI (post_inc:SI (match_operand:SI 2 "register_operand" "r"))))))]
"TARGET_MAC"
"clrmac\;mac @%2+,@%1+"
- [(set_attr "length" "6")
- (set_attr "cc" "none_0hit")])
+ [(set_attr "length" "6")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=a")
@@ -189,6 +257,5 @@
(match_operand:SI 3 "register_operand" "0")))]
"TARGET_MAC"
"mac @%2+,@%1+"
- [(set_attr "length" "4")
- (set_attr "cc" "none_0hit")])
+ [(set_attr "length" "4")])
diff --git a/gcc/config/h8300/other.md b/gcc/config/h8300/other.md
index 4b96a7c..572a29f 100644
--- a/gcc/config/h8300/other.md
+++ b/gcc/config/h8300/other.md
@@ -2,10 +2,20 @@
;; ABSOLUTE VALUE INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_insn "abssf2"
+(define_insn_and_split "abssf2"
[(set (match_operand:SF 0 "register_operand" "=r")
(abs:SF (match_operand:SF 1 "register_operand" "0")))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (abs:SF (match_dup 1)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "abssf2_clobber_flags"
+ [(set (match_operand:SF 0 "register_operand" "=r")
+ (abs:SF (match_operand:SF 1 "register_operand" "0")))
+ (clobber (reg:CC CC_REG))]
+ ""
"and.w\\t#32767,%e0"
[(set_attr "length" "4")])
@@ -13,5 +23,4 @@
[(const_int 0)]
""
"nop"
- [(set_attr "cc" "none")
- (set_attr "length" "2")])
+ [(set_attr "length" "2")])
diff --git a/gcc/config/h8300/peepholes.md b/gcc/config/h8300/peepholes.md
index 8442cd8..bd69018 100644
--- a/gcc/config/h8300/peepholes.md
+++ b/gcc/config/h8300/peepholes.md
@@ -433,96 +433,6 @@
: gen_rtx_LT (VOIDmode, cc0_rtx, const0_rtx));
})
-;; The next three peephole2's will try to transform
-;;
-;; mov.b A,r0l (or mov.l A,er0)
-;; and.l #CST,er0
-;;
-;; into
-;;
-;; sub.l er0
-;; mov.b A,r0l
-;; and.b #CST,r0l (if CST is not 255)
-
-(define_peephole2
- [(set (match_operand:QI 0 "register_operand" "")
- (match_operand:QI 1 "general_operand" ""))
- (set (match_operand:SI 2 "register_operand" "")
- (and:SI (match_dup 2)
- (const_int 255)))]
- "!reg_overlap_mentioned_p (operands[2], operands[1])
- && REGNO (operands[0]) == REGNO (operands[2])"
- [(set (match_dup 2)
- (const_int 0))
- (set (strict_low_part (match_dup 0))
- (match_dup 1))]
- "")
-
-(define_peephole2
- [(set (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "nonimmediate_operand" ""))
- (set (match_dup 0)
- (and:SI (match_dup 0)
- (const_int 255)))]
- "!reg_overlap_mentioned_p (operands[0], operands[1])
- && !(GET_CODE (operands[1]) == MEM && !offsettable_memref_p (operands[1]))
- && !(GET_CODE (operands[1]) == MEM && MEM_VOLATILE_P (operands[1]))"
- [(set (match_dup 0)
- (const_int 0))
- (set (strict_low_part (match_dup 2))
- (match_dup 3))]
- {
- operands[2] = gen_lowpart (QImode, operands[0]);
- operands[3] = gen_lowpart (QImode, operands[1]);
- })
-
-(define_peephole2
- [(set (match_operand 0 "register_operand" "")
- (match_operand 1 "nonimmediate_operand" ""))
- (set (match_operand:SI 2 "register_operand" "")
- (and:SI (match_dup 2)
- (match_operand:SI 3 "const_int_qi_operand" "")))]
- "(GET_MODE (operands[0]) == QImode
- || GET_MODE (operands[0]) == HImode
- || GET_MODE (operands[0]) == SImode)
- && GET_MODE (operands[0]) == GET_MODE (operands[1])
- && REGNO (operands[0]) == REGNO (operands[2])
- && !reg_overlap_mentioned_p (operands[2], operands[1])
- && !(GET_MODE (operands[1]) != QImode
- && GET_CODE (operands[1]) == MEM
- && !offsettable_memref_p (operands[1]))
- && !(GET_MODE (operands[1]) != QImode
- && GET_CODE (operands[1]) == MEM
- && MEM_VOLATILE_P (operands[1]))"
- [(set (match_dup 2)
- (const_int 0))
- (set (strict_low_part (match_dup 4))
- (match_dup 5))
- (set (match_dup 2)
- (and:SI (match_dup 2)
- (match_dup 6)))]
- {
- operands[4] = gen_lowpart (QImode, operands[0]);
- operands[5] = gen_lowpart (QImode, operands[1]);
- operands[6] = GEN_INT (~0xff | INTVAL (operands[3]));
- })
-
-(define_peephole2
- [(set (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "register_operand" ""))
- (set (match_dup 0)
- (and:SI (match_dup 0)
- (const_int 65280)))]
- "!reg_overlap_mentioned_p (operands[0], operands[1])"
- [(set (match_dup 0)
- (const_int 0))
- (set (zero_extract:SI (match_dup 0)
- (const_int 8)
- (const_int 8))
- (lshiftrt:SI (match_dup 1)
- (const_int 8)))]
- "")
-
;; If a load of mem:SI is followed by an AND that turns off the upper
;; half, then we can load mem:HI instead.
@@ -546,20 +456,6 @@
operands[4] = gen_lowpart (HImode, operands[1]);
})
-;; Convert a memory comparison to a move if there is a scratch register.
-
-(define_peephole2
- [(match_scratch:QHSI 1 "r")
- (set (cc0)
- (compare (match_operand:QHSI 0 "memory_operand" "")
- (const_int 0)))]
- ""
- [(set (match_dup 1)
- (match_dup 0))
- (set (cc0) (compare (match_dup 1)
- (const_int 0)))]
- "")
-
;; (compare (reg:HI) (const_int)) takes 4 bytes, so we try to achieve
;; the equivalent with shorter sequences. Here is the summary. Cases
;; are grouped for each define_peephole2.
diff --git a/gcc/config/h8300/predicates.md b/gcc/config/h8300/predicates.md
index b530c2c..7c4e12a 100644
--- a/gcc/config/h8300/predicates.md
+++ b/gcc/config/h8300/predicates.md
@@ -501,3 +501,12 @@
(define_predicate "pc_or_label_operand"
(match_code "pc,label_ref"))
+(define_predicate "simple_memory_operand"
+ (match_code "mem")
+{
+ if (GET_MODE (op) == mode
+ && (GET_CODE (XEXP (op, 0)) != PRE_DEC
+ && GET_CODE (XEXP (op, 0)) != POST_INC))
+ return 1;
+ return 0;
+})
diff --git a/gcc/config/h8300/proepi.md b/gcc/config/h8300/proepi.md
index 9d19ff5..44d5968 100644
--- a/gcc/config/h8300/proepi.md
+++ b/gcc/config/h8300/proepi.md
@@ -36,8 +36,7 @@
XVECLEN (operands[0], 0) - 2));
return "ldm.l\t@er7+,%S1-%S3";
}
- [(set_attr "cc" "none")
- (set_attr "length" "4")])
+ [(set_attr "length" "4")])
(define_insn "stm_h8300sx"
[(match_parallel 0 "h8300_stm_parallel"
@@ -49,8 +48,7 @@
XVECLEN (operands[0], 0) - 2));
return "stm.l\t%S2-%S3,@-er7";
}
- [(set_attr "cc" "none")
- (set_attr "length" "4")])
+ [(set_attr "length" "4")])
(define_insn "return_h8sx"
[(match_parallel 0 "h8300_return_parallel"
@@ -67,8 +65,7 @@
else
return "rts/l\t%S1-%S3";
}
- [(set_attr "cc" "none")
- (set_attr "can_delay" "no")
+ [(set_attr "can_delay" "no")
(set_attr "length" "2")])
(define_expand "return"
@@ -86,8 +83,7 @@
else
return "rts";
}
- [(set_attr "cc" "none")
- (set_attr "can_delay" "no")
+ [(set_attr "can_delay" "no")
(set_attr "length" "2")])
(define_expand "prologue"
diff --git a/gcc/config/h8300/shiftrotate.md b/gcc/config/h8300/shiftrotate.md
index 75606d7..f1c86f7 100644
--- a/gcc/config/h8300/shiftrotate.md
+++ b/gcc/config/h8300/shiftrotate.md
@@ -50,12 +50,24 @@
;; QI/HI/SI BIT SHIFTS
-(define_insn ""
+(define_insn_and_split ""
[(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
(match_operator:QHSI 3 "h8sx_unary_shift_operator"
[(match_operand:QHSI 1 "h8300_dst_operand" "0")
(match_operand:QI 2 "const_int_operand" "")]))]
"h8300_operands_match_p (operands)"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn ""
+ [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
+ (match_operator:QHSI 3 "h8sx_unary_shift_operator"
+ [(match_operand:QHSI 1 "h8300_dst_operand" "0")
+ (match_operand:QI 2 "const_int_operand" "")]))
+ (clobber (reg:CC CC_REG))]
+ "h8300_operands_match_p (operands)"
{
if (<MODE>mode == E_QImode)
return output_h8sx_shift (operands, 'b', 'X');
@@ -65,15 +77,68 @@
return output_h8sx_shift (operands, 'l', 'S');
gcc_unreachable ();
}
- [(set_attr "length_table" "unary")
- (set_attr "cc" "set_znv")])
+ [(set_attr "length_table" "unary")])
(define_insn ""
+ [(set (reg:CCZN CC_REG)
+ (compare:CCZN
+ (match_operator:QHSI 3 "h8sx_unary_shift_operator"
+ [(match_operand:QHSI 1 "h8300_dst_operand" "0")
+ (match_operand:QI 2 "const_int_operand" "")])
+ (const_int 0)))
+ (set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
+ (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
+ "h8300_operands_match_p (operands)"
+{
+ if (<MODE>mode == E_QImode)
+ return output_h8sx_shift (operands, 'b', 'X');
+ if (<MODE>mode == E_HImode)
+ return output_h8sx_shift (operands, 'w', 'T');
+ if (<MODE>mode == E_SImode)
+ return output_h8sx_shift (operands, 'l', 'S');
+ gcc_unreachable ();
+}
+ [(set_attr "length_table" "unary")])
+
+(define_insn_and_split ""
[(set (match_operand:QHSI 0 "register_operand" "=r")
(match_operator:QHSI 3 "h8sx_binary_shift_operator"
[(match_operand:QHSI 1 "register_operand" "0")
(match_operand:QI 2 "nonmemory_operand" "r P5>X")]))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn ""
+ [(set (match_operand:QHSI 0 "register_operand" "=r")
+ (match_operator:QHSI 3 "h8sx_binary_shift_operator"
+ [(match_operand:QHSI 1 "register_operand" "0")
+ (match_operand:QI 2 "nonmemory_operand" "r P5>X")]))
+ (clobber (reg:CC CC_REG))]
+ ""
+{
+ if (<MODE>mode == QImode)
+ return output_h8sx_shift (operands, 'b', 'X');
+ if (<MODE>mode == HImode)
+ return output_h8sx_shift (operands, 'w', 'T');
+ if (<MODE>mode == SImode)
+ return output_h8sx_shift (operands, 'l', 'S');
+ gcc_unreachable ();
+}
+ [(set_attr "length" "4")])
+
+(define_insn ""
+ [(set (reg:CCZN CC_REG)
+ (compare:CCZN
+ (match_operator:QHSI 3 "h8sx_binary_shift_operator"
+ [(match_operand:QHSI 1 "register_operand" "0")
+ (match_operand:QI 2 "nonmemory_operand" "r P5>X")])
+ (const_int 0)))
+ (set (match_operand:QHSI 0 "register_operand" "=r")
+ (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
+ ""
{
if (<MODE>mode == QImode)
return output_h8sx_shift (operands, 'b', 'X');
@@ -83,54 +148,172 @@
return output_h8sx_shift (operands, 'l', 'S');
gcc_unreachable ();
}
- [(set_attr "length" "4")
- (set_attr "cc" "set_znv")])
+ [(set_attr "length" "4")])
-(define_insn "*shiftqi"
+(define_insn_and_split "*shiftqi"
[(set (match_operand:QI 0 "register_operand" "=r,r")
(match_operator:QI 3 "nshift_operator"
[(match_operand:QI 1 "register_operand" "0,0")
(match_operand:QI 2 "nonmemory_operand" "R,rn")]))
(clobber (match_scratch:QI 4 "=X,&r"))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+ (clobber (match_dup 4))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*shiftqi_clobber_flags"
+ [(set (match_operand:QI 0 "register_operand" "=r,r")
+ (match_operator:QI 3 "nshift_operator"
+ [(match_operand:QI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "R,rn")]))
+ (clobber (match_scratch:QI 4 "=X,&r"))
+ (clobber (reg:CC CC_REG))]
+ ""
{
return output_a_shift (operands);
}
[(set (attr "length")
- (symbol_ref "compute_a_shift_length (insn, operands)"))
- (set (attr "cc")
- (symbol_ref "compute_a_shift_cc (insn, operands)"))])
+ (symbol_ref "compute_a_shift_length (insn, operands)"))])
+
+(define_insn_and_split "*shiftqi_noscratch"
+ [(set (match_operand:QI 0 "register_operand" "=r,r")
+ (match_operator:QI 3 "nshift_operator"
+ [(match_operand:QI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "R,rn")]))]
+ "(GET_CODE (operands[2]) == CONST_INT
+ && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), QImode,
+ GET_CODE (operands[3])))"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+ (clobber (reg:CC CC_REG))])])
-(define_insn "*shifthi"
+(define_insn "*shiftqi_noscratch_clobber_flags"
+ [(set (match_operand:QI 0 "register_operand" "=r,r")
+ (match_operator:QI 3 "nshift_operator"
+ [(match_operand:QI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "R,rn")]))
+ (clobber (reg:CC CC_REG))]
+ "(GET_CODE (operands[2]) == CONST_INT
+ && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), QImode,
+ GET_CODE (operands[3])))"
+{
+ return output_a_shift (operands);
+}
+ [(set (attr "length")
+ (symbol_ref "compute_a_shift_length (insn, operands)"))])
+
+(define_insn_and_split "*shifthi"
[(set (match_operand:HI 0 "register_operand" "=r,r")
(match_operator:HI 3 "nshift_operator"
[(match_operand:HI 1 "register_operand" "0,0")
(match_operand:QI 2 "nonmemory_operand" "S,rn")]))
(clobber (match_scratch:QI 4 "=X,&r"))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+ (clobber (match_dup 4))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*shifthi_clobber_flags"
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (match_operator:HI 3 "nshift_operator"
+ [(match_operand:HI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "S,rn")]))
+ (clobber (match_scratch:QI 4 "=X,&r"))
+ (clobber (reg:CC CC_REG))]
+ ""
{
return output_a_shift (operands);
}
[(set (attr "length")
- (symbol_ref "compute_a_shift_length (insn, operands)"))
- (set (attr "cc")
- (symbol_ref "compute_a_shift_cc (insn, operands)"))])
+ (symbol_ref "compute_a_shift_length (insn, operands)"))])
-(define_insn "*shiftsi"
+(define_insn_and_split "*shifthi_noscratch"
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (match_operator:HI 3 "nshift_operator"
+ [(match_operand:HI 1 "register_operand" "0,0")
+ (match_operand:HI 2 "nonmemory_operand" "S,rn")]))]
+ "(GET_CODE (operands[2]) == CONST_INT
+ && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), HImode,
+ GET_CODE (operands[3])))"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*shifthi_noscratch_clobber_flags"
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (match_operator:HI 3 "nshift_operator"
+ [(match_operand:HI 1 "register_operand" "0,0")
+ (match_operand:HI 2 "nonmemory_operand" "S,rn")]))
+ (clobber (reg:CC CC_REG))]
+ "(GET_CODE (operands[2]) == CONST_INT
+ && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), HImode,
+ GET_CODE (operands[3])))"
+{
+ return output_a_shift (operands);
+}
+ [(set (attr "length")
+ (symbol_ref "compute_a_shift_length (insn, operands)"))])
+
+(define_insn_and_split "*shiftsi"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(match_operator:SI 3 "nshift_operator"
[(match_operand:SI 1 "register_operand" "0,0")
(match_operand:QI 2 "nonmemory_operand" "T,rn")]))
(clobber (match_scratch:QI 4 "=X,&r"))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+ (clobber (match_dup 4))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "*shiftsi_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (match_operator:SI 3 "nshift_operator"
+ [(match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "T,rn")]))
+ (clobber (match_scratch:QI 4 "=X,&r"))
+ (clobber (reg:CC CC_REG))]
+ ""
{
return output_a_shift (operands);
}
[(set (attr "length")
- (symbol_ref "compute_a_shift_length (insn, operands)"))
- (set (attr "cc")
- (symbol_ref "compute_a_shift_cc (insn, operands)"))])
+ (symbol_ref "compute_a_shift_length (insn, operands)"))])
+
+(define_insn_and_split "*shiftsi_noscratch"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (match_operator:SI 3 "nshift_operator"
+ [(match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "T,rn")]))]
+ "(GET_CODE (operands[2]) == CONST_INT
+ && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), SImode,
+ GET_CODE (operands[3])))"
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+ (clobber (reg:CC CC_REG))])])
+(define_insn "*shiftsi_noscratch_clobber_flags"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (match_operator:SI 3 "nshift_operator"
+ [(match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "T,rn")]))
+ (clobber (reg:CC CC_REG))]
+ "(GET_CODE (operands[2]) == CONST_INT
+ && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), SImode,
+ GET_CODE (operands[3])))"
+{
+ return output_a_shift (operands);
+}
+ [(set (attr "length")
+ (symbol_ref "compute_a_shift_length (insn, operands)"))])
;; Split a variable shift into a loop. If the register containing
;; the shift count dies, then we just use that register.
@@ -140,12 +323,12 @@
(match_operator 2 "nshift_operator"
[(match_dup 0)
(match_operand:QI 1 "register_operand" "")]))
- (clobber (match_operand:QI 3 "register_operand" ""))]
+ (clobber (match_operand:QI 3 "register_operand" ""))
+ (clobber (reg:CC CC_REG))]
"epilogue_completed
&& find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
- [(set (cc0) (compare (match_dup 1) (const_int 0)))
- (set (pc)
- (if_then_else (le (cc0) (const_int 0))
+ [(set (pc)
+ (if_then_else (le (match_dup 1) (const_int 0))
(label_ref (match_dup 5))
(pc)))
(match_dup 4)
@@ -154,9 +337,8 @@
(match_op_dup 2 [(match_dup 0) (const_int 1)]))
(clobber (scratch:QI))])
(set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))
- (set (cc0) (compare (match_dup 1) (const_int 0)))
(set (pc)
- (if_then_else (ne (cc0) (const_int 0))
+ (if_then_else (ne (match_dup 1) (const_int 0))
(label_ref (match_dup 4))
(pc)))
(match_dup 5)]
@@ -170,14 +352,14 @@
(match_operator 2 "nshift_operator"
[(match_dup 0)
(match_operand:QI 1 "register_operand" "")]))
- (clobber (match_operand:QI 3 "register_operand" ""))]
+ (clobber (match_operand:QI 3 "register_operand" ""))
+ (clobber (reg:CC CC_REG))]
"epilogue_completed
&& !find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
[(set (match_dup 3)
(match_dup 1))
- (set (cc0) (compare (match_dup 3) (const_int 0)))
(set (pc)
- (if_then_else (le (cc0) (const_int 0))
+ (if_then_else (le (match_dup 3) (const_int 0))
(label_ref (match_dup 5))
(pc)))
(match_dup 4)
@@ -186,9 +368,8 @@
(match_op_dup 2 [(match_dup 0) (const_int 1)]))
(clobber (scratch:QI))])
(set (match_dup 3) (plus:QI (match_dup 3) (const_int -1)))
- (set (cc0) (compare (match_dup 3) (const_int 0)))
(set (pc)
- (if_then_else (ne (cc0) (const_int 0))
+ (if_then_else (ne (match_dup 3) (const_int 0))
(label_ref (match_dup 4))
(pc)))
(match_dup 5)]
@@ -196,6 +377,18 @@
operands[4] = gen_label_rtx ();
operands[5] = gen_label_rtx ();
})
+
+(define_split
+ [(set (match_operand:SI 0 "register_operand")
+ (match_operator:SI 3 "nshift_operator"
+ [(match_operand:SI 1 "register_operand")
+ (match_operand:QI 2 "nonmemory_operand")]))
+ (clobber (match_scratch:QI 4))]
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+ (clobber (match_dup 4))
+ (clobber (reg:CC CC_REG))])])
+
;; ----------------------------------------------------------------------
;; ROTATIONS
@@ -211,11 +404,22 @@
DONE;
})
-(define_insn "rotl<mode>3_1"
+(define_insn_and_split "rotl<mode>3_1"
[(set (match_operand:QHSI 0 "register_operand" "=r")
(rotate:QHSI (match_operand:QHSI 1 "register_operand" "0")
(match_operand:QI 2 "immediate_operand" "")))]
""
+ "#"
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (rotate:QHSI (match_dup 1) (match_dup 2)))
+ (clobber (reg:CC CC_REG))])])
+
+(define_insn "rotl<mode>3_1_clobber_flags"
+ [(set (match_operand:QHSI 0 "register_operand" "=r")
+ (rotate:QHSI (match_operand:QHSI 1 "register_operand" "0")
+ (match_operand:QI 2 "immediate_operand" "")))
+ (clobber (reg:CC CC_REG))]
+ ""
{
return output_a_rotate (ROTATE, operands);
}
diff --git a/gcc/config/h8300/testcompare.md b/gcc/config/h8300/testcompare.md
index 118db14..e9f6ddc 100644
--- a/gcc/config/h8300/testcompare.md
+++ b/gcc/config/h8300/testcompare.md
@@ -2,164 +2,149 @@
;; TEST INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_insn_and_split "*tst_extzv_1_n"
- [(set (cc0)
- (compare (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
- (const_int 1)
- (match_operand 1 "const_int_operand" "n,n,n"))
- (const_int 0)))
- (clobber (match_scratch:QI 2 "=X,X,&r"))]
- "!CONSTANT_P (operands[0])"
- "@
- btst\\t%Z1,%Y0
- btst\\t%Z1,%Y0
- #"
- "&& reload_completed
- && !satisfies_constraint_U (operands[0])"
- [(set (match_dup 2)
- (match_dup 0))
- (parallel [(set (cc0) (compare (zero_extract:SI (match_dup 2)
- (const_int 1)
- (match_dup 1))
- (const_int 0)))
- (clobber (scratch:QI))])]
- ""
- [(set_attr "length" "2,8,10")
- (set_attr "cc" "set_zn,set_zn,set_zn")])
-
-(define_insn ""
- [(set (cc0)
- (compare (zero_extract:HSI (match_operand:HSI 0 "register_operand" "r")
- (const_int 1)
- (match_operand 1 "const_int_operand" "n"))
- (const_int 0)))]
- "INTVAL (operands[1]) <= 15"
- "btst %Z1,%Y0"
- [(set_attr "length" "2")
- (set_attr "cc" "set_zn")])
-
-(define_insn_and_split "*tstsi_upper_bit"
- [(set (cc0)
- (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
- (const_int 1)
- (match_operand 1 "const_int_operand" "n"))
- (const_int 0)))
- (clobber (match_scratch:SI 2 "=&r"))]
- "INTVAL (operands[1]) >= 16"
- "#"
- "&& reload_completed"
- [(set (match_dup 2)
- (ior:SI (and:SI (match_dup 2)
- (const_int -65536))
- (lshiftrt:SI (match_dup 0)
- (const_int 16))))
- (set (cc0)
- (compare (zero_extract:SI (match_dup 2)
- (const_int 1)
- (match_dup 3))
- (const_int 0)))]
- {
- operands[3] = GEN_INT (INTVAL (operands[1]) - 16);
- })
-
-(define_insn "*tstsi_variable_bit"
- [(set (cc0)
- (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
- (const_int 1)
- (and:SI (match_operand:SI 1 "register_operand" "r")
- (const_int 7)))
- (const_int 0)))]
- ""
- "btst %w1,%w0"
- [(set_attr "length" "2")
- (set_attr "cc" "set_zn")])
-
-(define_insn_and_split "*tstsi_variable_bit_qi"
- [(set (cc0)
- (compare (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>"))
- (const_int 1)
- (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
- (const_int 7)))
- (const_int 0)))
- (clobber (match_scratch:QI 2 "=X,X,&r"))]
- "!CONSTANT_P (operands[0])"
- "@
- btst\\t%w1,%X0
- btst\\t%w1,%X0
- #"
- "&& reload_completed
- && !satisfies_constraint_U (operands[0])"
- [(set (match_dup 2)
- (match_dup 0))
- (parallel [(set (cc0)
- (compare (zero_extract:SI (zero_extend:SI (match_dup 2))
- (const_int 1)
- (and:SI (match_dup 1)
- (const_int 7)))
- (const_int 0)))
- (clobber (scratch:QI))])]
- ""
- [(set_attr "length" "2,8,10")
- (set_attr "cc" "set_zn,set_zn,set_zn")])
+;; (define_insn_and_split "*tst_extzv_1_n"
+;; [(set (cc0)
+;; (compare (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
+;; (const_int 1)
+;; (match_operand 1 "const_int_operand" "n,n,n"))
+;; (const_int 0)))
+;; (clobber (match_scratch:QI 2 "=X,X,&r"))]
+;; "!CONSTANT_P (operands[0])"
+;; "@
+;; btst\\t%Z1,%Y0
+;; btst\\t%Z1,%Y0
+;; #"
+;; "&& reload_completed
+;; && !satisfies_constraint_U (operands[0])"
+;; [(set (match_dup 2)
+;; (match_dup 0))
+;; (parallel [(set (cc0) (compare (zero_extract:SI (match_dup 2)
+;; (const_int 1)
+;; (match_dup 1))
+;; (const_int 0)))
+;; (clobber (scratch:QI))])]
+;; ""
+;; [(set_attr "length" "2,8,10")])
+;;
+;;(define_insn ""
+;; [(set (cc0)
+;; (compare (zero_extract:HSI (match_operand:HSI 0 "register_operand" "r")
+;; (const_int 1)
+;; (match_operand 1 "const_int_operand" "n"))
+;; (const_int 0)))]
+;; "INTVAL (operands[1]) <= 15"
+;; "btst %Z1,%Y0"
+;; [(set_attr "length" "2")])
+;;
+;;(define_insn_and_split "*tstsi_upper_bit"
+;; [(set (cc0)
+;; (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+;; (const_int 1)
+;; (match_operand 1 "const_int_operand" "n"))
+;; (const_int 0)))
+;; (clobber (match_scratch:SI 2 "=&r"))]
+;; "INTVAL (operands[1]) >= 16"
+;; "#"
+;; "&& reload_completed"
+;; [(set (match_dup 2)
+;; (ior:SI (and:SI (match_dup 2)
+;; (const_int -65536))
+;; (lshiftrt:SI (match_dup 0)
+;; (const_int 16))))
+;; (set (cc0)
+;; (compare (zero_extract:SI (match_dup 2)
+;; (const_int 1)
+;; (match_dup 3))
+;; (const_int 0)))]
+;; {
+;; operands[3] = GEN_INT (INTVAL (operands[1]) - 16);
+;; })
+;;
+;;(define_insn "*tstsi_variable_bit"
+;; [(set (cc0)
+;; (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+;; (const_int 1)
+;; (and:SI (match_operand:SI 1 "register_operand" "r")
+;; (const_int 7)))
+;; (const_int 0)))]
+;; ""
+;; "btst %w1,%w0"
+;; [(set_attr "length" "2")])
+;;
+;;(define_insn_and_split "*tstsi_variable_bit_qi"
+;; [(set (cc0)
+;; (compare (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>"))
+;; (const_int 1)
+;; (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
+;; (const_int 7)))
+;; (const_int 0)))
+;; (clobber (match_scratch:QI 2 "=X,X,&r"))]
+;; "!CONSTANT_P (operands[0])"
+;; "@
+;; btst\\t%w1,%X0
+;; btst\\t%w1,%X0
+;; #"
+;; "&& reload_completed
+;; && !satisfies_constraint_U (operands[0])"
+;; [(set (match_dup 2)
+;; (match_dup 0))
+;; (parallel [(set (cc0)
+;; (compare (zero_extract:SI (zero_extend:SI (match_dup 2))
+;; (const_int 1)
+;; (and:SI (match_dup 1)
+;; (const_int 7)))
+;; (const_int 0)))
+;; (clobber (scratch:QI))])]
+;; ""
+;; [(set_attr "length" "2,8,10")])
(define_insn "*tst<mode>"
- [(set (cc0)
- (compare (match_operand:QHI 0 "register_operand" "r")
- (const_int 0)))]
+ [(set (reg:CCZN CC_REG)
+ (compare:CCZN (match_operand:QHSI 0 "register_operand" "r")
+ (const_int 0)))]
""
{
if (<MODE>mode == QImode)
return "mov.b %X0,%X0";
else if (<MODE>mode == HImode)
return "mov.w %T0,%T0";
+ else if (<MODE>mode == SImode)
+ return "mov.l %S0,%S0";
gcc_unreachable ();
}
- [(set_attr "length" "2")
- (set_attr "cc" "set_znv")])
+ [(set_attr "length" "2")])
(define_insn "*tsthi_upper"
- [(set (cc0)
+ [(set (reg:CCZN CC_REG)
(compare (and:HI (match_operand:HI 0 "register_operand" "r")
(const_int -256))
(const_int 0)))]
- ""
+ "reload_completed"
"mov.b %t0,%t0"
- [(set_attr "length" "2")
- (set_attr "cc" "set_znv")])
-
-(define_insn "*tstsi"
- [(set (cc0)
- (compare (match_operand:SI 0 "register_operand" "r")
- (const_int 0)))]
- ""
- "mov.l %S0,%S0"
- [(set_attr "length" "2")
- (set_attr "cc" "set_znv")])
+ [(set_attr "length" "2")])
(define_insn "*tstsi_upper"
- [(set (cc0)
+ [(set (reg:CCZN CC_REG)
(compare (and:SI (match_operand:SI 0 "register_operand" "r")
(const_int -65536))
(const_int 0)))]
- ""
+ "reload_completed"
"mov.w %e0,%e0"
- [(set_attr "length" "2")
- (set_attr "cc" "set_znv")])
+ [(set_attr "length" "2")])
(define_insn "*cmpqi"
- [(set (cc0)
+ [(set (reg:CC CC_REG)
(compare (match_operand:QI 0 "h8300_dst_operand" "rQ")
(match_operand:QI 1 "h8300_src_operand" "rQi")))]
- ""
+ "reload_completed"
"cmp.b %X1,%X0"
- [(set_attr "length_table" "add")
- (set_attr "cc" "compare")])
+ [(set_attr "length_table" "add")])
-(define_insn "*cmphi_h8300hs_znvc"
- [(set (cc0)
+(define_insn "*cmphi"
+ [(set (reg:CC CC_REG)
(compare (match_operand:HI 0 "h8300_dst_operand" "rU,rQ")
(match_operand:HI 1 "h8300_src_operand" "P3>X,rQi")))]
- ""
+ "reload_completed"
{
switch (which_alternative)
{
@@ -174,14 +159,13 @@
gcc_unreachable ();
}
}
- [(set_attr "length_table" "short_immediate,add")
- (set_attr "cc" "compare,compare")])
+ [(set_attr "length_table" "short_immediate,add")])
(define_insn "cmpsi"
- [(set (cc0)
+ [(set (reg:CC CC_REG)
(compare (match_operand:SI 0 "h8300_dst_operand" "r,rQ")
(match_operand:SI 1 "h8300_src_operand" "P3>X,rQi")))]
- ""
+ "reload_completed"
{
switch (which_alternative)
{
@@ -197,5 +181,28 @@
}
}
[(set_attr "length" "2,*")
- (set_attr "length_table" "*,add")
- (set_attr "cc" "compare,compare")])
+ (set_attr "length_table" "*,add")])
+
+;; Convert a memory comparison to a move if there is a scratch register.
+
+(define_peephole2
+ [(match_scratch:QHSI 1 "r")
+ (set (reg:CC CC_REG)
+ (compare (match_operand:QHSI 0 "memory_operand" "")
+ (const_int 0)))]
+ ""
+ [(parallel [(set (match_dup 1) (match_dup 0)) (clobber (reg:CC CC_REG))])
+ (set (reg:CC CC_REG) (compare:CC (match_dup 1) (const_int 0)))])
+
+;; The compare-elimination pass does not handle memory reference. So this
+;; little peephole helps fill the gap and avoid code quality regressions.
+(define_peephole2
+ [(parallel [(set (match_operand:QHSI 0 "register_operand" "")
+ (match_operand:QHSI 1 "simple_memory_operand" ""))
+ (clobber (reg:CC CC_REG))])
+ (set (reg:CCZN CC_REG)
+ (compare:CCZN (match_dup 0) (const_int 0)))]
+ ""
+ [(parallel [(set (reg:CCZN CC_REG) (compare:CCZN (match_dup 1) (const_int 0)))
+ (set (match_dup 0) (match_dup 1))])])
+
diff --git a/gcc/config/i386/avx512vnnivlintrin.h b/gcc/config/i386/avx512vnnivlintrin.h
index b4a6db3..3845b03 100644
--- a/gcc/config/i386/avx512vnnivlintrin.h
+++ b/gcc/config/i386/avx512vnnivlintrin.h
@@ -34,13 +34,10 @@
#define __DISABLE_AVX512VNNIVL__
#endif /* __AVX512VNNIVL__ */
-extern __inline __m256i
-__attribute__((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_dpbusd_epi32 (__m256i __A, __m256i __B, __m256i __C)
-{
- return (__m256i) __builtin_ia32_vpdpbusd_v8si ((__v8si)__A, (__v8si) __B,
- (__v8si) __C);
-}
+#define _mm256_dpbusd_epi32(A, B, C) \
+ ((__m256i) __builtin_ia32_vpdpbusd_v8si ((__v8si) (A), \
+ (__v8si) (B), \
+ (__v8si) (C)))
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
@@ -58,13 +55,10 @@ _mm256_maskz_dpbusd_epi32 (__mmask8 __A, __m256i __B, __m256i __C, __m256i __D)
(__v8si) __C, (__v8si) __D, (__mmask8)__A);
}
-extern __inline __m128i
-__attribute__((__gnu_inline__, __always_inline__, __artificial__))
-_mm_dpbusd_epi32 (__m128i __A, __m128i __B, __m128i __C)
-{
- return (__m128i) __builtin_ia32_vpdpbusd_v4si ((__v4si)__A, (__v4si) __B,
- (__v4si) __C);
-}
+#define _mm_dpbusd_epi32(A, B, C) \
+ ((__m128i) __builtin_ia32_vpdpbusd_v4si ((__v4si) (A), \
+ (__v4si) (B), \
+ (__v4si) (C)))
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
@@ -82,13 +76,10 @@ _mm_maskz_dpbusd_epi32 (__mmask8 __A, __m128i __B, __m128i __C, __m128i __D)
(__v4si) __C, (__v4si) __D, (__mmask8)__A);
}
-extern __inline __m256i
-__attribute__((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_dpbusds_epi32 (__m256i __A, __m256i __B, __m256i __C)
-{
- return (__m256i) __builtin_ia32_vpdpbusds_v8si ((__v8si)__A, (__v8si) __B,
- (__v8si) __C);
-}
+#define _mm256_dpbusds_epi32(A, B, C) \
+ ((__m256i) __builtin_ia32_vpdpbusds_v8si ((__v8si) (A), \
+ (__v8si) (B), \
+ (__v8si) (C)))
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
@@ -107,13 +98,10 @@ _mm256_maskz_dpbusds_epi32 (__mmask8 __A, __m256i __B, __m256i __C,
(__v8si) __C, (__v8si) __D, (__mmask8)__A);
}
-extern __inline __m128i
-__attribute__((__gnu_inline__, __always_inline__, __artificial__))
-_mm_dpbusds_epi32 (__m128i __A, __m128i __B, __m128i __C)
-{
- return (__m128i) __builtin_ia32_vpdpbusds_v4si ((__v4si)__A, (__v4si) __B,
- (__v4si) __C);
-}
+#define _mm_dpbusds_epi32(A, B, C) \
+ ((__m128i) __builtin_ia32_vpdpbusds_v4si ((__v4si) (A), \
+ (__v4si) (B), \
+ (__v4si) (C)))
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
@@ -131,13 +119,10 @@ _mm_maskz_dpbusds_epi32 (__mmask8 __A, __m128i __B, __m128i __C, __m128i __D)
(__v4si) __C, (__v4si) __D, (__mmask8)__A);
}
-extern __inline __m256i
-__attribute__((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_dpwssd_epi32 (__m256i __A, __m256i __B, __m256i __C)
-{
- return (__m256i) __builtin_ia32_vpdpwssd_v8si ((__v8si)__A, (__v8si) __B,
- (__v8si) __C);
-}
+#define _mm256_dpwssd_epi32(A, B, C) \
+ ((__m256i) __builtin_ia32_vpdpwssd_v8si ((__v8si) (A), \
+ (__v8si) (B), \
+ (__v8si) (C)))
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
@@ -155,13 +140,10 @@ _mm256_maskz_dpwssd_epi32 (__mmask8 __A, __m256i __B, __m256i __C, __m256i __D)
(__v8si) __C, (__v8si) __D, (__mmask8)__A);
}
-extern __inline __m128i
-__attribute__((__gnu_inline__, __always_inline__, __artificial__))
-_mm_dpwssd_epi32 (__m128i __A, __m128i __B, __m128i __C)
-{
- return (__m128i) __builtin_ia32_vpdpwssd_v4si ((__v4si)__A, (__v4si) __B,
- (__v4si) __C);
-}
+#define _mm_dpwssd_epi32(A, B, C) \
+ ((__m128i) __builtin_ia32_vpdpwssd_v4si ((__v4si) (A), \
+ (__v4si) (B), \
+ (__v4si) (C)))
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
@@ -179,13 +161,10 @@ _mm_maskz_dpwssd_epi32 (__mmask8 __A, __m128i __B, __m128i __C, __m128i __D)
(__v4si) __C, (__v4si) __D, (__mmask8)__A);
}
-extern __inline __m256i
-__attribute__((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_dpwssds_epi32 (__m256i __A, __m256i __B, __m256i __C)
-{
- return (__m256i) __builtin_ia32_vpdpwssds_v8si ((__v8si)__A, (__v8si) __B,
- (__v8si) __C);
-}
+#define _mm256_dpwssds_epi32(A, B, C) \
+ ((__m256i) __builtin_ia32_vpdpwssds_v8si ((__v8si) (A), \
+ (__v8si) (B), \
+ (__v8si) (C)))
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
@@ -204,13 +183,10 @@ _mm256_maskz_dpwssds_epi32 (__mmask8 __A, __m256i __B, __m256i __C,
(__v8si) __C, (__v8si) __D, (__mmask8)__A);
}
-extern __inline __m128i
-__attribute__((__gnu_inline__, __always_inline__, __artificial__))
-_mm_dpwssds_epi32 (__m128i __A, __m128i __B, __m128i __C)
-{
- return (__m128i) __builtin_ia32_vpdpwssds_v4si ((__v4si)__A, (__v4si) __B,
- (__v4si) __C);
-}
+#define _mm_dpwssds_epi32(A, B, C) \
+ ((__m128i) __builtin_ia32_vpdpwssds_v4si ((__v4si) (A), \
+ (__v4si) (B), \
+ (__v4si) (C)))
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
diff --git a/gcc/config/i386/avxvnniintrin.h b/gcc/config/i386/avxvnniintrin.h
new file mode 100644
index 0000000..de7e6a9
--- /dev/null
+++ b/gcc/config/i386/avxvnniintrin.h
@@ -0,0 +1,113 @@
+/* Copyright (C) 2020 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.
+
+ 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/>. */
+
+#ifndef _IMMINTRIN_H_INCLUDED
+#error "Never use <avxvnniintrin.h> directly; include <immintrin.h> instead."
+#endif
+
+#ifndef _AVXVNNIINTRIN_H_INCLUDED
+#define _AVXVNNIINTRIN_H_INCLUDED
+
+#if !defined(__AVXVNNI__)
+#pragma GCC push_options
+#pragma GCC target("avxvnni")
+#define __DISABLE_AVXVNNIVL__
+#endif /* __AVXVNNIVL__ */
+
+extern __inline __m256i
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_dpbusd_avx_epi32(__m256i __A, __m256i __B, __m256i __C)
+{
+ return (__m256i) __builtin_ia32_vpdpbusd_v8si ((__v8si) __A,
+ (__v8si) __B,
+ (__v8si) __C);
+}
+
+extern __inline __m128i
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_dpbusd_avx_epi32(__m128i __A, __m128i __B, __m128i __C)
+{
+ return (__m128i) __builtin_ia32_vpdpbusd_v4si ((__v4si) __A,
+ (__v4si) __B,
+ (__v4si) __C);
+}
+
+extern __inline __m256i
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_dpbusds_avx_epi32(__m256i __A, __m256i __B, __m256i __C)
+{
+ return (__m256i) __builtin_ia32_vpdpbusds_v8si ((__v8si) __A,
+ (__v8si) __B,
+ (__v8si) __C);
+}
+
+extern __inline __m128i
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_dpbusds_avx_epi32(__m128i __A,__m128i __B,__m128i __C)
+{
+ return (__m128i) __builtin_ia32_vpdpbusds_v4si ((__v4si) __A,
+ (__v4si) __B,
+ (__v4si) __C);
+}
+
+extern __inline __m256i
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_dpwssd_avx_epi32(__m256i __A,__m256i __B,__m256i __C)
+{
+ return (__m256i) __builtin_ia32_vpdpwssd_v8si ((__v8si) __A,
+ (__v8si) __B,
+ (__v8si) __C);
+}
+
+extern __inline __m128i
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_dpwssd_avx_epi32(__m128i __A,__m128i __B,__m128i __C)
+{
+ return (__m128i) __builtin_ia32_vpdpwssd_v4si ((__v4si) __A,
+ (__v4si) __B,
+ (__v4si) __C);
+}
+
+extern __inline __m256i
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_dpwssds_avx_epi32(__m256i __A,__m256i __B,__m256i __C)
+{
+ return (__m256i) __builtin_ia32_vpdpwssds_v8si ((__v8si) __A,
+ (__v8si) __B,
+ (__v8si) __C);
+}
+
+extern __inline __m128i
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_dpwssds_avx_epi32(__m128i __A,__m128i __B,__m128i __C)
+{
+ return (__m128i) __builtin_ia32_vpdpwssds_v4si ((__v4si) __A,
+ (__v4si) __B,
+ (__v4si) __C);
+}
+
+#ifdef __DISABLE_AVXVNNIVL__
+#undef __DISABLE_AVXVNNIVL__
+#pragma GCC pop_options
+#endif /* __DISABLE_AVXVNNIVL__ */
+#endif /* _AVXVNNIINTRIN_H_INCLUDED */
diff --git a/gcc/config/i386/cet.c b/gcc/config/i386/cet.c
deleted file mode 100644
index 5450ac3..0000000
--- a/gcc/config/i386/cet.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Functions for CET/x86.
- Copyright (C) 2017-2020 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/>. */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "tm.h"
-#include "output.h"
-#include "linux-common.h"
-
-void
-file_end_indicate_exec_stack_and_cet (void)
-{
- file_end_indicate_exec_stack ();
-
- if (flag_cf_protection == CF_NONE)
- return;
-
- unsigned int feature_1 = 0;
-
- if (flag_cf_protection & CF_BRANCH)
- /* GNU_PROPERTY_X86_FEATURE_1_IBT. */
- feature_1 |= 0x1;
-
- if (flag_cf_protection & CF_RETURN)
- /* GNU_PROPERTY_X86_FEATURE_1_SHSTK. */
- feature_1 |= 0x2;
-
- if (feature_1)
- {
- int p2align = ptr_mode == SImode ? 2 : 3;
-
- /* Generate GNU_PROPERTY_X86_FEATURE_1_XXX. */
- switch_to_section (get_section (".note.gnu.property",
- SECTION_NOTYPE, NULL));
-
- ASM_OUTPUT_ALIGN (asm_out_file, p2align);
- /* name length. */
- fprintf (asm_out_file, ASM_LONG " 1f - 0f\n");
- /* data length. */
- fprintf (asm_out_file, ASM_LONG " 4f - 1f\n");
- /* note type: NT_GNU_PROPERTY_TYPE_0. */
- fprintf (asm_out_file, ASM_LONG " 5\n");
- fprintf (asm_out_file, "0:\n");
- /* vendor name: "GNU". */
- fprintf (asm_out_file, STRING_ASM_OP " \"GNU\"\n");
- fprintf (asm_out_file, "1:\n");
- ASM_OUTPUT_ALIGN (asm_out_file, p2align);
- /* pr_type: GNU_PROPERTY_X86_FEATURE_1_AND. */
- fprintf (asm_out_file, ASM_LONG " 0xc0000002\n");
- /* pr_datasz. */\
- fprintf (asm_out_file, ASM_LONG " 3f - 2f\n");
- fprintf (asm_out_file, "2:\n");
- /* GNU_PROPERTY_X86_FEATURE_1_XXX. */
- fprintf (asm_out_file, ASM_LONG " 0x%x\n", feature_1);
- fprintf (asm_out_file, "3:\n");
- ASM_OUTPUT_ALIGN (asm_out_file, p2align);
- fprintf (asm_out_file, "4:\n");
- }
-}
diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h
index 595b423..d2d42f7 100644
--- a/gcc/config/i386/cpuid.h
+++ b/gcc/config/i386/cpuid.h
@@ -25,6 +25,7 @@
#define _CPUID_H_INCLUDED
/* %eax */
+#define bit_AVXVNNI (1 << 4)
#define bit_AVX512BF16 (1 << 5)
#define bit_HRESET (1 << 22)
diff --git a/gcc/config/i386/gnu-property.c b/gcc/config/i386/gnu-property.c
new file mode 100644
index 0000000..1288325
--- /dev/null
+++ b/gcc/config/i386/gnu-property.c
@@ -0,0 +1,124 @@
+/* Functions for x86 GNU property.
+ Copyright (C) 2017-2020 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/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "output.h"
+#include "linux-common.h"
+
+static void
+emit_gnu_property (unsigned int type, unsigned int data)
+{
+ int p2align = ptr_mode == SImode ? 2 : 3;
+
+ switch_to_section (get_section (".note.gnu.property",
+ SECTION_NOTYPE, NULL));
+
+ ASM_OUTPUT_ALIGN (asm_out_file, p2align);
+ /* name length. */
+ fprintf (asm_out_file, ASM_LONG "1f - 0f\n");
+ /* data length. */
+ fprintf (asm_out_file, ASM_LONG "4f - 1f\n");
+ /* note type: NT_GNU_PROPERTY_TYPE_0. */
+ fprintf (asm_out_file, ASM_LONG "5\n");
+ fprintf (asm_out_file, "0:\n");
+ /* vendor name: "GNU". */
+ fprintf (asm_out_file, STRING_ASM_OP "\"GNU\"\n");
+ fprintf (asm_out_file, "1:\n");
+ ASM_OUTPUT_ALIGN (asm_out_file, p2align);
+ /* pr_type. */
+ fprintf (asm_out_file, ASM_LONG "0x%x\n", type);
+ /* pr_datasz. */
+ fprintf (asm_out_file, ASM_LONG "3f - 2f\n");
+ fprintf (asm_out_file, "2:\n");
+ fprintf (asm_out_file, ASM_LONG "0x%x\n", data);
+ fprintf (asm_out_file, "3:\n");
+ ASM_OUTPUT_ALIGN (asm_out_file, p2align);
+ fprintf (asm_out_file, "4:\n");
+}
+
+void
+file_end_indicate_exec_stack_and_gnu_property (void)
+{
+ file_end_indicate_exec_stack ();
+
+ if (flag_cf_protection == CF_NONE && !ix86_needed)
+ return;
+
+ unsigned int feature_1 = 0;
+
+ if (flag_cf_protection & CF_BRANCH)
+ /* GNU_PROPERTY_X86_FEATURE_1_IBT. */
+ feature_1 |= 0x1;
+
+ if (flag_cf_protection & CF_RETURN)
+ /* GNU_PROPERTY_X86_FEATURE_1_SHSTK. */
+ feature_1 |= 0x2;
+
+ /* Generate GNU_PROPERTY_X86_FEATURE_1_AND. */
+ if (feature_1)
+ emit_gnu_property (0xc0000002, feature_1);
+
+ unsigned int isa_1 = 0;
+ if (ix86_needed)
+ {
+ /* GNU_PROPERTY_X86_ISA_1_BASELINE. */
+ if (TARGET_64BIT
+ || TARGET_FXSR
+ || TARGET_80387
+ || TARGET_MMX
+ || TARGET_SSE
+ || TARGET_SSE2)
+ isa_1 |= 1 << 0;
+
+ /* GNU_PROPERTY_X86_ISA_1_V2. */
+ if (TARGET_CMPXCHG16B
+ || (TARGET_64BIT && TARGET_SAHF)
+ || TARGET_POPCNT
+ || TARGET_SSE3
+ || TARGET_SSSE3
+ || TARGET_SSE4_1
+ || TARGET_SSE4_2)
+ isa_1 |= 1 << 1;
+
+ /* GNU_PROPERTY_X86_ISA_1_V3. */
+ if (TARGET_AVX
+ || TARGET_AVX2
+ || TARGET_F16C
+ || TARGET_FMA
+ || TARGET_LZCNT
+ || TARGET_MOVBE
+ || TARGET_XSAVE)
+ isa_1 |= 1 << 2;
+
+ /* GNU_PROPERTY_X86_ISA_1_V4. */
+ if (TARGET_AVX512F
+ || TARGET_AVX512BW
+ || TARGET_AVX512CD
+ || TARGET_AVX512DQ
+ || TARGET_AVX512VL)
+ isa_1 |= 1 << 3;
+ }
+
+ /* Generate GNU_PROPERTY_X86_ISA_1_NEEDED. */
+ if (isa_1)
+ emit_gnu_property (0xc0008002, isa_1);
+}
diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def
index 4d38cea..67d5f2ef 100644
--- a/gcc/config/i386/i386-builtin.def
+++ b/gcc/config/i386/i386-builtin.def
@@ -2626,45 +2626,45 @@ BDESC (OPTION_MASK_ISA_GFNI | OPTION_MASK_ISA_AVX512VL | OPTION_MASK_ISA_AVX512B
BDESC (OPTION_MASK_ISA_GFNI | OPTION_MASK_ISA_SSE2, 0, CODE_FOR_vgf2p8mulb_v16qi, "__builtin_ia32_vgf2p8mulb_v16qi", IX86_BUILTIN_VGF2P8MULB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI)
BDESC (OPTION_MASK_ISA_GFNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vgf2p8mulb_v16qi_mask, "__builtin_ia32_vgf2p8mulb_v16qi_mask", IX86_BUILTIN_VGF2P8MULB128MASK, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI_V16QI_UHI)
-/* VNNI */
+/* AVX512_VNNI */
BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpbusd_v16si, "__builtin_ia32_vpdpbusd_v16si", IX86_BUILTIN_VPDPBUSDV16SI, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI)
BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpbusd_v16si_mask, "__builtin_ia32_vpdpbusd_v16si_mask", IX86_BUILTIN_VPDPBUSDV16SI_MASK, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpbusd_v16si_maskz, "__builtin_ia32_vpdpbusd_v16si_maskz", IX86_BUILTIN_VPDPBUSDV16SI_MASKZ, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusd_v8si, "__builtin_ia32_vpdpbusd_v8si", IX86_BUILTIN_VPDPBUSDV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, OPTION_MASK_ISA2_AVXVNNI, CODE_FOR_vpdpbusd_v8si, "__builtin_ia32_vpdpbusd_v8si", IX86_BUILTIN_VPDPBUSDV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusd_v8si_mask, "__builtin_ia32_vpdpbusd_v8si_mask", IX86_BUILTIN_VPDPBUSDV8SI_MASK, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusd_v8si_maskz, "__builtin_ia32_vpdpbusd_v8si_maskz", IX86_BUILTIN_VPDPBUSDV8SI_MASKZ, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusd_v4si, "__builtin_ia32_vpdpbusd_v4si", IX86_BUILTIN_VPDPBUSDV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, OPTION_MASK_ISA2_AVXVNNI, CODE_FOR_vpdpbusd_v4si, "__builtin_ia32_vpdpbusd_v4si", IX86_BUILTIN_VPDPBUSDV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusd_v4si_mask, "__builtin_ia32_vpdpbusd_v4si_mask", IX86_BUILTIN_VPDPBUSDV4SI_MASK, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusd_v4si_maskz, "__builtin_ia32_vpdpbusd_v4si_maskz", IX86_BUILTIN_VPDPBUSDV4SI_MASKZ, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpbusds_v16si, "__builtin_ia32_vpdpbusds_v16si", IX86_BUILTIN_VPDPBUSDSV16SI, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI)
BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpbusds_v16si_mask, "__builtin_ia32_vpdpbusds_v16si_mask", IX86_BUILTIN_VPDPBUSDSV16SI_MASK, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpbusds_v16si_maskz, "__builtin_ia32_vpdpbusds_v16si_maskz", IX86_BUILTIN_VPDPBUSDSV16SI_MASKZ, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusds_v8si, "__builtin_ia32_vpdpbusds_v8si", IX86_BUILTIN_VPDPBUSDSV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, OPTION_MASK_ISA2_AVXVNNI, CODE_FOR_vpdpbusds_v8si, "__builtin_ia32_vpdpbusds_v8si", IX86_BUILTIN_VPDPBUSDSV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusds_v8si_mask, "__builtin_ia32_vpdpbusds_v8si_mask", IX86_BUILTIN_VPDPBUSDSV8SI_MASK, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusds_v8si_maskz, "__builtin_ia32_vpdpbusds_v8si_maskz", IX86_BUILTIN_VPDPBUSDSV8SI_MASKZ, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusds_v4si, "__builtin_ia32_vpdpbusds_v4si", IX86_BUILTIN_VPDPBUSDSV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, OPTION_MASK_ISA2_AVXVNNI, CODE_FOR_vpdpbusds_v4si, "__builtin_ia32_vpdpbusds_v4si", IX86_BUILTIN_VPDPBUSDSV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusds_v4si_mask, "__builtin_ia32_vpdpbusds_v4si_mask", IX86_BUILTIN_VPDPBUSDSV4SI_MASK, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusds_v4si_maskz, "__builtin_ia32_vpdpbusds_v4si_maskz", IX86_BUILTIN_VPDPBUSDSV4SI_MASKZ, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpwssd_v16si, "__builtin_ia32_vpdpwssd_v16si", IX86_BUILTIN_VPDPWSSDV16SI, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI)
BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpwssd_v16si_mask, "__builtin_ia32_vpdpwssd_v16si_mask", IX86_BUILTIN_VPDPWSSDV16SI_MASK, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpwssd_v16si_maskz, "__builtin_ia32_vpdpwssd_v16si_maskz", IX86_BUILTIN_VPDPWSSDV16SI_MASKZ, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssd_v8si, "__builtin_ia32_vpdpwssd_v8si", IX86_BUILTIN_VPDPWSSDV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, OPTION_MASK_ISA2_AVXVNNI, CODE_FOR_vpdpwssd_v8si, "__builtin_ia32_vpdpwssd_v8si", IX86_BUILTIN_VPDPWSSDV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssd_v8si_mask, "__builtin_ia32_vpdpwssd_v8si_mask", IX86_BUILTIN_VPDPWSSDV8SI_MASK, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssd_v8si_maskz, "__builtin_ia32_vpdpwssd_v8si_maskz", IX86_BUILTIN_VPDPWSSDV8SI_MASKZ, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssd_v4si, "__builtin_ia32_vpdpwssd_v4si", IX86_BUILTIN_VPDPWSSDV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, OPTION_MASK_ISA2_AVXVNNI, CODE_FOR_vpdpwssd_v4si, "__builtin_ia32_vpdpwssd_v4si", IX86_BUILTIN_VPDPWSSDV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssd_v4si_mask, "__builtin_ia32_vpdpwssd_v4si_mask", IX86_BUILTIN_VPDPWSSDV4SI_MASK, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssd_v4si_maskz, "__builtin_ia32_vpdpwssd_v4si_maskz", IX86_BUILTIN_VPDPWSSDV4SI_MASKZ, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpwssds_v16si, "__builtin_ia32_vpdpwssds_v16si", IX86_BUILTIN_VPDPWSSDSV16SI, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI)
BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpwssds_v16si_mask, "__builtin_ia32_vpdpwssds_v16si_mask", IX86_BUILTIN_VPDPWSSDSV16SI_MASK, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpwssds_v16si_maskz, "__builtin_ia32_vpdpwssds_v16si_maskz", IX86_BUILTIN_VPDPWSSDSV16SI_MASKZ, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssds_v8si, "__builtin_ia32_vpdpwssds_v8si", IX86_BUILTIN_VPDPWSSDSV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, OPTION_MASK_ISA2_AVXVNNI, CODE_FOR_vpdpwssds_v8si, "__builtin_ia32_vpdpwssds_v8si", IX86_BUILTIN_VPDPWSSDSV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssds_v8si_mask, "__builtin_ia32_vpdpwssds_v8si_mask", IX86_BUILTIN_VPDPWSSDSV8SI_MASK, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssds_v8si_maskz, "__builtin_ia32_vpdpwssds_v8si_maskz", IX86_BUILTIN_VPDPWSSDSV8SI_MASKZ, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssds_v4si, "__builtin_ia32_vpdpwssds_v4si", IX86_BUILTIN_VPDPWSSDSV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, OPTION_MASK_ISA2_AVXVNNI, CODE_FOR_vpdpwssds_v4si, "__builtin_ia32_vpdpwssds_v4si", IX86_BUILTIN_VPDPWSSDSV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssds_v4si_mask, "__builtin_ia32_vpdpwssds_v4si_mask", IX86_BUILTIN_VPDPWSSDSV4SI_MASK, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssds_v4si_maskz, "__builtin_ia32_vpdpwssds_v4si_maskz", IX86_BUILTIN_VPDPWSSDSV4SI_MASKZ, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
diff --git a/gcc/config/i386/i386-builtins.c b/gcc/config/i386/i386-builtins.c
index 504987a..d8ec1e5 100644
--- a/gcc/config/i386/i386-builtins.c
+++ b/gcc/config/i386/i386-builtins.c
@@ -274,6 +274,10 @@ def_builtin (HOST_WIDE_INT mask, HOST_WIDE_INT mask2,
if (((mask2 == 0 || (mask2 & ix86_isa_flags2) != 0)
&& (mask == 0 || (mask & ix86_isa_flags) != 0))
|| ((mask & OPTION_MASK_ISA_MMX) != 0 && TARGET_MMX_WITH_SSE)
+ /* "Unified" builtin used by either AVXVNNI intrinsics or AVX512VNNIVL
+ non-mask intrinsics should be defined whenever avxvnni
+ or avx512vnni && avx512vl exist. */
+ || (mask2 == OPTION_MASK_ISA2_AVXVNNI)
|| (lang_hooks.builtin_function
== lang_hooks.builtin_function_ext_scope))
{
diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c
index 3299a56..87b3a2b 100644
--- a/gcc/config/i386/i386-c.c
+++ b/gcc/config/i386/i386-c.c
@@ -606,6 +606,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
def_or_undef (parse_in, "__KL__");
if (isa_flag2 & OPTION_MASK_ISA2_WIDEKL)
def_or_undef (parse_in, "__WIDEKL__");
+ if (isa_flag2 & OPTION_MASK_ISA2_AVXVNNI)
+ def_or_undef (parse_in, "__AVXVNNI__");
if (TARGET_IAMCU)
{
def_or_undef (parse_in, "__iamcu");
diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index 6f81b58..7c31cc7 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -196,6 +196,17 @@ ix86_expand_move (machine_mode mode, rtx operands[])
op0 = operands[0];
op1 = operands[1];
+ /* Avoid complex sets of likely spilled hard registers before reload. */
+ if (!ix86_hardreg_mov_ok (op0, op1))
+ {
+ tmp = gen_reg_rtx (mode);
+ operands[0] = tmp;
+ ix86_expand_move (mode, operands);
+ operands[0] = op0;
+ operands[1] = tmp;
+ op1 = tmp;
+ }
+
switch (GET_CODE (op1))
{
case CONST:
@@ -8052,7 +8063,17 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
}
else if (!TARGET_PECOFF && !TARGET_MACHO)
{
- if (TARGET_64BIT)
+ if (TARGET_64BIT
+ && ix86_cmodel == CM_LARGE_PIC
+ && DEFAULT_ABI != MS_ABI)
+ {
+ fnaddr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
+ UNSPEC_GOT);
+ fnaddr = gen_rtx_CONST (Pmode, fnaddr);
+ fnaddr = force_reg (Pmode, fnaddr);
+ fnaddr = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, fnaddr);
+ }
+ else if (TARGET_64BIT)
{
fnaddr = gen_rtx_UNSPEC (Pmode,
gen_rtvec (1, addr),
@@ -8288,16 +8309,12 @@ ix86_expand_multi_arg_builtin (enum insn_code icode, tree exp, rtx target,
enum rtx_code sub_code)
{
rtx pat;
- int i;
- int nargs;
+ unsigned int i, nargs;
bool comparison_p = false;
bool tf_p = false;
bool last_arg_constant = false;
int num_memory = 0;
- struct {
- rtx op;
- machine_mode mode;
- } args[4];
+ rtx xops[4];
machine_mode tmode = insn_data[icode].operand[0].mode;
@@ -8391,7 +8408,7 @@ ix86_expand_multi_arg_builtin (enum insn_code icode, tree exp, rtx target,
else if (memory_operand (target, tmode))
num_memory++;
- gcc_assert (nargs <= 4);
+ gcc_assert (nargs <= ARRAY_SIZE (xops));
for (i = 0; i < nargs; i++)
{
@@ -8471,38 +8488,36 @@ ix86_expand_multi_arg_builtin (enum insn_code icode, tree exp, rtx target,
op = force_reg (mode, op);
}
- args[i].op = op;
- args[i].mode = mode;
+ xops[i] = op;
}
switch (nargs)
{
case 1:
- pat = GEN_FCN (icode) (target, args[0].op);
+ pat = GEN_FCN (icode) (target, xops[0]);
break;
case 2:
if (tf_p)
- pat = GEN_FCN (icode) (target, args[0].op, args[1].op,
+ pat = GEN_FCN (icode) (target, xops[0], xops[1],
GEN_INT ((int)sub_code));
else if (! comparison_p)
- pat = GEN_FCN (icode) (target, args[0].op, args[1].op);
+ pat = GEN_FCN (icode) (target, xops[0], xops[1]);
else
{
rtx cmp_op = gen_rtx_fmt_ee (sub_code, GET_MODE (target),
- args[0].op,
- args[1].op);
+ xops[0], xops[1]);
- pat = GEN_FCN (icode) (target, cmp_op, args[0].op, args[1].op);
+ pat = GEN_FCN (icode) (target, cmp_op, xops[0], xops[1]);
}
break;
case 3:
- pat = GEN_FCN (icode) (target, args[0].op, args[1].op, args[2].op);
+ pat = GEN_FCN (icode) (target, xops[0], xops[1], xops[2]);
break;
case 4:
- pat = GEN_FCN (icode) (target, args[0].op, args[1].op, args[2].op, args[3].op);
+ pat = GEN_FCN (icode) (target, xops[0], xops[1], xops[2], xops[3]);
break;
default:
@@ -8982,11 +8997,7 @@ ix86_expand_args_builtin (const struct builtin_description *d,
unsigned int nargs_constant = 0;
unsigned int mask_pos = 0;
int num_memory = 0;
- struct
- {
- rtx op;
- machine_mode mode;
- } args[6];
+ rtx xops[6];
bool second_arg_count = false;
enum insn_code icode = d->icode;
const struct insn_data_d *insn_p = &insn_data[icode];
@@ -9746,7 +9757,7 @@ ix86_expand_args_builtin (const struct builtin_description *d,
gcc_unreachable ();
}
- gcc_assert (nargs <= ARRAY_SIZE (args));
+ gcc_assert (nargs <= ARRAY_SIZE (xops));
if (comparison != UNKNOWN)
{
@@ -9953,34 +9964,31 @@ ix86_expand_args_builtin (const struct builtin_description *d,
}
}
- args[i].op = op;
- args[i].mode = mode;
+ xops[i] = op;
}
switch (nargs)
{
case 1:
- pat = GEN_FCN (icode) (real_target, args[0].op);
+ pat = GEN_FCN (icode) (real_target, xops[0]);
break;
case 2:
- pat = GEN_FCN (icode) (real_target, args[0].op, args[1].op);
+ pat = GEN_FCN (icode) (real_target, xops[0], xops[1]);
break;
case 3:
- pat = GEN_FCN (icode) (real_target, args[0].op, args[1].op,
- args[2].op);
+ pat = GEN_FCN (icode) (real_target, xops[0], xops[1], xops[2]);
break;
case 4:
- pat = GEN_FCN (icode) (real_target, args[0].op, args[1].op,
- args[2].op, args[3].op);
+ pat = GEN_FCN (icode) (real_target, xops[0], xops[1],
+ xops[2], xops[3]);
break;
case 5:
- pat = GEN_FCN (icode) (real_target, args[0].op, args[1].op,
- args[2].op, args[3].op, args[4].op);
+ pat = GEN_FCN (icode) (real_target, xops[0], xops[1],
+ xops[2], xops[3], xops[4]);
break;
case 6:
- pat = GEN_FCN (icode) (real_target, args[0].op, args[1].op,
- args[2].op, args[3].op, args[4].op,
- args[5].op);
+ pat = GEN_FCN (icode) (real_target, xops[0], xops[1],
+ xops[2], xops[3], xops[4], xops[5]);
break;
default:
gcc_unreachable ();
@@ -10247,11 +10255,7 @@ ix86_expand_round_builtin (const struct builtin_description *d,
{
rtx pat;
unsigned int i, nargs;
- struct
- {
- rtx op;
- machine_mode mode;
- } args[6];
+ rtx xops[6];
enum insn_code icode = d->icode;
const struct insn_data_d *insn_p = &insn_data[icode];
machine_mode tmode = insn_p->operand[0].mode;
@@ -10351,7 +10355,7 @@ ix86_expand_round_builtin (const struct builtin_description *d,
default:
gcc_unreachable ();
}
- gcc_assert (nargs <= ARRAY_SIZE (args));
+ gcc_assert (nargs <= ARRAY_SIZE (xops));
if (optimize
|| target == 0
@@ -10423,34 +10427,31 @@ ix86_expand_round_builtin (const struct builtin_description *d,
}
}
- args[i].op = op;
- args[i].mode = mode;
+ xops[i] = op;
}
switch (nargs)
{
case 1:
- pat = GEN_FCN (icode) (target, args[0].op);
+ pat = GEN_FCN (icode) (target, xops[0]);
break;
case 2:
- pat = GEN_FCN (icode) (target, args[0].op, args[1].op);
+ pat = GEN_FCN (icode) (target, xops[0], xops[1]);
break;
case 3:
- pat = GEN_FCN (icode) (target, args[0].op, args[1].op,
- args[2].op);
+ pat = GEN_FCN (icode) (target, xops[0], xops[1], xops[2]);
break;
case 4:
- pat = GEN_FCN (icode) (target, args[0].op, args[1].op,
- args[2].op, args[3].op);
+ pat = GEN_FCN (icode) (target, xops[0], xops[1],
+ xops[2], xops[3]);
break;
case 5:
- pat = GEN_FCN (icode) (target, args[0].op, args[1].op,
- args[2].op, args[3].op, args[4].op);
+ pat = GEN_FCN (icode) (target, xops[0], xops[1],
+ xops[2], xops[3], xops[4]);
break;
case 6:
- pat = GEN_FCN (icode) (target, args[0].op, args[1].op,
- args[2].op, args[3].op, args[4].op,
- args[5].op);
+ pat = GEN_FCN (icode) (target, xops[0], xops[1],
+ xops[2], xops[3], xops[4], xops[5]);
break;
default:
gcc_unreachable ();
@@ -10477,13 +10478,8 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
rtx pat, op;
unsigned int i, nargs, arg_adjust, memory;
bool aligned_mem = false;
- struct
- {
- rtx op;
- machine_mode mode;
- } args[3];
+ rtx xops[3];
enum insn_code icode = d->icode;
- bool last_arg_constant = false;
const struct insn_data_d *insn_p = &insn_data[icode];
machine_mode tmode = insn_p->operand[0].mode;
enum { load, store } klass;
@@ -10556,7 +10552,7 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
nargs = 1;
klass = store;
/* Reserve memory operand for target. */
- memory = ARRAY_SIZE (args);
+ memory = ARRAY_SIZE (xops);
switch (icode)
{
/* These builtins and instructions require the memory
@@ -10693,7 +10689,7 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
nargs = 2;
klass = store;
/* Reserve memory operand for target. */
- memory = ARRAY_SIZE (args);
+ memory = ARRAY_SIZE (xops);
break;
case V4SF_FTYPE_PCV4SF_V4SF_UQI:
case V8SF_FTYPE_PCV8SF_V8SF_UQI:
@@ -10767,7 +10763,7 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
gcc_unreachable ();
}
- gcc_assert (nargs <= ARRAY_SIZE (args));
+ gcc_assert (nargs <= ARRAY_SIZE (xops));
if (klass == store)
{
@@ -10807,59 +10803,51 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
for (i = 0; i < nargs; i++)
{
machine_mode mode = insn_p->operand[i + 1].mode;
- bool match;
arg = CALL_EXPR_ARG (exp, i + arg_adjust);
op = expand_normal (arg);
- match = insn_p->operand[i + 1].predicate (op, mode);
- if (last_arg_constant && (i + 1) == nargs)
+ if (i == memory)
{
- if (!match)
- {
- error ("the last argument must be an 8-bit immediate");
- return const0_rtx;
- }
+ /* This must be the memory operand. */
+ op = ix86_zero_extend_to_Pmode (op);
+ op = gen_rtx_MEM (mode, op);
+ /* op at this point has just BITS_PER_UNIT MEM_ALIGN
+ on it. Try to improve it using get_pointer_alignment,
+ and if the special builtin is one that requires strict
+ mode alignment, also from it's GET_MODE_ALIGNMENT.
+ Failure to do so could lead to ix86_legitimate_combined_insn
+ rejecting all changes to such insns. */
+ unsigned int align = get_pointer_alignment (arg);
+ if (aligned_mem && align < GET_MODE_ALIGNMENT (mode))
+ align = GET_MODE_ALIGNMENT (mode);
+ if (MEM_ALIGN (op) < align)
+ set_mem_align (op, align);
}
else
{
- if (i == memory)
- {
- /* This must be the memory operand. */
- op = ix86_zero_extend_to_Pmode (op);
- op = gen_rtx_MEM (mode, op);
- /* op at this point has just BITS_PER_UNIT MEM_ALIGN
- on it. Try to improve it using get_pointer_alignment,
- and if the special builtin is one that requires strict
- mode alignment, also from it's GET_MODE_ALIGNMENT.
- Failure to do so could lead to ix86_legitimate_combined_insn
- rejecting all changes to such insns. */
- unsigned int align = get_pointer_alignment (arg);
- if (aligned_mem && align < GET_MODE_ALIGNMENT (mode))
- align = GET_MODE_ALIGNMENT (mode);
- if (MEM_ALIGN (op) < align)
- set_mem_align (op, align);
- }
- else
- {
- /* This must be register. */
- if (VECTOR_MODE_P (mode))
- op = safe_vector_operand (op, mode);
+ /* This must be register. */
+ if (VECTOR_MODE_P (mode))
+ op = safe_vector_operand (op, mode);
- op = fixup_modeless_constant (op, mode);
+ op = fixup_modeless_constant (op, mode);
- if (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode)
- op = copy_to_mode_reg (mode, op);
- else
- {
- op = copy_to_reg (op);
- op = lowpart_subreg (mode, op, GET_MODE (op));
- }
+ /* NB: 3-operands load implied it's a mask load,
+ and that mask operand shoud be at the end.
+ Keep all-ones mask which would be simplified by the expander. */
+ if (nargs == 3 && i == 2 && klass == load
+ && constm1_operand (op, mode))
+ ;
+ else if (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode)
+ op = copy_to_mode_reg (mode, op);
+ else
+ {
+ op = copy_to_reg (op);
+ op = lowpart_subreg (mode, op, GET_MODE (op));
}
}
- args[i].op = op;
- args[i].mode = mode;
+ xops[i]= op;
}
switch (nargs)
@@ -10868,13 +10856,13 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
pat = GEN_FCN (icode) (target);
break;
case 1:
- pat = GEN_FCN (icode) (target, args[0].op);
+ pat = GEN_FCN (icode) (target, xops[0]);
break;
case 2:
- pat = GEN_FCN (icode) (target, args[0].op, args[1].op);
+ pat = GEN_FCN (icode) (target, xops[0], xops[1]);
break;
case 3:
- pat = GEN_FCN (icode) (target, args[0].op, args[1].op, args[2].op);
+ pat = GEN_FCN (icode) (target, xops[0], xops[1], xops[2]);
break;
default:
gcc_unreachable ();
@@ -10882,6 +10870,7 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
if (! pat)
return 0;
+
emit_insn (pat);
return klass == store ? 0 : target;
}
@@ -11059,6 +11048,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A
OPTION_MASK_ISA_SSE4_2 | OPTION_MASK_ISA_CRC32
OPTION_MASK_ISA_FMA | OPTION_MASK_ISA_FMA4
+ (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL) or
+ OPTION_MASK_ISA2_AVXVNNI
where for each such pair it is sufficient if either of the ISAs is
enabled, plus if it is ored with other options also those others.
OPTION_MASK_ISA_MMX in bisa is satisfied also if TARGET_MMX_WITH_SSE. */
@@ -11077,6 +11068,17 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
&& (isa & (OPTION_MASK_ISA_FMA | OPTION_MASK_ISA_FMA4)) != 0)
isa |= (OPTION_MASK_ISA_FMA | OPTION_MASK_ISA_FMA4);
+ if ((((bisa & (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL))
+ == (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL))
+ || (bisa2 & OPTION_MASK_ISA2_AVXVNNI) != 0)
+ && (((isa & (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL))
+ == (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL))
+ || (isa2 & OPTION_MASK_ISA2_AVXVNNI) != 0))
+ {
+ isa |= OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL;
+ isa2 |= OPTION_MASK_ISA2_AVXVNNI;
+ }
+
if ((bisa & OPTION_MASK_ISA_MMX) && !TARGET_MMX && TARGET_MMX_WITH_SSE
/* __builtin_ia32_maskmovq requires MMX registers. */
&& fcode != IX86_BUILTIN_MASKMOVQ)
@@ -14540,6 +14542,112 @@ ix86_expand_vector_init (bool mmx_ok, rtx target, rtx vals)
ix86_expand_vector_init_general (mmx_ok, mode, target, vals);
}
+/* Implemented as
+ V setg (V v, int idx, T val)
+ {
+ V idxv = (V){idx, idx, idx, idx, idx, idx, idx, idx};
+ V valv = (V){val, val, val, val, val, val, val, val};
+ V mask = ((V){0, 1, 2, 3, 4, 5, 6, 7} == idxv);
+ v = (v & ~mask) | (valv & mask);
+ return v;
+ }. */
+void
+ix86_expand_vector_set_var (rtx target, rtx val, rtx idx)
+{
+ rtx vec[64];
+ machine_mode mode = GET_MODE (target);
+ machine_mode cmp_mode = mode;
+ int n_elts = GET_MODE_NUNITS (mode);
+ rtx valv,idxv,constv,idx_tmp;
+ bool ok = false;
+
+ /* 512-bits vector byte/word broadcast and comparison only available
+ under TARGET_AVX512BW, break 512-bits vector into two 256-bits vector
+ when without TARGET_AVX512BW. */
+ if ((mode == V32HImode || mode == V64QImode) && !TARGET_AVX512BW)
+ {
+ gcc_assert (TARGET_AVX512F);
+ rtx vhi, vlo, idx_hi;
+ machine_mode half_mode;
+ rtx (*extract_hi)(rtx, rtx);
+ rtx (*extract_lo)(rtx, rtx);
+
+ if (mode == V32HImode)
+ {
+ half_mode = V16HImode;
+ extract_hi = gen_vec_extract_hi_v32hi;
+ extract_lo = gen_vec_extract_lo_v32hi;
+ }
+ else
+ {
+ half_mode = V32QImode;
+ extract_hi = gen_vec_extract_hi_v64qi;
+ extract_lo = gen_vec_extract_lo_v64qi;
+ }
+
+ vhi = gen_reg_rtx (half_mode);
+ vlo = gen_reg_rtx (half_mode);
+ idx_hi = gen_reg_rtx (GET_MODE (idx));
+ emit_insn (extract_hi (vhi, target));
+ emit_insn (extract_lo (vlo, target));
+ vec[0] = idx_hi;
+ vec[1] = idx;
+ vec[2] = GEN_INT (n_elts/2);
+ ix86_expand_binary_operator (MINUS, GET_MODE (idx), vec);
+ ix86_expand_vector_set_var (vhi, val, idx_hi);
+ ix86_expand_vector_set_var (vlo, val, idx);
+ emit_insn (gen_rtx_SET (target, gen_rtx_VEC_CONCAT (mode, vlo, vhi)));
+ return;
+ }
+
+ if (FLOAT_MODE_P (GET_MODE_INNER (mode)))
+ {
+ switch (mode)
+ {
+ case E_V2DFmode:
+ cmp_mode = V2DImode;
+ break;
+ case E_V4DFmode:
+ cmp_mode = V4DImode;
+ break;
+ case E_V8DFmode:
+ cmp_mode = V8DImode;
+ break;
+ case E_V4SFmode:
+ cmp_mode = V4SImode;
+ break;
+ case E_V8SFmode:
+ cmp_mode = V8SImode;
+ break;
+ case E_V16SFmode:
+ cmp_mode = V16SImode;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ }
+
+ for (int i = 0; i != n_elts; i++)
+ vec[i] = GEN_INT (i);
+ constv = gen_rtx_CONST_VECTOR (cmp_mode, gen_rtvec_v (n_elts, vec));
+ valv = gen_reg_rtx (mode);
+ idxv = gen_reg_rtx (cmp_mode);
+ idx_tmp = convert_to_mode (GET_MODE_INNER (cmp_mode), idx, 1);
+
+ ok = ix86_expand_vector_init_duplicate (false, mode, valv, val);
+ gcc_assert (ok);
+ ok = ix86_expand_vector_init_duplicate (false, cmp_mode, idxv, idx_tmp);
+ gcc_assert (ok);
+ vec[0] = target;
+ vec[1] = valv;
+ vec[2] = target;
+ vec[3] = gen_rtx_EQ (mode, idxv, constv);
+ vec[4] = idxv;
+ vec[5] = constv;
+ ok = ix86_expand_int_vcond (vec);
+ gcc_assert (ok);
+}
+
void
ix86_expand_vector_set (bool mmx_ok, rtx target, rtx val, int elt)
{
diff --git a/gcc/config/i386/i386-features.c b/gcc/config/i386/i386-features.c
index 620f7f1..ff6676f 100644
--- a/gcc/config/i386/i386-features.c
+++ b/gcc/config/i386/i386-features.c
@@ -581,7 +581,8 @@ general_scalar_chain::compute_convert_gain ()
else if (GET_CODE (src) == NEG
|| GET_CODE (src) == NOT)
igain += m * ix86_cost->add - ix86_cost->sse_op - COSTS_N_INSNS (1);
- else if (GET_CODE (src) == SMAX
+ else if (GET_CODE (src) == ABS
+ || GET_CODE (src) == SMAX
|| GET_CODE (src) == SMIN
|| GET_CODE (src) == UMAX
|| GET_CODE (src) == UMIN)
@@ -986,13 +987,6 @@ general_scalar_chain::convert_insn (rtx_insn *insn)
switch (GET_CODE (src))
{
- case ASHIFT:
- case ASHIFTRT:
- case LSHIFTRT:
- convert_op (&XEXP (src, 0), insn);
- PUT_MODE (src, vmode);
- break;
-
case PLUS:
case MINUS:
case IOR:
@@ -1002,8 +996,14 @@ general_scalar_chain::convert_insn (rtx_insn *insn)
case SMIN:
case UMAX:
case UMIN:
- convert_op (&XEXP (src, 0), insn);
convert_op (&XEXP (src, 1), insn);
+ /* FALLTHRU */
+
+ case ABS:
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ convert_op (&XEXP (src, 0), insn);
PUT_MODE (src, vmode);
break;
@@ -1414,6 +1414,12 @@ general_scalar_to_vector_candidate_p (rtx_insn *insn, enum machine_mode mode)
return false;
break;
+ case ABS:
+ if ((mode == DImode && !TARGET_AVX512VL)
+ || (mode == SImode && !TARGET_SSSE3))
+ return false;
+ break;
+
case NEG:
case NOT:
break;
diff --git a/gcc/config/i386/i386-options.c b/gcc/config/i386/i386-options.c
index 4128e93..dc07697 100644
--- a/gcc/config/i386/i386-options.c
+++ b/gcc/config/i386/i386-options.c
@@ -216,7 +216,8 @@ static struct ix86_target_opts isa2_opts[] =
{ "-muintr", OPTION_MASK_ISA2_UINTR },
{ "-mhreset", OPTION_MASK_ISA2_HRESET },
{ "-mkl", OPTION_MASK_ISA2_KL },
- { "-mwidekl", OPTION_MASK_ISA2_WIDEKL }
+ { "-mwidekl", OPTION_MASK_ISA2_WIDEKL },
+ { "-mavxvnni", OPTION_MASK_ISA2_AVXVNNI }
};
static struct ix86_target_opts isa_opts[] =
{
@@ -1047,6 +1048,7 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[],
IX86_ATTR_ISA ("amx-int8", OPT_mamx_int8),
IX86_ATTR_ISA ("amx-bf16", OPT_mamx_bf16),
IX86_ATTR_ISA ("hreset", OPT_mhreset),
+ IX86_ATTR_ISA ("avxvnni", OPT_mavxvnni),
/* enum options */
IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_),
@@ -1207,7 +1209,7 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[],
{
if (!opt_set_p)
{
- error_at (loc, "pragma or attribute %<target(\"%s\")%> "
+ error_at (loc, "pragma or attribute %<target(\"%s\")%> "
"does not allow a negated form", p);
return false;
}
@@ -2075,7 +2077,7 @@ ix86_option_override_internal (bool main_args_p,
&& (!TARGET_64BIT_P (opts->x_ix86_isa_flags)
|| opts->x_ix86_abi != SYSV_ABI))
{
- error (G_("%<%s%> architecture level is only defined"
+ error (G_("%qs architecture level is only defined"
" for the x86-64 psABI"), opts->x_ix86_arch_string);
return false;
}
@@ -2304,6 +2306,10 @@ ix86_option_override_internal (bool main_args_p,
&& !(opts->x_ix86_isa_flags2_explicit
& OPTION_MASK_ISA2_AMX_BF16))
opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_AMX_BF16;
+ if (((processor_alias_table[i].flags & PTA_AVXVNNI) != 0)
+ && !(opts->x_ix86_isa_flags2_explicit
+ & OPTION_MASK_ISA2_AVXVNNI))
+ opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_AVXVNNI;
if (((processor_alias_table[i].flags & PTA_MOVDIRI) != 0)
&& !(opts->x_ix86_isa_flags_explicit & OPTION_MASK_ISA_MOVDIRI))
opts->x_ix86_isa_flags |= OPTION_MASK_ISA_MOVDIRI;
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index b70d598..65347a5 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -163,6 +163,7 @@ extern rtx ix86_find_base_term (rtx);
extern bool ix86_check_movabs (rtx, int);
extern bool ix86_check_no_addr_space (rtx);
extern void ix86_split_idivmod (machine_mode, rtx[], bool);
+extern bool ix86_hardreg_mov_ok (rtx, rtx);
extern rtx assign_386_stack_local (machine_mode, enum ix86_stack_slot);
extern int ix86_attr_length_immediate_default (rtx_insn *, bool);
@@ -244,6 +245,7 @@ extern rtx ix86_rewrite_tls_address (rtx);
extern void ix86_expand_vector_init (bool, rtx, rtx);
extern void ix86_expand_vector_set (bool, rtx, rtx, int);
+extern void ix86_expand_vector_set_var (rtx, rtx, rtx);
extern void ix86_expand_vector_extract (bool, rtx, rtx, int);
extern void ix86_expand_reduc (rtx (*)(rtx, rtx, rtx), rtx, rtx);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 4396f64..6321678 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -18889,6 +18889,22 @@ ix86_class_likely_spilled_p (reg_class_t rclass)
return false;
}
+/* Return true if a set of DST by the expression SRC should be allowed.
+ This prevents complex sets of likely_spilled hard regs before reload. */
+
+bool
+ix86_hardreg_mov_ok (rtx dst, rtx src)
+{
+ /* Avoid complex sets of likely_spilled hard registers before reload. */
+ if (REG_P (dst) && HARD_REGISTER_P (dst)
+ && !REG_P (src) && !MEM_P (src)
+ && !x86_64_immediate_operand (src, GET_MODE (dst))
+ && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dst)))
+ && !reload_completed)
+ return false;
+ return true;
+}
+
/* If we are copying between registers from different register sets
(e.g. FP and integer), we may need a memory location.
@@ -21492,40 +21508,18 @@ ix86_md_asm_adjust (vec<rtx> &outputs, vec<rtx> &/*inputs*/,
continue;
}
- if (dest_mode == DImode && !TARGET_64BIT)
- dest_mode = SImode;
-
- if (dest_mode != QImode)
- {
- rtx destqi = gen_reg_rtx (QImode);
- emit_insn (gen_rtx_SET (destqi, x));
-
- if (TARGET_ZERO_EXTEND_WITH_AND
- && optimize_function_for_speed_p (cfun))
- {
- x = force_reg (dest_mode, const0_rtx);
-
- emit_insn (gen_movstrictqi (gen_lowpart (QImode, x), destqi));
- }
- else
- {
- x = gen_rtx_ZERO_EXTEND (dest_mode, destqi);
- if (dest_mode == GET_MODE (dest)
- && !register_operand (dest, GET_MODE (dest)))
- x = force_reg (dest_mode, x);
- }
- }
-
- if (dest_mode != GET_MODE (dest))
+ if (dest_mode == QImode)
+ emit_insn (gen_rtx_SET (dest, x));
+ else
{
- rtx tmp = gen_reg_rtx (SImode);
+ rtx reg = gen_reg_rtx (QImode);
+ emit_insn (gen_rtx_SET (reg, x));
- emit_insn (gen_rtx_SET (tmp, x));
- emit_insn (gen_zero_extendsidi2 (dest, tmp));
+ reg = convert_to_mode (dest_mode, reg, 1);
+ emit_move_insn (dest, reg);
}
- else
- emit_insn (gen_rtx_SET (dest, x));
}
+
rtx_insn *seq = get_insns ();
end_sequence ();
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 5e01fe6..b8ae16e 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -217,6 +217,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define TARGET_KL_P(x) TARGET_ISA2_KL_P(x)
#define TARGET_WIDEKL TARGET_ISA2_WIDEKL
#define TARGET_WIDEKL_P(x) TARGET_ISA2_WIDEKL_P(x)
+#define TARGET_AVXVNNI TARGET_ISA2_AVXVNNI
+#define TARGET_AVXVNNI_P(x) TARGET_ISA2_AVXVNNI_P(x)
#define TARGET_LP64 TARGET_ABI_64
#define TARGET_LP64_P(x) TARGET_ABI_64_P(x)
@@ -2480,19 +2482,20 @@ const wide_int_bitmask PTA_AVX512VP2INTERSECT (0, HOST_WIDE_INT_1U << 9);
const wide_int_bitmask PTA_PTWRITE (0, HOST_WIDE_INT_1U << 10);
const wide_int_bitmask PTA_AVX512BF16 (0, HOST_WIDE_INT_1U << 11);
const wide_int_bitmask PTA_WAITPKG (0, HOST_WIDE_INT_1U << 12);
-const wide_int_bitmask PTA_MOVDIRI(0, HOST_WIDE_INT_1U << 13);
-const wide_int_bitmask PTA_MOVDIR64B(0, HOST_WIDE_INT_1U << 14);
+const wide_int_bitmask PTA_MOVDIRI (0, HOST_WIDE_INT_1U << 13);
+const wide_int_bitmask PTA_MOVDIR64B (0, HOST_WIDE_INT_1U << 14);
const wide_int_bitmask PTA_ENQCMD (0, HOST_WIDE_INT_1U << 15);
const wide_int_bitmask PTA_CLDEMOTE (0, HOST_WIDE_INT_1U << 16);
const wide_int_bitmask PTA_SERIALIZE (0, HOST_WIDE_INT_1U << 17);
const wide_int_bitmask PTA_TSXLDTRK (0, HOST_WIDE_INT_1U << 18);
-const wide_int_bitmask PTA_AMX_TILE(0, HOST_WIDE_INT_1U << 19);
-const wide_int_bitmask PTA_AMX_INT8(0, HOST_WIDE_INT_1U << 20);
-const wide_int_bitmask PTA_AMX_BF16(0, HOST_WIDE_INT_1U << 21);
+const wide_int_bitmask PTA_AMX_TILE (0, HOST_WIDE_INT_1U << 19);
+const wide_int_bitmask PTA_AMX_INT8 (0, HOST_WIDE_INT_1U << 20);
+const wide_int_bitmask PTA_AMX_BF16 (0, HOST_WIDE_INT_1U << 21);
const wide_int_bitmask PTA_UINTR (0, HOST_WIDE_INT_1U << 22);
-const wide_int_bitmask PTA_HRESET(0, HOST_WIDE_INT_1U << 23);
+const wide_int_bitmask PTA_HRESET (0, HOST_WIDE_INT_1U << 23);
const wide_int_bitmask PTA_KL (0, HOST_WIDE_INT_1U << 24);
const wide_int_bitmask PTA_WIDEKL (0, HOST_WIDE_INT_1U << 25);
+const wide_int_bitmask PTA_AVXVNNI (0, HOST_WIDE_INT_1U << 26);
const wide_int_bitmask PTA_X86_64_BASELINE = PTA_64BIT | PTA_MMX | PTA_SSE
| PTA_SSE2 | PTA_NO_SAHF | PTA_FXSR;
@@ -2515,7 +2518,8 @@ const wide_int_bitmask PTA_IVYBRIDGE = PTA_SANDYBRIDGE | PTA_FSGSBASE
| PTA_RDRND | PTA_F16C;
const wide_int_bitmask PTA_HASWELL = PTA_IVYBRIDGE | PTA_AVX2 | PTA_BMI
| PTA_BMI2 | PTA_LZCNT | PTA_FMA | PTA_MOVBE | PTA_HLE;
-const wide_int_bitmask PTA_BROADWELL = PTA_HASWELL | PTA_ADX | PTA_RDSEED;
+const wide_int_bitmask PTA_BROADWELL = PTA_HASWELL | PTA_ADX | PTA_RDSEED
+ | PTA_PRFCHW;
const wide_int_bitmask PTA_SKYLAKE = PTA_BROADWELL | PTA_AES | PTA_CLFLUSHOPT
| PTA_XSAVEC | PTA_XSAVES | PTA_SGX;
const wide_int_bitmask PTA_SKYLAKE_AVX512 = PTA_SKYLAKE | PTA_AVX512F
@@ -2536,9 +2540,9 @@ const wide_int_bitmask PTA_TIGERLAKE = PTA_ICELAKE_CLIENT | PTA_MOVDIRI
const wide_int_bitmask PTA_SAPPHIRERAPIDS = PTA_COOPERLAKE | PTA_MOVDIRI
| PTA_MOVDIR64B | PTA_AVX512VP2INTERSECT | PTA_ENQCMD | PTA_CLDEMOTE
| PTA_PTWRITE | PTA_WAITPKG | PTA_SERIALIZE | PTA_TSXLDTRK | PTA_AMX_TILE
- | PTA_AMX_INT8 | PTA_AMX_BF16 | PTA_UINTR;
+ | PTA_AMX_INT8 | PTA_AMX_BF16 | PTA_UINTR | PTA_AVXVNNI;
const wide_int_bitmask PTA_ALDERLAKE = PTA_SKYLAKE | PTA_CLDEMOTE | PTA_PTWRITE
- | PTA_WAITPKG | PTA_SERIALIZE | PTA_HRESET | PTA_KL | PTA_WIDEKL;
+ | PTA_WAITPKG | PTA_SERIALIZE | PTA_HRESET | PTA_KL | PTA_WIDEKL | PTA_AVXVNNI;
const wide_int_bitmask PTA_KNL = PTA_BROADWELL | PTA_AVX512PF | PTA_AVX512ER
| PTA_AVX512F | PTA_AVX512CD | PTA_PREFETCHWT1;
const wide_int_bitmask PTA_BONNELL = PTA_CORE2 | PTA_MOVBE;
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 979e49d..76e9499 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -818,7 +818,8 @@
sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
avx512bw,noavx512bw,avx512dq,noavx512dq,
- avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
+ avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw,
+ avxvnni,avx512vnnivl"
(const_string "base"))
;; Define instruction set of MMX instructions
@@ -867,6 +868,8 @@
(eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
(eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
(eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
+ (eq_attr "isa" "avxvnni") (symbol_ref "TARGET_AVXVNNI")
+ (eq_attr "isa" "avx512vnnivl") (symbol_ref "TARGET_AVX512VNNI && TARGET_AVX512VL")
(eq_attr "mmx_isa" "native")
(symbol_ref "!TARGET_MMX_WITH_SSE")
@@ -2086,7 +2089,8 @@
"=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,m,?r ,?*Yd,?r,?*v,?*y,?*x,*k,*k ,*r,*m,*k")
(match_operand:DI 1 "general_operand"
"riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,v,*Yd,r ,*v,r ,*x ,*y ,*r,*km,*k,*k,CBC"))]
- "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ "!(MEM_P (operands[0]) && MEM_P (operands[1]))
+ && ix86_hardreg_mov_ok (operands[0], operands[1])"
{
switch (get_attr_type (insn))
{
@@ -2306,7 +2310,8 @@
"=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm,*k")
(match_operand:SI 1 "general_operand"
"g ,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,*v,r ,*r,*km,*k ,CBC"))]
- "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ "!(MEM_P (operands[0]) && MEM_P (operands[1]))
+ && ix86_hardreg_mov_ok (operands[0], operands[1])"
{
switch (get_attr_type (insn))
{
@@ -2414,7 +2419,9 @@
(define_insn "*movhi_internal"
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,*k,*k ,*r,*m,*k")
(match_operand:HI 1 "general_operand" "r ,rn,rm,rn,*r,*km,*k,*k,CBC"))]
- "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ "!(MEM_P (operands[0]) && MEM_P (operands[1]))
+ && ix86_hardreg_mov_ok (operands[0], operands[1])"
+
{
switch (get_attr_type (insn))
{
@@ -2503,7 +2510,9 @@
"=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
(match_operand:QI 1 "general_operand"
"Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
- "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ "!(MEM_P (operands[0]) && MEM_P (operands[1]))
+ && ix86_hardreg_mov_ok (operands[0], operands[1])"
+
{
char buf[128];
const char *ops;
@@ -5171,7 +5180,7 @@
(define_insn_and_split "*lea<mode>"
[(set (match_operand:SWI48 0 "register_operand" "=r")
(match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
- ""
+ "ix86_hardreg_mov_ok (operands[0], operands[1])"
{
if (SImode_address_operand (operands[1], VOIDmode))
{
@@ -10053,8 +10062,8 @@
"#"
"reload_completed"
[(parallel
- [(set (reg:CCZ FLAGS_REG)
- (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
+ [(set (reg:CCC FLAGS_REG)
+ (ne:CCC (match_dup 1) (const_int 0)))
(set (match_dup 0) (neg:DWIH (match_dup 1)))])
(parallel
[(set (match_dup 2)
@@ -10068,7 +10077,7 @@
(clobber (reg:CC FLAGS_REG))])]
"split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
-(define_insn "*neg<mode>2_1"
+(define_insn "*neg<mode>_1"
[(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
(neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
(clobber (reg:CC FLAGS_REG))]
@@ -10077,7 +10086,7 @@
[(set_attr "type" "negnot")
(set_attr "mode" "<MODE>")])
-(define_insn "*negsi2_1_zext"
+(define_insn "*negsi_1_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
(neg:SI (match_operand:SI 1 "register_operand" "0"))))
@@ -10087,36 +10096,46 @@
[(set_attr "type" "negnot")
(set_attr "mode" "SI")])
-;; The problem with neg is that it does not perform (compare x 0),
-;; it really performs (compare 0 x), which leaves us with the zero
-;; flag being the only useful item.
-
-(define_insn "*neg<mode>2_cmpz"
- [(set (reg:CCZ FLAGS_REG)
- (compare:CCZ
+(define_insn "*neg<mode>_2"
+ [(set (reg FLAGS_REG)
+ (compare
(neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
- (const_int 0)))
+ (const_int 0)))
(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
(neg:SWI (match_dup 1)))]
- "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
+ "ix86_match_ccmode (insn, CCGOCmode)
+ && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
"neg{<imodesuffix>}\t%0"
[(set_attr "type" "negnot")
(set_attr "mode" "<MODE>")])
-(define_insn "*negsi2_cmpz_zext"
- [(set (reg:CCZ FLAGS_REG)
- (compare:CCZ
+(define_insn "*negsi_2_zext"
+ [(set (reg FLAGS_REG)
+ (compare
(neg:SI (match_operand:SI 1 "register_operand" "0"))
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
(neg:SI (match_dup 1))))]
- "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
+ "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
+ && ix86_unary_operator_ok (NEG, SImode, operands)"
"neg{l}\t%k0"
[(set_attr "type" "negnot")
(set_attr "mode" "SI")])
-(define_insn "*neg<mode>_ccc"
+(define_insn "*neg<mode>_ccc_1"
+ [(set (reg:CCC FLAGS_REG)
+ (ne:CCC
+ (match_operand:SWI 1 "nonimmediate_operand" "0")
+ (const_int 0)))
+ (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
+ (neg:SWI (match_dup 1)))]
+ ""
+ "neg{<imodesuffix>}\t%0"
+ [(set_attr "type" "negnot")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "*neg<mode>_ccc_2"
[(set (reg:CCC FLAGS_REG)
(ne:CCC
(match_operand:SWI 1 "nonimmediate_operand" "0")
@@ -10160,27 +10179,105 @@
;; Special expand pattern to handle integer mode abs
(define_expand "abs<mode>2"
- [(set (match_operand:SWI48x 0 "register_operand")
- (abs:SWI48x
- (match_operand:SWI48x 1 "register_operand")))]
- "TARGET_EXPAND_ABS"
- {
- machine_mode mode = <MODE>mode;
-
- /* Generate rtx abs using abs (x) = (((signed) x >> (W-1)) ^ x) -
- ((signed) x >> (W-1)) */
- rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
- rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
- shift_amount, NULL_RTX,
- 0, OPTAB_DIRECT);
- rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
- operands[0], 0, OPTAB_DIRECT);
- rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
- operands[0], 0, OPTAB_DIRECT);
- if (!rtx_equal_p (minus_dst, operands[0]))
- emit_move_insn (operands[0], minus_dst);
- DONE;
- })
+ [(parallel
+ [(set (match_operand:SDWIM 0 "register_operand")
+ (abs:SDWIM
+ (match_operand:SDWIM 1 "general_operand")))
+ (clobber (reg:CC FLAGS_REG))])]
+ "TARGET_CMOVE
+ && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
+{
+ if (TARGET_EXPAND_ABS)
+ {
+ machine_mode mode = <MODE>mode;
+ operands[1] = force_reg (mode, operands[1]);
+
+ /* Generate rtx abs using:
+ abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
+
+ rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
+ rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
+ shift_amount, NULL_RTX,
+ 0, OPTAB_DIRECT);
+ rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
+ operands[0], 0, OPTAB_DIRECT);
+ rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
+ operands[0], 0, OPTAB_DIRECT);
+ if (!rtx_equal_p (minus_dst, operands[0]))
+ emit_move_insn (operands[0], minus_dst);
+ DONE;
+ }
+})
+
+(define_insn_and_split "*abs<dwi>2_doubleword"
+ [(set (match_operand:<DWI> 0 "register_operand")
+ (abs:<DWI>
+ (match_operand:<DWI> 1 "general_operand")))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_CMOVE
+ && ix86_pre_reload_split ()"
+ "#"
+ "&& 1"
+ [(parallel
+ [(set (reg:CCC FLAGS_REG)
+ (ne:CCC (match_dup 1) (const_int 0)))
+ (set (match_dup 2) (neg:DWIH (match_dup 1)))])
+ (parallel
+ [(set (match_dup 5)
+ (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
+ (match_dup 4))
+ (const_int 0)))
+ (clobber (reg:CC FLAGS_REG))])
+ (parallel
+ [(set (reg:CCGOC FLAGS_REG)
+ (compare:CCGOC
+ (neg:DWIH (match_dup 5))
+ (const_int 0)))
+ (set (match_dup 5)
+ (neg:DWIH (match_dup 5)))])
+ (set (match_dup 0)
+ (if_then_else:DWIH
+ (ge (reg:CCGOC FLAGS_REG) (const_int 0))
+ (match_dup 2)
+ (match_dup 1)))
+ (set (match_dup 3)
+ (if_then_else:DWIH
+ (ge (reg:CCGOC FLAGS_REG) (const_int 0))
+ (match_dup 5)
+ (match_dup 4)))]
+{
+ operands[1] = force_reg (<DWI>mode, operands[1]);
+ operands[2] = gen_reg_rtx (<DWI>mode);
+
+ split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
+})
+
+(define_insn_and_split "*abs<mode>2_1"
+ [(set (match_operand:SWI 0 "register_operand")
+ (abs:SWI
+ (match_operand:SWI 1 "general_operand")))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_CMOVE
+ && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
+ && ix86_pre_reload_split ()"
+ "#"
+ "&& 1"
+ [(parallel
+ [(set (reg:CCGOC FLAGS_REG)
+ (compare:CCGOC
+ (neg:SWI (match_dup 1))
+ (const_int 0)))
+ (set (match_dup 2)
+ (neg:SWI (match_dup 1)))])
+ (set (match_dup 0)
+ (if_then_else:SWI
+ (ge (reg:CCGOC FLAGS_REG) (const_int 0))
+ (match_dup 2)
+ (match_dup 1)))]
+{
+ operands[1] = force_reg (<MODE>mode, operands[1]);
+ operands[2] = gen_reg_rtx (<MODE>mode);
+})
(define_expand "<code>tf2"
[(set (match_operand:TF 0 "register_operand")
@@ -10249,7 +10346,7 @@
(absneg:X87MODEF
(match_operand:X87MODEF 1 "register_operand" "0,0")))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_80387"
+ "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
"#")
(define_split
@@ -12619,9 +12716,9 @@
operands[2] = gen_lowpart (QImode, operands[0]);
})
-(define_insn_and_split "*setcc_si_1_and"
- [(set (match_operand:SI 0 "register_operand" "=q")
- (match_operator:SI 1 "ix86_comparison_operator"
+(define_insn_and_split "*setcc_<mode>_1_and"
+ [(set (match_operand:SWI24 0 "register_operand" "=q")
+ (match_operator:SWI24 1 "ix86_comparison_operator"
[(reg FLAGS_REG) (const_int 0)]))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_PARTIAL_REG_STALL
@@ -12629,7 +12726,7 @@
"#"
"&& reload_completed"
[(set (match_dup 2) (match_dup 1))
- (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
+ (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
(clobber (reg:CC FLAGS_REG))])]
{
operands[1] = shallow_copy_rtx (operands[1]);
@@ -12637,16 +12734,16 @@
operands[2] = gen_lowpart (QImode, operands[0]);
})
-(define_insn_and_split "*setcc_si_1_movzbl"
- [(set (match_operand:SI 0 "register_operand" "=q")
- (match_operator:SI 1 "ix86_comparison_operator"
+(define_insn_and_split "*setcc_<mode>_1_movzbl"
+ [(set (match_operand:SWI24 0 "register_operand" "=q")
+ (match_operator:SWI24 1 "ix86_comparison_operator"
[(reg FLAGS_REG) (const_int 0)]))]
"!TARGET_PARTIAL_REG_STALL
&& (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
"#"
"&& reload_completed"
[(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
+ (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
{
operands[1] = shallow_copy_rtx (operands[1]);
PUT_MODE (operands[1], QImode);
@@ -18872,33 +18969,92 @@
(define_expand "<code><mode>3"
[(parallel
- [(set (match_operand:SWI248 0 "register_operand")
- (maxmin:SWI248
- (match_operand:SWI248 1 "register_operand")
- (match_operand:SWI248 2 "general_operand")))
+ [(set (match_operand:SDWIM 0 "register_operand")
+ (maxmin:SDWIM
+ (match_operand:SDWIM 1 "register_operand")
+ (match_operand:SDWIM 2 "general_operand")))
(clobber (reg:CC FLAGS_REG))])]
- "TARGET_CMOVE")
+ "TARGET_CMOVE
+ && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
+
+(define_insn_and_split "*<code><dwi>3_doubleword"
+ [(set (match_operand:<DWI> 0 "register_operand")
+ (maxmin:<DWI>
+ (match_operand:<DWI> 1 "register_operand")
+ (match_operand:<DWI> 2 "general_operand")))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_CMOVE
+ && ix86_pre_reload_split ()"
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (if_then_else:DWIH (match_dup 6)
+ (match_dup 1)
+ (match_dup 2)))
+ (set (match_dup 3)
+ (if_then_else:DWIH (match_dup 6)
+ (match_dup 4)
+ (match_dup 5)))]
+{
+ operands[2] = force_reg (<DWI>mode, operands[2]);
+
+ split_double_mode (<DWI>mode, &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 (<MODE>mode, cmplo[0], cmplo[1]));
+
+ rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
+ emit_insn (sbb_insn (<MODE>mode, 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 ();
+ }
+})
(define_insn_and_split "*<code><mode>3_1"
- [(set (match_operand:SWI248 0 "register_operand")
- (maxmin:SWI248
- (match_operand:SWI248 1 "register_operand")
- (match_operand:SWI248 2 "general_operand")))
+ [(set (match_operand:SWI 0 "register_operand")
+ (maxmin:SWI
+ (match_operand:SWI 1 "register_operand")
+ (match_operand:SWI 2 "general_operand")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_CMOVE
+ && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
&& ix86_pre_reload_split ()"
"#"
"&& 1"
[(set (match_dup 0)
- (if_then_else:SWI248 (match_dup 3)
+ (if_then_else:SWI (match_dup 3)
(match_dup 1)
(match_dup 2)))]
{
machine_mode mode = <MODE>mode;
rtx cmp_op = operands[2];
- if (!register_operand (cmp_op, mode))
- operands[2] = force_reg (mode, cmp_op);
+ operands[2] = force_reg (mode, cmp_op);
enum rtx_code code = <maxmin_rel>;
@@ -18934,64 +19090,6 @@
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 "general_operand")))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT && TARGET_CMOVE
- && ix86_pre_reload_split ()"
- "#"
- "&& 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 ();
- }
-})
-
;; Avoid clearing a register between a flags setting comparison and its use,
;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
(define_peephole2
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 029cacb..87e6021 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -1143,3 +1143,12 @@ Support KL built-in functions and code generation.
mwidekl
Target Report Mask(ISA2_WIDEKL) Var(ix86_isa_flags2) Save
Support WIDEKL built-in functions and code generation.
+
+mavxvnni
+Target Report Mask(ISA2_AVXVNNI) Var(ix86_isa_flags2) Save
+Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, and
+AVXVNNI built-in functions and code generation.
+
+mneeded
+Target Report Var(ix86_needed) Save
+Emit GNU_PROPERTY_X86_ISA_1_NEEDED GNU property.
diff --git a/gcc/config/i386/immintrin.h b/gcc/config/i386/immintrin.h
index 0ce08e5..b787967 100644
--- a/gcc/config/i386/immintrin.h
+++ b/gcc/config/i386/immintrin.h
@@ -42,6 +42,8 @@
#include <avxintrin.h>
+#include <avxvnniintrin.h>
+
#include <avx2intrin.h>
#include <avx512fintrin.h>
diff --git a/gcc/config/i386/linux-common.h b/gcc/config/i386/linux-common.h
index 982390d..da0fabb 100644
--- a/gcc/config/i386/linux-common.h
+++ b/gcc/config/i386/linux-common.h
@@ -65,7 +65,7 @@ along with GCC; see the file COPYING3. If not see
#define MPX_LD_AS_NEEDED_GUARD_POP ""
#endif
-extern void file_end_indicate_exec_stack_and_cet (void);
+extern void file_end_indicate_exec_stack_and_gnu_property (void);
#undef TARGET_ASM_FILE_END
-#define TARGET_ASM_FILE_END file_end_indicate_exec_stack_and_cet
+#define TARGET_ASM_FILE_END file_end_indicate_exec_stack_and_gnu_property
diff --git a/gcc/config/i386/msformat-c.c b/gcc/config/i386/msformat-c.c
index 4ceec63..085ac88 100644
--- a/gcc/config/i386/msformat-c.c
+++ b/gcc/config/i386/msformat-c.c
@@ -32,10 +32,11 @@ along with GCC; see the file COPYING3. If not see
static format_length_info ms_printf_length_specs[] =
{
{ "h", FMT_LEN_h, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 },
- { "l", FMT_LEN_l, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 },
+ { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
+ { "L", FMT_LEN_L, STD_C89, NULL, FMT_LEN_none, STD_C89, 1 },
{ "I32", FMT_LEN_l, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
{ "I64", FMT_LEN_ll, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
- { "I", FMT_LEN_L, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
+ { "I", FMT_LEN_z, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
{ NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }
};
@@ -90,33 +91,35 @@ static const format_flag_pair ms_strftime_flag_pairs[] =
static const format_char_info ms_print_char_table[] =
{
/* C89 conversion specifiers. */
- { "di", 0, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +'", "i", NULL },
- { "oxX", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL },
- { "u", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0'", "i", NULL },
- { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "", NULL },
- { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL },
- { "c", 0, STD_C89, { T89_I, BADLEN, T89_S, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
- { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL },
- { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL },
- { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL },
+ { "di", 0, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +'", "i", NULL },
+ { "oxX", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL },
+ { "u", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0'", "i", NULL },
+ { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "", NULL },
+ { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL },
+ { "c", 0, STD_C89, { T89_I, BADLEN, T89_S, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
+ { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL },
+ { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL },
+ { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL },
+ /* C99 conversion specifiers. */
+ { "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL },
/* X/Open conversion specifiers. */
- { "C", 0, STD_EXT, { TEX_WI, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
- { "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL },
+ { "C", 0, STD_EXT, { TEX_WI, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
+ { "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL },
{ NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
};
static const format_char_info ms_scan_char_table[] =
{
/* C89 conversion specifiers. */
- { "di", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL },
- { "u", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL },
- { "oxX", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
- { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL },
- { "c", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW", NULL },
- { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW", NULL },
- { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[", NULL },
- { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
- { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "W", NULL },
+ { "di", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL },
+ { "u", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL },
+ { "oxX", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
+ { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL },
+ { "c", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW", NULL },
+ { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW", NULL },
+ { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[", NULL },
+ { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
+ { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "W", NULL },
/* X/Open conversion specifiers. */
{ "C", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
{ "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "W", NULL },
@@ -182,9 +185,9 @@ extern void TARGET_OVERRIDES_FORMAT_INIT (void);
void
TARGET_OVERRIDES_FORMAT_INIT (void)
{
- ms_printf_length_specs[2].std = C89_OR_EXT; /* I32 */
- ms_printf_length_specs[3].std = C89_OR_EXT; /* I64 */
- ms_printf_length_specs[4].std = C89_OR_EXT; /* I */
+ ms_printf_length_specs[3].std = C89_OR_EXT; /* I32 */
+ ms_printf_length_specs[4].std = C89_OR_EXT; /* I64 */
+ ms_printf_length_specs[5].std = C89_OR_EXT; /* I */
}
#undef C89_OR_EXT
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 36f9dfc..be5aaa4 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -1023,6 +1023,12 @@
return op == const1_rtx || op == constm1_rtx;
})
+;; True for registers, or const_int_operand, used to vec_setm expander.
+(define_predicate "vec_setm_operand"
+ (ior (and (match_operand 0 "register_operand")
+ (match_test "TARGET_AVX2"))
+ (match_code "const_int")))
+
;; True for registers, or 1 or -1. Used to optimize double-word shifts.
(define_predicate "reg_or_pm1_operand"
(ior (match_operand 0 "register_operand")
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index b153a87..94bb445 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -111,6 +111,8 @@
UNSPEC_MASKOP
UNSPEC_KORTEST
UNSPEC_KTEST
+ ;; Mask load
+ UNSPEC_MASKLOAD
;; For embed. rounding feature
UNSPEC_EMBEDDED_ROUNDING
@@ -466,6 +468,10 @@
[(V4TI "TARGET_AVX512BW") (V2TI "TARGET_AVX2") TI])
(define_mode_iterator VI12_AVX2
+ [(V32QI "TARGET_AVX2") V16QI
+ (V16HI "TARGET_AVX2") V8HI])
+
+(define_mode_iterator VI12_AVX2_AVX512BW
[(V64QI "TARGET_AVX512BW") (V32QI "TARGET_AVX2") V16QI
(V32HI "TARGET_AVX512BW") (V16HI "TARGET_AVX2") V8HI])
@@ -1065,18 +1071,39 @@
]
(symbol_ref "true")))])
-(define_insn "<avx512>_load<mode>_mask"
- [(set (match_operand:V48_AVX512VL 0 "register_operand" "=v,v")
+;; If mem_addr points to a memory region with less than whole vector size bytes
+;; of accessible memory and k is a mask that would prevent reading the inaccessible
+;; bytes from mem_addr, add UNSPEC_MASKLOAD to prevent it to be transformed to vpblendd
+;; See pr97642.
+(define_expand "<avx512>_load<mode>_mask"
+ [(set (match_operand:V48_AVX512VL 0 "register_operand")
(vec_merge:V48_AVX512VL
- (match_operand:V48_AVX512VL 1 "nonimmediate_operand" "vm,vm")
- (match_operand:V48_AVX512VL 2 "nonimm_or_0_operand" "0C,v")
- (match_operand:<avx512fmaskmode> 3 "register_operand" "Yk,Yk")))]
+ (match_operand:V48_AVX512VL 1 "nonimmediate_operand")
+ (match_operand:V48_AVX512VL 2 "nonimm_or_0_operand")
+ (match_operand:<avx512fmaskmode> 3 "register_or_constm1_operand")))]
"TARGET_AVX512F"
{
- if (REG_P (operands[2])
- && REGNO (operands[2]) != REGNO (operands[0]))
- return "v<sseintprefix>blendm<ssemodesuffix>\t{%1, %2, %0%{%3%}|%0%{%3%}, %2, %1}";
+ if (CONST_INT_P (operands[3]))
+ {
+ emit_insn (gen_rtx_SET (operands[0], operands[1]));
+ DONE;
+ }
+ else if (MEM_P (operands[1]))
+ operands[1] = gen_rtx_UNSPEC (<MODE>mode,
+ gen_rtvec(1, operands[1]),
+ UNSPEC_MASKLOAD);
+})
+(define_insn "*<avx512>_load<mode>_mask"
+ [(set (match_operand:V48_AVX512VL 0 "register_operand" "=v")
+ (vec_merge:V48_AVX512VL
+ (unspec:V48_AVX512VL
+ [(match_operand:V48_AVX512VL 1 "memory_operand" "m")]
+ UNSPEC_MASKLOAD)
+ (match_operand:V48_AVX512VL 2 "nonimm_or_0_operand" "0C")
+ (match_operand:<avx512fmaskmode> 3 "register_operand" "Yk")))]
+ "TARGET_AVX512F"
+{
if (FLOAT_MODE_P (GET_MODE_INNER (<MODE>mode)))
{
if (misaligned_operand (operands[1], <MODE>mode))
@@ -1096,20 +1123,60 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "<avx512>_load<mode>_mask"
- [(set (match_operand:VI12_AVX512VL 0 "register_operand" "=v,v")
+(define_insn_and_split "*<avx512>_load<mode>"
+ [(set (match_operand:V48_AVX512VL 0 "register_operand")
+ (unspec:V48_AVX512VL
+ [(match_operand:V48_AVX512VL 1 "memory_operand")]
+ UNSPEC_MASKLOAD))]
+ "TARGET_AVX512F"
+ "#"
+ "&& 1"
+ [(set (match_dup 0) (match_dup 1))])
+
+(define_expand "<avx512>_load<mode>_mask"
+ [(set (match_operand:VI12_AVX512VL 0 "register_operand")
(vec_merge:VI12_AVX512VL
- (match_operand:VI12_AVX512VL 1 "nonimmediate_operand" "vm,vm")
- (match_operand:VI12_AVX512VL 2 "nonimm_or_0_operand" "0C,v")
- (match_operand:<avx512fmaskmode> 3 "register_operand" "Yk,Yk")))]
+ (match_operand:VI12_AVX512VL 1 "nonimmediate_operand")
+ (match_operand:VI12_AVX512VL 2 "nonimm_or_0_operand")
+ (match_operand:<avx512fmaskmode> 3 "register_or_constm1_operand")))]
"TARGET_AVX512BW"
- "@
- vmovdqu<ssescalarsize>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
- vpblendm<ssemodesuffix>\t{%1, %2, %0%{%3%}|%0%{%3%}, %2, %1}"
+{
+ if (CONST_INT_P (operands[3]))
+ {
+ emit_insn (gen_rtx_SET (operands[0], operands[1]));
+ DONE;
+ }
+ else if (MEM_P (operands[1]))
+ operands[1] = gen_rtx_UNSPEC (<MODE>mode,
+ gen_rtvec(1, operands[1]),
+ UNSPEC_MASKLOAD);
+
+})
+
+(define_insn "*<avx512>_load<mode>_mask"
+ [(set (match_operand:VI12_AVX512VL 0 "register_operand" "=v")
+ (vec_merge:VI12_AVX512VL
+ (unspec:VI12_AVX512VL
+ [(match_operand:VI12_AVX512VL 1 "memory_operand" "m")]
+ UNSPEC_MASKLOAD)
+ (match_operand:VI12_AVX512VL 2 "nonimm_or_0_operand" "0C")
+ (match_operand:<avx512fmaskmode> 3 "register_operand" "Yk")))]
+ "TARGET_AVX512BW"
+ "vmovdqu<ssescalarsize>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
[(set_attr "type" "ssemov")
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
+(define_insn_and_split "*<avx512>_load<mode>"
+ [(set (match_operand:VI12_AVX512VL 0 "register_operand" "=v")
+ (unspec:VI12_AVX512VL
+ [(match_operand:VI12_AVX512VL 1 "memory_operand" "m")]
+ UNSPEC_MASKLOAD))]
+ "TARGET_AVX512BW"
+ "#"
+ "&& 1"
+ [(set (match_dup 0) (match_dup 1))])
+
(define_insn "avx512f_mov<ssescalarmodelower>_mask"
[(set (match_operand:VF_128 0 "register_operand" "=v")
(vec_merge:VF_128
@@ -1171,21 +1238,50 @@
(set_attr "memory" "store")
(set_attr "mode" "<MODE>")])
-(define_expand "<avx512>_blendm<mode>"
- [(set (match_operand:V48_AVX512VL 0 "register_operand" "=v")
+(define_insn "<avx512>_blendm<mode>"
+ [(set (match_operand:V48_AVX512VL 0 "register_operand" "=v,v")
(vec_merge:V48_AVX512VL
- (match_operand:V48_AVX512VL 2 "nonimmediate_operand" "vm")
- (match_operand:V48_AVX512VL 1 "register_operand" "v")
- (match_operand:<avx512fmaskmode> 3 "register_operand" "Yk")))]
- "TARGET_AVX512F")
+ (match_operand:V48_AVX512VL 2 "nonimmediate_operand" "vm,vm")
+ (match_operand:V48_AVX512VL 1 "nonimm_or_0_operand" "0C,v")
+ (match_operand:<avx512fmaskmode> 3 "register_operand" "Yk,Yk")))]
+ "TARGET_AVX512F"
+{
+ if (REG_P (operands[1])
+ && REGNO (operands[1]) != REGNO (operands[0]))
+ return "v<sseintprefix>blendm<ssemodesuffix>\t{%2, %1, %0%{%3%}|%0%{%3%}, %1, %2}";
-(define_expand "<avx512>_blendm<mode>"
- [(set (match_operand:VI12_AVX512VL 0 "register_operand" "=v")
+ if (FLOAT_MODE_P (GET_MODE_INNER (<MODE>mode)))
+ {
+ if (misaligned_operand (operands[2], <MODE>mode))
+ return "vmovu<ssemodesuffix>\t{%2, %0%{%3%}%N1|%0%{%3%}%N1, %2}";
+ else
+ return "vmova<ssemodesuffix>\t{%2, %0%{%3%}%N1|%0%{%3%}%N1, %2}";
+ }
+ else
+ {
+ if (misaligned_operand (operands[2], <MODE>mode))
+ return "vmovdqu<ssescalarsize>\t{%2, %0%{%3%}%N1|%0%{%3%}%N1, %2}";
+ else
+ return "vmovdqa<ssescalarsize>\t{%2, %0%{%3%}%N1|%0%{%3%}%N1, %2}";
+ }
+}
+ [(set_attr "type" "ssemov")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "<sseinsnmode>")])
+
+(define_insn "<avx512>_blendm<mode>"
+ [(set (match_operand:VI12_AVX512VL 0 "register_operand" "=v,v")
(vec_merge:VI12_AVX512VL
- (match_operand:VI12_AVX512VL 2 "nonimmediate_operand" "vm")
- (match_operand:VI12_AVX512VL 1 "register_operand" "v")
- (match_operand:<avx512fmaskmode> 3 "register_operand" "Yk")))]
- "TARGET_AVX512BW")
+ (match_operand:VI12_AVX512VL 2 "nonimmediate_operand" "vm,vm")
+ (match_operand:VI12_AVX512VL 1 "nonimm_or_0_operand" "0C,v")
+ (match_operand:<avx512fmaskmode> 3 "register_operand" "Yk,Yk")))]
+ "TARGET_AVX512BW"
+ "@
+ vmovdqu<ssescalarsize>\t{%2, %0%{%3%}%N1|%0%{%3%}%N1, %2}
+ vpblendm<ssemodesuffix>\t{%2, %1, %0%{%3%}|%0%{%3%}, %1, %2}"
+ [(set_attr "type" "ssemov")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "<sseinsnmode>")])
(define_insn "<avx512>_store<mode>_mask"
[(set (match_operand:V48_AVX512VL 0 "memory_operand" "=m")
@@ -3002,6 +3098,44 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
+(define_int_iterator UNSPEC_PCMP_ITER
+ [UNSPEC_PCMP UNSPEC_UNSIGNED_PCMP])
+
+(define_int_attr pcmp_signed_mask
+ [(UNSPEC_PCMP "3") (UNSPEC_UNSIGNED_PCMP "1")])
+
+;; PR96906 - optimize vpsubusw compared to 0 into vpcmpleuw or vpcmpnltuw.
+;; For signed comparison, handle EQ 0: NEQ 4,
+;; for unsigned comparison extra handle LE:2, NLE:6, equivalent to EQ and NEQ.
+
+(define_split
+ [(set (match_operand:<avx512fmaskmode> 0 "register_operand")
+ (unspec:<avx512fmaskmode>
+ [(us_minus:VI12_AVX512VL
+ (match_operand:VI12_AVX512VL 1 "vector_operand")
+ (match_operand:VI12_AVX512VL 2 "vector_operand"))
+ (match_operand:VI12_AVX512VL 3 "const0_operand")
+ (match_operand:SI 4 "const_0_to_7_operand")]
+ UNSPEC_PCMP_ITER))]
+ "TARGET_AVX512BW
+ && ix86_binary_operator_ok (US_MINUS, <MODE>mode, operands)
+ && (INTVAL (operands[4]) & <pcmp_signed_mask>) == 0"
+ [(const_int 0)]
+ {
+ /* LE: 2, NLT: 5, NLE: 6, LT: 1 */
+ int cmp_predicate = 2; /* LE */
+ if (MEM_P (operands[1]))
+ {
+ std::swap (operands[1], operands[2]);
+ cmp_predicate = 5; /* NLT (GE) */
+ }
+ if ((INTVAL (operands[4]) & 4) != 0)
+ cmp_predicate ^= 4; /* Invert the comparison to NLE (GT) or LT. */
+ emit_insn (gen_<avx512>_ucmp<mode>3 (operands[0], operands[1],operands[2],
+ GEN_INT (cmp_predicate)));
+ DONE;
+ })
+
(define_insn "avx512f_vmcmp<mode>3<round_saeonly_name>"
[(set (match_operand:<avx512fmaskmode> 0 "register_operand" "=k")
(and:<avx512fmaskmode>
@@ -8098,11 +8232,14 @@
(define_expand "vec_set<mode>"
[(match_operand:V 0 "register_operand")
(match_operand:<ssescalarmode> 1 "register_operand")
- (match_operand 2 "const_int_operand")]
+ (match_operand 2 "vec_setm_operand")]
"TARGET_SSE"
{
- ix86_expand_vector_set (false, operands[0], operands[1],
- INTVAL (operands[2]));
+ if (CONST_INT_P (operands[2]))
+ ix86_expand_vector_set (false, operands[0], operands[1],
+ INTVAL (operands[2]));
+ else
+ ix86_expand_vector_set_var (operands[0], operands[1], operands[2]);
DONE;
})
@@ -11392,18 +11529,18 @@
(set_attr "mode" "<sseinsnmode>")])
(define_expand "<sse2_avx2>_<plusminus_insn><mode>3<mask_name>"
- [(set (match_operand:VI12_AVX2 0 "register_operand")
- (sat_plusminus:VI12_AVX2
- (match_operand:VI12_AVX2 1 "vector_operand")
- (match_operand:VI12_AVX2 2 "vector_operand")))]
+ [(set (match_operand:VI12_AVX2_AVX512BW 0 "register_operand")
+ (sat_plusminus:VI12_AVX2_AVX512BW
+ (match_operand:VI12_AVX2_AVX512BW 1 "vector_operand")
+ (match_operand:VI12_AVX2_AVX512BW 2 "vector_operand")))]
"TARGET_SSE2 && <mask_mode512bit_condition> && <mask_avx512bw_condition>"
"ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
(define_insn "*<sse2_avx2>_<plusminus_insn><mode>3<mask_name>"
- [(set (match_operand:VI12_AVX2 0 "register_operand" "=x,v")
- (sat_plusminus:VI12_AVX2
- (match_operand:VI12_AVX2 1 "vector_operand" "<comm>0,v")
- (match_operand:VI12_AVX2 2 "vector_operand" "xBm,vm")))]
+ [(set (match_operand:VI12_AVX2_AVX512BW 0 "register_operand" "=x,v")
+ (sat_plusminus:VI12_AVX2_AVX512BW
+ (match_operand:VI12_AVX2_AVX512BW 1 "vector_operand" "<comm>0,v")
+ (match_operand:VI12_AVX2_AVX512BW 2 "vector_operand" "xBm,vm")))]
"TARGET_SSE2 && <mask_mode512bit_condition> && <mask_avx512bw_condition>
&& ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
"@
@@ -11415,6 +11552,23 @@
(set_attr "prefix" "orig,maybe_evex")
(set_attr "mode" "TI")])
+;; PR96906 - optimize psubusw compared to 0 into pminuw compared to op0.
+(define_split
+ [(set (match_operand:VI12_AVX2 0 "register_operand")
+ (eq:VI12_AVX2
+ (us_minus:VI12_AVX2
+ (match_operand:VI12_AVX2 1 "vector_operand")
+ (match_operand:VI12_AVX2 2 "vector_operand"))
+ (match_operand:VI12_AVX2 3 "const0_operand")))]
+ "TARGET_SSE2
+ && (<MODE>mode != V8HImode || TARGET_SSE4_1)
+ && ix86_binary_operator_ok (US_MINUS, <MODE>mode, operands)"
+ [(set (match_dup 4)
+ (umin:VI12_AVX2 (match_dup 1) (match_dup 2)))
+ (set (match_dup 0)
+ (eq:VI12_AVX2 (match_dup 4) (match_dup 1)))]
+ "operands[4] = gen_reg_rtx (<MODE>mode);")
+
(define_expand "mulv8qi3"
[(set (match_operand:V8QI 0 "register_operand")
(mult:V8QI (match_operand:V8QI 1 "register_operand")
@@ -12019,15 +12173,15 @@
})
(define_expand "uavg<mode>3_ceil"
- [(set (match_operand:VI12_AVX2 0 "register_operand")
- (truncate:VI12_AVX2
+ [(set (match_operand:VI12_AVX2_AVX512BW 0 "register_operand")
+ (truncate:VI12_AVX2_AVX512BW
(lshiftrt:<ssedoublemode>
(plus:<ssedoublemode>
(plus:<ssedoublemode>
(zero_extend:<ssedoublemode>
- (match_operand:VI12_AVX2 1 "vector_operand"))
+ (match_operand:VI12_AVX2_AVX512BW 1 "vector_operand"))
(zero_extend:<ssedoublemode>
- (match_operand:VI12_AVX2 2 "vector_operand")))
+ (match_operand:VI12_AVX2_AVX512BW 2 "vector_operand")))
(match_dup 3))
(const_int 1))))]
"TARGET_SSE2"
@@ -15741,15 +15895,15 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define_expand "<sse2_avx2>_uavg<mode>3<mask_name>"
- [(set (match_operand:VI12_AVX2 0 "register_operand")
- (truncate:VI12_AVX2
+ [(set (match_operand:VI12_AVX2_AVX512BW 0 "register_operand")
+ (truncate:VI12_AVX2_AVX512BW
(lshiftrt:<ssedoublemode>
(plus:<ssedoublemode>
(plus:<ssedoublemode>
(zero_extend:<ssedoublemode>
- (match_operand:VI12_AVX2 1 "vector_operand"))
+ (match_operand:VI12_AVX2_AVX512BW 1 "vector_operand"))
(zero_extend:<ssedoublemode>
- (match_operand:VI12_AVX2 2 "vector_operand")))
+ (match_operand:VI12_AVX2_AVX512BW 2 "vector_operand")))
(match_dup <mask_expand_op3>))
(const_int 1))))]
"TARGET_SSE2 && <mask_mode512bit_condition> && <mask_avx512bw_condition>"
@@ -15759,15 +15913,15 @@
})
(define_insn "*<sse2_avx2>_uavg<mode>3<mask_name>"
- [(set (match_operand:VI12_AVX2 0 "register_operand" "=x,v")
- (truncate:VI12_AVX2
+ [(set (match_operand:VI12_AVX2_AVX512BW 0 "register_operand" "=x,v")
+ (truncate:VI12_AVX2_AVX512BW
(lshiftrt:<ssedoublemode>
(plus:<ssedoublemode>
(plus:<ssedoublemode>
(zero_extend:<ssedoublemode>
- (match_operand:VI12_AVX2 1 "vector_operand" "%0,v"))
+ (match_operand:VI12_AVX2_AVX512BW 1 "vector_operand" "%0,v"))
(zero_extend:<ssedoublemode>
- (match_operand:VI12_AVX2 2 "vector_operand" "xBm,vm")))
+ (match_operand:VI12_AVX2_AVX512BW 2 "vector_operand" "xBm,vm")))
(match_operand:<ssedoublemode> <mask_expand_op3> "const1_operand"))
(const_int 1))))]
"TARGET_SSE2 && <mask_mode512bit_condition> && <mask_avx512bw_condition>
@@ -22678,6 +22832,12 @@
(set_attr ("prefix") ("evex"))
(set_attr ("mode") ("TI"))])
+(define_expand "popcount<mode>2"
+ [(set (match_operand:VI48_AVX512VL 0 "register_operand")
+ (popcount:VI48_AVX512VL
+ (match_operand:VI48_AVX512VL 1 "nonimmediate_operand")))]
+ "TARGET_AVX512VPOPCNTDQ")
+
(define_insn "vpopcount<mode><mask_name>"
[(set (match_operand:VI48_AVX512VL 0 "register_operand" "=v")
(popcount:VI48_AVX512VL
@@ -22722,6 +22882,12 @@
"TARGET_SSE && TARGET_64BIT"
"jmp\t%P1")
+(define_expand "popcount<mode>2"
+ [(set (match_operand:VI12_AVX512VL 0 "register_operand" "=v")
+ (popcount:VI12_AVX512VL
+ (match_operand:VI12_AVX512VL 1 "nonimmediate_operand" "vm")))]
+ "TARGET_AVX512BITALG")
+
(define_insn "vpopcount<mode><mask_name>"
[(set (match_operand:VI12_AVX512VL 0 "register_operand" "=v")
(popcount:VI12_AVX512VL
@@ -22915,16 +23081,30 @@
[(set_attr ("prefix") ("evex"))
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "vpdpbusd_<mode>"
- [(set (match_operand:VI4_AVX512VL 0 "register_operand" "=v")
- (unspec:VI4_AVX512VL
- [(match_operand:VI4_AVX512VL 1 "register_operand" "0")
- (match_operand:VI4_AVX512VL 2 "register_operand" "v")
- (match_operand:VI4_AVX512VL 3 "nonimmediate_operand" "vm")]
+(define_insn "vpdpbusd_v16si"
+ [(set (match_operand:V16SI 0 "register_operand" "=v")
+ (unspec:V16SI
+ [(match_operand:V16SI 1 "register_operand" "0")
+ (match_operand:V16SI 2 "register_operand" "v")
+ (match_operand:V16SI 3 "nonimmediate_operand" "vm")]
UNSPEC_VPMADDUBSWACCD))]
"TARGET_AVX512VNNI"
- "vpdpbusd\t{%3, %2, %0|%0, %2, %3 }"
- [(set_attr ("prefix") ("evex"))])
+ "vpdpbusd\t{%3, %2, %0|%0, %2, %3}"
+ [(set_attr ("prefix") ("evex"))])
+
+(define_insn "vpdpbusd_<mode>"
+ [(set (match_operand:VI4_AVX2 0 "register_operand" "=x,v")
+ (unspec:VI4_AVX2
+ [(match_operand:VI4_AVX2 1 "register_operand" "0,0")
+ (match_operand:VI4_AVX2 2 "register_operand" "x,v")
+ (match_operand:VI4_AVX2 3 "nonimmediate_operand" "xm,vm")]
+ UNSPEC_VPMADDUBSWACCD))]
+ "TARGET_AVXVNNI || (TARGET_AVX512VNNI && TARGET_AVX512VL)"
+ "@
+ %{vex%} vpdpbusd\t{%3, %2, %0|%0, %2, %3}
+ vpdpbusd\t{%3, %2, %0|%0, %2, %3}"
+ [(set_attr ("prefix") ("vex,evex"))
+ (set_attr ("isa") ("avxvnni,avx512vnnivl"))])
(define_insn "vpdpbusd_<mode>_mask"
[(set (match_operand:VI4_AVX512VL 0 "register_operand" "=v")
@@ -22969,17 +23149,30 @@
"vpdpbusd\t{%3, %2, %0%{%5%}%{z%}|%0%{%5%}%{z%}, %2, %3 }"
[(set_attr ("prefix") ("evex"))])
+(define_insn "vpdpbusds_v16si"
+ [(set (match_operand:V16SI 0 "register_operand" "=v")
+ (unspec:V16SI
+ [(match_operand:V16SI 1 "register_operand" "0")
+ (match_operand:V16SI 2 "register_operand" "v")
+ (match_operand:V16SI 3 "nonimmediate_operand" "vm")]
+ UNSPEC_VPMADDUBSWACCSSD))]
+ "TARGET_AVX512VNNI"
+ "vpdpbusds\t{%3, %2, %0|%0, %2, %3}"
+ [(set_attr ("prefix") ("evex"))])
(define_insn "vpdpbusds_<mode>"
- [(set (match_operand:VI4_AVX512VL 0 "register_operand" "=v")
- (unspec:VI4_AVX512VL
- [(match_operand:VI4_AVX512VL 1 "register_operand" "0")
- (match_operand:VI4_AVX512VL 2 "register_operand" "v")
- (match_operand:VI4_AVX512VL 3 "nonimmediate_operand" "vm")]
+ [(set (match_operand:VI4_AVX2 0 "register_operand" "=x,v")
+ (unspec:VI4_AVX2
+ [(match_operand:VI4_AVX2 1 "register_operand" "0,0")
+ (match_operand:VI4_AVX2 2 "register_operand" "x,v")
+ (match_operand:VI4_AVX2 3 "nonimmediate_operand" "xm,vm")]
UNSPEC_VPMADDUBSWACCSSD))]
- "TARGET_AVX512VNNI"
- "vpdpbusds\t{%3, %2, %0|%0, %2, %3 }"
- [(set_attr ("prefix") ("evex"))])
+ "TARGET_AVXVNNI || (TARGET_AVX512VNNI && TARGET_AVX512VL)"
+ "@
+ %{vex%} vpdpbusds\t{%3, %2, %0|%0, %2, %3}
+ vpdpbusds\t{%3, %2, %0|%0, %2, %3}"
+ [(set_attr ("prefix") ("vex,evex"))
+ (set_attr ("isa") ("avxvnni,avx512vnnivl"))])
(define_insn "vpdpbusds_<mode>_mask"
[(set (match_operand:VI4_AVX512VL 0 "register_operand" "=v")
@@ -23024,17 +23217,30 @@
"vpdpbusds\t{%3, %2, %0%{%5%}%{z%}|%0%{%5%}%{z%}, %2, %3 }"
[(set_attr ("prefix") ("evex"))])
+(define_insn "vpdpwssd_v16si"
+ [(set (match_operand:V16SI 0 "register_operand" "=v")
+ (unspec:V16SI
+ [(match_operand:V16SI 1 "register_operand" "0")
+ (match_operand:V16SI 2 "register_operand" "v")
+ (match_operand:V16SI 3 "nonimmediate_operand" "vm")]
+ UNSPEC_VPMADDWDACCD))]
+ "TARGET_AVX512VNNI"
+ "vpdpwssd\t{%3, %2, %0|%0, %2, %3}"
+ [(set_attr ("prefix") ("evex"))])
(define_insn "vpdpwssd_<mode>"
- [(set (match_operand:VI4_AVX512VL 0 "register_operand" "=v")
- (unspec:VI4_AVX512VL
- [(match_operand:VI4_AVX512VL 1 "register_operand" "0")
- (match_operand:VI4_AVX512VL 2 "register_operand" "v")
- (match_operand:VI4_AVX512VL 3 "nonimmediate_operand" "vm")]
+ [(set (match_operand:VI4_AVX2 0 "register_operand" "=x,v")
+ (unspec:VI4_AVX2
+ [(match_operand:VI4_AVX2 1 "register_operand" "0,0")
+ (match_operand:VI4_AVX2 2 "register_operand" "x,v")
+ (match_operand:VI4_AVX2 3 "nonimmediate_operand" "xm,vm")]
UNSPEC_VPMADDWDACCD))]
- "TARGET_AVX512VNNI"
- "vpdpwssd\t{%3, %2, %0|%0, %2, %3 }"
- [(set_attr ("prefix") ("evex"))])
+ "TARGET_AVXVNNI || (TARGET_AVX512VNNI && TARGET_AVX512VL)"
+ "@
+ %{vex%} vpdpwssd\t{%3, %2, %0|%0, %2, %3}
+ vpdpwssd\t{%3, %2, %0|%0, %2, %3}"
+ [(set_attr ("prefix") ("vex,evex"))
+ (set_attr ("isa") ("avxvnni,avx512vnnivl"))])
(define_insn "vpdpwssd_<mode>_mask"
[(set (match_operand:VI4_AVX512VL 0 "register_operand" "=v")
@@ -23079,17 +23285,30 @@
"vpdpwssd\t{%3, %2, %0%{%5%}%{z%}|%0%{%5%}%{z%}, %2, %3 }"
[(set_attr ("prefix") ("evex"))])
+(define_insn "vpdpwssds_v16si"
+ [(set (match_operand:V16SI 0 "register_operand" "=v")
+ (unspec:V16SI
+ [(match_operand:V16SI 1 "register_operand" "0")
+ (match_operand:V16SI 2 "register_operand" "v")
+ (match_operand:V16SI 3 "nonimmediate_operand" "vm")]
+ UNSPEC_VPMADDWDACCSSD))]
+ "TARGET_AVX512VNNI"
+ "vpdpwssds\t{%3, %2, %0|%0, %2, %3}"
+ [(set_attr ("prefix") ("evex"))])
(define_insn "vpdpwssds_<mode>"
- [(set (match_operand:VI4_AVX512VL 0 "register_operand" "=v")
- (unspec:VI4_AVX512VL
- [(match_operand:VI4_AVX512VL 1 "register_operand" "0")
- (match_operand:VI4_AVX512VL 2 "register_operand" "v")
- (match_operand:VI4_AVX512VL 3 "nonimmediate_operand" "vm")]
+ [(set (match_operand:VI4_AVX2 0 "register_operand" "=x,v")
+ (unspec:VI4_AVX2
+ [(match_operand:VI4_AVX2 1 "register_operand" "0,0")
+ (match_operand:VI4_AVX2 2 "register_operand" "x,v")
+ (match_operand:VI4_AVX2 3 "nonimmediate_operand" "xm,vm")]
UNSPEC_VPMADDWDACCSSD))]
- "TARGET_AVX512VNNI"
- "vpdpwssds\t{%3, %2, %0|%0, %2, %3 }"
- [(set_attr ("prefix") ("evex"))])
+ "TARGET_AVXVNNI || (TARGET_AVX512VNNI && TARGET_AVX512VL)"
+ "@
+ %{vex%} vpdpwssds\t{%3, %2, %0|%0, %2, %3}
+ vpdpwssds\t{%3, %2, %0|%0, %2, %3}"
+ [(set_attr ("prefix") ("vex,evex"))
+ (set_attr ("isa") ("avxvnni,avx512vnnivl"))])
(define_insn "vpdpwssds_<mode>_mask"
[(set (match_operand:VI4_AVX512VL 0 "register_operand" "=v")
diff --git a/gcc/config/i386/t-cet b/gcc/config/i386/t-gnu-property
index d685d31..fd8bbce 100644
--- a/gcc/config/i386/t-cet
+++ b/gcc/config/i386/t-gnu-property
@@ -16,6 +16,6 @@
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
-cet.o: $(srcdir)/config/i386/cet.c
+gnu-property.o: $(srcdir)/config/i386/gnu-property.c
$(COMPILE) $<
$(POSTCOMPILE)
diff --git a/gcc/config/m68k/linux.h b/gcc/config/m68k/linux.h
index 0d18e5a..a01647c 100644
--- a/gcc/config/m68k/linux.h
+++ b/gcc/config/m68k/linux.h
@@ -194,10 +194,10 @@ along with GCC; see the file COPYING3. If not see
#undef FINALIZE_TRAMPOLINE
#define FINALIZE_TRAMPOLINE(TRAMP) \
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"), \
- LCT_NORMAL, VOIDmode, TRAMP, Pmode, \
- plus_constant (Pmode, TRAMP, TRAMPOLINE_SIZE), \
- Pmode);
+ maybe_emit_call_builtin___clear_cache ((TRAMP), \
+ plus_constant (Pmode, \
+ (TRAMP), \
+ TRAMPOLINE_SIZE))
/* Clear the instruction cache from `beg' to `end'. This makes an
inline system call to SYS_cacheflush. The arguments are as
diff --git a/gcc/config/mcore/t-mcore b/gcc/config/mcore/t-mcore
index 0c8763a..638a2e0 100644
--- a/gcc/config/mcore/t-mcore
+++ b/gcc/config/mcore/t-mcore
@@ -23,7 +23,7 @@
# MULTILIB_DIRNAMES = align8 align4
# MULTILIB_MATCHES =
# MULTILIB_EXTRA_OPTS =
-# MULTILIB_EXCEPTIONS =
+MULTILIB_EXCEPTIONS = mlittle-endian/m210
MULTILIB_OPTIONS = mbig-endian/mlittle-endian m210/m340
MULTILIB_DIRNAMES = big little m210 m340
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 513fc5f..58e474e 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -9315,10 +9315,10 @@ mips_select_rtx_section (machine_mode mode, rtx x,
default_function_rodata_section. */
static section *
-mips_function_rodata_section (tree decl)
+mips_function_rodata_section (tree decl, bool)
{
if (!TARGET_ABICALLS || TARGET_ABSOLUTE_ABICALLS || TARGET_GPWORD)
- return default_function_rodata_section (decl);
+ return default_function_rodata_section (decl, false);
if (decl && DECL_SECTION_NAME (decl))
{
diff --git a/gcc/config/msp430/msp430-protos.h b/gcc/config/msp430/msp430-protos.h
index 0b4d9a4..33ad1ad 100644
--- a/gcc/config/msp430/msp430-protos.h
+++ b/gcc/config/msp430/msp430-protos.h
@@ -26,7 +26,7 @@ void msp430_expand_eh_return (rtx);
void msp430_expand_epilogue (int);
void msp430_expand_helper (rtx *operands, const char *, bool);
void msp430_expand_prologue (void);
-const char * msp430x_extendhisi (rtx *);
+int msp430x_extendhisi (rtx *, bool);
void msp430_fixup_compare_operands (machine_mode, rtx *);
int msp430_hard_regno_nregs_has_padding (int, machine_mode);
int msp430_hard_regno_nregs_with_padding (int, machine_mode);
@@ -49,10 +49,11 @@ rtx msp430_subreg (machine_mode, rtx, machine_mode, int);
bool msp430_use_f5_series_hwmult (void);
bool msp430_has_hwmult (void);
bool msp430_op_not_in_high_mem (rtx op);
+bool msp430x_insn_required (rtx op);
#ifdef RTX_CODE
int msp430_expand_shift (enum rtx_code code, machine_mode mode, rtx *operands);
-const char * msp430_output_asm_shift_insns (enum rtx_code code, machine_mode mode, rtx *operands);
+int msp430_output_asm_shift_insns (enum rtx_code code, machine_mode mode, rtx *operands, bool);
#endif
#endif /* GCC_MSP430_PROTOS_H */
diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c
index de4b16b..db3a9ff 100644
--- a/gcc/config/msp430/msp430.c
+++ b/gcc/config/msp430/msp430.c
@@ -49,13 +49,18 @@
#include "msp430-devices.h"
#include "incpath.h"
#include "prefix.h"
+#include "insn-config.h"
+#include "insn-attr.h"
+#include "recog.h"
/* This file should be included last. */
#include "target-def.h"
static void msp430_compute_frame_info (void);
-static bool use_32bit_hwmult (void);
+static bool msp430_use_16bit_hwmult (void);
+static bool msp430_use_32bit_hwmult (void);
+static bool use_helper_for_const_shift (machine_mode mode, HOST_WIDE_INT amt);
@@ -1031,30 +1036,635 @@ msp430_legitimate_constant (machine_mode mode, rtx x)
}
-#undef TARGET_RTX_COSTS
-#define TARGET_RTX_COSTS msp430_rtx_costs
+/* Describing Relative Costs of Operations
+ To model the cost of an instruction, use the number of cycles when
+ optimizing for speed, and the number of words when optimizing for size.
+ The cheapest instruction will execute in one cycle and cost one word.
+ The cycle and size costs correspond to 430 ISA instructions, not 430X
+ instructions or 430X "address" instructions. The relative costs of 430X
+ instructions is accurately modeled with the 430 costs. The relative costs
+ of some "address" instructions can differ, but these are not yet handled.
+ Adding support for this could improve performance/code size. */
+
+struct single_op_cost
+{
+ const int reg;
+ /* Indirect register (@Rn) or indirect autoincrement (@Rn+). */
+ const int ind;
+ const int mem;
+};
+
+static const struct single_op_cost cycle_cost_single_op =
+{
+ 1, 3, 4
+};
+
+static const struct single_op_cost size_cost_single_op =
+{
+ 1, 1, 2
+};
+
+/* When the destination of an insn is memory, the cost is always the same
+ regardless of whether that memory is accessed using indirect register,
+ indexed or absolute addressing.
+ When the source operand is memory, indirect register and post-increment have
+ the same cost, which is lower than indexed and absolute, which also have
+ the same cost. */
+struct double_op_cost
+{
+ /* Source operand is a register. */
+ const int r2r;
+ const int r2pc;
+ const int r2m;
+
+ /* Source operand is memory, using indirect register (@Rn) or indirect
+ autoincrement (@Rn+) addressing modes. */
+ const int ind2r;
+ const int ind2pc;
+ const int ind2m;
+
+ /* Source operand is an immediate. */
+ const int imm2r;
+ const int imm2pc;
+ const int imm2m;
+
+ /* Source operand is memory, using indexed (x(Rn)) or absolute (&ADDR)
+ addressing modes. */
+ const int mem2r;
+ const int mem2pc;
+ const int mem2m;
+};
+
+/* These structures describe the cost of MOV, BIT and CMP instructions, in terms
+ of clock cycles or words. */
+static const struct double_op_cost cycle_cost_double_op_mov =
+{
+ 1, 3, 3,
+ 2, 4, 4,
+ 2, 3, 4,
+ 3, 5, 5
+};
+
+/* Cycle count when memory is the destination operand is one larger than above
+ for instructions that aren't MOV, BIT or CMP. */
+static const struct double_op_cost cycle_cost_double_op =
+{
+ 1, 3, 4,
+ 2, 4, 5,
+ 2, 3, 5,
+ 3, 5, 6
+};
+
+static const struct double_op_cost size_cost_double_op =
+{
+ 1, 1, 2,
+ 1, 1, 2,
+ 2, 2, 3,
+ 2, 2, 3
+};
+
+struct msp430_multlib_costs
+{
+ const int mulhi;
+ const int mulsi;
+ const int muldi;
+};
+
+/* There is no precise size cost when using libcalls, instead it is disparaged
+ relative to other instructions.
+ The cycle costs are from the CALL to the RET, inclusive.
+ FIXME muldi cost is not accurate. */
+static const struct msp430_multlib_costs cycle_cost_multlib_32bit =
+{
+ 27, 33, 66
+};
+
+/* 32bit multiply takes a few more instructions on 16bit hwmult. */
+static const struct msp430_multlib_costs cycle_cost_multlib_16bit =
+{
+ 27, 42, 66
+};
+
+/* TARGET_REGISTER_MOVE_COST
+ There is only one class of general-purpose, non-fixed registers, and the
+ relative cost of moving data between them is always the same.
+ Therefore, the default of 2 is optimal. */
+
+#undef TARGET_MEMORY_MOVE_COST
+#define TARGET_MEMORY_MOVE_COST msp430_memory_move_cost
+
+/* Return the cost of moving data between registers and memory.
+ The returned cost must be relative to the default TARGET_REGISTER_MOVE_COST
+ of 2.
+ IN is false if the value is to be written to memory. */
+static int
+msp430_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
+ reg_class_t rclass ATTRIBUTE_UNUSED,
+ bool in)
+{
+ int cost;
+ const struct double_op_cost *cost_p;
+ /* Optimize with a code size focus by default, unless -O2 or above is
+ specified. */
+ bool speed = (!optimize_size && optimize >= 2);
+
+ cost_p = (speed ? &cycle_cost_double_op_mov : &size_cost_double_op);
+
+ if (in)
+ /* Reading from memory using indirect addressing is assumed to be the more
+ common case. */
+ cost = cost_p->ind2r;
+ else
+ cost = cost_p->r2m;
+
+ /* All register to register moves cost 1 cycle or 1 word, so multiply by 2
+ to get the costs relative to TARGET_REGISTER_MOVE_COST of 2. */
+ return 2 * cost;
+}
+
+/* For X, which must be a MEM RTX, return TRUE if it is an indirect memory
+ reference, @Rn or @Rn+. */
+static bool
+msp430_is_mem_indirect (rtx x)
+{
+ gcc_assert (GET_CODE (x) == MEM);
+ rtx op0 = XEXP (x, 0);
+ return (GET_CODE (op0) == REG || GET_CODE (op0) == POST_INC);
+}
+
+/* Costs of MSP430 instructions are generally based on the addressing mode
+ combination of the source and destination operands.
+ Given source operand SRC (which may be NULL to indicate a single-operand
+ instruction) and destination operand DST return the cost of this
+ expression. */
+static int
+msp430_costs (rtx src, rtx dst, bool speed, rtx outer_rtx)
+{
+ enum rtx_code src_code = GET_CODE (src);
+ enum rtx_code dst_code = GET_CODE (dst);
+ enum rtx_code outer_code = GET_CODE (outer_rtx);
+ machine_mode outer_mode = GET_MODE (outer_rtx);
+ const struct double_op_cost *cost_p;
+ cost_p = (speed ? &cycle_cost_double_op : &size_cost_double_op);
+
+ if (outer_code == TRUNCATE
+ && (outer_mode == QImode
+ || outer_mode == HImode
+ || outer_mode == PSImode))
+ /* Truncation to these modes is normally free as a side effect of the
+ instructions themselves. */
+ return 0;
+
+ if (dst_code == SYMBOL_REF
+ || dst_code == LABEL_REF
+ || dst_code == CONST_INT)
+ /* Catch RTX like (minus (const_int 0) (reg)) but don't add any cost. */
+ return 0;
+
+ switch (src_code)
+ {
+ case REG:
+ return (dst_code == REG ? cost_p->r2r
+ : (dst_code == PC ? cost_p->r2pc : cost_p->r2m));
+
+ case CONST_INT:
+ case SYMBOL_REF:
+ case LABEL_REF:
+ case CONST:
+ return (dst_code == REG ? cost_p->imm2r
+ : (dst_code == PC ? cost_p->imm2pc : cost_p->imm2m));
+
+
+ case MEM:
+ if (msp430_is_mem_indirect (src))
+ return (dst_code == REG ? cost_p->ind2r : (dst_code == PC
+ ? cost_p->ind2pc
+ : cost_p->ind2m));
+ else
+ return (dst_code == REG ? cost_p->mem2r : (dst_code == PC
+ ? cost_p->mem2pc
+ : cost_p->mem2m));
+ default:
+ return cost_p->mem2m;
+ }
+}
+
+/* Given source operand SRC and destination operand DST from the shift or
+ rotate RTX OUTER_RTX, return the cost of performing that shift, assuming
+ optimization for speed when SPEED is true. */
+static int
+msp430_shift_costs (rtx src, rtx dst, bool speed, rtx outer_rtx)
+{
+ int amt;
+ enum rtx_code src_code = GET_CODE (src);
+ enum rtx_code dst_code = GET_CODE (dst);
+ const struct single_op_cost *cost_p;
+
+ cost_p = (speed ? &cycle_cost_single_op : &size_cost_single_op);
+
+ if (src_code != CONST_INT)
+ /* The size or speed cost when the shift amount is unknown cannot be
+ accurately calculated, so just disparage it slightly. */
+ return 2 * msp430_costs (src, dst, speed, outer_rtx);
+
+ if (use_helper_for_const_shift (GET_MODE (outer_rtx), amt = INTVAL (src)))
+ {
+ /* GCC sometimes tries to perform shifts in some very inventive ways,
+ resulting in much larger code size usage than necessary, if
+ they are disparaged too much here. So in general, if
+ use_helper_for_const_shift thinks a helper should be used, obey
+ that and don't disparage the shift any more than a regular
+ instruction, even though the shift may actually cost more.
+ This ensures that the RTL generated at the initial expand pass has the
+ expected shift instructions, which can be mapped to the helper
+ functions. */
+ return msp430_costs (src, dst, speed, outer_rtx);
+ }
+
+ if (!msp430x)
+ {
+ /* Each shift by one place will be emitted individually. */
+ switch (dst_code)
+ {
+ case REG:
+ case CONST_INT:
+ return amt * cost_p->reg;
+ case MEM:
+ if (msp430_is_mem_indirect (dst))
+ return amt * cost_p->ind;
+ else
+ return amt * cost_p->mem;
+ default:
+ return amt * cost_p->mem;
+ }
+ }
+
+ /* RRAM, RRCM, RRUM, RLAM are used for shift counts <= 4, otherwise, the 'X'
+ versions are used.
+ Instructions which shift a MEM operand will never actually be output. It
+ will always be copied into a register to allow for efficient shifting. So
+ the cost just takes into account the cost of an additional copy in that
+ case. */
+ return (amt <= 4 ? (speed ? amt : 1) : (speed ? amt + 1 : 2)
+ + (dst_code == REG ? 0
+ : msp430_costs (dst, gen_rtx_REG (HImode, 10), speed, outer_rtx)));
+}
-static bool msp430_rtx_costs (rtx x ATTRIBUTE_UNUSED,
- machine_mode mode,
- int outer_code ATTRIBUTE_UNUSED,
- int opno ATTRIBUTE_UNUSED,
- int * total,
- bool speed ATTRIBUTE_UNUSED)
+/* Given source operand SRC and destination operand DST from the MULT/DIV/MOD
+ RTX OUTER_RTX, return the cost of performing that operation, assuming
+ optimization for speed when SPEED is true. */
+static int
+msp430_muldiv_costs (rtx src, rtx dst, bool speed, rtx outer_rtx,
+ machine_mode outer_mode)
{
- int code = GET_CODE (x);
+ enum rtx_code outer_code = GET_CODE (outer_rtx);
+ const struct msp430_multlib_costs *cost_p;
+ cost_p = (msp430_use_16bit_hwmult ()
+ ? &cycle_cost_multlib_32bit
+ : &cycle_cost_multlib_16bit);
+
+ int factor = 1;
+ /* Only used in some calculations. */
+ int mode_factor = 1;
+ if (outer_mode == SImode)
+ mode_factor = 2;
+ else if (outer_mode == PSImode)
+ /* PSImode multiplication is performed using SImode operands, so has extra
+ cost to factor in the conversions necessary before/after the
+ operation. */
+ mode_factor = 3;
+ else if (outer_mode == DImode)
+ mode_factor = 4;
+
+ if (!speed)
+ {
+ /* The codesize cost of using a helper function to perform the
+ multiplication or division cannot be accurately calculated, since the
+ cost depends on how many times the operation is performed in the
+ entire program. */
+ if (outer_code != MULT)
+ /* Division is always expensive. */
+ factor = 7;
+ else if (((msp430_use_16bit_hwmult () && outer_mode != DImode)
+ || msp430_use_32bit_hwmult ()
+ || msp430_use_f5_series_hwmult ()))
+ /* When the hardware multiplier is available, only disparage
+ slightly. */
+ factor = 2;
+ else
+ factor = 5;
+ return factor * mode_factor * msp430_costs (src, dst, speed, outer_rtx);
+ }
+ /* When there is hardware multiply support, there is a relatively low, fixed
+ cycle cost to performing any multiplication, but when there is no hardware
+ multiply support it is very costly. That precise cycle cost has not been
+ calculated here.
+ Division is extra slow since it always uses a software library.
+ The 16-bit hardware multiply library cannot be used to produce 64-bit
+ results. */
+ if (outer_code != MULT || !msp430_has_hwmult ()
+ || (outer_mode == DImode && msp430_use_16bit_hwmult ()))
+ {
+ factor = (outer_code == MULT ? 50 : 70);
+ return factor * mode_factor * msp430_costs (src, dst, speed, outer_rtx);
+ }
+
+ switch (outer_mode)
+ {
+ case E_QImode:
+ case E_HImode:
+ /* Include the cost of copying the operands into and out of the hardware
+ multiply routine. */
+ return cost_p->mulhi + (3 * msp430_costs (src, dst, speed, outer_rtx));
+
+ case E_PSImode:
+ /* Extra factor for the conversions necessary to do PSI->SI before the
+ operation. */
+ factor = 2;
+ /* fallthru. */
+ case E_SImode:
+ return factor * (cost_p->mulsi
+ + (6 * msp430_costs (src, dst, speed, outer_rtx)));
+
+ case E_DImode:
+ default:
+ return cost_p->muldi + (12 * msp430_costs (src, dst, speed, outer_rtx));
+ }
+}
+
+/* Recurse within X to find the actual destination operand of the expression.
+ For example:
+ (plus (ashift (minus (ashift (reg)
+ (const_int) ......
+ should return the reg RTX. */
+static rtx
+msp430_get_inner_dest_code (rtx x)
+{
+ enum rtx_code code = GET_CODE (x);
+ rtx op0 = XEXP (x, 0);
switch (code)
{
- case SIGN_EXTEND:
- if (mode == SImode && outer_code == SET)
+ case REG:
+ case SYMBOL_REF:
+ case CONST_INT:
+ case CONST:
+ case LABEL_REF:
+ return x;
+
+ case MEM:
+ /* Return the MEM expr not the inner REG for these cases. */
+ switch (GET_CODE (op0))
{
- *total = COSTS_N_INSNS (4);
- return true;
+ case REG:
+ case SYMBOL_REF:
+ case LABEL_REF:
+ case CONST:
+ case POST_INC:
+ return x;
+
+ case PLUS:
+ /* return MEM (PLUS (REG) (CONST)) */
+ if (GET_CODE (XEXP (op0, 0)) == REG)
+ {
+ if (GET_CODE (XEXP (op0, 1)) == CONST_INT
+ || GET_CODE (XEXP (op0, 1)) == CONST
+ || GET_CODE (XEXP (op0, 1)) == LABEL_REF
+ || GET_CODE (XEXP (op0, 1)) == SYMBOL_REF)
+ return x;
+ else
+ return msp430_get_inner_dest_code (op0);
+ }
+ return msp430_get_inner_dest_code (op0);
+
+ default:
+ if (GET_RTX_FORMAT (code)[0] != 'e')
+ return x;
+ return msp430_get_inner_dest_code (op0);
}
break;
+
+ default:
+ if (op0 == NULL_RTX)
+ gcc_unreachable ();
+ else
+ {
+ if (GET_RTX_FORMAT (code)[0] != 'e'
+ && code != ENTRY_VALUE)
+ return x;
+ return msp430_get_inner_dest_code (op0);
+ }
+ }
+}
+
+/* Calculate the cost of an MSP430 single-operand instruction, for operand DST
+ within the RTX OUTER_RTX, optimizing for speed if SPEED is true. */
+static int
+msp430_single_op_cost (rtx dst, bool speed, rtx outer_rtx)
+{
+ enum rtx_code dst_code = GET_CODE (dst);
+ const struct single_op_cost *cost_p;
+ const struct double_op_cost *double_op_cost_p;
+
+ cost_p = (speed ? &cycle_cost_single_op : &size_cost_single_op);
+ double_op_cost_p = (speed ? &cycle_cost_double_op : &size_cost_double_op);
+
+ switch (dst_code)
+ {
+ case REG:
+ return cost_p->reg;
+ case MEM:
+ if (msp430_is_mem_indirect (dst))
+ return cost_p->ind;
+ else
+ return cost_p->mem;
+
+ case CONST_INT:
+ case CONST_FIXED:
+ case CONST_DOUBLE:
+ case SYMBOL_REF:
+ case CONST:
+ /* A constant value would need to be copied into a register first. */
+ return double_op_cost_p->imm2r + cost_p->reg;
+
+ default:
+ return cost_p->mem;
}
- return false;
}
+
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS msp430_rtx_costs
+
+/* This target hook describes the relative costs of RTL expressions.
+ The function recurses to just before the lowest level of the expression,
+ when both of the operands of the expression can be examined at the same time.
+ This is because the cost of the expression depends on the specific
+ addressing mode combination of the operands.
+ The hook returns true when all subexpressions of X have been processed, and
+ false when rtx_cost should recurse. */
+static bool
+msp430_rtx_costs (rtx x,
+ machine_mode mode,
+ int outer_code ATTRIBUTE_UNUSED,
+ int opno ATTRIBUTE_UNUSED,
+ int * total,
+ bool speed)
+{
+ enum rtx_code code = GET_CODE (x);
+ rtx dst, src;
+ rtx dst_inner, src_inner;
+
+ *total = 0;
+ dst = XEXP (x, 0);
+ if (GET_RTX_LENGTH (code) == 1)
+ /* Some RTX that are single-op in GCC are double-op when translated to
+ MSP430 instructions e.g NOT, NEG, ZERO_EXTEND. */
+ src = dst;
+ else
+ src = XEXP (x, 1);
+
+
+ switch (code)
+ {
+ case SET:
+ /* Ignoring SET improves codesize. */
+ if (!speed)
+ return true;
+ /* fallthru. */
+ case PLUS:
+ if (outer_code == MEM)
+ /* Do not add any cost for the plus itself, but recurse in case there
+ are more complicated RTX inside. */
+ return false;
+ /* fallthru. */
+ case MINUS:
+ case AND:
+ case IOR:
+ case XOR:
+ case NOT:
+ case ZERO_EXTEND:
+ case TRUNCATE:
+ case NEG:
+ case ZERO_EXTRACT:
+ case SIGN_EXTRACT:
+ case IF_THEN_ELSE:
+ dst_inner = msp430_get_inner_dest_code (dst);
+ src_inner = msp430_get_inner_dest_code (src);
+ *total = COSTS_N_INSNS (msp430_costs (src_inner, dst_inner, speed, x));
+ if (mode == SImode)
+ *total *= 2;
+ if (mode == DImode)
+ *total *= 4;
+ return false;
+
+ case ROTATE:
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ dst_inner = msp430_get_inner_dest_code (dst);
+ src_inner = msp430_get_inner_dest_code (src);
+ *total = COSTS_N_INSNS (msp430_shift_costs (src_inner, dst_inner,
+ speed, x));
+ if (mode == SImode)
+ *total *= 2;
+ if (mode == DImode)
+ *total *= 4;
+ return false;
+
+ case MULT:
+ case DIV:
+ case MOD:
+ case UDIV:
+ case UMOD:
+ dst_inner = msp430_get_inner_dest_code (dst);
+ src_inner = msp430_get_inner_dest_code (src);
+ *total = COSTS_N_INSNS (msp430_muldiv_costs (src_inner, dst_inner, speed,
+ x, mode));
+ return false;
+
+ case CALL:
+ case SIGN_EXTEND:
+ dst_inner = msp430_get_inner_dest_code (dst);
+ *total = COSTS_N_INSNS (msp430_single_op_cost (dst_inner, speed, x));
+ if (mode == SImode)
+ *total *= 2;
+ if (mode == DImode)
+ *total *= 4;
+ return false;
+
+ case CONST_INT:
+ case CONST_FIXED:
+ case CONST_DOUBLE:
+ case SYMBOL_REF:
+ case CONST:
+ case LABEL_REF:
+ case REG:
+ case PC:
+ case POST_INC:
+ if (mode == SImode)
+ *total = COSTS_N_INSNS (2);
+ else if (mode == DImode)
+ *total = COSTS_N_INSNS (4);
+ return true;
+
+ case MEM:
+ /* PSImode operands are expensive when in memory. */
+ if (mode == PSImode)
+ *total = COSTS_N_INSNS (1);
+ else if (mode == SImode)
+ *total = COSTS_N_INSNS (2);
+ else if (mode == DImode)
+ *total = COSTS_N_INSNS (4);
+ /* Recurse into the MEM. */
+ return false;
+
+ case EQ:
+ case NE:
+ case GT:
+ case GTU:
+ case GE:
+ case GEU:
+ case LT:
+ case LTU:
+ case LE:
+ case LEU:
+ /* Conditions are mostly equivalent, changing their relative
+ costs has no effect. */
+ return false;
+
+ case ASM_OPERANDS:
+ case ASM_INPUT:
+ case CLOBBER:
+ case COMPARE:
+ case CONCAT:
+ case ENTRY_VALUE:
+ /* Other unhandled expressions. */
+ return false;
+
+ default:
+ return false;
+ }
+}
+
+#undef TARGET_INSN_COST
+#define TARGET_INSN_COST msp430_insn_cost
+
+static int
+msp430_insn_cost (rtx_insn *insn, bool speed ATTRIBUTE_UNUSED)
+{
+ if (recog_memoized (insn) < 0)
+ return 0;
+
+ /* The returned cost must be relative to COSTS_N_INSNS (1). An insn with a
+ length of 2 bytes is the smallest possible size and so must be equivalent
+ to COSTS_N_INSNS (1). */
+ return COSTS_N_INSNS (get_attr_length (insn) / 2);
+
+ /* FIXME Add more detailed costs when optimizing for speed.
+ For now the length of the instruction is a good approximiation and roughly
+ correlates with cycle cost. */
+}
+
/* Function Entry and Exit */
@@ -1358,15 +1968,18 @@ msp430_section_attr (tree * node,
const char * message = NULL;
- /* The "noinit" and "section" attributes are handled generically, so we
- cannot set up additional target-specific attribute exclusions using the
- existing mechanism. */
- if (has_attr (ATTR_NOINIT, *node))
+ /* The "noinit", "persistent", and "section" attributes are handled
+ generically, so we cannot set up additional target-specific attribute
+ exclusions using the existing mechanism. */
+ if (has_attr (ATTR_NOINIT, *node) && !TREE_NAME_EQ (name, "lower"))
message = G_("ignoring attribute %qE because it conflicts with "
"attribute %<noinit%>");
else if (has_attr ("section", *node) && !TREE_NAME_EQ (name, "lower"))
message = G_("ignoring attribute %qE because it conflicts with "
"attribute %<section%>");
+ else if (has_attr (ATTR_PERSIST, *node) && !TREE_NAME_EQ (name, "lower"))
+ message = G_("ignoring attribute %qE because it conflicts with "
+ "attribute %<persistent%>");
/* 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.
@@ -1387,56 +2000,6 @@ msp430_section_attr (tree * node,
return NULL_TREE;
}
-static tree
-msp430_persist_attr (tree *node,
- tree name,
- tree args,
- int flags ATTRIBUTE_UNUSED,
- bool * no_add_attrs ATTRIBUTE_UNUSED)
-{
- const char * message = NULL;
-
- gcc_assert (DECL_P (* node));
- gcc_assert (args == NULL);
- gcc_assert (TREE_NAME_EQ (name, ATTR_PERSIST));
-
- /* Check for the section attribute separately from DECL_SECTION_NAME so
- we can provide a clearer warning. */
- if (has_attr ("section", *node))
- message = G_("ignoring attribute %qE because it conflicts with "
- "attribute %<section%>");
- /* 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 (has_attr (ATTR_NOINIT, *node))
- message = G_("ignoring attribute %qE because it conflicts with "
- "attribute %<noinit%>");
- else if (TREE_CODE (*node) != VAR_DECL)
- message = G_("%qE attribute only applies to variables");
- else if (!TREE_STATIC (*node) && !TREE_PUBLIC (*node)
- && !DECL_EXTERNAL (*node))
- message = G_("%qE attribute has no effect on automatic variables");
- else if (DECL_COMMON (*node) || DECL_INITIAL (*node) == NULL)
- message = G_("variables marked with %qE attribute must be initialized");
- else
- /* It's not clear if there is anything that can be set here to prevent the
- front end placing the variable before the back end can handle it, in a
- similar way to how DECL_COMMON is cleared for .noinit variables in
- handle_noinit_attribute (gcc/c-family/c-attribs.c).
- So just place the variable in the .persistent section now. */
- set_decl_section_name (* node, ".persistent");
-
- if (message)
- {
- warning (OPT_Wattributes, message, name);
- * no_add_attrs = true;
- }
-
- return NULL_TREE;
-}
-
/* Helper to define attribute exclusions. */
#define ATTR_EXCL(name, function, type, variable) \
{ name, function, type, variable }
@@ -1471,7 +2034,6 @@ static const struct attribute_spec::exclusions attr_lower_exclusions[] =
{
ATTR_EXCL (ATTR_UPPER, true, true, true),
ATTR_EXCL (ATTR_EITHER, true, true, true),
- ATTR_EXCL (ATTR_PERSIST, true, true, true),
ATTR_EXCL (NULL, false, false, false)
};
@@ -1479,7 +2041,6 @@ static const struct attribute_spec::exclusions attr_upper_exclusions[] =
{
ATTR_EXCL (ATTR_LOWER, true, true, true),
ATTR_EXCL (ATTR_EITHER, true, true, true),
- ATTR_EXCL (ATTR_PERSIST, true, true, true),
ATTR_EXCL (NULL, false, false, false)
};
@@ -1487,15 +2048,6 @@ static const struct attribute_spec::exclusions attr_either_exclusions[] =
{
ATTR_EXCL (ATTR_LOWER, true, true, true),
ATTR_EXCL (ATTR_UPPER, true, true, true),
- ATTR_EXCL (ATTR_PERSIST, true, true, true),
- ATTR_EXCL (NULL, false, false, false)
-};
-
-static const struct attribute_spec::exclusions attr_persist_exclusions[] =
-{
- ATTR_EXCL (ATTR_LOWER, true, true, true),
- ATTR_EXCL (ATTR_UPPER, true, true, true),
- ATTR_EXCL (ATTR_EITHER, true, true, true),
ATTR_EXCL (NULL, false, false, false)
};
@@ -1523,9 +2075,6 @@ const struct attribute_spec msp430_attribute_table[] =
{ ATTR_EITHER, 0, 0, true, false, false, false, msp430_section_attr,
attr_either_exclusions },
- { ATTR_PERSIST, 0, 0, true, false, false, false, msp430_persist_attr,
- attr_persist_exclusions },
-
{ NULL, 0, 0, false, false, false, false, NULL, NULL }
};
@@ -1542,14 +2091,13 @@ msp430_handle_generic_attribute (tree *node,
{
const char *message = NULL;
- /* The front end has set up an exclusion between the "noinit" and "section"
- attributes. */
- if (!(TREE_NAME_EQ (name, ATTR_NOINIT) || TREE_NAME_EQ (name, "section")))
- return NULL_TREE;
-
- /* We allow the "lower" attribute to be used on variables with the "section"
- attribute. */
- if (has_attr (ATTR_LOWER, *node) && !TREE_NAME_EQ (name, "section"))
+ /* Permit the "lower" attribute to be set on variables with the "section",
+ "noinit" and "persistent" attributes. This is used to indicate that the
+ corresponding output section will be in lower memory, so a 430X
+ instruction is not required to handle it. */
+ if (has_attr (ATTR_LOWER, *node)
+ && !(TREE_NAME_EQ (name, "section") || TREE_NAME_EQ (name, ATTR_PERSIST)
+ || TREE_NAME_EQ (name, ATTR_NOINIT)))
message = G_("ignoring attribute %qE because it conflicts with "
"attribute %<lower%>");
else if (has_attr (ATTR_UPPER, *node))
@@ -1558,9 +2106,6 @@ msp430_handle_generic_attribute (tree *node,
else if (has_attr (ATTR_EITHER, *node))
message = G_("ignoring attribute %qE because it conflicts with "
"attribute %<either%>");
- else if (has_attr (ATTR_PERSIST, *node))
- message = G_("ignoring attribute %qE because it conflicts with "
- "attribute %<persistent%>");
if (message)
{
@@ -1818,18 +2363,6 @@ gen_prefix (tree decl)
return NULL;
}
-static section * persist_section;
-
-#undef TARGET_ASM_INIT_SECTIONS
-#define TARGET_ASM_INIT_SECTIONS msp430_init_sections
-
-static void
-msp430_init_sections (void)
-{
- persist_section = get_unnamed_section (0, output_section_asm_op,
- ".section .persistent,\"aw\"");
-}
-
#undef TARGET_ASM_SELECT_SECTION
#define TARGET_ASM_SELECT_SECTION msp430_select_section
@@ -1855,11 +2388,8 @@ msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
&& is_interrupt_func (decl))
return get_section (".lowtext", SECTION_CODE | SECTION_WRITE , decl);
- if (has_attr (ATTR_PERSIST, decl))
- return persist_section;
-
- /* ATTR_NOINIT is handled generically. */
- if (has_attr (ATTR_NOINIT, decl))
+ /* The "noinit" and "persistent" attributes are handled generically. */
+ if (has_attr (ATTR_NOINIT, decl) || has_attr (ATTR_PERSIST, decl))
return default_elf_select_section (decl, reloc, align);
prefix = gen_prefix (decl);
@@ -1955,8 +2485,6 @@ msp430_section_type_flags (tree decl, const char * name, int reloc)
name += strlen (upper_prefix);
else if (strncmp (name, either_prefix, strlen (either_prefix)) == 0)
name += strlen (either_prefix);
- else if (strcmp (name, ".persistent") == 0)
- return SECTION_WRITE | SECTION_NOTYPE;
return default_section_type_flags (decl, name, reloc);
}
@@ -2769,7 +3297,7 @@ msp430_expand_helper (rtx *operands, const char *helper_name,
if (msp430_use_f5_series_hwmult ())
fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
"_f5hw", NULL));
- else if (use_32bit_hwmult ())
+ else if (msp430_use_32bit_hwmult ())
{
/* When the arguments are 16-bits, the 16-bit hardware multiplier is
used. */
@@ -2780,8 +3308,7 @@ msp430_expand_helper (rtx *operands, const char *helper_name,
fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
"_hw32", NULL));
}
- /* 16-bit hardware multiply. */
- else if (msp430_has_hwmult ())
+ else if (msp430_use_16bit_hwmult ())
fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
"_hw", NULL));
else
@@ -2818,8 +3345,7 @@ msp430_expand_helper (rtx *operands, const char *helper_name,
/* Return TRUE if the helper function should be used and FALSE if the shifts
insns should be emitted inline. */
static bool
-use_helper_for_const_shift (enum rtx_code code, machine_mode mode,
- HOST_WIDE_INT amt)
+use_helper_for_const_shift (machine_mode mode, HOST_WIDE_INT amt)
{
const int default_inline_shift = 4;
/* We initialize the option to 65 so we know if the user set it or not. */
@@ -2830,6 +3356,9 @@ use_helper_for_const_shift (enum rtx_code code, machine_mode mode,
the heuristic accordingly. */
int max_inline_32 = max_inline / 2;
+ if (mode == E_DImode)
+ return true;
+
/* Don't use helpers for these modes on 430X, when optimizing for speed, or
when emitting a small number of insns. */
if ((mode == E_QImode || mode == E_HImode || mode == E_PSImode)
@@ -2867,7 +3396,7 @@ msp430_expand_shift (enum rtx_code code, machine_mode mode, rtx *operands)
constant. */
if (!CONST_INT_P (operands[2])
|| mode == E_DImode
- || use_helper_for_const_shift (code, mode, INTVAL (operands[2])))
+ || use_helper_for_const_shift (mode, INTVAL (operands[2])))
{
const char *helper_name = NULL;
/* The const variants of mspabi shifts have significantly larger code
@@ -2923,18 +3452,22 @@ msp430_expand_shift (enum rtx_code code, machine_mode mode, rtx *operands)
For 430X it is inneficient to do so for any modes except SI and DI, since we
can make use of R*M insns or RPT with 430X insns, so this function is only
used for SImode in that case. */
-const char *
+int
msp430_output_asm_shift_insns (enum rtx_code code, machine_mode mode,
- rtx *operands)
+ rtx *operands, bool return_length)
{
int i;
int amt;
int max_shift = GET_MODE_BITSIZE (mode) - 1;
+ int length = 0;
+
gcc_assert (CONST_INT_P (operands[2]));
amt = INTVAL (operands[2]);
if (amt == 0 || amt > max_shift)
{
+ if (return_length)
+ return 0;
switch (code)
{
case ASHIFT:
@@ -2952,17 +3485,28 @@ msp430_output_asm_shift_insns (enum rtx_code code, machine_mode mode,
default:
gcc_unreachable ();
}
- return "";
+ return 0;
}
if (code == ASHIFT)
{
if (!msp430x && mode == HImode)
- for (i = 0; i < amt; i++)
- output_asm_insn ("RLA.W\t%0", operands);
+ {
+ if (return_length)
+ length = 2 + (MEM_P (operands[0]) ? 2 : 0);
+ else
+ for (i = 0; i < amt; i++)
+ output_asm_insn ("RLA.W\t%0", operands);
+ }
else if (mode == SImode)
- for (i = 0; i < amt; i++)
- output_asm_insn ("RLA%X0.W\t%L0 { RLC%X0.W\t%H0", operands);
+ {
+ if (return_length)
+ length = 4 + (MEM_P (operands[0]) ? 4 : 0)
+ + (4 * msp430x_insn_required (operands[0]));
+ else
+ for (i = 0; i < amt; i++)
+ output_asm_insn ("RLA%X0.W\t%L0 { RLC%X0.W\t%H0", operands);
+ }
else
/* Catch unhandled cases. */
gcc_unreachable ();
@@ -2970,33 +3514,61 @@ msp430_output_asm_shift_insns (enum rtx_code code, machine_mode mode,
else if (code == ASHIFTRT)
{
if (!msp430x && mode == HImode)
- for (i = 0; i < amt; i++)
- output_asm_insn ("RRA.W\t%0", operands);
+ {
+ if (return_length)
+ length = 2 + (MEM_P (operands[0]) ? 2 : 0);
+ else
+ for (i = 0; i < amt; i++)
+ output_asm_insn ("RRA.W\t%0", operands);
+ }
else if (mode == SImode)
- for (i = 0; i < amt; i++)
- output_asm_insn ("RRA%X0.W\t%H0 { RRC%X0.W\t%L0", operands);
+ {
+ if (return_length)
+ length = 4 + (MEM_P (operands[0]) ? 4 : 0)
+ + (4 * msp430x_insn_required (operands[0]));
+ else
+ for (i = 0; i < amt; i++)
+ output_asm_insn ("RRA%X0.W\t%H0 { RRC%X0.W\t%L0", operands);
+ }
else
gcc_unreachable ();
}
else if (code == LSHIFTRT)
{
if (!msp430x && mode == HImode)
- for (i = 0; i < amt; i++)
- output_asm_insn ("CLRC { RRC.W\t%0", operands);
+ {
+ if (return_length)
+ length = 4 + (MEM_P (operands[0]) ? 2 : 0);
+ else
+ for (i = 0; i < amt; i++)
+ output_asm_insn ("CLRC { RRC.W\t%0", operands);
+ }
else if (mode == SImode)
- for (i = 0; i < amt; i++)
- output_asm_insn ("CLRC { RRC%X0.W\t%H0 { RRC%X0.W\t%L0", operands);
+ {
+ if (return_length)
+ length = 6 + (MEM_P (operands[0]) ? 4 : 0)
+ + (4 * msp430x_insn_required (operands[0]));
+ else
+ for (i = 0; i < amt; i++)
+ output_asm_insn ("CLRC { RRC%X0.W\t%H0 { RRC%X0.W\t%L0",
+ operands);
+ }
/* FIXME: Why doesn't "RRUX.W\t%H0 { RRC%X0.W\t%L0" work for msp430x?
It causes execution timeouts e.g. pr41963.c. */
#if 0
else if (msp430x && mode == SImode)
- for (i = 0; i < amt; i++)
- output_asm_insn ("RRUX.W\t%H0 { RRC%X0.W\t%L0", operands);
+ {
+ if (return_length)
+ length = 2;
+ else
+ for (i = 0; i < amt; i++)
+ output_asm_insn ("RRUX.W\t%H0 { RRC%X0.W\t%L0", operands);
+ }
#endif
else
gcc_unreachable ();
}
- return "";
+ return length * amt;
}
/* Called by cbranch<mode>4 to coerce operands into usable forms. */
@@ -3277,7 +3849,7 @@ msp430_use_f5_series_hwmult (void)
32-bit hardware multiplier. */
static bool
-use_32bit_hwmult (void)
+msp430_use_32bit_hwmult (void)
{
static const char * cached_match = NULL;
static bool cached_result;
@@ -3300,6 +3872,34 @@ use_32bit_hwmult (void)
return cached_result = false;
}
+/* Returns true if the current MCU has a first generation
+ 16-bit hardware multiplier. */
+
+static bool
+msp430_use_16bit_hwmult (void)
+{
+ static const char * cached_match = NULL;
+ static bool cached_result;
+
+ if (msp430_hwmult_type == MSP430_HWMULT_SMALL)
+ return true;
+
+ if (target_mcu == NULL || msp430_hwmult_type != MSP430_HWMULT_AUTO)
+ return false;
+
+ if (target_mcu == cached_match)
+ return cached_result;
+
+ cached_match = target_mcu;
+
+ msp430_extract_mcu_data (target_mcu);
+ if (extracted_mcu_data.name != NULL)
+ return cached_result = (extracted_mcu_data.hwmpy == 1
+ || extracted_mcu_data.hwmpy == 2);
+
+ return cached_result = false;
+}
+
/* Returns true if the current MCU does not have a
hardware multiplier of any kind. */
@@ -3349,28 +3949,6 @@ msp430_output_labelref (FILE *file, const char *name)
break;
}
- /* If we have been given a specific MCU name then we may be
- able to make use of its hardware multiply capabilities. */
- if (msp430_has_hwmult ())
- {
- if (strcmp ("__mspabi_mpyi", name) == 0)
- {
- if (msp430_use_f5_series_hwmult ())
- name = "__mulhi2_f5";
- else
- name = "__mulhi2";
- }
- else if (strcmp ("__mspabi_mpyl", name) == 0)
- {
- if (msp430_use_f5_series_hwmult ())
- name = "__mulsi2_f5";
- else if (use_32bit_hwmult ())
- name = "__mulsi2_hw32";
- else
- name = "__mulsi2";
- }
- }
-
if (user_label_prefix[0] != 0)
fputs (user_label_prefix, file);
@@ -3518,6 +4096,20 @@ msp430_op_not_in_high_mem (rtx op)
return false;
}
+/* Based on the operand OP, is a 430X insn required to handle it?
+ There are only 3 conditions for which a 430X insn is required:
+ - PSImode operand
+ - memory reference to a symbol which could be in upper memory
+ (so its address is > 0xFFFF)
+ - absolute address which has VOIDmode, i.e. (mem:HI (const_int))
+ Use a 430 insn if none of these conditions are true. */
+bool
+msp430x_insn_required (rtx op)
+{
+ return (GET_MODE (op) == PSImode
+ || !msp430_op_not_in_high_mem (op));
+}
+
#undef TARGET_PRINT_OPERAND
#define TARGET_PRINT_OPERAND msp430_print_operand
@@ -3858,35 +4450,52 @@ msp430_register_pre_includes (const char *sysroot ATTRIBUTE_UNUSED,
/* Generate a sequence of instructions to sign-extend an HI
value into an SI value. Handles the tricky case where
- we are overwriting the destination. */
-
-const char *
-msp430x_extendhisi (rtx * operands)
+ we are overwriting the destination.
+ Return the number of bytes used by the emitted instructions.
+ If RETURN_LENGTH is true then do not emit the assembly instruction
+ sequence. */
+int
+msp430x_extendhisi (rtx * operands, bool return_length)
{
if (REGNO (operands[0]) == REGNO (operands[1]))
- /* 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
-
- but this version does not involve any function calls or using argument
- 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. 6-byte sequence. */
- return "MOV.W\t%1, %L0 { RPT\t#15 { RRAX.W\t%H0";
+ {
+ /* Low word of dest == source word. */
+ if (!return_length)
+ output_asm_insn ("BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0",
+ operands);
+ return 8;
+ }
+ else 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
+
+ but this version does not involve any function calls or using argument
+ registers, so it reduces register pressure. */
+ if (!return_length)
+ output_asm_insn ("MOV.W\t%1, %L0 { BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0",
+ operands);
+ return 10;
+ }
+ else if (REGNO (operands[0]) + 1 == REGNO (operands[1]))
+ {
+ /* High word of dest == source word. */
+ if (!return_length)
+ output_asm_insn ("MOV.W\t%1, %L0 { RPT\t#15 { RRAX.W\t%H0",
+ operands);
+ return 6;
+ }
- /* 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";
+ /* No overlap between dest and source. */
+ if (!return_length)
+ output_asm_insn ("MOV.W\t%1, %L0 { MOV.W\t%1, %H0 { RPT\t#15 { RRAX.W\t%H0",
+ operands);
+ return 8;
}
/* Stop GCC from thinking that it can eliminate (SUBREG:PSI (SI)). */
diff --git a/gcc/config/msp430/msp430.h b/gcc/config/msp430/msp430.h
index 2500771..049151e 100644
--- a/gcc/config/msp430/msp430.h
+++ b/gcc/config/msp430/msp430.h
@@ -243,6 +243,14 @@ extern const char *msp430_get_linker_devices_include_path (int, const char **);
#define HAS_LONG_COND_BRANCH 0
#define HAS_LONG_UNCOND_BRANCH 0
+/* The cost of a branch sequence is roughly 3 "cheap" instructions. */
+#define BRANCH_COST(speed_p, predictable_p) 3
+
+/* Override the default BRANCH_COST heuristic to indicate that it is preferable
+ to retain short-circuit operations, this results in significantly better
+ codesize and performance. */
+#define LOGICAL_OP_NON_SHORT_CIRCUIT 0
+
#define LOAD_EXTEND_OP(M) ZERO_EXTEND
#define WORD_REGISTER_OPERATIONS 1
@@ -530,3 +538,13 @@ void msp430_register_pre_includes (const char *sysroot ATTRIBUTE_UNUSED,
#define SYMBOL_FLAG_LOW_MEM (SYMBOL_FLAG_MACH_DEP << 0)
+
+#define ADJUST_INSN_LENGTH(insn, length) \
+ do \
+ { \
+ if (recog_memoized (insn) >= 0) \
+ { \
+ length += get_attr_extra_length (insn); \
+ length *= get_attr_length_multiplier (insn); \
+ } \
+ } while (0)
diff --git a/gcc/config/msp430/msp430.md b/gcc/config/msp430/msp430.md
index ad244bb..1ec219c 100644
--- a/gcc/config/msp430/msp430.md
+++ b/gcc/config/msp430/msp430.md
@@ -58,8 +58,100 @@
UNS_DELAY_END
])
-;; This is an approximation.
-(define_attr "length" "" (const_int 4))
+;; Instruction length is calculated by examining the type and number of
+;; operands.
+;; Whether the insn uses the 430X extension word, or is a 430X address
+;; instruction also has an effect.
+;; "Cheap" source operands do not contribute to the overall length of the insn
+;; and are register (Rn), indirect post-increment (@Rn+) and indirect register
+;; (@Rn).
+;; The lengths of instructions in bytes are:
+;; Single-op 430: Cheap op == 2
+;; (also CALLA) Other op == 4
+;; Double-op 430: Source is not cheap == 2
+;; (also MOVA, Dest is register == 2
+;; CMPA, ADDA, Dest is not a register == 4
+;; SUBA) (sum the source and dest cost)
+;; Single-op 430X: For insn names ending in 'X' add 2 to single-op 430 cost.
+;; Double-op 430X: Insn name ends in 'M' == 2
+;; Others have the same cost as double-op 430 but add 2.
+;;
+;; The insn type describes whether it is a single or double operand MSP430
+;; instruction (some single-operand GCC instructions are actually
+;; double-operand on the target).
+;; "triple" and "cmp" types use the costs of a double operand type but
+;; instead assume that the src operand is in op2, and also cmp types assume the
+;; dst operand is in op1.
+;; This attribute also describes which operands are safe to examine
+;; when calculating the length or extension. GCC will segfault trying to
+;; examine a non-existant operand of an insn.
+(define_attr "type" "none,single,double,triple,cmp" (const_string "none"))
+
+;; The M extension is for instructions like RRAM - they always
+;; only, and the operand must be a register.
+(define_attr "extension" "none,x,a,m"
+ (cond [(eq_attr "type" "none")
+ (const_string "none")
+ (match_operand 0 "msp430_high_memory_operand" "")
+ (const_string "x")
+ (and (eq_attr "type" "double")
+ (match_operand 1 "msp430_high_memory_operand" ""))
+ (const_string "x")
+ (and (ior (eq_attr "type" "triple") (eq_attr "type" "cmp"))
+ (ior (match_operand 1 "msp430_high_memory_operand" "")
+ (match_operand 2 "msp430_high_memory_operand" "")))
+ (const_string "x")]
+ (const_string "none")))
+
+;; Multiply the default length by this constant value.
+(define_attr "length_multiplier" "" (const_int 1))
+
+;; Add an additional amount to the total length of the insn.
+(define_attr "extra_length" "" (const_int 0))
+
+;; FIXME for some reason if we move the addition of 2 for extension == x to
+;; ADJUST_INSN_LENGTH, codesize gets much worse.
+(define_attr "length" ""
+ (cond [(eq_attr "extension" "m")
+ (const_int 2)
+ (eq_attr "type" "single")
+ (plus (if_then_else (match_operand 0 "msp430_cheap_operand" "")
+ (const_int 2)
+ (const_int 4))
+ (if_then_else (eq_attr "extension" "x")
+ (const_int 2)
+ (const_int 0)))
+ (eq_attr "type" "double")
+ (plus (plus (if_then_else (match_operand 0 "register_operand" "")
+ (const_int 2)
+ (const_int 4))
+ (if_then_else (match_operand 1 "msp430_cheap_operand" "")
+ (const_int 0)
+ (const_int 2)))
+ (if_then_else (eq_attr "extension" "x")
+ (const_int 2)
+ (const_int 0)))
+ (eq_attr "type" "triple")
+ (plus (plus (if_then_else (match_operand 0 "register_operand" "")
+ (const_int 2)
+ (const_int 4))
+ (if_then_else (match_operand 2 "msp430_cheap_operand" "")
+ (const_int 0)
+ (const_int 2)))
+ (if_then_else (eq_attr "extension" "x")
+ (const_int 2)
+ (const_int 0)))
+ (eq_attr "type" "cmp")
+ (plus (plus (if_then_else (match_operand 1 "register_operand" "")
+ (const_int 2)
+ (const_int 4))
+ (if_then_else (match_operand 2 "msp430_cheap_operand" "")
+ (const_int 0)
+ (const_int 2)))
+ (if_then_else (eq_attr "extension" "x")
+ (const_int 2)
+ (const_int 0)))]
+ (const_int 2)))
(include "predicates.md")
(include "constraints.md")
@@ -97,35 +189,43 @@
(match_operand:HI 0 "register_operand" "r"))]
""
"PUSH\t%0"
- )
+ [(set_attr "type" "single")]
+)
(define_insn "pusha"
[(set (mem:PSI (pre_dec:PSI (reg:PSI SP_REGNO)))
(match_operand:PSI 0 "register_operand" "r"))]
"TARGET_LARGE"
"PUSHX.A\t%0"
- )
+ [(set_attr "type" "single")
+ (set_attr "extension" "x")]
+)
(define_insn "pushm"
[(unspec_volatile [(match_operand 0 "register_operand" "r")
(match_operand 1 "immediate_operand" "n")] UNS_PUSHM)]
""
"PUSHM%b0\t%1, %0"
- )
+ [(set_attr "type" "single")
+ (set_attr "extension" "m")]
+)
(define_insn "pop"
[(set (match_operand:HI 0 "register_operand" "=r")
(mem:HI (post_inc:HI (reg:HI SP_REGNO))))]
""
"POP\t%0"
- )
+ [(set_attr "type" "single")]
+)
(define_insn "popa"
[(set (match_operand:PSI 0 "register_operand" "=r")
(mem:PSI (post_inc:PSI (reg:PSI SP_REGNO))))]
"TARGET_LARGE"
"POPX.A\t%0"
- )
+ [(set_attr "type" "single")
+ (set_attr "extension" "x")]
+)
;; This is nasty. Operand0 is bogus. It is only there so that we can get a
;; mode for the %b0 to work. We should use operand1 for this, but that does
@@ -144,7 +244,9 @@
(match_operand 2 "immediate_operand" "i")] UNS_POPM)]
""
"POPM%b0\t%2, r%J1"
- )
+ [(set_attr "type" "single")
+ (set_attr "extension" "m")]
+)
;; The next two patterns are here to support a "feature" of how GCC implements
;; varargs. When a function uses varargs and the *second* to last named
@@ -170,6 +272,10 @@
return \"SUBA\t#2, r1 { MOVX.A\t2(r1), 0(r1)\";
return \"SUB\t#2, r1 { MOV.W\t2(r1), 0(r1)\";
"
+ [(set (attr "length")
+ (if_then_else (match_test "TARGET_LARGE")
+ (const_int 8)
+ (const_int 6)))]
)
(define_insn "swap_and_shrink"
@@ -178,7 +284,12 @@
"* return TARGET_LARGE
? \"MOVX.A\t0(r1), 2(r1) { ADDA\t#2, SP\"
: \"MOV.W\t0(r1), 2(r1) { ADD\t#2, SP\";
- ")
+ "
+ [(set (attr "length")
+ (if_then_else (match_test "TARGET_LARGE")
+ (const_int 10)
+ (const_int 8)))]
+)
; I set LOAD_EXTEND_OP and WORD_REGISTER_OPERATIONS, but gcc puts in a
; zero_extend anyway. Catch it here.
@@ -189,6 +300,7 @@
"@
MOV.B\t%1, %0
MOV%X1.B\t%1, %0"
+ [(set_attr "type" "double")]
)
(define_insn "movqi_topbyte"
@@ -196,6 +308,8 @@
(subreg:QI (match_operand:PSI 1 "msp430_general_operand" "r") 2))]
"msp430x"
"PUSHM.A\t#1,%1 { POPM.W\t#1,%0 { POPM.W\t#1,%0"
+ [(set_attr "length" "6")
+ (set_attr "type" "double")]
)
(define_insn "movqi"
@@ -205,6 +319,7 @@
"@
MOV.B\t%1, %0
MOVX.B\t%1, %0"
+ [(set_attr "type" "double")]
)
(define_insn "movhi"
@@ -215,6 +330,7 @@
MOV.B\t%1, %0
MOV.W\t%1, %0
MOVX.W\t%1, %0"
+ [(set_attr "type" "double")]
)
(define_expand "movsi"
@@ -222,7 +338,7 @@
(match_operand:SI 1 "general_operand"))]
""
""
- )
+)
(define_insn_and_split "movsi_s"
[(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=rm")
@@ -235,7 +351,8 @@
(set (match_operand:HI 3 "msp430_general_dst_nonv_operand")
(match_operand:HI 5 "general_operand"))]
"msp430_split_movsi (operands);"
- )
+ [(set_attr "type" "double")]
+)
(define_insn_and_split "movsi_x"
[(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=rm")
@@ -248,6 +365,7 @@
(set (match_operand:HI 3 "msp430_general_dst_nonv_operand")
(match_operand:HI 5 "general_operand"))]
"msp430_split_movsi (operands);"
+ [(set_attr "type" "double")]
)
;; FIXME: Some MOVX.A cases can be done with MOVA, this is only a few of them.
@@ -260,7 +378,10 @@
MOV.W\t%1, %0
MOVA\t%1, %0
MOVA\t%1, %0
- MOVX.A\t%1, %0")
+ MOVX.A\t%1, %0"
+ [(set_attr "extension" "none,none,a,a,x")
+ (set_attr "type" "double")]
+)
; This pattern is identical to the truncsipsi2 pattern except
; that it uses a SUBREG instead of a TRUNC. It is needed in
@@ -274,6 +395,8 @@
(subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))]
"msp430x"
"PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A #1, %0 ; Move reg-pair %L1:%H1 into pointer %0"
+ [(set_attr "length" "6")
+ (set_attr "type" "double")]
)
;; Produced when converting a pointer to an integer via a union, eg gcc.dg/pr47201.c.
@@ -282,6 +405,8 @@
(subreg:HI (match_operand:PSI 1 "msp430_symbol_operand" "i") 0))]
"msp430x"
"MOVA\t%1, %0"
+ [(set_attr "extension" "a")
+ (set_attr "type" "double")]
)
;;------------------------------------------------------------
@@ -295,6 +420,8 @@
"@
ADDA\t%2, %0
ADDX.A\t%2, %0"
+ [(set_attr "extension" "a,x")
+ (set_attr "type" "triple")]
)
(define_insn "addqi3"
@@ -305,6 +432,7 @@
"@
ADD.B\t%2, %0
ADDX.B\t%2, %0"
+ [(set_attr "type" "triple")]
)
(define_insn "addhi3"
@@ -315,6 +443,7 @@
"@
ADD.W\t%2, %0
ADDX.W\t%2, %0"
+ [(set_attr "type" "triple")]
)
; This pattern is needed in order to avoid reload problems.
@@ -327,6 +456,13 @@
(match_operand 2 "general_operand" "rmi")))]
""
"ADD%X2.W\t%L2, %L0 { ADDC%X2.W\t%H2, %H0 { PUSH.W\t%H0 { PUSH.W\t%L0 { POPM.A\t#1, %0"
+ [(set (attr "length")
+ (if_then_else (match_operand 2 "register_operand" "")
+ (const_int 10)
+ (if_then_else (match_operand 2 "msp430_high_memory_operand" "")
+ (const_int 18)
+ (const_int 14))))
+ (set_attr "type" "triple")]
)
(define_insn "addsi3"
@@ -337,6 +473,8 @@
"@
ADD\t%L2, %L0 { ADDC\t%H2, %H0
ADDX\t%L2, %L0 { ADDCX\t%H2, %H0"
+ [(set_attr "length_multiplier" "2")
+ (set_attr "type" "triple")]
)
; Version of addhi that exposes the carry operations, for SImode adds.
@@ -382,7 +520,8 @@
"@
ADD\t%2, %1 ; cy
ADDX\t%2, %1 ; cy"
- )
+ [(set_attr "type" "triple")]
+)
(define_insn "addhi3_cy_i"
[(set (match_operand:HI 0 "msp430_general_dst_nonv_operand" "=r,rm")
@@ -397,7 +536,8 @@
"@
ADD\t%2, %1 ; cy
ADD%X0\t%2, %1 ; cy"
- )
+ [(set_attr "type" "triple")]
+)
; Version of addhi that adds the carry, for SImode adds.
(define_insn "addchi4_cy"
@@ -410,7 +550,8 @@
"@
ADDC\t%2, %1
ADDCX\t%2, %1"
- )
+ [(set_attr "type" "triple")]
+)
; Split an SImode add into two HImode adds, keeping track of the carry
; so that gcc knows when it can and can't optimize away the two
@@ -440,7 +581,7 @@
if (msp430_split_addsi (operands))
FAIL;
"
- )
+)
;; Alternatives 2 and 3 are to handle cases generated by reload.
@@ -454,6 +595,9 @@
SUBX.A\t%2, %0
MOVX.A\t%1, %0 { SUBX.A\t%2, %0
MOVX.A\t%1, %0 { SUBA\t%2, %0"
+ [(set_attr "type" "triple")
+ (set_attr "extension" "a,x,x,x")
+ (set_attr "length_multiplier" "1,1,2,2")]
)
;; Alternatives 2 and 3 are to handle cases generated by reload.
@@ -467,6 +611,8 @@
SUBX.B\t%2, %0
MOV%X2.B\t%1, %0 { SUB%X2.B\t%2, %0
MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0"
+ [(set_attr "length_multiplier" "1,1,2,2")
+ (set_attr "type" "triple")]
)
;; Alternatives 2 and 3 are to handle cases generated by reload.
@@ -480,6 +626,8 @@
SUBX.W\t%2, %0
MOV%X2.W\t%1, %0 { SUB%X2.W\t%2, %0
MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0"
+ [(set_attr "length_multiplier" "1,1,2,2")
+ (set_attr "type" "triple")]
)
(define_insn "subsi3"
@@ -490,6 +638,8 @@
"@
SUB\t%L2, %L0 { SUBC\t%H2, %H0
SUBX\t%L2, %L0 { SUBCX\t%H2, %H0"
+ [(set_attr "length_multiplier" "2")
+ (set_attr "type" "triple")]
)
(define_insn "*bic<mode>_cg"
@@ -500,6 +650,8 @@
"@
BIC%x0%b0\t#%I2, %0
BIC%X0%b0\t#%I2, %0"
+ [(set_attr "length" "2") ; Smaller length achieved by using constant generator
+ (set_attr "type" "double")]
)
(define_insn "bic<mode>3"
@@ -510,6 +662,7 @@
"@
BIC%x0%b0\t%1, %0
BICX%b0\t%1, %0"
+ [(set_attr "type" "double")]
)
(define_insn "and<mode>3"
@@ -521,6 +674,7 @@
AND%x0.B\t%2, %0
AND%x0%b0\t%2, %0
ANDX%b0\t%2, %0"
+ [(set_attr "type" "triple")]
)
(define_insn "ior<mode>3"
@@ -531,6 +685,7 @@
"@
BIS%x0%b0\t%2, %0
BISX%b0\t%2, %0"
+ [(set_attr "type" "triple")]
)
(define_insn "xor<mode>3"
@@ -541,6 +696,7 @@
"@
XOR%x0%b0\t%2, %0
XORX%b0\t%2, %0"
+ [(set_attr "type" "triple")]
)
;; Macro : XOR #~0, %0
@@ -551,6 +707,7 @@
"@
INV%x0%b0\t%0
INV%X0%b0\t%0"
+ [(set_attr "type" "double")]
)
(define_insn "extendqihi2"
@@ -560,6 +717,7 @@
"@
SXT%X0\t%0
SXT%X0\t%0"
+ [(set_attr "type" "single")]
)
(define_insn "extendqipsi2"
@@ -569,6 +727,8 @@
"@
SXT\t%0
SXTX.A\t%0"
+ [(set_attr "type" "single")
+ (set_attr "extension" "none,x")]
)
;; ------------------------
@@ -590,6 +750,7 @@
MOV.B\t%1, %0
MOV%X1.B\t%1, %0
AND%X0\t#0xff, %0"
+ [(set_attr "type" "double")]
)
(define_insn "zero_extendqipsi2"
@@ -599,6 +760,7 @@
"@
MOV.B\t%1, %0
MOV%X1.B\t%1, %0"
+ [(set_attr "type" "double")]
)
(define_insn "zero_extendqisi2"
@@ -608,6 +770,9 @@
"@
CLR\t%H0
MOV%X1.B\t%1,%L0 { CLR\t%H0"
+ [(set_attr "extra_length" "2")
+ (set_attr "length_multiplier" "1,2")
+ (set_attr "type" "double")]
)
(define_insn "zero_extendhipsi2"
@@ -618,6 +783,7 @@
MOV.W\t%1, %0
MOV%X1\t%1, %0
MOVX.A\t%1, %0"
+ [(set_attr "type" "double")]
)
(define_insn "zero_extendhisi2"
@@ -627,6 +793,8 @@
"@
MOV%X0.W\t#0,%H0
MOV.W\t%1,%L0 { MOV.W\t#0,%H0"
+ [(set_attr "length_multiplier" "1,2")
+ (set_attr "type" "double")]
)
(define_insn "zero_extendhisipsi2"
@@ -636,6 +804,8 @@
"@
AND.W\t#-1,%0
MOV.W\t%1,%0"
+ [(set_attr "length" "4,2")
+ (set_attr "type" "double")]
)
; Nasty - we are sign-extending a 20-bit PSI value in one register into
@@ -671,6 +841,13 @@
else \
return \"PUSHM.A\t#1, %1 { POPX.W\t%L0 { POPX.W\t%H0 ; move pointer in %1 into reg-pair %L0:%H0\";
MOVX.A %1, %0"
+ [(set (attr "length")
+ (cond [(match_test "REGNO (operands[1]) == SP_REGNO")
+ (const_int 18)
+ (eq_attr "alternative" "1")
+ (const_int 6)]
+ (const_int 10)))
+ (set_attr "type" "double")]
)
;; Below are unnamed insn patterns to catch pointer manipulation insns
@@ -687,6 +864,7 @@
(sign_extend:PSI (subreg:HI (match_operand:QI 1 "general_operand" "rm") 0)))]
"msp430x"
"MOV%X1.B\t%1, %0"
+ [(set_attr "type" "double")]
)
(define_insn ""
@@ -696,6 +874,7 @@
"@
MOV.B\t%1, %0
MOV%X1.B\t%1, %0"
+ [(set_attr "type" "double")]
)
;; The next three insns emit identical assembly code.
@@ -711,6 +890,9 @@
RLAM.W %2, %L0 { CLR %H0
MOV%X1.B %1, %L0 { RLAM.W %2, %L0 { CLR %H0
MOV%X1.B %1, %L0 { RPT %2 { RLAX.W %L0 { CLR %H0"
+ [(set_attr "length" "4,*,*")
+ (set_attr "extra_length" "0,4,6")
+ (set_attr "type" "double")]
)
(define_insn ""
@@ -722,6 +904,9 @@
RLAM.W %2, %L0 { CLR %H0
MOV%X1.B %1, %L0 { RLAM.W %2, %L0 { CLR %H0
MOV%X1.B %1, %L0 { RPT %2 { RLAX.W %L0 { CLR %H0"
+ [(set_attr "length" "4,*,*")
+ (set_attr "extra_length" "0,4,6")
+ (set_attr "type" "double")]
)
;; Same as above but with a NOP sign_extend round the subreg
@@ -734,6 +919,9 @@
RLAM.W %2, %L0 { CLR %H0
MOV%X1.B %1, %L0 { RLAM.W %2, %L0 { CLR %H0
MOV%X1.B %1, %L0 { RPT %2 { RLAX.W %L0 { CLR %H0"
+ [(set_attr "length" "4,*,*")
+ (set_attr "extra_length" "0,4,6")
+ (set_attr "type" "double")]
)
(define_insn ""
@@ -741,6 +929,8 @@
(zero_extend:SI (sign_extend:PSI (subreg:HI (match_operand:QI 1 "general_operand" "rm") 0))))]
"msp430x"
"MOV%X1.B %1, %L0 { CLR %H0"
+ [(set_attr "extra_length" "4")
+ (set_attr "type" "double")]
)
(define_insn ""
@@ -752,6 +942,9 @@
RLAM.W %2, %0
MOV%X1.B %1, %0 { RLAM.W %2, %0
MOV%X1.B %1, %0 { RPT %2 { RLAX.A %0"
+ [(set_attr "length" "2,*,*")
+ (set_attr "extra_length" "0,2,4")
+ (set_attr "type" "double")]
)
;; END msp430 pointer manipulation combine insn patterns
@@ -771,13 +964,18 @@
(truncate:HI (match_operand:PSI 1 "register_operand" "r")))]
""
"MOVX\t%1, %0"
+ [(set_attr "extension" "m")
+ (set_attr "type" "double")]
)
(define_insn "extendhisi2"
[(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=r")
(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))]
""
- { return msp430x_extendhisi (operands); }
+ { msp430x_extendhisi (operands, 0); return ""; }
+ [(set (attr "length")
+ (symbol_ref "msp430x_extendhisi (operands, 1)"))
+ (set_attr "type" "double")]
)
(define_insn "extendhipsi2"
@@ -785,6 +983,9 @@
(subreg:PSI (sign_extend:SI (match_operand:HI 1 "general_operand" "0")) 0))]
"msp430x"
"RLAM.A #4, %0 { RRAM.A #4, %0"
+ [(set_attr "length_multiplier" "2")
+ (set_attr "extension" "m")
+ (set_attr "type" "double")]
)
;; Look for cases where integer/pointer conversions are suboptimal due
@@ -798,6 +999,9 @@
(const_int 1)))]
"msp430x"
"RLAM.A #4, %0 { RRAM.A #3, %0"
+ [(set_attr "length_multiplier" "2")
+ (set_attr "extension" "m")
+ (set_attr "type" "double")]
)
(define_insn "extend_and_shift2_hipsi2"
@@ -806,6 +1010,9 @@
(const_int 2)))]
"msp430x"
"RLAM.A #4, %0 { RRAM.A #2, %0"
+ [(set_attr "length_multiplier" "2")
+ (set_attr "extension" "m")
+ (set_attr "type" "double")]
)
;; We also need to be able to sign-extend pointer types (eg ptrdiff_t).
@@ -827,6 +1034,8 @@
else
return \"MOV.W\t%1, %L0 { MOVX.A\t%1, %H0 { RPT\t#16 { RRAX.A\t%H0 ; sign extend pointer in %1 into %L0:%H0\";
"
+ [(set_attr "length" "10")
+ (set_attr "type" "double")]
)
; See the movsipsi2 pattern above for another way that GCC performs this
@@ -836,6 +1045,8 @@
(truncate:PSI (match_operand:SI 1 "register_operand" "r")))]
""
"PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A\t#1, %L0"
+ [(set_attr "length" "6")
+ (set_attr "type" "single")]
)
;;------------------------------------------------------------
@@ -886,7 +1097,10 @@
(any_shift:HI (match_operand:HI 1 "general_operand" "0")
(match_operand:HI 2 "const_int_operand" "n")))]
"!msp430x"
- "* return msp430_output_asm_shift_insns (<CODE>, HImode, operands);"
+ "* msp430_output_asm_shift_insns (<CODE>, HImode, operands, false); return \"\";"
+ [(set (attr "length")
+ (symbol_ref "msp430_output_asm_shift_insns (<CODE>, HImode, operands, true)"))
+ (set_attr "type" "single")]
)
;; All 430 and 430X SImode constant shifts
@@ -895,7 +1109,10 @@
(any_shift:SI (match_operand:SI 1 "general_operand" "0")
(match_operand:SI 2 "const_int_operand" "n")))]
""
- "* return msp430_output_asm_shift_insns (<CODE>, SImode, operands);"
+ "* msp430_output_asm_shift_insns (<CODE>, SImode, operands, false); return \"\";"
+ [(set (attr "length")
+ (symbol_ref "msp430_output_asm_shift_insns (<CODE>, SImode, operands, true)"))
+ (set_attr "type" "single")]
)
(define_insn "ashl<mode>3_430x"
@@ -908,6 +1125,8 @@
RPT\t%2 { RLAX%b0\t%0
RPT\t#16 { RLAX%b0\t%0 { RPT\t%W2 { RLAX%b0\t%0
# undefined behavior left shift of %1 by %2"
+ [(set_attr "length" "2,4,8,0")
+ (set_attr "type" "single")]
)
(define_insn "ashr<mode>3_430x"
@@ -920,6 +1139,8 @@
RPT\t%2 { RRAX%b0\t%0
RPT\t#16 { RRAX%b0\t%0 { RPT\t%W2 { RRAX%b0\t%0
# undefined behavior arithmetic right shift of %1 by %2"
+ [(set_attr "length" "2,4,8,0")
+ (set_attr "type" "single")]
)
(define_insn "lshr<mode>3_430x"
@@ -932,6 +1153,8 @@
RPT\t%2 { RRUX%b0\t%0
RPT\t#16 { RRUX%b0\t%0 { RPT\t%W2 { RRUX%b0\t%0
# undefined behavior logical right shift of %1 by %2"
+ [(set_attr "length" "2,4,8,0")
+ (set_attr "type" "single")]
)
;;------------------------------------------------------------
@@ -941,39 +1164,43 @@
[(const_int 0)]
""
"msp430_expand_prologue (); DONE;"
- )
+)
(define_expand "epilogue"
[(const_int 0)]
""
"msp430_expand_epilogue (0); DONE;"
- )
+)
(define_insn "epilogue_helper"
[(set (pc)
- (unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER))
+ (unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER))
(return)]
- ""
+ "!msp430x"
"BR%Q0\t#__mspabi_func_epilog_%J0"
- )
+ [(set_attr "length" "2")]
+)
(define_insn "prologue_start_marker"
[(unspec_volatile [(const_int 0)] UNS_PROLOGUE_START_MARKER)]
""
"; start of prologue"
- )
+ [(set_attr "length" "0")]
+)
(define_insn "prologue_end_marker"
[(unspec_volatile [(const_int 0)] UNS_PROLOGUE_END_MARKER)]
""
"; end of prologue"
- )
+ [(set_attr "length" "0")]
+)
(define_insn "epilogue_start_marker"
[(unspec_volatile [(const_int 0)] UNS_EPILOGUE_START_MARKER)]
""
"; start of epilogue"
- )
+ [(set_attr "length" "0")]
+)
;; This makes the linker add a call to exit() after the call to main()
;; in crt0
@@ -981,7 +1208,8 @@
[(unspec_volatile [(const_int 0)] UNS_REFSYM_NEED_EXIT)]
""
".refsym\t__crt0_call_exit"
- )
+ [(set_attr "length" "0")]
+)
;;------------------------------------------------------------
;; Jumps
@@ -998,6 +1226,8 @@
(match_operand 1 ""))]
""
"CALL%Q0\t%0"
+ [(set_attr "extension" "none")
+ (set_attr "type" "single")]
)
(define_expand "call_value"
@@ -1014,12 +1244,15 @@
(match_operand 2 "")))]
""
"CALL%Q0\t%1"
+ [(set_attr "extension" "none")
+ (set_attr "type" "single")]
)
(define_insn "msp430_return"
[(return)]
""
{ return msp430_is_interrupt_func () ? "RETI" : (TARGET_LARGE ? "RETA" : "RET"); }
+ [(set_attr "length" "2")]
)
;; This pattern is NOT, as expected, a return pattern. It's called
@@ -1045,13 +1278,15 @@
"reload_completed"
[(const_int 0)]
"msp430_expand_epilogue (1); DONE;"
- )
+ [(set_attr "length" "40")]
+)
(define_insn "jump"
[(set (pc)
(label_ref (match_operand 0 "" "")))]
""
"BR%Q0\t#%l0"
+ [(set_attr "length" "4")]
)
;; FIXME: GCC currently (8/feb/2013) cannot handle symbol_refs
@@ -1061,6 +1296,10 @@
(match_operand 0 "nonimmediate_operand" "rYl"))]
""
"BR%Q0\t%0"
+ [(set (attr "length")
+ (if_then_else (match_operand 0 "register_operand" "")
+ (const_int 2)
+ (const_int 4)))]
)
;;------------------------------------------------------------
@@ -1077,14 +1316,14 @@
)]
""
"msp430_fixup_compare_operands (<MODE>mode, operands);"
- )
+)
(define_insn "cbranchpsi4_real"
[(set (pc) (if_then_else
(match_operator 0 "msp430_cmp_operator"
[(match_operand:PSI 1 "msp430_general_dst_nonv_operand" "r,rYs,rm")
(match_operand:PSI 2 "general_operand" "rLs,rYsi,rmi")])
- (label_ref (match_operand 3 "" ""))
+ (label_ref (match_operand 3 "" ""))
(pc)))
(clobber (reg:BI CARRY))
]
@@ -1093,7 +1332,9 @@
CMP%Q0\t%2, %1 { J%0\t%l3
CMPX.A\t%2, %1 { J%0\t%l3
CMPX.A\t%2, %1 { J%0\t%l3"
- )
+ [(set_attr "extra_length" "2")
+ (set_attr "type" "cmp")]
+)
(define_insn "cbranchqi4_real"
[(set (pc) (if_then_else
@@ -1108,7 +1349,9 @@
"@
CMP.B\t%2, %1 { J%0\t%l3
CMPX.B\t%2, %1 { J%0\t%l3"
- )
+ [(set_attr "extra_length" "2")
+ (set_attr "type" "cmp")]
+)
(define_insn "cbranchhi4_real"
[(set (pc) (if_then_else
@@ -1123,6 +1366,8 @@
"@
CMP.W\t%2, %1 { J%0\t%l3
CMPX.W\t%2, %1 { J%0\t%l3"
+ [(set_attr "extra_length" "2")
+ (set_attr "type" "cmp")]
)
(define_insn "cbranchpsi4_reversed"
@@ -1139,7 +1384,9 @@
CMP%Q0\t%1, %2 { J%R0\t%l3
CMPX.A\t%1, %2 { J%R0\t%l3
CMPX.A\t%1, %2 { J%R0\t%l3"
- )
+ [(set_attr "extra_length" "2")
+ (set_attr "type" "cmp")]
+)
(define_insn "cbranchqi4_reversed"
[(set (pc) (if_then_else
@@ -1154,7 +1401,9 @@
"@
CMP.B\t%1, %2 { J%R0\t%l3
CMPX.B\t%1, %2 { J%R0\t%l3"
- )
+ [(set_attr "extra_length" "2")
+ (set_attr "type" "cmp")]
+)
(define_insn "cbranchhi4_reversed"
[(set (pc) (if_then_else
@@ -1169,14 +1418,16 @@
"@
CMP.W\t%1, %2 { J%R0\t%l3
CMPX.W\t%1, %2 { J%R0\t%l3"
- )
+ [(set_attr "extra_length" "2")
+ (set_attr "type" "cmp")]
+)
(define_insn "*bitbranch<mode>4"
[(set (pc) (if_then_else
(ne (and:QHI (match_operand:QHI 0 "msp430_general_dst_operand" "rYsYx,rm")
(match_operand:QHI 1 "msp430_general_operand" "rYsYxi,rmi"))
(const_int 0))
- (label_ref (match_operand 2 "" ""))
+ (label_ref (match_operand 2 "" ""))
(pc)))
(clobber (reg:BI CARRY))
]
@@ -1184,14 +1435,16 @@
"@
BIT%x0%b0\t%1, %0 { JNE\t%l2
BITX%b0\t%1, %0 { JNE\t%l2"
- )
+ [(set_attr "extra_length" "2")
+ (set_attr "type" "double")]
+)
(define_insn "*bitbranch<mode>4"
[(set (pc) (if_then_else
(eq (and:QHI (match_operand:QHI 0 "msp430_general_dst_operand" "rYsYx,rm")
(match_operand:QHI 1 "msp430_general_operand" "rYsYxi,rmi"))
(const_int 0))
- (label_ref (match_operand 2 "" ""))
+ (label_ref (match_operand 2 "" ""))
(pc)))
(clobber (reg:BI CARRY))
]
@@ -1199,14 +1452,16 @@
"@
BIT%x0%b0\t%1, %0 { JEQ\t%l2
BITX%b0\t%1, %0 { JEQ\t%l2"
- )
+ [(set_attr "extra_length" "2")
+ (set_attr "type" "double")]
+)
(define_insn "*bitbranch<mode>4"
[(set (pc) (if_then_else
(eq (and:QHI (match_operand:QHI 0 "msp430_general_dst_operand" "rYsYx,rm")
(match_operand:QHI 1 "msp430_general_operand" "rYsYxi,rmi"))
(const_int 0))
- (pc)
+ (pc)
(label_ref (match_operand 2 "" ""))))
(clobber (reg:BI CARRY))
]
@@ -1214,14 +1469,16 @@
"@
BIT%x0%b0\t%1, %0 { JNE\t%l2
BITX%b0\t%1, %0 { JNE\t%l2"
- )
+ [(set_attr "extra_length" "2")
+ (set_attr "type" "double")]
+)
(define_insn "*bitbranch<mode>4"
[(set (pc) (if_then_else
(ne (and:QHI (match_operand:QHI 0 "msp430_general_dst_operand" "rYsYx,rm")
(match_operand:QHI 1 "msp430_general_operand" "rYsYxi,rmi"))
(const_int 0))
- (pc)
+ (pc)
(label_ref (match_operand 2 "" ""))))
(clobber (reg:BI CARRY))
]
@@ -1229,7 +1486,9 @@
"@
BIT%x0%b0\t%1, %0 { JEQ\t%l2
BITX%b0\t%1, %0 { JEQ\t%l2"
- )
+ [(set_attr "extra_length" "2")
+ (set_attr "type" "double")]
+)
;;------------------------------------------------------------
;; zero-extract versions of the above
@@ -1240,7 +1499,7 @@
(const_int 1)
(match_operand 1 "const_0_to_15_operand" "i,i"))
(const_int 0))
- (label_ref (match_operand 2 "" ""))
+ (label_ref (match_operand 2 "" ""))
(pc)))
(clobber (reg:BI CARRY))
]
@@ -1248,7 +1507,9 @@
"@
BIT%x0%b0\t%p1, %0 { JNE\t%l2
BIT%X0%b0\t%p1, %0 { JNE\t%l2"
- )
+ [(set_attr "extra_length" "2")
+ (set_attr "type" "double")]
+)
(define_insn "*bitbranch<mode>4_z"
[(set (pc) (if_then_else
@@ -1256,13 +1517,15 @@
(const_int 1)
(match_operand 1 "const_0_to_15_operand" "i"))
(const_int 0))
- (label_ref (match_operand 2 "" ""))
+ (label_ref (match_operand 2 "" ""))
(pc)))
(clobber (reg:BI CARRY))
]
""
"BIT%X0%b0\t%p1, %0 { JEQ\t%l2"
- )
+ [(set_attr "extra_length" "2")
+ (set_attr "type" "double")]
+)
(define_insn "*bitbranch<mode>4_z"
[(set (pc) (if_then_else
@@ -1270,13 +1533,15 @@
(const_int 1)
(match_operand 1 "const_0_to_15_operand" "i"))
(const_int 0))
- (pc)
+ (pc)
(label_ref (match_operand 2 "" ""))))
(clobber (reg:BI CARRY))
]
""
"BIT%X0%b0\t%p1, %0 { JNE\t%l2"
- )
+ [(set_attr "extra_length" "2")
+ (set_attr "type" "double")]
+)
(define_insn "*bitbranch<mode>4_z"
[(set (pc) (if_then_else
@@ -1284,13 +1549,15 @@
(const_int 1)
(match_operand 1 "const_0_to_15_operand" "i"))
(const_int 0))
- (pc)
+ (pc)
(label_ref (match_operand 2 "" ""))))
(clobber (reg:BI CARRY))
]
""
"BIT%X0%b0\t%p1, %0 { JEQ\t%l2"
- )
+ [(set_attr "extra_length" "2")
+ (set_attr "type" "double")]
+)
;;------------------------------------------------------------
;; Misc
@@ -1299,31 +1566,36 @@
[(const_int 0)]
"1"
"NOP"
+ [(set_attr "length" "2")]
)
(define_insn "disable_interrupts"
[(unspec_volatile [(const_int 0)] UNS_DINT)]
""
"DINT \; NOP"
- )
+ [(set_attr "length" "2")]
+)
(define_insn "enable_interrupts"
[(unspec_volatile [(const_int 0)] UNS_EINT)]
""
"EINT"
- )
+ [(set_attr "length" "2")]
+)
(define_insn "push_intr_state"
[(unspec_volatile [(const_int 0)] UNS_PUSH_INTR)]
""
"PUSH\tSR"
- )
+ [(set_attr "length" "2")]
+)
(define_insn "pop_intr_state"
[(unspec_volatile [(const_int 0)] UNS_POP_INTR)]
""
"POP\tSR"
- )
+ [(set_attr "length" "2")]
+)
;; Clear bits in the copy of the status register that is currently
;; saved on the stack at the top of the interrupt handler.
@@ -1331,7 +1603,9 @@
[(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIC_SR)]
""
"BIC.W\t%0, %O0(SP)"
- )
+ [(set_attr "type" "single")
+ (set_attr "extra_length" "2")]
+)
;; Set bits in the copy of the status register that is currently
;; saved on the stack at the top of the interrupt handler.
@@ -1339,30 +1613,33 @@
[(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIS_SR)]
""
"BIS.W\t%0, %O0(SP)"
- )
+ [(set_attr "type" "single")
+ (set_attr "extra_length" "2")]
+)
;; For some reason GCC is generating (set (reg) (and (neg (reg)) (int)))
;; very late on in the compilation and not splitting it into separate
;; instructions, so we provide a pattern to support it here.
(define_insn "andneghi3"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (and:HI (neg:HI (match_operand:HI 1 "general_operand" "rm"))
- (match_operand 2 "immediate_operand" "n")))]
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (and:HI (neg:HI (match_operand:HI 1 "general_operand" "0,rm"))
+ (match_operand 2 "immediate_operand" "n,n")))]
""
- "*
- if (REGNO (operands[0]) != REGNO (operands[1]))
- return \"MOV%X1.W\t%1, %0 { INV.W\t%0 { INC.W\t%0 { AND.W\t%2, %0\";
- else
- return \"INV.W\t%0 { INC.W\t%0 { AND.W\t%2, %0\";
- "
- )
+ "@
+ INV.W\t%0 { INC.W\t%0 { AND.W\t%2, %0
+ MOV%X1.W\t%1, %0 { INV.W\t%0 { INC.W\t%0 { AND.W\t%2, %0"
+ [(set_attr "length" "12,14")
+ (set_attr "type" "double")]
+)
+
(define_insn "delay_cycles_start"
[(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
UNS_DELAY_START)]
""
"; Begin %J0 cycle delay"
- )
+ [(set_attr "length" "0")]
+)
(define_insn "delay_cycles_end"
[(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
@@ -1387,7 +1664,8 @@
JNE 1b
POP r14
POP r13"
- )
+ [(set_attr "length" "32")]
+)
(define_insn "delay_cycles_32x"
[(unspec_volatile [(match_operand 0 "immediate_operand" "i")
@@ -1403,7 +1681,8 @@
TST.W r13
JNE 1b
POPM.A #2,r14"
- )
+ [(set_attr "length" "28")]
+)
(define_insn "delay_cycles_16"
[(unspec_volatile [(match_operand 0 "immediate_operand" "i")
@@ -1415,7 +1694,8 @@
1: SUB.W #1, r13
JNE 1b
POP r13"
- )
+ [(set_attr "length" "14")]
+)
(define_insn "delay_cycles_16x"
[(unspec_volatile [(match_operand 0 "immediate_operand" "i")
@@ -1427,19 +1707,44 @@
1: SUB.W #1, r13
JNE 1b
POPM.A #1,r13"
- )
+ [(set_attr "length" "14")]
+)
(define_insn "delay_cycles_2"
[(unspec_volatile [(const_int 0) ] UNS_DELAY_2)]
""
"JMP .+2"
- )
+ [(set_attr "length" "2")]
+)
(define_insn "delay_cycles_1"
[(unspec_volatile [(const_int 0) ] UNS_DELAY_1)]
""
"NOP"
- )
+ [(set_attr "length" "2")]
+)
+
+(define_expand "mulhi3"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (mult:HI (match_operand:HI 1 "register_operand" "%0")
+ (match_operand:HI 2 "register_operand" "r")))]
+ "msp430_has_hwmult ()"
+ {
+ msp430_expand_helper (operands, "__mspabi_mpyi", false);
+ DONE;
+ }
+)
+
+(define_expand "mulsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mult:SI (match_operand:SI 1 "register_operand" "%0")
+ (match_operand:SI 2 "register_operand" "r")))]
+ "msp430_has_hwmult ()"
+ {
+ msp430_expand_helper (operands, "__mspabi_mpyl", false);
+ DONE;
+ }
+)
; libgcc helper functions for widening multiplication aren't currently
; generated by gcc, so we can't catch them later and map them to the mspabi
@@ -1450,9 +1755,7 @@
; If we don't have hardware multiply support, it will generally be slower and
; result in larger code to call the mspabi library function to perform the
; widening multiplication than just leaving GCC to widen the arguments itself.
-;
-; We don't use library functions for SImode->DImode widening since its always
-; larger and slower than letting GCC widen the arguments inline.
+
(define_expand "mulhisi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
@@ -1483,6 +1786,37 @@
}
)
+(define_expand "mulsidi3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
+ (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
+ "msp430_has_hwmult ()"
+ {
+ /* Leave the other case for the inline insn. */
+ if (!(optimize > 2 && msp430_has_hwmult ()))
+ {
+ msp430_expand_helper (operands, "__mspabi_mpysll", false);
+ DONE;
+ }
+ }
+)
+
+(define_expand "umulsidi3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
+ (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
+ "msp430_has_hwmult ()"
+ {
+ /* Leave the other case for the inline insn. */
+ if (!(optimize > 2 && msp430_has_hwmult ()))
+ {
+ msp430_expand_helper (operands, "__mspabi_mpyull", false);
+ DONE;
+ }
+ }
+)
+
+
(define_insn "*mulhisi3_inline"
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
@@ -1494,6 +1828,7 @@
else
return \"PUSH.W sr { DINT { NOP { MOV.W %1, &0x0132 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0 { POP.W sr\";
"
+ [(set_attr "length" "24")]
)
(define_insn "*umulhisi3_inline"
@@ -1507,9 +1842,10 @@
else
return \"PUSH.W sr { DINT { NOP { MOV.W %1, &0x0130 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0 { POP.W sr\";
"
+ [(set_attr "length" "24")]
)
-(define_insn "mulsidi3"
+(define_insn "*mulsidi3_inline"
[(set (match_operand:DI 0 "register_operand" "=r")
(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
(sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
@@ -1520,9 +1856,10 @@
else
return \"PUSH.W sr { DINT { NOP { MOV.W %L1, &0x0144 { MOV.W %H1, &0x0146 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0 { POP.W sr\";
"
+ [(set_attr "length" "40")]
)
-(define_insn "umulsidi3"
+(define_insn "*umulsidi3_inline"
[(set (match_operand:DI 0 "register_operand" "=r")
(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
(zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
@@ -1533,4 +1870,5 @@
else
return \"PUSH.W sr { DINT { NOP { MOV.W %L1, &0x0140 { MOV.W %H1, &0x0142 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0 { POP.W sr\";
"
+ [(set_attr "length" "40")]
)
diff --git a/gcc/config/msp430/predicates.md b/gcc/config/msp430/predicates.md
index 4bfa0c0..eb1f61d 100644
--- a/gcc/config/msp430/predicates.md
+++ b/gcc/config/msp430/predicates.md
@@ -131,3 +131,16 @@
(define_predicate "msp430_symbol_operand"
(match_code "symbol_ref")
)
+
+; Used in length attribute tests - if a source operand is a reg,
+; (mem (post_inc)), or (mem (reg)) then it is cheap compared to other operand
+; types.
+(define_predicate "msp430_cheap_operand"
+ (ior (match_code "reg")
+ (and (match_code "mem")
+ (ior (match_code "reg" "0")
+ (match_code "post_inc" "0")))))
+
+; Used for insn attributes only. For insn patterns themselves, use constraints.
+(define_predicate "msp430_high_memory_operand"
+ (match_test "msp430x_insn_required (op)"))
diff --git a/gcc/config/pru/alu-zext.md b/gcc/config/pru/alu-zext.md
index 65916c7..35a6dbd 100644
--- a/gcc/config/pru/alu-zext.md
+++ b/gcc/config/pru/alu-zext.md
@@ -37,6 +37,10 @@
(define_subst_attr "alu3_zext_op2" "alu3_zext_op2_subst" "_z2" "_noz2")
(define_subst_attr "alu3_zext" "alu3_zext_subst" "_z" "_noz")
+(define_subst_attr "lmbd_zext_op1" "lmbd_zext_op1_subst" "_z1" "_noz1")
+(define_subst_attr "lmbd_zext_op2" "lmbd_zext_op2_subst" "_z2" "_noz2")
+(define_subst_attr "lmbd_zext" "lmbd_zext_subst" "_z" "_noz")
+
(define_subst_attr "bitalu_zext" "bitalu_zext_subst" "_z" "_noz")
(define_code_iterator ALUOP3 [plus minus and ior xor umin umax ashift lshiftrt])
@@ -72,6 +76,19 @@
[(set_attr "type" "alu")])
+;; Left Most Bit Detect instruction.
+(define_insn "pru_lmbd_impl<EQD:mode><EQS0:mode><EQS1:mode>_<lmbd_zext><lmbd_zext_op1><lmbd_zext_op2>"
+ [(set (match_operand:EQD 0 "register_operand" "=r")
+ (unspec:EQD
+ [(zero_extend:EQD
+ (match_operand:EQS0 1 "register_operand" "r"))
+ (zero_extend:EQD
+ (match_operand:EQS1 2 "reg_or_ubyte_operand" "r<EQS1:ubyte_constr>"))]
+ UNSPEC_LMBD))]
+ ""
+ "lmbd\t%0, %1, %2"
+ [(set_attr "type" "alu")])
+
(define_insn "neg_impl<EQD:mode><EQS0:mode>_<alu2_zext>"
[(set (match_operand:EQD 0 "register_operand" "=r")
(neg:EQD
@@ -179,3 +196,37 @@
[(set (match_dup 0)
(ALUOP3:EQD (zero_extend:EQD (match_dup 1))
(match_dup 2)))])
+
+
+(define_subst "lmbd_zext_subst"
+ [(set (match_operand:EQD 0)
+ (unspec:EQD [(zero_extend:EQD (match_operand:EQD 1))
+ (zero_extend:EQD (match_operand:EQD 2))]
+ UNSPEC_LMBD))]
+ ""
+ [(set (match_dup 0)
+ (unspec:EQD [(match_dup 1)
+ (match_dup 2)]
+ UNSPEC_LMBD))])
+
+(define_subst "lmbd_zext_op1_subst"
+ [(set (match_operand:EQD 0)
+ (unspec:EQD [(zero_extend:EQD (match_operand:EQD 1))
+ (zero_extend:EQD (match_operand:EQS1 2))]
+ UNSPEC_LMBD))]
+ ""
+ [(set (match_dup 0)
+ (unspec:EQD [(match_dup 1)
+ (zero_extend:EQD (match_dup 2))]
+ UNSPEC_LMBD))])
+
+(define_subst "lmbd_zext_op2_subst"
+ [(set (match_operand:EQD 0)
+ (unspec:EQD [(zero_extend:EQD (match_operand:EQD 1))
+ (zero_extend:EQD (match_operand:EQD 2))]
+ UNSPEC_LMBD))]
+ ""
+ [(set (match_dup 0)
+ (unspec:EQD [(zero_extend:EQD (match_dup 1))
+ (match_dup 2)]
+ UNSPEC_LMBD))])
diff --git a/gcc/config/pru/pru.c b/gcc/config/pru/pru.c
index 39104e5..65ad687 100644
--- a/gcc/config/pru/pru.c
+++ b/gcc/config/pru/pru.c
@@ -2705,6 +2705,8 @@ pru_reorg (void)
enum pru_builtin
{
PRU_BUILTIN_DELAY_CYCLES,
+ PRU_BUILTIN_HALT,
+ PRU_BUILTIN_LMBD,
PRU_BUILTIN_max
};
@@ -2719,11 +2721,31 @@ pru_init_builtins (void)
= build_function_type_list (void_type_node,
long_long_integer_type_node,
NULL);
+ tree uint_ftype_uint_uint
+ = build_function_type_list (unsigned_type_node,
+ unsigned_type_node,
+ unsigned_type_node,
+ NULL);
+
+ tree void_ftype_void
+ = build_function_type_list (void_type_node,
+ void_type_node,
+ NULL);
pru_builtins[PRU_BUILTIN_DELAY_CYCLES]
= add_builtin_function ("__delay_cycles", void_ftype_longlong,
PRU_BUILTIN_DELAY_CYCLES, BUILT_IN_MD, NULL,
NULL_TREE);
+
+ pru_builtins[PRU_BUILTIN_HALT]
+ = add_builtin_function ("__halt", void_ftype_void,
+ PRU_BUILTIN_HALT, BUILT_IN_MD, NULL,
+ NULL_TREE);
+
+ pru_builtins[PRU_BUILTIN_LMBD]
+ = add_builtin_function ("__lmbd", uint_ftype_uint_uint,
+ PRU_BUILTIN_LMBD, BUILT_IN_MD, NULL,
+ NULL_TREE);
}
/* Implement TARGET_BUILTIN_DECL. */
@@ -2734,6 +2756,8 @@ pru_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
switch (code)
{
case PRU_BUILTIN_DELAY_CYCLES:
+ case PRU_BUILTIN_HALT:
+ case PRU_BUILTIN_LMBD:
return pru_builtins[code];
default:
return error_mark_node;
@@ -2806,19 +2830,45 @@ pru_expand_delay_cycles (rtx arg)
IGNORE is nonzero if the value is to be ignored. */
static rtx
-pru_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
+pru_expand_builtin (tree exp, rtx target,
rtx subtarget ATTRIBUTE_UNUSED,
- machine_mode mode ATTRIBUTE_UNUSED,
+ machine_mode mode,
int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
- rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
- if (fcode == PRU_BUILTIN_DELAY_CYCLES)
- return pru_expand_delay_cycles (arg1);
+ switch (fcode)
+ {
+ case PRU_BUILTIN_DELAY_CYCLES:
+ {
+ rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
+ return pru_expand_delay_cycles (arg1);
+ }
+ break;
+ case PRU_BUILTIN_HALT:
+ {
+ emit_insn (gen_pru_halt ());
+ return NULL_RTX;
+ }
+ break;
+ case PRU_BUILTIN_LMBD:
+ {
+ rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
+ rtx arg2 = expand_normal (CALL_EXPR_ARG (exp, 1));
+
+ if (target == NULL_RTX || GET_MODE (target) != mode)
+ {
+ target = gen_reg_rtx (mode);
+ }
- internal_error ("bad builtin code");
+ emit_insn (gen_pru_lmbd (mode, target, arg1, arg2));
+ return target;
+ }
+ break;
+ default:
+ internal_error ("bad builtin code");
+ }
return NULL_RTX;
}
diff --git a/gcc/config/pru/pru.h b/gcc/config/pru/pru.h
index 314e877..7f217fe 100644
--- a/gcc/config/pru/pru.h
+++ b/gcc/config/pru/pru.h
@@ -562,6 +562,9 @@ do { \
#define CASE_VECTOR_MODE Pmode
+/* See definition of clz pattern for rationale of value -1. */
+#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = -1, 2)
+
/* Jumps are cheap on PRU. */
#define LOGICAL_OP_NON_SHORT_CIRCUIT 0
diff --git a/gcc/config/pru/pru.md b/gcc/config/pru/pru.md
index 2f1bc21..125444c 100644
--- a/gcc/config/pru/pru.md
+++ b/gcc/config/pru/pru.md
@@ -51,6 +51,10 @@
;; Enumeration of UNSPECs.
+(define_c_enum "unspec" [
+ UNSPEC_LMBD
+])
+
(define_c_enum "unspecv" [
UNSPECV_DELAY_CYCLES_START
UNSPECV_DELAY_CYCLES_END
@@ -61,6 +65,8 @@
UNSPECV_LOOP_BEGIN
UNSPECV_LOOP_END
+ UNSPECV_HALT
+
UNSPECV_BLOCKAGE
])
@@ -1020,3 +1026,37 @@
""
"nop\\t# Loop end guard"
[(set_attr "type" "alu")])
+
+;; HALT instruction.
+(define_insn "pru_halt"
+ [(unspec_volatile [(const_int 0)] UNSPECV_HALT)]
+ ""
+ "halt"
+ [(set_attr "type" "control")])
+
+;; Count Leading Zeros implemented using LMBD.
+;; LMBD returns 32 if bit value is not present, and we subtract 31 to get CLZ.
+;; Hence we get a defined value -1 for CLZ_DEFINED_VALUE_AT_ZERO.
+(define_expand "clz<mode>2"
+ [(set (match_operand:QISI 0 "register_operand")
+ (clz:QISI (match_operand:QISI 1 "register_operand")))]
+ ""
+{
+ rtx dst = operands[0];
+ rtx src = operands[1];
+ rtx tmpval = gen_reg_rtx (<MODE>mode);
+
+ emit_insn (gen_pru_lmbd (<MODE>mode, tmpval, src, const1_rtx));
+ emit_insn (gen_sub3_insn (dst, GEN_INT (31), tmpval));
+ DONE;
+})
+
+;; Left Most Bit Detect operation, which maps to a single instruction.
+(define_expand "@pru_lmbd<mode>"
+ [(set (match_operand:QISI 0 "register_operand")
+ (unspec:QISI
+ [(match_operand:QISI 1 "register_operand")
+ (match_operand:QISI 2 "reg_or_ubyte_operand")]
+ UNSPEC_LMBD))]
+ ""
+ "")
diff --git a/gcc/config/riscv/arch-canonicalize b/gcc/config/riscv/arch-canonicalize
new file mode 100755
index 0000000..2b4289e
--- /dev/null
+++ b/gcc/config/riscv/arch-canonicalize
@@ -0,0 +1,102 @@
+#!/usr/bin/env python
+
+# Tool for canonical RISC-V architecture string.
+# Copyright (C) 2011-2020 Free Software Foundation, Inc.
+# Contributed by Andrew Waterman (andrew@sifive.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/>.
+
+
+from __future__ import print_function
+import sys
+import collections
+import itertools
+from functools import reduce
+
+
+CANONICAL_ORDER = "mafdgqlcbjtpvn"
+LONG_EXT_PREFIXES = ['z', 's', 'h', 'x']
+
+#
+# IMPLIED_EXT(ext) -> implied extension list.
+#
+IMPLIED_EXT = {
+ "d" : ["f"],
+}
+
+def arch_canonicalize(arch):
+ # TODO: Support extension version.
+ new_arch = ""
+ if arch[:5] in ['rv32e', 'rv32i', 'rv32g', 'rv64i', 'rv64g']:
+ # TODO: We should expand g to imad_zifencei once we support newer spec.
+ new_arch = arch[:5].replace("g", "imafd")
+ else:
+ raise Exception("Unexpected arch: `%s`" % arch[:5])
+
+ # Find any Z, S, H or 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:].split("_")
+ std_exts = list(arch[5:first_long_ext_idx])
+ else:
+ long_exts = []
+ std_exts = list(arch[5:])
+
+ #
+ # Handle implied extensions.
+ #
+ for ext in std_exts + long_exts:
+ if ext in IMPLIED_EXT:
+ implied_exts = IMPLIED_EXT[ext]
+ for implied_ext in implied_exts:
+ if implied_ext not in std_exts + long_exts:
+ long_exts.append(implied_ext)
+
+ # Single letter extension might appear in the long_exts list,
+ # becasue we just append extensions list to the arch string.
+ std_exts += list(filter(lambda x:len(x) == 1, long_exts))
+
+ # Multi-letter extension must be in lexicographic order.
+ long_exts = list(sorted(filter(lambda x:len(x) != 1, long_exts)))
+
+ # Put extensions in canonical order.
+ for ext in CANONICAL_ORDER:
+ if ext in std_exts:
+ new_arch += ext
+
+ # Check every extension is processed.
+ for ext in std_exts:
+ if ext == '_':
+ continue
+ if ext not in CANONICAL_ORDER:
+ raise Exception("Unsupported extension `%s`" % ext)
+
+ # Concat rest of the multi-char extensions.
+ if long_exts:
+ new_arch += "_" + "_".join(long_exts)
+ return new_arch
+
+if len(sys.argv) < 2:
+ print ("Usage: %s <arch_str> [<arch_str>*]" % sys.argv)
+ sys.exit(1)
+
+for arg in sys.argv[1:]:
+ print (arch_canonicalize(arg))
diff --git a/gcc/config/riscv/multilib-generator b/gcc/config/riscv/multilib-generator
index 0d9ebcb..53c51df 100755
--- a/gcc/config/riscv/multilib-generator
+++ b/gcc/config/riscv/multilib-generator
@@ -35,9 +35,11 @@
from __future__ import print_function
import sys
+import os
import collections
import itertools
from functools import reduce
+import subprocess
#
# TODO: Add test for this script.
@@ -48,82 +50,13 @@ abis = collections.OrderedDict()
required = []
reuse = []
-canonical_order = "mafdgqlcbjtpvn"
-LONG_EXT_PREFIXES = ['z', 's', 'h', 'x']
-
-#
-# IMPLIED_EXT(ext) -> implied extension list.
-#
-IMPLIED_EXT = {
- "d" : ["f"],
-}
-
def arch_canonicalize(arch):
- # TODO: Support extension version.
- new_arch = ""
- if arch[:5] in ['rv32e', 'rv32i', 'rv32g', 'rv64i', 'rv64g']:
- # TODO: We should expand g to imad_zifencei once we support newer spec.
- new_arch = arch[:5].replace("g", "imafd")
- else:
- raise Exception("Unexpected arch: `%s`" % arch[:5])
-
- # Find any Z, S, H or 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:].split("_")
- std_exts = list(arch[5:first_long_ext_idx])
- else:
- long_exts = []
- std_exts = list(arch[5:])
-
- #
- # Handle implied extensions.
- #
- for ext in std_exts + long_exts:
- if ext in IMPLIED_EXT:
- implied_exts = IMPLIED_EXT[ext]
- for implied_ext in implied_exts:
- if implied_ext not in std_exts + long_exts:
- long_exts.append(implied_ext)
-
- # Single letter extension might appear in the long_exts list,
- # becasue we just append extensions list to the arch string.
- std_exts += list(filter(lambda x:len(x) == 1, long_exts))
-
- # Multi-letter extension must be in lexicographic order.
- long_exts = list(sorted(filter(lambda x:len(x) != 1, long_exts)))
-
- # Put extensions in canonical order.
- for ext in canonical_order:
- if ext in std_exts:
- new_arch += ext
-
- # Check every extension is processed.
- for ext in std_exts:
- if ext == '_':
- continue
- if ext not in canonical_order:
- raise Exception("Unsupported extension `%s`" % ext)
-
- # Concat rest of the multi-char extensions.
- if long_exts:
- new_arch += "_" + "_".join(long_exts)
- return new_arch
-
-#
-# add underline for each multi-char extensions.
-# e.g. ["a", "zfh"] -> ["a", "_zfh"]
-#
-def add_underline_prefix(ext):
- for long_ext_prefix in LONG_EXT_PREFIXES:
- if ext.startswith(long_ext_prefix):
- return "_" + ext
-
- return ext
+ this_file = os.path.abspath(os.path.join( __file__))
+ arch_can_script = \
+ os.path.join(os.path.dirname(this_file), "arch-canonicalize")
+ proc = subprocess.Popen([arch_can_script, arch], stdout=subprocess.PIPE)
+ out, err = proc.communicate()
+ return out.strip()
#
# Handle expansion operation.
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 2a3f9d9..0b83f17 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -39,6 +39,16 @@ enum riscv_code_model {
};
extern enum riscv_code_model riscv_cmodel;
+enum riscv_isa_spec_class {
+ ISA_SPEC_CLASS_NONE,
+
+ ISA_SPEC_CLASS_2P2,
+ ISA_SPEC_CLASS_20190608,
+ ISA_SPEC_CLASS_20191213
+};
+
+extern enum riscv_isa_spec_class riscv_isa_spec;
+
/* Keep this list in sync with define_attr "tune" in riscv.md. */
enum riscv_microarchitecture_type {
generic,
@@ -57,4 +67,10 @@ enum stack_protector_guard {
SSP_GLOBAL /* global canary */
};
+#define MASK_ZICSR (1 << 0)
+#define MASK_ZIFENCEI (1 << 1)
+
+#define TARGET_ZICSR ((riscv_zi_subext & MASK_ZICSR) != 0)
+#define TARGET_ZIFENCEI ((riscv_zi_subext & MASK_ZIFENCEI) != 0)
+
#endif /* ! GCC_RISCV_OPTS_H */
diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index 989a9f1..9b83da0 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -3110,7 +3110,7 @@ riscv_legitimize_call_address (rtx addr)
{
if (!call_insn_operand (addr, VOIDmode))
{
- rtx reg = RISCV_PROLOGUE_TEMP (Pmode);
+ rtx reg = RISCV_CALL_ADDRESS_TEMP (Pmode);
riscv_emit_move (reg, addr);
return reg;
}
@@ -3707,18 +3707,18 @@ riscv_compute_frame_info (void)
{
struct riscv_frame_info *frame;
HOST_WIDE_INT offset;
- bool interrupt_save_t1 = false;
+ bool interrupt_save_prologue_temp = false;
unsigned int regno, i, num_x_saved = 0, num_f_saved = 0;
frame = &cfun->machine->frame;
/* In an interrupt function, if we have a large frame, then we need to
- save/restore t1. We check for this before clearing the frame struct. */
+ save/restore t0. We check for this before clearing the frame struct. */
if (cfun->machine->interrupt_handler_p)
{
HOST_WIDE_INT step1 = riscv_first_stack_step (frame);
if (! SMALL_OPERAND (frame->total_size - step1))
- interrupt_save_t1 = true;
+ interrupt_save_prologue_temp = true;
}
memset (frame, 0, sizeof (*frame));
@@ -3728,7 +3728,8 @@ riscv_compute_frame_info (void)
/* Find out which GPRs we need to save. */
for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
if (riscv_save_reg_p (regno)
- || (interrupt_save_t1 && (regno == T1_REGNUM)))
+ || (interrupt_save_prologue_temp
+ && (regno == RISCV_PROLOGUE_TEMP_REGNUM)))
frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++;
/* If this function calls eh_return, we must also save and restore the
@@ -4902,9 +4903,9 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
rtx target_function = force_reg (Pmode, XEXP (DECL_RTL (fndecl), 0));
/* lui t2, hi(chain)
- lui t1, hi(func)
+ lui t0, hi(func)
addi t2, t2, lo(chain)
- jr r1, lo(func)
+ jr t0, lo(func)
*/
unsigned HOST_WIDE_INT lui_hi_chain_code, lui_hi_func_code;
unsigned HOST_WIDE_INT lo_chain_code, lo_func_code;
@@ -4929,7 +4930,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
mem = adjust_address (m_tramp, SImode, 0);
riscv_emit_move (mem, lui_hi_chain);
- /* Gen lui t1, hi(func). */
+ /* Gen lui t0, hi(func). */
rtx hi_func = riscv_force_binary (SImode, PLUS, target_function,
fixup_value);
hi_func = riscv_force_binary (SImode, AND, hi_func,
@@ -4956,7 +4957,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
mem = adjust_address (m_tramp, SImode, 2 * GET_MODE_SIZE (SImode));
riscv_emit_move (mem, addi_lo_chain);
- /* Gen jr r1, lo(func). */
+ /* Gen jr t0, lo(func). */
rtx lo_func = riscv_force_binary (SImode, AND, target_function,
imm12_mask);
lo_func = riscv_force_binary (SImode, ASHIFT, lo_func, GEN_INT (20));
@@ -4975,9 +4976,9 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
target_function_offset = static_chain_offset + GET_MODE_SIZE (ptr_mode);
/* auipc t2, 0
- l[wd] t1, target_function_offset(t2)
+ l[wd] t0, target_function_offset(t2)
l[wd] t2, static_chain_offset(t2)
- jr t1
+ jr t0
*/
trampoline[0] = OPCODE_AUIPC | (STATIC_CHAIN_REGNUM << SHIFT_RD);
trampoline[1] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW)
@@ -5299,6 +5300,19 @@ riscv_gpr_save_operation_p (rtx op)
return true;
}
+/* Implement TARGET_ASAN_SHADOW_OFFSET. */
+
+static unsigned HOST_WIDE_INT
+riscv_asan_shadow_offset (void)
+{
+ /* We only have libsanitizer support for RV64 at present.
+
+ This number must match kRiscv*_ShadowOffset* in the file
+ libsanitizer/asan/asan_mapping.h which is currently 1<<29 for rv64,
+ even though 1<<36 makes more sense. */
+ return TARGET_64BIT ? (HOST_WIDE_INT_1 << 29) : 0;
+}
+
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
@@ -5482,6 +5496,9 @@ riscv_gpr_save_operation_p (rtx op)
#undef TARGET_NEW_ADDRESS_PROFITABLE_P
#define TARGET_NEW_ADDRESS_PROFITABLE_P riscv_new_address_profitable_p
+#undef TARGET_ASAN_SHADOW_OFFSET
+#define TARGET_ASAN_SHADOW_OFFSET riscv_asan_shadow_offset
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-riscv.h"
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 172c7ca..df3003f 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -70,13 +70,29 @@ extern const char *riscv_default_mtune (int argc, const char **argv);
#define TARGET_64BIT (__riscv_xlen == 64)
#endif /* IN_LIBGCC2 */
+#ifdef HAVE_AS_MISA_SPEC
+#define ASM_MISA_SPEC "%{misa-spec=*}"
+#else
+#define ASM_MISA_SPEC ""
+#endif
+
+/* Reference:
+ https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html#Stringizing */
+#define STRINGIZING(s) __STRINGIZING(s)
+#define __STRINGIZING(s) #s
+
+#define MULTILIB_DEFAULTS \
+ {"march=" STRINGIZING (TARGET_RISCV_DEFAULT_ARCH), \
+ "mabi=" STRINGIZING (TARGET_RISCV_DEFAULT_ABI) }
+
#undef ASM_SPEC
#define ASM_SPEC "\
%(subtarget_asm_debugging_spec) \
%{" FPIE_OR_FPIC_SPEC ":-fpic} \
%{march=*} \
%{mabi=*} \
-%(subtarget_asm_spec)"
+%(subtarget_asm_spec)" \
+ASM_MISA_SPEC
#undef DRIVER_SELF_SPECS
#define DRIVER_SELF_SPECS \
@@ -342,9 +358,13 @@ extern const char *riscv_default_mtune (int argc, const char **argv);
The epilogue temporary mustn't conflict with the return registers,
the frame pointer, the EH stack adjustment, or the EH data registers. */
-#define RISCV_PROLOGUE_TEMP_REGNUM (GP_TEMP_FIRST + 1)
+#define RISCV_PROLOGUE_TEMP_REGNUM (GP_TEMP_FIRST)
#define RISCV_PROLOGUE_TEMP(MODE) gen_rtx_REG (MODE, RISCV_PROLOGUE_TEMP_REGNUM)
+#define RISCV_CALL_ADDRESS_TEMP_REGNUM (GP_TEMP_FIRST + 1)
+#define RISCV_CALL_ADDRESS_TEMP(MODE) \
+ gen_rtx_REG (MODE, RISCV_CALL_ADDRESS_TEMP_REGNUM)
+
#define MCOUNT_NAME "_mcount"
#define NO_PROFILE_COUNTERS 1
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index f15bad3..254147c 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -1543,7 +1543,8 @@
LCT_NORMAL, VOIDmode, operands[0], Pmode,
operands[1], Pmode, const0_rtx, Pmode);
#else
- emit_insn (gen_fence_i ());
+ if (TARGET_ZIFENCEI)
+ emit_insn (gen_fence_i ());
#endif
DONE;
})
@@ -1555,7 +1556,7 @@
(define_insn "fence_i"
[(unspec_volatile [(const_int 0)] UNSPECV_FENCE_I)]
- ""
+ "TARGET_ZIFENCEI"
"fence.i")
;;
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 808b4a0..9cf14bb 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -183,3 +183,23 @@ Use the given offset for addressing the stack-protector guard.
TargetVariable
long riscv_stack_protector_guard_offset = 0
+
+TargetVariable
+int riscv_zi_subext
+
+Enum
+Name(isa_spec_class) Type(enum riscv_isa_spec_class)
+Supported ISA specs (for use with the -misa-spec= option):
+
+EnumValue
+Enum(isa_spec_class) String(2.2) Value(ISA_SPEC_CLASS_2P2)
+
+EnumValue
+Enum(isa_spec_class) String(20190608) Value(ISA_SPEC_CLASS_20190608)
+
+EnumValue
+Enum(isa_spec_class) String(20191213) Value(ISA_SPEC_CLASS_20191213)
+
+misa-spec=
+Target Report RejectNegative Joined Enum(isa_spec_class) Var(riscv_isa_spec) Init(TARGET_DEFAULT_ISA_SPEC)
+Set the version of RISC-V ISA spec.
diff --git a/gcc/config/riscv/withmultilib.h b/gcc/config/riscv/withmultilib.h
deleted file mode 100644
index d022716..0000000
--- a/gcc/config/riscv/withmultilib.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* MULTILIB_DEFAULTS definitions for --with-multilib-list.
- Copyright (C) 2018-2020 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.
-
- 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/>. */
-
-#if TARGET_MLIB_ARCH == 1
-
-# if TARGET_MLIB_ABI == 1
-# define MULTILIB_DEFAULTS {"march=rv32gc", "mabi=ilp32" }
-# elif TARGET_MLIB_ABI == 2
-# define MULTILIB_DEFAULTS {"march=rv32gc", "mabi=ilp32f" }
-# elif TARGET_MLIB_ABI == 3
-# define MULTILIB_DEFAULTS {"march=rv32gc", "mabi=ilp32d" }
-# else
-# error "unsupported TARGET_MLIB_ABI value for rv32gc"
-# endif
-
-#elif TARGET_MLIB_ARCH == 2
-
-# if TARGET_MLIB_ABI == 4
-# define MULTILIB_DEFAULTS {"march=rv64gc", "mabi=lp64" }
-# elif TARGET_MLIB_ABI == 5
-# define MULTILIB_DEFAULTS {"march=rv64gc", "mabi=lp64f" }
-# elif TARGET_MLIB_ABI == 6
-# define MULTILIB_DEFAULTS {"march=rv64gc", "mabi=lp64d" }
-# else
-# error "unsupported TARGET_MLIB_ABI value for rv64gc"
-# endif
-
-#else
-# error "unsupported TARGET_MLIB_ARCH value"
-#endif
diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md
index a3fd28b..4d291c4 100644
--- a/gcc/config/rs6000/mma.md
+++ b/gcc/config/rs6000/mma.md
@@ -19,24 +19,18 @@
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
-;; The MMA patterns use the multi-register PXImode and POImode partial
-;; integer modes to implement the target specific __vector_quad and
-;; __vector_pair types that the MMA built-in functions reference.
-;; To use these modes, we must define XImode and OImode move patterns
-;; so the independent parts of the compiler can use our large partial
-;; integer modes. However, if we enable the XImode and OImode move
-;; patterns, then the compiler will attempt to use them and this can
-;; cause byte swapping issues on litte-endian systems. We don't need
-;; the XImode and OImode move patterns for actual code generation,
-;; therefore, we define the XImode and OImode move patterns, but we
-;; disable their use with a "false" condition flag.
+;; The MMA patterns use the multi-register XOmode and OOmode opaque
+;; modes to implement the target specific __vector_quad and
+;; __vector_pair types that the MMA built-in functions reference. We
+;; use OPAQUE_MODE to prevent anything from trying to open them up.
(define_constants [(MAX_MMA_OPERANDS 7)])
;; Constants for creating unspecs
(define_c_enum "unspec"
- [UNSPEC_MMA_ASSEMBLE_ACC
+ [UNSPEC_MMA_ASSEMBLE
+ UNSPEC_MMA_EXTRACT
UNSPEC_MMA_PMXVBF16GER2
UNSPEC_MMA_PMXVBF16GER2NN
UNSPEC_MMA_PMXVBF16GER2NP
@@ -97,6 +91,7 @@
UNSPEC_MMA_XVI8GER4SPP
UNSPEC_MMA_XXMFACC
UNSPEC_MMA_XXMTACC
+ UNSPEC_MMA_XXSETACCZ
])
;; MMA instructions with 1 accumulator argument
@@ -265,31 +260,22 @@
(UNSPEC_MMA_PMXVI8GER4SPP "pmxvi8ger4spp")])
-;; Define a disabled OImode move pattern, so we can use POImode.
-(define_expand "movoi"
- [(set (match_operand:OI 0 "nonimmediate_operand")
- (match_operand:OI 1 "input_operand"))]
- "0"
-{
- gcc_unreachable ();
-})
-
-;; Vector pair support. POImode can only live in VSRs.
-(define_expand "movpoi"
- [(set (match_operand:POI 0 "nonimmediate_operand")
- (match_operand:POI 1 "input_operand"))]
+;; Vector pair support. OOmode can only live in VSRs.
+(define_expand "movoo"
+ [(set (match_operand:OO 0 "nonimmediate_operand")
+ (match_operand:OO 1 "input_operand"))]
"TARGET_MMA"
{
- rs6000_emit_move (operands[0], operands[1], POImode);
+ rs6000_emit_move (operands[0], operands[1], OOmode);
DONE;
})
-(define_insn_and_split "*movpoi"
- [(set (match_operand:POI 0 "nonimmediate_operand" "=wa,m,wa")
- (match_operand:POI 1 "input_operand" "m,wa,wa"))]
+(define_insn_and_split "*movoo"
+ [(set (match_operand:OO 0 "nonimmediate_operand" "=wa,m,wa")
+ (match_operand:OO 1 "input_operand" "m,wa,wa"))]
"TARGET_MMA
- && (gpc_reg_operand (operands[0], POImode)
- || gpc_reg_operand (operands[1], POImode))"
+ && (gpc_reg_operand (operands[0], OOmode)
+ || gpc_reg_operand (operands[1], OOmode))"
"@
lxvp%X1 %x0,%1
stxvp%X0 %x1,%0
@@ -305,287 +291,370 @@
(set_attr "length" "*,*,8")])
-;; Define a disabled XImode move pattern, so we can use PXImode.
-(define_expand "movxi"
- [(set (match_operand:XI 0 "nonimmediate_operand")
- (match_operand:XI 1 "input_operand"))]
- "0"
-{
- gcc_unreachable ();
-})
-
-;; Vector quad support. PXImode can only live in FPRs.
-(define_expand "movpxi"
- [(set (match_operand:PXI 0 "nonimmediate_operand")
- (match_operand:PXI 1 "input_operand"))]
+;; Vector quad support. XOmode can only live in FPRs.
+(define_expand "movxo"
+ [(set (match_operand:XO 0 "nonimmediate_operand")
+ (match_operand:XO 1 "input_operand"))]
"TARGET_MMA"
{
- rs6000_emit_move (operands[0], operands[1], PXImode);
+ rs6000_emit_move (operands[0], operands[1], XOmode);
DONE;
})
-(define_insn_and_split "*movpxi"
- [(set (match_operand:PXI 0 "nonimmediate_operand" "=d,m,d,d")
- (match_operand:PXI 1 "input_operand" "m,d,d,O"))]
+(define_insn_and_split "*movxo"
+ [(set (match_operand:XO 0 "nonimmediate_operand" "=d,m,d")
+ (match_operand:XO 1 "input_operand" "m,d,d"))]
"TARGET_MMA
- && (gpc_reg_operand (operands[0], PXImode)
- || gpc_reg_operand (operands[1], PXImode))"
+ && (gpc_reg_operand (operands[0], XOmode)
+ || gpc_reg_operand (operands[1], XOmode))"
"@
#
#
- #
- xxsetaccz %A0"
- "&& reload_completed
- && !(fpr_reg_operand (operands[0], PXImode) && operands[1] == const0_rtx)"
+ #"
+ "&& reload_completed"
[(const_int 0)]
{
rs6000_split_multireg_move (operands[0], operands[1]);
DONE;
}
- [(set_attr "type" "vecload,vecstore,veclogical,mma")
- (set_attr "length" "8,8,16,*")
- (set_attr "max_prefixed_insns" "2,2,*,*")])
+ [(set_attr "type" "vecload,vecstore,veclogical")
+ (set_attr "length" "8,8,16")
+ (set_attr "max_prefixed_insns" "2,2,*")])
(define_expand "mma_assemble_pair"
- [(match_operand:POI 0 "vsx_register_operand")
- (match_operand:V16QI 1 "input_operand")
- (match_operand:V16QI 2 "input_operand")]
+ [(match_operand:OO 0 "vsx_register_operand")
+ (match_operand:V16QI 1 "mma_assemble_input_operand")
+ (match_operand:V16QI 2 "mma_assemble_input_operand")]
"TARGET_MMA"
{
- rtx dst;
+ rtx src = gen_rtx_UNSPEC (OOmode,
+ gen_rtvec (2, operands[1], operands[2]),
+ UNSPEC_MMA_ASSEMBLE);
+ emit_move_insn (operands[0], src);
+ DONE;
+})
- /* Let the compiler know the code below fully defines our output value. */
- emit_clobber (operands[0]);
+(define_insn_and_split "*mma_assemble_pair"
+ [(set (match_operand:OO 0 "vsx_register_operand" "=wa")
+ (unspec:OO [(match_operand:V16QI 1 "mma_assemble_input_operand" "mwa")
+ (match_operand:V16QI 2 "mma_assemble_input_operand" "mwa")]
+ UNSPEC_MMA_ASSEMBLE))]
+ "TARGET_MMA"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ rtx src = gen_rtx_UNSPEC (OOmode,
+ gen_rtvec (2, operands[1], operands[2]),
+ UNSPEC_MMA_ASSEMBLE);
+ rs6000_split_multireg_move (operands[0], src);
+ DONE;
+})
+
+(define_expand "mma_disassemble_pair"
+ [(match_operand:V16QI 0 "mma_disassemble_output_operand")
+ (match_operand:OO 1 "vsx_register_operand")
+ (match_operand 2 "const_0_to_1_operand")]
+ "TARGET_MMA"
+{
+ rtx src;
+ int regoff = INTVAL (operands[2]);
+ src = gen_rtx_UNSPEC (V16QImode,
+ gen_rtvec (2, operands[1], GEN_INT (regoff)),
+ UNSPEC_MMA_EXTRACT);
+ emit_move_insn (operands[0], src);
+ DONE;
+})
- dst = simplify_gen_subreg (V16QImode, operands[0], POImode, 0);
- emit_move_insn (dst, operands[1]);
- dst = simplify_gen_subreg (V16QImode, operands[0], POImode, 16);
- emit_move_insn (dst, operands[2]);
+(define_insn_and_split "*mma_disassemble_pair"
+ [(set (match_operand:V16QI 0 "mma_disassemble_output_operand" "=mwa")
+ (unspec:V16QI [(match_operand:OO 1 "vsx_register_operand" "wa")
+ (match_operand 2 "const_0_to_1_operand")]
+ UNSPEC_MMA_EXTRACT))]
+ "TARGET_MMA
+ && vsx_register_operand (operands[1], OOmode)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ int reg = REGNO (operands[1]);
+ int regoff = INTVAL (operands[2]);
+ rtx src = gen_rtx_REG (V16QImode, reg + regoff);
+ emit_move_insn (operands[0], src);
DONE;
})
(define_expand "mma_assemble_acc"
- [(match_operand:PXI 0 "fpr_reg_operand")
- (match_operand:V16QI 1 "input_operand")
- (match_operand:V16QI 2 "input_operand")
- (match_operand:V16QI 3 "input_operand")
- (match_operand:V16QI 4 "input_operand")]
+ [(match_operand:XO 0 "fpr_reg_operand")
+ (match_operand:V16QI 1 "mma_assemble_input_operand")
+ (match_operand:V16QI 2 "mma_assemble_input_operand")
+ (match_operand:V16QI 3 "mma_assemble_input_operand")
+ (match_operand:V16QI 4 "mma_assemble_input_operand")]
"TARGET_MMA"
{
- rtx src = gen_rtx_UNSPEC (PXImode,
+ rtx src = gen_rtx_UNSPEC (XOmode,
gen_rtvec (4, operands[1], operands[2],
operands[3], operands[4]),
- UNSPEC_MMA_ASSEMBLE_ACC);
+ UNSPEC_MMA_ASSEMBLE);
emit_move_insn (operands[0], src);
DONE;
})
(define_insn_and_split "*mma_assemble_acc"
- [(set (match_operand:PXI 0 "fpr_reg_operand" "=d")
- (unspec:PXI [(match_operand:V16QI 1 "mma_assemble_input_operand" "mwa")
- (match_operand:V16QI 2 "mma_assemble_input_operand" "mwa")
- (match_operand:V16QI 3 "mma_assemble_input_operand" "mwa")
- (match_operand:V16QI 4 "mma_assemble_input_operand" "mwa")]
- UNSPEC_MMA_ASSEMBLE_ACC))]
+ [(set (match_operand:XO 0 "fpr_reg_operand" "=d")
+ (unspec:XO [(match_operand:V16QI 1 "mma_assemble_input_operand" "mwa")
+ (match_operand:V16QI 2 "mma_assemble_input_operand" "mwa")
+ (match_operand:V16QI 3 "mma_assemble_input_operand" "mwa")
+ (match_operand:V16QI 4 "mma_assemble_input_operand" "mwa")]
+ UNSPEC_MMA_ASSEMBLE))]
"TARGET_MMA
- && fpr_reg_operand (operands[0], PXImode)"
+ && fpr_reg_operand (operands[0], XOmode)"
"#"
"&& reload_completed"
[(const_int 0)]
{
- rtx src = gen_rtx_UNSPEC (PXImode,
+ rtx src = gen_rtx_UNSPEC (XOmode,
gen_rtvec (4, operands[1], operands[2],
operands[3], operands[4]),
- UNSPEC_MMA_ASSEMBLE_ACC);
+ UNSPEC_MMA_ASSEMBLE);
rs6000_split_multireg_move (operands[0], src);
DONE;
})
+(define_expand "mma_disassemble_acc"
+ [(match_operand:V16QI 0 "mma_disassemble_output_operand")
+ (match_operand:XO 1 "fpr_reg_operand")
+ (match_operand 2 "const_0_to_3_operand")]
+ "TARGET_MMA"
+{
+ rtx src;
+ int regoff = INTVAL (operands[2]);
+ src = gen_rtx_UNSPEC (V16QImode,
+ gen_rtvec (2, operands[1], GEN_INT (regoff)),
+ UNSPEC_MMA_EXTRACT);
+ emit_move_insn (operands[0], src);
+ DONE;
+})
+
+(define_insn_and_split "*mma_disassemble_acc"
+ [(set (match_operand:V16QI 0 "mma_disassemble_output_operand" "=mwa")
+ (unspec:V16QI [(match_operand:XO 1 "fpr_reg_operand" "d")
+ (match_operand 2 "const_0_to_3_operand")]
+ UNSPEC_MMA_EXTRACT))]
+ "TARGET_MMA
+ && fpr_reg_operand (operands[1], XOmode)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ int reg = REGNO (operands[1]);
+ int regoff = INTVAL (operands[2]);
+ rtx src = gen_rtx_REG (V16QImode, reg + regoff);
+ emit_move_insn (operands[0], src);
+ DONE;
+})
+
;; MMA instructions that do not use their accumulators as an input, still
;; must not allow their vector operands to overlap the registers used by
;; the accumulator. We enforce this by marking the output as early clobber.
(define_insn "mma_<acc>"
- [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d")
- (unspec:PXI [(match_operand:PXI 1 "fpr_reg_operand" "0")]
+ [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
+ (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")]
MMA_ACC))]
"TARGET_MMA"
"<acc> %A0"
[(set_attr "type" "mma")])
+;; We can't have integer constants in XOmode so we wrap this in an UNSPEC.
+
(define_expand "mma_xxsetaccz"
- [(set (match_operand:PXI 0 "fpr_reg_operand")
+ [(set (match_operand:XO 0 "fpr_reg_operand")
(const_int 0))]
"TARGET_MMA"
{
- emit_insn (gen_movpxi (operands[0], const0_rtx));
+ rtx xo0 = gen_rtx_UNSPEC (XOmode, gen_rtvec (1, const0_rtx),
+ UNSPEC_MMA_XXSETACCZ);
+ emit_insn (gen_rtx_SET (operands[0], xo0));
DONE;
})
+(define_insn_and_split "*mma_xxsetaccz"
+ [(set (match_operand:XO 0 "fpr_reg_operand" "=d")
+ (unspec:XO [(match_operand 1 "const_0_to_1_operand" "O")]
+ UNSPEC_MMA_XXSETACCZ))]
+ "TARGET_MMA"
+ "xxsetaccz %A0"
+ "&& reload_completed"
+ [(set (match_dup 0) (unspec:XO [(match_dup 1)] UNSPEC_MMA_XXSETACCZ))]
+ ""
+ [(set_attr "type" "mma")
+ (set_attr "length" "4")])
+
(define_insn "mma_<vv>"
- [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d")
- (unspec:PXI [(match_operand:V16QI 1 "vsx_register_operand" "wa")
- (match_operand:V16QI 2 "vsx_register_operand" "wa")]
- MMA_VV))]
+ [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
+ (unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "wa")
+ (match_operand:V16QI 2 "vsx_register_operand" "wa")]
+ MMA_VV))]
"TARGET_MMA"
"<vv> %A0,%x1,%x2"
[(set_attr "type" "mma")])
(define_insn "mma_<avv>"
- [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d")
- (unspec:PXI [(match_operand:PXI 1 "fpr_reg_operand" "0")
- (match_operand:V16QI 2 "vsx_register_operand" "wa")
- (match_operand:V16QI 3 "vsx_register_operand" "wa")]
- MMA_AVV))]
+ [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
+ (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")
+ (match_operand:V16QI 2 "vsx_register_operand" "wa")
+ (match_operand:V16QI 3 "vsx_register_operand" "wa")]
+ MMA_AVV))]
"TARGET_MMA"
"<avv> %A0,%x2,%x3"
[(set_attr "type" "mma")])
(define_insn "mma_<pv>"
- [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d")
- (unspec:PXI [(match_operand:POI 1 "vsx_register_operand" "wa")
- (match_operand:V16QI 2 "vsx_register_operand" "wa")]
- MMA_PV))]
+ [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
+ (unspec:XO [(match_operand:OO 1 "vsx_register_operand" "wa")
+ (match_operand:V16QI 2 "vsx_register_operand" "wa")]
+ MMA_PV))]
"TARGET_MMA"
"<pv> %A0,%x1,%x2"
[(set_attr "type" "mma")])
(define_insn "mma_<apv>"
- [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d")
- (unspec:PXI [(match_operand:PXI 1 "fpr_reg_operand" "0")
- (match_operand:POI 2 "vsx_register_operand" "wa")
- (match_operand:V16QI 3 "vsx_register_operand" "wa")]
- MMA_APV))]
+ [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
+ (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")
+ (match_operand:OO 2 "vsx_register_operand" "wa")
+ (match_operand:V16QI 3 "vsx_register_operand" "wa")]
+ MMA_APV))]
"TARGET_MMA"
"<apv> %A0,%x2,%x3"
[(set_attr "type" "mma")])
(define_insn "mma_<vvi4i4i8>"
- [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d")
- (unspec:PXI [(match_operand:V16QI 1 "vsx_register_operand" "wa")
- (match_operand:V16QI 2 "vsx_register_operand" "wa")
- (match_operand:SI 3 "const_0_to_15_operand" "n")
- (match_operand:SI 4 "const_0_to_15_operand" "n")
- (match_operand:SI 5 "u8bit_cint_operand" "n")]
- MMA_VVI4I4I8))]
+ [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
+ (unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "wa")
+ (match_operand:V16QI 2 "vsx_register_operand" "wa")
+ (match_operand:SI 3 "const_0_to_15_operand" "n")
+ (match_operand:SI 4 "const_0_to_15_operand" "n")
+ (match_operand:SI 5 "u8bit_cint_operand" "n")]
+ MMA_VVI4I4I8))]
"TARGET_MMA"
"<vvi4i4i8> %A0,%x1,%x2,%3,%4,%5"
[(set_attr "type" "mma")
(set_attr "length" "8")])
(define_insn "mma_<avvi4i4i8>"
- [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d")
- (unspec:PXI [(match_operand:PXI 1 "fpr_reg_operand" "0")
- (match_operand:V16QI 2 "vsx_register_operand" "wa")
- (match_operand:V16QI 3 "vsx_register_operand" "wa")
- (match_operand:SI 4 "const_0_to_15_operand" "n")
- (match_operand:SI 5 "const_0_to_15_operand" "n")
- (match_operand:SI 6 "u8bit_cint_operand" "n")]
- MMA_AVVI4I4I8))]
+ [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
+ (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")
+ (match_operand:V16QI 2 "vsx_register_operand" "wa")
+ (match_operand:V16QI 3 "vsx_register_operand" "wa")
+ (match_operand:SI 4 "const_0_to_15_operand" "n")
+ (match_operand:SI 5 "const_0_to_15_operand" "n")
+ (match_operand:SI 6 "u8bit_cint_operand" "n")]
+ MMA_AVVI4I4I8))]
"TARGET_MMA"
"<avvi4i4i8> %A0,%x2,%x3,%4,%5,%6"
[(set_attr "type" "mma")
(set_attr "length" "8")])
(define_insn "mma_<vvi4i4i2>"
- [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d")
- (unspec:PXI [(match_operand:V16QI 1 "vsx_register_operand" "wa")
- (match_operand:V16QI 2 "vsx_register_operand" "wa")
- (match_operand:SI 3 "const_0_to_15_operand" "n")
- (match_operand:SI 4 "const_0_to_15_operand" "n")
- (match_operand:SI 5 "const_0_to_3_operand" "n")]
- MMA_VVI4I4I2))]
+ [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
+ (unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "wa")
+ (match_operand:V16QI 2 "vsx_register_operand" "wa")
+ (match_operand:SI 3 "const_0_to_15_operand" "n")
+ (match_operand:SI 4 "const_0_to_15_operand" "n")
+ (match_operand:SI 5 "const_0_to_3_operand" "n")]
+ MMA_VVI4I4I2))]
"TARGET_MMA"
"<vvi4i4i2> %A0,%x1,%x2,%3,%4,%5"
[(set_attr "type" "mma")
(set_attr "length" "8")])
(define_insn "mma_<avvi4i4i2>"
- [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d")
- (unspec:PXI [(match_operand:PXI 1 "fpr_reg_operand" "0")
- (match_operand:V16QI 2 "vsx_register_operand" "wa")
- (match_operand:V16QI 3 "vsx_register_operand" "wa")
- (match_operand:SI 4 "const_0_to_15_operand" "n")
- (match_operand:SI 5 "const_0_to_15_operand" "n")
- (match_operand:SI 6 "const_0_to_3_operand" "n")]
- MMA_AVVI4I4I2))]
+ [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
+ (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")
+ (match_operand:V16QI 2 "vsx_register_operand" "wa")
+ (match_operand:V16QI 3 "vsx_register_operand" "wa")
+ (match_operand:SI 4 "const_0_to_15_operand" "n")
+ (match_operand:SI 5 "const_0_to_15_operand" "n")
+ (match_operand:SI 6 "const_0_to_3_operand" "n")]
+ MMA_AVVI4I4I2))]
"TARGET_MMA"
"<avvi4i4i2> %A0,%x2,%x3,%4,%5,%6"
[(set_attr "type" "mma")
(set_attr "length" "8")])
(define_insn "mma_<vvi4i4>"
- [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d")
- (unspec:PXI [(match_operand:V16QI 1 "vsx_register_operand" "wa")
- (match_operand:V16QI 2 "vsx_register_operand" "wa")
- (match_operand:SI 3 "const_0_to_15_operand" "n")
- (match_operand:SI 4 "const_0_to_15_operand" "n")]
- MMA_VVI4I4))]
+ [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
+ (unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "wa")
+ (match_operand:V16QI 2 "vsx_register_operand" "wa")
+ (match_operand:SI 3 "const_0_to_15_operand" "n")
+ (match_operand:SI 4 "const_0_to_15_operand" "n")]
+ MMA_VVI4I4))]
"TARGET_MMA"
"<vvi4i4> %A0,%x1,%x2,%3,%4"
[(set_attr "type" "mma")
(set_attr "length" "8")])
(define_insn "mma_<avvi4i4>"
- [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d")
- (unspec:PXI [(match_operand:PXI 1 "fpr_reg_operand" "0")
- (match_operand:V16QI 2 "vsx_register_operand" "wa")
- (match_operand:V16QI 3 "vsx_register_operand" "wa")
- (match_operand:SI 4 "const_0_to_15_operand" "n")
- (match_operand:SI 5 "const_0_to_15_operand" "n")]
- MMA_AVVI4I4))]
+ [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
+ (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")
+ (match_operand:V16QI 2 "vsx_register_operand" "wa")
+ (match_operand:V16QI 3 "vsx_register_operand" "wa")
+ (match_operand:SI 4 "const_0_to_15_operand" "n")
+ (match_operand:SI 5 "const_0_to_15_operand" "n")]
+ MMA_AVVI4I4))]
"TARGET_MMA"
"<avvi4i4> %A0,%x2,%x3,%4,%5"
[(set_attr "type" "mma")
(set_attr "length" "8")])
(define_insn "mma_<pvi4i2>"
- [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d")
- (unspec:PXI [(match_operand:POI 1 "vsx_register_operand" "wa")
- (match_operand:V16QI 2 "vsx_register_operand" "wa")
- (match_operand:SI 3 "const_0_to_15_operand" "n")
- (match_operand:SI 4 "const_0_to_3_operand" "n")]
- MMA_PVI4I2))]
+ [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
+ (unspec:XO [(match_operand:OO 1 "vsx_register_operand" "wa")
+ (match_operand:V16QI 2 "vsx_register_operand" "wa")
+ (match_operand:SI 3 "const_0_to_15_operand" "n")
+ (match_operand:SI 4 "const_0_to_3_operand" "n")]
+ MMA_PVI4I2))]
"TARGET_MMA"
"<pvi4i2> %A0,%x1,%x2,%3,%4"
[(set_attr "type" "mma")
(set_attr "length" "8")])
(define_insn "mma_<apvi4i2>"
- [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d")
- (unspec:PXI [(match_operand:PXI 1 "fpr_reg_operand" "0")
- (match_operand:POI 2 "vsx_register_operand" "wa")
- (match_operand:V16QI 3 "vsx_register_operand" "wa")
- (match_operand:SI 4 "const_0_to_15_operand" "n")
- (match_operand:SI 5 "const_0_to_3_operand" "n")]
- MMA_APVI4I2))]
+ [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
+ (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")
+ (match_operand:OO 2 "vsx_register_operand" "wa")
+ (match_operand:V16QI 3 "vsx_register_operand" "wa")
+ (match_operand:SI 4 "const_0_to_15_operand" "n")
+ (match_operand:SI 5 "const_0_to_3_operand" "n")]
+ MMA_APVI4I2))]
"TARGET_MMA"
"<apvi4i2> %A0,%x2,%x3,%4,%5"
[(set_attr "type" "mma")
(set_attr "length" "8")])
(define_insn "mma_<vvi4i4i4>"
- [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d")
- (unspec:PXI [(match_operand:V16QI 1 "vsx_register_operand" "wa")
- (match_operand:V16QI 2 "vsx_register_operand" "wa")
- (match_operand:SI 3 "const_0_to_15_operand" "n")
- (match_operand:SI 4 "const_0_to_15_operand" "n")
- (match_operand:SI 5 "const_0_to_15_operand" "n")]
- MMA_VVI4I4I4))]
+ [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
+ (unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "wa")
+ (match_operand:V16QI 2 "vsx_register_operand" "wa")
+ (match_operand:SI 3 "const_0_to_15_operand" "n")
+ (match_operand:SI 4 "const_0_to_15_operand" "n")
+ (match_operand:SI 5 "const_0_to_15_operand" "n")]
+ MMA_VVI4I4I4))]
"TARGET_MMA"
"<vvi4i4i4> %A0,%x1,%x2,%3,%4,%5"
[(set_attr "type" "mma")
(set_attr "length" "8")])
(define_insn "mma_<avvi4i4i4>"
- [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d")
- (unspec:PXI [(match_operand:PXI 1 "fpr_reg_operand" "0")
- (match_operand:V16QI 2 "vsx_register_operand" "wa")
- (match_operand:V16QI 3 "vsx_register_operand" "wa")
- (match_operand:SI 4 "const_0_to_15_operand" "n")
- (match_operand:SI 5 "const_0_to_15_operand" "n")
- (match_operand:SI 6 "const_0_to_15_operand" "n")]
- MMA_AVVI4I4I4))]
+ [(set (match_operand:XO 0 "fpr_reg_operand" "=&d")
+ (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")
+ (match_operand:V16QI 2 "vsx_register_operand" "wa")
+ (match_operand:V16QI 3 "vsx_register_operand" "wa")
+ (match_operand:SI 4 "const_0_to_15_operand" "n")
+ (match_operand:SI 5 "const_0_to_15_operand" "n")
+ (match_operand:SI 6 "const_0_to_15_operand" "n")]
+ MMA_AVVI4I4I4))]
"TARGET_MMA"
"<avvi4i4i4> %A0,%x2,%x3,%4,%5,%6"
[(set_attr "type" "mma")
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 4c2fe7f..9ad5ae6 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -1144,6 +1144,18 @@
(match_test "(mode == V16QImode
&& (vsx_register_operand (op, mode) || MEM_P (op)))"))
+;; Return 1 if this operand is valid for an MMA disassemble insn.
+(define_predicate "mma_disassemble_output_operand"
+ (match_code "reg,subreg,mem")
+{
+ if (SUBREG_P (op))
+ op = SUBREG_REG (op);
+ if (!REG_P (op))
+ return true;
+
+ return vsx_register_operand (op, mode);
+})
+
;; Return true if operand is an operator used in rotate-and-mask instructions.
(define_predicate "rotate_mask_operator"
(match_code "rotate,ashift,lshiftrt"))
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index a58102c..47b1f74 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -352,7 +352,7 @@
| RS6000_BTC_UNARY), \
CODE_FOR_ ## ICODE) /* ICODE */
-#define BU_MMA_V2(ENUM, NAME, ATTR, ICODE) \
+#define BU_MMA_2(ENUM, NAME, ATTR, ICODE) \
RS6000_BUILTIN_M (MMA_BUILTIN_ ## ENUM, /* ENUM */ \
"__builtin_mma_" NAME, /* NAME */ \
RS6000_BTM_MMA, /* MASK */ \
@@ -360,7 +360,13 @@
| RS6000_BTC_BINARY \
| RS6000_BTC_VOID \
| RS6000_BTC_GIMPLE), \
- CODE_FOR_nothing) /* ICODE */
+ CODE_FOR_nothing) /* ICODE */ \
+ RS6000_BUILTIN_M (MMA_BUILTIN_ ## ENUM ## _INTERNAL, /* ENUM */ \
+ "__builtin_mma_" NAME "_internal", /* NAME */ \
+ RS6000_BTM_MMA, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_BINARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
#define BU_MMA_3(ENUM, NAME, ATTR, ICODE) \
RS6000_BUILTIN_M (MMA_BUILTIN_ ## ENUM, /* ENUM */ \
@@ -3108,8 +3114,8 @@ BU_MMA_1 (XXMFACC, "xxmfacc", QUAD, mma_xxmfacc)
BU_MMA_1 (XXMTACC, "xxmtacc", QUAD, mma_xxmtacc)
BU_MMA_1 (XXSETACCZ, "xxsetaccz", MISC, mma_xxsetaccz)
-BU_MMA_V2 (DISASSEMBLE_ACC, "disassemble_acc", QUAD, nothing)
-BU_MMA_V2 (DISASSEMBLE_PAIR,"disassemble_pair", PAIR, nothing)
+BU_MMA_2 (DISASSEMBLE_ACC, "disassemble_acc", QUAD, mma_disassemble_acc)
+BU_MMA_2 (DISASSEMBLE_PAIR,"disassemble_pair", PAIR, mma_disassemble_pair)
BU_MMA_3 (ASSEMBLE_PAIR, "assemble_pair", MISC, mma_assemble_pair)
BU_MMA_3 (XVBF16GER2, "xvbf16ger2", MISC, mma_xvbf16ger2)
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 3bd89a7..45bc048 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -6325,6 +6325,22 @@ rs6000_discover_homogeneous_aggregate (machine_mode mode, const_tree type,
bool
rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
{
+ /* We do not allow MMA types being used as return values. Only report
+ the invalid return value usage the first time we encounter it. */
+ if (cfun
+ && !cfun->machine->mma_return_type_error
+ && TREE_TYPE (cfun->decl) == fntype
+ && (TYPE_MODE (type) == OOmode || TYPE_MODE (type) == XOmode))
+ {
+ /* Record we have now handled function CFUN, so the next time we
+ are called, we do not re-report the same error. */
+ cfun->machine->mma_return_type_error = true;
+ if (TYPE_CANONICAL (type) != NULL_TREE)
+ type = TYPE_CANONICAL (type);
+ error ("invalid use of MMA type %qs as a function return value",
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
+ }
+
/* For the Darwin64 ABI, test if we can fit the return value in regs. */
if (TARGET_MACHO
&& rs6000_darwin64_abi
@@ -6577,30 +6593,8 @@ machine_mode
rs6000_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
machine_mode mode,
int *punsignedp ATTRIBUTE_UNUSED,
- const_tree, int for_return)
+ const_tree, int for_return ATTRIBUTE_UNUSED)
{
- /* Warning: this is a static local variable and not always NULL!
- This function is called multiple times for the same function
- and return value. PREV_FUNC is used to keep track of the
- first time we encounter a function's return value in order
- to not report an error with that return value multiple times. */
- static struct function *prev_func = NULL;
-
- /* We do not allow MMA types being used as return values. Only report
- the invalid return value usage the first time we encounter it. */
- if (for_return
- && prev_func != cfun
- && (mode == POImode || mode == PXImode))
- {
- /* Record we have now handled function CFUN, so the next time we
- are called, we do not re-report the same error. */
- prev_func = cfun;
- if (TYPE_CANONICAL (type) != NULL_TREE)
- type = TYPE_CANONICAL (type);
- error ("invalid use of MMA type %qs as a function return value",
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
- }
-
PROMOTE_MODE (mode, *punsignedp, type);
return mode;
@@ -7552,7 +7546,7 @@ rs6000_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
int n_elts;
/* We do not allow MMA types being used as function arguments. */
- if (mode == POImode || mode == PXImode)
+ if (mode == OOmode || mode == XOmode)
{
if (TYPE_CANONICAL (type) != NULL_TREE)
type = TYPE_CANONICAL (type);
@@ -10073,7 +10067,8 @@ mma_expand_builtin (tree exp, rtx target, bool *expandedp)
}
unsigned attr_args = attr & RS6000_BTC_OPND_MASK;
- if (attr & RS6000_BTC_QUAD)
+ if (attr & RS6000_BTC_QUAD
+ || fcode == MMA_BUILTIN_DISASSEMBLE_PAIR_INTERNAL)
attr_args++;
gcc_assert (nopnds == attr_args);
@@ -10895,7 +10890,7 @@ altivec_expand_vec_set_builtin (tree exp)
op0 = force_reg (tmode, op0);
op1 = force_reg (mode1, op1);
- rs6000_expand_vector_set (op0, op1, elt);
+ rs6000_expand_vector_set (op0, op1, GEN_INT (elt));
return op0;
}
@@ -11687,23 +11682,24 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi)
gimple *new_call;
tree new_decl;
- if (rs6000_builtin_info[fncode + 1].icode == CODE_FOR_nothing)
+ if (fncode == MMA_BUILTIN_DISASSEMBLE_ACC
+ || fncode == MMA_BUILTIN_DISASSEMBLE_PAIR)
{
/* This is an MMA disassemble built-in function. */
- gcc_assert (fncode == MMA_BUILTIN_DISASSEMBLE_ACC
- || fncode == MMA_BUILTIN_DISASSEMBLE_PAIR);
-
push_gimplify_context (true);
+ unsigned nvec = (fncode == MMA_BUILTIN_DISASSEMBLE_ACC) ? 4 : 2;
tree dst_ptr = gimple_call_arg (stmt, 0);
tree src_ptr = gimple_call_arg (stmt, 1);
tree src_type = TREE_TYPE (src_ptr);
tree src = make_ssa_name (TREE_TYPE (src_type));
gimplify_assign (src, build_simple_mem_ref (src_ptr), &new_seq);
- /* If we are not disassembling an accumulator or our destination is
- another accumulator, then just copy the entire thing as is. */
- if (fncode != MMA_BUILTIN_DISASSEMBLE_ACC
- || TREE_TYPE (TREE_TYPE (dst_ptr)) == vector_quad_type_node)
+ /* If we are not disassembling an accumulator/pair or our destination is
+ another accumulator/pair, then just copy the entire thing as is. */
+ if ((fncode == MMA_BUILTIN_DISASSEMBLE_ACC
+ && TREE_TYPE (TREE_TYPE (dst_ptr)) == vector_quad_type_node)
+ || (fncode == MMA_BUILTIN_DISASSEMBLE_PAIR
+ && TREE_TYPE (TREE_TYPE (dst_ptr)) == vector_pair_type_node))
{
tree dst = build_simple_mem_ref (build1 (VIEW_CONVERT_EXPR,
src_type, dst_ptr));
@@ -11713,29 +11709,33 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi)
return true;
}
- /* We're disassembling an accumulator into a different type, so we need
+ /* If we're disassembling an accumulator into a different type, we need
to emit a xxmfacc instruction now, since we cannot do it later. */
- new_decl = rs6000_builtin_decls[MMA_BUILTIN_XXMFACC_INTERNAL];
- new_call = gimple_build_call (new_decl, 1, src);
- src = make_ssa_name (vector_quad_type_node);
- gimple_call_set_lhs (new_call, src);
- gimple_seq_add_stmt (&new_seq, new_call);
+ if (fncode == MMA_BUILTIN_DISASSEMBLE_ACC)
+ {
+ new_decl = rs6000_builtin_decls[MMA_BUILTIN_XXMFACC_INTERNAL];
+ new_call = gimple_build_call (new_decl, 1, src);
+ src = make_ssa_name (vector_quad_type_node);
+ gimple_call_set_lhs (new_call, src);
+ gimple_seq_add_stmt (&new_seq, new_call);
+ }
- /* Copy the accumulator vector by vector. */
+ /* Copy the accumulator/pair vector by vector. */
+ new_decl = rs6000_builtin_decls[fncode + 1];
tree dst_type = build_pointer_type_for_mode (unsigned_V16QI_type_node,
ptr_mode, true);
tree dst_base = build1 (VIEW_CONVERT_EXPR, dst_type, dst_ptr);
- tree array_type = build_array_type_nelts (unsigned_V16QI_type_node, 4);
- tree src_array = build1 (VIEW_CONVERT_EXPR, array_type, src);
- for (unsigned i = 0; i < 4; i++)
+ for (unsigned i = 0; i < nvec; i++)
{
- unsigned index = WORDS_BIG_ENDIAN ? i : 3 - i;
- tree ref = build4 (ARRAY_REF, unsigned_V16QI_type_node, src_array,
- build_int_cst (size_type_node, i),
- NULL_TREE, NULL_TREE);
+ unsigned index = WORDS_BIG_ENDIAN ? i : nvec - 1 - i;
tree dst = build2 (MEM_REF, unsigned_V16QI_type_node, dst_base,
build_int_cst (dst_type, index * 16));
- gimplify_assign (dst, ref, &new_seq);
+ tree dstssa = make_ssa_name (unsigned_V16QI_type_node);
+ new_call = gimple_build_call (new_decl, 2, src,
+ build_int_cstu (uint16_type_node, i));
+ gimple_call_set_lhs (new_call, dstssa);
+ gimple_seq_add_stmt (&new_seq, new_call);
+ gimplify_assign (dst, dstssa, &new_seq);
}
pop_gimplify_context (NULL);
gsi_replace_with_seq (gsi, new_seq, true);
@@ -12808,6 +12808,22 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
case CODE_FOR_xsiexpqp_kf: icode = CODE_FOR_xsiexpqp_tf; break;
case CODE_FOR_xsiexpqpf_kf: icode = CODE_FOR_xsiexpqpf_tf; break;
case CODE_FOR_xststdcqp_kf: icode = CODE_FOR_xststdcqp_tf; break;
+
+ case CODE_FOR_xscmpexpqp_eq_kf:
+ icode = CODE_FOR_xscmpexpqp_eq_tf;
+ break;
+
+ case CODE_FOR_xscmpexpqp_lt_kf:
+ icode = CODE_FOR_xscmpexpqp_lt_tf;
+ break;
+
+ case CODE_FOR_xscmpexpqp_gt_kf:
+ icode = CODE_FOR_xscmpexpqp_gt_tf;
+ break;
+
+ case CODE_FOR_xscmpexpqp_unordered_kf:
+ icode = CODE_FOR_xscmpexpqp_unordered_tf;
+ break;
}
if (TARGET_DEBUG_BUILTIN)
@@ -13190,17 +13206,23 @@ rs6000_init_builtins (void)
/* Vector pair and vector quad support. */
if (TARGET_EXTRA_BUILTINS)
{
- vector_pair_type_node = make_unsigned_type (256);
+ vector_pair_type_node = make_node (OPAQUE_TYPE);
+ SET_TYPE_MODE (vector_pair_type_node, OOmode);
+ TYPE_SIZE (vector_pair_type_node) = bitsize_int (GET_MODE_BITSIZE (OOmode));
+ TYPE_PRECISION (vector_pair_type_node) = GET_MODE_BITSIZE (OOmode);
+ TYPE_SIZE_UNIT (vector_pair_type_node) = size_int (GET_MODE_SIZE (OOmode));
SET_TYPE_ALIGN (vector_pair_type_node, 256);
- SET_TYPE_MODE (vector_pair_type_node, POImode);
- layout_type (vector_pair_type_node);
+ TYPE_USER_ALIGN (vector_pair_type_node) = 0;
lang_hooks.types.register_builtin_type (vector_pair_type_node,
"__vector_pair");
- vector_quad_type_node = make_unsigned_type (512);
+ vector_quad_type_node = make_node (OPAQUE_TYPE);
+ SET_TYPE_MODE (vector_quad_type_node, XOmode);
+ TYPE_SIZE (vector_quad_type_node) = bitsize_int (GET_MODE_BITSIZE (XOmode));
+ TYPE_PRECISION (vector_quad_type_node) = GET_MODE_BITSIZE (XOmode);
+ TYPE_SIZE_UNIT (vector_quad_type_node) = size_int (GET_MODE_SIZE (XOmode));
SET_TYPE_ALIGN (vector_quad_type_node, 512);
- SET_TYPE_MODE (vector_quad_type_node, PXImode);
- layout_type (vector_quad_type_node);
+ TYPE_USER_ALIGN (vector_quad_type_node) = 0;
lang_hooks.types.register_builtin_type (vector_quad_type_node,
"__vector_quad");
}
@@ -13236,8 +13258,8 @@ rs6000_init_builtins (void)
builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
- builtin_mode_to_type[POImode][1] = vector_pair_type_node;
- builtin_mode_to_type[PXImode][1] = vector_quad_type_node;
+ builtin_mode_to_type[OOmode][1] = vector_pair_type_node;
+ builtin_mode_to_type[XOmode][1] = vector_quad_type_node;
tdecl = add_builtin_type ("__bool char", bool_char_type_node);
TYPE_NAME (bool_char_type_node) = tdecl;
@@ -14049,21 +14071,21 @@ mma_init_builtins (void)
}
else
{
- if ((attr & RS6000_BTC_QUAD) == 0)
+ if (!(d->code == MMA_BUILTIN_DISASSEMBLE_ACC_INTERNAL
+ || d->code == MMA_BUILTIN_DISASSEMBLE_PAIR_INTERNAL)
+ && (attr & RS6000_BTC_QUAD) == 0)
attr_args--;
/* Ensure we have the correct number and type of operands. */
gcc_assert (attr_args == insn_data[icode].n_operands - 1);
}
- if (icode == CODE_FOR_nothing)
+ /* This is a disassemble pair/acc function. */
+ if (d->code == MMA_BUILTIN_DISASSEMBLE_ACC
+ || d->code == MMA_BUILTIN_DISASSEMBLE_PAIR)
{
- /* This is a disassemble MMA built-in function. */
- gcc_assert (attr_args == RS6000_BTC_BINARY
- && (d->code == MMA_BUILTIN_DISASSEMBLE_ACC
- || d->code == MMA_BUILTIN_DISASSEMBLE_PAIR));
op[nopnds++] = build_pointer_type (void_type_node);
- if (attr & RS6000_BTC_QUAD)
+ if (d->code == MMA_BUILTIN_DISASSEMBLE_ACC)
op[nopnds++] = build_pointer_type (vector_quad_type_node);
else
op[nopnds++] = build_pointer_type (vector_pair_type_node);
@@ -14071,13 +14093,17 @@ mma_init_builtins (void)
else
{
/* This is a normal MMA built-in function. */
- unsigned j = (attr & RS6000_BTC_QUAD) ? 1 : 0;
+ unsigned j = 0;
+ if (attr & RS6000_BTC_QUAD
+ && d->code != MMA_BUILTIN_DISASSEMBLE_ACC_INTERNAL
+ && d->code != MMA_BUILTIN_DISASSEMBLE_PAIR_INTERNAL)
+ j = 1;
for (; j < (unsigned) insn_data[icode].n_operands; j++)
{
machine_mode mode = insn_data[icode].operand[j].mode;
- if (gimple_func && mode == PXImode)
+ if (gimple_func && mode == XOmode)
op[nopnds++] = build_pointer_type (vector_quad_type_node);
- else if (gimple_func && mode == POImode
+ else if (gimple_func && mode == OOmode
&& d->code == MMA_BUILTIN_ASSEMBLE_PAIR)
op[nopnds++] = build_pointer_type (vector_pair_type_node);
else
@@ -14709,7 +14735,7 @@ rs6000_common_init_builtins (void)
continue;
}
- if (icode == CODE_FOR_nothing)
+ if (icode == CODE_FOR_nothing)
{
if (TARGET_DEBUG_BUILTIN)
fprintf (stderr, "rs6000_builtin, skip ternary %s (no code)\n",
@@ -14775,7 +14801,7 @@ rs6000_common_init_builtins (void)
continue;
}
- if (icode == CODE_FOR_nothing)
+ if (icode == CODE_FOR_nothing)
{
if (TARGET_DEBUG_BUILTIN)
fprintf (stderr, "rs6000_builtin, skip binary %s (no code)\n",
@@ -14784,9 +14810,9 @@ rs6000_common_init_builtins (void)
continue;
}
- mode0 = insn_data[icode].operand[0].mode;
- mode1 = insn_data[icode].operand[1].mode;
- mode2 = insn_data[icode].operand[2].mode;
+ mode0 = insn_data[icode].operand[0].mode;
+ mode1 = insn_data[icode].operand[1].mode;
+ mode2 = insn_data[icode].operand[2].mode;
type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
d->code, d->name);
@@ -14819,7 +14845,7 @@ rs6000_common_init_builtins (void)
NULL_TREE);
}
else
- {
+ {
enum insn_code icode = d->icode;
if (d->name == 0)
{
@@ -14830,7 +14856,7 @@ rs6000_common_init_builtins (void)
continue;
}
- if (icode == CODE_FOR_nothing)
+ if (icode == CODE_FOR_nothing)
{
if (TARGET_DEBUG_BUILTIN)
fprintf (stderr, "rs6000_builtin, skip unary %s (no code)\n",
@@ -14839,8 +14865,8 @@ rs6000_common_init_builtins (void)
continue;
}
- mode0 = insn_data[icode].operand[0].mode;
- mode1 = insn_data[icode].operand[1].mode;
+ mode0 = insn_data[icode].operand[0].mode;
+ mode1 = insn_data[icode].operand[1].mode;
type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
d->code, d->name);
diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def
index 8d2c1ff..482e1b6 100644
--- a/gcc/config/rs6000/rs6000-cpus.def
+++ b/gcc/config/rs6000/rs6000-cpus.def
@@ -51,7 +51,6 @@
| OPTION_MASK_CRYPTO \
| OPTION_MASK_DIRECT_MOVE \
| OPTION_MASK_EFFICIENT_UNALIGNED_VSX \
- | OPTION_MASK_HTM \
| OPTION_MASK_QUAD_MEMORY \
| OPTION_MASK_QUAD_MEMORY_ATOMIC)
@@ -240,10 +239,13 @@ RS6000_CPU ("power6x", PROCESSOR_POWER6, MASK_POWERPC64 | MASK_PPC_GPOPT
| MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND
| MASK_CMPB | MASK_DFP | MASK_RECIP_PRECISION)
RS6000_CPU ("power7", PROCESSOR_POWER7, MASK_POWERPC64 | ISA_2_6_MASKS_SERVER)
-RS6000_CPU ("power8", PROCESSOR_POWER8, MASK_POWERPC64 | ISA_2_7_MASKS_SERVER)
-RS6000_CPU ("power9", PROCESSOR_POWER9, MASK_POWERPC64 | ISA_3_0_MASKS_SERVER)
+RS6000_CPU ("power8", PROCESSOR_POWER8, MASK_POWERPC64 | ISA_2_7_MASKS_SERVER
+ | OPTION_MASK_HTM)
+RS6000_CPU ("power9", PROCESSOR_POWER9, MASK_POWERPC64 | ISA_3_0_MASKS_SERVER
+ | OPTION_MASK_HTM)
RS6000_CPU ("power10", PROCESSOR_POWER10, MASK_POWERPC64 | ISA_3_1_MASKS_SERVER)
RS6000_CPU ("powerpc", PROCESSOR_POWERPC, 0)
RS6000_CPU ("powerpc64", PROCESSOR_POWERPC64, MASK_PPC_GFXOPT | MASK_POWERPC64)
-RS6000_CPU ("powerpc64le", PROCESSOR_POWER8, MASK_POWERPC64 | ISA_2_7_MASKS_SERVER)
+RS6000_CPU ("powerpc64le", PROCESSOR_POWER8, MASK_POWERPC64 | ISA_2_7_MASKS_SERVER
+ | OPTION_MASK_HTM)
RS6000_CPU ("rs64", PROCESSOR_RS64A, MASK_PPC_GFXOPT | MASK_POWERPC64)
diff --git a/gcc/config/rs6000/rs6000-modes.def b/gcc/config/rs6000/rs6000-modes.def
index ddb218b..e81a32c 100644
--- a/gcc/config/rs6000/rs6000-modes.def
+++ b/gcc/config/rs6000/rs6000-modes.def
@@ -83,12 +83,6 @@ VECTOR_MODE (INT, SI, 2); /* V2SI */
combination. */
PARTIAL_INT_MODE (TI, 128, PTI);
-/* Define, but don't use the larger integer modes. We need an integer mode
- defined that is the same size as the vector pair and vector quad modes. */
-
-INT_MODE (OI, 32);
-INT_MODE (XI, 64);
-
/* Modes used by __vector_pair and __vector_quad. */
-PARTIAL_INT_MODE (OI, 256, POI); /* __vector_pair. */
-PARTIAL_INT_MODE (XI, 512, PXI); /* __vector_quad. */
+OPAQUE_MODE (OO, 32);
+OPAQUE_MODE (XO, 64);
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 25fa5dd..3c4682b 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -57,7 +57,7 @@ extern bool rs6000_move_128bit_ok_p (rtx []);
extern bool rs6000_split_128bit_ok_p (rtx []);
extern void rs6000_expand_float128_convert (rtx, rtx, bool);
extern void rs6000_expand_vector_init (rtx, rtx);
-extern void rs6000_expand_vector_set (rtx, rtx, int);
+extern void rs6000_expand_vector_set (rtx, rtx, rtx);
extern void rs6000_expand_vector_extract (rtx, rtx, rtx);
extern void rs6000_split_vec_extract_var (rtx, rtx, rtx, rtx, rtx);
extern rtx rs6000_adjust_vec_address (rtx, rtx, rtx, rtx, machine_mode);
@@ -155,6 +155,7 @@ extern void rs6000_split_logical (rtx [], enum rtx_code, bool, bool, bool);
extern bool rs6000_function_pcrel_p (struct function *);
extern bool rs6000_pcrel_p (void);
extern bool rs6000_fndecl_pcrel_p (const_tree);
+extern void rs6000_output_addr_vec_elt (FILE *, int);
/* Different PowerPC instruction formats that are used by GCC. There are
various other instruction formats used by the PowerPC hardware, but these
diff --git a/gcc/config/rs6000/rs6000-string.c b/gcc/config/rs6000/rs6000-string.c
index 82cc24e..a2e6821 100644
--- a/gcc/config/rs6000/rs6000-string.c
+++ b/gcc/config/rs6000/rs6000-string.c
@@ -2787,7 +2787,7 @@ expand_block_move (rtx operands[], bool might_overlap)
rtx src, dest;
bool move_with_length = false;
- /* Use POImode for paired vsx load/store. Use V2DI for single
+ /* Use OOmode for paired vsx load/store. Use V2DI for single
unaligned vsx load/store, for consistency with what other
expansions (compare) already do, and so we can use lxvd2x on
p8. Order is VSX pair unaligned, VSX unaligned, Altivec, VSX
@@ -2799,8 +2799,8 @@ expand_block_move (rtx operands[], bool might_overlap)
&& (align >= 256 || !STRICT_ALIGNMENT))
{
move_bytes = 32;
- mode = POImode;
- gen_func.mov = gen_movpoi;
+ mode = OOmode;
+ gen_func.mov = gen_movoo;
}
else if (TARGET_POWERPC64 && TARGET_BLOCK_OPS_UNALIGNED_VSX
&& VECTOR_MEM_VSX_P (V2DImode)
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index d7dcd93..c661f7a 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1367,6 +1367,9 @@ static const struct attribute_spec rs6000_attribute_table[] =
#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
+#undef TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC
+#define TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC rs6000_gen_pic_addr_diff_vec
+
#undef TARGET_LEGITIMIZE_ADDRESS
#define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
@@ -1826,15 +1829,12 @@ rs6000_hard_regno_mode_ok_uncached (int regno, machine_mode mode)
mode = GET_MODE_INNER (mode);
/* Vector pair modes need even/odd VSX register pairs. Only allow vector
- registers. We need to allow OImode to have the same registers as POImode,
- even though we do not enable the move pattern for OImode. */
- if (mode == POImode || mode == OImode)
+ registers. */
+ if (mode == OOmode)
return (TARGET_MMA && VSX_REGNO_P (regno) && (regno & 1) == 0);
- /* MMA accumulator modes need FPR registers divisible by 4. We need to allow
- XImode to have the same registers as PXImode, even though we do not enable
- the move pattern for XImode. */
- if (mode == PXImode || mode == XImode)
+ /* MMA accumulator modes need FPR registers divisible by 4. */
+ if (mode == XOmode)
return (TARGET_MMA && FP_REGNO_P (regno) && (regno & 3) == 0);
/* PTImode can only go in GPRs. Quad word memory operations require even/odd
@@ -1941,8 +1941,8 @@ rs6000_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
GPR registers, and TImode can go in any GPR as well as VSX registers (PR
57744).
- Similarly, don't allow POImode (vector pair, restricted to even VSX
- registers) or PXImode (vector quad, restricted to FPR registers divisible
+ Similarly, don't allow OOmode (vector pair, restricted to even VSX
+ registers) or XOmode (vector quad, restricted to FPR registers divisible
by 4) to tie with other modes.
Altivec/VSX vector tests were moved ahead of scalar float mode, so that IEEE
@@ -1951,8 +1951,8 @@ rs6000_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
static bool
rs6000_modes_tieable_p (machine_mode mode1, machine_mode mode2)
{
- if (mode1 == PTImode || mode1 == POImode || mode1 == PXImode
- || mode2 == PTImode || mode2 == POImode || mode2 == PXImode)
+ if (mode1 == PTImode || mode1 == OOmode || mode1 == XOmode
+ || mode2 == PTImode || mode2 == OOmode || mode2 == XOmode)
return mode1 == mode2;
if (ALTIVEC_OR_VSX_VECTOR_MODE (mode1))
@@ -2241,10 +2241,8 @@ rs6000_debug_reg_global (void)
V2DFmode,
V8SFmode,
V4DFmode,
- OImode,
- XImode,
- POImode,
- PXImode,
+ OOmode,
+ XOmode,
CCmode,
CCUNSmode,
CCEQmode,
@@ -2706,13 +2704,13 @@ rs6000_setup_reg_addr_masks (void)
since it will be broken into two vector moves. Vector quads can
only do offset loads. */
else if ((addr_mask != 0) && TARGET_MMA
- && (m2 == POImode || m2 == PXImode))
+ && (m2 == OOmode || m2 == XOmode))
{
addr_mask |= RELOAD_REG_OFFSET;
if (rc == RELOAD_REG_FPR || rc == RELOAD_REG_VMX)
{
addr_mask |= RELOAD_REG_QUAD_OFFSET;
- if (m2 == POImode)
+ if (m2 == OOmode)
addr_mask |= RELOAD_REG_INDEXED;
}
}
@@ -2921,13 +2919,13 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
/* Add support for vector pairs and vector quad registers. */
if (TARGET_MMA)
{
- rs6000_vector_unit[POImode] = VECTOR_NONE;
- rs6000_vector_mem[POImode] = VECTOR_VSX;
- rs6000_vector_align[POImode] = 256;
+ rs6000_vector_unit[OOmode] = VECTOR_NONE;
+ rs6000_vector_mem[OOmode] = VECTOR_VSX;
+ rs6000_vector_align[OOmode] = 256;
- rs6000_vector_unit[PXImode] = VECTOR_NONE;
- rs6000_vector_mem[PXImode] = VECTOR_VSX;
- rs6000_vector_align[PXImode] = 512;
+ rs6000_vector_unit[XOmode] = VECTOR_NONE;
+ rs6000_vector_mem[XOmode] = VECTOR_VSX;
+ rs6000_vector_align[XOmode] = 512;
}
/* Register class constraints for the constraints that depend on compile
@@ -3064,10 +3062,10 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
if (TARGET_MMA)
{
- reg_addr[POImode].reload_store = CODE_FOR_reload_poi_di_store;
- reg_addr[POImode].reload_load = CODE_FOR_reload_poi_di_load;
- reg_addr[PXImode].reload_store = CODE_FOR_reload_pxi_di_store;
- reg_addr[PXImode].reload_load = CODE_FOR_reload_pxi_di_load;
+ reg_addr[OOmode].reload_store = CODE_FOR_reload_oo_di_store;
+ reg_addr[OOmode].reload_load = CODE_FOR_reload_oo_di_load;
+ reg_addr[XOmode].reload_store = CODE_FOR_reload_xo_di_store;
+ reg_addr[XOmode].reload_load = CODE_FOR_reload_xo_di_load;
}
}
}
@@ -3810,9 +3808,10 @@ rs6000_option_override_internal (bool global_init_p)
}
/* If little-endian, default to -mstrict-align on older processors.
- Testing for htm matches power8 and later. */
+ Testing for direct_move matches power8 and later. */
if (!BYTES_BIG_ENDIAN
- && !(processor_target_table[tune_index].target_enable & OPTION_MASK_HTM))
+ && !(processor_target_table[tune_index].target_enable
+ & OPTION_MASK_DIRECT_MOVE))
rs6000_isa_flags |= ~rs6000_isa_flags_explicit & OPTION_MASK_STRICT_ALIGN;
if (!rs6000_fold_gimple)
@@ -4122,11 +4121,10 @@ rs6000_option_override_internal (bool global_init_p)
if (!(rs6000_isa_flags_explicit & OPTION_MASK_BLOCK_OPS_VECTOR_PAIR))
{
- /* When the POImode issues of PR96791 are resolved, then we can
- once again enable use of vector pair for memcpy/memmove on
- P10 if we have TARGET_MMA. For now we make it disabled by
- default for all targets. */
- rs6000_isa_flags &= ~OPTION_MASK_BLOCK_OPS_VECTOR_PAIR;
+ if (TARGET_MMA && TARGET_EFFICIENT_UNALIGNED_VSX)
+ rs6000_isa_flags |= OPTION_MASK_BLOCK_OPS_VECTOR_PAIR;
+ else
+ rs6000_isa_flags &= ~OPTION_MASK_BLOCK_OPS_VECTOR_PAIR;
}
/* Use long double size to select the appropriate long double. We use
@@ -4787,10 +4785,13 @@ rs6000_option_override_internal (bool global_init_p)
SET_OPTION_IF_UNSET (&global_options, &global_options_set,
param_max_completely_peeled_insns, 400);
- /* Temporarily disable it for now since lxvl/stxvl on the default
- supported hardware Power9 has unexpected performance behaviors. */
- SET_OPTION_IF_UNSET (&global_options, &global_options_set,
- param_vect_partial_vector_usage, 0);
+ /* The lxvl/stxvl instructions don't perform well before Power10. */
+ if (TARGET_POWER10)
+ SET_OPTION_IF_UNSET (&global_options, &global_options_set,
+ param_vect_partial_vector_usage, 1);
+ else
+ SET_OPTION_IF_UNSET (&global_options, &global_options_set,
+ param_vect_partial_vector_usage, 0);
/* Use the 'model' -fsched-pressure algorithm by default. */
SET_OPTION_IF_UNSET (&global_options, &global_options_set,
@@ -6788,7 +6789,8 @@ rs6000_expand_vector_init (rtx target, rtx vals)
rs6000_expand_vector_init (target, copy);
/* Insert variable. */
- rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
+ rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var),
+ GEN_INT (one_var));
return;
}
@@ -6977,10 +6979,10 @@ rs6000_expand_vector_init (rtx target, rtx vals)
emit_move_insn (target, mem);
}
-/* Set field ELT of TARGET to VAL. */
+/* Set field ELT_RTX of TARGET to VAL. */
void
-rs6000_expand_vector_set (rtx target, rtx val, int elt)
+rs6000_expand_vector_set (rtx target, rtx val, rtx elt_rtx)
{
machine_mode mode = GET_MODE (target);
machine_mode inner_mode = GET_MODE_INNER (mode);
@@ -6994,7 +6996,6 @@ rs6000_expand_vector_set (rtx target, rtx val, int elt)
if (VECTOR_MEM_VSX_P (mode))
{
rtx insn = NULL_RTX;
- rtx elt_rtx = GEN_INT (elt);
if (mode == V2DFmode)
insn = gen_vsx_set_v2df (target, target, val, elt_rtx);
@@ -7021,8 +7022,11 @@ rs6000_expand_vector_set (rtx target, rtx val, int elt)
}
}
+ gcc_assert (CONST_INT_P (elt_rtx));
+
/* Simplify setting single element vectors like V1TImode. */
- if (GET_MODE_SIZE (mode) == GET_MODE_SIZE (inner_mode) && elt == 0)
+ if (GET_MODE_SIZE (mode) == GET_MODE_SIZE (inner_mode)
+ && INTVAL (elt_rtx) == 0)
{
emit_move_insn (target, gen_lowpart (mode, val));
return;
@@ -7045,8 +7049,7 @@ rs6000_expand_vector_set (rtx target, rtx val, int elt)
/* Set permute mask to insert element into target. */
for (i = 0; i < width; ++i)
- XVECEXP (mask, 0, elt*width + i)
- = GEN_INT (i + 0x10);
+ XVECEXP (mask, 0, INTVAL (elt_rtx) * width + i) = GEN_INT (i + 0x10);
x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
if (BYTES_BIG_ENDIAN)
@@ -8129,8 +8132,8 @@ reg_offset_addressing_ok_p (machine_mode mode)
/* The vector pair/quad types support offset addressing if the
underlying vectors support offset addressing. */
- case E_POImode:
- case E_PXImode:
+ case E_OOmode:
+ case E_XOmode:
return TARGET_MMA;
case E_SDmode:
@@ -10323,11 +10326,11 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
operands[1] = force_const_mem (mode, operands[1]);
break;
- case E_POImode:
- case E_PXImode:
+ case E_OOmode:
+ case E_XOmode:
if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) != 0)
error ("%qs is an opaque type, and you can't set it to other values.",
- (mode == POImode) ? "__vector_pair" : "__vector_quad");
+ (mode == OOmode) ? "__vector_pair" : "__vector_quad");
break;
case E_SImode:
@@ -12596,10 +12599,10 @@ rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
the GPR registers. */
if (rclass == GEN_OR_FLOAT_REGS)
{
- if (mode == POImode)
+ if (mode == OOmode)
return VSX_REGS;
- if (mode == PXImode)
+ if (mode == XOmode)
return FLOAT_REGS;
if (GET_MODE_CLASS (mode) == MODE_INT)
@@ -16323,15 +16326,15 @@ rs6000_split_multireg_move (rtx dst, rtx src)
/* If we have a vector quad register for MMA, and this is a load or store,
see if we can use vector paired load/stores. */
- if (mode == PXImode && TARGET_MMA
+ if (mode == XOmode && TARGET_MMA
&& (MEM_P (dst) || MEM_P (src)))
{
- reg_mode = POImode;
+ reg_mode = OOmode;
nregs /= 2;
}
/* If we have a vector pair/quad mode, split it into two/four separate
vectors. */
- else if (mode == POImode || mode == PXImode)
+ else if (mode == OOmode || mode == XOmode)
reg_mode = V1TImode;
else if (FP_REGNO_P (reg))
reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
@@ -16377,12 +16380,16 @@ rs6000_split_multireg_move (rtx dst, rtx src)
return;
}
- /* The __vector_pair and __vector_quad modes are multi-register modes,
- so if have to load or store the registers, we have to be careful to
- properly swap them if we're in little endian mode below. This means
- the last register gets the first memory location. */
- if (mode == POImode || mode == PXImode)
+ /* The __vector_pair and __vector_quad modes are multi-register
+ modes, so if we have to load or store the registers, we have to be
+ careful to properly swap them if we're in little endian mode
+ below. This means the last register gets the first memory
+ location. We also need to be careful of using the right register
+ numbers if we are splitting XO to OO. */
+ if (mode == OOmode || mode == XOmode)
{
+ nregs = hard_regno_nregs (reg, mode);
+ int reg_mode_nregs = hard_regno_nregs (reg, reg_mode);
if (MEM_P (dst))
{
unsigned offset = 0;
@@ -16391,15 +16398,15 @@ rs6000_split_multireg_move (rtx dst, rtx src)
/* If we are reading an accumulator register, we have to
deprime it before we can access it. */
if (TARGET_MMA
- && GET_MODE (src) == PXImode && FP_REGNO_P (REGNO (src)))
+ && GET_MODE (src) == XOmode && FP_REGNO_P (REGNO (src)))
emit_insn (gen_mma_xxmfacc (src, src));
- for (int i = 0; i < nregs; i++)
+ for (int i = 0; i < nregs; i += reg_mode_nregs)
{
- unsigned subreg = (WORDS_BIG_ENDIAN)
- ? i * size : (nregs - 1 - i) * size;
+ unsigned subreg =
+ (WORDS_BIG_ENDIAN) ? i : (nregs - reg_mode_nregs - i);
rtx dst2 = adjust_address (dst, reg_mode, offset);
- rtx src2 = simplify_gen_subreg (reg_mode, src, mode, subreg);
+ rtx src2 = gen_rtx_REG (reg_mode, reg + subreg);
offset += size;
emit_insn (gen_rtx_SET (dst2, src2));
}
@@ -16412,11 +16419,11 @@ rs6000_split_multireg_move (rtx dst, rtx src)
unsigned offset = 0;
unsigned size = GET_MODE_SIZE (reg_mode);
- for (int i = 0; i < nregs; i++)
+ for (int i = 0; i < nregs; i += reg_mode_nregs)
{
- unsigned subreg = (WORDS_BIG_ENDIAN)
- ? i * size : (nregs - 1 - i) * size;
- rtx dst2 = simplify_gen_subreg (reg_mode, dst, mode, subreg);
+ unsigned subreg =
+ (WORDS_BIG_ENDIAN) ? i : (nregs - reg_mode_nregs - i);
+ rtx dst2 = gen_rtx_REG (reg_mode, reg + subreg);
rtx src2 = adjust_address (src, reg_mode, offset);
offset += size;
emit_insn (gen_rtx_SET (dst2, src2));
@@ -16425,7 +16432,7 @@ rs6000_split_multireg_move (rtx dst, rtx src)
/* If we are writing an accumulator register, we have to
prime it after we've written it. */
if (TARGET_MMA
- && GET_MODE (dst) == PXImode && FP_REGNO_P (REGNO (dst)))
+ && GET_MODE (dst) == XOmode && FP_REGNO_P (REGNO (dst)))
emit_insn (gen_mma_xxmtacc (dst, dst));
return;
@@ -16433,9 +16440,12 @@ rs6000_split_multireg_move (rtx dst, rtx src)
if (GET_CODE (src) == UNSPEC)
{
- gcc_assert (REG_P (dst)
- && FP_REGNO_P (REGNO (dst))
- && XINT (src, 1) == UNSPEC_MMA_ASSEMBLE_ACC);
+ gcc_assert (XINT (src, 1) == UNSPEC_MMA_ASSEMBLE);
+ gcc_assert (REG_P (dst));
+ if (GET_MODE (src) == XOmode)
+ gcc_assert (FP_REGNO_P (REGNO (dst)));
+ if (GET_MODE (src) == OOmode)
+ gcc_assert (VSX_REGNO_P (REGNO (dst)));
reg_mode = GET_MODE (XVECEXP (src, 0, 0));
for (int i = 0; i < XVECLEN (src, 0); i++)
@@ -16446,7 +16456,8 @@ rs6000_split_multireg_move (rtx dst, rtx src)
/* We are writing an accumulator register, so we have to
prime it after we've written it. */
- emit_insn (gen_mma_xxmtacc (dst, dst));
+ if (GET_MODE (src) == XOmode)
+ emit_insn (gen_mma_xxmtacc (dst, dst));
return;
}
@@ -16459,22 +16470,35 @@ rs6000_split_multireg_move (rtx dst, rtx src)
/* If we are reading an accumulator register, we have to
deprime it before we can access it. */
if (TARGET_MMA
- && GET_MODE (src) == PXImode && FP_REGNO_P (REGNO (src)))
+ && GET_MODE (src) == XOmode && FP_REGNO_P (REGNO (src)))
emit_insn (gen_mma_xxmfacc (src, src));
/* Move register range backwards, if we might have destructive
overlap. */
int i;
- for (i = nregs - 1; i >= 0; i--)
- emit_insn (gen_rtx_SET (simplify_gen_subreg (reg_mode, dst, mode,
- i * reg_mode_size),
- simplify_gen_subreg (reg_mode, src, mode,
- i * reg_mode_size)));
+ /* XO/OO are opaque so cannot use subregs. */
+ if (mode == OOmode || mode == XOmode )
+ {
+ for (i = nregs - 1; i >= 0; i--)
+ {
+ rtx dst_i = gen_rtx_REG (reg_mode, REGNO (dst) + i);
+ rtx src_i = gen_rtx_REG (reg_mode, REGNO (src) + i);
+ emit_insn (gen_rtx_SET (dst_i, src_i));
+ }
+ }
+ else
+ {
+ for (i = nregs - 1; i >= 0; i--)
+ emit_insn (gen_rtx_SET (simplify_gen_subreg (reg_mode, dst, mode,
+ i * reg_mode_size),
+ simplify_gen_subreg (reg_mode, src, mode,
+ i * reg_mode_size)));
+ }
/* If we are writing an accumulator register, we have to
prime it after we've written it. */
if (TARGET_MMA
- && GET_MODE (dst) == PXImode && FP_REGNO_P (REGNO (dst)))
+ && GET_MODE (dst) == XOmode && FP_REGNO_P (REGNO (dst)))
emit_insn (gen_mma_xxmtacc (dst, dst));
}
else
@@ -16611,7 +16635,7 @@ rs6000_split_multireg_move (rtx dst, rtx src)
/* If we are reading an accumulator register, we have to
deprime it before we can access it. */
if (TARGET_MMA && REG_P (src)
- && GET_MODE (src) == PXImode && FP_REGNO_P (REGNO (src)))
+ && GET_MODE (src) == XOmode && FP_REGNO_P (REGNO (src)))
emit_insn (gen_mma_xxmfacc (src, src));
for (i = 0; i < nregs; i++)
@@ -16626,16 +16650,24 @@ rs6000_split_multireg_move (rtx dst, rtx src)
if (j == 0 && used_update)
continue;
- emit_insn (gen_rtx_SET (simplify_gen_subreg (reg_mode, dst, mode,
- j * reg_mode_size),
- simplify_gen_subreg (reg_mode, src, mode,
- j * reg_mode_size)));
+ /* XO/OO are opaque so cannot use subregs. */
+ if (mode == OOmode || mode == XOmode )
+ {
+ rtx dst_i = gen_rtx_REG (reg_mode, REGNO (dst) + j);
+ rtx src_i = gen_rtx_REG (reg_mode, REGNO (src) + j);
+ emit_insn (gen_rtx_SET (dst_i, src_i));
+ }
+ else
+ emit_insn (gen_rtx_SET (simplify_gen_subreg (reg_mode, dst, mode,
+ j * reg_mode_size),
+ simplify_gen_subreg (reg_mode, src, mode,
+ j * reg_mode_size)));
}
/* If we are writing an accumulator register, we have to
prime it after we've written it. */
if (TARGET_MMA && REG_P (dst)
- && GET_MODE (dst) == PXImode && FP_REGNO_P (REGNO (dst)))
+ && GET_MODE (dst) == XOmode && FP_REGNO_P (REGNO (dst)))
emit_insn (gen_mma_xxmtacc (dst, dst));
if (restore_basereg != NULL_RTX)
@@ -19865,7 +19897,8 @@ rs6000_mangle_type (const_tree type)
type = TYPE_MAIN_VARIANT (type);
if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
- && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
+ && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE
+ && TREE_CODE (type) != OPAQUE_TYPE)
return NULL;
if (type == bool_char_type_node) return "U6__boolc";
@@ -21753,6 +21786,14 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
}
break;
+ case UNSPEC:
+ if (XINT (x, 1) == UNSPEC_MMA_XXSETACCZ)
+ {
+ *total = 0;
+ return true;
+ }
+ break;
+
default:
break;
}
@@ -27186,14 +27227,14 @@ rs6000_invalid_conversion (const_tree fromtype, const_tree totype)
if (frommode != tomode)
{
- /* Do not allow conversions to/from PXImode and POImode types. */
- if (frommode == PXImode)
+ /* Do not allow conversions to/from XOmode and OOmode types. */
+ if (frommode == XOmode)
return N_("invalid conversion from type %<__vector_quad%>");
- if (tomode == PXImode)
+ if (tomode == XOmode)
return N_("invalid conversion to type %<__vector_quad%>");
- if (frommode == POImode)
+ if (frommode == OOmode)
return N_("invalid conversion from type %<__vector_pair%>");
- if (tomode == POImode)
+ if (tomode == OOmode)
return N_("invalid conversion to type %<__vector_pair%>");
}
else if (POINTER_TYPE_P (fromtype) && POINTER_TYPE_P (totype))
@@ -27202,19 +27243,19 @@ rs6000_invalid_conversion (const_tree fromtype, const_tree totype)
frommode = TYPE_MODE (TREE_TYPE (fromtype));
tomode = TYPE_MODE (TREE_TYPE (totype));
- /* Do not allow conversions to/from PXImode and POImode pointer
+ /* Do not allow conversions to/from XOmode and OOmode pointer
types, except to/from void pointers. */
if (frommode != tomode
&& frommode != VOIDmode
&& tomode != VOIDmode)
{
- if (frommode == PXImode)
+ if (frommode == XOmode)
return N_("invalid conversion from type %<* __vector_quad%>");
- if (tomode == PXImode)
+ if (tomode == XOmode)
return N_("invalid conversion to type %<* __vector_quad%>");
- if (frommode == POImode)
+ if (frommode == OOmode)
return N_("invalid conversion from type %<* __vector_pair%>");
- if (tomode == POImode)
+ if (tomode == OOmode)
return N_("invalid conversion to type %<* __vector_pair%>");
}
}
@@ -27244,6 +27285,26 @@ rs6000_emit_xxspltidp_v2df (rtx dst, long value)
emit_insn( gen_xxspltidp_v2df_inst (dst, GEN_INT (value)));
}
+/* Implement TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC. */
+
+static bool
+rs6000_gen_pic_addr_diff_vec (void)
+{
+ return rs6000_relative_jumptables;
+}
+
+void
+rs6000_output_addr_vec_elt (FILE *file, int value)
+{
+ const char *directive = TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t";
+ char buf[100];
+
+ fprintf (file, "%s", directive);
+ ASM_GENERATE_INTERNAL_LABEL (buf, "L", value);
+ assemble_name (file, buf);
+ fprintf (file, "\n");
+}
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-rs6000.h"
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 5a47aa1..5bf9c83 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1041,7 +1041,7 @@ enum data_align { align_abi, align_opt, align_both };
/* Modes that are not vectors, but require vector alignment. Treat these like
vectors in terms of loads and stores. */
#define VECTOR_ALIGNMENT_P(MODE) \
- (FLOAT128_VECTOR_P (MODE) || (MODE) == POImode || (MODE) == PXImode)
+ (FLOAT128_VECTOR_P (MODE) || (MODE) == OOmode || (MODE) == XOmode)
#define ALTIVEC_VECTOR_MODE(MODE) \
((MODE) == V16QImode \
@@ -1756,15 +1756,15 @@ typedef struct rs6000_args
/* #define LEGITIMATE_PIC_OPERAND_P (X) */
-/* Specify the machine mode that this machine uses
- for the index in the tablejump instruction. */
-#define CASE_VECTOR_MODE SImode
-
/* Define as C expression which evaluates to nonzero if the tablejump
instruction expects the table to contain offsets from the address of the
table.
Do not define this if the table should contain absolute addresses. */
-#define CASE_VECTOR_PC_RELATIVE 1
+#define CASE_VECTOR_PC_RELATIVE rs6000_relative_jumptables
+
+/* Specify the machine mode that this machine uses
+ for the index in the tablejump instruction. */
+#define CASE_VECTOR_MODE (rs6000_relative_jumptables ? SImode : Pmode)
/* Define this as 1 if `char' should by default be signed; else as 0. */
#define DEFAULT_SIGNED_CHAR 0
@@ -2194,6 +2194,11 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
putc ('\n', FILE); \
} while (0)
+/* This is how to output an element of a case-vector
+ that is non-relative. */
+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
+ rs6000_output_addr_vec_elt ((FILE), (VALUE))
+
/* This is how to output an assembler line
that says to advance the location counter
to a multiple of 2**LOG bytes. */
@@ -2556,6 +2561,7 @@ typedef struct GTY(()) machine_function
bool fpr_is_wrapped_separately[32];
bool lr_is_wrapped_separately;
bool toc_is_wrapped_separately;
+ bool mma_return_type_error;
} machine_function;
#endif
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 5e5ad9f..b89990f 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -778,7 +778,7 @@
;; supplement addressing modes.
(define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
SF SD SI DF DD DI TI PTI KF IF TF
- POI PXI])
+ OO XO])
;; Iterate over smin, smax
(define_code_iterator fp_minmax [smin smax])
@@ -8761,7 +8761,7 @@
UNSPEC_P8V_MTVSRD))]
"TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
"mtvsrd %x0,%1"
- [(set_attr "type" "mfvsr")])
+ [(set_attr "type" "mtvsr")])
(define_insn "p8_xxpermdi_<mode>"
[(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
@@ -12713,15 +12713,22 @@
""
{
if (rs6000_speculate_indirect_jumps)
- emit_jump_insn (gen_tablejump_normal (Pmode, operands[0], operands[1]));
+ {
+ if (rs6000_relative_jumptables)
+ emit_jump_insn (gen_tablejump_normal (Pmode, operands[0], operands[1]));
+ else
+ emit_jump_insn (gen_tablejump_absolute (Pmode, operands[0],
+ operands[1]));
+ }
else
{
rtx ccreg = gen_reg_rtx (CCmode);
rtx jump;
- if (TARGET_32BIT)
- jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
+ if (rs6000_relative_jumptables)
+ jump = gen_tablejump_nospec (Pmode, operands[0], operands[1], ccreg);
else
- jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
+ jump = gen_tablejump_absolute_nospec (Pmode, operands[0], operands[1],
+ ccreg);
emit_jump_insn (jump);
}
DONE;
@@ -12730,7 +12737,7 @@
(define_expand "@tablejump<mode>_normal"
[(use (match_operand:SI 0))
(use (match_operand:P 1))]
- "rs6000_speculate_indirect_jumps"
+ "rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
{
rtx off = force_reg (SImode, operands[0]);
if (<MODE>mode != SImode)
@@ -12748,11 +12755,23 @@
DONE;
})
+(define_expand "@tablejump<mode>_absolute"
+ [(use (match_operand:P 0))
+ (use (match_operand:P 1))]
+ "rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
+{
+ rtx addr = gen_reg_rtx (Pmode);
+ emit_move_insn (addr, operands[0]);
+
+ emit_jump_insn (gen_tablejump_insn_normal (Pmode, addr, operands[1]));
+ DONE;
+})
+
(define_expand "@tablejump<mode>_nospec"
[(use (match_operand:SI 0))
(use (match_operand:P 1))
(use (match_operand:CC 2))]
- "!rs6000_speculate_indirect_jumps"
+ "!rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
{
rtx off = force_reg (SImode, operands[0]);
if (<MODE>mode != SImode)
@@ -12771,6 +12790,20 @@
DONE;
})
+(define_expand "@tablejump<mode>_absolute_nospec"
+ [(use (match_operand:P 0))
+ (use (match_operand:P 1))
+ (use (match_operand:CC 2))]
+ "!rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
+{
+ rtx addr = gen_reg_rtx (Pmode);
+ emit_move_insn (addr, operands[0]);
+
+ emit_jump_insn (gen_tablejump_insn_nospec (Pmode, addr, operands[1],
+ operands[2]));
+ DONE;
+})
+
(define_insn "@tablejump<mode>_insn_normal"
[(set (pc)
(match_operand:P 0 "register_operand" "c,*l"))
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index b2a70e8..2888172 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -589,3 +589,6 @@ Generate (do not generate) pc-relative memory addressing.
mmma
Target Report Mask(MMA) Var(rs6000_isa_flags)
Generate (do not generate) MMA instructions.
+
+mrelative-jumptables
+Target Undocumented Var(rs6000_relative_jumptables) Init(1) Save
diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md
index 796345c..7aab188 100644
--- a/gcc/config/rs6000/vector.md
+++ b/gcc/config/rs6000/vector.md
@@ -1227,10 +1227,10 @@
(define_expand "vec_set<mode>"
[(match_operand:VEC_E 0 "vlogical_operand")
(match_operand:<VEC_base> 1 "register_operand")
- (match_operand 2 "const_int_operand")]
+ (match_operand 2 "reg_or_cint_operand")]
"VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
{
- rs6000_expand_vector_set (operands[0], operands[1], INTVAL (operands[2]));
+ rs6000_expand_vector_set (operands[0], operands[1], operands[2]);
DONE;
})
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index ad2f7f7..eb10c3f 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -135,6 +135,7 @@ extern void s390_split_access_reg (rtx, rtx *, rtx *);
extern void print_operand_address (FILE *, rtx);
extern void print_operand (FILE *, rtx, int);
extern void s390_output_pool_entry (rtx, machine_mode, unsigned int);
+extern bool s390_const_int_pool_entry_p (rtx, HOST_WIDE_INT *);
extern int s390_label_align (rtx_insn *);
extern int s390_agen_dep_p (rtx_insn *, rtx_insn *);
extern rtx_insn *s390_load_got (void);
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 2300a51..fb48102 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -9400,6 +9400,37 @@ s390_output_pool_entry (rtx exp, machine_mode mode, unsigned int align)
}
}
+/* Return true if MEM refers to an integer constant in the literal pool. If
+ VAL is not nullptr, then also fill it with the constant's value. */
+
+bool
+s390_const_int_pool_entry_p (rtx mem, HOST_WIDE_INT *val)
+{
+ /* Try to match the following:
+ - (mem (unspec [(symbol_ref) (reg)] UNSPEC_LTREF)).
+ - (mem (symbol_ref)). */
+
+ if (!MEM_P (mem))
+ return false;
+
+ rtx addr = XEXP (mem, 0);
+ rtx sym;
+ if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_LTREF)
+ sym = XVECEXP (addr, 0, 0);
+ else
+ sym = addr;
+
+ if (!SYMBOL_REF_P (sym) || !CONSTANT_POOL_ADDRESS_P (sym))
+ return false;
+
+ rtx val_rtx = get_pool_constant (sym);
+ if (!CONST_INT_P (val_rtx))
+ return false;
+
+ if (val != nullptr)
+ *val = INTVAL (val_rtx);
+ return true;
+}
/* Return an RTL expression representing the value of the return address
for the frame COUNT steps up from the current frame. FRAME is the
@@ -11746,7 +11777,7 @@ s390_output_split_stack_data (rtx parm_block, rtx call_done,
rtx ops[] = { parm_block, call_done };
switch_to_section (targetm.asm_out.function_rodata_section
- (current_function_decl));
+ (current_function_decl, false));
if (TARGET_64BIT)
output_asm_insn (".align\t8", NULL);
@@ -16376,20 +16407,28 @@ s390_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1, const_tree ty
return NULL;
}
-/* Implement TARGET_C_EXCESS_PRECISION.
+#if ENABLE_S390_EXCESS_FLOAT_PRECISION == 1
+/* Implement TARGET_C_EXCESS_PRECISION to maintain historic behavior with older
+ glibc versions
- FIXME: For historical reasons, float_t and double_t are typedef'ed to
+ For historical reasons, float_t and double_t had been typedef'ed to
double on s390, causing operations on float_t to operate in a higher
precision than is necessary. However, it is not the case that SFmode
operations have implicit excess precision, and we generate more optimal
code if we let the compiler know no implicit extra precision is added.
- That means when we are compiling with -fexcess-precision=fast, the value
- we set for FLT_EVAL_METHOD will be out of line with the actual precision of
- float_t (though they would be correct for -fexcess-precision=standard).
+ With a glibc with that "historic" definition, configure will enable this hook
+ to set FLT_EVAL_METHOD to 1 for -fexcess-precision=standard (e.g., as implied
+ by -std=cXY). That means when we are compiling with -fexcess-precision=fast,
+ the value we set for FLT_EVAL_METHOD will be out of line with the actual
+ precision of float_t.
- A complete fix would modify glibc to remove the unnecessary typedef
- of float_t to double. */
+ Newer versions of glibc will be modified to derive the definition of float_t
+ from FLT_EVAL_METHOD on s390x, as on many other architectures. There,
+ configure will disable this hook by default, so that we defer to the default
+ of FLT_EVAL_METHOD_PROMOTE_TO_FLOAT and a resulting typedef of float_t to
+ float. Note that in that scenario, float_t and FLT_EVAL_METHOD will be in
+ line independent of -fexcess-precision. */
static enum flt_eval_method
s390_excess_precision (enum excess_precision_type type)
@@ -16412,6 +16451,7 @@ s390_excess_precision (enum excess_precision_type type)
}
return FLT_EVAL_METHOD_UNPREDICTABLE;
}
+#endif
/* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */
@@ -16708,8 +16748,12 @@ s390_shift_truncation_mask (machine_mode mode)
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
+#if ENABLE_S390_EXCESS_FLOAT_PRECISION == 1
+/* This hook is only needed to maintain the historic behavior with glibc
+ versions that typedef float_t to double. */
#undef TARGET_C_EXCESS_PRECISION
#define TARGET_C_EXCESS_PRECISION s390_excess_precision
+#endif
#undef TARGET_SCHED_ADJUST_PRIORITY
#define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index 8c02831..bc579a3 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -1187,8 +1187,9 @@ struct GTY(()) machine_function
#define TARGET_INDIRECT_BRANCH_TABLE s390_indirect_branch_table
#ifdef GENERATOR_FILE
-/* gencondmd.c is built before insn-flags.h. */
-#define HAVE_TF(icode) true
+/* gencondmd.c is built before insn-flags.h. Use an arbitrary opaque value
+ that cannot be optimized away by gen_insn. */
+#define HAVE_TF(icode) TARGET_HARD_FLOAT
#else
#define HAVE_TF(icode) (HAVE_##icode##_fpr || HAVE_##icode##_vr)
#endif
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index a2c033b..d6d8965 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -2116,6 +2116,29 @@
[(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
"")
+; Split loading of 64-bit constants into GPRs into llihf + oilf -
+; counterintuitively, using oilf is faster than iilf. oilf clobbers
+; cc, so cc must be dead.
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "memory_operand" ""))]
+ "TARGET_64BIT
+ && TARGET_EXTIMM
+ && GENERAL_REG_P (operands[0])
+ && s390_const_int_pool_entry_p (operands[1], nullptr)
+ && peep2_reg_dead_p (1, gen_rtx_REG (CCmode, CC_REGNUM))"
+ [(set (match_dup 0) (match_dup 2))
+ (parallel
+ [(set (match_dup 0) (ior:DI (match_dup 0) (match_dup 3)))
+ (clobber (reg:CC CC_REGNUM))])]
+{
+ HOST_WIDE_INT val;
+ bool ok = s390_const_int_pool_entry_p (operands[1], &val);
+ gcc_assert (ok);
+ operands[2] = GEN_INT (val & 0xFFFFFFFF00000000ULL);
+ operands[3] = GEN_INT (val & 0x00000000FFFFFFFFULL);
+})
+
;
; movsi instruction pattern(s).
;
@@ -11093,8 +11116,8 @@
(define_expand "@probe_stack2<mode>"
[(set (reg:CCZ CC_REGNUM)
- (compare:CCZ (reg:P 0)
- (match_operand 0 "memory_operand")))
+ (compare:CCZ (reg:W 0)
+ (match_operand:W 0 "memory_operand")))
(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
"")
@@ -11102,7 +11125,7 @@
[(match_operand 0 "memory_operand")]
""
{
- emit_insn (gen_probe_stack2 (Pmode, operands[0]));
+ emit_insn (gen_probe_stack2 (word_mode, operands[0]));
DONE;
})
@@ -11290,7 +11313,7 @@
""
{
switch_to_section (targetm.asm_out.function_rodata_section
- (current_function_decl));
+ (current_function_decl, false));
return "";
}
[(set_attr "length" "0")])
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index 31d3239..029ee08 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -137,7 +137,7 @@
; Resulting mode of a vector comparison. For floating point modes an
; integer vector mode with the same element size is picked.
-(define_mode_attr tointvec [(V1QI "V1QI") (V2QI "V2QI") (V4QI "V4QI") (V8QI "V8QI") (V16QI "V16QI")
+(define_mode_attr TOINTVEC [(V1QI "V1QI") (V2QI "V2QI") (V4QI "V4QI") (V8QI "V8QI") (V16QI "V16QI")
(V1HI "V1HI") (V2HI "V2HI") (V4HI "V4HI") (V8HI "V8HI")
(V1SI "V1SI") (V2SI "V2SI") (V4SI "V4SI")
(V1DI "V1DI") (V2DI "V2DI")
@@ -145,6 +145,16 @@
(V1SF "V1SI") (V2SF "V2SI") (V4SF "V4SI")
(V1DF "V1DI") (V2DF "V2DI")
(V1TF "V1TI") (TF "V1TI")])
+
+(define_mode_attr tointvec [(V1QI "v1qi") (V2QI "v2qi") (V4QI "v4qi") (V8QI "v8qi") (V16QI "v16qi")
+ (V1HI "v1hi") (V2HI "v2hi") (V4HI "v4hi") (V8HI "v8hi")
+ (V1SI "v1si") (V2SI "v2si") (V4SI "v4si")
+ (V1DI "v1di") (V2DI "v2di")
+ (V1TI "v1ti")
+ (V1SF "v1si") (V2SF "v2si") (V4SF "v4si")
+ (V1DF "v1di") (V2DF "v2di")
+ (V1TF "v1ti") (TF "v1ti")])
+
(define_mode_attr vw [(SF "w") (V1SF "w") (V2SF "v") (V4SF "v")
(DF "w") (V1DF "w") (V2DF "v")
(TF "w") (V1TF "w")])
@@ -697,12 +707,12 @@
(define_expand "vcond_mask_<mode><mode>"
[(set (match_operand:V 0 "register_operand" "")
(if_then_else:V
- (eq (match_operand:<tointvec> 3 "register_operand" "")
+ (eq (match_operand:<TOINTVEC> 3 "register_operand" "")
(match_dup 4))
(match_operand:V 2 "register_operand" "")
(match_operand:V 1 "register_operand" "")))]
"TARGET_VX"
- "operands[4] = CONST0_RTX (<tointvec>mode);")
+ "operands[4] = CONST0_RTX (<TOINTVEC>mode);")
; We only have HW support for byte vectors. The middle-end is
@@ -1546,14 +1556,14 @@
})
;;
-;; Integer compares
+;; Compares
;;
-(define_expand "vec_cmp<VI_HW:mode><VI_HW:mode>"
- [(set (match_operand:VI_HW 0 "register_operand" "")
- (match_operator:VI_HW 1 ""
- [(match_operand:VI_HW 2 "register_operand" "")
- (match_operand:VI_HW 3 "register_operand" "")]))]
+(define_expand "vec_cmp<mode><tointvec>"
+ [(set (match_operand:<TOINTVEC> 0 "register_operand" "")
+ (match_operator:<TOINTVEC> 1 "vcond_comparison_operator"
+ [(match_operand:V_HW 2 "register_operand" "")
+ (match_operand:V_HW 3 "register_operand" "")]))]
"TARGET_VX"
{
s390_expand_vec_compare (operands[0], GET_CODE(operands[1]), operands[2], operands[3]);
@@ -1586,8 +1596,8 @@
; vfcesb, vfcedb, wfcexb: non-signaling "==" comparison (a == b)
(define_insn "*vec_cmpeq<mode>_quiet_nocc"
- [(set (match_operand:<tointvec> 0 "register_operand" "=v")
- (eq:<tointvec> (match_operand:VFT 1 "register_operand" "v")
+ [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (eq:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
(match_operand:VFT 2 "register_operand" "v")))]
"TARGET_VX"
"<vw>fce<sdx>b\t%v0,%v1,%v2"
@@ -1595,45 +1605,45 @@
; vfchsb, vfchdb, wfchxb: non-signaling > comparison (!(b u>= a))
(define_insn "vec_cmpgt<mode>_quiet_nocc"
- [(set (match_operand:<tointvec> 0 "register_operand" "=v")
- (not:<tointvec>
- (unge:<tointvec> (match_operand:VFT 2 "register_operand" "v")
+ [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (not:<TOINTVEC>
+ (unge:<TOINTVEC> (match_operand:VFT 2 "register_operand" "v")
(match_operand:VFT 1 "register_operand" "v"))))]
"TARGET_VX"
"<vw>fch<sdx>b\t%v0,%v1,%v2"
[(set_attr "op_type" "VRR")])
(define_expand "vec_cmplt<mode>_quiet_nocc"
- [(set (match_operand:<tointvec> 0 "register_operand" "=v")
- (not:<tointvec>
- (unge:<tointvec> (match_operand:VFT 1 "register_operand" "v")
+ [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (not:<TOINTVEC>
+ (unge:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
(match_operand:VFT 2 "register_operand" "v"))))]
"TARGET_VX")
; vfchesb, vfchedb, wfchexb: non-signaling >= comparison (!(a u< b))
(define_insn "vec_cmpge<mode>_quiet_nocc"
- [(set (match_operand:<tointvec> 0 "register_operand" "=v")
- (not:<tointvec>
- (unlt:<tointvec> (match_operand:VFT 1 "register_operand" "v")
+ [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (not:<TOINTVEC>
+ (unlt:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
(match_operand:VFT 2 "register_operand" "v"))))]
"TARGET_VX"
"<vw>fche<sdx>b\t%v0,%v1,%v2"
[(set_attr "op_type" "VRR")])
(define_expand "vec_cmple<mode>_quiet_nocc"
- [(set (match_operand:<tointvec> 0 "register_operand" "=v")
- (not:<tointvec>
- (unlt:<tointvec> (match_operand:VFT 2 "register_operand" "v")
+ [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (not:<TOINTVEC>
+ (unlt:<TOINTVEC> (match_operand:VFT 2 "register_operand" "v")
(match_operand:VFT 1 "register_operand" "v"))))]
"TARGET_VX")
; vfkesb, vfkedb, wfkexb: signaling == comparison ((a >= b) & (b >= a))
(define_insn "*vec_cmpeq<mode>_signaling_nocc"
- [(set (match_operand:<tointvec> 0 "register_operand" "=v")
- (and:<tointvec>
- (ge:<tointvec> (match_operand:VFT 1 "register_operand" "v")
+ [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (and:<TOINTVEC>
+ (ge:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
(match_operand:VFT 2 "register_operand" "v"))
- (ge:<tointvec> (match_dup 2)
+ (ge:<TOINTVEC> (match_dup 2)
(match_dup 1))))]
"TARGET_VXE"
"<vw>fke<sdx>b\t%v0,%v1,%v2"
@@ -1641,16 +1651,16 @@
; vfkhsb, vfkhdb, wfkhxb: signaling > comparison (a > b)
(define_insn "*vec_cmpgt<mode>_signaling_nocc"
- [(set (match_operand:<tointvec> 0 "register_operand" "=v")
- (gt:<tointvec> (match_operand:VFT 1 "register_operand" "v")
+ [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (gt:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
(match_operand:VFT 2 "register_operand" "v")))]
"TARGET_VXE"
"<vw>fkh<sdx>b\t%v0,%v1,%v2"
[(set_attr "op_type" "VRR")])
(define_insn "*vec_cmpgt<mode>_signaling_finite_nocc"
- [(set (match_operand:<tointvec> 0 "register_operand" "=v")
- (gt:<tointvec> (match_operand:VFT 1 "register_operand" "v")
+ [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (gt:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
(match_operand:VFT 2 "register_operand" "v")))]
"TARGET_NONSIGNALING_VECTOR_COMPARE_OK"
"<vw>fch<sdx>b\t%v0,%v1,%v2"
@@ -1658,16 +1668,16 @@
; vfkhesb, vfkhedb, wfkhexb: signaling >= comparison (a >= b)
(define_insn "*vec_cmpge<mode>_signaling_nocc"
- [(set (match_operand:<tointvec> 0 "register_operand" "=v")
- (ge:<tointvec> (match_operand:VFT 1 "register_operand" "v")
+ [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (ge:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
(match_operand:VFT 2 "register_operand" "v")))]
"TARGET_VXE"
"<vw>fkhe<sdx>b\t%v0,%v1,%v2"
[(set_attr "op_type" "VRR")])
(define_insn "*vec_cmpge<mode>_signaling_finite_nocc"
- [(set (match_operand:<tointvec> 0 "register_operand" "=v")
- (ge:<tointvec> (match_operand:VFT 1 "register_operand" "v")
+ [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (ge:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
(match_operand:VFT 2 "register_operand" "v")))]
"TARGET_NONSIGNALING_VECTOR_COMPARE_OK"
"<vw>fche<sdx>b\t%v0,%v1,%v2"
@@ -1679,84 +1689,84 @@
; UNGT a u> b -> !!(b u< a)
(define_expand "vec_cmpungt<mode>"
- [(set (match_operand:<tointvec> 0 "register_operand" "=v")
- (not:<tointvec>
- (unlt:<tointvec> (match_operand:VFT 2 "register_operand" "v")
+ [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (not:<TOINTVEC>
+ (unlt:<TOINTVEC> (match_operand:VFT 2 "register_operand" "v")
(match_operand:VFT 1 "register_operand" "v"))))
(set (match_dup 0)
- (not:<tointvec> (match_dup 0)))]
+ (not:<TOINTVEC> (match_dup 0)))]
"TARGET_VX")
; UNGE a u>= b -> !!(a u>= b)
(define_expand "vec_cmpunge<mode>"
- [(set (match_operand:<tointvec> 0 "register_operand" "=v")
- (not:<tointvec>
- (unge:<tointvec> (match_operand:VFT 1 "register_operand" "v")
+ [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (not:<TOINTVEC>
+ (unge:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
(match_operand:VFT 2 "register_operand" "v"))))
(set (match_dup 0)
- (not:<tointvec> (match_dup 0)))]
+ (not:<TOINTVEC> (match_dup 0)))]
"TARGET_VX")
; UNEQ a u== b -> !(!(a u>= b) | !(b u>= a))
(define_expand "vec_cmpuneq<mode>"
- [(set (match_operand:<tointvec> 0 "register_operand" "=v")
- (not:<tointvec>
- (unge:<tointvec> (match_operand:VFT 1 "register_operand" "v")
+ [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (not:<TOINTVEC>
+ (unge:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
(match_operand:VFT 2 "register_operand" "v"))))
(set (match_dup 3)
- (not:<tointvec>
- (unge:<tointvec> (match_dup 2)
+ (not:<TOINTVEC>
+ (unge:<TOINTVEC> (match_dup 2)
(match_dup 1))))
(set (match_dup 0)
- (ior:<tointvec> (match_dup 0)
+ (ior:<TOINTVEC> (match_dup 0)
(match_dup 3)))
(set (match_dup 0)
- (not:<tointvec> (match_dup 0)))]
+ (not:<TOINTVEC> (match_dup 0)))]
"TARGET_VX"
{
- operands[3] = gen_reg_rtx (<tointvec>mode);
+ operands[3] = gen_reg_rtx (<TOINTVEC>mode);
})
; LTGT a <> b -> a > b | b > a
(define_expand "vec_cmpltgt<mode>"
- [(set (match_operand:<tointvec> 0 "register_operand" "=v")
- (gt:<tointvec> (match_operand:VFT 1 "register_operand" "v")
+ [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (gt:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
(match_operand:VFT 2 "register_operand" "v")))
- (set (match_dup 3) (gt:<tointvec> (match_dup 2) (match_dup 1)))
- (set (match_dup 0) (ior:<tointvec> (match_dup 0) (match_dup 3)))]
+ (set (match_dup 3) (gt:<TOINTVEC> (match_dup 2) (match_dup 1)))
+ (set (match_dup 0) (ior:<TOINTVEC> (match_dup 0) (match_dup 3)))]
"TARGET_VXE"
{
- operands[3] = gen_reg_rtx (<tointvec>mode);
+ operands[3] = gen_reg_rtx (<TOINTVEC>mode);
})
; ORDERED (a, b): !(a u< b) | !(a u>= b)
(define_expand "vec_cmpordered<mode>"
- [(set (match_operand:<tointvec> 0 "register_operand" "=v")
- (not:<tointvec>
- (unlt:<tointvec> (match_operand:VFT 1 "register_operand" "v")
+ [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (not:<TOINTVEC>
+ (unlt:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v")
(match_operand:VFT 2 "register_operand" "v"))))
(set (match_dup 3)
- (not:<tointvec>
- (unge:<tointvec> (match_dup 1)
+ (not:<TOINTVEC>
+ (unge:<TOINTVEC> (match_dup 1)
(match_dup 2))))
(set (match_dup 0)
- (ior:<tointvec> (match_dup 0)
+ (ior:<TOINTVEC> (match_dup 0)
(match_dup 3)))]
"TARGET_VX"
{
- operands[3] = gen_reg_rtx (<tointvec>mode);
+ operands[3] = gen_reg_rtx (<TOINTVEC>mode);
})
; UNORDERED (a, b): !ORDERED (a, b)
(define_expand "vec_cmpunordered<mode>"
- [(match_operand:<tointvec> 0 "register_operand" "=v")
+ [(match_operand:<TOINTVEC> 0 "register_operand" "=v")
(match_operand:VFT 1 "register_operand" "v")
(match_operand:VFT 2 "register_operand" "v")]
"TARGET_VX"
{
emit_insn (gen_vec_cmpordered<mode> (operands[0], operands[1], operands[2]));
emit_insn (gen_rtx_SET (operands[0],
- gen_rtx_NOT (<tointvec>mode, operands[0])));
+ gen_rtx_NOT (<TOINTVEC>mode, operands[0])));
DONE;
})
@@ -1835,7 +1845,7 @@
(define_split
[(set (match_operand:V 0 "register_operand" "")
(if_then_else:V
- (eq (match_operand:<tointvec> 3 "register_operand" "")
+ (eq (match_operand:<TOINTVEC> 3 "register_operand" "")
(match_operand:V 4 "const0_operand" ""))
(match_operand:V 1 "const0_operand" "")
(match_operand:V 2 "all_ones_operand" "")))]
@@ -1849,7 +1859,7 @@
(define_split
[(set (match_operand:V 0 "register_operand" "")
(if_then_else:V
- (eq (match_operand:<tointvec> 3 "register_operand" "")
+ (eq (match_operand:<TOINTVEC> 3 "register_operand" "")
(match_operand:V 4 "const0_operand" ""))
(match_operand:V 1 "all_ones_operand" "")
(match_operand:V 2 "const0_operand" "")))]
@@ -1863,7 +1873,7 @@
(define_split
[(set (match_operand:V 0 "register_operand" "")
(if_then_else:V
- (ne (match_operand:<tointvec> 3 "register_operand" "")
+ (ne (match_operand:<TOINTVEC> 3 "register_operand" "")
(match_operand:V 4 "const0_operand" ""))
(match_operand:V 1 "all_ones_operand" "")
(match_operand:V 2 "const0_operand" "")))]
@@ -1877,7 +1887,7 @@
(define_split
[(set (match_operand:V 0 "register_operand" "")
(if_then_else:V
- (ne (match_operand:<tointvec> 3 "register_operand" "")
+ (ne (match_operand:<TOINTVEC> 3 "register_operand" "")
(match_operand:V 4 "const0_operand" ""))
(match_operand:V 1 "const0_operand" "")
(match_operand:V 2 "all_ones_operand" "")))]
@@ -1891,8 +1901,8 @@
(define_insn "*vec_sel0<mode>"
[(set (match_operand:V 0 "register_operand" "=v")
(if_then_else:V
- (eq (match_operand:<tointvec> 3 "register_operand" "v")
- (match_operand:<tointvec> 4 "const0_operand" ""))
+ (eq (match_operand:<TOINTVEC> 3 "register_operand" "v")
+ (match_operand:<TOINTVEC> 4 "const0_operand" ""))
(match_operand:V 1 "register_operand" "v")
(match_operand:V 2 "register_operand" "v")))]
"TARGET_VX"
@@ -1903,8 +1913,8 @@
(define_insn "*vec_sel0<mode>"
[(set (match_operand:V 0 "register_operand" "=v")
(if_then_else:V
- (eq (not:<tointvec> (match_operand:<tointvec> 3 "register_operand" "v"))
- (match_operand:<tointvec> 4 "const0_operand" ""))
+ (eq (not:<TOINTVEC> (match_operand:<TOINTVEC> 3 "register_operand" "v"))
+ (match_operand:<TOINTVEC> 4 "const0_operand" ""))
(match_operand:V 1 "register_operand" "v")
(match_operand:V 2 "register_operand" "v")))]
"TARGET_VX"
@@ -1915,8 +1925,8 @@
(define_insn "*vec_sel1<mode>"
[(set (match_operand:V 0 "register_operand" "=v")
(if_then_else:V
- (eq (match_operand:<tointvec> 3 "register_operand" "v")
- (match_operand:<tointvec> 4 "all_ones_operand" ""))
+ (eq (match_operand:<TOINTVEC> 3 "register_operand" "v")
+ (match_operand:<TOINTVEC> 4 "all_ones_operand" ""))
(match_operand:V 1 "register_operand" "v")
(match_operand:V 2 "register_operand" "v")))]
"TARGET_VX"
@@ -1927,8 +1937,8 @@
(define_insn "*vec_sel1<mode>"
[(set (match_operand:V 0 "register_operand" "=v")
(if_then_else:V
- (eq (not:<tointvec> (match_operand:<tointvec> 3 "register_operand" "v"))
- (match_operand:<tointvec> 4 "all_ones_operand" ""))
+ (eq (not:<TOINTVEC> (match_operand:<TOINTVEC> 3 "register_operand" "v"))
+ (match_operand:<TOINTVEC> 4 "all_ones_operand" ""))
(match_operand:V 1 "register_operand" "v")
(match_operand:V 2 "register_operand" "v")))]
"TARGET_VX"
diff --git a/gcc/config/s390/vx-builtins.md b/gcc/config/s390/vx-builtins.md
index 010db4d..2bbed19 100644
--- a/gcc/config/s390/vx-builtins.md
+++ b/gcc/config/s390/vx-builtins.md
@@ -76,7 +76,7 @@
(define_insn "vec_gather_element<mode>"
[(set (match_operand:V_HW_32_64 0 "register_operand" "=v")
(unspec:V_HW_32_64 [(match_operand:V_HW_32_64 1 "register_operand" "0")
- (match_operand:<tointvec> 2 "register_operand" "v")
+ (match_operand:<TOINTVEC> 2 "register_operand" "v")
(match_operand:BLK 3 "memory_operand" "R")
(match_operand:QI 4 "const_mask_operand" "C")]
UNSPEC_VEC_GATHER))]
@@ -477,7 +477,7 @@
(define_insn "vec_scatter_element<mode>_<non_vec_int>"
[(set (mem:<non_vec>
(plus:<non_vec_int> (unspec:<non_vec_int>
- [(match_operand:<tointvec> 1 "register_operand" "v")
+ [(match_operand:<TOINTVEC> 1 "register_operand" "v")
(match_operand:QI 3 "const_mask_operand" "C")]
UNSPEC_VEC_EXTRACT)
(match_operand:DI 2 "address_operand" "ZQ")))
@@ -492,7 +492,7 @@
; multiplexing here in the expander.
(define_expand "vec_scatter_element<V_HW_32_64:mode>"
[(match_operand:V_HW_32_64 0 "register_operand" "")
- (match_operand:<tointvec> 1 "register_operand" "")
+ (match_operand:<TOINTVEC> 1 "register_operand" "")
(match_operand 2 "address_operand" "")
(match_operand:QI 3 "const_mask_operand" "")]
"TARGET_VX"
@@ -813,8 +813,8 @@
})
(define_expand "vec_cmp<fpcmp:code><mode>"
- [(set (match_operand:<tointvec> 0 "register_operand" "=v")
- (fpcmp:<tointvec> (match_operand:VF_HW 1 "register_operand" "v")
+ [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (fpcmp:<TOINTVEC> (match_operand:VF_HW 1 "register_operand" "v")
(match_operand:VF_HW 2 "register_operand" "v")))]
"TARGET_VX"
{
@@ -1050,7 +1050,7 @@
(define_expand "vec_slb<mode>"
[(set (match_operand:V_HW 0 "register_operand" "")
(unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
- (match_operand:<tointvec> 2 "register_operand" "")]
+ (match_operand:<TOINTVEC> 2 "register_operand" "")]
UNSPEC_VEC_SLB))]
"TARGET_VX"
{
@@ -1121,7 +1121,7 @@
(define_insn "vec_srab<mode>"
[(set (match_operand:V_HW 0 "register_operand" "=v")
(unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
- (match_operand:<tointvec> 2 "register_operand" "v")]
+ (match_operand:<TOINTVEC> 2 "register_operand" "v")]
UNSPEC_VEC_SRAB))]
"TARGET_VX"
"vsrab\t%v0,%v1,%v2"
@@ -1146,7 +1146,7 @@
(define_expand "vec_srb<mode>"
[(set (match_operand:V_HW 0 "register_operand" "")
(unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
- (match_operand:<tointvec> 2 "register_operand" "")]
+ (match_operand:<TOINTVEC> 2 "register_operand" "")]
UNSPEC_VEC_SRLB))]
"TARGET_VX"
{
@@ -1229,7 +1229,7 @@
(define_expand "vec_test_mask_int<mode>"
[(set (reg:CCRAW CC_REGNUM)
(unspec:CCRAW [(match_operand:V_HW 1 "register_operand" "")
- (match_operand:<tointvec> 2 "register_operand" "")]
+ (match_operand:<TOINTVEC> 2 "register_operand" "")]
UNSPEC_VEC_TEST_MASK))
(set (match_operand:SI 0 "register_operand" "")
(unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
@@ -1238,7 +1238,7 @@
(define_insn "*vec_test_mask<mode>"
[(set (reg:CCRAW CC_REGNUM)
(unspec:CCRAW [(match_operand:V_HW 0 "register_operand" "v")
- (match_operand:<tointvec> 1 "register_operand" "v")]
+ (match_operand:<TOINTVEC> 1 "register_operand" "v")]
UNSPEC_VEC_TEST_MASK))]
"TARGET_VX"
"vtm\t%v0,%v1"
@@ -1946,7 +1946,7 @@
(unspec:CCRAW [(match_operand:VF_HW 1 "register_operand" "v")
(match_operand:HI 2 "const_int_operand" "J")]
UNSPEC_VEC_VFTCICC))
- (clobber (match_scratch:<tointvec> 0 "=v"))]
+ (clobber (match_scratch:<TOINTVEC> 0 "=v"))]
"TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")"
"<vw>ftci<sdx>b\t%v0,%v1,%x2"
[(set_attr "op_type" "VRR")])
@@ -1957,7 +1957,7 @@
(unspec:CCRAW [(match_operand:VF_HW 0 "register_operand")
(match_operand:HI 1 "const_int_operand")]
UNSPEC_VEC_VFTCICC))
- (clobber (scratch:<tointvec>))])
+ (clobber (scratch:<TOINTVEC>))])
(set (match_operand:SI 2 "register_operand" "")
(unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
"TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")")
@@ -2083,7 +2083,7 @@
[(set (reg:VFCMP CC_REGNUM)
(compare:VFCMP (match_operand:VF_HW 0 "register_operand" "v")
(match_operand:VF_HW 1 "register_operand" "v")))
- (clobber (match_scratch:<tointvec> 2 "=v"))]
+ (clobber (match_scratch:<TOINTVEC> 2 "=v"))]
"TARGET_VX"
"<vw>fc<asm_fcmp><sdx>bs\t%v2,%v0,%v1"
[(set_attr "op_type" "VRR")])
@@ -2094,8 +2094,8 @@
[(set (reg:CCVEQ CC_REGNUM)
(compare:CCVEQ (match_operand:VF_HW 1 "register_operand" "v")
(match_operand:VF_HW 2 "register_operand" "v")))
- (set (match_operand:<tointvec> 0 "register_operand" "=v")
- (eq:<tointvec> (match_dup 1) (match_dup 2)))])
+ (set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (eq:<TOINTVEC> (match_dup 1) (match_dup 2)))])
(set (match_operand:SI 3 "memory_operand" "")
(unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))]
"TARGET_VX")
@@ -2105,8 +2105,8 @@
[(set (reg:CCVFH CC_REGNUM)
(compare:CCVFH (match_operand:VF_HW 1 "register_operand" "v")
(match_operand:VF_HW 2 "register_operand" "v")))
- (set (match_operand:<tointvec> 0 "register_operand" "=v")
- (gt:<tointvec> (match_dup 1) (match_dup 2)))])
+ (set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (gt:<TOINTVEC> (match_dup 1) (match_dup 2)))])
(set (match_operand:SI 3 "memory_operand" "")
(unspec:SI [(reg:CCVIH CC_REGNUM)] UNSPEC_CC_TO_INT))]
"TARGET_VX")
@@ -2116,8 +2116,8 @@
[(set (reg:CCVFHE CC_REGNUM)
(compare:CCVFHE (match_operand:VF_HW 1 "register_operand" "v")
(match_operand:VF_HW 2 "register_operand" "v")))
- (set (match_operand:<tointvec> 0 "register_operand" "=v")
- (ge:<tointvec> (match_dup 1) (match_dup 2)))])
+ (set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
+ (ge:<TOINTVEC> (match_dup 1) (match_dup 2)))])
(set (match_operand:SI 3 "memory_operand" "")
(unspec:SI [(reg:CCVFHE CC_REGNUM)] UNSPEC_CC_TO_INT))]
"TARGET_VX")
@@ -2131,8 +2131,8 @@
[(set (reg:CCVEQ CC_REGNUM)
(compare:CCVEQ (match_operand:VF_HW 0 "register_operand" "v")
(match_operand:VF_HW 1 "register_operand" "v")))
- (set (match_operand:<tointvec> 2 "register_operand" "=v")
- (eq:<tointvec> (match_dup 0) (match_dup 1)))]
+ (set (match_operand:<TOINTVEC> 2 "register_operand" "=v")
+ (eq:<TOINTVEC> (match_dup 0) (match_dup 1)))]
"TARGET_VX"
"<vw>fce<sdx>bs\t%v2,%v0,%v1"
[(set_attr "op_type" "VRR")])
@@ -2142,8 +2142,8 @@
[(set (reg:CCVFH CC_REGNUM)
(compare:CCVFH (match_operand:VF_HW 0 "register_operand" "v")
(match_operand:VF_HW 1 "register_operand" "v")))
- (set (match_operand:<tointvec> 2 "register_operand" "=v")
- (gt:<tointvec> (match_dup 0) (match_dup 1)))]
+ (set (match_operand:<TOINTVEC> 2 "register_operand" "=v")
+ (gt:<TOINTVEC> (match_dup 0) (match_dup 1)))]
"TARGET_VX"
"<vw>fch<sdx>bs\t%v2,%v0,%v1"
[(set_attr "op_type" "VRR")])
@@ -2153,8 +2153,8 @@
[(set (reg:CCVFHE CC_REGNUM)
(compare:CCVFHE (match_operand:VF_HW 0 "register_operand" "v")
(match_operand:VF_HW 1 "register_operand" "v")))
- (set (match_operand:<tointvec> 2 "register_operand" "=v")
- (ge:<tointvec> (match_dup 0) (match_dup 1)))]
+ (set (match_operand:<TOINTVEC> 2 "register_operand" "=v")
+ (ge:<TOINTVEC> (match_dup 0) (match_dup 1)))]
"TARGET_VX"
"<vw>fche<sdx>bs\t%v2,%v0,%v1"
[(set_attr "op_type" "VRR")])
diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h
index 91b4602..7a21f22 100644
--- a/gcc/config/sol2.h
+++ b/gcc/config/sol2.h
@@ -381,9 +381,6 @@ along with GCC; see the file COPYING3. If not see
{ "endfile_vtv", ENDFILE_VTV_SPEC }, \
SUBTARGET_CPU_EXTRA_SPECS
-/* C++11 programs need -lrt for nanosleep. */
-#define TIME_LIBRARY "rt"
-
#ifndef USE_GLD
/* With Sun ld, -rdynamic is a no-op. */
#define RDYNAMIC_SPEC ""
diff --git a/gcc/config/sparc/predicates.md b/gcc/config/sparc/predicates.md
index 3d49972..42316ad 100644
--- a/gcc/config/sparc/predicates.md
+++ b/gcc/config/sparc/predicates.md
@@ -296,6 +296,8 @@
if (arith_double_operand (op, mode))
return true;
+ /* Turning an add/sub instruction into the other changes the Carry flag
+ so the 4096 trick cannot be used for double operations in 32-bit mode. */
return TARGET_ARCH64 && const_4096_operand (op, mode);
})
diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h
index f525cd7..5f9999a 100644
--- a/gcc/config/sparc/sparc-protos.h
+++ b/gcc/config/sparc/sparc-protos.h
@@ -86,7 +86,6 @@ extern int mems_ok_for_ldd_peep (rtx, rtx, rtx);
extern rtx widen_mem_for_ldd_peep (rtx, rtx, machine_mode);
extern int empty_delay_slot (rtx_insn *);
extern int emit_cbcond_nop (rtx_insn *);
-extern int eligible_for_call_delay (rtx_insn *);
extern int eligible_for_return_delay (rtx_insn *);
extern int eligible_for_sibcall_delay (rtx_insn *);
extern int emit_move_sequence (rtx, machine_mode);
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 2780b42..ec0921b 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -708,6 +708,7 @@ static HOST_WIDE_INT sparc_constant_alignment (const_tree, HOST_WIDE_INT);
static bool sparc_vectorize_vec_perm_const (machine_mode, rtx, rtx, rtx,
const vec_perm_indices &);
static bool sparc_can_follow_jump (const rtx_insn *, const rtx_insn *);
+static HARD_REG_SET sparc_zero_call_used_regs (HARD_REG_SET);
#ifdef SUBTARGET_ATTRIBUTE_TABLE
/* Table of valid machine attributes. */
@@ -959,6 +960,9 @@ char sparc_hard_reg_printed[8];
#undef TARGET_CAN_FOLLOW_JUMP
#define TARGET_CAN_FOLLOW_JUMP sparc_can_follow_jump
+#undef TARGET_ZERO_CALL_USED_REGS
+#define TARGET_ZERO_CALL_USED_REGS sparc_zero_call_used_regs
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Return the memory reference contained in X if any, zero otherwise. */
@@ -3949,41 +3953,6 @@ emit_cbcond_nop (rtx_insn *insn)
return 1;
}
-/* Return nonzero if TRIAL can go into the call delay slot. */
-
-int
-eligible_for_call_delay (rtx_insn *trial)
-{
- rtx pat;
-
- if (get_attr_in_branch_delay (trial) == IN_BRANCH_DELAY_FALSE)
- return 0;
-
- /* The only problematic cases are TLS sequences with Sun as/ld. */
- if ((TARGET_GNU_TLS && HAVE_GNU_LD) || !TARGET_TLS)
- return 1;
-
- pat = PATTERN (trial);
-
- /* We must reject tgd_add{32|64}, i.e.
- (set (reg) (plus (reg) (unspec [(reg) (symbol_ref)] UNSPEC_TLSGD)))
- and tldm_add{32|64}, i.e.
- (set (reg) (plus (reg) (unspec [(reg) (symbol_ref)] UNSPEC_TLSLDM)))
- for Sun as/ld. */
- if (GET_CODE (pat) == SET
- && GET_CODE (SET_SRC (pat)) == PLUS)
- {
- rtx unspec = XEXP (SET_SRC (pat), 1);
-
- if (GET_CODE (unspec) == UNSPEC
- && (XINT (unspec, 1) == UNSPEC_TLSGD
- || XINT (unspec, 1) == UNSPEC_TLSLDM))
- return 0;
- }
-
- return 1;
-}
-
/* Return nonzero if TRIAL, an insn, can be combined with a 'restore'
instruction. RETURN_P is true if the v9 variant 'return' is to be
considered in the test too.
@@ -13845,4 +13814,50 @@ sparc_constant_alignment (const_tree exp, HOST_WIDE_INT align)
return align;
}
+/* Implement TARGET_ZERO_CALL_USED_REGS.
+
+ Generate a sequence of instructions that zero registers specified by
+ NEED_ZEROED_HARDREGS. Return the ZEROED_HARDREGS that are actually
+ zeroed. */
+
+static HARD_REG_SET
+sparc_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
+{
+ for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
+ {
+ /* Do not touch the CC registers or the FP registers if no VIS. */
+ if (regno >= SPARC_FCC_REG
+ || (regno >= SPARC_FIRST_FP_REG && !TARGET_VIS))
+ CLEAR_HARD_REG_BIT (need_zeroed_hardregs, regno);
+
+ /* Do not access the odd upper FP registers individually. */
+ else if (regno >= SPARC_FIRST_V9_FP_REG && (regno & 1))
+ ;
+
+ /* Use the most natural mode for the registers, which is not given by
+ regno_reg_rtx/reg_raw_mode for the FP registers on the SPARC. */
+ else
+ {
+ machine_mode mode;
+ rtx reg;
+
+ if (regno < SPARC_FIRST_FP_REG)
+ {
+ reg = regno_reg_rtx[regno];
+ mode = GET_MODE (reg);
+ }
+ else
+ {
+ mode = regno < SPARC_FIRST_V9_FP_REG ? SFmode : DFmode;
+ reg = gen_raw_REG (mode, regno);
+ }
+
+ emit_move_insn (reg, CONST0_RTX (mode));
+ }
+ }
+
+ return need_zeroed_hardregs;
+}
+
#include "gt-sparc.h"
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 231c0d8..6e9ccb4 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -561,9 +561,9 @@
(set_attr "type" "multi")])
;; Attributes for branch scheduling
-(define_attr "in_call_delay" "false,true"
- (symbol_ref "(eligible_for_call_delay (insn)
- ? IN_CALL_DELAY_TRUE : IN_CALL_DELAY_FALSE)"))
+(define_attr "tls_delay_slot" "false,true"
+ (symbol_ref "((TARGET_GNU_TLS && HAVE_GNU_LD) != 0
+ ? TLS_DELAY_SLOT_TRUE : TLS_DELAY_SLOT_FALSE)"))
(define_attr "in_sibcall_delay" "false,true"
(symbol_ref "(eligible_for_sibcall_delay (insn)
@@ -613,27 +613,24 @@
(const_string "true")
] (const_string "false")))
-(define_delay (eq_attr "type" "call")
- [(eq_attr "in_call_delay" "true") (nil) (nil)])
-
(define_delay (eq_attr "type" "sibcall")
[(eq_attr "in_sibcall_delay" "true") (nil) (nil)])
(define_delay (eq_attr "type" "return")
[(eq_attr "in_return_delay" "true") (nil) (nil)])
-(define_delay (and (eq_attr "type" "branch")
- (not (eq_attr "branch_type" "icc")))
- [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay" "true")])
-
-(define_delay (and (eq_attr "type" "branch")
- (eq_attr "branch_type" "icc"))
- [(eq_attr "in_branch_delay" "true") (nil)
- (eq_attr "in_integer_branch_annul_delay" "true")])
-
-(define_delay (eq_attr "type" "uncond_branch")
+(define_delay (ior (eq_attr "type" "call") (eq_attr "type" "uncond_branch"))
[(eq_attr "in_branch_delay" "true") (nil) (nil)])
+(define_delay (and (eq_attr "type" "branch") (not (eq_attr "branch_type" "icc")))
+ [(eq_attr "in_branch_delay" "true")
+ (nil)
+ (eq_attr "in_branch_delay" "true")])
+
+(define_delay (and (eq_attr "type" "branch") (eq_attr "branch_type" "icc"))
+ [(eq_attr "in_branch_delay" "true")
+ (nil)
+ (eq_attr "in_integer_branch_annul_delay" "true")])
;; Include SPARC DFA schedulers
@@ -3771,10 +3768,13 @@ visl")
}
})
+;; Turning an add/sub instruction into the other changes the Carry flag
+;; so the 4096 trick cannot be used for operations in CCXCmode.
+
(define_expand "uaddvdi4"
[(parallel [(set (reg:CCXC CC_REG)
(compare:CCXC (plus:DI (match_operand:DI 1 "register_operand")
- (match_operand:DI 2 "arith_add_operand"))
+ (match_operand:DI 2 "arith_double_operand"))
(match_dup 1)))
(set (match_operand:DI 0 "register_operand")
(plus:DI (match_dup 1) (match_dup 2)))])
@@ -3793,10 +3793,13 @@ visl")
}
})
+;; Turning an add/sub instruction into the other does not change the Overflow
+;; flag so the 4096 trick can be used for operations in CCXVmode.
+
(define_expand "addvdi4"
[(parallel [(set (reg:CCXV CC_REG)
(compare:CCXV (plus:DI (match_operand:DI 1 "register_operand")
- (match_operand:DI 2 "arith_add_operand"))
+ (match_operand:DI 2 "arith_double_add_operand"))
(unspec:DI [(match_dup 1) (match_dup 2)]
UNSPEC_ADDV)))
(set (match_operand:DI 0 "register_operand")
@@ -3969,9 +3972,10 @@ visl")
""
"@
add\t%1, %2, %0
- sub\t%1, -%2, %0"
- [(set_attr "type" "*,*")
- (set_attr "fptype" "*,*")])
+ sub\t%1, -%2, %0")
+
+;; Turning an add/sub instruction into the other changes the Carry flag
+;; so the 4096 trick cannot be used for operations in CCCmode.
(define_expand "uaddvsi4"
[(parallel [(set (reg:CCC CC_REG)
@@ -3985,10 +3989,13 @@ visl")
(pc)))]
"")
+;; Turning an add/sub instruction into the other does not change the Overflow
+;; flag so the 4096 trick can be used for operations in CCVmode.
+
(define_expand "addvsi4"
[(parallel [(set (reg:CCV CC_REG)
(compare:CCV (plus:SI (match_operand:SI 1 "register_operand")
- (match_operand:SI 2 "arith_operand"))
+ (match_operand:SI 2 "arith_add_operand"))
(unspec:SI [(match_dup 1) (match_dup 2)]
UNSPEC_ADDV)))
(set (match_operand:SI 0 "register_operand")
@@ -4097,42 +4104,50 @@ visl")
(define_insn "*cmp_ccv_plus"
[(set (reg:CCV CC_REG)
- (compare:CCV (plus:SI (match_operand:SI 0 "register_operand" "%r")
- (match_operand:SI 1 "arith_operand" "rI"))
+ (compare:CCV (plus:SI (match_operand:SI 0 "register_operand" "%r,r")
+ (match_operand:SI 1 "arith_add_operand" "rI,O"))
(unspec:SI [(match_dup 0) (match_dup 1)] UNSPEC_ADDV)))]
""
- "addcc\t%0, %1, %%g0"
+ "@
+ addcc\t%0, %1, %%g0
+ subcc\t%0, -%1, %%g0"
[(set_attr "type" "compare")])
(define_insn "*cmp_ccxv_plus"
[(set (reg:CCXV CC_REG)
- (compare:CCXV (plus:DI (match_operand:DI 0 "register_operand" "%r")
- (match_operand:DI 1 "arith_operand" "rI"))
+ (compare:CCXV (plus:DI (match_operand:DI 0 "register_operand" "%r,r")
+ (match_operand:DI 1 "arith_add_operand" "rI,O"))
(unspec:DI [(match_dup 0) (match_dup 1)] UNSPEC_ADDV)))]
"TARGET_ARCH64"
- "addcc\t%0, %1, %%g0"
+ "@
+ addcc\t%0, %1, %%g0
+ subcc\t%0, -%1, %%g0"
[(set_attr "type" "compare")])
(define_insn "*cmp_ccv_plus_set"
[(set (reg:CCV CC_REG)
- (compare:CCV (plus:SI (match_operand:SI 1 "register_operand" "%r")
- (match_operand:SI 2 "arith_operand" "rI"))
+ (compare:CCV (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
+ (match_operand:SI 2 "arith_add_operand" "rI,O"))
(unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))
- (set (match_operand:SI 0 "register_operand" "=r")
+ (set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (match_dup 1) (match_dup 2)))]
""
- "addcc\t%1, %2, %0"
+ "@
+ addcc\t%1, %2, %0
+ subcc\t%1, -%2, %0"
[(set_attr "type" "compare")])
(define_insn "*cmp_ccxv_plus_set"
[(set (reg:CCXV CC_REG)
- (compare:CCXV (plus:DI (match_operand:DI 1 "register_operand" "%r")
- (match_operand:DI 2 "arith_operand" "rI"))
+ (compare:CCXV (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
+ (match_operand:DI 2 "arith_add_operand" "rI,O"))
(unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))
- (set (match_operand:DI 0 "register_operand" "=r")
+ (set (match_operand:DI 0 "register_operand" "=r,r")
(plus:DI (match_dup 1) (match_dup 2)))]
"TARGET_ARCH64"
- "addcc\t%1, %2, %0"
+ "@
+ addcc\t%1, %2, %0
+ subcc\t%1, -%2, %0"
[(set_attr "type" "compare")])
(define_insn "*cmp_ccv_plus_sltu_set"
@@ -4164,10 +4179,13 @@ visl")
}
})
+;; Turning an add/sub instruction into the other changes the Carry flag
+;; so the 4096 trick cannot be used for operations in CCXmode.
+
(define_expand "usubvdi4"
[(parallel [(set (reg:CCX CC_REG)
(compare:CCX (match_operand:DI 1 "register_or_zero_operand")
- (match_operand:DI 2 "arith_add_operand")))
+ (match_operand:DI 2 "arith_double_operand")))
(set (match_operand:DI 0 "register_operand")
(minus:DI (match_dup 1) (match_dup 2)))])
(set (pc) (if_then_else (ltu (reg:CCX CC_REG) (const_int 0))
@@ -4191,10 +4209,13 @@ visl")
}
})
+;; Turning an add/sub instruction into the other does not change the Overflow
+;; flag so the 4096 trick can be used for operations in CCXVmode.
+
(define_expand "subvdi4"
[(parallel [(set (reg:CCXV CC_REG)
(compare:CCXV (minus:DI (match_operand:DI 1 "register_operand")
- (match_operand:DI 2 "arith_add_operand"))
+ (match_operand:DI 2 "arith_double_add_operand"))
(unspec:DI [(match_dup 1) (match_dup 2)]
UNSPEC_SUBV)))
(set (match_operand:DI 0 "register_operand")
@@ -4365,9 +4386,10 @@ visl")
""
"@
sub\t%1, %2, %0
- add\t%1, -%2, %0"
- [(set_attr "type" "*,*")
- (set_attr "fptype" "*,*")])
+ add\t%1, -%2, %0")
+
+;; Turning an add/sub instruction into the other changes the Carry flag
+;; so the 4096 trick cannot be used for operations in CCmode.
(define_expand "usubvsi4"
[(parallel [(set (reg:CC CC_REG)
@@ -4387,10 +4409,13 @@ visl")
}
})
+;; Turning an add/sub instruction into the other does not change the Overflow
+;; flag so the 4096 trick can be used for operations in CCVmode.
+
(define_expand "subvsi4"
[(parallel [(set (reg:CCV CC_REG)
(compare:CCV (minus:SI (match_operand:SI 1 "register_operand")
- (match_operand:SI 2 "arith_operand"))
+ (match_operand:SI 2 "arith_add_operand"))
(unspec:SI [(match_dup 1) (match_dup 2)]
UNSPEC_SUBV)))
(set (match_operand:SI 0 "register_operand")
@@ -4483,42 +4508,50 @@ visl")
(define_insn "*cmp_ccv_minus"
[(set (reg:CCV CC_REG)
- (compare:CCV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
- (match_operand:SI 1 "arith_operand" "rI"))
+ (compare:CCV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ,rJ")
+ (match_operand:SI 1 "arith_add_operand" "rI,O"))
(unspec:SI [(match_dup 0) (match_dup 1)] UNSPEC_SUBV)))]
""
- "subcc\t%r0, %1, %%g0"
+ "@
+ subcc\t%r0, %1, %%g0
+ addcc\t%r0, -%1, %%g0"
[(set_attr "type" "compare")])
(define_insn "*cmp_ccxv_minus"
[(set (reg:CCXV CC_REG)
- (compare:CCXV (minus:DI (match_operand:DI 0 "register_or_zero_operand" "rJ")
- (match_operand:DI 1 "arith_operand" "rI"))
+ (compare:CCXV (minus:DI (match_operand:DI 0 "register_or_zero_operand" "rJ,rJ")
+ (match_operand:DI 1 "arith_add_operand" "rI,O"))
(unspec:DI [(match_dup 0) (match_dup 1)] UNSPEC_SUBV)))]
"TARGET_ARCH64"
- "subcc\t%r0, %1, %%g0"
+ "@
+ subcc\t%r0, %1, %%g0
+ addcc\t%r0, -%1, %%g0"
[(set_attr "type" "compare")])
(define_insn "*cmp_ccv_minus_set"
[(set (reg:CCV CC_REG)
- (compare:CCV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
- (match_operand:SI 2 "arith_operand" "rI"))
+ (compare:CCV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
+ (match_operand:SI 2 "arith_add_operand" "rI,O"))
(unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))
- (set (match_operand:SI 0 "register_operand" "=r")
+ (set (match_operand:SI 0 "register_operand" "=r,r")
(minus:SI (match_dup 1) (match_dup 2)))]
""
- "subcc\t%r1, %2, %0"
+ "@
+ subcc\t%r1, %2, %0
+ addcc\t%r1, -%2, %0"
[(set_attr "type" "compare")])
(define_insn "*cmp_ccxv_minus_set"
[(set (reg:CCXV CC_REG)
- (compare:CCXV (minus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
- (match_operand:DI 2 "arith_operand" "rI"))
+ (compare:CCXV (minus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ,rJ")
+ (match_operand:DI 2 "arith_add_operand" "rI,O"))
(unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))
- (set (match_operand:DI 0 "register_operand" "=r")
+ (set (match_operand:DI 0 "register_operand" "=r,r")
(minus:DI (match_dup 1) (match_dup 2)))]
"TARGET_ARCH64"
- "subcc\t%r1, %2, %0"
+ "@
+ subcc\t%r1, %2, %0
+ addcc\t%r1, -%2, %0"
[(set_attr "type" "compare")])
(define_insn "*cmp_ccv_minus_sltu_set"
@@ -5769,13 +5802,13 @@ visl")
(define_insn "negsi2"
[(set (match_operand:SI 0 "register_operand" "=r")
- (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
+ (neg:SI (match_operand:SI 1 "register_operand" "r")))]
""
"sub\t%%g0, %1, %0")
(define_expand "unegvsi3"
[(parallel [(set (reg:CCC CC_REG)
- (compare:CCC (not:SI (match_operand:SI 1 "arith_operand" ""))
+ (compare:CCC (not:SI (match_operand:SI 1 "register_operand" ""))
(const_int -1)))
(set (match_operand:SI 0 "register_operand" "")
(neg:SI (match_dup 1)))])
@@ -5787,7 +5820,7 @@ visl")
(define_expand "negvsi3"
[(parallel [(set (reg:CCV CC_REG)
- (compare:CCV (neg:SI (match_operand:SI 1 "arith_operand" ""))
+ (compare:CCV (neg:SI (match_operand:SI 1 "register_operand" ""))
(unspec:SI [(match_dup 1)] UNSPEC_NEGV)))
(set (match_operand:SI 0 "register_operand" "")
(neg:SI (match_dup 1)))])
@@ -5799,7 +5832,7 @@ visl")
(define_insn "*cmp_ccnz_neg"
[(set (reg:CCNZ CC_REG)
- (compare:CCNZ (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
+ (compare:CCNZ (neg:SI (match_operand:SI 0 "register_operand" "r"))
(const_int 0)))]
""
"subcc\t%%g0, %0, %%g0"
@@ -5807,7 +5840,7 @@ visl")
(define_insn "*cmp_ccxnz_neg"
[(set (reg:CCXNZ CC_REG)
- (compare:CCXNZ (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
+ (compare:CCXNZ (neg:DI (match_operand:DI 0 "register_operand" "r"))
(const_int 0)))]
"TARGET_ARCH64"
"subcc\t%%g0, %0, %%g0"
@@ -5815,7 +5848,7 @@ visl")
(define_insn "*cmp_ccnz_neg_set"
[(set (reg:CCNZ CC_REG)
- (compare:CCNZ (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
+ (compare:CCNZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
(const_int 0)))
(set (match_operand:SI 0 "register_operand" "=r")
(neg:SI (match_dup 1)))]
@@ -5825,7 +5858,7 @@ visl")
(define_insn "*cmp_ccxnz_neg_set"
[(set (reg:CCXNZ CC_REG)
- (compare:CCXNZ (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
+ (compare:CCXNZ (neg:DI (match_operand:DI 1 "register_operand" "r"))
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "=r")
(neg:DI (match_dup 1)))]
@@ -5835,7 +5868,7 @@ visl")
(define_insn "*cmp_ccc_neg_set"
[(set (reg:CCC CC_REG)
- (compare:CCC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
+ (compare:CCC (not:SI (match_operand:SI 1 "register_operand" "r"))
(const_int -1)))
(set (match_operand:SI 0 "register_operand" "=r")
(neg:SI (match_dup 1)))]
@@ -5845,7 +5878,7 @@ visl")
(define_insn "*cmp_ccxc_neg_set"
[(set (reg:CCXC CC_REG)
- (compare:CCXC (not:DI (match_operand:DI 1 "arith_operand" "rI"))
+ (compare:CCXC (not:DI (match_operand:DI 1 "register_operand" "r"))
(const_int -1)))
(set (match_operand:DI 0 "register_operand" "=r")
(neg:DI (match_dup 1)))]
@@ -5856,7 +5889,7 @@ visl")
(define_insn "*cmp_ccc_neg_sltu_set"
[(set (reg:CCC CC_REG)
(compare:CCC (zero_extend:DI
- (neg:SI (plus:SI (match_operand:SI 1 "arith_operand" "rI")
+ (neg:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
(ltu:SI (reg:CCC CC_REG)
(const_int 0)))))
(neg:DI (plus:DI (zero_extend:DI (match_dup 1))
@@ -5871,7 +5904,7 @@ visl")
(define_insn "*cmp_ccv_neg"
[(set (reg:CCV CC_REG)
- (compare:CCV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
+ (compare:CCV (neg:SI (match_operand:SI 0 "register_operand" "r"))
(unspec:SI [(match_dup 0)] UNSPEC_NEGV)))]
""
"subcc\t%%g0, %0, %%g0"
@@ -5879,7 +5912,7 @@ visl")
(define_insn "*cmp_ccxv_neg"
[(set (reg:CCXV CC_REG)
- (compare:CCXV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
+ (compare:CCXV (neg:DI (match_operand:DI 0 "register_operand" "r"))
(unspec:DI [(match_dup 0)] UNSPEC_NEGV)))]
"TARGET_ARCH64"
"subcc\t%%g0, %0, %%g0"
@@ -5887,7 +5920,7 @@ visl")
(define_insn "*cmp_ccv_neg_set"
[(set (reg:CCV CC_REG)
- (compare:CCV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
+ (compare:CCV (neg:SI (match_operand:SI 1 "register_operand" "r"))
(unspec:SI [(match_dup 1)] UNSPEC_NEGV)))
(set (match_operand:SI 0 "register_operand" "=r")
(neg:SI (match_dup 1)))]
@@ -5897,7 +5930,7 @@ visl")
(define_insn "*cmp_ccxv_neg_set"
[(set (reg:CCXV CC_REG)
- (compare:CCXV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
+ (compare:CCXV (neg:DI (match_operand:DI 1 "register_operand" "r"))
(unspec:DI [(match_dup 1)] UNSPEC_NEGV)))
(set (match_operand:DI 0 "register_operand" "=r")
(neg:DI (match_dup 1)))]
@@ -5907,7 +5940,7 @@ visl")
(define_insn "*cmp_ccv_neg_sltu_set"
[(set (reg:CCV CC_REG)
- (compare:CCV (neg:SI (plus:SI (match_operand:SI 1 "arith_operand" "rI")
+ (compare:CCV (neg:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
(ltu:SI (reg:CCC CC_REG) (const_int 0))))
(unspec:SI [(plus:SI (match_dup 1)
(ltu:SI (reg:CCC CC_REG)
@@ -7935,7 +7968,9 @@ visl")
(clobber (reg:P O7_REG))]
"TARGET_TLS"
"call\t%a1, %%tgd_call(%a2)%#"
- [(set_attr "type" "call")])
+ [(set (attr "type") (if_then_else (eq_attr "tls_delay_slot" "true")
+ (const_string "call")
+ (const_string "call_no_delay_slot")))])
(define_insn "tldm_hi22<P:mode>"
[(set (match_operand:P 0 "register_operand" "=r")
@@ -7966,7 +8001,9 @@ visl")
(clobber (reg:P O7_REG))]
"TARGET_TLS"
"call\t%a1, %%tldm_call(%&)%#"
- [(set_attr "type" "call")])
+ [(set (attr "type") (if_then_else (eq_attr "tls_delay_slot" "true")
+ (const_string "call")
+ (const_string "call_no_delay_slot")))])
(define_insn "tldo_hix22<P:mode>"
[(set (match_operand:P 0 "register_operand" "=r")
diff --git a/gcc/config/t-darwin b/gcc/config/t-darwin
index 7f2ac28..355389c 100644
--- a/gcc/config/t-darwin
+++ b/gcc/config/t-darwin
@@ -26,6 +26,9 @@ darwin-c.o: $(srcdir)/config/darwin-c.c
$(COMPILE) $(PREPROCESSOR_DEFINES) $<
$(POSTCOMPILE)
+darwin-d.o: $(srcdir)/config/darwin-d.c
+ $(COMPILE) $<
+ $(POSTCOMPILE)
darwin-f.o: $(srcdir)/config/darwin-f.c
$(COMPILE) $<
diff --git a/gcc/config/t-dragonfly b/gcc/config/t-dragonfly
new file mode 100644
index 0000000..764ced9
--- /dev/null
+++ b/gcc/config/t-dragonfly
@@ -0,0 +1,21 @@
+# Copyright (C) 2020 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/>.
+
+dragonfly-d.o: $(srcdir)/config/dragonfly-d.c
+ $(COMPILE) $<
+ $(POSTCOMPILE)
diff --git a/gcc/config/t-freebsd b/gcc/config/t-freebsd
new file mode 100644
index 0000000..ca0cb2e
--- /dev/null
+++ b/gcc/config/t-freebsd
@@ -0,0 +1,21 @@
+# Copyright (C) 2020 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/>.
+
+freebsd-d.o: $(srcdir)/config/freebsd-d.c
+ $(COMPILE) $<
+ $(POSTCOMPILE)
diff --git a/gcc/config/tilegx/tilegx.c b/gcc/config/tilegx/tilegx.c
index 92a1655..142e342 100644
--- a/gcc/config/tilegx/tilegx.c
+++ b/gcc/config/tilegx/tilegx.c
@@ -5049,9 +5049,7 @@ tilegx_trampoline_init (rtx m_tramp, tree fndecl, rtx static_chain)
end_addr = force_reg (Pmode, plus_constant (Pmode, XEXP (m_tramp, 0),
TRAMPOLINE_SIZE));
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"),
- LCT_NORMAL, VOIDmode, begin_addr, Pmode,
- end_addr, Pmode);
+ maybe_emit_call_builtin___clear_cache (begin_addr, end_addr);
}
diff --git a/gcc/config/tilepro/tilepro.c b/gcc/config/tilepro/tilepro.c
index 540c635..3990194 100644
--- a/gcc/config/tilepro/tilepro.c
+++ b/gcc/config/tilepro/tilepro.c
@@ -4458,9 +4458,7 @@ tilepro_trampoline_init (rtx m_tramp, tree fndecl, rtx static_chain)
end_addr = force_reg (Pmode, plus_constant (Pmode, XEXP (m_tramp, 0),
TRAMPOLINE_SIZE));
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"),
- LCT_NORMAL, VOIDmode, begin_addr, Pmode,
- end_addr, Pmode);
+ maybe_emit_call_builtin___clear_cache (begin_addr, end_addr);
}
diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c
index 4a1ecfa..da4e6cb 100644
--- a/gcc/config/vax/vax.c
+++ b/gcc/config/vax/vax.c
@@ -764,7 +764,7 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code,
int opno ATTRIBUTE_UNUSED,
int *total, bool speed ATTRIBUTE_UNUSED)
{
- int code = GET_CODE (x);
+ enum rtx_code code = GET_CODE (x);
int i = 0; /* may be modified in switch */
const char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */
@@ -1369,7 +1369,7 @@ vax_output_int_add (rtx_insn *insn, rtx *operands, machine_mode mode)
if (TARGET_QMATH)
{
gcc_assert (rtx_equal_p (operands[0], operands[1]));
-#ifdef NO_EXTERNAL_INDIRECT_ADDRESSS
+#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
gcc_assert (!flag_pic || !external_memory_operand (low[2], SImode));
gcc_assert (!flag_pic || !external_memory_operand (low[0], SImode));
#endif
@@ -1511,7 +1511,7 @@ vax_output_int_add (rtx_insn *insn, rtx *operands, machine_mode mode)
if (flag_pic
&& (symbolic_operand (operands[1], SImode)
- || symbolic_operand (operands[1], SImode)))
+ || symbolic_operand (operands[2], SImode)))
debug_rtx (insn);
return "addl3 %1,%2,%0";
diff --git a/gcc/config/vxworks.c b/gcc/config/vxworks.c
index ca0f5de..b67d21d 100644
--- a/gcc/config/vxworks.c
+++ b/gcc/config/vxworks.c
@@ -27,6 +27,9 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-core.h"
#include "output.h"
#include "fold-const.h"
+#include "rtl.h"
+#include "memmodel.h"
+#include "optabs.h"
#if !HAVE_INITFINI_ARRAY_SUPPORT
/* Like default_named_section_asm_out_constructor, except that even
@@ -169,4 +172,25 @@ vxworks_override_options (void)
if (!global_options_set.x_dwarf_version)
dwarf_version = VXWORKS_DWARF_VERSION_DEFAULT;
+
+}
+
+/* We don't want to use library symbol __clear_cache on SR0640. Avoid
+ it and issue a direct call to cacheTextUpdate. It takes a size_t
+ length rather than the END address, so we have to compute it. */
+
+void
+vxworks_emit_call_builtin___clear_cache (rtx begin, rtx end)
+{
+ /* STATUS cacheTextUpdate (void *, size_t); */
+ rtx callee = gen_rtx_SYMBOL_REF (Pmode, "cacheTextUpdate");
+
+ enum machine_mode size_mode = TYPE_MODE (sizetype);
+
+ rtx len = simplify_gen_binary (MINUS, size_mode, end, begin);
+
+ emit_library_call (callee,
+ LCT_NORMAL, VOIDmode,
+ begin, ptr_mode,
+ len, size_mode);
}
diff --git a/gcc/config/vxworks.h b/gcc/config/vxworks.h
index e2ce22b..cd43139 100644
--- a/gcc/config/vxworks.h
+++ b/gcc/config/vxworks.h
@@ -282,10 +282,13 @@ extern void vxworks_asm_out_destructor (rtx symbol, int priority);
/* The diab linker does not handle .gnu_attribute sections. */
#undef HAVE_AS_GNU_ATTRIBUTE
-/* We provide our own version of __clear_cache in libgcc, using a separate C
- file to facilitate #inclusion of VxWorks header files. */
-#undef CLEAR_INSN_CACHE
-#define CLEAR_INSN_CACHE 1
+/* We call vxworks's cacheTextUpdate instead of CLEAR_INSN_CACHE if
+ needed. We don't want to force a call on targets that don't define
+ cache-clearing insns nor CLEAR_INSN_CACHE. */
+#undef TARGET_EMIT_CALL_BUILTIN___CLEAR_CACHE
+#define TARGET_EMIT_CALL_BUILTIN___CLEAR_CACHE \
+ vxworks_emit_call_builtin___clear_cache
+extern void vxworks_emit_call_builtin___clear_cache (rtx begin, rtx end);
/* Default dwarf control values, for non-gdb debuggers that come with
VxWorks. */
diff --git a/gcc/configure b/gcc/configure
index 9d2fd0d..785d656 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -710,6 +710,7 @@ subdirs
dollar
gcc_tooldir
enable_lto
+DO_LINK_SERIALIZATION
DO_LINK_MUTEX
MAINT
zlibinc
@@ -1013,6 +1014,7 @@ with_gc
with_system_zlib
enable_maintainer_mode
enable_link_mutex
+enable_link_serialization
enable_version_specific_runtime_libs
enable_plugin
enable_host_shared
@@ -1022,6 +1024,7 @@ with_diagnostics_color
with_diagnostics_urls
enable_default_pie
enable_cet
+enable_s390_excess_float_precision
'
ac_precious_vars='build_alias
host_alias
@@ -1768,6 +1771,10 @@ Optional Features:
sometimes confusing) to the casual installer
--enable-link-mutex avoid linking multiple front-ends at once to avoid
thrashing on the build machine
+ --enable-link-serialization
+ avoid linking multiple GCC front-ends at once using
+ make dependencies to avoid thrashing on the build
+ machine
--enable-version-specific-runtime-libs
specify that runtime libraries should be installed
in a compiler-specific directory
@@ -1777,6 +1784,9 @@ Optional Features:
disable libquadmath support for Fortran
--enable-default-pie enable Position Independent Executable as default
--enable-cet enable Intel CET in host libraries [default=auto]
+ --enable-s390-excess-float-precision
+ on s390 targets, evaluate float with double
+ precision when in standards-conforming mode
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -10136,8 +10146,8 @@ fi
for ac_func in times clock kill getrlimit setrlimit atoq \
popen sysconf strsignal getrusage nl_langinfo \
- gettimeofday mbstowcs wcswidth mmap setlocale \
- clearerr_unlocked feof_unlocked ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked fileno_unlocked fprintf_unlocked fputc_unlocked fputs_unlocked fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked putchar_unlocked putc_unlocked madvise mallinfo mallinfo2
+ gettimeofday mbstowcs wcswidth mmap posix_fallocate setlocale \
+ clearerr_unlocked feof_unlocked ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked fileno_unlocked fprintf_unlocked fputc_unlocked fputs_unlocked fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked putchar_unlocked putc_unlocked madvise mallinfo mallinfo2 fstatat
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -10209,6 +10219,14 @@ _ACEOF
fi
+ac_fn_cxx_check_type "$LINENO" "sighander_t" "ac_cv_type_sighander_t" "signal.h
+"
+if test "x$ac_cv_type_sighander_t" = xyes; then :
+
+$as_echo "#define HAVE_SIGHANDLER_T 1" >>confdefs.h
+
+fi
+
ac_fn_cxx_check_header_preproc "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h"
@@ -11932,6 +11950,142 @@ $as_echo "#define HOST_HAS_F_SETLKW 1" >>confdefs.h
fi
+# Check if O_CLOEXEC is defined by fcntl
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for O_CLOEXEC" >&5
+$as_echo_n "checking for O_CLOEXEC... " >&6; }
+if ${ac_cv_o_cloexec+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <fcntl.h>
+int
+main ()
+{
+
+return open ("/dev/null", O_RDONLY | O_CLOEXEC);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_o_cloexec=yes
+else
+ ac_cv_o_cloexec=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_o_cloexec" >&5
+$as_echo "$ac_cv_o_cloexec" >&6; }
+if test $ac_cv_o_cloexec = yes; then
+
+$as_echo "#define HOST_HAS_O_CLOEXEC 1" >>confdefs.h
+
+fi
+
+# C++ Modules would like some networking features to provide the mapping
+# server. You can still use modules without them though.
+# The following network-related checks could probably do with some
+# Windows and other non-linux defenses and checking.
+
+# Local socket connectivity wants AF_UNIX networking
+# Check for AF_UNIX networking
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for AF_UNIX" >&5
+$as_echo_n "checking for AF_UNIX... " >&6; }
+if ${ac_cv_af_unix+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+int
+main ()
+{
+
+sockaddr_un un;
+un.sun_family = AF_UNSPEC;
+int fd = socket (AF_UNIX, SOCK_STREAM, 0);
+connect (fd, (sockaddr *)&un, sizeof (un));
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_af_unix=yes
+else
+ ac_cv_af_unix=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_af_unix" >&5
+$as_echo "$ac_cv_af_unix" >&6; }
+if test $ac_cv_af_unix = yes; then
+
+$as_echo "#define HAVE_AF_UNIX 1" >>confdefs.h
+
+fi
+
+# Remote socket connectivity wants AF_INET6 networking
+# Check for AF_INET6 networking
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for AF_INET6" >&5
+$as_echo_n "checking for AF_INET6... " >&6; }
+if ${ac_cv_af_inet6+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+int
+main ()
+{
+
+sockaddr_in6 in6;
+in6.sin6_family = AF_UNSPEC;
+struct addrinfo *addrs = 0;
+struct addrinfo hints;
+hints.ai_flags = 0;
+hints.ai_family = AF_INET6;
+hints.ai_socktype = SOCK_STREAM;
+hints.ai_protocol = 0;
+hints.ai_canonname = 0;
+hints.ai_addr = 0;
+hints.ai_next = 0;
+int e = getaddrinfo ("localhost", 0, &hints, &addrs);
+const char *str = gai_strerror (e);
+freeaddrinfo (addrs);
+int fd = socket (AF_INET6, SOCK_STREAM, 0);
+connect (fd, (sockaddr *)&in6, sizeof (in6));
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_af_inet6=yes
+else
+ ac_cv_af_inet6=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_af_inet6" >&5
+$as_echo "$ac_cv_af_inet6" >&6; }
+if test $ac_cv_af_inet6 = yes; then
+
+$as_echo "#define HAVE_AF_INET6 1" >>confdefs.h
+
+fi
+
# Restore CFLAGS, CXXFLAGS from before the gcc_AC_NEED_DECLARATIONS tests.
CFLAGS="$saved_CFLAGS"
CXXFLAGS="$saved_CXXFLAGS"
@@ -17314,7 +17468,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -17326,7 +17480,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -19030,7 +19184,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 19033 "configure"
+#line 19187 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -19136,7 +19290,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 19139 "configure"
+#line 19293 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -20158,7 +20312,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
aCC*)
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
@@ -20182,7 +20336,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test $with_gnu_ld = no; then
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
@@ -23407,6 +23561,43 @@ else
fi
+case "${target}" in
+ riscv*-*-linux*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker ifunc IRELATIVE support" >&5
+$as_echo_n "checking linker ifunc IRELATIVE support... " >&6; }
+ cat > conftest.s <<EOF
+ .text
+ .type foo_resolver, @function
+foo_resolver:
+ ret
+ .size foo_resolver, .-foo_resolver
+
+ .globl foo
+ .type foo, %gnu_indirect_function
+ .set foo, foo_resolver
+
+ .globl bar
+ .type bar, @function
+bar:
+ call foo
+ ret
+ .size bar, .-bar
+EOF
+ if test x$gcc_cv_as != x \
+ && test x$gcc_cv_ld != x \
+ && test x$gcc_cv_readelf != x \
+ && $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \
+ && $gcc_cv_ld -o conftest conftest.o > /dev/null 2>&1 \
+ && $gcc_cv_readelf --relocs --wide conftest \
+ | grep R_RISCV_IRELATIVE > /dev/null 2>&1; then
+ enable_gnu_indirect_function=yes
+ fi
+ rm -f conftest conftest.o conftest.s
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_gnu_indirect_function" >&5
+$as_echo "$enable_gnu_indirect_function" >&6; }
+ ;;
+esac
+
gif=`if test x$enable_gnu_indirect_function = xyes; then echo 1; else echo 0; fi`
cat >>confdefs.h <<_ACEOF
@@ -23762,6 +23953,8 @@ _ACEOF
# Check if we have .[us]leb128, and support symbol arithmetic with it.
+# Older versions of GAS and some non-GNU assemblers, have a bugs handling
+# these directives, even when they appear to accept them.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .sleb128 and .uleb128" >&5
$as_echo_n "checking assembler for .sleb128 and .uleb128... " >&6; }
if ${gcc_cv_as_leb128+:} false; then :
@@ -23779,7 +23972,9 @@ fi
L1:
.uleb128 1280
.sleb128 -1010
-L2:' > conftest.s
+L2:
+ .uleb128 0x8000000000000000
+' > conftest.s
if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
@@ -23787,22 +23982,22 @@ L2:' > conftest.s
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; }
then
- # GAS versions before 2.11 do not support uleb128,
- # despite appearing to.
- # ??? There exists an elf-specific test that will crash
- # the assembler. Perhaps it's better to figure out whether
- # arbitrary sections are supported and try the test.
- as_ver=`$gcc_cv_as --version 2>/dev/null | sed 1q`
- if echo "$as_ver" | grep GNU > /dev/null; then
- as_vers=`echo $as_ver | sed -n \
- -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*.*\)$,\1,p'`
- as_major=`expr "$as_vers" : '\([0-9]*\)'`
- as_minor=`expr "$as_vers" : '[0-9]*\.\([0-9]*\)'`
- if test $as_major -eq 2 && test $as_minor -lt 11
- then :
- else gcc_cv_as_leb128=yes
- fi
+
+if test "x$gcc_cv_objdump" != x; then
+ if $gcc_cv_objdump -s conftest.o 2>/dev/null \
+ | grep '04800a8e 78808080 80808080 808001' >/dev/null; then
+ gcc_cv_as_leb128=yes
+ fi
+elif test "x$gcc_cv_otool" != x; then
+ if $gcc_cv_otool -d conftest.o 2>/dev/null \
+ | grep '04 80 0a 8e 78 80 80 80 80 80 80 80 80 80 01' >/dev/null; then
+ gcc_cv_as_leb128=yes
fi
+else
+ # play safe, assume the assembler is broken.
+ :
+fi
+
else
echo "configure: failed program was" >&5
cat conftest.s >&5
@@ -24235,6 +24430,109 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
+# Test if the assembler supports the section flag 'R' for specifying
+# section with SHF_GNU_RETAIN.
+case "${target}" in
+ # Solaris may use GNU assembler with Solairs ld. Even if GNU
+ # assembler supports the section flag 'R', it doesn't mean that
+ # Solairs ld supports it.
+ *-*-solaris2*)
+ gcc_cv_as_shf_gnu_retain=no
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for section 'R' flag" >&5
+$as_echo_n "checking assembler for section 'R' flag... " >&6; }
+if ${gcc_cv_as_shf_gnu_retain+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcc_cv_as_shf_gnu_retain=no
+ if test $in_tree_gas = yes; then
+ if test $in_tree_gas_is_elf = yes \
+ && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 36 \) \* 1000 + 0`
+ then gcc_cv_as_shf_gnu_retain=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ $as_echo '.section .foo,"awR",%progbits
+.byte 0' > conftest.s
+ if { ac_try='$gcc_cv_as $gcc_cv_as_flags --fatal-warnings -o conftest.o conftest.s >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ then
+ gcc_cv_as_shf_gnu_retain=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_shf_gnu_retain" >&5
+$as_echo "$gcc_cv_as_shf_gnu_retain" >&6; }
+
+
+ ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GAS_SHF_GNU_RETAIN `if test $gcc_cv_as_shf_gnu_retain = yes; then echo 1; else echo 0; fi`
+_ACEOF
+
+
+# Test if the assembler supports the section flag 'o' for specifying
+# section with link-order.
+case "${target}" in
+ # Solaris may use GNU assembler with Solairs ld. Even if GNU
+ # assembler supports the section flag 'o', it doesn't mean that
+ # Solairs ld supports it.
+ *-*-solaris2*)
+ gcc_cv_as_section_link_order=no
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for section 'o' flag" >&5
+$as_echo_n "checking assembler for section 'o' flag... " >&6; }
+if ${gcc_cv_as_section_link_order+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcc_cv_as_section_link_order=no
+ if test $in_tree_gas = yes; then
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 35 \) \* 1000 + 0`
+ then gcc_cv_as_section_link_order=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ $as_echo '.section .foo,"a"
+.byte 0
+.section __patchable_function_entries,"awo",%progbits,.foo
+.byte 0' > conftest.s
+ if { ac_try='$gcc_cv_as $gcc_cv_as_flags --fatal-warnings -o conftest.o conftest.s >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ then
+ gcc_cv_as_section_link_order=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_section_link_order" >&5
+$as_echo "$gcc_cv_as_section_link_order" >&6; }
+
+
+ ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GAS_SECTION_LINK_ORDER `if test $gcc_cv_as_section_link_order = yes; then echo 1; else echo 0; fi`
+_ACEOF
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for section merging support" >&5
$as_echo_n "checking assembler for section merging support... " >&6; }
if ${gcc_cv_as_shf_merge+:} false; then :
@@ -28101,6 +28399,68 @@ $as_echo "#define HAVE_AS_RISCV_ATTRIBUTE 1" >>confdefs.h
fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for -misa-spec= support" >&5
+$as_echo_n "checking assembler for -misa-spec= support... " >&6; }
+if ${gcc_cv_as_riscv_isa_spec+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcc_cv_as_riscv_isa_spec=no
+ if test x$gcc_cv_as != x; then
+ $as_echo '' > conftest.s
+ if { ac_try='$gcc_cv_as $gcc_cv_as_flags -misa-spec=2.2 -o conftest.o conftest.s >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ then
+ gcc_cv_as_riscv_isa_spec=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_riscv_isa_spec" >&5
+$as_echo "$gcc_cv_as_riscv_isa_spec" >&6; }
+if test $gcc_cv_as_riscv_isa_spec = yes; then
+
+$as_echo "#define HAVE_AS_MISA_SPEC 1" >>confdefs.h
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for -march=rv32i_zifencei support" >&5
+$as_echo_n "checking assembler for -march=rv32i_zifencei support... " >&6; }
+if ${gcc_cv_as_riscv_march_zifencei+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcc_cv_as_riscv_march_zifencei=no
+ if test x$gcc_cv_as != x; then
+ $as_echo '' > conftest.s
+ if { ac_try='$gcc_cv_as $gcc_cv_as_flags -march=rv32i_zifencei -o conftest.o conftest.s >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ then
+ gcc_cv_as_riscv_march_zifencei=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_riscv_march_zifencei" >&5
+$as_echo "$gcc_cv_as_riscv_march_zifencei" >&6; }
+if test $gcc_cv_as_riscv_march_zifencei = yes; then
+
+$as_echo "#define HAVE_AS_MARCH_ZIFENCEI 1" >>confdefs.h
+
+fi
+
;;
s390*-*-*)
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .gnu_attribute support" >&5
@@ -30474,6 +30834,31 @@ else
fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to serialize linking of multiple front-ends" >&5
+$as_echo_n "checking whether to serialize linking of multiple front-ends... " >&6; }
+ # Check whether --enable-link-serialization was given.
+if test "${enable_link_serialization+set}" = set; then :
+ enableval=$enable_link_serialization; do_link_serialization=$enableval
+else
+ do_link_serialization=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $do_link_serialization" >&5
+$as_echo "$do_link_serialization" >&6; }
+
+case "$do_link_serialization" in
+ yes)
+ DO_LINK_SERIALIZATION=1;;
+ [1-9] | [1-9][0-9] | [1-9][0-9][0-9])
+ DO_LINK_SERIALIZATION=$do_link_serialization;;
+ no)
+ DO_LINK_SERIALIZATION=;;
+ *)
+ as_fn_error $? "bad value ${do_link_serialization} given for --enable-link-serialization" "$LINENO" 5 ;;
+esac
+
+
# --------------
# Language hooks
# --------------
@@ -30634,6 +31019,43 @@ do
echo "lang.$t: $x" >> Make-hooks
done
+echo "ifeq (\$(DO_LINK_SERIALIZATION),)" >> Make-hooks
+echo "SERIAL_LIST =" >> Make-hooks
+echo else >> Make-hooks
+lang_cnt=0
+lang_list=
+prev=c
+serialization_languages=c
+for lang in $all_selected_languages
+do
+ test $lang = c && continue
+ if test $lang = lto; then
+ serialization_languages="$serialization_languages lto1 lto2"
+ else
+ serialization_languages="$serialization_languages $lang"
+ fi
+done
+for lang in $serialization_languages
+do
+ test $lang = c && continue
+ lang_cnt=`expr $lang_cnt + 1`
+ lang_list=" $prev$lang_list"
+ prev=${lang}
+done
+echo "SERIAL_LIST = \$(wordlist \$(DO_LINK_SERIALIZATION),$lang_cnt,$lang_list)" >> Make-hooks
+echo endif >> Make-hooks
+echo "SERIAL_COUNT = `expr $lang_cnt + 1`" >> Make-hooks
+echo "INDEX.c = 0" >> Make-hooks
+lang_idx=1
+for lang in $serialization_languages
+do
+ test $lang = c && continue
+ echo "$lang.prev = \$(if \$(word $lang_cnt,\$(SERIAL_LIST)),\$(\$(word $lang_cnt,\$(SERIAL_LIST)).serial))" >> Make-hooks
+ echo "INDEX.$lang = $lang_idx" >> Make-hooks
+ lang_cnt=`expr $lang_cnt - 1`
+ lang_idx=`expr $lang_idx + 1`
+done
+
# --------
# Option include files
# --------
@@ -31420,6 +31842,75 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_pushpopstate_support" >&5
$as_echo "$ld_pushpopstate_support" >&6; }
+# On s390, float_t has historically been statically defined as double for no
+# good reason. To comply with the C standard in the light of this definition,
+# gcc has evaluated float expressions in double precision when in
+# standards-compatible mode or when given -fexcess-precision=standard. To enable
+# a smooth transition towards the new model used by most architectures, where
+# gcc describes its behavior via the macro __FLT_EVAL_METHOD__ and glibc derives
+# float_t from that, this behavior can be configured with
+# --enable-s390-excess-float-precision. When given as enabled, that flag selects
+# the old model. When omitted, native builds will derive the flag from the
+# behavior of glibc. When glibc clamps float_t to double, gcc follows the old
+# model. In any other case, it defaults to the new model.
+# Check whether --enable-s390-excess-float-precision was given.
+if test "${enable_s390_excess_float_precision+set}" = set; then :
+ enableval=$enable_s390_excess_float_precision;
+else
+ enable_s390_excess_float_precision=auto
+fi
+
+
+case $target in
+ s390*-linux*)
+ if test "$target" = "$host" -a "$host" = "$build" -a \
+ x"$enable_s390_excess_float_precision" = xauto; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glibc clamping float_t to double" >&5
+$as_echo_n "checking for glibc clamping float_t to double... " >&6; }
+if ${gcc_cv_float_t_clamped_to_double+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define __FLT_EVAL_METHOD__ 0
+#include <math.h>
+int main() {
+ return !(sizeof(float_t) == sizeof(double));
+}
+_ACEOF
+if ac_fn_cxx_try_run "$LINENO"; then :
+ gcc_cv_float_t_clamped_to_double=yes
+else
+ gcc_cv_float_t_clamped_to_double=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_float_t_clamped_to_double" >&5
+$as_echo "$gcc_cv_float_t_clamped_to_double" >&6; }
+ if test x"$gcc_cv_float_t_clamped_to_double" = xyes; then
+ enable_s390_excess_float_precision=yes
+ fi
+ fi
+
+
+ if test x"$enable_s390_excess_float_precision" = xyes; then
+
+$as_echo "#define ENABLE_S390_EXCESS_FLOAT_PRECISION 1" >>confdefs.h
+
+ fi
+ ;;
+esac
+
# Configure the subdirectories
# AC_CONFIG_SUBDIRS($subdirs)
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 73034bb..062f57f 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -1417,8 +1417,8 @@ define(gcc_UNLOCKED_FUNCS, clearerr_unlocked feof_unlocked dnl
putchar_unlocked putc_unlocked)
AC_CHECK_FUNCS(times clock kill getrlimit setrlimit atoq \
popen sysconf strsignal getrusage nl_langinfo \
- gettimeofday mbstowcs wcswidth mmap setlocale \
- gcc_UNLOCKED_FUNCS madvise mallinfo mallinfo2)
+ gettimeofday mbstowcs wcswidth mmap posix_fallocate setlocale \
+ gcc_UNLOCKED_FUNCS madvise mallinfo mallinfo2 fstatat)
if test x$ac_cv_func_mbstowcs = xyes; then
AC_CACHE_CHECK(whether mbstowcs works, gcc_cv_func_mbstowcs_works,
@@ -1440,6 +1440,10 @@ fi
AC_CHECK_TYPE(ssize_t, int)
AC_CHECK_TYPE(caddr_t, char *)
+AC_CHECK_TYPE(sighander_t,
+ AC_DEFINE(HAVE_SIGHANDLER_T, 1,
+ [Define if <sys/signal.h> defines sighandler_t]),
+ ,signal.h)
GCC_AC_FUNC_MMAP_BLACKLIST
@@ -1585,6 +1589,72 @@ if test $ac_cv_f_setlkw = yes; then
[Define if F_SETLKW supported by fcntl.])
fi
+# Check if O_CLOEXEC is defined by fcntl
+AC_CACHE_CHECK(for O_CLOEXEC, ac_cv_o_cloexec, [
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <fcntl.h>]], [[
+return open ("/dev/null", O_RDONLY | O_CLOEXEC);]])],
+[ac_cv_o_cloexec=yes],[ac_cv_o_cloexec=no])])
+if test $ac_cv_o_cloexec = yes; then
+ AC_DEFINE(HOST_HAS_O_CLOEXEC, 1,
+ [Define if O_CLOEXEC supported by fcntl.])
+fi
+
+# C++ Modules would like some networking features to provide the mapping
+# server. You can still use modules without them though.
+# The following network-related checks could probably do with some
+# Windows and other non-linux defenses and checking.
+
+# Local socket connectivity wants AF_UNIX networking
+# Check for AF_UNIX networking
+AC_CACHE_CHECK(for AF_UNIX, ac_cv_af_unix, [
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>]],[[
+sockaddr_un un;
+un.sun_family = AF_UNSPEC;
+int fd = socket (AF_UNIX, SOCK_STREAM, 0);
+connect (fd, (sockaddr *)&un, sizeof (un));]])],
+[ac_cv_af_unix=yes],
+[ac_cv_af_unix=no])])
+if test $ac_cv_af_unix = yes; then
+ AC_DEFINE(HAVE_AF_UNIX, 1,
+ [Define if AF_UNIX supported.])
+fi
+
+# Remote socket connectivity wants AF_INET6 networking
+# Check for AF_INET6 networking
+AC_CACHE_CHECK(for AF_INET6, ac_cv_af_inet6, [
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>]],[[
+sockaddr_in6 in6;
+in6.sin6_family = AF_UNSPEC;
+struct addrinfo *addrs = 0;
+struct addrinfo hints;
+hints.ai_flags = 0;
+hints.ai_family = AF_INET6;
+hints.ai_socktype = SOCK_STREAM;
+hints.ai_protocol = 0;
+hints.ai_canonname = 0;
+hints.ai_addr = 0;
+hints.ai_next = 0;
+int e = getaddrinfo ("localhost", 0, &hints, &addrs);
+const char *str = gai_strerror (e);
+freeaddrinfo (addrs);
+int fd = socket (AF_INET6, SOCK_STREAM, 0);
+connect (fd, (sockaddr *)&in6, sizeof (in6));]])],
+[ac_cv_af_inet6=yes],
+[ac_cv_af_inet6=no])])
+if test $ac_cv_af_inet6 = yes; then
+ AC_DEFINE(HAVE_AF_INET6, 1,
+ [Define if AF_INET6 supported.])
+fi
+
# Restore CFLAGS, CXXFLAGS from before the gcc_AC_NEED_DECLARATIONS tests.
CFLAGS="$saved_CFLAGS"
CXXFLAGS="$saved_CXXFLAGS"
@@ -2807,6 +2877,41 @@ Valid choices are 'yes' and 'no'.]) ;;
esac],
[enable_gnu_indirect_function="$default_gnu_indirect_function"])
+case "${target}" in
+ riscv*-*-linux*)
+ AC_MSG_CHECKING(linker ifunc IRELATIVE support)
+ cat > conftest.s <<EOF
+ .text
+ .type foo_resolver, @function
+foo_resolver:
+ ret
+ .size foo_resolver, .-foo_resolver
+
+ .globl foo
+ .type foo, %gnu_indirect_function
+ .set foo, foo_resolver
+
+ .globl bar
+ .type bar, @function
+bar:
+ call foo
+ ret
+ .size bar, .-bar
+EOF
+ if test x$gcc_cv_as != x \
+ && test x$gcc_cv_ld != x \
+ && test x$gcc_cv_readelf != x \
+ && $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \
+ && $gcc_cv_ld -o conftest conftest.o > /dev/null 2>&1 \
+ && $gcc_cv_readelf --relocs --wide conftest \
+ | grep R_RISCV_IRELATIVE > /dev/null 2>&1; then
+ enable_gnu_indirect_function=yes
+ fi
+ rm -f conftest conftest.o conftest.s
+ AC_MSG_RESULT($enable_gnu_indirect_function)
+ ;;
+esac
+
gif=`if test x$enable_gnu_indirect_function = xyes; then echo 1; else echo 0; fi`
AC_DEFINE_UNQUOTED(HAVE_GNU_INDIRECT_FUNCTION, $gif,
[Define if your system supports gnu indirect functions.])
@@ -2967,34 +3072,38 @@ AC_MSG_RESULT($gcc_cv_ld_ro_rw_mix)
gcc_AC_INITFINI_ARRAY
# Check if we have .[us]leb128, and support symbol arithmetic with it.
+# Older versions of GAS and some non-GNU assemblers, have a bugs handling
+# these directives, even when they appear to accept them.
gcc_GAS_CHECK_FEATURE([.sleb128 and .uleb128], gcc_cv_as_leb128,
- [elf,2,11,0],,
+ [elf,2,11,0],,
[ .data
.uleb128 L2 - L1
L1:
.uleb128 1280
.sleb128 -1010
-L2:],
-[[# GAS versions before 2.11 do not support uleb128,
- # despite appearing to.
- # ??? There exists an elf-specific test that will crash
- # the assembler. Perhaps it's better to figure out whether
- # arbitrary sections are supported and try the test.
- as_ver=`$gcc_cv_as --version 2>/dev/null | sed 1q`
- if echo "$as_ver" | grep GNU > /dev/null; then
- as_vers=`echo $as_ver | sed -n \
- -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*.*\)$,\1,p'`
- as_major=`expr "$as_vers" : '\([0-9]*\)'`
- as_minor=`expr "$as_vers" : '[0-9]*\.\([0-9]*\)'`
- if test $as_major -eq 2 && test $as_minor -lt 11
- then :
- else gcc_cv_as_leb128=yes
- fi
- fi]],
- [AC_DEFINE(HAVE_AS_LEB128, 1,
- [Define if your assembler supports .sleb128 and .uleb128.])],
- [AC_DEFINE(HAVE_AS_LEB128, 0,
- [Define if your assembler supports .sleb128 and .uleb128.])])
+L2:
+ .uleb128 0x8000000000000000
+],
+[[
+if test "x$gcc_cv_objdump" != x; then
+ if $gcc_cv_objdump -s conftest.o 2>/dev/null \
+ | grep '04800a8e 78808080 80808080 808001' >/dev/null; then
+ gcc_cv_as_leb128=yes
+ fi
+elif test "x$gcc_cv_otool" != x; then
+ if $gcc_cv_otool -d conftest.o 2>/dev/null \
+ | grep '04 80 0a 8e 78 80 80 80 80 80 80 80 80 80 01' >/dev/null; then
+ gcc_cv_as_leb128=yes
+ fi
+else
+ # play safe, assume the assembler is broken.
+ :
+fi
+]],
+ [AC_DEFINE(HAVE_AS_LEB128, 1,
+ [Define if your assembler supports .sleb128 and .uleb128.])],
+ [AC_DEFINE(HAVE_AS_LEB128, 0,
+ [Define if your assembler supports .sleb128 and .uleb128.])])
# Determine if an .eh_frame section is read-only.
gcc_fn_eh_frame_ro () {
@@ -3221,6 +3330,48 @@ AC_DEFINE_UNQUOTED(HAVE_GAS_SECTION_EXCLUDE,
[`if test $gcc_cv_as_section_exclude_e = yes || test $gcc_cv_as_section_exclude_hash = yes; then echo 1; else echo 0; fi`],
[Define if your assembler supports specifying the exclude section flag.])
+# Test if the assembler supports the section flag 'R' for specifying
+# section with SHF_GNU_RETAIN.
+case "${target}" in
+ # Solaris may use GNU assembler with Solairs ld. Even if GNU
+ # assembler supports the section flag 'R', it doesn't mean that
+ # Solairs ld supports it.
+ *-*-solaris2*)
+ gcc_cv_as_shf_gnu_retain=no
+ ;;
+ *)
+ gcc_GAS_CHECK_FEATURE([section 'R' flag], gcc_cv_as_shf_gnu_retain,
+ [elf,2,36,0], [--fatal-warnings],
+ [.section .foo,"awR",%progbits
+.byte 0])
+ ;;
+esac
+AC_DEFINE_UNQUOTED(HAVE_GAS_SHF_GNU_RETAIN,
+ [`if test $gcc_cv_as_shf_gnu_retain = yes; then echo 1; else echo 0; fi`],
+ [Define 0/1 if your assembler supports marking sections with SHF_GNU_RETAIN flag.])
+
+# Test if the assembler supports the section flag 'o' for specifying
+# section with link-order.
+case "${target}" in
+ # Solaris may use GNU assembler with Solairs ld. Even if GNU
+ # assembler supports the section flag 'o', it doesn't mean that
+ # Solairs ld supports it.
+ *-*-solaris2*)
+ gcc_cv_as_section_link_order=no
+ ;;
+ *)
+ gcc_GAS_CHECK_FEATURE([section 'o' flag], gcc_cv_as_section_link_order,
+ [2,35,0], [--fatal-warnings],
+ [.section .foo,"a"
+.byte 0
+.section __patchable_function_entries,"awo",%progbits,.foo
+.byte 0])
+ ;;
+esac
+AC_DEFINE_UNQUOTED(HAVE_GAS_SECTION_LINK_ORDER,
+ [`if test $gcc_cv_as_section_link_order = yes; then echo 1; else echo 0; fi`],
+ [Define 0/1 if your assembler supports 'o' flag in .section directive.])
+
gcc_GAS_CHECK_FEATURE(section merging support, gcc_cv_as_shf_merge,
[elf,2,12,0], [--fatal-warnings],
[.section .rodata.str, "aMS", @progbits, 1])
@@ -5076,6 +5227,16 @@ configured with --enable-newlib-nano-formatted-io.])
[.attribute stack_align,4],,
[AC_DEFINE(HAVE_AS_RISCV_ATTRIBUTE, 1,
[Define if your assembler supports .attribute.])])
+ gcc_GAS_CHECK_FEATURE([-misa-spec= support],
+ gcc_cv_as_riscv_isa_spec,,
+ [-misa-spec=2.2],,,
+ [AC_DEFINE(HAVE_AS_MISA_SPEC, 1,
+ [Define if the assembler understands -misa-spec=.])])
+ gcc_GAS_CHECK_FEATURE([-march=rv32i_zifencei support],
+ gcc_cv_as_riscv_march_zifencei,,
+ [-march=rv32i_zifencei],,,
+ [AC_DEFINE(HAVE_AS_MARCH_ZIFENCEI, 1,
+ [Define if the assembler understands -march=rv*_zifencei.])])
;;
s390*-*-*)
gcc_GAS_CHECK_FEATURE([.gnu_attribute support],
@@ -6631,6 +6792,29 @@ else
fi
AC_SUBST(DO_LINK_MUTEX)
+dnl Whether to prevent multiple GCC front-ends from linking at the same time
+
+AC_MSG_CHECKING([whether to serialize linking of multiple front-ends])
+ AC_ARG_ENABLE(link-serialization,
+[AS_HELP_STRING([--enable-link-serialization],
+ [avoid linking multiple GCC front-ends at once using make
+ dependencies to avoid thrashing on the build machine])],
+ do_link_serialization=$enableval,
+ do_link_serialization=no)
+AC_MSG_RESULT($do_link_serialization)
+
+case "$do_link_serialization" in
+ yes)
+ DO_LINK_SERIALIZATION=1;;
+ [[1-9]] | [[1-9]][[0-9]] | [[1-9]][[0-9]][[0-9]])
+ DO_LINK_SERIALIZATION=$do_link_serialization;;
+ no)
+ DO_LINK_SERIALIZATION=;;
+ *)
+ AC_MSG_ERROR(bad value ${do_link_serialization} given for --enable-link-serialization) ;;
+esac
+AC_SUBST(DO_LINK_SERIALIZATION)
+
# --------------
# Language hooks
# --------------
@@ -6791,6 +6975,43 @@ do
echo "lang.$t: $x" >> Make-hooks
done
+echo "ifeq (\$(DO_LINK_SERIALIZATION),)" >> Make-hooks
+echo "SERIAL_LIST =" >> Make-hooks
+echo else >> Make-hooks
+lang_cnt=0
+lang_list=
+prev=c
+serialization_languages=c
+for lang in $all_selected_languages
+do
+ test $lang = c && continue
+ if test $lang = lto; then
+ serialization_languages="$serialization_languages lto1 lto2"
+ else
+ serialization_languages="$serialization_languages $lang"
+ fi
+done
+for lang in $serialization_languages
+do
+ test $lang = c && continue
+ lang_cnt=`expr $lang_cnt + 1`
+ lang_list=" $prev$lang_list"
+ prev=${lang}
+done
+echo "SERIAL_LIST = \$(wordlist \$(DO_LINK_SERIALIZATION),$lang_cnt,$lang_list)" >> Make-hooks
+echo endif >> Make-hooks
+echo "SERIAL_COUNT = `expr $lang_cnt + 1`" >> Make-hooks
+echo "INDEX.c = 0" >> Make-hooks
+lang_idx=1
+for lang in $serialization_languages
+do
+ test $lang = c && continue
+ echo "$lang.prev = \$(if \$(word $lang_cnt,\$(SERIAL_LIST)),\$(\$(word $lang_cnt,\$(SERIAL_LIST)).serial))" >> Make-hooks
+ echo "INDEX.$lang = $lang_idx" >> Make-hooks
+ lang_cnt=`expr $lang_cnt - 1`
+ lang_idx=`expr $lang_idx + 1`
+done
+
# --------
# Option include files
# --------
@@ -7143,6 +7364,51 @@ if test x"$ld_pushpopstate_support" = xyes; then
fi
AC_MSG_RESULT($ld_pushpopstate_support)
+# On s390, float_t has historically been statically defined as double for no
+# good reason. To comply with the C standard in the light of this definition,
+# gcc has evaluated float expressions in double precision when in
+# standards-compatible mode or when given -fexcess-precision=standard. To enable
+# a smooth transition towards the new model used by most architectures, where
+# gcc describes its behavior via the macro __FLT_EVAL_METHOD__ and glibc derives
+# float_t from that, this behavior can be configured with
+# --enable-s390-excess-float-precision. When given as enabled, that flag selects
+# the old model. When omitted, native builds will derive the flag from the
+# behavior of glibc. When glibc clamps float_t to double, gcc follows the old
+# model. In any other case, it defaults to the new model.
+AC_ARG_ENABLE(s390-excess-float-precision,
+ [AS_HELP_STRING([--enable-s390-excess-float-precision],
+ [on s390 targets, evaluate float with double precision
+ when in standards-conforming mode])],
+ [],[enable_s390_excess_float_precision=auto])
+
+case $target in
+ s390*-linux*)
+ if test "$target" = "$host" -a "$host" = "$build" -a \
+ x"$enable_s390_excess_float_precision" = xauto; then
+ AC_CACHE_CHECK([for glibc clamping float_t to double],
+ gcc_cv_float_t_clamped_to_double,
+ [AC_RUN_IFELSE([AC_LANG_SOURCE([
+#define __FLT_EVAL_METHOD__ 0
+#include <math.h>
+int main() {
+ return !(sizeof(float_t) == sizeof(double));
+}])],
+ [gcc_cv_float_t_clamped_to_double=yes],
+ [gcc_cv_float_t_clamped_to_double=no])])
+ if test x"$gcc_cv_float_t_clamped_to_double" = xyes; then
+ enable_s390_excess_float_precision=yes
+ fi
+ fi
+
+ GCC_TARGET_TEMPLATE(ENABLE_S390_EXCESS_FLOAT_PRECISION)
+ if test x"$enable_s390_excess_float_precision" = xyes; then
+ AC_DEFINE(ENABLE_S390_EXCESS_FLOAT_PRECISION, 1,
+[Define to enable evaluating float expressions with double precision in
+standards-compatible mode on s390 targets.])
+ fi
+ ;;
+esac
+
# Configure the subdirectories
# AC_CONFIG_SUBDIRS($subdirs)
diff --git a/gcc/coverage.c b/gcc/coverage.c
index 7711412..d299e48 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -1097,6 +1097,25 @@ build_gcov_exit_decl (void)
cgraph_build_static_cdtor ('D', dtor, priority);
}
+/* Generate the pointer to the gcov_info_var in a dedicated section. */
+
+static void
+build_gcov_info_var_registration (tree gcov_info_type)
+{
+ tree var = build_decl (BUILTINS_LOCATION,
+ VAR_DECL, NULL_TREE,
+ build_pointer_type (gcov_info_type));
+ TREE_STATIC (var) = 1;
+ TREE_READONLY (var) = 1;
+ char name_buf[32];
+ ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 2);
+ DECL_NAME (var) = get_identifier (name_buf);
+ get_section (profile_info_section, SECTION_UNNAMED, NULL);
+ set_decl_section_name (var, profile_info_section);
+ DECL_INITIAL (var) = build_fold_addr_expr (gcov_info_var);
+ varpool_node::finalize_decl (var);
+}
+
/* Create the gcov_info types and object. Generate the constructor
function to call __gcov_init. Does not generate the initializer
for the object. Returns TRUE if coverage data is being emitted. */
@@ -1151,8 +1170,13 @@ coverage_obj_init (void)
ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
DECL_NAME (gcov_info_var) = get_identifier (name_buf);
- build_init_ctor (gcov_info_type);
- build_gcov_exit_decl ();
+ if (profile_info_section)
+ build_gcov_info_var_registration (gcov_info_type);
+ else
+ {
+ build_init_ctor (gcov_info_type);
+ build_gcov_exit_decl ();
+ }
return true;
}
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9c36b80..6728ea1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,473 @@
+2020-12-03 Peter Bergner <bergner@linux.ibm.com>
+
+ PR c++/97947
+ * typeck2.c (digest_init_r): Handle OPAQUE_TYPE as an aggregate type.
+
+2020-12-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/80780
+ PR c++/93093
+ * cp-tree.h (source_location_current_p): Declare.
+ * tree.c (source_location_current_p): New function.
+ * call.c (immediate_invocation_p): New function.
+ (build_over_call): Use it to resolve LWG3396.
+ * constexpr.c (cxx_eval_builtin_function_call): Temporarily set
+ current_function_decl from ctx->call->fundef->decl if any.
+ * cp-gimplify.c (cp_genericize_r) <case CALL_EXPR>: Fold calls
+ to immediate function std::source_location::current ().
+
+2020-12-02 Jason Merrill <jason@redhat.com>
+
+ * decl.c (grokdeclarator): Improve diagnostic for
+ disallowed CTAD placeholder.
+
+2020-12-02 Jason Merrill <jason@redhat.com>
+
+ * decl.c (check_initializer): Also look through STMT_EXPR
+ and BIND_EXPR.
+
+2020-12-02 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (comparing_typenames): Declare.
+ * pt.c (comparing_typenames): Define.
+ (spec_hasher::equal): Increment it around comparisons.
+ * typeck.c (structural_comptypes): Adjust TYPENAME resolution
+ check.
+
+2020-12-02 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97975
+ * constexpr.c (fold_non_dependent_init): Add a tree parameter.
+ Use it.
+ * cp-tree.h (fold_non_dependent_init): Add a tree parameter with
+ a default value.
+ * typeck2.c (store_init_value): Call fold_non_dependent_expr
+ only when checking the initializer for constexpr variables.
+ Call fold_non_dependent_init instead of maybe_constant_init.
+
+2020-12-02 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97187
+ PR c++/97993
+ * pt.c (tsubst_copy_and_build) <case NEW_EXPR>: Return error_mark_node
+ if init is erroneous.
+
+2020-12-02 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (DECL_MODULE_PURVIEW_P, DECL_MODULE_IMPORT_P)
+ (DECL_MODULE_ENTITY_P): New.
+ (DECL_MODULE_PENDING_SPECIALIZATIONS_P): New.
+ (DECL_MODULE_PENDING_MEMBERS_P): New.
+ (DECL_MODULE_ATTACHMENTS_P): New.
+ (DECL_MODULE_EXPORT_P): New.
+ (struct lang_decl_base): Shrink sel field. Add new
+ module-specific fields.
+
+2020-12-02 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (DECL_TINFO_P): Also for TYPE_DECLs.
+ (get_tinfo_decl_direct): Declare.
+ (get_pseudo_tinfo_index, get_pseudo_tinfo_type): Declare.
+ * rtti.c (get_tinfo_decl_direct): Externalize.
+ (get_tinfo_desc): Set DECL_TINFO_P on the typedef.
+ (get_pseudo_tinfo_index, get_pseudo_tinfo_type): New.
+
+2020-12-02 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (maybe_add_lang_decl_raw, maybe_add_lang_type_raw):
+ Declare.
+ * lex.c (maybe_add_lang_decl_raw, maybe_add_lang_type_raw):
+ Externalize, reformat.
+
+2020-12-02 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (build_cplus_array_type): Add defaulted DEP parm.
+ * tree.c (set_array_type_common): Add DEP parm.
+ (build_cplus_array_type): Add DEP parm, determine dependency if
+ needed.
+ (cp_build_qualified_type_real): Adjust array-building call.
+ (strip_typedefs): Likewise.
+
+2020-12-02 Nathan Sidwell <nathan@acm.org>
+
+ * ptree.c (cxx_print_xnode): Increase binding-vector prefix size.
+
+2020-12-02 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.def (BINDING_VECTOR): New.
+ * name-lookup.h (struct binding_slot): New.
+ (BINDING_VECTOR_SLOTS_PER_CLUSTER): New.
+ (struct binding_index, struct binding_cluster): New.
+ (BINDING_VECTOR_ALLOC_CLUSTERS, BINDING_VECTOR_CLUSTER_BASE)
+ (BINDING_VECTOR_CLUSTER): New.
+ (struct tree_binding_vec): New.
+ (BINDING_VECTOR_NAME, BINDING_VECTOR_GLOBAL_DUPS_P)
+ (BINDING_VECTOR_PARTITION_DUPS_P): New.
+ (BINDING_BINDING_GLOBAL_P, BINDING_BINDING_PARTITION_P): New.
+ (BINDING_VECTOR_PENDING_SPECIALIZATIONS)
+ (BINDING_VECTOR_PENDING_IS_HEADER_P)
+ (BINDING_VECTOR_PENDING_IS_PARTITION_P): New.
+ * cp-tree.h (enum cp_tree_node_structure_enum): Add
+ TS_CP_BINDING_VECTOR.
+ (union lang_tree_node): Add binding_vec field.
+ (make_binding_vec): Declare.
+ (named_decl_hash::hash, named_decl_hash::equal): Check for binding
+ vector.
+ * decl.c (cp_tree_node_structure): Add BINDING_VECTOR case.
+ * ptree.c (cxx_print_xnode): Add BINDING_VECTOR case.
+ * tree.c (make_binding_vec): New.
+
+2020-12-01 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ PR c++/98054
+ * cxx-pretty-print.c (pp_cxx_trait_expression):
+ Add support for __is_nothrow_{assignable,constructible}.
+
+2020-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/98072
+ * parser.c (cp_parser_omp_depobj): Suppress location wrappers when
+ parsing depend clause.
+
+2020-12-01 Nathan Sidwell <nathan@acm.org>
+
+ * lex.c (init_reswords): Maybe enable module keywords.
+
+2020-12-01 Nathan Sidwell <nathan@acm.org>
+
+ * lang-specs.h: Add module-related options.
+
+2020-12-01 Iain Sandoe <iain@sandoe.co.uk>
+
+ * parser.c (cp_parser_declaration): Add a not about where
+ attributes may be placed.
+
+2020-11-27 Martin Sebor <msebor@redhat.com>
+
+ * error.c (add_quotes): Revert previous change and use pragma to
+ suppress -Wformat-diag.
+
+2020-11-26 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * g++spec.c (TIMELIB, TIME_LIBRARY): Remove.
+ (lang_specific_driver): Remove TIME_LIBRARY handling.
+
+2020-11-26 Thomas Schwinge <thomas@codesourcery.com>
+
+ * parser.c (cp_parser_omp_var_list_no_open): Assert that array
+ section's 'low_bound', 'length' are not location wrapper nodes.
+ (cp_parser_oacc_all_clauses, cp_parser_oacc_cache): Instantiate
+ 'auto_suppress_location_wrappers'.
+
+2020-11-25 Martin Sebor <msebor@redhat.com>
+
+ PR bootstrap/94982
+ * constraint.cc (debug_argument_list): Avoid -Wformat-diag.
+ * error.c (function_category): Same.
+ (print_template_differences): Same.
+ * logic.cc (debug): Same.
+ * name-lookup.c (lookup_using_decl): Same.
+ * parser.c (maybe_add_cast_fixit): Same.
+ (cp_parser_template_introduction): Same.
+ * typeck.c (access_failure_info::add_fixit_hint): Same.
+
+2020-11-25 Thomas Schwinge <thomas@codesourcery.com>
+
+ * pt.c (tsubst_omp_clauses): Handle 'OMP_CLAUSE__CACHE_'.
+ (tsubst_expr): Handle 'OACC_CACHE'.
+
+2020-11-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/97899
+ * typeck2.c (store_init_value): Don't split_nonconstant_init in a
+ template.
+
+2020-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/96929
+ * constexpr.c (cxx_eval_binary_expression): For shifts by constant
+ with MSB set, emulate older wide_int_binop behavior to preserve
+ diagnostics and -fpermissive behavior.
+
+2020-11-23 Nathan Sidwell <nathan@acm.org>
+
+ * module.cc: New dummy file.
+ * Make-lang.in: Add rules to build module.o
+
+2020-11-23 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * decl.c (start_decl): Set DECL_INITIAL for initialized decls
+ before attribute processing.
+
+2020-11-23 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR c++/97904
+ * pt.c (tsubst): Use verify_type_context to check the type
+ of an array element.
+
+2020-11-21 Marek Polacek <polacek@redhat.com>
+
+ PR c++/94695
+ * parser.c (warn_for_range_copy): Warn when the loop variable is
+ initialized with a value of a different type resulting in a copy.
+
+2020-11-21 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97846
+ * constexpr.c (potential_constant_expression_1): Reject
+ LABEL_EXPRs that use non-artifical LABEL_DECLs.
+
+2020-11-21 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97881
+ * parser.c (warn_about_ambiguous_parse): Only assume "int" if we
+ actually saw any type-specifiers.
+
+2020-11-21 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97839
+ * parser.c (cp_parser_lambda_declarator_opt): Don't require ().
+
+2020-11-21 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97427
+ * constexpr.c (cxx_set_object_constness): New function.
+ (cxx_eval_call_expression): Set new_obj for destructors too.
+ Call cxx_set_object_constness to set/unset TREE_READONLY of
+ the object under construction/destruction.
+
+2020-11-21 Aaron Sawdey <acsawdey@linux.ibm.com>
+
+ * error.c (dump_type): Handle opaque types.
+ (dump_type_prefix): Handle opaque types.
+ (dump_type_suffix): Handle opaque types.
+ (dump_expr): Handle opaque types.
+ * pt.c (tsubst): Allow opaque types in templates.
+ (unify): Allow opaque types in templates.
+ * typeck.c (structural_comptypes): Handle comparison
+ of opaque types.
+
+2020-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/97911
+ * Make-lang.in (c++.serial): Change from goal to a variable.
+ (.PHONY): Drop c++.serial and c++.prev.
+ (cc1plus$(exeext)): Depend on $(c++.serial) rather than c++.serial.
+
+2020-11-19 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (struct spec_entry): Moved from pt.c.
+ (walk_specializations, match_mergeable_specialization)
+ (get_mergeable_specialization_flags)
+ (add_mergeable_specialization): Declare.
+ * pt.c (struct spec_entry): Moved to cp-tree.h.
+ (walk_specializations, match_mergeable_specialization)
+ (get_mergeable_specialization_flags)
+ (add_mergeable_specialization): New.
+
+2020-11-19 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (struct constexpr_fundef): Moved from constexpr.c.
+ (maybe_save_constexpr_fundef): Declare.
+ (register_constexpr_fundef): Take constexpr_fundef object, return
+ void.
+ * decl.c (mabe_save_function_definition): Delete, functionality
+ moved to maybe_save_constexpr_fundef.
+ (emit_coro_helper, finish_function): Adjust.
+ * constexpr.c (struct constexpr_fundef): Moved to cp-tree.h.
+ (constexpr_fundef_hasher::equal): Constify.
+ (constexpr_fundef_hasher::hash): Constify.
+ (retrieve_constexpr_fundef): Make non-static.
+ (maybe_save_constexpr_fundef): Break out checking and duplication
+ from ...
+ (register_constexpr_fundef): ... here. Just register the constexpr.
+
+2020-11-19 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97523
+ * init.c (build_new): When value-initializing an array new,
+ leave the INIT as an empty vector.
+
+2020-11-19 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97895
+ * pt.c (do_auto_deduction): Don't crash when the constructor has
+ zero elements.
+
+2020-11-19 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/97905
+ * decl.c (duplicate_decls): Relax new assert.
+
+2020-11-18 Iain Sandoe <iain@sandoe.co.uk>
+
+ * parser.c (cp_parser_objc_valid_prefix_attributes): Check
+ for empty attributes.
+
+2020-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ * Make-lang.in (c++.serial): New goal.
+ (.PHONY): Add c++.serial c++.prev.
+ (cc1plus$(exeext)): Depend on c++.prev. Call LINK_PROGRESS.
+
+2020-11-17 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/97877
+ * decl.c (duplicate_decls): Deal with duplicated DECL_LOCAL_DECL_P
+ decls. Extend decl_lang_specific checking assert.
+
+2020-11-17 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (enum cp_tree_index): Reorder to place lazy fields
+ after newly-added CPTI_MODULE_HWM.
+
+2020-11-17 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR c++/97871
+ * parser.c (cp_parser_declaration): Remove checking assert.
+
+2020-11-15 Jason Merrill <jason@redhat.com>
+
+ * decl.c (cp_finish_decl): Only check abstractness on definition.
+ (require_complete_types_for_parms): Check abstractness here.
+ (create_array_type_for_decl): Not here.
+ (grokdeclarator, grokparms, complete_vars): Not here.
+ * pt.c (tsubst, tsubst_arg_types, tsubst_function_type): Not here.
+ * typeck2.c (struct pending_abstract_type): Remove.
+ (struct abstract_type_hasher): Remove.
+ (abstract_pending_vars, complete_type_check_abstract): Remove.
+ (abstract_virtuals_error_sfinae): Handle arrays.
+ * call.c (conv_is_prvalue): Split out from...
+ (conv_binds_ref_to_prvalue): ...here.
+ (implicit_conversion_1): Rename from implicit_conversion.
+ (implicit_conversion): An abstract prvalue is bad.
+ (convert_like_internal): Don't complain if expr is already
+ error_mark_node.
+
+2020-11-13 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (USING_DECL_UNRELATED_P): New.
+ (CONST_DECL_USING_P): New.
+ * class.c (handle_using_decl): If USING_DECL_UNRELATED_P,
+ clone the CONST_DECL.
+ * name-lookup.c (supplement_binding_1): A clone hides its
+ using-declaration.
+ (lookup_using_decl): Rewrite to separate lookup and validation.
+ (do_class_using_decl): Adjust.
+ (finish_nonmember_using_decl): Adjust.
+ * parser.c (make_location): Add cp_token overload.
+ (finish_using_decl): Split out from...
+ (cp_parser_using_declaration): ...here. Don't look through enums.
+ (cp_parser_using_enum): New.
+ (cp_parser_block_declaration): Call it.
+ (cp_parser_member_declaration): Call it.
+ * semantics.c (finish_id_expression_1): Handle enumerator
+ used from class scope.
+
+2020-11-13 Vladimir N. Makarov <vmakarov@redhat.com>
+
+ * parser.c (cp_parser_asm_definition): Parse outputs for asm
+ goto too.
+
+2020-11-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR objc/77404
+ * parser.c (cp_parser_objc_class_interface): Pass the
+ location of the class name to the interface declaration.
+
+2020-11-13 Patrick Palka <ppalka@redhat.com>
+
+ * semantics.c (finish_compound_literal): Don't wrap the original
+ compound literal in a TARGET_EXPR when inside a template.
+
+2020-11-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/97790
+ * constexpr.c (cxx_eval_constant_expression) <case CLEANUP_POINT_EXPR,
+ case TRY_FINALLY_EXPR, case CLEANUP_STMT>: Don't pass jump_target to
+ cxx_eval_constant_expression when evaluating the cleanups.
+
+2020-11-11 Iain Sandoe <iain@sandoe.co.uk>
+
+ * parser.c (cp_parser_declaration): Unless we are compiling for
+ Ojective-C++, warn about and discard any attributes that prefix
+ a linkage specification.
+
+2020-11-11 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/88115
+ * mangle.c (write_expression): Mangle __alignof_ differently
+ from alignof when the ABI version is at least 15.
+
+2020-11-11 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/88115
+ * cp-tree.h (cxx_sizeof_or_alignof_expr): Add bool parameter.
+ * decl.c (fold_sizeof_expr): Pass false to
+ cxx_sizeof_or_alignof_expr.
+ * parser.c (cp_parser_unary_expression): Pass std_alignof to
+ cxx_sizeof_or_alignof_expr.
+ * pt.c (tsubst_copy): Pass false to cxx_sizeof_or_alignof_expr.
+ (tsubst_copy_and_build): Pass std_alignof to
+ cxx_sizeof_or_alignof_expr.
+ * typeck.c (cxx_alignof_expr): Add std_alignof bool parameter
+ and pass it to cxx_sizeof_or_alignof_type. Set ALIGNOF_EXPR_STD_P
+ appropriately.
+ (cxx_sizeof_or_alignof_expr): Add std_alignof bool parameter
+ and pass it to cxx_alignof_expr. Assert op is either
+ SIZEOF_EXPR or ALIGNOF_EXPR.
+
+2020-11-11 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97518
+ * pt.c (tsubst_qualified_id): Use EXPR_LOCATION of the qualified-id.
+ Use it to maybe_wrap_with_location the final expression.
+
+2020-11-10 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97518
+ * cp-tree.h (finish_static_assert): Adjust declaration.
+ * parser.c (cp_parser_static_assert): Pass false to
+ finish_static_assert.
+ * pt.c (tsubst_expr): Pass true to finish_static_assert.
+ * semantics.c (find_failing_clause_r): New function.
+ (find_failing_clause): New function.
+ (finish_static_assert): Add a bool parameter. Use
+ iloc_sentinel. Call contextual_conv_bool instead of
+ perform_implicit_conversion_flags. Don't check for INTEGER_CST before
+ calling integer_zerop. Call find_failing_clause and maybe use its
+ location. Print the original condition or the failing clause if
+ SHOW_EXPR_P.
+
+2020-11-10 Strager Neds <strager.nds@gmail.com>
+
+ * decl.c (duplicate_decls): Use new overload of
+ set_decl_section_name.
+ * method.c (use_thunk): Same.
+ * optimize.c (maybe_clone_body): Same.
+ * coroutines.cc (act_des_fn): Same.
+
+2020-11-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/97748
+ * cvt.c (convert_to_void): Check (complain & tf_warning) in the outer
+ if rather than twice times in the inner one. Use warn_if_unused_value.
+ Formatting fix.
+
+2020-11-10 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * parser.c (cp_parser_omp_target_data): Add use of
+ new c_omp_adjust_map_clauses function. Add GOMP_MAP_ATTACH_DETACH as
+ handled map clause kind.
+ (cp_parser_omp_target_enter_data): Likewise.
+ (cp_parser_omp_target_exit_data): Likewise.
+ (cp_parser_omp_target): Likewise.
+ * semantics.c (handle_omp_array_sections): Adjust COMPONENT_REF case to
+ use GOMP_MAP_ATTACH_DETACH map kind for C_ORT_OMP region type. Fix
+ interaction between reference case and attach/detach.
+ (finish_omp_clauses): Adjust bitmap checks to allow struct decl and
+ same struct field access to co-exist on OpenMP construct.
+
2020-11-09 Marek Polacek <polacek@redhat.com>
DR 1914
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 6ee4e41..ebfdc90 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -47,12 +47,16 @@ CP_PLUGIN_HEADERS := cp-tree.h cxx-pretty-print.h name-lookup.h type-utils.h ope
# into the C++ rule, but that needs a little bit of work
# to do the right thing within all.cross.
c++: cc1plus$(exeext)
+c++.serial = cc1plus$(exeext)
# Tell GNU make to ignore these if they exist.
.PHONY: c++
CFLAGS-cp/g++spec.o += $(DRIVER_DEFINES)
+CFLAGS-cp/module.o += -DHOST_MACHINE=\"$(host)\" \
+ -DTARGET_MACHINE=\"$(target)\"
+
# Create the compiler driver for g++.
GXX_OBJS = $(GCC_OBJS) cp/g++spec.o
xg++$(exeext): $(GXX_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a $(LIBDEPS)
@@ -80,7 +84,7 @@ CXX_AND_OBJCXX_OBJS = \
cp/error.o cp/except.o cp/expr.o \
cp/friend.o cp/init.o \
cp/lambda.o cp/lex.o cp/logic.o \
- cp/mangle.o cp/method.o \
+ cp/mangle.o cp/method.o cp/module.o \
cp/name-lookup.o cp/optimize.o \
cp/parser.o cp/pt.o cp/ptree.o \
cp/rtti.o \
@@ -116,9 +120,11 @@ cc1plus-checksum.c : build/genchecksum$(build_exeext) checksum-options \
$(srcdir)/../move-if-change cc1plus-checksum.c.tmp cc1plus-checksum.c; \
fi
-cc1plus$(exeext): $(CXX_OBJS) cc1plus-checksum.o $(BACKEND) $(LIBDEPS)
+cc1plus$(exeext): $(CXX_OBJS) cc1plus-checksum.o $(BACKEND) $(LIBDEPS) $(c++.prev)
+ @$(call LINK_PROGRESS,$(INDEX.c++),start)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(CXX_OBJS) cc1plus-checksum.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
+ @$(call LINK_PROGRESS,$(INDEX.c++),end)
ifeq ($(ENABLE_MAINTAINER_RULES), true)
# Special build rule. This is a maintainer rule, that is only
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 9861be1..f1e0bcb 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -213,6 +213,7 @@ static conversion *merge_conversion_sequences (conversion *, conversion *);
static tree build_temp (tree, tree, int, diagnostic_t *, tsubst_flags_t);
static conversion *build_identity_conv (tree, tree);
static inline bool conv_binds_to_array_of_unknown_bound (conversion *);
+static bool conv_is_prvalue (conversion *);
static tree prevent_lifetime_extension (tree);
/* Returns nonzero iff the destructor name specified in NAME matches BASETYPE.
@@ -1963,14 +1964,12 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
return conv;
}
-/* Returns the implicit conversion sequence (see [over.ics]) from type
- FROM to type TO. The optional expression EXPR may affect the
- conversion. FLAGS are the usual overloading flags. If C_CAST_P is
- true, this conversion is coming from a C-style cast. */
+/* Most of the implementation of implicit_conversion, with the same
+ parameters. */
static conversion *
-implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
- int flags, tsubst_flags_t complain)
+implicit_conversion_1 (tree to, tree from, tree expr, bool c_cast_p,
+ int flags, tsubst_flags_t complain)
{
conversion *conv;
@@ -2096,6 +2095,26 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
return NULL;
}
+/* Returns the implicit conversion sequence (see [over.ics]) from type
+ FROM to type TO. The optional expression EXPR may affect the
+ conversion. FLAGS are the usual overloading flags. If C_CAST_P is
+ true, this conversion is coming from a C-style cast. */
+
+static conversion *
+implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
+ int flags, tsubst_flags_t complain)
+{
+ conversion *conv = implicit_conversion_1 (to, from, expr, c_cast_p,
+ flags, complain);
+ if (!conv || conv->bad_p)
+ return conv;
+ if (conv_is_prvalue (conv)
+ && CLASS_TYPE_P (conv->type)
+ && CLASSTYPE_PURE_VIRTUALS (conv->type))
+ conv->bad_p = true;
+ return conv;
+}
+
/* Like implicit_conversion, but return NULL if the conversion is bad.
This is not static so that check_non_deducible_conversion can call it within
@@ -7407,7 +7426,7 @@ convert_like_internal (conversion *convs, tree expr, tree fn, int argnum,
else if (t->kind == ck_identity)
break;
}
- if (!complained)
+ if (!complained && expr != error_mark_node)
{
range_label_for_type_mismatch label (TREE_TYPE (expr), totype);
gcc_rich_location richloc (loc, &label);
@@ -8438,20 +8457,15 @@ unsafe_copy_elision_p (tree target, tree exp)
&& !AGGR_INIT_VIA_CTOR_P (init));
}
-/* True iff C is a conversion that binds a reference to a prvalue. */
+/* True IFF the result of the conversion C is a prvalue. */
static bool
-conv_binds_ref_to_prvalue (conversion *c)
+conv_is_prvalue (conversion *c)
{
- if (c->kind != ck_ref_bind)
- return false;
- if (c->need_temporary_p)
- return true;
-
- c = next_conversion (c);
-
if (c->kind == ck_rvalue)
return true;
+ if (c->kind == ck_base && c->need_temporary_p)
+ return true;
if (c->kind == ck_user && !TYPE_REF_P (c->type))
return true;
if (c->kind == ck_identity && c->u.expr
@@ -8461,6 +8475,19 @@ conv_binds_ref_to_prvalue (conversion *c)
return false;
}
+/* True iff C is a conversion that binds a reference to a prvalue. */
+
+static bool
+conv_binds_ref_to_prvalue (conversion *c)
+{
+ if (c->kind != ck_ref_bind)
+ return false;
+ if (c->need_temporary_p)
+ return true;
+
+ return conv_is_prvalue (next_conversion (c));
+}
+
/* True iff converting EXPR to a reference type TYPE does not involve
creating a temporary. */
@@ -8513,6 +8540,25 @@ build_trivial_dtor_call (tree instance, bool no_ptr_deref)
instance, clobber);
}
+/* Return true if a call to FN with number of arguments NARGS
+ is an immediate invocation. */
+
+static bool
+immediate_invocation_p (tree fn, int nargs)
+{
+ return (TREE_CODE (fn) == FUNCTION_DECL
+ && DECL_IMMEDIATE_FUNCTION_P (fn)
+ && cp_unevaluated_operand == 0
+ && (current_function_decl == NULL_TREE
+ || !DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
+ && (current_binding_level->kind != sk_function_parms
+ || !current_binding_level->immediate_fn_ctx_p)
+ /* As an exception, we defer std::source_location::current ()
+ invocations until genericization because LWG3396 mandates
+ special behavior for it. */
+ && (nargs > 1 || !source_location_current_p (fn)));
+}
+
/* Subroutine of the various build_*_call functions. Overload resolution
has chosen a winning candidate CAND; build up a CALL_EXPR accordingly.
ARGS is a TREE_LIST of the unconverted arguments to the call. FLAGS is a
@@ -8580,13 +8626,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
addr, nargs, argarray);
if (TREE_THIS_VOLATILE (fn) && cfun)
current_function_returns_abnormally = 1;
- if (TREE_CODE (fn) == FUNCTION_DECL
- && DECL_IMMEDIATE_FUNCTION_P (fn)
- && cp_unevaluated_operand == 0
- && (current_function_decl == NULL_TREE
- || !DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
- && (current_binding_level->kind != sk_function_parms
- || !current_binding_level->immediate_fn_ctx_p))
+ if (immediate_invocation_p (fn, nargs))
{
tree obj_arg = NULL_TREE, exprimm = expr;
if (DECL_CONSTRUCTOR_P (fn))
@@ -9224,13 +9264,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
if (TREE_CODE (fn) == ADDR_EXPR)
{
tree fndecl = STRIP_TEMPLATE (TREE_OPERAND (fn, 0));
- if (TREE_CODE (fndecl) == FUNCTION_DECL
- && DECL_IMMEDIATE_FUNCTION_P (fndecl)
- && cp_unevaluated_operand == 0
- && (current_function_decl == NULL_TREE
- || !DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
- && (current_binding_level->kind != sk_function_parms
- || !current_binding_level->immediate_fn_ctx_p))
+ if (immediate_invocation_p (fndecl, nargs))
{
tree obj_arg = NULL_TREE;
if (DECL_CONSTRUCTOR_P (fndecl))
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 7c34d94..ec47b06 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1331,6 +1331,23 @@ handle_using_decl (tree using_decl, tree t)
add_method (t, *iter, true);
alter_access (t, *iter, access);
}
+ else if (USING_DECL_UNRELATED_P (using_decl))
+ {
+ /* C++20 using enum can import non-inherited enumerators into class
+ scope. We implement that by making a copy of the CONST_DECL for which
+ CONST_DECL_USING_P is true. */
+ gcc_assert (TREE_CODE (decl) == CONST_DECL);
+
+ tree copy = copy_decl (decl);
+ DECL_CONTEXT (copy) = t;
+ DECL_ARTIFICIAL (copy) = true;
+ /* We emitted debug info for the USING_DECL above; make sure we don't
+ also emit anything for this clone. */
+ DECL_IGNORED_P (copy) = true;
+ DECL_SOURCE_LOCATION (copy) = DECL_SOURCE_LOCATION (using_decl);
+ finish_member_declaration (copy);
+ DECL_ABSTRACT_ORIGIN (copy) = decl;
+ }
else
alter_access (t, decl, access);
}
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index b6f9c43..e0d3580 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -133,19 +133,10 @@ ensure_literal_type_for_constexpr_object (tree decl)
return decl;
}
-/* Representation of entries in the constexpr function definition table. */
-
-struct GTY((for_user)) constexpr_fundef {
- tree decl;
- tree body;
- tree parms;
- tree result;
-};
-
struct constexpr_fundef_hasher : ggc_ptr_hash<constexpr_fundef>
{
- static hashval_t hash (constexpr_fundef *);
- static bool equal (constexpr_fundef *, constexpr_fundef *);
+ static hashval_t hash (const constexpr_fundef *);
+ static bool equal (const constexpr_fundef *, const constexpr_fundef *);
};
/* This table holds all constexpr function definitions seen in
@@ -158,7 +149,8 @@ static GTY (()) hash_table<constexpr_fundef_hasher> *constexpr_fundef_table;
same constexpr function. */
inline bool
-constexpr_fundef_hasher::equal (constexpr_fundef *lhs, constexpr_fundef *rhs)
+constexpr_fundef_hasher::equal (const constexpr_fundef *lhs,
+ const constexpr_fundef *rhs)
{
return lhs->decl == rhs->decl;
}
@@ -167,20 +159,20 @@ constexpr_fundef_hasher::equal (constexpr_fundef *lhs, constexpr_fundef *rhs)
Return a hash value for the entry pointed to by Q. */
inline hashval_t
-constexpr_fundef_hasher::hash (constexpr_fundef *fundef)
+constexpr_fundef_hasher::hash (const constexpr_fundef *fundef)
{
return DECL_UID (fundef->decl);
}
/* Return a previously saved definition of function FUN. */
-static constexpr_fundef *
+constexpr_fundef *
retrieve_constexpr_fundef (tree fun)
{
if (constexpr_fundef_table == NULL)
return NULL;
- constexpr_fundef fundef = { fun, NULL, NULL, NULL };
+ constexpr_fundef fundef = { fun, NULL_TREE, NULL_TREE, NULL_TREE };
return constexpr_fundef_table->find (&fundef);
}
@@ -669,7 +661,7 @@ get_function_named_in_call (tree t)
return fun;
}
-/* Subroutine of register_constexpr_fundef. BODY is the body of a function
+/* Subroutine of check_constexpr_fundef. BODY is the body of a function
declared to be constexpr, or a sub-statement thereof. Returns the
return value if suitable, error_mark_node for a statement not allowed in
a constexpr function, or NULL_TREE if no return value was found. */
@@ -738,7 +730,7 @@ constexpr_fn_retval (tree body)
}
}
-/* Subroutine of register_constexpr_fundef. BODY is the DECL_SAVED_TREE of
+/* Subroutine of check_constexpr_fundef. BODY is the DECL_SAVED_TREE of
FUN; do the necessary transformations to turn it into a single expression
that we can store in the hash table. */
@@ -868,27 +860,28 @@ cx_check_missing_mem_inits (tree ctype, tree body, bool complain)
}
/* We are processing the definition of the constexpr function FUN.
- Check that its BODY fulfills the propriate requirements and
- enter it in the constexpr function definition table.
- For constructor BODY is actually the TREE_LIST of the
- member-initializer list. */
+ Check that its body fulfills the apropriate requirements and
+ enter it in the constexpr function definition table. */
-tree
-register_constexpr_fundef (tree fun, tree body)
+void
+maybe_save_constexpr_fundef (tree fun)
{
- constexpr_fundef entry;
- constexpr_fundef **slot;
+ if (processing_template_decl
+ || !DECL_DECLARED_CONSTEXPR_P (fun)
+ || cp_function_chain->invalid_constexpr
+ || DECL_CLONED_FUNCTION_P (fun))
+ return;
if (!is_valid_constexpr_fn (fun, !DECL_GENERATED_P (fun)))
- return NULL;
+ return;
- tree massaged = massage_constexpr_body (fun, body);
+ tree massaged = massage_constexpr_body (fun, DECL_SAVED_TREE (fun));
if (massaged == NULL_TREE || massaged == error_mark_node)
{
if (!DECL_CONSTRUCTOR_P (fun))
error ("body of %<constexpr%> function %qD not a return-statement",
fun);
- return NULL;
+ return;
}
bool potential = potential_rvalue_constant_expression (massaged);
@@ -901,39 +894,47 @@ register_constexpr_fundef (tree fun, tree body)
potential = false;
if (!potential && !DECL_GENERATED_P (fun))
- return NULL;
-
- /* Create the constexpr function table if necessary. */
- if (constexpr_fundef_table == NULL)
- constexpr_fundef_table
- = hash_table<constexpr_fundef_hasher>::create_ggc (101);
+ return;
- entry.decl = fun;
- tree saved_fn = current_function_decl;
+ constexpr_fundef entry = {fun, NULL_TREE, NULL_TREE, NULL_TREE};
bool clear_ctx = false;
- current_function_decl = fun;
if (DECL_RESULT (fun) && DECL_CONTEXT (DECL_RESULT (fun)) == NULL_TREE)
{
clear_ctx = true;
DECL_CONTEXT (DECL_RESULT (fun)) = fun;
}
- entry.body = copy_fn (fun, entry.parms, entry.result);
+ tree saved_fn = current_function_decl;
+ current_function_decl = fun;
+ entry.body = copy_fn (entry.decl, entry.parms, entry.result);
current_function_decl = saved_fn;
- slot = constexpr_fundef_table->find_slot (&entry, INSERT);
if (clear_ctx)
- DECL_CONTEXT (DECL_RESULT (fun)) = NULL_TREE;
-
+ DECL_CONTEXT (DECL_RESULT (entry.decl)) = NULL_TREE;
if (!potential)
/* For a template instantiation, we want to remember the pre-generic body
for explain_invalid_constexpr_fn, but do tell cxx_eval_call_expression
that it doesn't need to bother trying to expand the function. */
entry.result = error_mark_node;
+ register_constexpr_fundef (entry);
+}
+
+/* BODY is a validated and massaged definition of a constexpr
+ function. Register it in the hash table. */
+
+void
+register_constexpr_fundef (const constexpr_fundef &value)
+{
+ /* Create the constexpr function table if necessary. */
+ if (constexpr_fundef_table == NULL)
+ constexpr_fundef_table
+ = hash_table<constexpr_fundef_hasher>::create_ggc (101);
+
+ constexpr_fundef **slot = constexpr_fundef_table->find_slot
+ (const_cast<constexpr_fundef *> (&value), INSERT);
+
gcc_assert (*slot == NULL);
*slot = ggc_alloc<constexpr_fundef> ();
- **slot = entry;
-
- return fun;
+ **slot = value;
}
/* FUN is a non-constexpr function called in a context that requires a
@@ -1331,7 +1332,12 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
}
if (fndecl_built_in_p (fun, CP_BUILT_IN_SOURCE_LOCATION, BUILT_IN_FRONTEND))
- return fold_builtin_source_location (EXPR_LOCATION (t));
+ {
+ temp_override<tree> ovr (current_function_decl);
+ if (ctx->call && ctx->call->fundef)
+ current_function_decl = ctx->call->fundef->decl;
+ return fold_builtin_source_location (EXPR_LOCATION (t));
+ }
int strops = 0;
int strret = 0;
@@ -2186,6 +2192,27 @@ cxx_eval_thunk_call (const constexpr_ctx *ctx, tree t, tree thunk_fndecl,
non_constant_p, overflow_p);
}
+/* If OBJECT is of const class type, evaluate it to a CONSTRUCTOR and set
+ its TREE_READONLY flag according to READONLY_P. Used for constexpr
+ 'tors to detect modifying const objects in a constexpr context. */
+
+static void
+cxx_set_object_constness (const constexpr_ctx *ctx, tree object,
+ bool readonly_p, bool *non_constant_p,
+ bool *overflow_p)
+{
+ if (CLASS_TYPE_P (TREE_TYPE (object))
+ && CP_TYPE_CONST_P (TREE_TYPE (object)))
+ {
+ /* Subobjects might not be stored in ctx->global->values but we
+ can get its CONSTRUCTOR by evaluating *this. */
+ tree e = cxx_eval_constant_expression (ctx, object, /*lval*/false,
+ non_constant_p, overflow_p);
+ if (TREE_CODE (e) == CONSTRUCTOR && !*non_constant_p)
+ TREE_READONLY (e) = readonly_p;
+ }
+}
+
/* Subroutine of cxx_eval_constant_expression.
Evaluate the call expression tree T in the context of OLD_CALL expression
evaluation. */
@@ -2514,11 +2541,11 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
depth_ok = push_cx_call_context (t);
- /* Remember the object we are constructing. */
+ /* Remember the object we are constructing or destructing. */
tree new_obj = NULL_TREE;
- if (DECL_CONSTRUCTOR_P (fun))
+ if (DECL_CONSTRUCTOR_P (fun) || DECL_DESTRUCTOR_P (fun))
{
- /* In a constructor, it should be the first `this' argument.
+ /* In a cdtor, 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);
@@ -2655,6 +2682,12 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
unsigned save_heap_alloc_count = ctx->global->heap_vars.length ();
unsigned save_heap_dealloc_count = ctx->global->heap_dealloc_count;
+ /* If this is a constexpr destructor, the object's const and volatile
+ semantics are no longer in effect; see [class.dtor]p5. */
+ if (new_obj && DECL_DESTRUCTOR_P (fun))
+ cxx_set_object_constness (ctx, new_obj, /*readonly_p=*/false,
+ non_constant_p, overflow_p);
+
tree jump_target = NULL_TREE;
cxx_eval_constant_expression (&ctx_with_save_exprs, body,
lval, non_constant_p, overflow_p,
@@ -2685,19 +2718,9 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
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->global->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);
- if (TREE_CODE (e) == CONSTRUCTOR && !*non_constant_p)
- TREE_READONLY (e) = true;
- }
+ if (new_obj && DECL_CONSTRUCTOR_P (fun))
+ cxx_set_object_constness (ctx, new_obj, /*readonly_p=*/true,
+ non_constant_p, overflow_p);
/* Forget the saved values of the callee's SAVE_EXPRs and
TARGET_EXPRs. */
@@ -3144,6 +3167,21 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
if (r == NULL_TREE)
r = fold_binary_loc (loc, code, type, lhs, rhs);
+ if (r == NULL_TREE
+ && (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
+ && TREE_CODE (lhs) == INTEGER_CST
+ && TREE_CODE (rhs) == INTEGER_CST
+ && wi::neg_p (wi::to_wide (rhs)))
+ {
+ /* For diagnostics and -fpermissive emulate previous behavior of
+ handling shifts by negative amount. */
+ tree nrhs = const_unop (NEGATE_EXPR, TREE_TYPE (rhs), rhs);
+ if (nrhs)
+ r = fold_binary_loc (loc,
+ code == LSHIFT_EXPR ? RSHIFT_EXPR : LSHIFT_EXPR,
+ type, lhs, nrhs);
+ }
+
if (r == NULL_TREE)
{
if (lhs == orig_lhs && rhs == orig_rhs)
@@ -3912,6 +3950,205 @@ cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
return error_mark_node;
}
+/* Helper for cxx_eval_bit_cast.
+ Check [bit.cast]/3 rules, bit_cast is constexpr only if the To and From
+ types and types of all subobjects have is_union_v<T>, is_pointer_v<T>,
+ is_member_pointer_v<T>, is_volatile_v<T> false and has no non-static
+ data members of reference type. */
+
+static bool
+check_bit_cast_type (const constexpr_ctx *ctx, location_t loc, tree type,
+ tree orig_type)
+{
+ if (TREE_CODE (type) == UNION_TYPE)
+ {
+ if (!ctx->quiet)
+ {
+ if (type == orig_type)
+ error_at (loc, "%qs is not a constant expression because %qT is "
+ "a union type", "__builtin_bit_cast", type);
+ else
+ error_at (loc, "%qs is not a constant expression because %qT "
+ "contains a union type", "__builtin_bit_cast",
+ orig_type);
+ }
+ return true;
+ }
+ if (TREE_CODE (type) == POINTER_TYPE)
+ {
+ if (!ctx->quiet)
+ {
+ if (type == orig_type)
+ error_at (loc, "%qs is not a constant expression because %qT is "
+ "a pointer type", "__builtin_bit_cast", type);
+ else
+ error_at (loc, "%qs is not a constant expression because %qT "
+ "contains a pointer type", "__builtin_bit_cast",
+ orig_type);
+ }
+ return true;
+ }
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ if (!ctx->quiet)
+ {
+ if (type == orig_type)
+ error_at (loc, "%qs is not a constant expression because %qT is "
+ "a reference type", "__builtin_bit_cast", type);
+ else
+ error_at (loc, "%qs is not a constant expression because %qT "
+ "contains a reference type", "__builtin_bit_cast",
+ orig_type);
+ }
+ return true;
+ }
+ if (TYPE_PTRMEM_P (type))
+ {
+ if (!ctx->quiet)
+ {
+ if (type == orig_type)
+ error_at (loc, "%qs is not a constant expression because %qT is "
+ "a pointer to member type", "__builtin_bit_cast",
+ type);
+ else
+ error_at (loc, "%qs is not a constant expression because %qT "
+ "contains a pointer to member type",
+ "__builtin_bit_cast", orig_type);
+ }
+ return true;
+ }
+ if (TYPE_VOLATILE (type))
+ {
+ if (!ctx->quiet)
+ {
+ if (type == orig_type)
+ error_at (loc, "%qs is not a constant expression because %qT is "
+ "volatile", "__builtin_bit_cast", type);
+ else
+ error_at (loc, "%qs is not a constant expression because %qT "
+ "contains a volatile subobject",
+ "__builtin_bit_cast", orig_type);
+ }
+ return true;
+ }
+ if (TREE_CODE (type) == RECORD_TYPE)
+ for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL
+ && check_bit_cast_type (ctx, loc, TREE_TYPE (field), orig_type))
+ return true;
+ return false;
+}
+
+/* Subroutine of cxx_eval_constant_expression.
+ Attempt to evaluate a BIT_CAST_EXPR. */
+
+static tree
+cxx_eval_bit_cast (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
+ bool *overflow_p)
+{
+ if (check_bit_cast_type (ctx, EXPR_LOCATION (t), TREE_TYPE (t),
+ TREE_TYPE (t))
+ || check_bit_cast_type (ctx, cp_expr_loc_or_loc (TREE_OPERAND (t, 0),
+ EXPR_LOCATION (t)),
+ TREE_TYPE (TREE_OPERAND (t, 0)),
+ TREE_TYPE (TREE_OPERAND (t, 0))))
+ {
+ *non_constant_p = true;
+ return t;
+ }
+
+ tree op = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), false,
+ non_constant_p, overflow_p);
+ if (*non_constant_p)
+ return t;
+
+ location_t loc = EXPR_LOCATION (t);
+ if (BITS_PER_UNIT != 8 || CHAR_BIT != 8)
+ {
+ if (!ctx->quiet)
+ sorry_at (loc, "%qs cannot be constant evaluated on the target",
+ "__builtin_bit_cast");
+ *non_constant_p = true;
+ return t;
+ }
+
+ if (!tree_fits_shwi_p (TYPE_SIZE_UNIT (TREE_TYPE (t))))
+ {
+ if (!ctx->quiet)
+ sorry_at (loc, "%qs cannot be constant evaluated because the "
+ "type is too large", "__builtin_bit_cast");
+ *non_constant_p = true;
+ return t;
+ }
+
+ HOST_WIDE_INT len = tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (t)));
+ if (len < 0 || (int) len != len)
+ {
+ if (!ctx->quiet)
+ sorry_at (loc, "%qs cannot be constant evaluated because the "
+ "type is too large", "__builtin_bit_cast");
+ *non_constant_p = true;
+ return t;
+ }
+
+ unsigned char buf[64];
+ unsigned char *ptr, *mask;
+ size_t alen = (size_t) len * 2;
+ if (alen <= sizeof (buf))
+ ptr = buf;
+ else
+ ptr = XNEWVEC (unsigned char, alen);
+ mask = ptr + (size_t) len;
+ /* At the beginning consider everything indeterminate. */
+ memset (mask, ~0, (size_t) len);
+
+ if (native_encode_initializer (op, ptr, len, 0, mask) != len)
+ {
+ if (!ctx->quiet)
+ sorry_at (loc, "%qs cannot be constant evaluated because the "
+ "argument cannot be encoded", "__builtin_bit_cast");
+ *non_constant_p = true;
+ if (ptr != buf)
+ XDELETE (ptr);
+ return t;
+ }
+
+ tree r = NULL_TREE;
+ if (can_native_interpret_type_p (TREE_TYPE (t)))
+ r = native_interpret_expr (TREE_TYPE (t), ptr, len);
+ else if (TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE)
+ {
+ r = native_interpret_aggregate (TREE_TYPE (t), ptr, 0, len);
+ if (r != NULL_TREE)
+ clear_type_padding_in_mask (TREE_TYPE (t), mask);
+ }
+
+ if (r != NULL_TREE)
+ {
+ for (int i = 0; i < len; i++)
+ if (mask[i])
+ {
+ if (!ctx->quiet)
+ error_at (loc, "%qs accessing uninitialized byte at offset %d",
+ "__builtin_bit_cast", i);
+ *non_constant_p = true;
+ r = t;
+ break;
+ }
+ if (ptr != buf)
+ XDELETE (ptr);
+ return r;
+ }
+
+ if (!ctx->quiet)
+ sorry_at (loc, "%qs cannot be constant evaluated because the "
+ "argument cannot be interpreted", "__builtin_bit_cast");
+ *non_constant_p = true;
+ if (ptr != buf)
+ XDELETE (ptr);
+ return t;
+}
+
/* Subroutine of cxx_eval_constant_expression.
Evaluate a short-circuited logical expression T in the context
of a given constexpr CALL. BAILOUT_VALUE is the value for
@@ -6018,8 +6255,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
/* Evaluate the cleanups. */
FOR_EACH_VEC_ELT_REVERSE (cleanups, i, cleanup)
cxx_eval_constant_expression (ctx, cleanup, false,
- non_constant_p, overflow_p,
- jump_target);
+ non_constant_p, overflow_p);
}
break;
@@ -6030,29 +6266,20 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
if (!*non_constant_p)
/* Also evaluate the cleanup. */
cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), true,
- non_constant_p, overflow_p,
- jump_target);
+ non_constant_p, overflow_p);
break;
case CLEANUP_STMT:
- {
- tree initial_jump_target = jump_target ? *jump_target : NULL_TREE;
- r = cxx_eval_constant_expression (ctx, CLEANUP_BODY (t), lval,
- non_constant_p, overflow_p,
- jump_target);
- if (!CLEANUP_EH_ONLY (t) && !*non_constant_p)
- {
- iloc_sentinel ils (loc);
- /* Also evaluate the cleanup. If we weren't skipping at the
- start of the CLEANUP_BODY, change jump_target temporarily
- to &initial_jump_target, so that even a return or break or
- continue in the body doesn't skip the cleanup. */
- cxx_eval_constant_expression (ctx, CLEANUP_EXPR (t), true,
- non_constant_p, overflow_p,
- jump_target ? &initial_jump_target
- : NULL);
- }
- }
+ r = cxx_eval_constant_expression (ctx, CLEANUP_BODY (t), lval,
+ non_constant_p, overflow_p,
+ jump_target);
+ if (!CLEANUP_EH_ONLY (t) && !*non_constant_p)
+ {
+ iloc_sentinel ils (loc);
+ /* Also evaluate the cleanup. */
+ cxx_eval_constant_expression (ctx, CLEANUP_EXPR (t), true,
+ non_constant_p, overflow_p);
+ }
break;
/* These differ from cxx_eval_unary_expression in that this doesn't
@@ -6625,6 +6852,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
*non_constant_p = true;
return t;
+ case BIT_CAST_EXPR:
+ r = cxx_eval_bit_cast (ctx, t, non_constant_p, overflow_p);
+ break;
+
default:
if (STATEMENT_CODE_P (TREE_CODE (t)))
{
@@ -7248,7 +7479,8 @@ maybe_fold_non_dependent_expr (tree expr,
tree
fold_non_dependent_init (tree t,
tsubst_flags_t complain /*=tf_warning_or_error*/,
- bool manifestly_const_eval /*=false*/)
+ bool manifestly_const_eval /*=false*/,
+ tree object /* = NULL_TREE */)
{
if (t == NULL_TREE)
return NULL_TREE;
@@ -7256,7 +7488,7 @@ fold_non_dependent_init (tree t,
if (processing_template_decl)
{
t = fold_non_dependent_expr_template (t, complain,
- manifestly_const_eval, NULL_TREE);
+ manifestly_const_eval, object);
/* maybe_constant_init does this stripping, so do it here too. */
if (TREE_CODE (t) == TARGET_EXPR)
{
@@ -7267,7 +7499,7 @@ fold_non_dependent_init (tree t,
return t;
}
- return maybe_constant_init (t, NULL_TREE, manifestly_const_eval);
+ return maybe_constant_init (t, object, manifestly_const_eval);
}
/* Like maybe_constant_value, but returns a CONSTRUCTOR directly, rather
@@ -7494,7 +7726,6 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
case OVERLOAD:
case TEMPLATE_ID_EXPR:
case LABEL_DECL:
- case LABEL_EXPR:
case CASE_LABEL_EXPR:
case PREDICT_EXPR:
case CONST_DECL:
@@ -8403,9 +8634,20 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
return false;
}
+ case LABEL_EXPR:
+ t = LABEL_EXPR_LABEL (t);
+ if (DECL_ARTIFICIAL (t))
+ return true;
+ else if (flags & tf_error)
+ error_at (loc, "label definition is not a constant expression");
+ return false;
+
case ANNOTATE_EXPR:
return RECUR (TREE_OPERAND (t, 0), rval);
+ case BIT_CAST_EXPR:
+ return RECUR (TREE_OPERAND (t, 0), rval);
+
/* Coroutine await, yield and return expressions are not. */
case CO_AWAIT_EXPR:
case CO_YIELD_EXPR:
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 8691281..00d2f2e 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -533,9 +533,9 @@ debug_argument_list (tree args)
{
tree arg = TREE_VEC_ELT (args, i);
if (TYPE_P (arg))
- verbatim ("ARG %qT", arg);
+ verbatim ("argument %qT", arg);
else
- verbatim ("ARG %qE", arg);
+ verbatim ("argument %qE", arg);
}
}
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 9b9141e..fd6cda4 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -3756,7 +3756,7 @@ act_des_fn (tree orig, tree fn_type, tree coro_frame_ptr, const char* name)
/* Copy selected attributes from the original function. */
TREE_USED (fn) = TREE_USED (orig);
if (DECL_SECTION_NAME (orig))
- set_decl_section_name (fn, DECL_SECTION_NAME (orig));
+ set_decl_section_name (fn, orig);
/* Copy any alignment that the FE added. */
if (DECL_ALIGN (orig))
SET_DECL_ALIGN (fn, DECL_ALIGN (orig));
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 064a44c..bafcaf5 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -1374,6 +1374,14 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
break;
}
+ if (tree fndecl = cp_get_callee_fndecl (stmt))
+ if (DECL_IMMEDIATE_FUNCTION_P (fndecl))
+ {
+ gcc_assert (source_location_current_p (fndecl));
+ *stmt_p = cxx_constant_value (stmt);
+ break;
+ }
+
if (!wtd->no_sanitize_p
&& sanitize_flags_p ((SANITIZE_NULL
| SANITIZE_ALIGNMENT | SANITIZE_VPTR)))
@@ -1552,6 +1560,11 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
cp_genericize_r, cp_walk_subtrees);
break;
+ case BIT_CAST_EXPR:
+ *stmt_p = build1_loc (EXPR_LOCATION (stmt), VIEW_CONVERT_EXPR,
+ TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
+ break;
+
default:
if (IS_TYPE_OR_DECL_P (stmt))
*walk_subtrees = 0;
diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index a38bb0a..7ff4d39 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -391,6 +391,7 @@ names_builtin_p (const char *name)
case RID_BUILTIN_HAS_ATTRIBUTE:
case RID_BUILTIN_SHUFFLE:
case RID_BUILTIN_LAUNDER:
+ case RID_BUILTIN_BIT_CAST:
case RID_OFFSETOF:
case RID_HAS_NOTHROW_ASSIGN:
case RID_HAS_NOTHROW_CONSTRUCTOR:
@@ -489,6 +490,7 @@ cp_common_init_ts (void)
MARK_TS_EXP (ALIGNOF_EXPR);
MARK_TS_EXP (ARROW_EXPR);
MARK_TS_EXP (AT_ENCODE_EXPR);
+ MARK_TS_EXP (BIT_CAST_EXPR);
MARK_TS_EXP (CAST_EXPR);
MARK_TS_EXP (CONST_CAST_EXPR);
MARK_TS_EXP (CTOR_INITIALIZER);
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index a188576..c58b233 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -233,6 +233,9 @@ DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", tcc_expression, 2)
/* One of a set of overloaded functions. */
DEFTREECODE (OVERLOAD, "overload", tcc_exceptional, 0)
+/* A vector of binding slots. */
+DEFTREECODE (BINDING_VECTOR, "binding_vector", tcc_exceptional, 0)
+
/* A pseudo-destructor, of the form "OBJECT.~DESTRUCTOR" or
"OBJECT.SCOPE::~DESTRUCTOR. The first operand is the OBJECT. The
second operand (if non-NULL) is the SCOPE. The third operand is
@@ -437,6 +440,9 @@ DEFTREECODE (UNARY_RIGHT_FOLD_EXPR, "unary_right_fold_expr", tcc_expression, 2)
DEFTREECODE (BINARY_LEFT_FOLD_EXPR, "binary_left_fold_expr", tcc_expression, 3)
DEFTREECODE (BINARY_RIGHT_FOLD_EXPR, "binary_right_fold_expr", tcc_expression, 3)
+/* Represents the __builtin_bit_cast (type, expr) expression.
+ The type is in TREE_TYPE, expression in TREE_OPERAND (bitcast, 0). */
+DEFTREECODE (BIT_CAST_EXPR, "bit_cast_expr", tcc_expression, 1)
/** C++ extensions. */
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b98d47a..69f8ed5 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -128,12 +128,8 @@ enum cp_tree_index
CPTI_EXPLICIT_VOID_LIST,
CPTI_VTBL_TYPE,
CPTI_VTBL_PTR_TYPE,
- CPTI_STD,
- CPTI_ABI,
CPTI_GLOBAL,
CPTI_GLOBAL_TYPE,
- CPTI_CONST_TYPE_INFO_TYPE,
- CPTI_TYPE_INFO_PTR_TYPE,
CPTI_ABORT_FNDECL,
CPTI_AGGR_TAG,
CPTI_CONV_OP_MARKER,
@@ -190,8 +186,28 @@ enum cp_tree_index
CPTI_NOEXCEPT_FALSE_SPEC,
CPTI_NOEXCEPT_DEFERRED_SPEC,
+ CPTI_NULLPTR,
+ CPTI_NULLPTR_TYPE,
+
+ CPTI_ANY_TARG,
+
+ CPTI_MODULE_HWM,
+ /* Nodes after here change during compilation, or should not be in
+ the module's global tree table. */
+
+ /* We must find these via the global namespace. */
+ CPTI_STD,
+ CPTI_ABI,
+
+ /* These are created at init time, but the library/headers provide
+ definitions. */
+ CPTI_ALIGN_TYPE,
+ CPTI_CONST_TYPE_INFO_TYPE,
+ CPTI_TYPE_INFO_PTR_TYPE,
CPTI_TERMINATE_FN,
CPTI_CALL_UNEXPECTED_FN,
+
+ /* These are lazily inited. */
CPTI_GET_EXCEPTION_PTR_FN,
CPTI_BEGIN_CATCH_FN,
CPTI_END_CATCH_FN,
@@ -204,13 +220,6 @@ enum cp_tree_index
CPTI_DSO_HANDLE,
CPTI_DCAST,
- CPTI_NULLPTR,
- CPTI_NULLPTR_TYPE,
-
- CPTI_ALIGN_TYPE,
-
- CPTI_ANY_TARG,
-
CPTI_SOURCE_LOCATION_IMPL,
CPTI_FALLBACK_DFLOAT32_TYPE,
@@ -479,13 +488,14 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
CALL_EXPR_ORDERED_ARGS (in CALL_EXPR, AGGR_INIT_EXPR)
DECLTYPE_FOR_REF_CAPTURE (in DECLTYPE_TYPE)
CONSTRUCTOR_C99_COMPOUND_LITERAL (in CONSTRUCTOR)
+ DECL_MODULE_EXPORT_P (in _DECL)
OVL_NESTED_P (in OVERLOAD)
LAMBDA_EXPR_INSTANTIATED (in LAMBDA_EXPR)
Reserved for DECL_MODULE_EXPORT (in DECL_)
4: IDENTIFIER_MARKED (IDENTIFIER_NODEs)
TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
CALL_EXPR, or FIELD_DECL).
- DECL_TINFO_P (in VAR_DECL)
+ DECL_TINFO_P (in VAR_DECL, TYPE_DECL)
FUNCTION_REF_QUALIFIED (in FUNCTION_TYPE, METHOD_TYPE)
OVL_LOOKUP_P (in OVERLOAD)
LOOKUP_FOUND_P (in RECORD_TYPE, UNION_TYPE, ENUMERAL_TYPE, NAMESPACE_DECL)
@@ -529,6 +539,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
TEMPLATE_DECL_COMPLEX_ALIAS_P (in TEMPLATE_DECL)
DECL_INSTANTIATING_NSDMI_P (in a FIELD_DECL)
LABEL_DECL_CDTOR (in LABEL_DECL)
+ USING_DECL_UNRELATED_P (in USING_DECL)
3: DECL_IN_AGGR_P.
4: DECL_C_BIT_FIELD (in a FIELD_DECL)
DECL_ANON_UNION_VAR_P (in a VAR_DECL)
@@ -1634,6 +1645,46 @@ check_constraint_info (tree t)
#define CONSTRAINED_PARM_PROTOTYPE(NODE) \
DECL_INITIAL (TYPE_DECL_CHECK (NODE))
+/* Module defines. */
+// Too many _DECLS: FUNCTION,VAR,TYPE,TEMPLATE,CONCEPT or NAMESPACE
+#define DECL_MODULE_CHECK(NODE) (NODE)
+
+/* In the purview of a module (including header unit). */
+#define DECL_MODULE_PURVIEW_P(N) \
+ (DECL_LANG_SPECIFIC (DECL_MODULE_CHECK (N))->u.base.module_purview_p)
+
+/* True if the live version of the decl was imported. */
+#define DECL_MODULE_IMPORT_P(NODE) \
+ (DECL_LANG_SPECIFIC (DECL_MODULE_CHECK (NODE))->u.base.module_import_p)
+
+/* True if this decl is in the entity hash & array. This means that
+ some variant was imported, even if DECL_MODULE_IMPORT_P is false. */
+#define DECL_MODULE_ENTITY_P(NODE) \
+ (DECL_LANG_SPECIFIC (DECL_MODULE_CHECK (NODE))->u.base.module_entity_p)
+
+/* True if there are unloaded specializations keyed to this template. */
+#define DECL_MODULE_PENDING_SPECIALIZATIONS_P(NODE) \
+ (DECL_LANG_SPECIFIC (TEMPLATE_DECL_CHECK (NODE)) \
+ ->u.base.module_pending_p)
+
+/* True if this class has unloaded members. These should be loaded
+ before we do member lookups. */
+#define DECL_MODULE_PENDING_MEMBERS_P(NODE) \
+ (DECL_LANG_SPECIFIC (TYPE_DECL_CHECK (NODE)) \
+ ->u.base.module_pending_p)
+
+/* DECL that has attached decls for ODR-relatedness. */
+#define DECL_MODULE_ATTACHMENTS_P(NODE) \
+ (DECL_LANG_SPECIFIC (TREE_CHECK2(NODE,FUNCTION_DECL,VAR_DECL))\
+ ->u.base.module_pending_p)
+
+/* Whether this is an exported DECL. Held on any decl that can appear
+ at namespace scope (function, var, type, template, const or
+ namespace). templates copy from their template_result, consts have
+ it for unscoped enums. */
+#define DECL_MODULE_EXPORT_P(NODE) TREE_LANG_FLAG_3 (NODE)
+
+
/* The list of local parameters introduced by this requires-expression,
in the form of a chain of PARM_DECLs. */
#define REQUIRES_EXPR_PARMS(NODE) \
@@ -1655,6 +1706,7 @@ enum cp_tree_node_structure_enum {
TS_CP_TPI,
TS_CP_PTRMEM,
TS_CP_OVERLOAD,
+ TS_CP_BINDING_VECTOR,
TS_CP_BASELINK,
TS_CP_TEMPLATE_DECL,
TS_CP_DEFERRED_PARSE,
@@ -1676,6 +1728,7 @@ union GTY((desc ("cp_tree_node_structure (&%h)"),
struct template_parm_index GTY ((tag ("TS_CP_TPI"))) tpi;
struct ptrmem_cst GTY ((tag ("TS_CP_PTRMEM"))) ptrmem;
struct tree_overload GTY ((tag ("TS_CP_OVERLOAD"))) overload;
+ struct tree_binding_vec GTY ((tag ("TS_CP_BINDING_VECTOR"))) binding_vec;
struct tree_baselink GTY ((tag ("TS_CP_BASELINK"))) baselink;
struct tree_template_decl GTY ((tag ("TS_CP_TEMPLATE_DECL"))) template_decl;
struct tree_deferred_parse GTY ((tag ("TS_CP_DEFERRED_PARSE"))) deferred_parse;
@@ -2643,15 +2696,15 @@ enum lang_decl_selector
/* Flags shared by all forms of DECL_LANG_SPECIFIC.
Some of the flags live here only to make lang_decl_min/fn smaller. Do
- not make this struct larger than 32 bits; instead, make sel smaller. */
+ not make this struct larger than 32 bits. */
struct GTY(()) lang_decl_base {
- /* Larger than necessary for faster access. */
- ENUM_BITFIELD(lang_decl_selector) selector : 16;
+ ENUM_BITFIELD(lang_decl_selector) selector : 3;
ENUM_BITFIELD(languages) language : 1;
unsigned use_template : 2;
unsigned not_really_extern : 1; /* var or fn */
unsigned initialized_in_class : 1; /* var or fn */
+
unsigned threadprivate_or_deleted_p : 1; /* var or fn */
/* anticipated_p is no longer used for anticipated_decls (fn, type
or template). It is used as DECL_OMP_PRIVATIZED_MEMBER in
@@ -2660,11 +2713,22 @@ struct GTY(()) lang_decl_base {
unsigned friend_or_tls : 1; /* var, fn, type or template */
unsigned unknown_bound_p : 1; /* var */
unsigned odr_used : 1; /* var or fn */
- unsigned spare : 1;
unsigned concept_p : 1; /* applies to vars and functions */
unsigned var_declared_inline_p : 1; /* var */
unsigned dependent_init_p : 1; /* var */
- /* 2 spare bits */
+
+ /* The following apply to VAR, FUNCTION, TYPE, CONCEPT, TEMPLATE,
+ NAMESPACE decls. */
+ unsigned module_purview_p : 1; /* in module purview (not GMF) */
+ unsigned module_import_p : 1; /* from an import */
+ unsigned module_entity_p : 1; /* is in the entitity ary &
+ hash. */
+ /* TEMPLATE_DECL has specializations or,
+ TYPE_DECL has class members yet to load, or
+ VAR_DECL or FUNCTION_DECL has attached decls. */
+ unsigned module_pending_p : 1;
+
+ /* 12 spare bits. */
};
/* True for DECL codes which have template info and access. */
@@ -3338,7 +3402,8 @@ struct GTY(()) lang_decl {
/* 1 iff VAR_DECL node NODE is a type-info decl. This flag is set for
both the primary typeinfo object and the associated NTBS name. */
-#define DECL_TINFO_P(NODE) TREE_LANG_FLAG_4 (VAR_DECL_CHECK (NODE))
+#define DECL_TINFO_P(NODE) \
+ TREE_LANG_FLAG_4 (TREE_CHECK2 (NODE,VAR_DECL,TYPE_DECL))
/* 1 iff VAR_DECL node NODE is virtual table or VTT. We forward to
DECL_VIRTUAL_P from the common code, as that has the semantics we
@@ -3409,6 +3474,16 @@ struct GTY(()) lang_decl {
/* Non zero if the using decl refers to a dependent type. */
#define USING_DECL_TYPENAME_P(NODE) DECL_LANG_FLAG_1 (USING_DECL_CHECK (NODE))
+/* True if member using decl NODE refers to a non-inherited NODE. */
+#define USING_DECL_UNRELATED_P(NODE) DECL_LANG_FLAG_2 (USING_DECL_CHECK (NODE))
+
+/* True iff the CONST_DECL is a class-scope clone from C++20 using enum,
+ created by handle_using_decl. */
+#define CONST_DECL_USING_P(NODE) \
+ (TREE_CODE (NODE) == CONST_DECL \
+ && TREE_CODE (TREE_TYPE (NODE)) == ENUMERAL_TYPE \
+ && DECL_CONTEXT (NODE) != TREE_TYPE (NODE))
+
/* In a FUNCTION_DECL, this is nonzero if this function was defined in
the class definition. We have saved away the text of the function,
but have not yet processed it. */
@@ -5324,6 +5399,10 @@ extern int function_depth;
in structrual_comptypes. */
extern int comparing_specializations;
+/* Nonzero if we are inside eq_specializations, which affects
+ resolving of typenames in structural_comptypes. */
+extern int comparing_typenames;
+
/* In parser.c. */
/* Nonzero if we are parsing an unevaluated operand: an operand to
@@ -5383,6 +5462,14 @@ public:
hash_map<tree, tree> *saved;
};
+/* Entry in the specialization hash table. */
+struct GTY((for_user)) spec_entry
+{
+ tree tmpl; /* The general template this is a specialization of. */
+ tree args; /* The args for this (maybe-partial) specialization. */
+ tree spec; /* The specialization itself. */
+};
+
/* in class.c */
extern int current_class_depth;
@@ -6455,6 +6542,7 @@ extern bool check_omp_return (void);
extern tree make_typename_type (tree, tree, enum tag_types, tsubst_flags_t);
extern tree build_typename_type (tree, tree, tree, tag_types);
extern tree make_unbound_class_template (tree, tree, tree, tsubst_flags_t);
+extern tree make_unbound_class_template_raw (tree, tree, tree);
extern tree build_library_fn_ptr (const char *, tree, int);
extern tree build_cp_library_fn_ptr (const char *, tree, int);
extern tree push_library_fn (tree, tree, tree, int);
@@ -6729,6 +6817,8 @@ extern tree unqualified_fn_lookup_error (cp_expr);
extern tree make_conv_op_name (tree);
extern tree build_lang_decl (enum tree_code, tree, tree);
extern tree build_lang_decl_loc (location_t, enum tree_code, tree, tree);
+extern bool maybe_add_lang_decl_raw (tree, bool decomp_p);
+extern bool maybe_add_lang_type_raw (tree);
extern void retrofit_lang_decl (tree);
extern void fit_decomposition_lang_decl (tree, tree);
extern tree copy_decl (tree CXX_MEM_STAT_INFO);
@@ -6791,6 +6881,7 @@ extern void maybe_show_extern_c_location (void);
extern bool literal_integer_zerop (const_tree);
/* in pt.c */
+extern tree canonical_type_parameter (tree);
extern void push_access_scope (tree);
extern void pop_access_scope (tree);
extern bool check_template_shadow (tree);
@@ -6974,6 +7065,15 @@ extern bool copy_guide_p (const_tree);
extern bool template_guide_p (const_tree);
extern bool builtin_guide_p (const_tree);
extern void store_explicit_specifier (tree, tree);
+extern void walk_specializations (bool,
+ void (*)(bool, spec_entry *,
+ void *),
+ void *);
+extern tree match_mergeable_specialization (bool is_decl, tree tmpl,
+ tree args, tree spec);
+extern unsigned get_mergeable_specialization_flags (tree tmpl, tree spec);
+extern void add_mergeable_specialization (tree tmpl, tree args,
+ tree spec, unsigned);
extern tree add_outermost_template_args (tree, tree);
extern tree add_extra_args (tree, tree);
extern tree build_extra_args (tree, tree, tsubst_flags_t);
@@ -6984,6 +7084,7 @@ extern GTY(()) vec<tree, va_gc> *unemitted_tinfo_decls;
extern void init_rtti_processing (void);
extern tree build_typeid (tree, tsubst_flags_t);
+extern tree get_tinfo_decl_direct (tree, tree, int);
extern tree get_tinfo_decl (tree);
extern tree get_typeid (tree, tsubst_flags_t);
extern tree build_headof (tree);
@@ -6991,6 +7092,8 @@ extern tree build_dynamic_cast (location_t, tree, tree,
tsubst_flags_t);
extern void emit_support_tinfos (void);
extern bool emit_tinfo_decl (tree);
+extern unsigned get_pseudo_tinfo_index (tree);
+extern tree get_pseudo_tinfo_type (unsigned);
/* in search.c */
extern bool accessible_base_p (tree, tree, bool);
@@ -7234,7 +7337,7 @@ extern bool cxx_omp_create_clause_info (tree, tree, bool, bool,
bool, bool);
extern tree baselink_for_fns (tree);
extern void finish_static_assert (tree, tree, location_t,
- bool);
+ bool, bool);
extern tree finish_decltype_type (tree, bool, tsubst_flags_t);
extern tree finish_trait_expr (location_t, enum cp_trait_kind, tree, tree);
extern tree build_lambda_expr (void);
@@ -7271,6 +7374,8 @@ extern tree finish_builtin_launder (location_t, tree,
tsubst_flags_t);
extern tree cp_build_vec_convert (tree, location_t, tree,
tsubst_flags_t);
+extern tree cp_build_bit_cast (location_t, tree, tree,
+ tsubst_flags_t);
extern void start_lambda_scope (tree);
extern void record_lambda_scope (tree);
extern void record_null_lambda_scope (tree);
@@ -7338,7 +7443,7 @@ extern bool is_local_temp (tree);
extern tree build_aggr_init_expr (tree, tree);
extern tree get_target_expr (tree);
extern tree get_target_expr_sfinae (tree, tsubst_flags_t);
-extern tree build_cplus_array_type (tree, tree);
+extern tree build_cplus_array_type (tree, tree, int is_dep = -1);
extern tree build_array_of_n_type (tree, int);
extern bool array_of_runtime_bound_p (tree);
extern bool vla_type_p (tree);
@@ -7349,6 +7454,7 @@ extern tree hash_tree_cons (tree, tree, tree);
extern tree hash_tree_chain (tree, tree);
extern tree build_qualified_name (tree, tree, tree, bool);
extern tree build_ref_qualified_type (tree, cp_ref_qualifier);
+extern tree make_binding_vec (tree, unsigned clusters);
inline tree ovl_first (tree) ATTRIBUTE_PURE;
extern tree ovl_make (tree fn,
tree next = NULL_TREE);
@@ -7376,6 +7482,7 @@ extern tree bind_template_template_parm (tree, tree);
extern tree array_type_nelts_total (tree);
extern tree array_type_nelts_top (tree);
extern bool array_of_unknown_bound_p (const_tree);
+extern bool source_location_current_p (tree);
extern tree break_out_target_exprs (tree, bool = false);
extern tree build_ctor_subob_ref (tree, tree, tree);
extern tree replace_placeholders (tree, tree, bool * = NULL);
@@ -7461,7 +7568,7 @@ extern int comp_cv_qualification (const_tree, const_tree);
extern int comp_cv_qualification (int, int);
extern int comp_cv_qual_signature (tree, tree);
extern tree cxx_sizeof_or_alignof_expr (location_t, tree,
- enum tree_code, bool);
+ enum tree_code, bool, bool);
extern tree cxx_sizeof_or_alignof_type (location_t, tree,
enum tree_code, bool, bool);
extern tree cxx_alignas_expr (tree);
@@ -7875,9 +7982,20 @@ extern void vtv_recover_class_info (void);
extern void vtv_build_vtable_verify_fndecl (void);
/* In constexpr.c */
+/* Representation of entries in the constexpr function definition table. */
+
+struct GTY((for_user)) constexpr_fundef {
+ tree decl;
+ tree body;
+ tree parms;
+ tree result;
+};
+
extern void fini_constexpr (void);
extern bool literal_type_p (tree);
-extern tree register_constexpr_fundef (tree, tree);
+extern void maybe_save_constexpr_fundef (tree);
+extern void register_constexpr_fundef (const constexpr_fundef &);
+extern constexpr_fundef *retrieve_constexpr_fundef (tree);
extern bool is_valid_constexpr_fn (tree, bool);
extern bool check_constexpr_ctor_body (tree, tree, bool);
extern tree constexpr_fn_retval (tree);
@@ -7905,7 +8023,7 @@ extern tree maybe_fold_non_dependent_expr (tree,
tsubst_flags_t = tf_warning_or_error);
extern tree fold_non_dependent_init (tree,
tsubst_flags_t = tf_warning_or_error,
- bool = false);
+ bool = false, tree = NULL_TREE);
extern tree fold_simple (tree);
extern bool reduced_constant_expression_p (tree);
extern bool is_instantiation_of_constexpr (tree);
@@ -7972,14 +8090,16 @@ type_unknown_p (const_tree expr)
inline hashval_t
named_decl_hash::hash (const value_type decl)
{
- tree name = OVL_NAME (decl);
+ tree name = (TREE_CODE (decl) == BINDING_VECTOR
+ ? BINDING_VECTOR_NAME (decl) : OVL_NAME (decl));
return name ? IDENTIFIER_HASH_VALUE (name) : 0;
}
inline bool
named_decl_hash::equal (const value_type existing, compare_type candidate)
{
- tree name = OVL_NAME (existing);
+ tree name = (TREE_CODE (existing) == BINDING_VECTOR
+ ? BINDING_VECTOR_NAME (existing) : OVL_NAME (existing));
return candidate == name;
}
diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c
index 058b9c2..b97f70e 100644
--- a/gcc/cp/cxx-pretty-print.c
+++ b/gcc/cp/cxx-pretty-print.c
@@ -655,6 +655,15 @@ cxx_pretty_printer::postfix_expression (tree t)
pp_right_paren (this);
break;
+ case BIT_CAST_EXPR:
+ pp_cxx_ws_string (this, "__builtin_bit_cast");
+ pp_left_paren (this);
+ type_id (TREE_TYPE (t));
+ pp_comma (this);
+ expression (TREE_OPERAND (t, 0));
+ pp_right_paren (this);
+ break;
+
case EMPTY_CLASS_EXPR:
type_id (TREE_TYPE (t));
pp_left_paren (this);
@@ -2666,6 +2675,12 @@ pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
case CPTK_IS_CONSTRUCTIBLE:
pp_cxx_ws_string (pp, "__is_constructible");
break;
+ case CPTK_IS_NOTHROW_ASSIGNABLE:
+ pp_cxx_ws_string (pp, "__is_nothrow_assignable");
+ break;
+ case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
+ pp_cxx_ws_string (pp, "__is_nothrow_constructible");
+ break;
default:
gcc_unreachable ();
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 6264884..a28e792 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -2452,6 +2452,20 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
if (! DECL_COMDAT (olddecl))
DECL_COMDAT (newdecl) = 0;
+ if (VAR_OR_FUNCTION_DECL_P (newdecl) && DECL_LOCAL_DECL_P (newdecl))
+ {
+ if (!DECL_LOCAL_DECL_P (olddecl))
+ /* This can happen if olddecl was brought in from the
+ enclosing namespace via a using-decl. The new decl is
+ then not a block-scope extern at all. */
+ DECL_LOCAL_DECL_P (newdecl) = false;
+ else
+ {
+ retrofit_lang_decl (newdecl);
+ DECL_LOCAL_DECL_ALIAS (newdecl) = DECL_LOCAL_DECL_ALIAS (olddecl);
+ }
+ }
+
new_template_info = NULL_TREE;
if (DECL_LANG_SPECIFIC (newdecl) && DECL_LANG_SPECIFIC (olddecl))
{
@@ -2735,8 +2749,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
with that from NEWDECL below. */
if (DECL_LANG_SPECIFIC (olddecl))
{
- gcc_assert (DECL_LANG_SPECIFIC (olddecl)
- != DECL_LANG_SPECIFIC (newdecl));
+ gcc_checking_assert (DECL_LANG_SPECIFIC (olddecl)
+ != DECL_LANG_SPECIFIC (newdecl));
ggc_free (DECL_LANG_SPECIFIC (olddecl));
}
@@ -2866,7 +2880,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
done later in decl_attributes since we are called before attributes
are assigned. */
if (DECL_SECTION_NAME (newdecl) != NULL)
- set_decl_section_name (olddecl, DECL_SECTION_NAME (newdecl));
+ set_decl_section_name (olddecl, newdecl);
if (DECL_ONE_ONLY (newdecl))
{
@@ -4118,6 +4132,14 @@ make_unbound_class_template (tree context, tree name, tree parm_list,
return tmpl;
}
+ return make_unbound_class_template_raw (context, name, parm_list);
+}
+
+/* Build an UNBOUND_CLASS_TEMPLATE. */
+
+tree
+make_unbound_class_template_raw (tree context, tree name, tree parm_list)
+{
/* Build the UNBOUND_CLASS_TEMPLATE. */
tree t = cxx_make_type (UNBOUND_CLASS_TEMPLATE);
TYPE_CONTEXT (t) = FROB_CONTEXT (context);
@@ -5234,6 +5256,7 @@ start_decl (const cp_declarator *declarator,
bool was_public;
int flags;
bool alias;
+ tree initial;
*pushed_scope_p = NULL_TREE;
@@ -5258,6 +5281,10 @@ start_decl (const cp_declarator *declarator,
return error_mark_node;
}
+ /* Save the DECL_INITIAL value in case it gets clobbered to assist
+ with attribute validation. */
+ initial = DECL_INITIAL (decl);
+
if (initialized)
{
if (! toplevel_bindings_p ()
@@ -5267,6 +5294,10 @@ start_decl (const cp_declarator *declarator,
DECL_EXTERNAL (decl) = 0;
if (toplevel_bindings_p ())
TREE_STATIC (decl) = 1;
+ /* Tell 'cplus_decl_attributes' this is an initialized decl,
+ even though we might not yet have the initializer expression. */
+ if (!DECL_INITIAL (decl))
+ DECL_INITIAL (decl) = error_mark_node;
}
alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl)) != 0;
@@ -5285,6 +5316,10 @@ start_decl (const cp_declarator *declarator,
/* Set attributes here so if duplicate decl, will have proper attributes. */
cplus_decl_attributes (&decl, attributes, flags);
+ /* Restore the original DECL_INITIAL that we may have clobbered earlier to
+ assist with attribute validation. */
+ DECL_INITIAL (decl) = initial;
+
/* Dllimported symbols cannot be defined. Static data members (which
can be initialized in-class and dllimported) go through grokfield,
not here, so we don't need to exclude those decls when checking for
@@ -6865,9 +6900,17 @@ check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups)
have returned an INIT_EXPR rather than a CALL_EXPR. In that
case, pull the initializer back out and pass it down into
store_init_value. */
- while (TREE_CODE (init_code) == EXPR_STMT
- || TREE_CODE (init_code) == CONVERT_EXPR)
- init_code = TREE_OPERAND (init_code, 0);
+ while (true)
+ {
+ if (TREE_CODE (init_code) == EXPR_STMT
+ || TREE_CODE (init_code) == STMT_EXPR
+ || TREE_CODE (init_code) == CONVERT_EXPR)
+ init_code = TREE_OPERAND (init_code, 0);
+ else if (TREE_CODE (init_code) == BIND_EXPR)
+ init_code = BIND_EXPR_BODY (init_code);
+ else
+ break;
+ }
if (TREE_CODE (init_code) == INIT_EXPR)
{
/* In C++20, the call to build_aggr_init could have created
@@ -7926,10 +7969,9 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
make_rtl_for_nonlocal_decl (decl, init, asmspec);
- /* Check for abstractness of the type. Notice that there is no
- need to strip array types here since the check for those types
- is already done within create_array_type_for_decl. */
- abstract_virtuals_error (decl, type);
+ /* Check for abstractness of the type. */
+ if (var_definition_p)
+ abstract_virtuals_error (decl, type);
if (TREE_TYPE (decl) == error_mark_node)
/* No initialization required. */
@@ -10335,7 +10377,7 @@ fold_sizeof_expr (tree t)
else
r = cxx_sizeof_or_alignof_expr (EXPR_LOCATION (t),
TREE_OPERAND (t, 0), SIZEOF_EXPR,
- false);
+ false, false);
if (r == error_mark_node)
r = size_one_node;
return r;
@@ -10701,11 +10743,6 @@ create_array_type_for_decl (tree name, tree type, tree size, location_t loc)
itype = compute_array_index_type_loc (loc, name, size,
tf_warning_or_error);
- /* [dcl.array]
- T is called the array element type; this type shall not be [...] an
- abstract class type. */
- abstract_virtuals_error (name, type);
-
return build_cplus_array_type (type, itype);
}
@@ -12097,11 +12134,6 @@ grokdeclarator (const cp_declarator *declarator,
/* Declaring a function type. */
- {
- iloc_sentinel ils (declspecs->locations[ds_type_spec]);
- abstract_virtuals_error (ACU_RETURN, type);
- }
-
/* Pick up type qualifiers which should be applied to `this'. */
memfn_quals = declarator->u.function.qualifiers;
/* Pick up virt-specifiers. */
@@ -13121,6 +13153,16 @@ grokdeclarator (const cp_declarator *declarator,
if (decl_context == PARM && AUTO_IS_DECLTYPE (auto_node))
error_at (typespec_loc,
"cannot declare a parameter with %<decltype(auto)%>");
+ else if (tree c = CLASS_PLACEHOLDER_TEMPLATE (auto_node))
+ {
+ auto_diagnostic_group g;
+ error_at (typespec_loc,
+ "class template placeholder %qE not permitted "
+ "in this context", c);
+ if (decl_context == PARM && cxx_dialect >= cxx20)
+ inform (typespec_loc, "use %<auto%> for an "
+ "abbreviated function template");
+ }
else
error_at (typespec_loc,
"%<auto%> parameter not permitted in this context");
@@ -13872,6 +13914,7 @@ require_complete_types_for_parms (tree parms)
relayout_decl (parms);
DECL_ARG_TYPE (parms) = type_passed_as (TREE_TYPE (parms));
+ abstract_virtuals_error (parms, TREE_TYPE (parms));
maybe_warn_parm_abi (TREE_TYPE (parms),
DECL_SOURCE_LOCATION (parms));
}
@@ -14109,9 +14152,6 @@ grokparms (tree parmlist, tree *parms)
type = build_pointer_type (type);
TREE_TYPE (decl) = type;
}
- else if (abstract_virtuals_error (decl, type))
- /* Ignore any default argument. */
- init = NULL_TREE;
else if (cxx_dialect < cxx17 && INDIRECT_TYPE_P (type))
{
/* Before C++17 DR 393:
@@ -16871,20 +16911,6 @@ record_key_method_defined (tree fndecl)
}
}
-/* Subroutine of finish_function.
- Save the body of constexpr functions for possible
- future compile time evaluation. */
-
-static void
-maybe_save_function_definition (tree fun)
-{
- if (!processing_template_decl
- && DECL_DECLARED_CONSTEXPR_P (fun)
- && !cp_function_chain->invalid_constexpr
- && !DECL_CLONED_FUNCTION_P (fun))
- register_constexpr_fundef (fun, DECL_SAVED_TREE (fun));
-}
-
/* Attempt to add a fix-it hint to RICHLOC suggesting the insertion
of "return *this;" immediately before its location, using FNDECL's
first statement (if any) to give the indentation, if appropriate. */
@@ -16918,7 +16944,7 @@ emit_coro_helper (tree helper)
allocate_struct_function (helper, false);
cfun->language = ggc_cleared_alloc<language_function> ();
poplevel (1, 0, 1);
- maybe_save_function_definition (helper);
+ maybe_save_constexpr_fundef (helper);
/* We must start each function with a clear fold cache. */
clear_fold_cache ();
cp_fold_function (helper);
@@ -17152,7 +17178,7 @@ finish_function (bool inline_p)
/* Save constexpr function body before it gets munged by
the NRV transformation. */
- maybe_save_function_definition (fndecl);
+ maybe_save_constexpr_fundef (fndecl);
/* Invoke the pre-genericize plugin before we start munging things. */
if (!processing_template_decl)
@@ -17427,9 +17453,6 @@ complete_vars (tree type)
else
ix++;
}
-
- /* Check for pending declarations which may have abstract type. */
- complete_type_check_abstract (type);
}
/* If DECL is of a type which needs a cleanup, build and return an
@@ -17597,6 +17620,7 @@ cp_tree_node_structure (union lang_tree_node * t)
case DEFERRED_PARSE: return TS_CP_DEFERRED_PARSE;
case IDENTIFIER_NODE: return TS_CP_IDENTIFIER;
case LAMBDA_EXPR: return TS_CP_LAMBDA_EXPR;
+ case BINDING_VECTOR: return TS_CP_BINDING_VECTOR;
case OVERLOAD: return TS_CP_OVERLOAD;
case PTRMEM_CST: return TS_CP_PTRMEM;
case STATIC_ASSERT: return TS_CP_STATIC_ASSERT;
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 396558b..d11591d 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -529,6 +529,7 @@ dump_type (cxx_pretty_printer *pp, tree t, int flags)
case INTEGER_TYPE:
case REAL_TYPE:
case VOID_TYPE:
+ case OPAQUE_TYPE:
case BOOLEAN_TYPE:
case COMPLEX_TYPE:
case VECTOR_TYPE:
@@ -874,6 +875,7 @@ dump_type_prefix (cxx_pretty_printer *pp, tree t, int flags)
case UNION_TYPE:
case LANG_TYPE:
case VOID_TYPE:
+ case OPAQUE_TYPE:
case TYPENAME_TYPE:
case COMPLEX_TYPE:
case VECTOR_TYPE:
@@ -997,6 +999,7 @@ dump_type_suffix (cxx_pretty_printer *pp, tree t, int flags)
case UNION_TYPE:
case LANG_TYPE:
case VOID_TYPE:
+ case OPAQUE_TYPE:
case TYPENAME_TYPE:
case COMPLEX_TYPE:
case VECTOR_TYPE:
@@ -2810,6 +2813,7 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags)
case ENUMERAL_TYPE:
case REAL_TYPE:
case VOID_TYPE:
+ case OPAQUE_TYPE:
case BOOLEAN_TYPE:
case INTEGER_TYPE:
case COMPLEX_TYPE:
@@ -3549,6 +3553,14 @@ function_category (tree fn)
return _("In function %qs");
}
+/* Disable warnings about missing quoting in GCC diagnostics for
+ the pp_verbatim calls. Their format strings deliberately don't
+ follow GCC diagnostic conventions. */
+#if __GNUC__ >= 10
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wformat-diag"
+#endif
+
/* Report the full context of a current template instantiation,
onto BUFFER. */
static void
@@ -4149,12 +4161,17 @@ add_quotes (const char *content, bool show_color)
pp_show_color (&tmp_pp) = show_color;
/* We have to use "%<%s%>" rather than "%qs" here in order to avoid
- quoting colorization bytes within the results. */
+ quoting colorization bytes within the results and using either
+ pp_quote or pp_begin_quote doesn't work the same. */
pp_printf (&tmp_pp, "%<%s%>", content);
return pp_ggc_formatted_text (&tmp_pp);
}
+#if __GNUC__ >= 10
+# pragma GCC diagnostic pop
+#endif
+
/* If we had %H and %I, and hence deferred printing them,
print them now, storing the result into the chunk_info
for pp_format. Quote them if 'q' was provided.
diff --git a/gcc/cp/g++spec.c b/gcc/cp/g++spec.c
index 0ab63bc..0f17148 100644
--- a/gcc/cp/g++spec.c
+++ b/gcc/cp/g++spec.c
@@ -27,12 +27,10 @@ along with GCC; see the file COPYING3. If not see
#define LANGSPEC (1<<1)
/* This bit is set if they did `-lm' or `-lmath'. */
#define MATHLIB (1<<2)
-/* This bit is set if they did `-lrt' or equivalent. */
-#define TIMELIB (1<<3)
/* This bit is set if they did `-lc'. */
-#define WITHLIBC (1<<4)
+#define WITHLIBC (1<<3)
/* Skip this option. */
-#define SKIPOPT (1<<5)
+#define SKIPOPT (1<<4)
#ifndef MATH_LIBRARY
#define MATH_LIBRARY "m"
@@ -41,10 +39,6 @@ along with GCC; see the file COPYING3. If not see
#define MATH_LIBRARY_PROFILE MATH_LIBRARY
#endif
-#ifndef TIME_LIBRARY
-#define TIME_LIBRARY ""
-#endif
-
#ifndef LIBSTDCXX
#define LIBSTDCXX "stdc++"
#endif
@@ -95,15 +89,12 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
const struct cl_decoded_option *saw_libc = NULL;
/* An array used to flag each argument that needs a bit set for
- LANGSPEC, MATHLIB, TIMELIB, or WITHLIBC. */
+ LANGSPEC, MATHLIB, or WITHLIBC. */
int *args;
/* By default, we throw on the math library if we have one. */
int need_math = (MATH_LIBRARY[0] != '\0');
- /* By default, we throw on the time library if we have one. */
- int need_time = (TIME_LIBRARY[0] != '\0');
-
/* True if we saw -static. */
int static_link = 0;
@@ -147,11 +138,6 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
args[i] |= MATHLIB;
need_math = 0;
}
- else if (strcmp (arg, TIME_LIBRARY) == 0)
- {
- args[i] |= TIMELIB;
- need_time = 0;
- }
else if (strcmp (arg, "c") == 0)
args[i] |= WITHLIBC;
else
@@ -285,12 +271,6 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
saw_math = &decoded_options[i];
}
- if (!saw_time && (args[i] & TIMELIB) && library > 0)
- {
- --j;
- saw_time = &decoded_options[i];
- }
-
if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
{
--j;
@@ -377,13 +357,6 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
}
if (saw_time)
new_decoded_options[j++] = *saw_time;
- else if (library > 0 && need_time)
- {
- generate_option (OPT_l, TIME_LIBRARY, 1, CL_DRIVER,
- &new_decoded_options[j]);
- added_libraries++;
- j++;
- }
if (saw_libc)
new_decoded_options[j++] = *saw_libc;
if (shared_libgcc && !static_link)
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index ffb84ea..0b98f33 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -3766,7 +3766,11 @@ build_new (location_t loc, vec<tree, va_gc> **placement, tree type,
/* P1009: Array size deduction in new-expressions. */
const bool array_p = TREE_CODE (type) == ARRAY_TYPE;
- if (*init && (array_p || (nelts && cxx_dialect >= cxx20)))
+ if (*init
+ /* If ARRAY_P, we have to deduce the array bound. For C++20 paren-init,
+ we have to process the parenthesized-list. But don't do it for (),
+ which is value-initialization, and INIT should stay empty. */
+ && (array_p || (cxx_dialect >= cxx20 && nelts && !(*init)->is_empty ())))
{
/* This means we have 'new T[]()'. */
if ((*init)->is_empty ())
diff --git a/gcc/cp/lang-specs.h b/gcc/cp/lang-specs.h
index 0ad4a33..1388aae 100644
--- a/gcc/cp/lang-specs.h
+++ b/gcc/cp/lang-specs.h
@@ -40,17 +40,57 @@ along with GCC; see the file COPYING3. If not see
{".tcc", "@c++-header", 0, 0, 0},
{".hh", "@c++-header", 0, 0, 0},
{"@c++-header",
- "%{E|M|MM:cc1plus -E %(cpp_options) %2 %(cpp_debug_options)}"
+ "%{E|M|MM:cc1plus -E %{fmodules-ts:-fdirectives-only -fmodule-header}"
+ " %(cpp_options) %2 %(cpp_debug_options)}"
+ "%{!E:%{!M:%{!MM:"
+ " %{save-temps*|no-integrated-cpp:cc1plus -E"
+ " %{fmodules-ts:-fdirectives-only -fmodule-header}"
+ " %(cpp_options) %2 -o %{save-temps*:%b.ii} %{!save-temps*:%g.ii} \n}"
+ " cc1plus %{save-temps*|no-integrated-cpp:-fpreprocessed"
+ " %{fmodules-ts:-fdirectives-only}"
+ " %{save-temps*:%b.ii} %{!save-temps*:%g.ii}}"
+ " %{!save-temps*:%{!no-integrated-cpp:%(cpp_unique_options)}}"
+ " %{fmodules-ts:-fmodule-header %{fpreprocessed:-fdirectives-only}}"
+ " %(cc1_options) %2"
+ " %{!S:-o %g.s%V}"
+ " %{!fsyntax-only:%{!fmodule-*:%{!fmodules-*:%{!fdump-ada-spec*:"
+ " %{!o*:--output-pch=%i.gch}%W{o*:--output-pch=%*}}}}}}}}",
+ CPLUSPLUS_CPP_SPEC, 0, 0},
+ {"@c++-system-header",
+ "%{E|M|MM:cc1plus -E"
+ " %{fmodules-ts:-fdirectives-only -fmodule-header=system}"
+ " %(cpp_options) %2 %(cpp_debug_options)}"
"%{!E:%{!M:%{!MM:"
" %{save-temps*|no-integrated-cpp:cc1plus -E"
+ " %{fmodules-ts:-fdirectives-only -fmodule-header=system}"
" %(cpp_options) %2 -o %{save-temps*:%b.ii} %{!save-temps*:%g.ii} \n}"
" cc1plus %{save-temps*|no-integrated-cpp:-fpreprocessed"
+ " %{fmodules-ts:-fdirectives-only}"
" %{save-temps*:%b.ii} %{!save-temps*:%g.ii}}"
" %{!save-temps*:%{!no-integrated-cpp:%(cpp_unique_options)}}"
+ " %{fmodules-ts:-fmodule-header=system %{fpreprocessed:-fdirectives-only}}"
" %(cc1_options) %2"
- " %{!fsyntax-only:%{!S:-o %g.s}"
- " %{!fdump-ada-spec*:%{!o*:--output-pch=%i.gch}"
- " %W{o*:--output-pch=%*}}%V}}}}",
+ " %{!S:-o %g.s%V}"
+ " %{!fsyntax-only:%{!fmodule-*:%{!fmodules-*:%{!fdump-ada-spec*:"
+ " %{!o*:--output-pch=%i.gch}%W{o*:--output-pch=%*}}}}}}}}",
+ CPLUSPLUS_CPP_SPEC, 0, 0},
+ {"@c++-user-header",
+ "%{E|M|MM:cc1plus -E"
+ " %{fmodules-ts:-fdirectives-only -fmodule-header=user}"
+ " %(cpp_options) %2 %(cpp_debug_options)}"
+ "%{!E:%{!M:%{!MM:"
+ " %{save-temps*|no-integrated-cpp:cc1plus -E"
+ " %{fmodules-ts:-fdirectives-only -fmodule-header=user}"
+ " %(cpp_options) %2 -o %{save-temps*:%b.ii} %{!save-temps*:%g.ii} \n}"
+ " cc1plus %{save-temps*|no-integrated-cpp:-fpreprocessed"
+ " %{fmodules-ts:-fdirectives-only}"
+ " %{save-temps*:%b.ii} %{!save-temps*:%g.ii}}"
+ " %{!save-temps*:%{!no-integrated-cpp:%(cpp_unique_options)}}"
+ " %{fmodules-ts:-fmodule-header=user %{fpreprocessed:-fdirectives-only}}"
+ " %(cc1_options) %2"
+ " %{!S:-o %g.s%V}"
+ " %{!fsyntax-only:%{!fmodule-*:%{!fmodules-*:%{!fdump-ada-spec*:"
+ " %{!o*:--output-pch=%i.gch}%W{o*:--output-pch=%*}}}}}}}}",
CPLUSPLUS_CPP_SPEC, 0, 0},
{"@c++",
"%{E|M|MM:cc1plus -E %(cpp_options) %2 %(cpp_debug_options)}"
@@ -60,11 +100,14 @@ along with GCC; see the file COPYING3. If not see
" cc1plus %{save-temps*|no-integrated-cpp:-fpreprocessed"
" %{save-temps*:%b.ii} %{!save-temps*:%g.ii}}"
" %{!save-temps*:%{!no-integrated-cpp:%(cpp_unique_options)}}"
- " %(cc1_options) %2"
- " %{!fsyntax-only:%(invoke_as)}}}}",
+ " %(cc1_options) %2"
+ " %{fmodule-only:%{!S:-o %g.s%V}}"
+ " %{!fsyntax-only:%{!fmodule-only:%(invoke_as)}}}}}",
CPLUSPLUS_CPP_SPEC, 0, 0},
{".ii", "@c++-cpp-output", 0, 0, 0},
{"@c++-cpp-output",
"%{!E:%{!M:%{!MM:"
" cc1plus -fpreprocessed %i %(cc1_options) %2"
- " %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
+ " %{fmodule-only:%{!S:-o %g.s%V}}"
+ " %{!fsyntax-only:%{!fmodule-only:%{!fmodule-header*:"
+ " %(invoke_as)}}}}}}", 0, 0, 0},
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 8a69bc4..795f571 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -235,6 +235,8 @@ init_reswords (void)
mask |= D_CXX_CONCEPTS;
if (!flag_coroutines)
mask |= D_CXX_COROUTINES;
+ if (!flag_modules)
+ mask |= D_CXX_MODULES;
if (!flag_tm)
mask |= D_TRANSMEM;
if (!flag_char8_t)
@@ -678,7 +680,7 @@ build_lang_decl_loc (location_t loc, enum tree_code code, tree name, tree type)
/* Maybe add a raw lang_decl to T, a decl. Return true if it needed
one. */
-static bool
+bool
maybe_add_lang_decl_raw (tree t, bool decomp_p)
{
size_t size;
@@ -831,8 +833,7 @@ copy_lang_type (tree node)
if (! TYPE_LANG_SPECIFIC (node))
return;
- struct lang_type *lt
- = (struct lang_type *) ggc_internal_alloc (sizeof (struct lang_type));
+ auto *lt = (struct lang_type *) ggc_internal_alloc (sizeof (struct lang_type));
memcpy (lt, TYPE_LANG_SPECIFIC (node), (sizeof (struct lang_type)));
TYPE_LANG_SPECIFIC (node) = lt;
@@ -858,15 +859,15 @@ copy_type (tree type MEM_STAT_DECL)
/* Add a raw lang_type to T, a type, should it need one. */
-static bool
+bool
maybe_add_lang_type_raw (tree t)
{
if (!RECORD_OR_UNION_CODE_P (TREE_CODE (t)))
return false;
- TYPE_LANG_SPECIFIC (t)
- = (struct lang_type *) (ggc_internal_cleared_alloc
- (sizeof (struct lang_type)));
+ auto *lt = (struct lang_type *) (ggc_internal_cleared_alloc
+ (sizeof (struct lang_type)));
+ TYPE_LANG_SPECIFIC (t) = lt;
if (GATHER_STATISTICS)
{
diff --git a/gcc/cp/logic.cc b/gcc/cp/logic.cc
index 6701488..5592680 100644
--- a/gcc/cp/logic.cc
+++ b/gcc/cp/logic.cc
@@ -303,9 +303,10 @@ debug (formula& f)
{
for (formula::iterator i = f.begin(); i != f.end(); ++i)
{
- verbatim ("(((");
+ /* Format punctuators via %s to avoid -Wformat-diag. */
+ verbatim ("%s", "(((");
debug (*i);
- verbatim (")))");
+ verbatim ("%s", ")))");
}
}
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 9fd3001..5548e51 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -3049,11 +3049,30 @@ write_expression (tree expr)
else
goto normal_expr;
}
- else if (TREE_CODE (expr) == ALIGNOF_EXPR
- && TYPE_P (TREE_OPERAND (expr, 0)))
+ else if (TREE_CODE (expr) == ALIGNOF_EXPR)
{
- write_string ("at");
- write_type (TREE_OPERAND (expr, 0));
+ if (!ALIGNOF_EXPR_STD_P (expr))
+ {
+ if (abi_warn_or_compat_version_crosses (15))
+ G.need_abi_warning = true;
+ if (abi_version_at_least (15))
+ {
+ /* We used to mangle __alignof__ like alignof. */
+ write_string ("v111__alignof__");
+ if (TYPE_P (TREE_OPERAND (expr, 0)))
+ write_type (TREE_OPERAND (expr, 0));
+ else
+ write_expression (TREE_OPERAND (expr, 0));
+ return;
+ }
+ }
+ if (TYPE_P (TREE_OPERAND (expr, 0)))
+ {
+ write_string ("at");
+ write_type (TREE_OPERAND (expr, 0));
+ }
+ else
+ goto normal_expr;
}
else if (code == SCOPE_REF
|| code == BASELINK)
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 16e7635..4de192f 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -351,7 +351,7 @@ use_thunk (tree thunk_fndecl, bool emit_p)
resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
/* Output the thunk into the same section as function. */
- set_decl_section_name (thunk_fndecl, DECL_SECTION_NAME (fn));
+ set_decl_section_name (thunk_fndecl, fn);
symtab_node::get (thunk_fndecl)->implicit_section
= symtab_node::get (fn)->implicit_section;
}
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
new file mode 100644
index 0000000..596061b
--- /dev/null
+++ b/gcc/cp/module.cc
@@ -0,0 +1,21 @@
+/* C++ modules. Experimental!
+ Copyright (C) 2017-2020 Free Software Foundation, Inc.
+ Written by Nathan Sidwell <nathan@acm.org> while at FaceBook
+
+ 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 intentionally left empty. */
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 410ec59..c87d151 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -2125,6 +2125,10 @@ supplement_binding_1 (cxx_binding *binding, tree decl)
region to refer only to the namespace to which it already
refers. */
ok = false;
+ else if (TREE_CODE (bval) == USING_DECL
+ && CONST_DECL_USING_P (decl))
+ /* Let the clone hide the using-decl that introduced it. */
+ binding->value = decl;
else
{
if (!error_operand_p (bval))
@@ -3287,12 +3291,17 @@ begin_scope (scope_kind kind, tree entity)
case sk_cond:
case sk_class:
case sk_scoped_enum:
- case sk_function_parms:
case sk_transaction:
case sk_omp:
scope->keep = keep_next_level_flag;
break;
+ case sk_function_parms:
+ scope->keep = keep_next_level_flag;
+ if (entity)
+ scope->immediate_fn_ctx_p = DECL_IMMEDIATE_FUNCTION_P (entity);
+ break;
+
case sk_namespace:
NAMESPACE_LEVEL (entity) = scope;
break;
@@ -4540,43 +4549,66 @@ push_class_level_binding (tree name, tree x)
/* Process and lookup a using decl SCOPE::lookup.name, filling in
lookup.values & lookup.type. Return true if ok. */
-static bool
+static tree
lookup_using_decl (tree scope, name_lookup &lookup)
{
tree current = current_scope ();
bool dependent_p = false;
+ tree binfo = NULL_TREE;
+ base_kind b_kind = bk_not_base;
+
+ /* Because C++20 breaks the invariant that only member using-decls
+ refer to members and only non-member using-decls refer to
+ non-members, we first do the lookups, and then do validation that
+ what we found is ok. */
+
+ if (TREE_CODE (scope) == ENUMERAL_TYPE
+ && cxx_dialect < cxx20
+ && UNSCOPED_ENUM_P (scope)
+ && !TYPE_FUNCTION_SCOPE_P (scope))
+ {
+ /* PR c++/60265 argued that since C++11 added explicit enum scope, we
+ should allow it as meaning the enclosing scope. I don't see any
+ justification for this in C++11, but let's keep allowing it. */
+ tree ctx = CP_TYPE_CONTEXT (scope);
+ if (CLASS_TYPE_P (ctx) == CLASS_TYPE_P (current))
+ scope = ctx;
+ }
if (TREE_CODE (scope) == NAMESPACE_DECL)
{
/* Naming a namespace member. */
- if (TYPE_P (current))
+ qualified_namespace_lookup (scope, &lookup);
+
+ if (TYPE_P (current)
+ && (!lookup.value
+ || lookup.type
+ || cxx_dialect < cxx20
+ || TREE_CODE (lookup.value) != CONST_DECL))
{
error ("using-declaration for non-member at class scope");
- return false;
+ return NULL_TREE;
}
-
- qualified_namespace_lookup (scope, &lookup);
}
else if (TREE_CODE (scope) == ENUMERAL_TYPE)
{
- error ("using-declaration may not name enumerator %<%E::%D%>",
- scope, lookup.name);
- return false;
+ /* Naming an enumeration member. */
+ if (cxx_dialect < cxx20)
+ error ("%<using%> with enumeration scope %q#T "
+ "only available with %<-std=c++20%> or %<-std=gnu++20%>",
+ scope);
+ lookup.value = lookup_enumerator (scope, lookup.name);
}
else
{
- /* Naming a class member. */
- if (!TYPE_P (current))
- {
- error ("using-declaration for member at non-class scope");
- return false;
- }
+ /* Naming a class member. This is awkward in C++20, because we
+ might be naming an enumerator of an unrelated class. */
- /* Make sure the name is not invalid */
+ /* You cannot using-decl a destructor. */
if (TREE_CODE (lookup.name) == BIT_NOT_EXPR)
{
error ("%<%T::%D%> names destructor", scope, lookup.name);
- return false;
+ return NULL_TREE;
}
/* Using T::T declares inheriting ctors, even if T is a typedef. */
@@ -4584,91 +4616,151 @@ lookup_using_decl (tree scope, name_lookup &lookup)
&& (lookup.name == TYPE_IDENTIFIER (scope)
|| constructor_name_p (lookup.name, scope)))
{
+ if (!TYPE_P (current))
+ {
+ error ("non-member using-declaration names constructor of %qT",
+ scope);
+ return NULL_TREE;
+ }
maybe_warn_cpp0x (CPP0X_INHERITING_CTORS);
lookup.name = ctor_identifier;
CLASSTYPE_NON_AGGREGATE (current) = true;
}
- /* Cannot introduce a constructor name. */
- if (constructor_name_p (lookup.name, current))
+ if (!MAYBE_CLASS_TYPE_P (scope))
+ ;
+ else if (TYPE_P (current))
{
- error ("%<%T::%D%> names constructor in %qT",
- scope, lookup.name, current);
- return false;
- }
-
- /* Member using decls finish processing when completing the
- class. */
- /* From [namespace.udecl]:
-
- A using-declaration used as a member-declaration shall refer
- to a member of a base class of the class being defined.
+ dependent_p = dependent_scope_p (scope);
+ if (!dependent_p)
+ {
+ binfo = lookup_base (current, scope, ba_any, &b_kind, tf_none);
+ gcc_checking_assert (b_kind >= bk_not_base);
- In general, we cannot check this constraint in a template
- because we do not know the entire set of base classes of the
- current class type. Morover, if SCOPE is dependent, it might
- match a non-dependent base. */
+ if (lookup.name == ctor_identifier)
+ {
+ /* Even if there are dependent bases, SCOPE will not
+ be direct base, no matter. */
+ if (b_kind < bk_proper_base || !binfo_direct_p (binfo))
+ {
+ error ("%qT is not a direct base of %qT", scope, current);
+ return NULL_TREE;
+ }
+ }
+ else if (b_kind < bk_proper_base)
+ binfo = TYPE_BINFO (scope);
+ else if (IDENTIFIER_CONV_OP_P (lookup.name)
+ && dependent_type_p (TREE_TYPE (lookup.name)))
+ dependent_p = true;
+ }
+ }
+ else
+ binfo = TYPE_BINFO (scope);
- dependent_p = dependent_scope_p (scope);
if (!dependent_p)
{
- base_kind b_kind;
- tree binfo = lookup_base (current, scope, ba_any, &b_kind,
- tf_warning_or_error);
- if (b_kind < bk_proper_base)
+ if (binfo)
+ lookup.value = lookup_member (binfo, lookup.name, /*protect=*/2,
+ /*want_type=*/false, tf_none);
+
+ tree saved_value = lookup.value;
+ if (lookup.value
+ && b_kind < bk_proper_base)
{
- /* If there are dependent bases, scope might resolve at
- instantiation time, even if it isn't exactly one of
- the dependent bases. */
- if (b_kind == bk_same_type || !any_dependent_bases_p ())
+ if (cxx_dialect >= cxx20
+ && TREE_CODE (lookup.value) == CONST_DECL)
{
- error_not_base_type (scope, current);
- return false;
+ /* Using an unrelated enum; check access here rather
+ than separately for class and non-class using. */
+ perform_or_defer_access_check
+ (binfo, lookup.value, lookup.value, tf_warning_or_error);
+ /* And then if this is a copy from handle_using_decl, look
+ through to the original enumerator. */
+ if (CONST_DECL_USING_P (lookup.value))
+ lookup.value = DECL_ABSTRACT_ORIGIN (lookup.value);
}
- /* Treat as-if dependent. */
- dependent_p = true;
+ else
+ lookup.value = NULL_TREE;
}
- else if (lookup.name == ctor_identifier && !binfo_direct_p (binfo))
+
+ if (!lookup.value)
{
- error ("cannot inherit constructors from indirect base %qT",
- scope);
- return false;
+ if (!TYPE_P (current))
+ {
+ error ("using-declaration for member at non-class scope");
+ return NULL_TREE;
+ }
+
+ if (b_kind < bk_proper_base)
+ {
+ if (b_kind == bk_not_base && any_dependent_bases_p ())
+ /* Treat as-if dependent. */
+ dependent_p = true;
+ else
+ {
+ auto_diagnostic_group g;
+ error_not_base_type (scope, current);
+ if (saved_value && DECL_IMPLICIT_TYPEDEF_P (saved_value)
+ && (TREE_CODE (TREE_TYPE (saved_value))
+ == ENUMERAL_TYPE))
+ inform (input_location,
+ "did you mean %<using enum %T::%D%>?",
+ scope, lookup.name);
+ return NULL_TREE;
+ }
+ }
}
- else if (IDENTIFIER_CONV_OP_P (lookup.name)
- && dependent_type_p (TREE_TYPE (lookup.name)))
- dependent_p = true;
- else
- lookup.value = lookup_member (binfo, lookup.name, 0,
- false, tf_warning_or_error);
}
}
- if (!dependent_p)
+ /* Did we find anything sane? */
+ if (dependent_p)
+ ;
+ else if (!lookup.value)
{
- if (!lookup.value)
- {
- error ("%qD has not been declared in %qE", lookup.name, scope);
- return false;
- }
+ error ("%qD has not been declared in %qD", lookup.name, scope);
+ return NULL_TREE;
+ }
+ else if (TREE_CODE (lookup.value) == TREE_LIST
+ /* We can (independently) have ambiguous implicit typedefs. */
+ || (lookup.type && TREE_CODE (lookup.type) == TREE_LIST))
+ {
+ error ("reference to %qD is ambiguous", lookup.name);
+ print_candidates (TREE_CODE (lookup.value) == TREE_LIST
+ ? lookup.value : lookup.type);
+ return NULL_TREE;
+ }
+ else if (TREE_CODE (lookup.value) == NAMESPACE_DECL)
+ {
+ error ("using-declaration may not name namespace %qD", lookup.value);
+ return NULL_TREE;
+ }
- if (TREE_CODE (lookup.value) == TREE_LIST
- /* We can (independently) have ambiguous implicit typedefs. */
- || (lookup.type && TREE_CODE (lookup.type) == TREE_LIST))
- {
- error ("reference to %qD is ambiguous", lookup.name);
- print_candidates (TREE_CODE (lookup.value) == TREE_LIST
- ? lookup.value : lookup.type);
- return false;
- }
+ if (TYPE_P (current))
+ {
+ /* In class scope. */
- if (TREE_CODE (lookup.value) == NAMESPACE_DECL)
+ /* Cannot introduce a constructor name. */
+ if (constructor_name_p (lookup.name, current))
{
- error ("using-declaration may not name namespace %qD", lookup.value);
- return false;
+ error ("%<%T::%D%> names constructor in %qT",
+ scope, lookup.name, current);
+ return NULL_TREE;
}
+
+ if (lookup.value && BASELINK_P (lookup.value))
+ /* The binfo from which the functions came does not matter. */
+ lookup.value = BASELINK_FUNCTIONS (lookup.value);
}
- return true;
+ tree using_decl = build_lang_decl (USING_DECL, lookup.name, NULL_TREE);
+ USING_DECL_SCOPE (using_decl) = scope;
+ USING_DECL_DECLS (using_decl) = lookup.value;
+ DECL_DEPENDENT_P (using_decl) = dependent_p;
+ if (TYPE_P (current) && b_kind == bk_not_base)
+ USING_DECL_UNRELATED_P (using_decl) = true;
+
+ return using_decl;
}
/* Process "using SCOPE::NAME" in a class scope. Return the
@@ -4682,20 +4774,7 @@ do_class_using_decl (tree scope, tree name)
return NULL_TREE;
name_lookup lookup (name);
- if (!lookup_using_decl (scope, lookup))
- return NULL_TREE;
-
- tree found = lookup.value;
- if (found && BASELINK_P (found))
- /* The binfo from which the functions came does not matter. */
- found = BASELINK_FUNCTIONS (found);
-
- tree using_decl = build_lang_decl (USING_DECL, lookup.name, NULL_TREE);
- USING_DECL_SCOPE (using_decl) = scope;
- USING_DECL_DECLS (using_decl) = found;
- DECL_DEPENDENT_P (using_decl) = !found;
-
- return using_decl;
+ return lookup_using_decl (scope, lookup);
}
@@ -5076,7 +5155,8 @@ finish_nonmember_using_decl (tree scope, tree name)
name_lookup lookup (name);
- if (!lookup_using_decl (scope, lookup))
+ tree using_decl = lookup_using_decl (scope, lookup);
+ if (!using_decl)
return;
/* Emit debug info. */
@@ -5105,8 +5185,6 @@ finish_nonmember_using_decl (tree scope, tree name)
}
else
{
- tree using_decl = build_lang_decl (USING_DECL, lookup.name, NULL_TREE);
- USING_DECL_SCOPE (using_decl) = scope;
add_decl_expr (using_decl);
cxx_binding *binding = find_local_binding (current_binding_level, name);
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index 6d18539..9cc8a42 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -68,6 +68,125 @@ struct GTY(()) cxx_saved_binding {
tree real_type_value;
};
+/* To support lazy module loading, we squirrel away a section number
+ (and a couple of flags) in the binding slot of unloaded bindings.
+ We rely on pointers being aligned and setting the bottom bit to
+ mark a lazy value. GTY doesn't like an array of union, so we have
+ a containing struct. */
+
+struct GTY(()) binding_slot {
+ union GTY((desc ("%1.is_lazy ()"))) binding_slot_lazy {
+ tree GTY((tag ("false"))) binding;
+ } u;
+
+ operator tree & ()
+ {
+ gcc_checking_assert (!is_lazy ());
+ return u.binding;
+ }
+ binding_slot &operator= (tree t)
+ {
+ u.binding = t;
+ return *this;
+ }
+ bool is_lazy () const
+ {
+ return bool (uintptr_t (u.binding) & 1);
+ }
+ void set_lazy (unsigned snum)
+ {
+ gcc_checking_assert (!u.binding);
+ u.binding = tree (uintptr_t ((snum << 1) | 1));
+ }
+ void or_lazy (unsigned snum)
+ {
+ gcc_checking_assert (is_lazy ());
+ u.binding = tree (uintptr_t (u.binding) | (snum << 1));
+ }
+ unsigned get_lazy () const
+ {
+ gcc_checking_assert (is_lazy ());
+ return unsigned (uintptr_t (u.binding) >> 1);
+ }
+};
+
+/* Bindings for modules are held in a sparse array. There is always a
+ current TU slot, others are allocated as needed. By construction
+ of the importing mechanism we only ever need to append to the
+ array. Rather than have straight index/slot tuples, we bunch them
+ up for greater packing.
+
+ The cluster representation packs well on a 64-bit system. */
+
+#define BINDING_VECTOR_SLOTS_PER_CLUSTER 2
+struct binding_index {
+ unsigned short base;
+ unsigned short span;
+};
+
+struct GTY(()) binding_cluster
+{
+ binding_index GTY((skip)) indices[BINDING_VECTOR_SLOTS_PER_CLUSTER];
+ binding_slot slots[BINDING_VECTOR_SLOTS_PER_CLUSTER];
+};
+
+/* These two fields overlay lang flags. So don't use those. */
+#define BINDING_VECTOR_ALLOC_CLUSTERS(NODE) \
+ (BINDING_VECTOR_CHECK (NODE)->base.u.dependence_info.clique)
+#define BINDING_VECTOR_NUM_CLUSTERS(NODE) \
+ (BINDING_VECTOR_CHECK (NODE)->base.u.dependence_info.base)
+#define BINDING_VECTOR_CLUSTER_BASE(NODE) \
+ (((tree_binding_vec *)BINDING_VECTOR_CHECK (NODE))->vec)
+#define BINDING_VECTOR_CLUSTER_LAST(NODE) \
+ (&BINDING_VECTOR_CLUSTER (NODE, BINDING_VECTOR_NUM_CLUSTERS (NODE) - 1))
+#define BINDING_VECTOR_CLUSTER(NODE,IX) \
+ (((tree_binding_vec *)BINDING_VECTOR_CHECK (NODE))->vec[IX])
+
+struct GTY(()) tree_binding_vec {
+ struct tree_base base;
+ tree name;
+ binding_cluster GTY((length ("%h.base.u.dependence_info.base"))) vec[1];
+};
+
+/* The name of a module vector. */
+#define BINDING_VECTOR_NAME(NODE) \
+ (((tree_binding_vec *)BINDING_VECTOR_CHECK (NODE))->name)
+
+/* tree_binding_vec does uses base.u.dependence_info.base field for
+ length. It does not have lang_flag etc available! */
+
+/* These two flags note if a module-vector contains deduplicated
+ bindings (i.e. multiple declarations in different imports). */
+/* This binding contains duplicate references to a global module
+ entity. */
+#define BINDING_VECTOR_GLOBAL_DUPS_P(NODE) \
+ (BINDING_VECTOR_CHECK (NODE)->base.static_flag)
+/* This binding contains duplicate references to a partioned module
+ entity. */
+#define BINDING_VECTOR_PARTITION_DUPS_P(NODE) \
+ (BINDING_VECTOR_CHECK (NODE)->base.volatile_flag)
+
+/* These two flags indicate the provenence of the bindings on this
+ particular vector slot. We can of course determine this from slot
+ number, but that's a relatively expensive lookup. This avoids
+ that when iterating. */
+/* This slot is part of the global module (a header unit). */
+#define MODULE_BINDING_GLOBAL_P(NODE) \
+ (OVERLOAD_CHECK (NODE)->base.static_flag)
+/* This slot is part of the current module (a partition or primary). */
+#define MODULE_BINDING_PARTITION_P(NODE) \
+ (OVERLOAD_CHECK (NODE)->base.volatile_flag)
+
+/* There are specializations of a template keyed to this binding. */
+#define BINDING_VECTOR_PENDING_SPECIALIZATIONS_P(NODE) \
+ (BINDING_VECTOR_CHECK (NODE)->base.public_flag)
+/* The key is in a header unit (not a named module partition or
+ primary). */
+#define BINDING_VECTOR_PENDING_IS_HEADER_P(NODE) \
+ (BINDING_VECTOR_CHECK (NODE)->base.protected_flag)
+/* The key is in a named module (primary or partition). */
+#define BINDING_VECTOR_PENDING_IS_PARTITION_P(NODE) \
+ (BINDING_VECTOR_CHECK (NODE)->base.private_flag)
extern tree identifier_type_value (tree);
extern void set_identifier_type_value (tree, tree);
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index 00621d6..127d7fa 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -512,7 +512,7 @@ maybe_clone_body (tree fn)
DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn);
DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn));
DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn);
- set_decl_section_name (clone, DECL_SECTION_NAME (fn));
+ set_decl_section_name (clone, fn);
/* Adjust the parameter names and locations. */
parm = DECL_ARGUMENTS (fn);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 9c08c0e..103567c 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -808,6 +808,14 @@ make_location (location_t caret, location_t start, cp_lexer *lexer)
return make_location (caret, start, t->location);
}
+/* Overload for make_location taking tokens instead of locations. */
+
+static inline location_t
+make_location (cp_token *caret, cp_token *start, cp_token *end)
+{
+ return make_location (caret->location, start->location, end->location);
+}
+
/* nonzero if we are presently saving tokens. */
static inline int
@@ -2187,7 +2195,7 @@ static void cp_parser_already_scoped_statement
static void cp_parser_declaration_seq_opt
(cp_parser *);
static void cp_parser_declaration
- (cp_parser *);
+ (cp_parser *, tree);
static void cp_parser_toplevel_declaration
(cp_parser *);
static void cp_parser_block_declaration
@@ -2233,12 +2241,14 @@ static bool cp_parser_using_declaration
(cp_parser *, bool);
static void cp_parser_using_directive
(cp_parser *);
+static void cp_parser_using_enum
+ (cp_parser *);
static tree cp_parser_alias_declaration
(cp_parser *);
static void cp_parser_asm_definition
(cp_parser *);
static void cp_parser_linkage_specification
- (cp_parser *);
+ (cp_parser *, tree);
static void cp_parser_static_assert
(cp_parser *, bool);
static tree cp_parser_decltype
@@ -5804,8 +5814,11 @@ cp_parser_primary_expression (cp_parser *parser,
if ((parser->local_variables_forbidden_p & LOCAL_VARS_FORBIDDEN)
&& local_variable_p (decl))
{
- error_at (id_expression.get_location (),
- "local variable %qD may not appear in this context",
+ const char *msg
+ = (TREE_CODE (decl) == PARM_DECL
+ ? _("parameter %qD may not appear in this context")
+ : _("local variable %qD may not appear in this context"));
+ error_at (id_expression.get_location (), msg,
decl.get_value ());
return error_mark_node;
}
@@ -7237,6 +7250,32 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
tf_warning_or_error);
}
+ case RID_BUILTIN_BIT_CAST:
+ {
+ tree expression;
+ tree type;
+ /* Consume the `__builtin_bit_cast' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the opening `('. */
+ matching_parens parens;
+ parens.require_open (parser);
+ location_t type_location
+ = cp_lexer_peek_token (parser->lexer)->location;
+ /* Parse the type-id. */
+ {
+ type_id_in_expr_sentinel s (parser);
+ type = cp_parser_type_id (parser);
+ }
+ /* Look for the `,'. */
+ cp_parser_require (parser, CPP_COMMA, RT_COMMA);
+ /* Now, parse the assignment-expression. */
+ expression = cp_parser_assignment_expression (parser);
+ /* Look for the closing `)'. */
+ parens.require_close (parser);
+ return cp_build_bit_cast (type_location, type, expression,
+ tf_warning_or_error);
+ }
+
default:
{
tree type;
@@ -8335,8 +8374,8 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
"ISO C++ does not allow %<alignof%> "
"with a non-type");
- ret = cxx_sizeof_or_alignof_expr (compound_loc,
- operand, op, true);
+ ret = cxx_sizeof_or_alignof_expr (compound_loc, operand, op,
+ std_alignof, true);
}
/* For SIZEOF_EXPR, just issue diagnostics, but keep
SIZEOF_EXPR with the original operand. */
@@ -9372,7 +9411,8 @@ maybe_add_cast_fixit (rich_location *rich_loc, location_t open_paren_loc,
/* Replace the open paren with "CAST_SUGGESTION<". */
pretty_printer pp;
- pp_printf (&pp, "%s<", cast_suggestion);
+ pp_string (&pp, cast_suggestion);
+ pp_less (&pp);
rich_loc->add_fixit_replace (open_paren_loc, pp_formatted_text (&pp));
/* Replace the close paren with "> (". */
@@ -10594,6 +10634,8 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
lambda-expression:
lambda-introducer lambda-declarator [opt] compound-statement
+ lambda-introducer < template-parameter-list > requires-clause [opt]
+ lambda-declarator [opt] compound-statement
Returns a representation of the expression. */
@@ -11051,13 +11093,11 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
/* Parse the (optional) middle of a lambda expression.
lambda-declarator:
- < template-parameter-list [opt] >
- requires-clause [opt]
- ( parameter-declaration-clause [opt] )
- attribute-specifier [opt]
+ ( parameter-declaration-clause )
decl-specifier-seq [opt]
- exception-specification [opt]
- lambda-return-type-clause [opt]
+ noexcept-specifier [opt]
+ attribute-specifier-seq [opt]
+ trailing-return-type [opt]
requires-clause [opt]
LAMBDA_EXPR is the current representation of the lambda expression. */
@@ -11207,8 +11247,6 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
trailing-return-type in case of decltype. */
pop_bindings_and_leave_scope ();
}
- else if (template_param_list != NULL_TREE) // generate diagnostic
- cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
/* Create the function call operator.
@@ -12671,8 +12709,15 @@ do_range_for_auto_deduction (tree decl, tree range_expr)
for (const auto &x : range)
- if this version doesn't make a copy. DECL is the RANGE_DECL; EXPR is the
- *__for_begin expression.
+ if this version doesn't make a copy.
+
+ This function also warns when the loop variable is initialized with
+ a value of a different type resulting in a copy:
+
+ int arr[10];
+ for (const double &x : arr)
+
+ DECL is the RANGE_DECL; EXPR is the *__for_begin expression.
This function is never called when processing_template_decl is on. */
static void
@@ -12690,7 +12735,22 @@ warn_for_range_copy (tree decl, tree expr)
if (TYPE_REF_P (type))
{
- /* TODO: Implement reference warnings. */
+ if (glvalue_p (expr) && !ref_conv_binds_directly_p (type, expr))
+ {
+ auto_diagnostic_group d;
+ if (warning_at (loc, OPT_Wrange_loop_construct,
+ "loop variable %qD of type %qT binds to a temporary "
+ "constructed from type %qT", decl, type,
+ TREE_TYPE (expr)))
+ {
+ tree ref = cp_build_qualified_type (TREE_TYPE (expr),
+ TYPE_QUAL_CONST);
+ ref = cp_build_reference_type (ref, /*rval*/false);
+ inform (loc, "use non-reference type %qT to make the copy "
+ "explicit or %qT to prevent copying",
+ non_reference (type), ref);
+ }
+ }
return;
}
else if (!CP_TYPE_CONST_P (type))
@@ -13496,7 +13556,7 @@ cp_parser_declaration_seq_opt (cp_parser* parser)
__extension__ declaration */
static void
-cp_parser_declaration (cp_parser* parser)
+cp_parser_declaration (cp_parser* parser, tree prefix_attrs)
{
int saved_pedantic;
@@ -13504,7 +13564,7 @@ cp_parser_declaration (cp_parser* parser)
if (cp_parser_extension_opt (parser, &saved_pedantic))
{
/* Parse the qualified declaration. */
- cp_parser_declaration (parser);
+ cp_parser_declaration (parser, prefix_attrs);
/* Restore the PEDANTIC flag. */
pedantic = saved_pedantic;
@@ -13521,11 +13581,52 @@ cp_parser_declaration (cp_parser* parser)
tree attributes = NULL_TREE;
+ /* Conditionally, allow attributes to precede a linkage specification. */
+ if (token1->keyword == RID_ATTRIBUTE)
+ {
+ cp_lexer_save_tokens (parser->lexer);
+ attributes = cp_parser_attributes_opt (parser);
+ cp_token *t1 = cp_lexer_peek_token (parser->lexer);
+ cp_token *t2 = (t1->type == CPP_EOF
+ ? t1 : cp_lexer_peek_nth_token (parser->lexer, 2));
+ if (t1->keyword == RID_EXTERN
+ && cp_parser_is_pure_string_literal (t2))
+ {
+ cp_lexer_commit_tokens (parser->lexer);
+ /* We might have already been here. */
+ if (!c_dialect_objc ())
+ {
+ location_t where = get_finish (t2->location);
+ warning_at (token1->location, OPT_Wattributes, "attributes are"
+ " not permitted in this position");
+ where = linemap_position_for_loc_and_offset (line_table,
+ where, 1);
+ inform (where, "attributes may be inserted here");
+ attributes = NULL_TREE;
+ }
+ token1 = t1;
+ token2 = t2;
+ }
+ else
+ {
+ cp_lexer_rollback_tokens (parser->lexer);
+ attributes = NULL_TREE;
+ }
+ }
+ /* If we already had some attributes, and we've added more, then prepend.
+ Otherwise attributes just contains any that we just read. */
+ if (prefix_attrs)
+ {
+ if (attributes)
+ TREE_CHAIN (prefix_attrs) = attributes;
+ attributes = prefix_attrs;
+ }
+
/* If the next token is `extern' and the following token is a string
literal, then we have a linkage specification. */
if (token1->keyword == RID_EXTERN
&& cp_parser_is_pure_string_literal (token2))
- cp_parser_linkage_specification (parser);
+ cp_parser_linkage_specification (parser, attributes);
/* If the next token is `template', then we have either a template
declaration, an explicit instantiation, or an explicit
specialization. */
@@ -13575,7 +13676,7 @@ cp_parser_declaration (cp_parser* parser)
cp_parser_namespace_definition (parser);
/* Objective-C++ declaration/definition. */
else if (c_dialect_objc () && OBJC_IS_AT_KEYWORD (token1->keyword))
- cp_parser_objc_declaration (parser, NULL_TREE);
+ cp_parser_objc_declaration (parser, attributes);
else if (c_dialect_objc ()
&& token1->keyword == RID_ATTRIBUTE
&& cp_parser_objc_valid_prefix_attributes (parser, &attributes))
@@ -13617,7 +13718,7 @@ cp_parser_toplevel_declaration (cp_parser* parser)
}
else
/* Parse the declaration itself. */
- cp_parser_declaration (parser);
+ cp_parser_declaration (parser, NULL_TREE);
}
/* Parse a block-declaration.
@@ -13687,6 +13788,8 @@ cp_parser_block_declaration (cp_parser *parser,
token2 = cp_lexer_peek_nth_token (parser->lexer, 2);
if (token2->keyword == RID_NAMESPACE)
cp_parser_using_directive (parser);
+ else if (token2->keyword == RID_ENUM)
+ cp_parser_using_enum (parser);
/* If the second token after 'using' is '=', then we have an
alias-declaration. */
else if (cxx_dialect >= cxx11
@@ -14726,7 +14829,7 @@ cp_parser_function_specifier_opt (cp_parser* parser,
extern string-literal declaration */
static void
-cp_parser_linkage_specification (cp_parser* parser)
+cp_parser_linkage_specification (cp_parser* parser, tree prefix_attr)
{
tree linkage;
@@ -14791,7 +14894,7 @@ cp_parser_linkage_specification (cp_parser* parser)
saved_in_unbraced_linkage_specification_p
= parser->in_unbraced_linkage_specification_p;
parser->in_unbraced_linkage_specification_p = true;
- cp_parser_declaration (parser);
+ cp_parser_declaration (parser, prefix_attr);
parser->in_unbraced_linkage_specification_p
= saved_in_unbraced_linkage_specification_p;
}
@@ -14886,7 +14989,8 @@ cp_parser_static_assert(cp_parser *parser, bool member_p)
/* Complete the static assertion, which may mean either processing
the static assert now or saving it for template instantiation. */
- finish_static_assert (condition, message, assert_loc, member_p);
+ finish_static_assert (condition, message, assert_loc, member_p,
+ /*show_expr_p=*/false);
}
/* Parse the expression in decltype ( expression ). */
@@ -19970,6 +20074,31 @@ cp_parser_qualified_namespace_specifier (cp_parser* parser)
return cp_parser_namespace_name (parser);
}
+/* Subroutine of cp_parser_using_declaration. */
+
+static tree
+finish_using_decl (tree qscope, tree identifier, bool typename_p = false)
+{
+ tree decl = NULL_TREE;
+ if (at_class_scope_p ())
+ {
+ /* Create the USING_DECL. */
+ decl = do_class_using_decl (qscope, identifier);
+
+ if (check_for_bare_parameter_packs (decl))
+ return error_mark_node;
+
+ if (decl && typename_p)
+ USING_DECL_TYPENAME_P (decl) = 1;
+
+ /* Add it to the list of members in this class. */
+ finish_member_declaration (decl);
+ }
+ else
+ finish_nonmember_using_decl (qscope, identifier);
+ return decl;
+}
+
/* Parse a using-declaration, or, if ACCESS_DECLARATION_P is true, an
access declaration.
@@ -19989,7 +20118,6 @@ cp_parser_using_declaration (cp_parser* parser,
cp_token *token;
bool typename_p = false;
bool global_scope_p;
- tree decl;
tree identifier;
tree qscope;
int oldcount = errorcount;
@@ -20048,9 +20176,6 @@ cp_parser_using_declaration (cp_parser* parser,
/*is_declaration=*/true);
if (!qscope)
qscope = global_namespace;
- else if (UNSCOPED_ENUM_P (qscope)
- && !TYPE_FUNCTION_SCOPE_P (qscope))
- qscope = CP_TYPE_CONTEXT (qscope);
cp_warn_deprecated_use_scopes (qscope);
@@ -20098,25 +20223,13 @@ cp_parser_using_declaration (cp_parser* parser,
"a template-id may not appear in a using-declaration");
else
{
- if (at_class_scope_p ())
- {
- /* Create the USING_DECL. */
- decl = do_class_using_decl (qscope, identifier);
-
- if (decl && typename_p)
- USING_DECL_TYPENAME_P (decl) = 1;
+ tree decl = finish_using_decl (qscope, identifier, typename_p);
- if (check_for_bare_parameter_packs (decl))
- {
- cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
- return false;
- }
- else
- /* Add it to the list of members in this class. */
- finish_member_declaration (decl);
+ if (decl == error_mark_node)
+ {
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+ return false;
}
- else
- finish_nonmember_using_decl (qscope, identifier);
}
if (!access_declaration_p
@@ -20142,6 +20255,76 @@ cp_parser_using_declaration (cp_parser* parser,
return true;
}
+/* C++20 using enum declaration.
+
+ using-enum-declaration :
+ using elaborated-enum-specifier ; */
+
+static void
+cp_parser_using_enum (cp_parser *parser)
+{
+ cp_parser_require_keyword (parser, RID_USING, RT_USING);
+
+ /* Using cp_parser_elaborated_type_specifier rejects typedef-names, which
+ breaks one of the motivating examples in using-enum-5.C.
+ cp_parser_simple_type_specifier seems to be closer to what we actually
+ want, though that hasn't been properly specified yet. */
+
+ /* Consume 'enum'. */
+ gcc_checking_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_ENUM));
+ cp_lexer_consume_token (parser->lexer);
+
+ cp_token *start = cp_lexer_peek_token (parser->lexer);
+
+ tree type = (cp_parser_simple_type_specifier
+ (parser, NULL, CP_PARSER_FLAGS_TYPENAME_OPTIONAL));
+
+ cp_token *end = cp_lexer_previous_token (parser->lexer);
+
+ if (type == error_mark_node
+ || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
+ {
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ return;
+ }
+ if (TREE_CODE (type) == TYPE_DECL)
+ type = TREE_TYPE (type);
+
+ /* The elaborated-enum-specifier shall not name a dependent type and the type
+ shall have a reachable enum-specifier. */
+ const char *msg = nullptr;
+ if (cxx_dialect < cxx20)
+ msg = _("%<using enum%> "
+ "only available with %<-std=c++20%> or %<-std=gnu++20%>");
+ else if (dependent_type_p (type))
+ msg = _("%<using enum%> of dependent type %qT");
+ else if (TREE_CODE (type) != ENUMERAL_TYPE)
+ msg = _("%<using enum%> of non-enumeration type %q#T");
+ else if (!COMPLETE_TYPE_P (type))
+ msg = _("%<using enum%> of incomplete type %qT");
+ else if (OPAQUE_ENUM_P (type))
+ msg = _("%<using enum%> of %qT before its enum-specifier");
+ if (msg)
+ {
+ location_t loc = make_location (start, start, end);
+ auto_diagnostic_group g;
+ error_at (loc, msg, type);
+ loc = location_of (type);
+ if (cxx_dialect < cxx20 || loc == input_location)
+ ;
+ else if (OPAQUE_ENUM_P (type))
+ inform (loc, "opaque-enum-declaration here");
+ else
+ inform (loc, "declared here");
+ }
+
+ /* A using-enum-declaration introduces the enumerator names of the named
+ enumeration as if by a using-declaration for each enumerator. */
+ if (TREE_CODE (type) == ENUMERAL_TYPE)
+ for (tree v = TYPE_VALUES (type); v; v = TREE_CHAIN (v))
+ finish_using_decl (type, DECL_NAME (TREE_VALUE (v)));
+}
+
/* Parse an alias-declaration.
alias-declaration:
@@ -20494,8 +20677,7 @@ cp_parser_asm_definition (cp_parser* parser)
&& cp_lexer_next_token_is_not (parser->lexer,
CPP_SCOPE)
&& cp_lexer_next_token_is_not (parser->lexer,
- CPP_CLOSE_PAREN)
- && !goto_p)
+ CPP_CLOSE_PAREN))
{
outputs = cp_parser_asm_operand_list (parser);
if (outputs == error_mark_node)
@@ -20663,13 +20845,12 @@ warn_about_ambiguous_parse (const cp_decl_specifier_seq *decl_specifiers,
if (same_type_p (type, void_type_node))
return;
}
+ else if (decl_specifiers->any_type_specifiers_p)
+ /* Code like long f(); will have null ->type. If we have any
+ type-specifiers, pretend we've seen int. */
+ type = integer_type_node;
else
- {
- /* Code like long f(); will have null ->type. If we have any
- type-specifiers, pretend we've seen int. */
- gcc_checking_assert (decl_specifiers->any_type_specifiers_p);
- type = integer_type_node;
- }
+ return;
auto_diagnostic_group d;
location_t loc = declarator->u.function.parens_loc;
@@ -25240,12 +25421,10 @@ cp_parser_member_declaration (cp_parser* parser)
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
{
if (cxx_dialect < cxx11)
- {
- /* Parse the using-declaration. */
- cp_parser_using_declaration (parser,
- /*access_declaration_p=*/false);
- return;
- }
+ /* Parse the using-declaration. */
+ cp_parser_using_declaration (parser, /*access_declaration_p=*/false);
+ else if (cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_ENUM))
+ cp_parser_using_enum (parser);
else
{
tree decl;
@@ -25266,8 +25445,8 @@ cp_parser_member_declaration (cp_parser* parser)
else
cp_parser_using_declaration (parser,
/*access_declaration_p=*/false);
- return;
}
+ return;
}
/* Check for @defs. */
@@ -29604,7 +29783,8 @@ cp_parser_template_introduction (cp_parser* parser, bool member_p)
{
if (!flag_concepts_ts)
pedwarn (introduction_loc, 0, "template-introductions"
- " are not part of C++20 concepts [-fconcepts-ts]");
+ " are not part of C++20 concepts; use %qs to enable",
+ "-fconcepts-ts");
cp_parser_template_declaration_after_parameters (parser, parms,
member_p);
@@ -30400,7 +30580,6 @@ static void
cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
{
unsigned char saved_local_variables_forbidden_p;
- tree parm, parmdecl;
/* While we're parsing the default args, we might (due to the
statement expression extension) encounter more classes. We want
@@ -30415,11 +30594,20 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
push_defarg_context (fn);
- for (parm = TYPE_ARG_TYPES (TREE_TYPE (fn)),
- parmdecl = DECL_ARGUMENTS (fn);
+ begin_scope (sk_function_parms, fn);
+
+ /* Gather the PARM_DECLs into a vec so we can keep track of them when
+ pushdecl clears DECL_CHAIN. */
+ releasing_vec parms;
+ for (tree parmdecl = DECL_ARGUMENTS (fn); parmdecl;
+ parmdecl = DECL_CHAIN (parmdecl))
+ vec_safe_push (parms, parmdecl);
+
+ tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ for (int i = 0;
parm && parm != void_list_node;
parm = TREE_CHAIN (parm),
- parmdecl = DECL_CHAIN (parmdecl))
+ ++i)
{
tree default_arg = TREE_PURPOSE (parm);
tree parsed_arg;
@@ -30427,6 +30615,9 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
tree copy;
unsigned ix;
+ tree parmdecl = parms[i];
+ pushdecl (parmdecl);
+
if (!default_arg)
continue;
@@ -30447,6 +30638,16 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
TREE_PURPOSE (copy) = parsed_arg;
}
+ pop_bindings_and_leave_scope ();
+
+ /* Restore DECL_CHAINs after clobbering by pushdecl. */
+ parm = NULL_TREE;
+ for (int i = parms->length () - 1; i >= 0; --i)
+ {
+ DECL_CHAIN (parms[i]) = parm;
+ parm = parms[i];
+ }
+
pop_defarg_context ();
/* Make sure no default arg is missing. */
@@ -33098,7 +33299,7 @@ cp_parser_objc_interstitial_code (cp_parser* parser)
if (token->keyword == RID_EXTERN
&& cp_parser_is_pure_string_literal
(cp_lexer_peek_nth_token (parser->lexer, 2)))
- cp_parser_linkage_specification (parser);
+ cp_parser_linkage_specification (parser, NULL_TREE);
/* Handle #pragma, if any. */
else if (token->type == CPP_PRAGMA)
cp_parser_pragma (parser, pragma_objc_icode, NULL);
@@ -33534,6 +33735,7 @@ cp_parser_objc_class_interface (cp_parser* parser, tree attributes)
bool is_class_extension;
cp_lexer_consume_token (parser->lexer); /* Eat '@interface'. */
+ location_t nam_loc = cp_lexer_peek_token (parser->lexer)->location;
name = cp_parser_identifier (parser);
if (name == error_mark_node)
{
@@ -33553,7 +33755,7 @@ cp_parser_objc_class_interface (cp_parser* parser, tree attributes)
objc_start_category_interface (name, categ, protos, attributes);
else
{
- objc_start_class_interface (name, super, protos, attributes);
+ objc_start_class_interface (name, nam_loc, super, protos, attributes);
/* Handle instance variable declarations, if any. */
cp_parser_objc_class_ivars (parser);
objc_continue_interface ();
@@ -33863,11 +34065,15 @@ static bool
cp_parser_objc_valid_prefix_attributes (cp_parser* parser, tree *attrib)
{
cp_lexer_save_tokens (parser->lexer);
- *attrib = cp_parser_attributes_opt (parser);
- gcc_assert (*attrib);
- if (OBJC_IS_AT_KEYWORD (cp_lexer_peek_token (parser->lexer)->keyword))
+ tree addon = cp_parser_attributes_opt (parser);
+ if (addon
+ && OBJC_IS_AT_KEYWORD (cp_lexer_peek_token (parser->lexer)->keyword))
{
cp_lexer_commit_tokens (parser->lexer);
+ if (*attrib)
+ TREE_CHAIN (*attrib) = addon;
+ else
+ *attrib = addon;
return true;
}
cp_lexer_rollback_tokens (parser->lexer);
@@ -34684,7 +34890,11 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
parser->colon_corrects_to_scope_p = false;
cp_lexer_consume_token (parser->lexer);
if (!cp_lexer_next_token_is (parser->lexer, CPP_COLON))
- low_bound = cp_parser_expression (parser);
+ {
+ low_bound = cp_parser_expression (parser);
+ /* Later handling is not prepared to see through these. */
+ gcc_checking_assert (!location_wrapper_p (low_bound));
+ }
if (!colon)
parser->colon_corrects_to_scope_p
= saved_colon_corrects_to_scope_p;
@@ -34704,7 +34914,11 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
cp_parser_commit_to_tentative_parse (parser);
if (!cp_lexer_next_token_is (parser->lexer,
CPP_CLOSE_SQUARE))
- length = cp_parser_expression (parser);
+ {
+ length = cp_parser_expression (parser);
+ /* Later handling is not prepared to see through these. */
+ gcc_checking_assert (!location_wrapper_p (length));
+ }
}
/* Look for the closing `]'. */
if (!cp_parser_require (parser, CPP_CLOSE_SQUARE,
@@ -37368,6 +37582,9 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
tree clauses = NULL;
bool first = true;
+ /* Don't create location wrapper nodes within OpenACC clauses. */
+ auto_suppress_location_wrappers sentinel;
+
while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
{
location_t here;
@@ -38620,6 +38837,8 @@ cp_parser_omp_depobj (cp_parser *parser, cp_token *pragma_tok)
cp_lexer_consume_token (parser->lexer);
if (!strcmp ("depend", p))
{
+ /* Don't create location wrapper nodes within the depend clause. */
+ auto_suppress_location_wrappers sentinel;
clause = cp_parser_omp_clause_depend (parser, NULL_TREE, c_loc);
if (clause)
clause = finish_omp_clauses (clause, C_ORT_OMP);
@@ -41291,6 +41510,10 @@ check_clauses:
static tree
cp_parser_oacc_cache (cp_parser *parser, cp_token *pragma_tok)
{
+ /* Don't create location wrapper nodes within 'OMP_CLAUSE__CACHE_'
+ clauses. */
+ auto_suppress_location_wrappers sentinel;
+
tree stmt, clauses;
clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE__CACHE_, NULL_TREE);
@@ -41891,7 +42114,7 @@ cp_parser_omp_declare_simd (cp_parser *parser, cp_token *pragma_tok,
switch (context)
{
case pragma_external:
- cp_parser_declaration (parser);
+ cp_parser_declaration (parser, NULL_TREE);
break;
case pragma_member:
cp_parser_member_declaration (parser);
@@ -43448,7 +43671,7 @@ cp_parser_oacc_routine (cp_parser *parser, cp_token *pragma_tok,
}
/* We only have to consider the pragma_external case here. */
- cp_parser_declaration (parser);
+ cp_parser_declaration (parser, NULL_TREE);
if (parser->oacc_routine
&& !parser->oacc_routine->fndecl_seen)
cp_ensure_no_oacc_routine (parser);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index a2655a0..3ca2813 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -103,13 +103,6 @@ local_specialization_stack::~local_specialization_stack ()
/* True if we've recursed into fn_type_unification too many times. */
static bool excessive_deduction_depth;
-struct GTY((for_user)) spec_entry
-{
- tree tmpl;
- tree args;
- tree spec;
-};
-
struct spec_hasher : ggc_ptr_hash<spec_entry>
{
static hashval_t hash (spec_entry *);
@@ -1709,9 +1702,11 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
return spec;
}
-/* Returns true iff two spec_entry nodes are equivalent. */
-
+/* Restricts tree and type comparisons. */
int comparing_specializations;
+int comparing_typenames;
+
+/* Returns true iff two spec_entry nodes are equivalent. */
bool
spec_hasher::equal (spec_entry *e1, spec_entry *e2)
@@ -1719,6 +1714,7 @@ spec_hasher::equal (spec_entry *e1, spec_entry *e2)
int equal;
++comparing_specializations;
+ ++comparing_typenames;
equal = (e1->tmpl == e2->tmpl
&& comp_template_args (e1->args, e2->args));
if (equal && flag_concepts
@@ -1734,6 +1730,7 @@ spec_hasher::equal (spec_entry *e1, spec_entry *e2)
equal = equivalent_constraints (c1, c2);
}
--comparing_specializations;
+ --comparing_typenames;
return equal;
}
@@ -4435,7 +4432,7 @@ build_template_parm_index (int index,
parameter. Returns the canonical type parameter, which may be TYPE
if no such parameter existed. */
-static tree
+tree
canonical_type_parameter (tree type)
{
int idx = TEMPLATE_TYPE_IDX (type);
@@ -13215,19 +13212,24 @@ tsubst_argument_pack (tree orig_arg, tree args, tsubst_flags_t complain,
tree in_decl)
{
/* Substitute into each of the arguments. */
- tree new_arg = TYPE_P (orig_arg)
- ? cxx_make_type (TREE_CODE (orig_arg))
- : make_node (TREE_CODE (orig_arg));
-
tree pack_args = tsubst_template_args (ARGUMENT_PACK_ARGS (orig_arg),
args, complain, in_decl);
- if (pack_args == error_mark_node)
- new_arg = error_mark_node;
- else
- SET_ARGUMENT_PACK_ARGS (new_arg, pack_args);
+ tree new_arg = error_mark_node;
+ if (pack_args != error_mark_node)
+ {
+ if (TYPE_P (orig_arg))
+ {
+ new_arg = cxx_make_type (TREE_CODE (orig_arg));
+ SET_TYPE_STRUCTURAL_EQUALITY (new_arg);
+ }
+ else
+ {
+ new_arg = make_node (TREE_CODE (orig_arg));
+ TREE_CONSTANT (new_arg) = TREE_CONSTANT (orig_arg);
+ }
- if (TREE_CODE (new_arg) == NONTYPE_ARGUMENT_PACK)
- TREE_CONSTANT (new_arg) = TREE_CONSTANT (orig_arg);
+ SET_ARGUMENT_PACK_ARGS (new_arg, pack_args);
+ }
return new_arg;
}
@@ -14932,9 +14934,6 @@ tsubst_arg_types (tree arg_types,
}
return error_mark_node;
}
- /* DR 657. */
- if (abstract_virtuals_error_sfinae (ACU_PARM, type, complain))
- return error_mark_node;
/* Do array-to-pointer, function-to-pointer conversion, and ignore
top-level qualifiers as required. */
@@ -15052,9 +15051,6 @@ tsubst_function_type (tree t,
}
return error_mark_node;
}
- /* And DR 657. */
- if (abstract_virtuals_error_sfinae (ACU_RETURN, return_type, complain))
- return error_mark_node;
if (!late_return_type_p)
{
@@ -15389,6 +15385,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
case ERROR_MARK:
case IDENTIFIER_NODE:
case VOID_TYPE:
+ case OPAQUE_TYPE:
case REAL_TYPE:
case COMPLEX_TYPE:
case VECTOR_TYPE:
@@ -15880,7 +15877,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
return error_mark_node;
}
- if (abstract_virtuals_error_sfinae (ACU_ARRAY, type, complain))
+ if (!verify_type_context (input_location, TCTX_ARRAY_ELEMENT, type,
+ !(complain & tf_error)))
return error_mark_node;
r = build_cplus_array_type (type, domain);
@@ -16214,7 +16212,7 @@ tsubst_qualified_id (tree qualified_id, tree args,
tree name;
bool is_template;
tree template_args;
- location_t loc = UNKNOWN_LOCATION;
+ location_t loc = EXPR_LOCATION (qualified_id);
gcc_assert (TREE_CODE (qualified_id) == SCOPE_REF);
@@ -16223,7 +16221,6 @@ tsubst_qualified_id (tree qualified_id, tree args,
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
{
is_template = true;
- loc = EXPR_LOCATION (name);
template_args = TREE_OPERAND (name, 1);
if (template_args)
template_args = tsubst_template_args (template_args, args,
@@ -16351,6 +16348,8 @@ tsubst_qualified_id (tree qualified_id, tree args,
if (REF_PARENTHESIZED_P (qualified_id))
expr = force_paren_expr (expr);
+ expr = maybe_wrap_with_location (expr, loc);
+
return expr;
}
@@ -16737,6 +16736,13 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
return build1 (code, type, op0);
}
+ case BIT_CAST_EXPR:
+ {
+ tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
+ return cp_build_bit_cast (EXPR_LOCATION (t), type, op0, complain);
+ }
+
case SIZEOF_EXPR:
if (PACK_EXPANSION_P (TREE_OPERAND (t, 0))
|| ARGUMENT_PACK_P (TREE_OPERAND (t, 0)))
@@ -16789,6 +16795,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
else
return cxx_sizeof_or_alignof_expr (input_location,
expanded, SIZEOF_EXPR,
+ false,
complain & tf_error);
}
else
@@ -17254,6 +17261,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
case OMP_CLAUSE_FROM:
case OMP_CLAUSE_TO:
case OMP_CLAUSE_MAP:
+ case OMP_CLAUSE__CACHE_:
case OMP_CLAUSE_NONTEMPORAL:
case OMP_CLAUSE_USE_DEVICE_PTR:
case OMP_CLAUSE_USE_DEVICE_ADDR:
@@ -18492,8 +18500,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
tree condition;
++c_inhibit_evaluation_warnings;
- condition =
- tsubst_expr (STATIC_ASSERT_CONDITION (t),
+ condition =
+ tsubst_expr (STATIC_ASSERT_CONDITION (t),
args,
complain, in_decl,
/*integral_constant_expression_p=*/true);
@@ -18502,7 +18510,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
finish_static_assert (condition,
STATIC_ASSERT_MESSAGE (t),
STATIC_ASSERT_SOURCE_LOCATION (t),
- /*member_p=*/false);
+ /*member_p=*/false, /*show_expr_p=*/true);
}
break;
@@ -18770,6 +18778,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
add_stmt (t);
break;
+ case OACC_CACHE:
case OACC_ENTER_DATA:
case OACC_EXIT_DATA:
case OACC_UPDATE:
@@ -19731,7 +19740,7 @@ tsubst_copy_and_build (tree t,
complain & tf_error);
else
r = cxx_sizeof_or_alignof_expr (input_location,
- op1, TREE_CODE (t),
+ op1, TREE_CODE (t), std_alignof,
complain & tf_error);
if (TREE_CODE (t) == SIZEOF_EXPR && r != error_mark_node)
{
@@ -19836,6 +19845,8 @@ tsubst_copy_and_build (tree t,
parameter packs are of length zero. */
if (init == NULL_TREE && TREE_OPERAND (t, 3) == NULL_TREE)
init_vec = NULL;
+ else if (init == error_mark_node)
+ RETURN (error_mark_node);
else
{
init_vec = make_tree_vector ();
@@ -23602,6 +23613,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
case BOOLEAN_TYPE:
case ENUMERAL_TYPE:
case VOID_TYPE:
+ case OPAQUE_TYPE:
case NULLPTR_TYPE:
if (TREE_CODE (arg) != TREE_CODE (parm))
return unify_type_mismatch (explain_p, parm, arg);
@@ -29257,10 +29269,13 @@ do_auto_deduction (tree type, tree init, tree auto_node,
return error_mark_node;
if (BRACE_ENCLOSED_INITIALIZER_P (init))
- /* We don't recurse here because we can't deduce from a nested
- initializer_list. */
- for (constructor_elt &elt : *CONSTRUCTOR_ELTS (init))
- elt.value = resolve_nondeduced_context (elt.value, complain);
+ {
+ /* We don't recurse here because we can't deduce from a nested
+ initializer_list. */
+ if (CONSTRUCTOR_ELTS (init))
+ for (constructor_elt &elt : *CONSTRUCTOR_ELTS (init))
+ elt.value = resolve_nondeduced_context (elt.value, complain);
+ }
else
init = resolve_nondeduced_context (init, complain);
@@ -29629,6 +29644,101 @@ declare_integer_pack (void)
CP_BUILT_IN_INTEGER_PACK);
}
+/* Walk the decl or type specialization table calling FN on each
+ entry. */
+
+void
+walk_specializations (bool decls_p,
+ void (*fn) (bool decls_p, spec_entry *entry, void *data),
+ void *data)
+{
+ spec_hash_table *table = decls_p ? decl_specializations
+ : type_specializations;
+ spec_hash_table::iterator end (table->end ());
+ for (spec_hash_table::iterator iter (table->begin ()); iter != end; ++iter)
+ fn (decls_p, *iter, data);
+}
+
+/* Lookup the specialization of TMPL, ARGS in the decl or type
+ specialization table. Return what's there, or if SPEC is non-null,
+ add it and return NULL. */
+
+tree
+match_mergeable_specialization (bool decl_p, tree tmpl, tree args, tree spec)
+{
+ spec_entry elt = {tmpl, args, spec};
+ hash_table<spec_hasher> *specializations
+ = decl_p ? decl_specializations : type_specializations;
+ hashval_t hash = spec_hasher::hash (&elt);
+ spec_entry **slot
+ = specializations->find_slot_with_hash (&elt, hash,
+ spec ? INSERT : NO_INSERT);
+ spec_entry *entry = slot ? *slot: NULL;
+
+ if (entry)
+ return entry->spec;
+
+ if (spec)
+ {
+ entry = ggc_alloc<spec_entry> ();
+ *entry = elt;
+ *slot = entry;
+ }
+
+ return NULL_TREE;
+}
+
+/* Return flags encoding whether SPEC is on the instantiation and/or
+ specialization lists of TMPL. */
+
+unsigned
+get_mergeable_specialization_flags (tree tmpl, tree decl)
+{
+ unsigned flags = 0;
+
+ for (tree inst = DECL_TEMPLATE_INSTANTIATIONS (tmpl);
+ inst; inst = TREE_CHAIN (inst))
+ if (TREE_VALUE (inst) == decl)
+ {
+ flags |= 1;
+ break;
+ }
+
+ if (CLASS_TYPE_P (TREE_TYPE (decl))
+ && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (decl))
+ && CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl)) == 2)
+ /* Only need to search if DECL is a partial specialization. */
+ for (tree part = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
+ part; part = TREE_CHAIN (part))
+ if (TREE_VALUE (part) == decl)
+ {
+ flags |= 2;
+ break;
+ }
+
+ return flags;
+}
+
+/* Add a new specialization of TMPL. FLAGS is as returned from
+ get_mergeable_specialization_flags. */
+
+void
+add_mergeable_specialization (tree tmpl, tree args, tree decl, unsigned flags)
+{
+ if (flags & 1)
+ DECL_TEMPLATE_INSTANTIATIONS (tmpl)
+ = tree_cons (args, decl, DECL_TEMPLATE_INSTANTIATIONS (tmpl));
+
+ if (flags & 2)
+ {
+ /* A partial specialization. */
+ DECL_TEMPLATE_SPECIALIZATIONS (tmpl)
+ = tree_cons (args, decl, DECL_TEMPLATE_SPECIALIZATIONS (tmpl));
+ TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (tmpl))
+ = TREE_TYPE (DECL_TEMPLATE_RESULT (decl));
+ }
+}
+
/* Set up the hash tables for template instantiations. */
void
diff --git a/gcc/cp/ptree.c b/gcc/cp/ptree.c
index a28b722..f8d2208 100644
--- a/gcc/cp/ptree.c
+++ b/gcc/cp/ptree.c
@@ -250,6 +250,44 @@ cxx_print_xnode (FILE *file, tree node, int indent)
print_node (file, "function", OVL_FUNCTION (node), indent + 4);
print_node (file, "next", OVL_CHAIN (node), indent + 4);
break;
+ case BINDING_VECTOR:
+ {
+ unsigned len = BINDING_VECTOR_NUM_CLUSTERS (node);
+ print_node (file, "name", BINDING_VECTOR_NAME (node), indent + 4);
+ fprintf (file, " clusters %u, alloc %u", len,
+ BINDING_VECTOR_ALLOC_CLUSTERS (node));
+ for (unsigned ix = 0; ix != len; ix++)
+ {
+ binding_cluster *cluster = &BINDING_VECTOR_CLUSTER (node, ix);
+ char pfx[24];
+ for (unsigned jx = 0; jx != BINDING_VECTOR_SLOTS_PER_CLUSTER; jx++)
+ if (cluster->indices[jx].span)
+ {
+ int len = sprintf (pfx, "module:%u",
+ cluster->indices[jx].base);
+ if (cluster->indices[jx].span > 1)
+ len += sprintf (&pfx[len], "(+%u)",
+ cluster->indices[jx].span);
+ len += sprintf (&pfx[len], " cluster:%u/%u", ix, jx);
+ binding_slot &slot = cluster->slots[jx];
+ if (slot.is_lazy ())
+ {
+ indent_to (file, indent + 4);
+ unsigned lazy = slot.get_lazy ();
+ fprintf (file, "%s snum:%u flags:%d",
+ pfx, lazy >> 2, lazy & 3);
+ }
+ else if (slot)
+ print_node (file, pfx, slot, indent + 4);
+ else
+ {
+ indent_to (file, indent + 4);
+ fprintf (file, "%s NULL", pfx);
+ }
+ }
+ }
+ }
+ break;
case TEMPLATE_PARM_INDEX:
print_node (file, "decl", TEMPLATE_PARM_DECL (node), indent+4);
indent_to (file, indent + 3);
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 887aae3..d628862 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -123,7 +123,6 @@ static GTY (()) vec<tinfo_s, va_gc> *tinfo_descs;
static tree ifnonnull (tree, tree, tsubst_flags_t);
static tree tinfo_name (tree, bool);
-static tree get_tinfo_decl_direct (tree type, tree name, int pseudo_ix);
static tree build_dynamic_cast_1 (location_t, tree, tree, tsubst_flags_t);
static tree throw_bad_cast (void);
static tree throw_bad_typeid (void);
@@ -431,7 +430,7 @@ get_tinfo_decl (tree type)
/* Get or create a tinfo VAR_DECL directly from the provided information.
The caller must have already checked it is valid to do so. */
-static tree
+tree
get_tinfo_decl_direct (tree type, tree name, int pseudo_ix)
{
/* For a class type, the variable is cached in the type node
@@ -1479,6 +1478,7 @@ get_tinfo_desc (unsigned ix)
finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE);
CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type;
DECL_CONTEXT (TYPE_NAME (pseudo_type)) = FROB_CONTEXT (global_namespace);
+ DECL_TINFO_P (TYPE_NAME (pseudo_type)) = true;
xref_basetypes (pseudo_type, /*bases=*/NULL_TREE);
res->type = cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
@@ -1491,6 +1491,36 @@ get_tinfo_desc (unsigned ix)
return res;
}
+/* Return an identifying index for the pseudo type_info TYPE.
+ We wrote the index at the end of the name, so just scan it from
+ there. This isn't critical, as it's only on the first use of this
+ type during module stream out. */
+
+unsigned
+get_pseudo_tinfo_index (tree type)
+{
+ tree name = DECL_NAME (TYPE_NAME (type));
+ unsigned ix = 0, scale = 1;
+ size_t len = IDENTIFIER_LENGTH (name);
+ const char *ptr = IDENTIFIER_POINTER (name) + len;
+
+ for (; *--ptr != '_'; scale *= 10)
+ {
+ len--;
+ gcc_checking_assert (len && ISDIGIT (*ptr));
+ ix += (*ptr - '0') * scale;
+ }
+
+ gcc_assert (len != IDENTIFIER_LENGTH (name));
+ return ix;
+}
+
+tree
+get_pseudo_tinfo_type (unsigned ix)
+{
+ return get_tinfo_desc (ix)->type;
+}
+
/* We lazily create the type info types. */
static void
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 33d715e..d33ef42 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -3006,12 +3006,7 @@ finish_compound_literal (tree type, tree compound_literal,
/* If we're in a template, return the original compound literal. */
if (orig_cl)
- {
- if (!VECTOR_TYPE_P (type))
- return get_target_expr_sfinae (orig_cl, complain);
- else
- return orig_cl;
- }
+ return orig_cl;
if (TREE_CODE (compound_literal) == CONSTRUCTOR)
{
@@ -4024,9 +4019,17 @@ finish_id_expression_1 (tree id_expression,
if (context != current_class_type)
{
tree path = currently_open_derived_class (context);
- perform_or_defer_access_check (TYPE_BINFO (path),
- decl, decl,
- tf_warning_or_error);
+ if (!path)
+ /* PATH can be null for using an enum of an unrelated
+ class; we checked its access in lookup_using_decl.
+
+ ??? Should this case make a clone instead, like
+ handle_using_decl? */
+ gcc_assert (TREE_CODE (decl) == CONST_DECL);
+ else
+ perform_or_defer_access_check (TYPE_BINFO (path),
+ decl, decl,
+ tf_warning_or_error);
}
}
@@ -9827,13 +9830,53 @@ init_cp_semantics (void)
{
}
+
+/* If we have a condition in conjunctive normal form (CNF), find the first
+ failing clause. In other words, given an expression like
+
+ true && true && false && true && false
+
+ return the first 'false'. EXPR is the expression. */
+
+static tree
+find_failing_clause_r (tree expr)
+{
+ if (TREE_CODE (expr) == TRUTH_ANDIF_EXPR)
+ {
+ /* First check the left side... */
+ tree e = find_failing_clause_r (TREE_OPERAND (expr, 0));
+ if (e == NULL_TREE)
+ /* ...if we didn't find a false clause, check the right side. */
+ e = find_failing_clause_r (TREE_OPERAND (expr, 1));
+ return e;
+ }
+ tree e = contextual_conv_bool (expr, tf_none);
+ e = fold_non_dependent_expr (e, tf_none, /*manifestly_const_eval=*/true);
+ if (integer_zerop (e))
+ /* This is the failing clause. */
+ return expr;
+ return NULL_TREE;
+}
+
+/* Wrapper for find_failing_clause_r. */
+
+static tree
+find_failing_clause (tree expr)
+{
+ if (TREE_CODE (expr) != TRUTH_ANDIF_EXPR)
+ return NULL_TREE;
+ return find_failing_clause_r (expr);
+}
+
/* Build a STATIC_ASSERT for a static assertion with the condition
CONDITION and the message text MESSAGE. LOCATION is the location
of the static assertion in the source code. When MEMBER_P, this
- static assertion is a member of a class. */
+ static assertion is a member of a class. If SHOW_EXPR_P is true,
+ print the condition (because it was instantiation-dependent). */
+
void
finish_static_assert (tree condition, tree message, location_t location,
- bool member_p)
+ bool member_p, bool show_expr_p)
{
tsubst_flags_t complain = tf_warning_or_error;
@@ -9871,8 +9914,7 @@ finish_static_assert (tree condition, tree message, location_t location,
tree orig_condition = condition;
/* Fold the expression and convert it to a boolean value. */
- condition = perform_implicit_conversion_flags (boolean_type_node, condition,
- complain, LOOKUP_NORMAL);
+ condition = contextual_conv_bool (condition, complain);
condition = fold_non_dependent_expr (condition, complain,
/*manifestly_const_eval=*/true);
@@ -9881,21 +9923,32 @@ finish_static_assert (tree condition, tree message, location_t location,
;
else
{
- location_t saved_loc = input_location;
+ iloc_sentinel ils (location);
- input_location = location;
- if (TREE_CODE (condition) == INTEGER_CST
- && integer_zerop (condition))
+ if (integer_zerop (condition))
{
int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT
(TREE_TYPE (TREE_TYPE (message))));
int len = TREE_STRING_LENGTH (message) / sz - 1;
+
+ /* See if we can find which clause was failing (for logical AND). */
+ tree bad = find_failing_clause (orig_condition);
+ /* If not, or its location is unusable, fall back to the previous
+ location. */
+ location_t cloc = location;
+ if (cp_expr_location (bad) != UNKNOWN_LOCATION)
+ cloc = cp_expr_location (bad);
+
/* Report the error. */
if (len == 0)
- error ("static assertion failed");
+ error_at (cloc, "static assertion failed");
else
- error ("static assertion failed: %s",
- TREE_STRING_POINTER (message));
+ error_at (cloc, "static assertion failed: %s",
+ TREE_STRING_POINTER (message));
+ if (show_expr_p)
+ inform (cloc, "%qE evaluates to false",
+ /* Nobody wants to see the artificial (bool) cast. */
+ (bad ? tree_strip_nop_conversions (bad) : orig_condition));
/* Actually explain the failure if this is a concept check or a
requires-expression. */
@@ -9909,7 +9962,6 @@ finish_static_assert (tree condition, tree message, location_t location,
if (require_rvalue_constant_expression (condition))
cxx_constant_value (condition);
}
- input_location = saved_loc;
}
}
@@ -10627,4 +10679,75 @@ cp_build_vec_convert (tree arg, location_t loc, tree type,
return build_call_expr_internal_loc (loc, IFN_VEC_CONVERT, type, 1, arg);
}
+/* Finish __builtin_bit_cast (type, arg). */
+
+tree
+cp_build_bit_cast (location_t loc, tree type, tree arg,
+ tsubst_flags_t complain)
+{
+ if (error_operand_p (type))
+ return error_mark_node;
+ if (!dependent_type_p (type))
+ {
+ if (!complete_type_or_maybe_complain (type, NULL_TREE, complain))
+ return error_mark_node;
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ /* std::bit_cast for destination ARRAY_TYPE is not possible,
+ as functions may not return an array, so don't bother trying
+ to support this (and then deal with VLAs etc.). */
+ error_at (loc, "%<__builtin_bit_cast%> destination type %qT "
+ "is an array type", type);
+ return error_mark_node;
+ }
+ if (!trivially_copyable_p (type))
+ {
+ error_at (loc, "%<__builtin_bit_cast%> destination type %qT "
+ "is not trivially copyable", type);
+ return error_mark_node;
+ }
+ }
+
+ if (error_operand_p (arg))
+ return error_mark_node;
+
+ if (!type_dependent_expression_p (arg))
+ {
+ if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
+ {
+ /* Don't perform array-to-pointer conversion. */
+ arg = mark_rvalue_use (arg, loc, true);
+ if (!complete_type_or_maybe_complain (TREE_TYPE (arg), arg, complain))
+ return error_mark_node;
+ }
+ else
+ arg = decay_conversion (arg, complain);
+
+ if (error_operand_p (arg))
+ return error_mark_node;
+
+ if (!trivially_copyable_p (TREE_TYPE (arg)))
+ {
+ error_at (cp_expr_loc_or_loc (arg, loc),
+ "%<__builtin_bit_cast%> source type %qT "
+ "is not trivially copyable", TREE_TYPE (arg));
+ return error_mark_node;
+ }
+ if (!dependent_type_p (type)
+ && !cp_tree_equal (TYPE_SIZE_UNIT (type),
+ TYPE_SIZE_UNIT (TREE_TYPE (arg))))
+ {
+ error_at (loc, "%<__builtin_bit_cast%> source size %qE "
+ "not equal to destination type size %qE",
+ TYPE_SIZE_UNIT (TREE_TYPE (arg)),
+ TYPE_SIZE_UNIT (type));
+ return error_mark_node;
+ }
+ }
+
+ tree ret = build_min (BIT_CAST_EXPR, type, arg);
+ SET_EXPR_LOCATION (ret, loc);
+ return ret;
+}
+
#include "gt-cp-semantics.h"
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 28e5910..8d7df60 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -998,7 +998,7 @@ build_min_array_type (tree elt_type, tree index_type)
build_cplus_array_type. */
static void
-set_array_type_canon (tree t, tree elt_type, tree index_type)
+set_array_type_canon (tree t, tree elt_type, tree index_type, bool dep)
{
/* Set the canonical type for this new node. */
if (TYPE_STRUCTURAL_EQUALITY_P (elt_type)
@@ -1009,30 +1009,33 @@ set_array_type_canon (tree t, tree elt_type, tree index_type)
TYPE_CANONICAL (t)
= build_cplus_array_type (TYPE_CANONICAL (elt_type),
index_type
- ? TYPE_CANONICAL (index_type) : index_type);
+ ? TYPE_CANONICAL (index_type) : index_type,
+ dep);
else
TYPE_CANONICAL (t) = t;
}
/* Like build_array_type, but handle special C++ semantics: an array of a
variant element type is a variant of the array of the main variant of
- the element type. */
+ the element type. IS_DEPENDENT is -ve if we should determine the
+ dependency. Otherwise its bool value indicates dependency. */
tree
-build_cplus_array_type (tree elt_type, tree index_type)
+build_cplus_array_type (tree elt_type, tree index_type, int dependent)
{
tree t;
if (elt_type == error_mark_node || index_type == error_mark_node)
return error_mark_node;
- bool dependent = (uses_template_parms (elt_type)
- || (index_type && uses_template_parms (index_type)));
+ if (dependent < 0)
+ dependent = (uses_template_parms (elt_type)
+ || (index_type && uses_template_parms (index_type)));
if (elt_type != TYPE_MAIN_VARIANT (elt_type))
/* Start with an array of the TYPE_MAIN_VARIANT. */
t = build_cplus_array_type (TYPE_MAIN_VARIANT (elt_type),
- index_type);
+ index_type, dependent);
else if (dependent)
{
/* Since type_hash_canon calls layout_type, we need to use our own
@@ -1062,13 +1065,20 @@ build_cplus_array_type (tree elt_type, tree index_type)
*e = t;
/* Set the canonical type for this new node. */
- set_array_type_canon (t, elt_type, index_type);
+ set_array_type_canon (t, elt_type, index_type, dependent);
+
+ /* Mark it as dependent now, this saves time later. */
+ TYPE_DEPENDENT_P_VALID (t) = true;
+ TYPE_DEPENDENT_P (t) = true;
}
}
else
{
bool typeless_storage = is_byte_access_type (elt_type);
t = build_array_type (elt_type, index_type, typeless_storage);
+
+ /* Mark as non-dependenty now, this will save time later. */
+ TYPE_DEPENDENT_P_VALID (t) = true;
}
/* Now check whether we already have this array variant. */
@@ -1083,7 +1093,10 @@ build_cplus_array_type (tree elt_type, tree index_type)
if (!t)
{
t = build_min_array_type (elt_type, index_type);
- set_array_type_canon (t, elt_type, index_type);
+ /* Mark dependency now, this saves time later. */
+ TYPE_DEPENDENT_P_VALID (t) = true;
+ TYPE_DEPENDENT_P (t) = dependent;
+ set_array_type_canon (t, elt_type, index_type, dependent);
if (!dependent)
{
layout_type (t);
@@ -1319,7 +1332,10 @@ cp_build_qualified_type_real (tree type,
if (!t)
{
- t = build_cplus_array_type (element_type, TYPE_DOMAIN (type));
+ gcc_checking_assert (TYPE_DEPENDENT_P_VALID (type)
+ || !dependent_type_p (type));
+ t = build_cplus_array_type (element_type, TYPE_DOMAIN (type),
+ TYPE_DEPENDENT_P (type));
/* Keep the typedef name. */
if (TYPE_NAME (t) != TYPE_NAME (type))
@@ -1555,7 +1571,9 @@ strip_typedefs (tree t, bool *remove_attributes, unsigned int flags)
case ARRAY_TYPE:
type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
t0 = strip_typedefs (TYPE_DOMAIN (t), remove_attributes, flags);
- result = build_cplus_array_type (type, t0);
+ gcc_checking_assert (TYPE_DEPENDENT_P_VALID (t)
+ || !dependent_type_p (t));
+ result = build_cplus_array_type (type, t0, TYPE_DEPENDENT_P (t));
break;
case FUNCTION_TYPE:
case METHOD_TYPE:
@@ -2218,6 +2236,23 @@ build_ref_qualified_type (tree type, cp_ref_qualifier rqual)
return build_cp_fntype_variant (type, rqual, raises, late);
}
+tree
+make_binding_vec (tree name, unsigned clusters MEM_STAT_DECL)
+{
+ /* Stored in an unsigned short, but we're limited to the number of
+ modules anyway. */
+ gcc_checking_assert (clusters <= (unsigned short)(~0));
+ size_t length = (offsetof (tree_binding_vec, vec)
+ + clusters * sizeof (binding_cluster));
+ tree vec = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT);
+ TREE_SET_CODE (vec, BINDING_VECTOR);
+ BINDING_VECTOR_NAME (vec) = name;
+ BINDING_VECTOR_ALLOC_CLUSTERS (vec) = clusters;
+ BINDING_VECTOR_NUM_CLUSTERS (vec) = 0;
+
+ return vec;
+}
+
/* Make a raw overload node containing FN. */
tree
@@ -2968,6 +3003,32 @@ array_type_nelts_total (tree type)
return sz;
}
+/* Return true if FNDECL is std::source_location::current () method. */
+
+bool
+source_location_current_p (tree fndecl)
+{
+ gcc_checking_assert (TREE_CODE (fndecl) == FUNCTION_DECL
+ && DECL_IMMEDIATE_FUNCTION_P (fndecl));
+ if (DECL_NAME (fndecl) == NULL_TREE
+ || TREE_CODE (TREE_TYPE (fndecl)) != FUNCTION_TYPE
+ || TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != RECORD_TYPE
+ || DECL_CONTEXT (fndecl) != TREE_TYPE (TREE_TYPE (fndecl))
+ || !id_equal (DECL_NAME (fndecl), "current"))
+ return false;
+
+ tree source_location = DECL_CONTEXT (fndecl);
+ if (TYPE_NAME (source_location) == NULL_TREE
+ || TREE_CODE (TYPE_NAME (source_location)) != TYPE_DECL
+ || TYPE_IDENTIFIER (source_location) == NULL_TREE
+ || !id_equal (TYPE_IDENTIFIER (source_location),
+ "source_location")
+ || !decl_in_std_namespace_p (TYPE_NAME (source_location)))
+ return false;
+
+ return true;
+}
+
struct bot_data
{
splay_tree target_remap;
@@ -3918,6 +3979,7 @@ cp_tree_equal (tree t1, tree t2)
CASE_CONVERT:
case NON_LVALUE_EXPR:
case VIEW_CONVERT_EXPR:
+ case BIT_CAST_EXPR:
if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
return false;
/* Now compare operands as usual. */
@@ -5163,6 +5225,7 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
case CONST_CAST_EXPR:
case DYNAMIC_CAST_EXPR:
case IMPLICIT_CONV_EXPR:
+ case BIT_CAST_EXPR:
if (TREE_TYPE (*tp))
WALK_SUBTREE (TREE_TYPE (*tp));
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 08e0c80..6294a78 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1256,16 +1256,15 @@ structural_comptypes (tree t1, tree t2, int strict)
gcc_assert (TYPE_P (t1) && TYPE_P (t2));
- if (!comparing_specializations)
- {
- /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
- current instantiation. */
- if (TREE_CODE (t1) == TYPENAME_TYPE)
- t1 = resolve_typename_type (t1, /*only_current_p=*/true);
+ /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
+ current instantiation, and we don't care about typename
+ structural equality. The comparing_typenames check is after the
+ code check, in order to early-out the common case. */
+ if (TREE_CODE (t1) == TYPENAME_TYPE && !comparing_typenames)
+ t1 = resolve_typename_type (t1, /*only_current_p=*/true);
- if (TREE_CODE (t2) == TYPENAME_TYPE)
- t2 = resolve_typename_type (t2, /*only_current_p=*/true);
- }
+ if (TREE_CODE (t2) == TYPENAME_TYPE && !comparing_typenames)
+ t2 = resolve_typename_type (t2, /*only_current_p=*/true);
if (TYPE_PTRMEMFUNC_P (t1))
t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
@@ -1314,6 +1313,7 @@ structural_comptypes (tree t1, tree t2, int strict)
/* All void and bool types are the same. */
break;
+ case OPAQUE_TYPE:
case INTEGER_TYPE:
case FIXED_POINT_TYPE:
case REAL_TYPE:
@@ -1832,10 +1832,12 @@ cxx_sizeof_expr (location_t loc, tree e, tsubst_flags_t complain)
/* Implement the __alignof keyword: Return the minimum required
alignment of E, measured in bytes. For VAR_DECL's and
FIELD_DECL's return DECL_ALIGN (which can be set from an
- "aligned" __attribute__ specification). */
+ "aligned" __attribute__ specification). STD_ALIGNOF acts
+ like in cxx_sizeof_or_alignof_type. */
static tree
-cxx_alignof_expr (location_t loc, tree e, tsubst_flags_t complain)
+cxx_alignof_expr (location_t loc, tree e, bool std_alignof,
+ tsubst_flags_t complain)
{
tree t;
@@ -1848,6 +1850,7 @@ cxx_alignof_expr (location_t loc, tree e, tsubst_flags_t complain)
TREE_SIDE_EFFECTS (e) = 0;
TREE_READONLY (e) = 1;
SET_EXPR_LOCATION (e, loc);
+ ALIGNOF_EXPR_STD_P (e) = std_alignof;
return e;
}
@@ -1900,23 +1903,25 @@ cxx_alignof_expr (location_t loc, tree e, tsubst_flags_t complain)
}
else
return cxx_sizeof_or_alignof_type (loc, TREE_TYPE (e),
- ALIGNOF_EXPR, false,
+ ALIGNOF_EXPR, std_alignof,
complain & tf_error);
return fold_convert_loc (loc, size_type_node, t);
}
/* Process a sizeof or alignof expression E with code OP where the operand
- is an expression. */
+ is an expression. STD_ALIGNOF acts like in cxx_sizeof_or_alignof_type. */
tree
cxx_sizeof_or_alignof_expr (location_t loc, tree e, enum tree_code op,
- bool complain)
+ bool std_alignof, bool complain)
{
+ gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR);
if (op == SIZEOF_EXPR)
return cxx_sizeof_expr (loc, e, complain? tf_warning_or_error : tf_none);
else
- return cxx_alignof_expr (loc, e, complain? tf_warning_or_error : tf_none);
+ return cxx_alignof_expr (loc, e, std_alignof,
+ complain? tf_warning_or_error : tf_none);
}
/* Build a representation of an expression 'alignas(E).' Return the
@@ -2895,7 +2900,8 @@ access_failure_info::add_fixit_hint (rich_location *richloc,
tree accessor_decl)
{
pretty_printer pp;
- pp_printf (&pp, "%s()", IDENTIFIER_POINTER (DECL_NAME (accessor_decl)));
+ pp_string (&pp, IDENTIFIER_POINTER (DECL_NAME (accessor_decl)));
+ pp_string (&pp, "()");
richloc->add_fixit_replace (pp_formatted_text (&pp));
}
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 445e2a2..3fd2b17 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -123,123 +123,6 @@ cxx_readonly_error (location_t loc, tree arg, enum lvalue_use errstring)
readonly_error (loc, arg, errstring);
}
-/* Structure that holds information about declarations whose type was
- incomplete and we could not check whether it was abstract or not. */
-
-struct GTY((chain_next ("%h.next"), for_user)) pending_abstract_type {
- /* Declaration which we are checking for abstractness. It is either
- a DECL node, or an IDENTIFIER_NODE if we do not have a full
- declaration available. */
- tree decl;
-
- /* Type which will be checked for abstractness. */
- tree type;
-
- /* Kind of use in an unnamed declarator. */
- enum abstract_class_use use;
-
- /* Position of the declaration. This is only needed for IDENTIFIER_NODEs,
- because DECLs already carry locus information. */
- location_t locus;
-
- /* Link to the next element in list. */
- struct pending_abstract_type* next;
-};
-
-struct abstract_type_hasher : ggc_ptr_hash<pending_abstract_type>
-{
- typedef tree compare_type;
- static hashval_t hash (pending_abstract_type *);
- static bool equal (pending_abstract_type *, tree);
-};
-
-/* Compute the hash value of the node VAL. This function is used by the
- hash table abstract_pending_vars. */
-
-hashval_t
-abstract_type_hasher::hash (pending_abstract_type *pat)
-{
- return (hashval_t) TYPE_UID (pat->type);
-}
-
-
-/* Compare node VAL1 with the type VAL2. This function is used by the
- hash table abstract_pending_vars. */
-
-bool
-abstract_type_hasher::equal (pending_abstract_type *pat1, tree type2)
-{
- return (pat1->type == type2);
-}
-
-/* Hash table that maintains pending_abstract_type nodes, for which we still
- need to check for type abstractness. The key of the table is the type
- of the declaration. */
-static GTY (()) hash_table<abstract_type_hasher> *abstract_pending_vars = NULL;
-
-static int abstract_virtuals_error_sfinae (tree, tree, abstract_class_use, tsubst_flags_t);
-
-/* This function is called after TYPE is completed, and will check if there
- are pending declarations for which we still need to verify the abstractness
- of TYPE, and emit a diagnostic (through abstract_virtuals_error) if TYPE
- turned out to be incomplete. */
-
-void
-complete_type_check_abstract (tree type)
-{
- struct pending_abstract_type *pat;
- location_t cur_loc = input_location;
-
- gcc_assert (COMPLETE_TYPE_P (type));
-
- if (!abstract_pending_vars)
- return;
-
- /* Retrieve the list of pending declarations for this type. */
- pending_abstract_type **slot
- = abstract_pending_vars->find_slot_with_hash (type, TYPE_UID (type),
- NO_INSERT);
- if (!slot)
- return;
- pat = *slot;
- gcc_assert (pat);
-
- /* If the type is not abstract, do not do anything. */
- if (CLASSTYPE_PURE_VIRTUALS (type))
- {
- struct pending_abstract_type *prev = 0, *next;
-
- /* Reverse the list to emit the errors in top-down order. */
- for (; pat; pat = next)
- {
- next = pat->next;
- pat->next = prev;
- prev = pat;
- }
- pat = prev;
-
- /* Go through the list, and call abstract_virtuals_error for each
- element: it will issue a diagnostic if the type is abstract. */
- while (pat)
- {
- gcc_assert (type == pat->type);
-
- /* Tweak input_location so that the diagnostic appears at the correct
- location. Notice that this is only needed if the decl is an
- IDENTIFIER_NODE. */
- input_location = pat->locus;
- abstract_virtuals_error_sfinae (pat->decl, pat->type, pat->use,
- tf_warning_or_error);
- pat = pat->next;
- }
- }
-
- abstract_pending_vars->clear_slot (slot);
-
- input_location = cur_loc;
-}
-
-
/* If TYPE has abstract virtual functions, issue an error about trying
to create an object of that type. DECL is the object declared, or
NULL_TREE if the declaration is unavailable, in which case USE specifies
@@ -252,6 +135,13 @@ abstract_virtuals_error_sfinae (tree decl, tree type, abstract_class_use use,
{
vec<tree, va_gc> *pure;
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ decl = NULL_TREE;
+ use = ACU_ARRAY;
+ type = strip_array_types (type);
+ }
+
/* This function applies only to classes. Any other entity can never
be abstract. */
if (!CLASS_TYPE_P (type))
@@ -266,38 +156,6 @@ abstract_virtuals_error_sfinae (tree decl, tree type, abstract_class_use use,
complete_type (type);
#endif
- /* If the type is incomplete, we register it within a hash table,
- so that we can check again once it is completed. This makes sense
- only for objects for which we have a declaration or at least a
- name. */
- if (!COMPLETE_TYPE_P (type) && (complain & tf_error))
- {
- struct pending_abstract_type *pat;
-
- gcc_assert (!decl || DECL_P (decl) || identifier_p (decl));
-
- if (!abstract_pending_vars)
- abstract_pending_vars
- = hash_table<abstract_type_hasher>::create_ggc (31);
-
- pending_abstract_type **slot
- = abstract_pending_vars->find_slot_with_hash (type, TYPE_UID (type),
- INSERT);
-
- pat = ggc_alloc<pending_abstract_type> ();
- pat->type = type;
- pat->decl = decl;
- pat->use = use;
- pat->locus = ((decl && DECL_P (decl))
- ? DECL_SOURCE_LOCATION (decl)
- : input_location);
-
- pat->next = *slot;
- *slot = pat;
-
- return 0;
- }
-
if (!TYPE_SIZE (type))
/* TYPE is being defined, and during that time
CLASSTYPE_PURE_VIRTUALS holds the inline friends. */
@@ -886,11 +744,13 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
{
bool const_init;
tree oldval = value;
- value = fold_non_dependent_expr (value, tf_warning_or_error, true, decl);
if (DECL_DECLARED_CONSTEXPR_P (decl)
|| (DECL_IN_AGGR_P (decl)
&& DECL_INITIALIZED_IN_CLASS_P (decl)))
{
+ value = fold_non_dependent_expr (value, tf_warning_or_error,
+ /*manifestly_const_eval=*/true,
+ decl);
/* Diagnose a non-constant initializer for constexpr variable or
non-inline in-class-initialized static data member. */
if (!require_constant_expression (value))
@@ -904,7 +764,8 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
value = cxx_constant_init (value, decl);
}
else
- value = maybe_constant_init (value, decl, true);
+ value = fold_non_dependent_init (value, tf_warning_or_error,
+ /*manifestly_const_eval=*/true, decl);
if (TREE_CODE (value) == CONSTRUCTOR && cp_has_mutable_p (type))
/* Poison this CONSTRUCTOR so it can't be copied to another
constexpr variable. */
@@ -948,6 +809,7 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
the bits that are constant, and then return an expression that
will perform the dynamic initialization. */
if (value != error_mark_node
+ && !processing_template_decl
&& (TREE_SIDE_EFFECTS (value)
|| vla_type_p (type)
|| ! reduced_constant_expression_p (value)))
@@ -1288,6 +1150,7 @@ digest_init_r (tree type, tree init, int nested, int flags,
|| VECTOR_TYPE_P (type)
|| code == RECORD_TYPE
|| code == UNION_TYPE
+ || code == OPAQUE_TYPE
|| code == COMPLEX_TYPE);
/* "If T is a class type and the initializer list has a single
@@ -2594,6 +2457,3 @@ require_complete_eh_spec_types (tree fntype, tree decl)
}
}
}
-
-
-#include "gt-cp-typeck2.h"
diff --git a/gcc/cppbuiltin.c b/gcc/cppbuiltin.c
index 61efe9b..fc61c78 100644
--- a/gcc/cppbuiltin.c
+++ b/gcc/cppbuiltin.c
@@ -93,6 +93,9 @@ define_builtin_macros_for_compilation_flags (cpp_reader *pfile)
if (flag_sanitize & SANITIZE_ADDRESS)
cpp_define (pfile, "__SANITIZE_ADDRESS__");
+ if (flag_sanitize & SANITIZE_HWADDRESS)
+ cpp_define (pfile, "__SANITIZE_HWADDRESS__");
+
if (flag_sanitize & SANITIZE_THREAD)
cpp_define (pfile, "__SANITIZE_THREAD__");
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index adab9a9..37cc3dc 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,84 @@
+2020-11-29 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * d-target.def (d_minfo_section): New hook.
+ (d_minfo_start_name): New hook.
+ (d_minfo_end_name): New hook.
+ * modules.cc: Include d-target.h.
+ (register_moduleinfo): Update to use new targetdm hooks.
+
+2020-11-29 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/87788
+ * dmd/MERGE: Merge upsream dmd 45fa6cfd2.
+
+2020-11-27 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * dmd/MERGE: Merge upstream dmd db0df3f7e.
+ * types.cc (TypeVisitor::visit (TypeFunction *)): Remove LINKpascal.
+
+2020-11-27 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * intrinsics.cc (maybe_expand_intrinsic): Handle new intrinsics.
+ * intrinsics.def (INTRINSIC_COS): Add float and double overloads.
+ (INTRINSIC_FABS): Likewise.
+ (INTRINSIC_LDEXP): Likewise.
+ (INTRINSIC_RINT): Likewise.
+ (INTRINSIC_RNDTOL): Likewise.
+ (INTRINSIC_SIN): Likewise.
+ (INTRINSIC_TOPREC): Adjust signature.
+
+2020-11-22 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/97889
+ * expr.cc (ExprVisitor::visit (CatAssignExp *)): Enforce LTR order of
+ evaluation on left and right hand side expressions.
+
+2020-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/97911
+ * Make-lang.in (d.serial): Change from goal to a variable.
+ (.PHONY): Drop d.serial and d.prev.
+ (d21$(exeext)): Depend on $(d.serial) rather than d.serial.
+
+2020-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ * Make-lang.in (d.serial): New goal.
+ (.PHONY): Add d.serial d.prev.
+ (d21$(exeext)): Depend on d.prev. Call LINK_PROGRESS.
+
+2020-11-18 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/97843
+ * d-codegen.cc (build_assign): Evaluate TARGET_EXPR before use in
+ the right hand side of an assignment.
+ * expr.cc (ExprVisitor::visit (CatAssignExp *)): Force a TARGET_EXPR
+ on the element to append if it is a CALL_EXPR.
+
+2020-11-18 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/97842
+ * dmd/MERGE: Merge upstream dmd b6a779e49
+
+2020-11-13 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * intrinsics.cc (expand_intrinsic_copysign): Explicitly determine
+ which built-in copysign function to call.
+
+2020-11-13 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/97644
+ * dmd/MERGE: Merge upstream dmd 95044d8e4.
+ * d-target.cc (TargetCPP::thunkMangle): New function.
+ * decl.cc (finish_thunk): Don't force expand thunks for external
+ functions.
+ (make_thunk): Emit thunks only if the function has a definition.
+ Generate correct mangling for thunks to C++ classes.
+
+2020-11-10 Strager Neds <strager.nds@gmail.com>
+
+ * decl.cc (finish_thunk): Use new overload of
+ set_decl_section_name
+
2020-10-27 Iain Buclaw <ibuclaw@gdcproject.org>
* dmd/MERGE: Merge upstream dmd bec5973b0.
diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in
index 18d99ab..8c0c753 100644
--- a/gcc/d/Make-lang.in
+++ b/gcc/d/Make-lang.in
@@ -27,6 +27,7 @@ D_LIBPHOBOS = -DLIBPHOBOS=\"gphobos\"
# The name for selecting d in LANGUAGES.
d: d21$(exeext)
+d.serial = d21$(exeext)
# Tell GNU make to ignore these if they exist.
.PHONY: d
@@ -162,9 +163,11 @@ D_ALL_OBJS = $(D_FRONTEND_OBJS) $(D_GENERATED_OBJS) $(D_OBJS) $(D_TARGET_OBJS)
d_OBJS = $(D_ALL_OBJS) d/d-spec.o
-d21$(exeext): $(D_ALL_OBJS) attribs.o $(BACKEND) $(LIBDEPS)
+d21$(exeext): $(D_ALL_OBJS) attribs.o $(BACKEND) $(LIBDEPS) $(d.prev)
+ @$(call LINK_PROGRESS,$(INDEX.d),start)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(D_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
+ @$(call LINK_PROGRESS,$(INDEX.d),end)
# Documentation.
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 1f2d65c..4c16f6a 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -1343,7 +1343,10 @@ build_assign (tree_code code, tree lhs, tree rhs)
since that would cause the LHS to be constructed twice.
So we force the TARGET_EXPR to be expanded without a target. */
if (code != INIT_EXPR)
- rhs = compound_expr (rhs, TARGET_EXPR_SLOT (rhs));
+ {
+ init = compound_expr (init, rhs);
+ rhs = TARGET_EXPR_SLOT (rhs);
+ }
else
{
d_mark_addressable (lhs);
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index 692fce6..cd136524 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -329,6 +329,15 @@ TargetCPP::typeInfoMangle (ClassDeclaration *cd)
return cppTypeInfoMangleItanium (cd);
}
+/* Get mangle name of a this-adjusting thunk to the function declaration FD
+ at call offset OFFSET for C++ linkage. */
+
+const char *
+TargetCPP::thunkMangle (FuncDeclaration *fd, int offset)
+{
+ return cppThunkMangleItanium (fd, offset);
+}
+
/* For a vendor-specific type, return a string containing the C++ mangling.
In all other cases, return NULL. */
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index 41b3172..728cba7 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -46,5 +46,30 @@ relating to the target operating system.",
void, (void),
hook_void_void)
+/* ModuleInfo section name and brackets. */
+DEFHOOKPOD
+(d_minfo_section,
+ "Contains the name of the section in which module info references should be\n\
+placed. This section is expected to be bracketed by two symbols to indicate\n\
+the start and end address of the section, so that the runtime library can\n\
+collect all modules for each loaded shared library and executable. The\n\
+default value of @code{NULL} disables the use of sections altogether.",
+ const char *, NULL)
+
+DEFHOOKPOD
+(d_minfo_start_name,
+ "If @code{TARGET_D_MINFO_SECTION} is defined, then this must also be defined\n\
+as the name of the symbol indicating the start address of the module info\n\
+section",
+ const char *, NULL)
+
+/* The name of the ModuleInfo section. */
+DEFHOOKPOD
+(d_minfo_end_name,
+ "If @code{TARGET_D_MINFO_SECTION} is defined, then this must also be defined\n\
+as the name of the symbol indicating the end address of the module info\n\
+section",
+ const char *, NULL)
+
/* Close the 'struct gcc_targetdm' definition. */
HOOK_VECTOR_END (C90_EMPTY_HACK)
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index 457894f..218f358 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -1663,7 +1663,7 @@ finish_thunk (tree thunk, tree function)
resolve_unique_section (thunk, 0, flag_function_sections);
/* Output the thunk into the same section as function. */
- set_decl_section_name (thunk, DECL_SECTION_NAME (fn));
+ set_decl_section_name (thunk, fn);
symtab_node::get (thunk)->implicit_section
= symtab_node::get (fn)->implicit_section;
}
@@ -1693,26 +1693,6 @@ finish_thunk (tree thunk, tree function)
if (DECL_ONE_ONLY (function))
thunk_node->add_to_same_comdat_group (funcn);
-
- /* Target assemble_mi_thunk doesn't work across section boundaries
- on many targets, instead force thunk to be expanded in gimple. */
- if (DECL_EXTERNAL (function))
- {
- /* cgraph::expand_thunk writes over current_function_decl, so if this
- could ever be in use by the codegen pass, we want to know about it. */
- gcc_assert (current_function_decl == NULL_TREE);
-
- if (!stdarg_p (TREE_TYPE (thunk)))
- {
- thunk_node->create_edge (funcn, NULL, thunk_node->count);
- expand_thunk (thunk_node, false, true);
- }
-
- /* Tell the back-end to not bother inlining the function, this is
- assumed not to work as it could be referencing symbols outside
- of the current compilation unit. */
- DECL_UNINLINABLE (function) = 1;
- }
}
/* Return a thunk to DECL. Thunks adjust the incoming `this' pointer by OFFSET.
@@ -1789,12 +1769,11 @@ make_thunk (FuncDeclaration *decl, int offset)
DECL_CONTEXT (thunk) = d_decl_context (decl);
- /* Thunks inherit the public access of the function they are targetting.
- When the function is outside the current compilation unit however, then the
- thunk must be kept private to not conflict. */
- TREE_PUBLIC (thunk) = TREE_PUBLIC (function) && !DECL_EXTERNAL (function);
-
- DECL_EXTERNAL (thunk) = 0;
+ /* Thunks inherit the public access of the function they are targeting.
+ Thunks are connected to the definitions of the functions, so thunks are
+ not produced for external functions. */
+ TREE_PUBLIC (thunk) = TREE_PUBLIC (function);
+ DECL_EXTERNAL (thunk) = DECL_EXTERNAL (function);
/* Thunks are always addressable. */
TREE_ADDRESSABLE (thunk) = 1;
@@ -1806,18 +1785,31 @@ make_thunk (FuncDeclaration *decl, int offset)
DECL_COMDAT (thunk) = DECL_COMDAT (function);
DECL_WEAK (thunk) = DECL_WEAK (function);
- tree target_name = DECL_ASSEMBLER_NAME (function);
- unsigned identlen = IDENTIFIER_LENGTH (target_name) + 14;
- const char *ident = XNEWVEC (const char, identlen);
- snprintf (CONST_CAST (char *, ident), identlen,
- "_DT%u%s", offset, IDENTIFIER_POINTER (target_name));
+ /* When the thunk is for an extern C++ function, let C++ do the thunk
+ generation and just reference the symbol as extern, instead of
+ forcing a D local thunk to be emitted. */
+ const char *ident;
+
+ if (decl->linkage == LINKcpp)
+ ident = target.cpp.thunkMangle (decl, offset);
+ else
+ {
+ tree target_name = DECL_ASSEMBLER_NAME (function);
+ unsigned identlen = IDENTIFIER_LENGTH (target_name) + 14;
+ ident = XNEWVEC (const char, identlen);
+
+ snprintf (CONST_CAST (char *, ident), identlen,
+ "_DTi%u%s", offset, IDENTIFIER_POINTER (target_name));
+ }
DECL_NAME (thunk) = get_identifier (ident);
SET_DECL_ASSEMBLER_NAME (thunk, DECL_NAME (thunk));
d_keep (thunk);
+ free (CONST_CAST (char *, ident));
- finish_thunk (thunk, function);
+ if (!DECL_EXTERNAL (function))
+ finish_thunk (thunk, function);
/* Add it to the list of thunks associated with the function. */
DECL_LANG_THUNKS (thunk) = NULL_TREE;
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 39e424f..4fa62a9 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-bec5973b0203c95adbda2a049ccdf3cd3a4378f6
+45fa6cfd20827bb4252a616dc789514a1e673687
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/cond.c b/gcc/d/dmd/cond.c
index beda133..9f76e83 100644
--- a/gcc/d/dmd/cond.c
+++ b/gcc/d/dmd/cond.c
@@ -705,6 +705,10 @@ int StaticIfCondition::include(Scope *sc)
sc = sc->push(sc->scopesym);
bool errors = false;
+
+ if (!exp)
+ goto Lerror;
+
bool result = evalStaticCondition(sc, exp, exp, errors);
sc->pop();
diff --git a/gcc/d/dmd/cppmangle.c b/gcc/d/dmd/cppmangle.c
index b361d37..3f571fc 100644
--- a/gcc/d/dmd/cppmangle.c
+++ b/gcc/d/dmd/cppmangle.c
@@ -582,13 +582,21 @@ class CppMangleVisitor : public Visitor
//printf("mangle_function(%s)\n", d->toChars());
/*
* <mangled-name> ::= _Z <encoding>
+ */
+ buf->writestring("_Z");
+ this->mangle_function_encoding(d);
+ }
+
+ void mangle_function_encoding(FuncDeclaration *d)
+ {
+ //printf("mangle_function_encoding(%s)\n", d->toChars());
+ /*
* <encoding> ::= <function name> <bare-function-type>
* ::= <data name>
* ::= <special-name>
*/
TypeFunction *tf = (TypeFunction *)d->type;
- buf->writestring("_Z");
if (getFuncTemplateDecl(d))
{
/* It's an instance of a function template
@@ -1132,3 +1140,13 @@ const char *cppTypeInfoMangleItanium(Dsymbol *s)
v.cpp_mangle_name(s, false);
return buf.extractChars();
}
+
+const char *cppThunkMangleItanium(FuncDeclaration *fd, int offset)
+{
+ //printf("cppThunkMangleItanium(%s)\n", fd.toChars());
+ OutBuffer buf;
+ buf.printf("_ZThn%u_", offset); // "Th" means thunk, "n%u" is the call offset
+ CppMangleVisitor v(&buf, fd->loc);
+ v.mangle_function_encoding(fd);
+ return buf.extractChars();
+}
diff --git a/gcc/d/dmd/dmangle.c b/gcc/d/dmd/dmangle.c
index ea63bf3..8f86926 100644
--- a/gcc/d/dmd/dmangle.c
+++ b/gcc/d/dmd/dmangle.c
@@ -223,7 +223,6 @@ public:
case LINKd: mc = 'F'; break;
case LINKc: mc = 'U'; break;
case LINKwindows: mc = 'W'; break;
- case LINKpascal: mc = 'V'; break;
case LINKcpp: mc = 'R'; break;
case LINKobjc: mc = 'Y'; break;
default:
@@ -415,7 +414,6 @@ public:
case LINKc:
case LINKwindows:
- case LINKpascal:
case LINKobjc:
buf->writestring(d->ident->toChars());
return;
diff --git a/gcc/d/dmd/expression.c b/gcc/d/dmd/expression.c
index 2ad75ed..09dd3af 100644
--- a/gcc/d/dmd/expression.c
+++ b/gcc/d/dmd/expression.c
@@ -4340,7 +4340,7 @@ Expression *ArrayLiteralExp::syntaxCopy()
arraySyntaxCopy(elements));
}
-Expression *ArrayLiteralExp::getElement(d_size_t i)
+Expression *ArrayLiteralExp::getElement(size_t i)
{
Expression *el = (*elements)[i];
if (!el)
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index fde029c..ccfaa65 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -523,7 +523,7 @@ public:
static ArrayLiteralExp *create(Loc loc, Expressions *elements);
Expression *syntaxCopy();
bool equals(RootObject *o);
- Expression *getElement(d_size_t i);
+ Expression *getElement(size_t i);
static Expressions* copyElements(Expression *e1, Expression *e2 = NULL);
bool isBool(bool result);
StringExp *toStringExp();
diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h
index 9d6e1ec..6aff9b4 100644
--- a/gcc/d/dmd/globals.h
+++ b/gcc/d/dmd/globals.h
@@ -310,7 +310,6 @@ enum LINK
LINKc,
LINKcpp,
LINKwindows,
- LINKpascal,
LINKobjc,
LINKsystem
};
diff --git a/gcc/d/dmd/hdrgen.c b/gcc/d/dmd/hdrgen.c
index 22ae9c8..fd4d162 100644
--- a/gcc/d/dmd/hdrgen.c
+++ b/gcc/d/dmd/hdrgen.c
@@ -1271,7 +1271,6 @@ public:
case LINKc: p = "C"; break;
case LINKcpp: p = "C++"; break;
case LINKwindows: p = "Windows"; break;
- case LINKpascal: p = "Pascal"; break;
case LINKobjc: p = "Objective-C"; break;
default:
assert(0);
@@ -3367,7 +3366,6 @@ const char *linkageToChars(LINK linkage)
case LINKc: return "C";
case LINKcpp: return "C++";
case LINKwindows: return "Windows";
- case LINKpascal: return "Pascal";
case LINKobjc: return "Objective-C";
case LINKsystem: return "System";
default: assert(0);
diff --git a/gcc/d/dmd/idgen.c b/gcc/d/dmd/idgen.c
index a6267c5..16f3b5f 100644
--- a/gcc/d/dmd/idgen.c
+++ b/gcc/d/dmd/idgen.c
@@ -145,7 +145,6 @@ Msgtable msgtable[] =
{ "C", NULL },
{ "D", NULL },
{ "Windows", NULL },
- { "Pascal", NULL },
{ "System", NULL },
{ "Objective", NULL },
diff --git a/gcc/d/dmd/json.c b/gcc/d/dmd/json.c
index 7da127e..802de81 100644
--- a/gcc/d/dmd/json.c
+++ b/gcc/d/dmd/json.c
@@ -323,9 +323,6 @@ public:
case LINKwindows:
property(name, "windows");
break;
- case LINKpascal:
- property(name, "pascal");
- break;
default:
assert(false);
}
diff --git a/gcc/d/dmd/mangle.h b/gcc/d/dmd/mangle.h
index 77801ab..c60f4a7 100644
--- a/gcc/d/dmd/mangle.h
+++ b/gcc/d/dmd/mangle.h
@@ -20,6 +20,7 @@ struct OutBuffer;
// In cppmangle.c
const char *toCppMangleItanium(Dsymbol *s);
const char *cppTypeInfoMangleItanium(Dsymbol *s);
+const char *cppThunkMangleItanium(FuncDeclaration *fd, int offset);
// In cppmanglewin.c
const char *toCppMangleMSVC(Dsymbol *s);
diff --git a/gcc/d/dmd/mtype.c b/gcc/d/dmd/mtype.c
index bc66be0..6f0195a 100644
--- a/gcc/d/dmd/mtype.c
+++ b/gcc/d/dmd/mtype.c
@@ -7418,6 +7418,12 @@ void TypeTypeof::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol
//printf("TypeTypeof::resolve(sc = %p, idents = '%s')\n", sc, toChars());
//static int nest; if (++nest == 50) *(char*)0=0;
+ if (sc == NULL)
+ {
+ *pt = Type::terror;
+ error(loc, "Invalid scope.");
+ return;
+ }
if (inuse)
{
inuse = 2;
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index 4e28dea..b0878c8 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -12,7 +12,6 @@
#include "root/root.h"
#include "root/stringtable.h"
-#include "root/dcompat.h" // for d_size_t
#include "arraytypes.h"
#include "ast_node.h"
@@ -635,7 +634,7 @@ public:
static Parameters *arraySyntaxCopy(Parameters *parameters);
static size_t dim(Parameters *parameters);
- static Parameter *getNth(Parameters *parameters, d_size_t nth, d_size_t *pn = NULL);
+ static Parameter *getNth(Parameters *parameters, size_t nth, size_t *pn = NULL);
const char *toChars();
bool isCovariant(bool returnByRef, const Parameter *p) const;
static bool isCovariantScope(bool returnByRef, StorageClass from, StorageClass to);
diff --git a/gcc/d/dmd/parse.c b/gcc/d/dmd/parse.c
index d1017ac..3e4dd06 100644
--- a/gcc/d/dmd/parse.c
+++ b/gcc/d/dmd/parse.c
@@ -1294,8 +1294,6 @@ LINK Parser::parseLinkage(Identifiers **pidents, CPPMANGLE *pcppmangle, bool *pc
nextToken();
if (id == Id::Windows)
link = LINKwindows;
- else if (id == Id::Pascal)
- link = LINKpascal;
else if (id == Id::D)
link = LINKd;
else if (id == Id::C)
@@ -1399,7 +1397,7 @@ LINK Parser::parseLinkage(Identifiers **pidents, CPPMANGLE *pcppmangle, bool *pc
else
{
LinvalidLinkage:
- error("valid linkage identifiers are D, C, C++, Objective-C, Pascal, Windows, System");
+ error("valid linkage identifiers are D, C, C++, Objective-C, Windows, System");
link = LINKd;
}
}
diff --git a/gcc/d/dmd/root/array.h b/gcc/d/dmd/root/array.h
index fb838e6..d4eccd8 100644
--- a/gcc/d/dmd/root/array.h
+++ b/gcc/d/dmd/root/array.h
@@ -16,7 +16,7 @@
template <typename TYPE>
struct Array
{
- d_size_t length;
+ size_t length;
private:
DArray<TYPE> data;
@@ -42,8 +42,8 @@ struct Array
char *toChars() const
{
const char **buf = (const char **)mem.xmalloc(length * sizeof(const char *));
- d_size_t len = 2;
- for (d_size_t u = 0; u < length; u++)
+ size_t len = 2;
+ for (size_t u = 0; u < length; u++)
{
buf[u] = ((RootObject *)data.ptr[u])->toChars();
len += strlen(buf[u]) + 1;
@@ -52,7 +52,7 @@ struct Array
str[0] = '[';
char *p = str + 1;
- for (d_size_t u = 0; u < length; u++)
+ for (size_t u = 0; u < length; u++)
{
if (u)
*p++ = ',';
@@ -77,7 +77,7 @@ struct Array
insert(length, a);
}
- void reserve(d_size_t nentries)
+ void reserve(size_t nentries)
{
//printf("Array::reserve: length = %d, data.length = %d, nentries = %d\n", (int)length, (int)data.length, (int)nentries);
if (data.length - length < nentries)
@@ -106,7 +106,7 @@ struct Array
{
/* Increase size by 1.5x to avoid excessive memory fragmentation
*/
- d_size_t increment = length / 2;
+ size_t increment = length / 2;
if (nentries > increment) // if 1.5 is not enough
increment = nentries;
data.length = length + increment;
@@ -115,18 +115,18 @@ struct Array
}
}
- void remove(d_size_t i)
+ void remove(size_t i)
{
if (length - i - 1)
memmove(data.ptr + i, data.ptr + i + 1, (length - i - 1) * sizeof(TYPE));
length--;
}
- void insert(d_size_t index, Array *a)
+ void insert(size_t index, Array *a)
{
if (a)
{
- d_size_t d = a->length;
+ size_t d = a->length;
reserve(d);
if (length != index)
memmove(data.ptr + index + d, data.ptr + index, (length - index) * sizeof(TYPE));
@@ -135,7 +135,7 @@ struct Array
}
}
- void insert(d_size_t index, TYPE ptr)
+ void insert(size_t index, TYPE ptr)
{
reserve(1);
memmove(data.ptr + index + 1, data.ptr + index, (length - index) * sizeof(TYPE));
@@ -143,7 +143,7 @@ struct Array
length++;
}
- void setDim(d_size_t newdim)
+ void setDim(size_t newdim)
{
if (length < newdim)
{
@@ -152,9 +152,9 @@ struct Array
length = newdim;
}
- d_size_t find(TYPE ptr) const
+ size_t find(TYPE ptr) const
{
- for (d_size_t i = 0; i < length; i++)
+ for (size_t i = 0; i < length; i++)
{
if (data.ptr[i] == ptr)
return i;
@@ -167,7 +167,7 @@ struct Array
return find(ptr) != SIZE_MAX;
}
- TYPE& operator[] (d_size_t index)
+ TYPE& operator[] (size_t index)
{
#ifdef DEBUG
assert(index < length);
diff --git a/gcc/d/dmd/root/bitarray.h b/gcc/d/dmd/root/bitarray.h
index fa01dd9..195e3be 100644
--- a/gcc/d/dmd/root/bitarray.h
+++ b/gcc/d/dmd/root/bitarray.h
@@ -24,8 +24,8 @@ struct BitArray
mem.xfree(ptr);
}
- d_size_t len;
- d_size_t *ptr;
+ size_t len;
+ size_t *ptr;
private:
BitArray(const BitArray&);
diff --git a/gcc/d/dmd/root/dcompat.h b/gcc/d/dmd/root/dcompat.h
index 72326d5..5aec84e 100644
--- a/gcc/d/dmd/root/dcompat.h
+++ b/gcc/d/dmd/root/dcompat.h
@@ -34,15 +34,3 @@ struct DString : public DArray<const char>
DString(size_t length, const char *ptr)
: DArray<const char>(length, ptr) { }
};
-
-/// Corresponding C++ type that maps to D size_t
-#if __APPLE__ && __i386__
-// size_t is 'unsigned long', which makes it mangle differently than D's 'uint'
-typedef unsigned d_size_t;
-#elif MARS && DMD_VERSION >= 2079 && DMD_VERSION <= 2081 && \
- __APPLE__ && __SIZEOF_SIZE_T__ == 8
-// DMD versions between 2.079 and 2.081 mapped D ulong to uint64_t on OS X.
-typedef uint64_t d_size_t;
-#else
-typedef size_t d_size_t;
-#endif
diff --git a/gcc/d/dmd/root/outbuffer.h b/gcc/d/dmd/root/outbuffer.h
index 49b1c3e5..2ff5ee9 100644
--- a/gcc/d/dmd/root/outbuffer.h
+++ b/gcc/d/dmd/root/outbuffer.h
@@ -39,13 +39,13 @@ public:
mem.xfree(data.ptr);
}
const DArray<unsigned char> slice() const { return data; }
- d_size_t length() const { return offset; }
+ size_t length() const { return offset; }
char *extractData();
void reserve(size_t nbytes);
void setsize(size_t size);
void reset();
- void write(const void *data, d_size_t nbytes);
+ void write(const void *data, size_t nbytes);
void writestring(const char *string);
void prependstring(const char *string);
void writenl(); // write newline
diff --git a/gcc/d/dmd/root/rmem.h b/gcc/d/dmd/root/rmem.h
index 7f5e980..fdb8676 100644
--- a/gcc/d/dmd/root/rmem.h
+++ b/gcc/d/dmd/root/rmem.h
@@ -8,18 +8,18 @@
#pragma once
-#include "dcompat.h" // for d_size_t
+#include "dsystem.h" // for size_t
struct Mem
{
Mem() { }
static char *xstrdup(const char *s);
- static void *xmalloc(d_size_t size);
- static void *xcalloc(d_size_t size, d_size_t n);
- static void *xrealloc(void *p, d_size_t size);
+ static void *xmalloc(size_t size);
+ static void *xcalloc(size_t size, size_t n);
+ static void *xrealloc(void *p, size_t size);
static void xfree(void *p);
- static void *xmallocdup(void *o, d_size_t size);
+ static void *xmallocdup(void *o, size_t size);
static void error();
};
diff --git a/gcc/d/dmd/root/stringtable.h b/gcc/d/dmd/root/stringtable.h
index 7df5c87..8cbdbd8 100644
--- a/gcc/d/dmd/root/stringtable.h
+++ b/gcc/d/dmd/root/stringtable.h
@@ -9,7 +9,6 @@
#pragma once
#include "root.h"
-#include "dcompat.h" // for d_size_t
struct StringEntry;
@@ -40,13 +39,13 @@ private:
size_t count;
public:
- void _init(d_size_t size = 0);
- void reset(d_size_t size = 0);
+ void _init(size_t size = 0);
+ void reset(size_t size = 0);
~StringTable();
- StringValue *lookup(const char *s, d_size_t len);
+ StringValue *lookup(const char *s, size_t len);
StringValue *insert(const char *s, size_t len, void *ptrvalue);
- StringValue *update(const char *s, d_size_t len);
+ StringValue *update(const char *s, size_t len);
int apply(int (*fp)(StringValue *));
private:
diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h
index c34826a..f2a55d6 100644
--- a/gcc/d/dmd/target.h
+++ b/gcc/d/dmd/target.h
@@ -19,6 +19,7 @@
class ClassDeclaration;
class Dsymbol;
class Expression;
+class FuncDeclaration;
class Parameter;
class Type;
class TypeTuple;
@@ -38,6 +39,7 @@ struct TargetCPP
const char *toMangle(Dsymbol *s);
const char *typeInfoMangle(ClassDeclaration *cd);
+ const char *thunkMangle(FuncDeclaration *fd, int offset);
const char *typeMangle(Type *t);
Type *parameterType(Parameter *p);
bool fundamentalType(const Type *t, bool& isFundamental);
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 79f212c..2a1818a 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -838,59 +838,81 @@ public:
Type *tb2 = e->e2->type->toBasetype ();
Type *etype = tb1->nextOf ()->toBasetype ();
+ /* Save the address of `e1', so it can be evaluated first.
+ As all D run-time library functions for concat assignments update `e1'
+ in-place and then return its value, the saved address can also be used as
+ the result of this expression as well. */
+ tree lhs = build_expr (e->e1);
+ tree lexpr = stabilize_expr (&lhs);
+ tree ptr = d_save_expr (build_address (lhs));
+ tree result = NULL_TREE;
+
if (tb1->ty == Tarray && tb2->ty == Tdchar
&& (etype->ty == Tchar || etype->ty == Twchar))
{
- /* Append a dchar to a char[] or wchar[] */
+ /* Append a dchar to a char[] or wchar[]:
+ The assignment is handled by the D run-time library, so only
+ need to call `_d_arrayappend[cw]d(&e1, e2)' */
libcall_fn libcall = (etype->ty == Tchar)
? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;
- this->result_ = build_libcall (libcall, e->type, 2,
- build_address (build_expr (e->e1)),
- build_expr (e->e2));
+ result = build_libcall (libcall, e->type, 2,
+ ptr, build_expr (e->e2));
}
else
{
gcc_assert (tb1->ty == Tarray || tb2->ty == Tsarray);
- tree tinfo = build_typeinfo (e->loc, e->type);
- tree ptr = build_address (build_expr (e->e1));
-
if ((tb2->ty == Tarray || tb2->ty == Tsarray)
&& same_type_p (etype, tb2->nextOf ()->toBasetype ()))
{
- /* Append an array. */
- this->result_ = build_libcall (LIBCALL_ARRAYAPPENDT, e->type, 3,
- tinfo, ptr, d_array_convert (e->e2));
-
+ /* Append an array to another array:
+ The assignment is handled by the D run-time library, so only
+ need to call `_d_arrayappendT(ti, &e1, e2)' */
+ result = build_libcall (LIBCALL_ARRAYAPPENDT, e->type, 3,
+ build_typeinfo (e->loc, e->type),
+ ptr, d_array_convert (e->e2));
}
else if (same_type_p (etype, tb2))
{
- /* Append an element. */
- tree result = build_libcall (LIBCALL_ARRAYAPPENDCTX, e->type, 3,
- tinfo, ptr, size_one_node);
- result = d_save_expr (result);
+ /* Append an element to an array:
+ The assignment is generated inline, so need to handle temporaries
+ here, and ensure that they are evaluated in the correct order.
+
+ The generated code should end up being equivalent to:
+ _d_arrayappendcTX(ti, &e1, 1)[e1.length - 1] = e2
+ */
+ tree callexp = build_libcall (LIBCALL_ARRAYAPPENDCTX, e->type, 3,
+ build_typeinfo (e->loc, e->type),
+ ptr, size_one_node);
+ callexp = d_save_expr (callexp);
/* Assign e2 to last element. */
- tree offexp = d_array_length (result);
+ tree offexp = d_array_length (callexp);
offexp = build2 (MINUS_EXPR, TREE_TYPE (offexp),
offexp, size_one_node);
- tree ptrexp = d_array_ptr (result);
+ tree ptrexp = d_array_ptr (callexp);
ptrexp = void_okay_p (ptrexp);
ptrexp = build_array_index (ptrexp, offexp);
/* Evaluate expression before appending. */
- tree t2 = build_expr (e->e2);
- tree expr = stabilize_expr (&t2);
+ tree rhs = build_expr (e->e2);
+ tree rexpr = stabilize_expr (&rhs);
- result = modify_expr (build_deref (ptrexp), t2);
+ if (TREE_CODE (rhs) == CALL_EXPR)
+ rhs = force_target_expr (rhs);
- this->result_ = compound_expr (expr, result);
+ result = modify_expr (build_deref (ptrexp), rhs);
+ result = compound_expr (rexpr, result);
}
else
gcc_unreachable ();
}
+
+ /* Construct in order: ptr = &e1, _d_arrayappend(ptr, e2), *ptr; */
+ result = compound_expr (compound_expr (lexpr, ptr), result);
+ this->result_ = compound_expr (result, build_deref (ptr));
}
/* Build an assignment expression. The right operand is implicitly
diff --git a/gcc/d/intrinsics.cc b/gcc/d/intrinsics.cc
index a629472..4196ed3 100644
--- a/gcc/d/intrinsics.cc
+++ b/gcc/d/intrinsics.cc
@@ -466,11 +466,14 @@ expand_intrinsic_copysign (tree callexp)
from = fold_convert (type, from);
/* Which variant of __builtin_copysign* should we call? */
- tree builtin = mathfn_built_in (type, BUILT_IN_COPYSIGN);
- gcc_assert (builtin != NULL_TREE);
+ built_in_function code = (type == float_type_node) ? BUILT_IN_COPYSIGNF
+ : (type == double_type_node) ? BUILT_IN_COPYSIGN
+ : (type == long_double_type_node) ? BUILT_IN_COPYSIGNL
+ : END_BUILTINS;
- return call_builtin_fn (callexp, DECL_FUNCTION_CODE (builtin), 2,
- to, from);
+ gcc_assert (code != END_BUILTINS);
+
+ return call_builtin_fn (callexp, code, 2, to, from);
}
/* Expand a front-end intrinsic call to pow(). This takes two arguments, the
@@ -811,10 +814,14 @@ maybe_expand_intrinsic (tree callexp)
case INTRINSIC_CEIL:
case INTRINSIC_CEILF:
case INTRINSIC_CEILL:
+ case INTRINSIC_COS:
+ case INTRINSIC_COSF:
case INTRINSIC_COSL:
case INTRINSIC_EXP:
case INTRINSIC_EXP2:
case INTRINSIC_EXPM1:
+ case INTRINSIC_FABS:
+ case INTRINSIC_FABSF:
case INTRINSIC_FABSL:
case INTRINSIC_FLOOR:
case INTRINSIC_FLOORF:
@@ -825,9 +832,15 @@ maybe_expand_intrinsic (tree callexp)
case INTRINSIC_LOG:
case INTRINSIC_LOG10:
case INTRINSIC_LOG2:
+ case INTRINSIC_RINT:
+ case INTRINSIC_RINTF:
case INTRINSIC_RINTL:
+ case INTRINSIC_RNDTOL:
+ case INTRINSIC_RNDTOLF:
case INTRINSIC_RNDTOLL:
case INTRINSIC_ROUND:
+ case INTRINSIC_SIN:
+ case INTRINSIC_SINF:
case INTRINSIC_SINL:
case INTRINSIC_SQRT:
case INTRINSIC_SQRTF:
@@ -841,6 +854,8 @@ maybe_expand_intrinsic (tree callexp)
case INTRINSIC_FMAX:
case INTRINSIC_FMIN:
+ case INTRINSIC_LDEXP:
+ case INTRINSIC_LDEXPF:
case INTRINSIC_LDEXPL:
code = intrinsic_decls[intrinsic].built_in;
gcc_assert (code != BUILT_IN_NONE);
diff --git a/gcc/d/intrinsics.def b/gcc/d/intrinsics.def
index 5b8cb71..c05a666 100644
--- a/gcc/d/intrinsics.def
+++ b/gcc/d/intrinsics.def
@@ -93,22 +93,34 @@ DEF_D_BUILTIN (NEGSL, NONE, "negs", "core.checkedint", "FNaNbNiNflKbZl")
/* core.math intrinsics. */
+DEF_D_BUILTIN (COSF, COSF, "cos", "core.math", "FNaNbNiNffZf")
+DEF_D_BUILTIN (COS, COS, "cos", "core.math", "FNaNbNiNfdZd")
DEF_D_BUILTIN (COSL, COSL, "cos", "core.math", "FNaNbNiNfeZe")
+DEF_D_BUILTIN (FABSF, FABSL, "fabs", "core.math", "FNaNbNiNffZf")
+DEF_D_BUILTIN (FABS, FABS, "fabs", "core.math", "FNaNbNiNfdZd")
DEF_D_BUILTIN (FABSL, FABSL, "fabs", "core.math", "FNaNbNiNfeZe")
+DEF_D_BUILTIN (LDEXPF, LDEXPF, "ldexp", "core.math", "FNaNbNiNffiZf")
+DEF_D_BUILTIN (LDEXP, LDEXP, "ldexp", "core.math", "FNaNbNiNfdiZd")
DEF_D_BUILTIN (LDEXPL, LDEXPL, "ldexp", "core.math", "FNaNbNiNfeiZe")
+DEF_D_BUILTIN (RINTF, RINTF, "rint", "core.math", "FNaNbNiNffZf")
+DEF_D_BUILTIN (RINT, RINT, "rint", "core.math", "FNaNbNiNfdZd")
DEF_D_BUILTIN (RINTL, RINTL, "rint", "core.math", "FNaNbNiNfeZe")
-/* Not sure if `llroundl' stands as a good replacement for the expected
+/* Not sure if `llround{f,l}' stands as a good replacement for the expected
behavior of `rndtol()'. */
+DEF_D_BUILTIN (RNDTOLF, LLROUNDF, "rndtol", "core.math", "FNaNbNiNffZl")
+DEF_D_BUILTIN (RNDTOL, LLROUND, "rndtol", "core.math", "FNaNbNiNfdZl")
DEF_D_BUILTIN (RNDTOLL, LLROUNDL, "rndtol", "core.math", "FNaNbNiNfeZl")
+DEF_D_BUILTIN (SINF, SINF, "sin", "core.math", "FNaNbNiNffZf")
+DEF_D_BUILTIN (SIN, SIN, "sin", "core.math", "FNaNbNiNfdZd")
DEF_D_BUILTIN (SINL, SINL, "sin", "core.math", "FNaNbNiNfeZe")
DEF_D_BUILTIN (SQRTF, SQRTF, "sqrt", "core.math", "FNaNbNiNffZf")
DEF_D_BUILTIN (SQRT, SQRT, "sqrt", "core.math", "FNaNbNiNfdZd")
DEF_D_BUILTIN (SQRTL, SQRTL, "sqrt", "core.math", "FNaNbNiNfeZe")
-DEF_D_BUILTIN (TOPRECF, NONE, "toPrec", "core.math", "FNaNbNffZI1T")
-DEF_D_BUILTIN (TOPREC, NONE, "toPrec", "core.math", "FNaNbNfdZI1T")
-DEF_D_BUILTIN (TOPRECL, NONE, "toPrec", "core.math", "FNaNbNfeZI1T")
+DEF_D_BUILTIN (TOPRECF, NONE, "toPrec", "core.math", "FfZI1T")
+DEF_D_BUILTIN (TOPREC, NONE, "toPrec", "core.math", "FdZI1T")
+DEF_D_BUILTIN (TOPRECL, NONE, "toPrec", "core.math", "FeZI1T")
/* std.math intrinsics. */
diff --git a/gcc/d/modules.cc b/gcc/d/modules.cc
index 4b48c19..742a24f 100644
--- a/gcc/d/modules.cc
+++ b/gcc/d/modules.cc
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see
#include "stringpool.h"
#include "d-tree.h"
+#include "d-target.h"
/* D generates module information to inform the runtime library which modules
@@ -405,6 +406,10 @@ build_dso_registry_var (const char * name, tree type)
static void
register_moduleinfo (Module *decl, tree minfo)
{
+ /* No defined minfo section for target. */
+ if (targetdm.d_minfo_section == NULL)
+ return;
+
if (!targetm_common.have_named_sections)
sorry ("%<-fmoduleinfo%> is not supported on this target");
@@ -420,7 +425,8 @@ register_moduleinfo (Module *decl, tree minfo)
DECL_EXTERNAL (mref) = 0;
DECL_PRESERVE_P (mref) = 1;
- set_decl_section_name (mref, "minfo");
+ set_decl_section_name (mref, targetdm.d_minfo_section);
+ symtab_node::get (mref)->implicit_section = true;
d_pushdecl (mref);
rest_of_decl_compilation (mref, 1, 0);
@@ -431,10 +437,12 @@ register_moduleinfo (Module *decl, tree minfo)
if (!first_module)
return;
- start_minfo_node = build_dso_registry_var ("__start_minfo", ptr_type_node);
+ start_minfo_node = build_dso_registry_var (targetdm.d_minfo_start_name,
+ ptr_type_node);
rest_of_decl_compilation (start_minfo_node, 1, 0);
- stop_minfo_node = build_dso_registry_var ("__stop_minfo", ptr_type_node);
+ stop_minfo_node = build_dso_registry_var (targetdm.d_minfo_end_name,
+ ptr_type_node);
rest_of_decl_compilation (stop_minfo_node, 1, 0);
/* Declare dso_slot and dso_initialized. */
diff --git a/gcc/d/types.cc b/gcc/d/types.cc
index 6df1e78..94aa1f6 100644
--- a/gcc/d/types.cc
+++ b/gcc/d/types.cc
@@ -791,7 +791,6 @@ public:
/* Handle any special support for calling conventions. */
switch (t->linkage)
{
- case LINKpascal:
case LINKwindows:
/* [attribute/linkage]
diff --git a/gcc/dbgcnt.def b/gcc/dbgcnt.def
index a5b6bb6..c0744b2 100644
--- a/gcc/dbgcnt.def
+++ b/gcc/dbgcnt.def
@@ -170,6 +170,7 @@ DEBUG_COUNTER (if_after_combine)
DEBUG_COUNTER (if_after_reload)
DEBUG_COUNTER (if_conversion)
DEBUG_COUNTER (if_conversion_tree)
+DEBUG_COUNTER (if_to_switch)
DEBUG_COUNTER (ipa_cp_bits)
DEBUG_COUNTER (ipa_cp_values)
DEBUG_COUNTER (ipa_cp_vr)
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index 5a20fde..eaee2f1 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -1963,6 +1963,7 @@ dbxout_type (tree type, int full)
case VOID_TYPE:
case NULLPTR_TYPE:
case LANG_TYPE:
+ case OPAQUE_TYPE:
/* For a void type, just define it as itself; i.e., "5=5".
This makes us consider it defined
without saying what it is. The debugger will make it
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 1b6c984..da20cdb 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -689,12 +689,13 @@ diagnostic_report_current_module (diagnostic_context *context, location_t where)
set_last_module (context, map);
if (! MAIN_FILE_P (map))
{
- bool first = true;
+ bool first = true, need_inc = true, was_module = MAP_MODULE_P (map);
expanded_location s = {};
do
{
where = linemap_included_from (map);
map = linemap_included_from_linemap (line_table, map);
+ bool is_module = MAP_MODULE_P (map);
s.file = LINEMAP_FILE (map);
s.line = SOURCE_LINE (map, where);
int col = -1;
@@ -706,14 +707,24 @@ diagnostic_report_current_module (diagnostic_context *context, location_t where)
const char *line_col = maybe_line_and_column (s.line, col);
static const char *const msgs[] =
{
- N_("In file included from"),
+ NULL,
N_(" from"),
+ N_("In file included from"), /* 2 */
+ N_(" included from"),
+ N_("In module"), /* 4 */
+ N_("of module"),
+ N_("In module imported at"), /* 6 */
+ N_("imported at"),
};
- unsigned index = !first;
+
+ unsigned index = (was_module ? 6 : is_module ? 4
+ : need_inc ? 2 : 0) + !first;
+
pp_verbatim (context->printer, "%s%s %r%s%s%R",
- first ? "" : ",\n", _(msgs[index]),
+ first ? "" : was_module ? ", " : ",\n",
+ _(msgs[index]),
"locus", s.file, line_col);
- first = false;
+ first = false, need_inc = was_module, was_module = is_module;
}
while (! MAIN_FILE_P (map));
pp_verbatim (context->printer, ":");
@@ -1161,7 +1172,7 @@ diagnostic_report_diagnostic (diagnostic_context *context,
return false;
}
- if (diagnostic->kind != DK_NOTE)
+ if (diagnostic->kind != DK_NOTE && diagnostic->kind != DK_ICE)
diagnostic_check_max_errors (context);
context->lock++;
diff --git a/gcc/digraph.cc b/gcc/digraph.cc
index 31b3e19..cd376ba 100644
--- a/gcc/digraph.cc
+++ b/gcc/digraph.cc
@@ -67,7 +67,7 @@ struct test_edge : public dedge<test_graph_traits>
void dump_dot (graphviz_out *gv, const dump_args_t &) const OVERRIDE
{
- gv->println ("%s -> %s;", m_src->m_name, m_dest->m_name);
+ gv->println ("%s %s %s%c", m_src->m_name, "->", m_dest->m_name, ';');
}
};
diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi
index 33f876a..5dcd672 100644
--- a/gcc/doc/cpp.texi
+++ b/gcc/doc/cpp.texi
@@ -2451,6 +2451,15 @@ features are supported by GCC.
@item __NO_MATH_ERRNO__
This macro is defined if @option{-fno-math-errno} is used, or enabled
by another option such as @option{-ffast-math} or by default.
+
+@item __GNUC_EXECUTION_CHARSET_NAME
+@itemx __GNUC_WIDE_EXECUTION_CHARSET_NAME
+These macros are defined to expand to a narrow string literal of
+the name of the narrow and wide compile-time execution character
+set used. It directly reflects the name passed to the options
+@option{-fexec-charset} and @option{-fwide-exec-charset}, or the defaults
+documented for those options (that is, it can expand to something like
+@code{"UTF-8"}). @xref{Invocation}.
@end table
@node System-specific Predefined Macros
@@ -3159,6 +3168,7 @@ directive}: @samp{#if}, @samp{#ifdef} or @samp{#ifndef}.
* Elif::
* @code{__has_attribute}::
* @code{__has_cpp_attribute}::
+* @code{__has_c_attribute}::
* @code{__has_builtin}::
* @code{__has_include}::
@end menu
@@ -3432,8 +3442,9 @@ condition succeeds after the original @samp{#if} and all previous
The special operator @code{__has_attribute (@var{operand})} may be used
in @samp{#if} and @samp{#elif} expressions to test whether the attribute
referenced by its @var{operand} is recognized by GCC. Using the operator
-in other contexts is not valid. In C code, @var{operand} must be
-a valid identifier. In C++ code, @var{operand} may be optionally
+in other contexts is not valid. In C code, if compiling for strict
+conformance to standards before C2x, @var{operand} must be
+a valid identifier. Otherwise, @var{operand} may be optionally
introduced by the @code{@var{attribute-scope}::} prefix.
The @var{attribute-scope} prefix identifies the ``namespace'' within
which the attribute is recognized. The scope of GCC attributes is
@@ -3479,6 +3490,21 @@ information including the dates of the introduction of current standard
attributes, see @w{@uref{https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations/,
SD-6: SG10 Feature Test Recommendations}}.
+@node @code{__has_c_attribute}
+@subsection @code{__has_c_attribute}
+@cindex @code{__has_c_attribute}
+
+The special operator @code{__has_c_attribute (@var{operand})} may be
+used in @samp{#if} and @samp{#elif} expressions in C code to test
+whether the attribute referenced by its @var{operand} is recognized by
+GCC in attributes using the @samp{[[]]} syntax. GNU attributes must
+be specified with the scope @samp{gnu} or @samp{__gnu__} with
+@code{__has_c_attribute}. When @var{operand} designates a supported
+standard attribute it evaluates to an integer constant of the form
+@code{YYYYMM} indicating the year and month when the attribute was
+first introduced into the C standard, or when the syntax of operands
+to the attribute was extended in the C standard.
+
@node @code{__has_builtin}
@subsection @code{__has_builtin}
@cindex @code{__has_builtin}
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 5f1e3bf..195bb21 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -6161,9 +6161,10 @@ and for static member methods.
On 32-bit and 64-bit x86 targets, you can use an ABI attribute
to indicate which calling convention should be used for a function. The
@code{ms_abi} attribute tells the compiler to use the Microsoft ABI,
-while the @code{sysv_abi} attribute tells the compiler to use the ABI
-used on GNU/Linux and other systems. The default is to use the Microsoft ABI
-when targeting Windows. On all other systems, the default is the x86/AMD ABI.
+while the @code{sysv_abi} attribute tells the compiler to use the System V
+ELF ABI, which is used on GNU/Linux and other systems. The default is to use
+the Microsoft ABI when targeting Windows. On all other systems, the default
+is the System V ELF ABI.
Note, the @code{ms_abi} attribute for Microsoft Windows 64-bit targets currently
requires the @option{-maccumulate-outgoing-args} option.
@@ -6750,6 +6751,11 @@ Enable/disable the generation of the KEYLOCKER instructions.
@cindex @code{target("widekl")} function attribute, x86
Enable/disable the generation of the WIDEKL instructions.
+@item avxvnni
+@itemx no-avxvnni
+@cindex @code{target("avxvnni")} function attribute, x86
+Enable/disable the generation of the AVXVNNI instructions.
+
@item cld
@itemx no-cld
@cindex @code{target("cld")} function attribute, x86
@@ -7420,9 +7426,49 @@ The @code{weak} attribute is described in
@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
+data in this way can reduce program startup times.
+
+This attribute is specific to ELF targets and relies on the linker
+script to place sections with the @code{.noinit} prefix in the right
+location.
+
+@item persistent
+@cindex @code{persistent} variable attribute
+Any data with the @code{persistent} attribute will not be initialized by
+the C runtime startup code, but will be initialized by the program
+loader. This enables the value of the variable to @samp{persist}
+between processor resets.
+
+This attribute is specific to ELF targets and relies on the linker
+script to place the sections with the @code{.persistent} prefix in the
+right location. Specifically, some type of non-volatile, writeable
+memory is required.
+
+@item objc_nullability (@var{nullability kind}) @r{(Objective-C and Objective-C++ only)}
+@cindex @code{objc_nullability} variable attribute
+This attribute applies to pointer variables only. It allows marking the
+pointer with one of four possible values describing the conditions under
+which the pointer might have a @code{nil} value. In most cases, the
+attribute is intended to be an internal representation for property and
+method nullability (specified by language keywords); it is not recommended
+to use it directly.
+
+When @var{nullability kind} is @code{"unspecified"} or @code{0}, nothing is
+known about the conditions in which the pointer might be @code{nil}. Making
+this state specific serves to avoid false positives in diagnostics.
+
+When @var{nullability kind} is @code{"nonnull"} or @code{1}, the pointer has
+no meaning if it is @code{nil} and thus the compiler is free to emit
+diagnostics if it can be determined that the value will be @code{nil}.
+
+When @var{nullability kind} is @code{"nullable"} or @code{2}, the pointer might
+be @code{nil} and carry meaning as such.
+
+When @var{nullability kind} is @code{"resettable"} or @code{3} (used only in
+the context of property attribute lists) this describes the case in which a
+property setter may take the value @code{nil} (which perhaps causes the
+property to be reset in some manner to a default) but for which the property
+getter will never validly return @code{nil}.
@end table
@@ -7817,23 +7863,6 @@ The @code{shared} attribute is only available on Microsoft Windows@.
@subsection MSP430 Variable Attributes
@table @code
-@item noinit
-@cindex @code{noinit} variable attribute, MSP430
-Any data with the @code{noinit} attribute will not be initialised by
-the C runtime startup code, or the program loader. Not initialising
-data in this way can reduce program startup times.
-
-@item persistent
-@cindex @code{persistent} variable attribute, MSP430
-Any variable with the @code{persistent} attribute will not be
-initialised by the C runtime startup code. Instead its value will be
-set once, when the application is loaded, and then never initialised
-again, even if the processor is reset or the program restarts.
-Persistent data is intended to be placed into FLASH RAM, where its
-value will be retained across resets. The linker script being used to
-create the application should ensure that persistent data is correctly
-placed.
-
@item upper
@itemx either
@cindex @code{upper} variable attribute, MSP430
@@ -8513,6 +8542,12 @@ and caught in another, the class must have default visibility.
Otherwise the two shared objects are unable to use the same
typeinfo node and exception handling will break.
+@item objc_root_class @r{(Objective-C and Objective-C++ only)}
+@cindex @code{objc_root_class} type attribute
+This attribute marks a class as being a root class, and thus allows
+the compiler to elide any warnings about a missing superclass and to
+make additional checks for mandatory methods as needed.
+
@end table
To specify multiple attributes, separate them by commas within the
@@ -9529,7 +9564,7 @@ asm @var{asm-qualifiers} ( @var{AssemblerTemplate}
@r{[} : @var{Clobbers} @r{]} @r{]})
asm @var{asm-qualifiers} ( @var{AssemblerTemplate}
- :
+ : @var{OutputOperands}
: @var{InputOperands}
: @var{Clobbers}
: @var{GotoLabels})
@@ -9636,7 +9671,7 @@ there is no need for the output variables. Also, the optimizers may move
code out of loops if they believe that the code will always return the same
result (i.e.@: none of its input values change between calls). Using the
@code{volatile} qualifier disables these optimizations. @code{asm} statements
-that have no output operands, including @code{asm goto} statements,
+that have no output operands and @code{asm goto} statements,
are implicitly volatile.
This i386 code demonstrates a case that does not use (or require) the
@@ -10495,9 +10530,6 @@ case, consider using the @code{__builtin_unreachable} intrinsic after the
using the @code{hot} and @code{cold} label attributes (@pxref{Label
Attributes}).
-An @code{asm goto} statement cannot have outputs.
-This is due to an internal restriction of
-the compiler: control transfer instructions cannot have outputs.
If the assembler code does modify anything, use the @code{"memory"} clobber
to force the
optimizers to flush all register values to memory and reload them if
@@ -10506,6 +10538,13 @@ necessary after the @code{asm} statement.
Also note that an @code{asm goto} statement is always implicitly
considered volatile.
+Be careful when you set output operands inside @code{asm goto} only on
+some possible control flow paths. If you don't set up the output on
+given path and never use it on this path, it is okay. Otherwise, you
+should use @samp{+} constraint modifier meaning that the operand is
+input and output one. With this modifier you will have the correct
+values on all possible paths from the @code{asm goto}.
+
To reference a label in the assembler template,
prefix it with @samp{%l} (lowercase @samp{L}) followed
by its (zero-based) position in @var{GotoLabels} plus the number of input
@@ -10551,6 +10590,41 @@ error:
@}
@end example
+The following example shows an @code{asm goto} that uses an output.
+
+@example
+int foo(int count)
+@{
+ asm goto ("dec %0; jb %l[stop]"
+ : "+r" (count)
+ :
+ :
+ : stop);
+ return count;
+stop:
+ return 0;
+@}
+@end example
+
+The following artificial example shows an @code{asm goto} that sets
+up an output only on one path inside the @code{asm goto}. Usage of
+constraint modifier @code{=} instead of @code{+} would be wrong as
+@code{factor} is used on all paths from the @code{asm goto}.
+
+@example
+int foo(int inp)
+@{
+ int factor = 0;
+ asm goto ("cmp %1, 10; jb %l[lab]; mov 2, %0"
+ : "+r" (factor)
+ : "r" (inp)
+ :
+ : lab);
+lab:
+ return inp * factor; /* return 2 * inp or 0 if inp < 10 */
+@}
+@end example
+
@anchor{x86Operandmodifiers}
@subsubsection x86 Operand Modifiers
@@ -13487,6 +13561,34 @@ initializers of variables usable in constant expressions. For more details
refer to the latest revision of the C++ standard.
@end deftypefn
+@deftypefn {Built-in Function} void __builtin_clear_padding (@var{ptr})
+The built-in function @code{__builtin_clear_padding} function clears
+padding bits inside of the object representation of object pointed by
+@var{ptr}, which has to be a pointer. The value representation of the
+object is not affected. The type of the object is assumed to be the type
+the pointer points to. Inside of a union, the only cleared bits are
+bits that are padding bits for all the union members.
+
+This built-in-function is useful if the padding bits of an object might
+have intederminate values and the object representation needs to be
+bitwise compared to some other object, for example for atomic operations.
+@end deftypefn
+
+@deftypefn {Built-in Function} @var{type} __builtin_bit_cast (@var{type}, @var{arg})
+The @code{__builtin_bit_cast} function is available only
+in C++. The built-in is intended to be used by implementations of
+the @code{std::bit_cast} C++ template function. Programs should make
+use of the latter function rather than invoking the built-in directly.
+
+This built-in function allows reinterpreting the bits of the @var{arg}
+argument as if it had type @var{type}. @var{type} and the type of the
+@var{arg} argument need to be trivially copyable types with the same size.
+When manifestly constant-evaluated, it performs extra diagnostics required
+for @code{std::bit_cast} and returns a constant expression if @var{arg}
+is a constant expression. For more details
+refer to the latest revision of the C++ standard.
+@end deftypefn
+
@deftypefn {Built-in Function} long __builtin_expect (long @var{exp}, long @var{c})
@opindex fprofile-arcs
You may use @code{__builtin_expect} to provide the compiler with
@@ -14077,6 +14179,7 @@ instructions, but allow the compiler to schedule those calls.
* PowerPC Hardware Transactional Memory Built-in Functions::
* PowerPC Atomic Memory Operation Functions::
* PowerPC Matrix-Multiply Assist Built-in Functions::
+* PRU Built-in Functions::
* RISC-V Built-in Functions::
* RX Built-in Functions::
* S/390 System z Built-in Functions::
@@ -21857,6 +21960,33 @@ vec_t __builtin_vsx_xvcvspbf16 (vec_t);
vec_t __builtin_vsx_xvcvbf16spn (vec_t);
@end smallexample
+@node PRU Built-in Functions
+@subsection PRU Built-in Functions
+
+GCC provides a couple of special builtin functions to aid in utilizing
+special PRU instructions.
+
+The built-in functions supported are:
+
+@table @code
+@item __delay_cycles (long long @var{cycles})
+This inserts an instruction sequence that takes exactly @var{cycles}
+cycles (between 0 and 0xffffffff) to complete. The inserted sequence
+may use jumps, loops, or no-ops, and does not interfere with any other
+instructions. Note that @var{cycles} must be a compile-time constant
+integer - that is, you must pass a number, not a variable that may be
+optimized to a constant later. The number of cycles delayed by this
+builtin is exact.
+
+@item __halt (void)
+This inserts a HALT instruction to stop processor execution.
+
+@item unsigned int __lmbd (unsigned int @var{wordval}, unsigned int @var{bitval})
+This inserts LMBD instruction to calculate the left-most bit with value
+@var{bitval} in value @var{wordval}. Only the least significant bit
+of @var{bitval} is taken into account.
+@end table
+
@node RISC-V Built-in Functions
@subsection RISC-V Built-in Functions
diff --git a/gcc/doc/generic.texi b/gcc/doc/generic.texi
index 7373266..9791f8b 100644
--- a/gcc/doc/generic.texi
+++ b/gcc/doc/generic.texi
@@ -302,6 +302,7 @@ The elements are indexed from zero.
@tindex ARRAY_TYPE
@tindex RECORD_TYPE
@tindex UNION_TYPE
+@tindex OPAQUE_TYPE
@tindex UNKNOWN_TYPE
@tindex OFFSET_TYPE
@findex TYPE_UNQUALIFIED
@@ -487,6 +488,13 @@ assigned to that constant. These constants will appear in the order in
which they were declared. The @code{TREE_TYPE} of each of these
constants will be the type of enumeration type itself.
+@item OPAQUE_TYPE
+Used for things that have a @code{MODE_OPAQUE} mode class in the
+backend. Opaque types have a size and precision, and can be held in
+memory or registers. They are used when we do not want the compiler to
+make assumptions about the availability of other operations as would
+happen with integer types.
+
@item BOOLEAN_TYPE
Used to represent the @code{bool} type.
@@ -1790,6 +1798,10 @@ a value from @code{enum annot_expr_kind}, the third is an @code{INTEGER_CST}.
@tindex VEC_RSHIFT_EXPR
@tindex VEC_WIDEN_MULT_HI_EXPR
@tindex VEC_WIDEN_MULT_LO_EXPR
+@tindex VEC_WIDEN_PLUS_HI_EXPR
+@tindex VEC_WIDEN_PLUS_LO_EXPR
+@tindex VEC_WIDEN_MINUS_HI_EXPR
+@tindex VEC_WIDEN_MINUS_LO_EXPR
@tindex VEC_UNPACK_HI_EXPR
@tindex VEC_UNPACK_LO_EXPR
@tindex VEC_UNPACK_FLOAT_HI_EXPR
@@ -1836,6 +1848,33 @@ vector of @code{N/2} products. In the case of @code{VEC_WIDEN_MULT_LO_EXPR} the
low @code{N/2} elements of the two vector are multiplied to produce the
vector of @code{N/2} products.
+@item VEC_WIDEN_PLUS_HI_EXPR
+@itemx VEC_WIDEN_PLUS_LO_EXPR
+These nodes represent widening vector addition of the high and low parts of
+the two input vectors, respectively. Their operands are vectors that contain
+the same number of elements (@code{N}) of the same integral type. The result
+is a vector that contains half as many elements, of an integral type whose size
+is twice as wide. In the case of @code{VEC_WIDEN_PLUS_HI_EXPR} the high
+@code{N/2} elements of the two vectors are added to produce the vector of
+@code{N/2} products. In the case of @code{VEC_WIDEN_PLUS_LO_EXPR} the low
+@code{N/2} elements of the two vectors are added to produce the vector of
+@code{N/2} products.
+
+@item VEC_WIDEN_MINUS_HI_EXPR
+@itemx VEC_WIDEN_MINUS_LO_EXPR
+These nodes represent widening vector subtraction of the high and low parts of
+the two input vectors, respectively. Their operands are vectors that contain
+the same number of elements (@code{N}) of the same integral type. The high/low
+elements of the second vector are subtracted from the high/low elements of the
+first. The result is a vector that contains half as many elements, of an
+integral type whose size is twice as wide. In the case of
+@code{VEC_WIDEN_MINUS_HI_EXPR} the high @code{N/2} elements of the second
+vector are subtracted from the high @code{N/2} of the first to produce the
+vector of @code{N/2} products. In the case of
+@code{VEC_WIDEN_MINUS_LO_EXPR} the low @code{N/2} elements of the second
+vector are subtracted from the low @code{N/2} of the first to produce the
+vector of @code{N/2} products.
+
@item VEC_UNPACK_HI_EXPR
@itemx VEC_UNPACK_LO_EXPR
These nodes represent unpacking of the high and low parts of the input vector,
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index ed737d1..a38ca3e 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -464,6 +464,9 @@ Necessary when modifying @command{gperf} input files, e.g.@:
@item DejaGnu 1.4.4
@itemx Expect
@itemx Tcl
+@c Once Tcl 8.5 or higher is required, remove any obsolete
+@c compatibility workarounds:
+@c git grep 'compatibility with earlier Tcl releases'
Necessary to run the GCC testsuite; see the section on testing for
details.
@@ -1371,7 +1374,7 @@ Specify which cpu variant the compiler should generate code for by default.
This option is only supported on some targets, including ARC, ARM, i386, M68k,
PowerPC, and SPARC@. It is mandatory for ARC@. The @option{--with-cpu-32} and
@option{--with-cpu-64} options specify separate default CPUs for
-32-bit and 64-bit modes; these options are only supported for i386,
+32-bit and 64-bit modes; these options are only supported for aarch64, i386,
x86-64, PowerPC, and SPARC@.
@item --with-schedule=@var{cpu}
@@ -1564,6 +1567,14 @@ When building GCC, use a mutex to avoid linking the compilers for
multiple languages at the same time, to avoid thrashing on build
systems with limited free memory. The default is not to use such a mutex.
+@item --enable-link-serialization
+When building GCC, use make dependencies to serialize linking the compilers for
+multiple languages, to avoid thrashing on build
+systems with limited free memory. The default is not to add such
+dependencies and thus with parallel make potentially link different
+compilers concurrently. If the argument is a positive integer, allow
+that number of concurrent link processes for the large binaries.
+
@item --enable-maintainer-mode
The build rules that regenerate the Autoconf and Automake output files as
well as the GCC master message catalog @file{gcc.pot} are normally
@@ -2248,11 +2259,10 @@ instrumentation, see @option{-fcf-protection} option. When
to add @option{-fcf-protection} and, if needed, other target
specific options to a set of building options.
-The option is disabled by default. When @code{--enable-cet=auto}
-is used, it is enabled on Linux/x86 if target binutils
-supports @code{Intel CET} instructions and disabled otherwise.
-In this case the target libraries are configured to get additional
-@option{-fcf-protection} option.
+@code{--enable-cet=auto} is default. CET is enabled on Linux/x86 if
+target binutils supports @code{Intel CET} instructions and disabled
+otherwise. In this case, the target libraries are configured to get
+additional @option{-fcf-protection} option.
@item --with-riscv-attribute=@samp{yes}, @samp{no} or @samp{default}
Generate RISC-V attribute by default, in order to record extra build
@@ -2260,6 +2270,16 @@ information in object.
The option is disabled by default. It is enabled on RISC-V/ELF (bare-metal)
target if target binutils supported.
+
+@item --enable-s390-excess-float-precision
+@itemx --disable-s390-excess-float-precision
+On s390(x) targets, enable treatment of float expressions with double precision
+when in standards-compliant mode (e.g., when @code{--std=c99} or
+@code{-fexcess-precision=standard} are given).
+
+For a native build, the option's default is derived from glibc's behavior. When
+glibc clamps float_t to double, gcc follows and enables the option. In all other
+cases, it defaults to off.
@end table
@subheading Cross-Compiler-Specific Options
@@ -2790,6 +2810,15 @@ Arranges for the run time of each program started by the GCC driver,
built in any stage, to be logged to @file{time.log}, in the top level of
the build tree.
+@item @samp{bootstrap-asan}
+Compiles GCC itself using Address Sanitization in order to catch invalid memory
+accesses within the GCC code.
+
+@item @samp{bootstrap-hwasan}
+Compiles GCC itself using HWAddress Sanitization in order to catch invalid
+memory accesses within the GCC code. This option is only available on AArch64
+systems that are running Linux kernel version 5.4 or later.
+
@end table
@section Building a cross compiler
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index d01beb2..35cd3dc 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -97,7 +97,7 @@ The usual way to run GCC is to run the executable called @command{gcc}, or
When you compile C++ programs, you should invoke GCC as @command{g++}
instead. @xref{Invoking G++,,Compiling C++ Programs},
for information about the differences in behavior between @command{gcc}
-and @code{g++} when compiling C++ programs.
+and @command{g++} when compiling C++ programs.
@cindex grouping options
@cindex options, grouping
@@ -201,7 +201,7 @@ in the following sections.
-aux-info @var{filename} -fallow-parameterless-variadic-functions @gol
-fno-asm -fno-builtin -fno-builtin-@var{function} -fgimple@gol
-fhosted -ffreestanding @gol
--fopenacc -fopenacc-dim=@var{geom} @gol
+-fopenacc -fopenacc-dim=@var{geom} -fopenacc-kernels=@var{mode} @gol
-fopenmp -fopenmp-simd @gol
-fms-extensions -fplan9-extensions -fsso-struct=@var{endianness} @gol
-fallow-single-precision -fcond-mismatch -flax-vector-conversions @gol
@@ -276,7 +276,7 @@ Objective-C and Objective-C++ Dialects}.
-fzero-link @gol
-gen-decls @gol
-Wassign-intercept -Wno-property-assign-default @gol
--Wno-protocol -Wselector @gol
+-Wno-protocol -Wobjc-root-class -Wselector @gol
-Wstrict-selector-match @gol
-Wundeclared-selector}
@@ -425,6 +425,8 @@ Objective-C and Objective-C++ Dialects}.
-Wno-analyzer-null-dereference @gol
-Wno-analyzer-possible-null-argument @gol
-Wno-analyzer-possible-null-dereference @gol
+-Wno-analyzer-shift-count-negative @gol
+-Wno-analyzer-shift-count-overflow @gol
-Wno-analyzer-stale-setjmp-buffer @gol
-Wno-analyzer-tainted-array-index @gol
-Wanalyzer-too-complex @gol
@@ -564,6 +566,7 @@ Objective-C and Objective-C++ Dialects}.
@gccoptlist{-p -pg -fprofile-arcs --coverage -ftest-coverage @gol
-fprofile-abs-path @gol
-fprofile-dir=@var{path} -fprofile-generate -fprofile-generate=@var{path} @gol
+-fprofile-info-section -fprofile-info-section=@var{name} @gol
-fprofile-note=@var{path} -fprofile-prefix-path=@var{path} @gol
-fprofile-update=@var{method} -fprofile-filter-files=@var{regex} @gol
-fprofile-exclude-files=@var{regex} @gol
@@ -1367,7 +1370,7 @@ See RS/6000 and PowerPC Options.
-mvpclmulqdq -mavx512bitalg -mmovdiri -mmovdir64b -mavx512vpopcntdq @gol
-mavx5124fmaps -mavx512vnni -mavx5124vnniw -mprfchw -mrdpid @gol
-mrdseed -msgx -mavx512vp2intersect -mserialize -mtsxldtrk@gol
--mamx-tile -mamx-int8 -mamx-bf16 -muintr -mhreset@gol
+-mamx-tile -mamx-int8 -mamx-bf16 -muintr -mhreset -mavxvnni@gol
-mcldemote -mms-bitfields -mno-align-stringops -minline-all-stringops @gol
-minline-stringops-dynamically -mstringop-strategy=@var{alg} @gol
-mkl -mwidekl @gol
@@ -1389,7 +1392,7 @@ See RS/6000 and PowerPC Options.
-mstack-protector-guard-symbol=@var{symbol} @gol
-mgeneral-regs-only -mcall-ms2sysv-xlogues @gol
-mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol
--mindirect-branch-register}
+-mindirect-branch-register -mneeded}
@emph{x86 Windows Options}
@gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol
@@ -2587,6 +2590,18 @@ not explicitly specify. The @var{geom} value is a triple of
':'-separated sizes, in order 'gang', 'worker' and, 'vector'. A size
can be omitted, to use a target-specific default value.
+@item -fopenacc-kernels=@var{mode}
+@opindex fopenacc-kernels
+@cindex OpenACC accelerator programming
+Specify mode of OpenACC `kernels' constructs handling.
+With @option{-fopenacc-kernels=decompose}, OpenACC `kernels'
+constructs are decomposed into parts, a sequence of compute
+constructs, each then handled individually.
+This is work in progress.
+With @option{-fopenacc-kernels=parloops}, OpenACC `kernels' constructs
+are handled by the @samp{parloops} pass, en bloc.
+This is the current default.
+
@item -fopenmp
@opindex fopenmp
@cindex OpenMP parallel
@@ -2807,6 +2822,9 @@ change in version 12.
Version 14, which first appeared in G++ 10, corrects the mangling of
the nullptr expression.
+Version 15, which first appeared in G++ 11, changes the mangling of
+@code{__alignof__} to be distinct from that of @code{alignof}.
+
See also @option{-Wabi}.
@item -fabi-compat-version=@var{n}
@@ -3663,7 +3681,23 @@ void fn () @{
@end smallexample
It does not warn when the type being copied is a trivially-copyable type whose
-size is less than 64 bytes. This warning is enabled by @option{-Wall}.
+size is less than 64 bytes.
+
+This warning also warns when a loop variable in a range-based for-loop is
+initialized with a value of a different type resulting in a copy. For example:
+
+@smallexample
+void fn() @{
+ int arr[10];
+ for (const double &x : arr) @{ @dots{} @}
+@}
+@end smallexample
+
+In the example above, in every iteration of the loop a temporary value of
+type @code{double} is created and destroyed, to which the reference
+@code{const double &} is bound.
+
+This warning is enabled by @option{-Wall}.
@item -Wredundant-tags @r{(C++ and Objective-C++ only)}
@opindex Wredundant-tags
@@ -4343,6 +4377,13 @@ from the superclass. If you use the @option{-Wno-protocol} option, then
methods inherited from the superclass are considered to be implemented,
and no warning is issued for them.
+@item -Wobjc-root-class @r{(Objective-C and Objective-C++ only)}
+@opindex Wobjc-root-class
+Warn if a class interface lacks a superclass. Most classes will inherit
+from @code{NSObject} (or @code{Object}) for example. When declaring
+classes intended to be root classes, the warning can be suppressed by
+marking their interfaces with @code{__attribute__((objc_root_class))}.
+
@item -Wselector @r{(Objective-C and Objective-C++ only)}
@opindex Wselector
@opindex Wno-selector
@@ -8894,6 +8935,8 @@ Enabling this option effectively enables the following warnings:
-Wanalyzer-possible-null-dereference @gol
-Wanalyzer-null-argument @gol
-Wanalyzer-null-dereference @gol
+-Wanalyzer-shift-count-negative @gol
+-Wanalyzer-shift-count-overflow @gol
-Wanalyzer-stale-setjmp-buffer @gol
-Wanalyzer-tainted-array-index @gol
-Wanalyzer-unsafe-call-within-signal-handler @gol
@@ -9027,6 +9070,35 @@ This warning requires @option{-fanalyzer}, which enables it; use
This diagnostic warns for paths through the code in which a
value known to be NULL is dereferenced.
+@item -Wno-analyzer-shift-count-negative
+@opindex Wanalyzer-shift-count-negative
+@opindex Wno-analyzer-shift-count-negative
+This warning requires @option{-fanalyzer}, which enables it; use
+@option{-Wno-analyzer-shift-count-negative} to disable it.
+
+This diagnostic warns for paths through the code in which a
+shift is attempted with a negative count. It is analogous to
+the @option{-Wshift-count-negative} diagnostic implemented in
+the C/C++ front ends, but is implemented based on analyzing
+interprocedural paths, rather than merely parsing the syntax tree.
+However, the analyzer does not prioritize detection of such paths, so
+false negatives are more likely relative to other warnings.
+
+@item -Wno-analyzer-shift-count-overflow
+@opindex Wanalyzer-shift-count-overflow
+@opindex Wno-analyzer-shift-count-overflow
+This warning requires @option{-fanalyzer}, which enables it; use
+@option{-Wno-analyzer-shift-count-overflow} to disable it.
+
+This diagnostic warns for paths through the code in which a
+shift is attempted with a count greater than or equal to the
+precision of the operand's type. It is analogous to
+the @option{-Wshift-count-overflow} diagnostic implemented in
+the C/C++ front ends, but is implemented based on analyzing
+interprocedural paths, rather than merely parsing the syntax tree.
+However, the analyzer does not prioritize detection of such paths, so
+false negatives are more likely relative to other warnings.
+
@item -Wno-analyzer-stale-setjmp-buffer
@opindex Wanalyzer-stale-setjmp-buffer
@opindex Wno-analyzer-stale-setjmp-buffer
@@ -11384,7 +11456,8 @@ and @option{-fauto-profile}.
@item -fvect-cost-model=@var{model}
@opindex fvect-cost-model
Alter the cost model used for vectorization. The @var{model} argument
-should be one of @samp{unlimited}, @samp{dynamic} or @samp{cheap}.
+should be one of @samp{unlimited}, @samp{dynamic}, @samp{cheap} or
+@samp{very-cheap}.
With the @samp{unlimited} model the vectorized code-path is assumed
to be profitable while with the @samp{dynamic} model a runtime check
guards the vectorized code-path to enable it only for iteration
@@ -11392,7 +11465,14 @@ counts that will likely execute faster than when executing the original
scalar loop. The @samp{cheap} model disables vectorization of
loops where doing so would be cost prohibitive for example due to
required runtime checks for data dependence or alignment but otherwise
-is equal to the @samp{dynamic} model.
+is equal to the @samp{dynamic} model. The @samp{very-cheap} model only
+allows vectorization if the vector code would entirely replace the
+scalar code that is being vectorized. For example, if each iteration
+of a vectorized loop would only be able to handle exactly four iterations
+of the scalar loop, the @samp{very-cheap} model would only allow
+vectorization if the scalar iteration count is known to be a multiple
+of four.
+
The default cost model depends on other optimization flags and is
either @samp{dynamic} or @samp{cheap}.
@@ -12953,6 +13033,13 @@ memory locations using the mod/ref information. This parameter ought to be
bigger than @option{--param ipa-modref-max-bases} and @option{--param
ipa-modref-max-refs}.
+@item ipa-modref-max-depth
+Specifies the maximum depth of DFS walk used by modref escape analysis.
+Setting to 0 disables the analysis completely.
+
+@item modref-max-escape-points
+Specifies the maximum number of escape points tracked by modref per SSA-name.
+
@item profile-func-internal-id
A parameter to control whether to use function internal id in profile
database lookup. If the value is 0, the compiler uses an id that
@@ -13446,11 +13533,6 @@ is aborted and the load or store is not considered redundant. The
number of queries is algorithmically limited to the number of
stores on all paths from the load to the function entry.
-@item max-pre-hoist-insert-iterations
-The maximum number of iterations doing insertion during code
-hoisting which is done as part of the partial redundancy elimination
-insertion phase.
-
@item ira-max-loops-num
IRA uses regional register allocation by default. If a function
contains more loops than the number given by this parameter, only at most
@@ -13747,6 +13829,53 @@ is greater or equal to this number, use callbacks instead of inline checks.
E.g. to disable inline code use
@option{--param asan-instrumentation-with-call-threshold=0}.
+@item hwasan-instrument-stack
+Enable hwasan instrumentation of statically sized stack-allocated variables.
+This kind of instrumentation is enabled by default when using
+@option{-fsanitize=hwaddress} and disabled by default when using
+@option{-fsanitize=kernel-hwaddress}.
+To disable stack instrumentation use
+@option{--param hwasan-instrument-stack=0}, and to enable it use
+@option{--param hwasan-instrument-stack=1}.
+
+@item hwasan-random-frame-tag
+When using stack instrumentation, decide tags for stack variables using a
+deterministic sequence beginning at a random tag for each frame. With this
+parameter unset tags are chosen using the same sequence but beginning from 1.
+This is enabled by default for @option{-fsanitize=hwaddress} and unavailable
+for @option{-fsanitize=kernel-hwaddress}.
+To disable it use @option{--param hwasan-random-frame-tag=0}.
+
+@item hwasan-instrument-allocas
+Enable hwasan instrumentation of dynamically sized stack-allocated variables.
+This kind of instrumentation is enabled by default when using
+@option{-fsanitize=hwaddress} and disabled by default when using
+@option{-fsanitize=kernel-hwaddress}.
+To disable instrumentation of such variables use
+@option{--param hwasan-instrument-allocas=0}, and to enable it use
+@option{--param hwasan-instrument-allocas=1}.
+
+@item hwasan-instrument-reads
+Enable hwasan checks on memory reads. Instrumentation of reads is enabled by
+default for both @option{-fsanitize=hwaddress} and
+@option{-fsanitize=kernel-hwaddress}.
+To disable checking memory reads use
+@option{--param hwasan-instrument-reads=0}.
+
+@item hwasan-instrument-writes
+Enable hwasan checks on memory writes. Instrumentation of writes is enabled by
+default for both @option{-fsanitize=hwaddress} and
+@option{-fsanitize=kernel-hwaddress}.
+To disable checking memory writes use
+@option{--param hwasan-instrument-writes=0}.
+
+@item hwasan-instrument-mem-intrinsics
+Enable hwasan instrumentation of builtin functions. Instrumentation of these
+builtin functions is enabled by default for both @option{-fsanitize=hwaddress}
+and @option{-fsanitize=kernel-hwaddress}.
+To disable instrumentation of builtin functions use
+@option{--param hwasan-instrument-mem-intrinsics=0}.
+
@item use-after-scope-direct-emission-threshold
If the size of a local variable in bytes is smaller or equal to this
number, directly poison (or unpoison) shadow memory instead of using
@@ -13996,6 +14125,24 @@ The number of Newton iterations for calculating the reciprocal for double type.
The precision of division is propotional to this param when division
approximation is enabled. The default value is 2.
+@item aarch64-autovec-preference
+Force an ISA selection strategy for auto-vectorization. Accepts values from
+0 to 4, inclusive.
+@table @samp
+@item 0
+Use the default heuristics.
+@item 1
+Use only Advanced SIMD for auto-vectorization.
+@item 2
+Use only SVE for auto-vectorization.
+@item 3
+Use both Advanced SIMD and SVE. Prefer Advanced SIMD when the costs are
+deemed equal.
+@item 4
+Use both Advanced SIMD and SVE. Prefer SVE when the costs are deemed equal.
+@end table
+The default value is 0.
+
@end table
@end table
@@ -14183,6 +14330,34 @@ the profile feedback data files. See @option{-fprofile-dir}.
To optimize the program based on the collected profile information, use
@option{-fprofile-use}. @xref{Optimize Options}, for more information.
+@item -fprofile-info-section
+@itemx -fprofile-info-section=@var{name}
+@opindex fprofile-info-section
+
+Register the profile information in the specified section instead of using a
+constructor/destructor. The section name is @var{name} if it is specified,
+otherwise the section name defaults to @code{.gcov_info}. A pointer to the
+profile information generated by @option{-fprofile-arcs} or
+@option{-ftest-coverage} is placed in the specified section for each
+translation unit. This option disables the profile information registration
+through a constructor and it disables the profile information processing
+through a destructor. This option is not intended to be used in hosted
+environments such as GNU/Linux. It targets systems with limited resources
+which do not support constructors and destructors. The linker could collect
+the input sections in a continuous memory block and define start and end
+symbols. The runtime support could dump the profiling information registered
+in this linker set during program termination to a serial line for example. A
+GNU linker script example which defines a linker output section follows:
+
+@smallexample
+ .gcov_info :
+ @{
+ PROVIDE (__gcov_info_start = .);
+ KEEP (*(.gcov_info))
+ PROVIDE (__gcov_info_end = .);
+ @}
+@end smallexample
+
@item -fprofile-note=@var{path}
@opindex fprofile-note
@@ -14258,7 +14433,7 @@ Note that it is quite common that execution counts of some part of
programs depends, for example, on length of temporary file names or
memory space randomization (that may affect hash-table collision rate).
Such non-reproducible part of programs may be annotated by
-@code{no_instrument_function} function attribute. @code{gcov-dump} with
+@code{no_instrument_function} function attribute. @command{gcov-dump} with
@option{-l} can be used to dump gathered data and verify that they are
indeed reproducible.
@@ -14281,13 +14456,47 @@ more details. The run-time behavior can be influenced using the
the available options are shown at startup of the instrumented program. See
@url{https://github.com/google/sanitizers/wiki/AddressSanitizerFlags#run-time-flags}
for a list of supported options.
-The option cannot be combined with @option{-fsanitize=thread}.
+The option cannot be combined with @option{-fsanitize=thread} or
+@option{-fsanitize=hwaddress}. Note that the only target this option is
+currently supported on is AArch64.
@item -fsanitize=kernel-address
@opindex fsanitize=kernel-address
Enable AddressSanitizer for Linux kernel.
See @uref{https://github.com/google/kasan/wiki} for more details.
+@item -fsanitize=hwaddress
+@opindex fsanitize=hwaddress
+Enable Hardware-assisted AddressSanitizer, which uses a hardware ability to
+ignore the top byte of a pointer to allow the detection of memory errors with
+a low memory overhead.
+Memory access instructions are instrumented to detect out-of-bounds and
+use-after-free bugs.
+The option enables @option{-fsanitize-address-use-after-scope}.
+See
+@uref{https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html}
+for more details. The run-time behavior can be influenced using the
+@env{HWASAN_OPTIONS} environment variable. When set to @code{help=1},
+the available options are shown at startup of the instrumented program.
+The option cannot be combined with @option{-fsanitize=thread} or
+@option{-fsanitize=address}, and is currently only available on AArch64.
+
+@item -fsanitize=kernel-hwaddress
+@opindex fsanitize=kernel-hwaddress
+Enable Hardware-assisted AddressSanitizer for compilation of the Linux kernel.
+Similar to @option{-fsanitize=kernel-address} but using an alternate
+instrumentation method, and similar to @option{-fsanitize=hwaddress} but with
+instrumentation differences necessary for compiling the Linux kernel.
+These differences are to avoid hwasan library initialization calls and to
+account for the stack pointer having a different value in its top byte.
+
+@emph{Note:} This option has different defaults to the @option{-fsanitize=hwaddress}.
+Instrumenting the stack and alloca calls are not on by default but are still
+possible by specifying the command-line options
+@option{--param hwasan-instrument-stack=1} and
+@option{--param hwasan-instrument-allocas=1} respectively. Using a random frame
+tag is not implemented for kernel instrumentation.
+
@item -fsanitize=pointer-compare
@opindex fsanitize=pointer-compare
Instrument comparison operation (<, <=, >, >=) with pointer operands.
@@ -17955,6 +18164,9 @@ Enable brain half-precision floating-point instructions. This also enables
Advanced SIMD and floating-point instructions. This option is enabled by
default for @option{-march=armv8.6-a}. Use of this option with architectures
prior to Armv8.2-A is not supported.
+@item flagm
+Enable the Flag Manipulation instructions Extension. This option is enabled by
+default for @option{-march=armv8.4-a}.
@end table
@@ -29529,13 +29741,13 @@ BMI, BMI2 and F16C instruction set support.
@item broadwell
Intel Broadwell CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2,
-F16C, RDSEED and ADCX instruction set support.
+F16C, RDSEED ADCX and PREFETCHW instruction set support.
@item skylake
Intel Skylake CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA,
-BMI, BMI2, F16C, RDSEED, ADCX, CLFLUSHOPT, XSAVEC and XSAVES instruction set
-support.
+BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC and XSAVES
+instruction set support.
@item bonnell
Intel Bonnell CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3 and SSSE3
@@ -29564,32 +29776,33 @@ MOVDIR64B, CLDEMOTE and WAITPKG instruction set support.
@item knl
Intel Knight's Landing CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3,
SSSE3, SSE4.1, SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA,
-BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHWT1, AVX512F, AVX512PF, AVX512ER and
-AVX512CD instruction set support.
+BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, PREFETCHWT1, AVX512F, AVX512PF,
+AVX512ER and AVX512CD instruction set support.
@item knm
Intel Knights Mill CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3,
SSSE3, SSE4.1, SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA,
-BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHWT1, AVX512F, AVX512PF, AVX512ER, AVX512CD,
-AVX5124VNNIW, AVX5124FMAPS and AVX512VPOPCNTDQ instruction set support.
+BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, PREFETCHWT1, AVX512F, AVX512PF,
+AVX512ER, AVX512CD, AVX5124VNNIW, AVX5124FMAPS and AVX512VPOPCNTDQ instruction
+set support.
@item skylake-avx512
Intel Skylake Server CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3,
SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA,
-BMI, BMI2, F16C, RDSEED, ADCX, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F,
+BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F,
CLWB, AVX512VL, AVX512BW, AVX512DQ and AVX512CD instruction set support.
@item cannonlake
Intel Cannonlake Server CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2,
SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE,
-RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, CLFLUSHOPT, XSAVEC,
+RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC,
XSAVES, AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI,
AVX512IFMA, SHA and UMIP instruction set support.
@item icelake-client
Intel Icelake Client CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2,
SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE,
-RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, CLFLUSHOPT, XSAVEC,
+RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC,
XSAVES, AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI,
AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ,
AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES instruction set support.
@@ -29597,7 +29810,7 @@ AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES instruction set support.
@item icelake-server
Intel Icelake Server CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2,
SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE,
-RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, CLFLUSHOPT, XSAVEC,
+RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC,
XSAVES, AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI,
AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ,
AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES, PCONFIG and WBNOINVD instruction
@@ -29606,37 +29819,40 @@ set support.
@item cascadelake
Intel Cascadelake CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
-BMI2, F16C, RDSEED, ADCX, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, CLWB,
+BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, CLWB,
AVX512VL, AVX512BW, AVX512DQ, AVX512CD and AVX512VNNI instruction set support.
@item cooperlake
Intel cooperlake CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
-BMI2, F16C, RDSEED, ADCX, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, CLWB,
+BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, CLWB,
AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VNNI and AVX512BF16 instruction
set support.
@item tigerlake
Intel Tigerlake CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
-BMI2, F16C, RDSEED, ADCX, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, AVX512VL,
-AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI, AVX512IFMA, SHA, CLWB, UMIP, RDPID,
-GFNI, AVX512VBMI2, AVX512VPOPCNTDQ, AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES,
-PCONFIG, WBNOINVD, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT and KEYLOCKER
+BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F,
+AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI, AVX512IFMA, SHA, CLWB, UMIP,
+RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ, AVX512BITALG, AVX512VNNI, VPCLMULQDQ,
+VAES, PCONFIG, WBNOINVD, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT and KEYLOCKER
instruction set support.
@item sapphirerapids
Intel sapphirerapids CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3,
SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND,
-FMA, BMI, BMI2, F16C, RDSEED, ADCX, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, CLWB,
-AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VNNI, AVX512BF16, MOVDIRI,
-MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, SERIALIZE,
-TSXLDTRK, UINTR, AMX-BF16, AMX-TILE and AMX-INT8 instruction set support.
+FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES,
+AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VNNI, AVX512BF16,
+MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG,
+SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE, AMX-INT8 and AVX-VNNI
+instruction set support.
@item alderlake
Intel Alderlake CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
-SSE4.1, SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, CLDEMOTE,
-PTWRITE, WAITPKG, SERIALIZE, KEYLOCKER and HRESET instruction set support.
+SSE4.1, SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
+BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, CLDEMOTE,
+PTWRITE, WAITPKG, SERIALIZE, KEYLOCKER, HRESET and AVX-VNNI instruction set
+support.
@item k6
AMD K6 CPU with MMX instruction set support.
@@ -30409,6 +30625,9 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}.
@itemx -mavx512vnni
@opindex mavx512vnni
@need 200
+@itemx -mavxvnni
+@opindex mavxvnni
+@need 200
@itemx -mavx5124vnniw
@opindex mavx5124vnniw
@need 200
@@ -30443,9 +30662,9 @@ WBNOINVD, FMA4, PREFETCHW, RDPID, PREFETCHWT1, RDSEED, SGX, XOP, LWP,
XSAVEOPT, XSAVEC, XSAVES, RTM, HLE, TBM, MWAITX, CLZERO, PKU, AVX512VBMI2,
GFNI, VAES, WAITPKG, VPCLMULQDQ, AVX512BITALG, MOVDIRI, MOVDIR64B, AVX512BF16,
ENQCMD, AVX512VPOPCNTDQ, AVX5124FMAPS, AVX512VNNI, AVX5124VNNIW, SERIALIZE,
-UINTR, HRESET, AMXTILE, AMXINT8, AMXBF16, KL, WIDEKL or CLDEMOTE extended
-instruction sets. Each has a corresponding @option{-mno-} option to disable
-use of these instructions.
+UINTR, HRESET, AMXTILE, AMXINT8, AMXBF16, KL, WIDEKL, AVXVNNI or CLDEMOTE
+extended instruction sets. Each has a corresponding @option{-mno-} option to
+disable use of these instructions.
These extensions are also available as built-in functions: see
@ref{x86 Built-in Functions}, for details of the functions enabled and
@@ -31161,6 +31380,12 @@ environments.
Generate code for short address mode. This is only supported for 32-bit
and x32 environments. It is the default address mode for 32-bit and
x32 environments.
+
+@item -mneeded
+@itemx -mno-needed
+@opindex mneeded
+Emit GNU_PROPERTY_X86_ISA_1_NEEDED GNU property for Linux target to
+indicate the micro-architecture ISA level required to execute the binary.
@end table
@node x86 Windows Options
@@ -31634,6 +31859,9 @@ Marks the argument containing or following the @samp{%w} as the
designated output file of this compilation. This puts the argument
into the sequence of arguments that @samp{%o} substitutes.
+@item %V
+Indicates that this compilation produces no output file.
+
@item %o
Substitutes the names of all the output files, with spaces
automatically placed around them. You should write spaces
@@ -31652,16 +31880,6 @@ been substituted, except that @samp{%g, %u, and %U} do not currently
support additional @var{suffix} characters following @samp{%O} as they do
following, for example, @samp{.o}.
-@item %p
-Substitutes the standard macro predefinitions for the
-current target machine. Use this when running @command{cpp}.
-
-@item %P
-Like @samp{%p}, but puts @samp{__} before and after the name of each
-predefined macro, except for macros that start with @samp{__} or with
-@samp{_@var{L}}, where @var{L} is an uppercase letter. This is for ISO
-C@.
-
@item %I
Substitute any of @option{-iprefix} (made from @env{GCC_EXEC_PREFIX}),
@option{-isysroot} (made from @env{TARGET_SYSTEM_ROOT}),
@@ -31686,6 +31904,9 @@ searched.
Print @var{str} as an error message. @var{str} is terminated by a newline.
Use this when inconsistent options are detected.
+@item %n@var{str}
+Print @var{str} as a notice. @var{str} is terminated by a newline.
+
@item %(@var{name})
Substitute the contents of spec string @var{name} at this point.
@@ -31702,6 +31923,12 @@ Output the accumulated assembler options specified by @option{-Wa}.
@item %Z
Output the accumulated preprocessor options specified by @option{-Wp}.
+@item %M
+Output @code{multilib_os_dir}.
+
+@item %R
+Output the concatenation of @code{target_system_root} and @code{target_sysroot_suffix}.
+
@item %a
Process the @code{asm} spec. This is used to compute the
switches to be passed to the assembler.
@@ -31761,6 +31988,12 @@ command is position dependent. @samp{%} commands in the spec string
before this one see @code{-S}, @samp{%} commands in the spec string
after this one do not.
+@item %<S*
+Similar to @samp{%<S}, but match all switches beginning with @code{-S}.
+
+@item %>S
+Similar to @samp{%<S}, but keep @code{-S} in the GCC command line.
+
@item %:@var{function}(@var{args})
Call the named function @var{function}, passing it @var{args}.
@var{args} is first processed as a nested spec string, then split
@@ -31821,6 +32054,14 @@ usage:
-l%:if-exists-then-else(%:getenv(VSB_DIR rtnet.h) rtnet net)
@end smallexample
+@item @code{sanitize}
+The @code{sanitize} spec function takes no arguments. It returns non-NULL if
+any address, thread or undefined behaviour sanitizers are active.
+
+@smallexample
+%@{%:sanitize(address):-funwind-tables@}
+@end smallexample
+
@item @code{replace-outfile}
The @code{replace-outfile} spec function takes two arguments. It looks for the
first argument in the outfiles array and replaces it with the second argument. Here
@@ -31839,6 +32080,56 @@ its usage:
%:remove-outfile(-lm)
@end smallexample
+@item @code{version-compare}
+The @code{version-compare} spec function takes four or five arguments of the following
+form:
+
+@smallexample
+<comparison-op> <arg1> [<arg2>] <switch> <result>
+@end smallexample
+
+It returns @code{result} if the comparison evaluates to true, and NULL if it doesn't.
+The supported @code{comparison-op} values are:
+
+@table @code
+@item >=
+True if @code{switch} is a later (or same) version than @code{arg1}
+
+@item !>
+Opposite of @code{>=}
+
+@item <
+True if @code{switch} is an earlier version than @code{arg1}
+
+@item !<
+Opposite of @code{<}
+
+@item ><
+True if @code{switch} is @code{arg1} or later, and earlier than @code{arg2}
+
+@item <>
+True if @code{switch} is earlier than @code{arg1}, or is @code{arg2} or later
+@end table
+
+If the @code{switch} is not present at all, the condition is false unless the first character
+of the @code{comparison-op} is @code{!}.
+
+@smallexample
+%:version-compare(>= 10.3 mmacosx-version-min= -lmx)
+@end smallexample
+
+The above example would add @option{-lmx} if @option{-mmacosx-version-min=10.3.9} was
+passed.
+
+@item @code{include}
+The @code{include} spec function behaves much like @code{%include}, with the advantage
+that it can be nested inside a spec and thus be conditionalized. It takes one argument,
+the filename, and looks for it in the startfile path. It always returns NULL.
+
+@smallexample
+%@{static-libasan|static:%:include(libsanitizer.spec)%(link_libasan)@}
+@end smallexample
+
@item @code{pass-through-libs}
The @code{pass-through-libs} spec function takes any number of arguments. It
finds any @option{-l} options and any non-options ending in @file{.a} (which it
@@ -31864,6 +32155,25 @@ Use "-Wa,OPTION" to pass "OPTION" to the assembler.
It is used to separate compiler options from assembler options
in the @option{--target-help} output.
+
+@item @code{gt}
+The @code{gt} spec function takes two or more arguments. It returns @code{""} (the
+empty string) if the second-to-last argument is greater than the last argument, and NULL
+otherwise. The following example inserts the @code{link_gomp} spec if the last
+@option{-ftree-parallelize-loops=} option given on the command line is greater than 1:
+
+@smallexample
+%@{%:gt(%@{ftree-parallelize-loops=*:%*@} 1):%:include(libgomp.spec)%(link_gomp)@}
+@end smallexample
+
+@item @code{debug-level-gt}
+The @code{debug-level-gt} spec function takes one argument and returns @code{""} (the
+empty string) if @code{debug_info_level} is greater than the specified number, and NULL
+otherwise.
+
+@smallexample
+%@{%:debug-level-gt(0):%@{gdwarf*:--gdwarf2@}@}
+@end smallexample
@end table
@item %@{S@}
@@ -31878,6 +32188,10 @@ and outputs the command-line option @option{-foo}.
Like %@{@code{S}@} but mark last argument supplied within as a file to be
deleted on failure.
+@item %@@@{S@}
+Like %@{@code{S}@} but puts the result into a @code{FILE} and substitutes
+@code{@@FILE} if an @code{@@file} argument has been supplied.
+
@item %@{S*@}
Substitutes all the switches specified to GCC whose names start
with @code{-S}, but which also take an argument. This is used for
@@ -31960,6 +32274,12 @@ jim.d -bar -boggle
-d jim.d -bar -baz -boggle
@end smallexample
+@item %@{%:@var{function}(@var{args}):X@}
+
+Call function named @var{function} with args @var{args}. If the
+function returns non-NULL, then @code{X} is substituted, if it returns
+NULL, it isn't substituted.
+
@item %@{S:X; T:Y; :D@}
If @code{S} is given to GCC, substitutes @code{X}; else if @code{T} is
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 813875b..da8c9a2 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -5626,6 +5626,28 @@ with N signed/unsigned elements of size S@. Operand 2 is a constant. Shift
the high/low elements of operand 1, and put the N/2 results of size 2*S in the
output vector (operand 0).
+@cindex @code{vec_widen_saddl_hi_@var{m}} instruction pattern
+@cindex @code{vec_widen_saddl_lo_@var{m}} instruction pattern
+@cindex @code{vec_widen_uaddl_hi_@var{m}} instruction pattern
+@cindex @code{vec_widen_uaddl_lo_@var{m}} instruction pattern
+@item @samp{vec_widen_uaddl_hi_@var{m}}, @samp{vec_widen_uaddl_lo_@var{m}}
+@itemx @samp{vec_widen_saddl_hi_@var{m}}, @samp{vec_widen_saddl_lo_@var{m}}
+Signed/Unsigned widening add long. Operands 1 and 2 are vectors with N
+signed/unsigned elements of size S@. Add the high/low elements of 1 and 2
+together, widen the resulting elements and put the N/2 results of size 2*S in
+the output vector (operand 0).
+
+@cindex @code{vec_widen_ssubl_hi_@var{m}} instruction pattern
+@cindex @code{vec_widen_ssubl_lo_@var{m}} instruction pattern
+@cindex @code{vec_widen_usubl_hi_@var{m}} instruction pattern
+@cindex @code{vec_widen_usubl_lo_@var{m}} instruction pattern
+@item @samp{vec_widen_usubl_hi_@var{m}}, @samp{vec_widen_usubl_lo_@var{m}}
+@itemx @samp{vec_widen_ssubl_hi_@var{m}}, @samp{vec_widen_ssubl_lo_@var{m}}
+Signed/Unsigned widening subtract long. Operands 1 and 2 are vectors with N
+signed/unsigned elements of size S@. Subtract the high/low elements of 2 from
+1 and widen the resulting elements. Put the N/2 results of size 2*S in the
+output vector (operand 0).
+
@cindex @code{mulhisi3} instruction pattern
@item @samp{mulhisi3}
Multiply operands 1 and 2, which have mode @code{HImode}, and store
diff --git a/gcc/doc/plugins.texi b/gcc/doc/plugins.texi
index 23a8b41..1c211bb 100644
--- a/gcc/doc/plugins.texi
+++ b/gcc/doc/plugins.texi
@@ -218,6 +218,10 @@ enum plugin_event
as a const char* pointer. */
PLUGIN_INCLUDE_FILE,
+ /* Called when -fanalyzer starts. The event data is an
+ ana::plugin_analyzer_init_iface *. */
+ PLUGIN_ANALYZER_INIT,
+
PLUGIN_EVENT_FIRST_DYNAMIC /* Dummy event used for indexing callback
array. */
@};
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index 22af573..4f9b990 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -1406,6 +1406,12 @@ Pointer bounds modes. Used to represent values of pointer bounds type.
Operations in these modes may be executed as NOPs depending on hardware
features and environment setup.
+@findex MODE_OPAQUE
+@item MODE_OPAQUE
+This is a mode class for modes that don't want to provide operations
+other than register moves, memory moves, loads, stores, and
+@code{unspec}s. They have a size and precision and that's all.
+
@findex MODE_RANDOM
@item MODE_RANDOM
This is a catchall mode class for modes which don't fit into the above
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index b3c5e53..586dce7 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -1141,7 +1141,7 @@ but not if @code{-fpic} is also present:
/* @{ dg-skip-if "" @{ *-*-* @} @{ "-O2 -g" "-O3 -g" @} @{ "-fpic" @} @} */
@end smallexample
-@item @{ dg-require-effective-target @var{keyword} [@{ @var{selector} @}] @}
+@item @{ dg-require-effective-target @var{keyword} [@{ target @var{selector} @}] @}
Skip the test if the test target, including current multilib flags,
is not covered by the effective-target keyword.
If the directive includes the optional @samp{@{ @var{selector} @}}
@@ -1443,6 +1443,10 @@ Target has runtime support for any options added with
@item inf
Target supports floating point infinite (@code{inf}) for type
@code{double}.
+
+@item inff
+Target supports floating point infinite (@code{inf}) for type
+@code{float}.
@end table
@subsubsection Fortran-specific attributes
@@ -2243,6 +2247,9 @@ Target supports compiling @code{avx2} instructions.
@item avx2_runtime
Target supports the execution of @code{avx2} instructions.
+@item avxvnni
+Target supports the execution of @code{avxvnni} instructions.
+
@item avx512f
Target supports compiling @code{avx512f} instructions.
@@ -2455,6 +2462,9 @@ Target supports wide characters.
@subsubsection Other attributes
@table @code
+@item R_flag_in_section
+Target supports the 'R' flag in .section directive in assembly inputs.
+
@item automatic_stack_alignment
Target supports automatic stack alignment.
@@ -2538,9 +2548,15 @@ Target supports the @code{noinit} variable attribute.
@item nonpic
Target does not generate PIC by default.
+@item o_flag_in_section
+Target supports the 'o' flag in .section directive in assembly inputs.
+
@item offload_gcn
Target has been configured for OpenACC/OpenMP offloading on AMD GCN.
+@item persistent
+Target supports the @code{persistent} variable attribute.
+
@item pie_enabled
Target generates PIE by default.
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 833320b..f507765 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5457,11 +5457,24 @@ Note that the block move need only cover the constant parts of the
trampoline. If the target isolates the variable parts of the trampoline
to the end, not all @code{TRAMPOLINE_SIZE} bytes need be copied.
-If the target requires any other actions, such as flushing caches or
+If the target requires any other actions, such as flushing caches
+(possibly calling function maybe_emit_call_builtin___clear_cache) or
enabling stack execution, these actions should be performed after
initializing the trampoline proper.
@end deftypefn
+@deftypefn {Target Hook} void TARGET_EMIT_CALL_BUILTIN___CLEAR_CACHE (rtx @var{begin}, rtx @var{end})
+On targets that do not define a @code{clear_cache} insn expander,
+but that define the @code{CLEAR_CACHE_INSN} macro,
+maybe_emit_call_builtin___clear_cache relies on this target hook
+to clear an address range in the instruction cache.
+
+The default implementation calls the @code{__clear_cache} builtin,
+taking the assembler name from the builtin declaration. Overriding
+definitions may call alternate functions, with alternate calling
+conventions, or emit alternate RTX to perform the job.
+@end deftypefn
+
@deftypefn {Target Hook} rtx TARGET_TRAMPOLINE_ADJUST_ADDRESS (rtx @var{addr})
This hook should perform any machine-specific adjustment in
the address of the trampoline. Its argument contains the address of the
@@ -5490,7 +5503,7 @@ the following macro.
If defined, expands to a C expression clearing the @emph{instruction
cache} in the specified interval. The definition of this macro would
typically be a series of @code{asm} statements. Both @var{beg} and
-@var{end} are both pointer expressions.
+@var{end} are pointer expressions.
@end defmac
To use a standard subroutine, define the following macro. In addition,
@@ -7711,13 +7724,14 @@ example, the function @code{foo} would be placed in @code{.text.foo}.
Whatever the actual target object format, this is often good enough.
@end deftypefn
-@deftypefn {Target Hook} {section *} TARGET_ASM_FUNCTION_RODATA_SECTION (tree @var{decl})
-Return the readonly data section associated with
-@samp{DECL_SECTION_NAME (@var{decl})}.
+@deftypefn {Target Hook} {section *} TARGET_ASM_FUNCTION_RODATA_SECTION (tree @var{decl}, bool @var{relocatable})
+Return the readonly data or reloc readonly data section associated with
+@samp{DECL_SECTION_NAME (@var{decl})}. @var{relocatable} selects the latter
+over the former.
The default version of this function selects @code{.gnu.linkonce.r.name} if
the function's section is @code{.gnu.linkonce.t.name}, @code{.rodata.name}
-if function is in @code{.text.name}, and the normal readonly-data section
-otherwise.
+or @code{.data.rel.ro.name} if function is in @code{.text.name}, and
+the normal readonly-data or reloc readonly data section otherwise.
@end deftypefn
@deftypevr {Target Hook} {const char *} TARGET_ASM_MERGEABLE_RODATA_PREFIX
@@ -9560,6 +9574,10 @@ given instruction. This is only used when @code{TARGET_EXCEPT_UNWIND_INFO}
returns @code{UI_TARGET}.
@end deftypefn
+@deftypefn {Target Hook} rtx TARGET_ASM_MAKE_EH_SYMBOL_INDIRECT (rtx @var{origsymbol}, bool @var{pubvis})
+If necessary, modify personality and LSDA references to handle indirection. The original symbol is in @code{origsymbol} and if @code{pubvis} is true the symbol is visible outside the TU.
+@end deftypefn
+
@deftypevr {Target Hook} bool TARGET_ASM_UNWIND_EMIT_BEFORE_INSN
True if the @code{TARGET_ASM_UNWIND_EMIT} hook should be called before the assembly for @var{insn} has been emitted, false if the hook should be called afterward.
@end deftypevr
@@ -10817,6 +10835,26 @@ Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions
relating to the target operating system.
@end deftypefn
+@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_SECTION
+Contains the name of the section in which module info references should be
+placed. This section is expected to be bracketed by two symbols to indicate
+the start and end address of the section, so that the runtime library can
+collect all modules for each loaded shared library and executable. The
+default value of @code{NULL} disables the use of sections altogether.
+@end deftypevr
+
+@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_START_NAME
+If @code{TARGET_D_MINFO_SECTION} is defined, then this must also be defined
+as the name of the symbol indicating the start address of the module info
+section
+@end deftypevr
+
+@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_END_NAME
+If @code{TARGET_D_MINFO_SECTION} is defined, then this must also be defined
+as the name of the symbol indicating the end address of the module info
+section
+@end deftypevr
+
@node Named Address Spaces
@section Adding support for named address spaces
@cindex named address spaces
@@ -12090,7 +12128,8 @@ is zero, which disables this optimization.
@deftypefn {Target Hook} {unsigned HOST_WIDE_INT} TARGET_ASAN_SHADOW_OFFSET (void)
Return the offset bitwise ored into shifted address to get corresponding
Address Sanitizer shadow memory address. NULL if Address Sanitizer is not
-supported by the target.
+supported by the target. May return 0 if Address Sanitizer is not supported
+by a subtarget.
@end deftypefn
@deftypefn {Target Hook} {unsigned HOST_WIDE_INT} TARGET_MEMMODEL_CHECK (unsigned HOST_WIDE_INT @var{val})
@@ -12216,3 +12255,69 @@ This target hook can be used to generate a target-specific code
@deftypefn {Target Hook} void TARGET_RUN_TARGET_SELFTESTS (void)
If selftests are enabled, run any selftests for this target.
@end deftypefn
+
+@deftypefn {Target Hook} bool TARGET_MEMTAG_CAN_TAG_ADDRESSES ()
+True if the backend architecture naturally supports ignoring some region
+of pointers. This feature means that @option{-fsanitize=hwaddress} can
+work.
+
+At preset, this feature does not support address spaces. It also requires
+@code{Pmode} to be the same as @code{ptr_mode}.
+@end deftypefn
+
+@deftypefn {Target Hook} uint8_t TARGET_MEMTAG_TAG_SIZE ()
+Return the size of a tag (in bits) for this platform.
+
+The default returns 8.
+@end deftypefn
+
+@deftypefn {Target Hook} uint8_t TARGET_MEMTAG_GRANULE_SIZE ()
+Return the size in real memory that each byte in shadow memory refers to.
+I.e. if a variable is @var{X} bytes long in memory, then this hook should
+return the value @var{Y} such that the tag in shadow memory spans
+@var{X}/@var{Y} bytes.
+
+Most variables will need to be aligned to this amount since two variables
+that are neighbors in memory and share a tag granule would need to share
+the same tag.
+
+The default returns 16.
+@end deftypefn
+
+@deftypefn {Target Hook} rtx TARGET_MEMTAG_INSERT_RANDOM_TAG (rtx @var{untagged}, rtx @var{target})
+Return an RTX representing the value of @var{untagged} but with a
+(possibly) random tag in it.
+Put that value into @var{target} if it is convenient to do so.
+This function is used to generate a tagged base for the current stack frame.
+@end deftypefn
+
+@deftypefn {Target Hook} rtx TARGET_MEMTAG_ADD_TAG (rtx @var{base}, poly_int64 @var{addr_offset}, uint8_t @var{tag_offset})
+Return an RTX that represents the result of adding @var{addr_offset} to
+the address in pointer @var{base} and @var{tag_offset} to the tag in pointer
+@var{base}.
+The resulting RTX must either be a valid memory address or be able to get
+put into an operand with @code{force_operand}.
+
+Unlike other memtag hooks, this must return an expression and not emit any
+RTL.
+@end deftypefn
+
+@deftypefn {Target Hook} rtx TARGET_MEMTAG_SET_TAG (rtx @var{untagged_base}, rtx @var{tag}, rtx @var{target})
+Return an RTX representing @var{untagged_base} but with the tag @var{tag}.
+Try and store this in @var{target} if convenient.
+@var{untagged_base} is required to have a zero tag when this hook is called.
+The default of this hook is to set the top byte of @var{untagged_base} to
+@var{tag}.
+@end deftypefn
+
+@deftypefn {Target Hook} rtx TARGET_MEMTAG_EXTRACT_TAG (rtx @var{tagged_pointer}, rtx @var{target})
+Return an RTX representing the tag stored in @var{tagged_pointer}.
+Store the result in @var{target} if it is convenient.
+The default represents the top byte of the original pointer.
+@end deftypefn
+
+@deftypefn {Target Hook} rtx TARGET_MEMTAG_UNTAGGED_POINTER (rtx @var{tagged_pointer}, rtx @var{target})
+Return an RTX representing @var{tagged_pointer} with its tag set to zero.
+Store the result in @var{target} if convenient.
+The default clears the top byte of the original pointer.
+@end deftypefn
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 58109be..ad56858 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3877,6 +3877,8 @@ is used for aligning trampolines.
@hook TARGET_TRAMPOLINE_INIT
+@hook TARGET_EMIT_CALL_BUILTIN___CLEAR_CACHE
+
@hook TARGET_TRAMPOLINE_ADJUST_ADDRESS
Implementing trampolines is difficult on many machines because they have
@@ -3897,7 +3899,7 @@ the following macro.
If defined, expands to a C expression clearing the @emph{instruction
cache} in the specified interval. The definition of this macro would
typically be a series of @code{asm} statements. Both @var{beg} and
-@var{end} are both pointer expressions.
+@var{end} are pointer expressions.
@end defmac
To use a standard subroutine, define the following macro. In addition,
@@ -6456,6 +6458,8 @@ the jump-table.
@hook TARGET_ASM_UNWIND_EMIT
+@hook TARGET_ASM_MAKE_EH_SYMBOL_INDIRECT
+
@hook TARGET_ASM_UNWIND_EMIT_BEFORE_INSN
@node Exception Region Output
@@ -7351,6 +7355,12 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_OS_VERSIONS
+@hook TARGET_D_MINFO_SECTION
+
+@hook TARGET_D_MINFO_START_NAME
+
+@hook TARGET_D_MINFO_END_NAME
+
@node Named Address Spaces
@section Adding support for named address spaces
@cindex named address spaces
@@ -8182,3 +8192,19 @@ maintainer is familiar with.
@hook TARGET_SPECULATION_SAFE_VALUE
@hook TARGET_RUN_TARGET_SELFTESTS
+
+@hook TARGET_MEMTAG_CAN_TAG_ADDRESSES
+
+@hook TARGET_MEMTAG_TAG_SIZE
+
+@hook TARGET_MEMTAG_GRANULE_SIZE
+
+@hook TARGET_MEMTAG_INSERT_RANDOM_TAG
+
+@hook TARGET_MEMTAG_ADD_TAG
+
+@hook TARGET_MEMTAG_SET_TAG
+
+@hook TARGET_MEMTAG_EXTRACT_TAG
+
+@hook TARGET_MEMTAG_UNTAGGED_POINTER
diff --git a/gcc/dse.c b/gcc/dse.c
index d65266b..651e6e7 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -1757,8 +1757,7 @@ find_shift_sequence (poly_int64 access_size,
the machine. */
opt_scalar_int_mode new_mode_iter;
- FOR_EACH_MODE_FROM (new_mode_iter,
- smallest_int_mode_for_size (GET_MODE_BITSIZE (read_mode)))
+ FOR_EACH_MODE_IN_CLASS (new_mode_iter, MODE_INT)
{
rtx target, new_reg, new_lhs;
rtx_insn *shift_seq, *insn;
@@ -1767,6 +1766,8 @@ find_shift_sequence (poly_int64 access_size,
new_mode = new_mode_iter.require ();
if (GET_MODE_BITSIZE (new_mode) > BITS_PER_WORD)
break;
+ if (maybe_lt (GET_MODE_SIZE (new_mode), GET_MODE_SIZE (read_mode)))
+ continue;
/* Try a wider mode if truncating the store mode to NEW_MODE
requires a real instruction. */
diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c
index 8e53aef..80a65fe 100644
--- a/gcc/dumpfile.c
+++ b/gcc/dumpfile.c
@@ -492,6 +492,14 @@ dump_loc (dump_flags_t dump_kind, FILE *dfile, location_t loc)
static void
dump_loc (dump_flags_t dump_kind, pretty_printer *pp, location_t loc)
{
+ /* Disable warnings about missing quoting in GCC diagnostics for
+ the pp_printf calls. Their format strings aren't used to format
+ diagnostics so don't need to follow GCC diagnostic conventions. */
+#if __GNUC__ >= 10
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wformat-diag"
+#endif
+
if (dump_kind)
{
if (LOCATION_LOCUS (loc) > BUILTINS_LOCATION)
@@ -507,6 +515,10 @@ dump_loc (dump_flags_t dump_kind, pretty_printer *pp, location_t loc)
for (unsigned i = 0; i < get_dump_scope_depth (); i++)
pp_character (pp, ' ');
}
+
+#if __GNUC__ >= 10
+# pragma GCC diagnostic pop
+#endif
}
/* Implementation of dump_context member functions. */
@@ -1118,8 +1130,12 @@ dump_context::begin_scope (const char *name,
if (m_test_pp && apply_dump_filter_p (MSG_NOTE, m_test_pp_flags))
::dump_loc (MSG_NOTE, m_test_pp, src_loc);
+ /* Format multiple consecutive punctuation characters via %s to
+ avoid -Wformat-diag in the pp_printf call below whose output
+ isn't used for diagnostic output. */
pretty_printer pp;
- pp_printf (&pp, "=== %s ===\n", name);
+ pp_printf (&pp, "%s %s %s", "===", name, "===");
+ pp_newline (&pp);
optinfo_item *item
= new optinfo_item (OPTINFO_ITEM_KIND_TEXT, UNKNOWN_LOCATION,
xstrdup (pp_formatted_text (&pp)));
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index bc32a17..c23a3ca 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -991,7 +991,12 @@ dwarf2out_do_cfi_startproc (bool second)
in the assembler. Further, the assembler can't handle any
of the weirder relocation types. */
if (enc & DW_EH_PE_indirect)
- ref = dw2_force_const_mem (ref, true);
+ {
+ if (targetm.asm_out.make_eh_symbol_indirect != NULL)
+ ref = targetm.asm_out.make_eh_symbol_indirect (ref, true);
+ else
+ ref = dw2_force_const_mem (ref, true);
+ }
fprintf (asm_out_file, "\t.cfi_personality %#x,", enc);
output_addr_const (asm_out_file, ref);
@@ -1009,7 +1014,12 @@ dwarf2out_do_cfi_startproc (bool second)
SYMBOL_REF_FLAGS (ref) = SYMBOL_FLAG_LOCAL;
if (enc & DW_EH_PE_indirect)
- ref = dw2_force_const_mem (ref, true);
+ {
+ if (targetm.asm_out.make_eh_symbol_indirect != NULL)
+ ref = targetm.asm_out.make_eh_symbol_indirect (ref, true);
+ else
+ ref = dw2_force_const_mem (ref, true);
+ }
fprintf (asm_out_file, "\t.cfi_lsda %#x,", enc);
output_addr_const (asm_out_file, ref);
@@ -12963,18 +12973,19 @@ base_type_die (tree type, bool reverse)
break;
case fixed_point_scale_factor_arbitrary:
- /* Arbitrary scale factors cannot be described in standard DWARF,
- yet. */
+ /* Arbitrary scale factors cannot be described in standard DWARF. */
if (!dwarf_strict)
{
/* Describe the scale factor as a rational constant. */
const dw_die_ref scale_factor
= new_die (DW_TAG_constant, comp_unit_die (), type);
- add_AT_unsigned (scale_factor, DW_AT_GNU_numerator,
- fpt_info.scale_factor.arbitrary.numerator);
- add_AT_int (scale_factor, DW_AT_GNU_denominator,
- fpt_info.scale_factor.arbitrary.denominator);
+ add_scalar_info (scale_factor, DW_AT_GNU_numerator,
+ fpt_info.scale_factor.arbitrary.numerator,
+ dw_scalar_form_constant, NULL);
+ add_scalar_info (scale_factor, DW_AT_GNU_denominator,
+ fpt_info.scale_factor.arbitrary.denominator,
+ dw_scalar_form_constant, NULL);
add_AT_die_ref (base_type_result, DW_AT_small, scale_factor);
}
@@ -13027,6 +13038,7 @@ is_base_type (tree type)
return 1;
case VOID_TYPE:
+ case OPAQUE_TYPE:
case ARRAY_TYPE:
case RECORD_TYPE:
case UNION_TYPE:
@@ -20763,12 +20775,23 @@ add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value,
else
add_AT_int (die, attr, TREE_INT_CST_LOW (value));
}
- else
+ else if (dwarf_version >= 5
+ && TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (value))) == 128)
/* Otherwise represent the bound as an unsigned value with
the precision of its type. The precision and signedness
of the type will be necessary to re-interpret it
unambiguously. */
add_AT_wide (die, attr, wi::to_wide (value));
+ else
+ {
+ rtx v = immed_wide_int_const (wi::to_wide (value),
+ TYPE_MODE (TREE_TYPE (value)));
+ dw_loc_descr_ref loc
+ = loc_descriptor (v, TYPE_MODE (TREE_TYPE (value)),
+ VAR_INIT_STATUS_INITIALIZED);
+ if (loc)
+ add_AT_loc (die, attr, loc);
+ }
return;
}
@@ -22183,6 +22206,9 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
dw_die_ref enum_die = new_die (DW_TAG_enumerator, type_die, link);
tree value = TREE_VALUE (link);
+ if (DECL_P (value))
+ equate_decl_number_to_die (value, enum_die);
+
gcc_assert (!ENUM_IS_OPAQUE (type));
add_name_attribute (enum_die,
IDENTIFIER_POINTER (TREE_PURPOSE (link)));
@@ -22766,6 +22792,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
tree origin = decl_ultimate_origin (decl);
dw_die_ref subr_die;
dw_die_ref old_die = lookup_decl_die (decl);
+ bool old_die_had_no_children = false;
/* This function gets called multiple times for different stages of
the debug process. For example, for func() in this code:
@@ -22849,6 +22876,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
available.
*/
int declaration = (current_function_decl != decl
+ || (!DECL_INITIAL (decl) && !origin)
|| class_or_namespace_scope_p (context_die));
/* A declaration that has been previously dumped needs no
@@ -22856,6 +22884,9 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
if (old_die && declaration)
return;
+ if (in_lto_p && old_die && old_die->die_child == NULL)
+ old_die_had_no_children = true;
+
/* Now that the C++ front end lazily declares artificial member fns, we
might need to retrofit the declaration into its class. */
if (!declaration && !origin && !old_die
@@ -23375,6 +23406,10 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
else if (DECL_INITIAL (decl) == NULL_TREE)
gen_unspecified_parameters_die (decl, subr_die);
}
+ else if ((subr_die != old_die || old_die_had_no_children)
+ && prototype_p (TREE_TYPE (decl))
+ && stdarg_p (TREE_TYPE (decl)))
+ gen_unspecified_parameters_die (decl, subr_die);
}
if (subr_die != old_die)
@@ -24609,7 +24644,7 @@ gen_compile_unit_die (const char *filename)
if (dwarf_version >= 5 /* || !dwarf_strict */)
if (strcmp (language_string, "GNU C11") == 0
|| strcmp (language_string, "GNU C17") == 0
- || strcmp (language_string, "GNU C2X"))
+ || strcmp (language_string, "GNU C2X") == 0)
language = DW_LANG_C11;
}
}
@@ -24622,7 +24657,8 @@ gen_compile_unit_die (const char *filename)
language = DW_LANG_C_plus_plus_11;
else if (strcmp (language_string, "GNU C++14") == 0)
language = DW_LANG_C_plus_plus_14;
- else if (strcmp (language_string, "GNU C++17") == 0)
+ else if (strcmp (language_string, "GNU C++17") == 0
+ || strcmp (language_string, "GNU C++20") == 0)
/* For now. */
language = DW_LANG_C_plus_plus_14;
}
@@ -25236,6 +25272,10 @@ gen_member_die (tree type, dw_die_ref context_die)
splice = false;
}
}
+ else if (child->die_tag == DW_TAG_enumerator)
+ /* Enumerators remain under their enumeration even if
+ their names are introduced in the enclosing scope. */
+ splice = false;
if (splice)
splice_child_die (context_die, child);
@@ -25749,6 +25789,7 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
return;
case VOID_TYPE:
+ case OPAQUE_TYPE:
case INTEGER_TYPE:
case REAL_TYPE:
case FIXED_POINT_TYPE:
@@ -26147,6 +26188,13 @@ force_decl_die (tree decl)
decl_die = comp_unit_die ();
break;
+ case CONST_DECL:
+ /* Enumerators shouldn't need force_decl_die. */
+ gcc_assert (DECL_CONTEXT (decl) == NULL_TREE
+ || TREE_CODE (DECL_CONTEXT (decl)) != ENUMERAL_TYPE);
+ gen_decl_die (decl, NULL, NULL, context_die);
+ break;
+
case TRANSLATION_UNIT_DECL:
decl_die = comp_unit_die ();
break;
@@ -26732,7 +26780,7 @@ dwarf2out_imported_module_or_decl_1 (tree decl,
else
xloc = expand_location (input_location);
- if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == CONST_DECL)
+ if (TREE_CODE (decl) == TYPE_DECL)
{
at_import_die = force_type_die (TREE_TYPE (decl));
/* For namespace N { typedef void T; } using N::T; base_type_die
@@ -32135,13 +32183,13 @@ dwarf2out_early_finish (const char *filename)
emit full debugging info for them. */
retry_incomplete_types ();
+ gen_scheduled_generic_parms_dies ();
+ gen_remaining_tmpl_value_param_die_attribute ();
+
/* The point here is to flush out the limbo list so that it is empty
and we don't need to stream it for LTO. */
flush_limbo_die_list ();
- gen_scheduled_generic_parms_dies ();
- gen_remaining_tmpl_value_param_die_attribute ();
-
/* Add DW_AT_linkage_name for all deferred DIEs. */
for (limbo_die_node *node = deferred_asm_name; node; node = node->next)
{
diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h
index 9571f8b..0b06cff 100644
--- a/gcc/dwarf2out.h
+++ b/gcc/dwarf2out.h
@@ -362,23 +362,18 @@ enum fixed_point_scale_factor
struct fixed_point_type_info
{
- /* A scale factor is the value one has to multiply with physical data in
- order to get the fixed point logical data. The DWARF standard enables one
- to encode it in three ways. */
+ /* The scale factor is the value one has to multiply the actual data with
+ to get the fixed point value. We support three ways to encode it. */
enum fixed_point_scale_factor scale_factor_kind;
union
{
- /* For binary scale factor, the scale factor is: 2 ** binary. */
+ /* For a binary scale factor, the scale factor is 2 ** binary. */
int binary;
- /* For decimal scale factor, the scale factor is: 10 ** binary. */
+ /* For a decimal scale factor, the scale factor is 10 ** decimal. */
int decimal;
- /* For arbitrary scale factor, the scale factor is:
+ /* For an arbitrary scale factor, the scale factor is the ratio
numerator / denominator. */
- struct
- {
- unsigned HOST_WIDE_INT numerator;
- HOST_WIDE_INT denominator;
- } arbitrary;
+ struct { tree numerator; tree denominator; } arbitrary;
} scale_factor;
};
diff --git a/gcc/edit-context.c b/gcc/edit-context.c
index 97897d6..80641c2 100644
--- a/gcc/edit-context.c
+++ b/gcc/edit-context.c
@@ -447,8 +447,13 @@ edited_file::print_diff (pretty_printer *pp, bool show_filenames)
if (show_filenames)
{
pp_string (pp, colorize_start (pp_show_color (pp), "diff-filename"));
- pp_printf (pp, "--- %s\n", m_filename);
- pp_printf (pp, "+++ %s\n", m_filename);
+ /* Avoid -Wformat-diag in non-diagnostic output. */
+ pp_string (pp, "--- ");
+ pp_string (pp, m_filename);
+ pp_newline (pp);
+ pp_string (pp, "+++ ");
+ pp_string (pp, m_filename);
+ pp_newline (pp);
pp_string (pp, colorize_stop (pp_show_color (pp)));
}
@@ -519,8 +524,9 @@ edited_file::print_diff_hunk (pretty_printer *pp, int old_start_of_hunk,
= get_effective_line_count (old_start_of_hunk, old_end_of_hunk);
pp_string (pp, colorize_start (pp_show_color (pp), "diff-hunk"));
- pp_printf (pp, "@@ -%i,%i +%i,%i @@\n", old_start_of_hunk, old_num_lines,
- new_start_of_hunk, new_num_lines);
+ pp_printf (pp, "%s -%i,%i +%i,%i %s",
+ "@@", old_start_of_hunk, old_num_lines,
+ new_start_of_hunk, new_num_lines, "@@\n");
pp_string (pp, colorize_stop (pp_show_color (pp)));
int line_num = old_start_of_hunk;
diff --git a/gcc/explow.c b/gcc/explow.c
index 0fbc6d2..65f904a 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -27,9 +27,9 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "memmodel.h"
#include "tm_p.h"
+#include "optabs.h"
#include "expmed.h"
#include "profile-count.h"
-#include "optabs.h"
#include "emit-rtl.h"
#include "recog.h"
#include "diagnostic-core.h"
@@ -1583,10 +1583,14 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
OFFSET is the offset of the area into the virtual stack vars area.
REQUIRED_ALIGN is the alignment (in bits) required for the region
- of memory. */
+ of memory.
+
+ BASE is the rtx of the base of this virtual stack vars area.
+ The only time this is not `virtual_stack_vars_rtx` is when tagging pointers
+ on the stack. */
rtx
-get_dynamic_stack_base (poly_int64 offset, unsigned required_align)
+get_dynamic_stack_base (poly_int64 offset, unsigned required_align, rtx base)
{
rtx target;
@@ -1594,7 +1598,7 @@ get_dynamic_stack_base (poly_int64 offset, unsigned required_align)
crtl->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
target = gen_reg_rtx (Pmode);
- emit_move_insn (target, virtual_stack_vars_rtx);
+ emit_move_insn (target, base);
target = expand_binop (Pmode, add_optab, target,
gen_int_mode (offset, Pmode),
NULL_RTX, 1, OPTAB_LIB_WIDEN);
diff --git a/gcc/explow.h b/gcc/explow.h
index 0df8c62..581831c 100644
--- a/gcc/explow.h
+++ b/gcc/explow.h
@@ -106,7 +106,7 @@ extern rtx allocate_dynamic_stack_space (rtx, unsigned, unsigned,
extern void get_dynamic_stack_size (rtx *, unsigned, unsigned, HOST_WIDE_INT *);
/* Returns the address of the dynamic stack space without allocating it. */
-extern rtx get_dynamic_stack_base (poly_int64, unsigned);
+extern rtx get_dynamic_stack_base (poly_int64, unsigned, rtx);
/* Return an rtx doing runtime alignment to REQUIRED_ALIGN on TARGET. */
extern rtx align_dynamic_address (rtx, unsigned);
diff --git a/gcc/expmed.c b/gcc/expmed.c
index d34f0fb..0d600bd 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -31,8 +31,8 @@ along with GCC; see the file COPYING3. If not see
#include "predict.h"
#include "memmodel.h"
#include "tm_p.h"
-#include "expmed.h"
#include "optabs.h"
+#include "expmed.h"
#include "regs.h"
#include "emit-rtl.h"
#include "diagnostic-core.h"
@@ -412,7 +412,8 @@ flip_storage_order (machine_mode mode, rtx x)
&& __builtin_expect (reverse_float_storage_order_supported < 0, 0))
check_reverse_float_storage_order_support ();
- if (!int_mode_for_size (GET_MODE_PRECISION (mode), 0).exists (&int_mode))
+ if (!int_mode_for_size (GET_MODE_PRECISION (mode), 0).exists (&int_mode)
+ || !targetm.scalar_mode_supported_p (int_mode))
{
sorry ("reverse storage order for %smode", GET_MODE_NAME (mode));
return x;
@@ -4193,7 +4194,8 @@ expand_sdiv_pow2 (scalar_int_mode mode, rtx op0, HOST_WIDE_INT d)
rtx
expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
- rtx op0, rtx op1, rtx target, int unsignedp)
+ rtx op0, rtx op1, rtx target, int unsignedp,
+ enum optab_methods methods)
{
machine_mode compute_mode;
rtx tquotient;
@@ -4299,17 +4301,22 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
optab2 = (op1_is_pow2 ? optab1
: (unsignedp ? udivmod_optab : sdivmod_optab));
- FOR_EACH_MODE_FROM (compute_mode, mode)
- if (optab_handler (optab1, compute_mode) != CODE_FOR_nothing
- || optab_handler (optab2, compute_mode) != CODE_FOR_nothing)
- break;
-
- if (compute_mode == VOIDmode)
- FOR_EACH_MODE_FROM (compute_mode, mode)
- if (optab_libfunc (optab1, compute_mode)
- || optab_libfunc (optab2, compute_mode))
+ if (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN)
+ {
+ FOR_EACH_MODE_FROM (compute_mode, mode)
+ if (optab_handler (optab1, compute_mode) != CODE_FOR_nothing
+ || optab_handler (optab2, compute_mode) != CODE_FOR_nothing)
break;
+ if (compute_mode == VOIDmode && methods == OPTAB_LIB_WIDEN)
+ FOR_EACH_MODE_FROM (compute_mode, mode)
+ if (optab_libfunc (optab1, compute_mode)
+ || optab_libfunc (optab2, compute_mode))
+ break;
+ }
+ else
+ compute_mode = mode;
+
/* If we still couldn't find a mode, use MODE, but expand_binop will
probably die. */
if (compute_mode == VOIDmode)
@@ -4412,8 +4419,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
remainder
= expand_binop (int_mode, and_optab, op0,
gen_int_mode (mask, int_mode),
- remainder, 1,
- OPTAB_LIB_WIDEN);
+ remainder, 1, methods);
if (remainder)
return gen_lowpart (mode, remainder);
}
@@ -4721,7 +4727,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
remainder = expand_binop
(int_mode, and_optab, op0,
gen_int_mode (mask, int_mode),
- remainder, 0, OPTAB_LIB_WIDEN);
+ remainder, 0, methods);
if (remainder)
return gen_lowpart (mode, remainder);
}
@@ -4846,7 +4852,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
do_cmp_and_jump (op1, const0_rtx, LT, compute_mode, label2);
do_cmp_and_jump (adjusted_op0, const0_rtx, LT, compute_mode, label1);
tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
- quotient, 0, OPTAB_LIB_WIDEN);
+ quotient, 0, methods);
if (tem != quotient)
emit_move_insn (quotient, tem);
emit_jump_insn (targetm.gen_jump (label5));
@@ -4858,7 +4864,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
emit_label (label2);
do_cmp_and_jump (adjusted_op0, const0_rtx, GT, compute_mode, label3);
tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
- quotient, 0, OPTAB_LIB_WIDEN);
+ quotient, 0, methods);
if (tem != quotient)
emit_move_insn (quotient, tem);
emit_jump_insn (targetm.gen_jump (label5));
@@ -4867,7 +4873,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
expand_dec (adjusted_op0, const1_rtx);
emit_label (label4);
tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
- quotient, 0, OPTAB_LIB_WIDEN);
+ quotient, 0, methods);
if (tem != quotient)
emit_move_insn (quotient, tem);
expand_dec (quotient, const1_rtx);
@@ -4892,7 +4898,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
floor_log2 (d), tquotient, 1);
t2 = expand_binop (int_mode, and_optab, op0,
gen_int_mode (d - 1, int_mode),
- NULL_RTX, 1, OPTAB_LIB_WIDEN);
+ NULL_RTX, 1, methods);
t3 = gen_reg_rtx (int_mode);
t3 = emit_store_flag (t3, NE, t2, const0_rtx, int_mode, 1, 1);
if (t3 == 0)
@@ -4963,7 +4969,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
emit_label (label1);
expand_dec (adjusted_op0, const1_rtx);
tem = expand_binop (compute_mode, udiv_optab, adjusted_op0, op1,
- quotient, 1, OPTAB_LIB_WIDEN);
+ quotient, 1, methods);
if (tem != quotient)
emit_move_insn (quotient, tem);
expand_inc (quotient, const1_rtx);
@@ -4987,7 +4993,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
floor_log2 (d), tquotient, 0);
t2 = expand_binop (compute_mode, and_optab, op0,
gen_int_mode (d - 1, compute_mode),
- NULL_RTX, 1, OPTAB_LIB_WIDEN);
+ NULL_RTX, 1, methods);
t3 = gen_reg_rtx (compute_mode);
t3 = emit_store_flag (t3, NE, t2, const0_rtx,
compute_mode, 1, 1);
@@ -5063,7 +5069,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
do_cmp_and_jump (adjusted_op0, const0_rtx, GT,
compute_mode, label1);
tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
- quotient, 0, OPTAB_LIB_WIDEN);
+ quotient, 0, methods);
if (tem != quotient)
emit_move_insn (quotient, tem);
emit_jump_insn (targetm.gen_jump (label5));
@@ -5076,7 +5082,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
do_cmp_and_jump (adjusted_op0, const0_rtx, LT,
compute_mode, label3);
tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
- quotient, 0, OPTAB_LIB_WIDEN);
+ quotient, 0, methods);
if (tem != quotient)
emit_move_insn (quotient, tem);
emit_jump_insn (targetm.gen_jump (label5));
@@ -5085,7 +5091,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
expand_inc (adjusted_op0, const1_rtx);
emit_label (label4);
tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
- quotient, 0, OPTAB_LIB_WIDEN);
+ quotient, 0, methods);
if (tem != quotient)
emit_move_insn (quotient, tem);
expand_inc (quotient, const1_rtx);
@@ -5133,10 +5139,10 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
{
rtx tem;
quotient = expand_binop (int_mode, udiv_optab, op0, op1,
- quotient, 1, OPTAB_LIB_WIDEN);
+ quotient, 1, methods);
tem = expand_mult (int_mode, quotient, op1, NULL_RTX, 1);
remainder = expand_binop (int_mode, sub_optab, op0, tem,
- remainder, 1, OPTAB_LIB_WIDEN);
+ remainder, 1, methods);
}
tem = plus_constant (int_mode, op1, -1);
tem = expand_shift (RSHIFT_EXPR, int_mode, tem, 1, NULL_RTX, 1);
@@ -5158,10 +5164,10 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
{
rtx tem;
quotient = expand_binop (int_mode, sdiv_optab, op0, op1,
- quotient, 0, OPTAB_LIB_WIDEN);
+ quotient, 0, methods);
tem = expand_mult (int_mode, quotient, op1, NULL_RTX, 0);
remainder = expand_binop (int_mode, sub_optab, op0, tem,
- remainder, 0, OPTAB_LIB_WIDEN);
+ remainder, 0, methods);
}
abs_rem = expand_abs (int_mode, remainder, NULL_RTX, 1, 0);
abs_op1 = expand_abs (int_mode, op1, NULL_RTX, 1, 0);
@@ -5258,7 +5264,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
quotient = sign_expand_binop (compute_mode,
udiv_optab, sdiv_optab,
op0, op1, target,
- unsignedp, OPTAB_LIB_WIDEN);
+ unsignedp, methods);
}
}
}
@@ -5273,10 +5279,11 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
/* No divide instruction either. Use library for remainder. */
remainder = sign_expand_binop (compute_mode, umod_optab, smod_optab,
op0, op1, target,
- unsignedp, OPTAB_LIB_WIDEN);
+ unsignedp, methods);
/* No remainder function. Try a quotient-and-remainder
function, keeping the remainder. */
- if (!remainder)
+ if (!remainder
+ && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
{
remainder = gen_reg_rtx (compute_mode);
if (!expand_twoval_binop_libfunc
@@ -5294,10 +5301,14 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
NULL_RTX, unsignedp);
remainder = expand_binop (compute_mode, sub_optab, op0,
remainder, target, unsignedp,
- OPTAB_LIB_WIDEN);
+ methods);
}
}
+ if (methods != OPTAB_LIB_WIDEN
+ && (rem_flag ? remainder : quotient) == NULL_RTX)
+ return NULL_RTX;
+
return gen_lowpart (mode, rem_flag ? remainder : quotient);
}
diff --git a/gcc/expmed.h b/gcc/expmed.h
index b719b94..6a9bab7 100644
--- a/gcc/expmed.h
+++ b/gcc/expmed.h
@@ -716,8 +716,10 @@ extern rtx expand_variable_shift (enum tree_code, machine_mode,
rtx, tree, rtx, int);
extern rtx expand_shift (enum tree_code, machine_mode, rtx, poly_int64, rtx,
int);
+#ifdef GCC_OPTABS_H
extern rtx expand_divmod (int, enum tree_code, machine_mode, rtx, rtx,
- rtx, int);
+ rtx, int, enum optab_methods = OPTAB_LIB_WIDEN);
+#endif
#endif
extern void store_bit_field (rtx, poly_uint64, poly_uint64,
diff --git a/gcc/expr.c b/gcc/expr.c
index ae16f07..798285e 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -29,8 +29,8 @@ along with GCC; see the file COPYING3. If not see
#include "memmodel.h"
#include "tm_p.h"
#include "ssa.h"
-#include "expmed.h"
#include "optabs.h"
+#include "expmed.h"
#include "regs.h"
#include "emit-rtl.h"
#include "recog.h"
@@ -6171,6 +6171,7 @@ count_type_elements (const_tree type, bool for_ctor_p)
return 0;
case VOID_TYPE:
+ case OPAQUE_TYPE:
case METHOD_TYPE:
case FUNCTION_TYPE:
case LANG_TYPE:
@@ -9034,6 +9035,8 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
target, unsignedp);
return target;
+ case WIDEN_PLUS_EXPR:
+ case WIDEN_MINUS_EXPR:
case WIDEN_MULT_EXPR:
/* If first operand is constant, swap them.
Thus the following special case checks need only
@@ -9754,6 +9757,10 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
return temp;
}
+ case VEC_WIDEN_PLUS_HI_EXPR:
+ case VEC_WIDEN_PLUS_LO_EXPR:
+ case VEC_WIDEN_MINUS_HI_EXPR:
+ case VEC_WIDEN_MINUS_LO_EXPR:
case VEC_WIDEN_MULT_HI_EXPR:
case VEC_WIDEN_MULT_LO_EXPR:
case VEC_WIDEN_MULT_EVEN_EXPR:
diff --git a/gcc/final.c b/gcc/final.c
index 80423d1..fc9a05e 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -81,6 +81,7 @@ along with GCC; see the file COPYING3. If not see
#include "rtl-iter.h"
#include "print-rtl.h"
#include "function-abi.h"
+#include "common/common-target.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h" /* Needed for external data declarations. */
@@ -2154,6 +2155,21 @@ asm_show_source (const char *filename, int linenum)
fputc ('\n', asm_out_file);
}
+/* Judge if an absolute jump table is relocatable. */
+
+bool
+jumptable_relocatable (void)
+{
+ bool relocatable = false;
+
+ if (!CASE_VECTOR_PC_RELATIVE
+ && !targetm.asm_out.generate_pic_addr_diff_vec ()
+ && targetm_common.have_named_sections)
+ relocatable = targetm.asm_out.reloc_rw_mask ();
+
+ return relocatable;
+}
+
/* The final scan for one insn, INSN.
Args are same as in `final', except that INSN
is the insn being scanned.
@@ -2493,7 +2509,8 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
int log_align;
switch_to_section (targetm.asm_out.function_rodata_section
- (current_function_decl));
+ (current_function_decl,
+ jumptable_relocatable ()));
#ifdef ADDR_VEC_ALIGN
log_align = ADDR_VEC_ALIGN (table);
@@ -2572,7 +2589,8 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
if (! JUMP_TABLES_IN_TEXT_SECTION)
switch_to_section (targetm.asm_out.function_rodata_section
- (current_function_decl));
+ (current_function_decl,
+ jumptable_relocatable ()));
else
switch_to_section (current_function_section ());
diff --git a/gcc/flag-types.h b/gcc/flag-types.h
index a887c75..9342bd8 100644
--- a/gcc/flag-types.h
+++ b/gcc/flag-types.h
@@ -232,12 +232,14 @@ enum scalar_storage_order_kind {
SSO_LITTLE_ENDIAN
};
-/* Vectorizer cost-model. */
+/* Vectorizer cost-model. Except for DEFAULT, the values are ordered from
+ the most conservative to the least conservative. */
enum vect_cost_model {
+ VECT_COST_MODEL_VERY_CHEAP = -3,
+ VECT_COST_MODEL_CHEAP = -2,
+ VECT_COST_MODEL_DYNAMIC = -1,
VECT_COST_MODEL_UNLIMITED = 0,
- VECT_COST_MODEL_CHEAP = 1,
- VECT_COST_MODEL_DYNAMIC = 2,
- VECT_COST_MODEL_DEFAULT = 3
+ VECT_COST_MODEL_DEFAULT = 1
};
/* Different instrumentation modes. */
@@ -274,6 +276,9 @@ enum sanitize_code {
SANITIZE_BUILTIN = 1UL << 25,
SANITIZE_POINTER_COMPARE = 1UL << 26,
SANITIZE_POINTER_SUBTRACT = 1UL << 27,
+ SANITIZE_HWADDRESS = 1UL << 28,
+ SANITIZE_USER_HWADDRESS = 1UL << 29,
+ SANITIZE_KERNEL_HWADDRESS = 1UL << 30,
SANITIZE_SHIFT = SANITIZE_SHIFT_BASE | SANITIZE_SHIFT_EXPONENT,
SANITIZE_UNDEFINED = SANITIZE_SHIFT | SANITIZE_DIVIDE | SANITIZE_UNREACHABLE
| SANITIZE_VLA | SANITIZE_NULL | SANITIZE_RETURN
@@ -415,6 +420,13 @@ enum evrp_mode
EVRP_MODE_RVRP_DEBUG = EVRP_MODE_RVRP_ONLY | EVRP_MODE_DEBUG
};
+/* Modes of OpenACC 'kernels' constructs handling. */
+enum openacc_kernels
+{
+ OPENACC_KERNELS_DECOMPOSE,
+ OPENACC_KERNELS_PARLOOPS
+};
+
#endif
#endif /* ! GCC_FLAG_TYPES_H */
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index c47557d..e77d74e 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -992,26 +992,19 @@ wide_int_binop (wide_int &res,
res = wi::bit_and (arg1, arg2);
break;
- case RSHIFT_EXPR:
case LSHIFT_EXPR:
if (wi::neg_p (arg2))
- {
- tmp = -arg2;
- if (code == RSHIFT_EXPR)
- code = LSHIFT_EXPR;
- else
- code = RSHIFT_EXPR;
- }
- else
- tmp = arg2;
+ return false;
+ res = wi::lshift (arg1, arg2);
+ break;
- if (code == RSHIFT_EXPR)
- /* It's unclear from the C standard whether shifts can overflow.
- The following code ignores overflow; perhaps a C standard
- interpretation ruling is needed. */
- res = wi::rshift (arg1, tmp, sign);
- else
- res = wi::lshift (arg1, tmp);
+ case RSHIFT_EXPR:
+ if (wi::neg_p (arg2))
+ return false;
+ /* It's unclear from the C standard whether shifts can overflow.
+ The following code ignores overflow; perhaps a C standard
+ interpretation ruling is needed. */
+ res = wi::rshift (arg1, arg2, sign);
break;
case RROTATE_EXPR:
@@ -3312,10 +3305,36 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1,
case COMPONENT_REF:
/* Handle operand 2 the same as for ARRAY_REF. Operand 0
may be NULL when we're called to compare MEM_EXPRs. */
- if (!OP_SAME_WITH_NULL (0)
- || !OP_SAME (1))
+ if (!OP_SAME_WITH_NULL (0))
return false;
- flags &= ~OEP_ADDRESS_OF;
+ {
+ bool compare_address = flags & OEP_ADDRESS_OF;
+
+ /* Most of time we only need to compare FIELD_DECLs for equality.
+ However when determining address look into actual offsets.
+ These may match for unions and unshared record types. */
+ flags &= ~OEP_ADDRESS_OF;
+ if (!OP_SAME (1))
+ {
+ if (compare_address)
+ {
+ if (TREE_OPERAND (arg0, 2)
+ || TREE_OPERAND (arg1, 2))
+ return OP_SAME_WITH_NULL (2);
+ tree field0 = TREE_OPERAND (arg0, 1);
+ tree field1 = TREE_OPERAND (arg1, 1);
+
+ if (!operand_equal_p (DECL_FIELD_OFFSET (field0),
+ DECL_FIELD_OFFSET (field1), flags)
+ || !operand_equal_p (DECL_FIELD_BIT_OFFSET (field0),
+ DECL_FIELD_BIT_OFFSET (field1),
+ flags))
+ return false;
+ }
+ else
+ return false;
+ }
+ }
return OP_SAME_WITH_NULL (2);
case BIT_FIELD_REF:
@@ -3324,24 +3343,6 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1,
flags &= ~OEP_ADDRESS_OF;
return OP_SAME (1) && OP_SAME (2);
- /* Virtual table call. */
- case OBJ_TYPE_REF:
- {
- if (!operand_equal_p (OBJ_TYPE_REF_EXPR (arg0),
- OBJ_TYPE_REF_EXPR (arg1), flags))
- return false;
- if (tree_to_uhwi (OBJ_TYPE_REF_TOKEN (arg0))
- != tree_to_uhwi (OBJ_TYPE_REF_TOKEN (arg1)))
- return false;
- if (!operand_equal_p (OBJ_TYPE_REF_OBJECT (arg0),
- OBJ_TYPE_REF_OBJECT (arg1), flags))
- return false;
- if (!types_same_for_odr (obj_type_ref_class (arg0),
- obj_type_ref_class (arg1)))
- return false;
- return true;
- }
-
default:
return false;
}
@@ -3420,6 +3421,27 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1,
return OP_SAME (0);
return false;
+ case OBJ_TYPE_REF:
+ /* Virtual table reference. */
+ if (!operand_equal_p (OBJ_TYPE_REF_EXPR (arg0),
+ OBJ_TYPE_REF_EXPR (arg1), flags))
+ return false;
+ flags &= ~OEP_ADDRESS_OF;
+ if (tree_to_uhwi (OBJ_TYPE_REF_TOKEN (arg0))
+ != tree_to_uhwi (OBJ_TYPE_REF_TOKEN (arg1)))
+ return false;
+ if (!operand_equal_p (OBJ_TYPE_REF_OBJECT (arg0),
+ OBJ_TYPE_REF_OBJECT (arg1), flags))
+ return false;
+ if (virtual_method_call_p (arg0))
+ {
+ if (!virtual_method_call_p (arg1))
+ return false;
+ return types_same_for_odr (obj_type_ref_class (arg0),
+ obj_type_ref_class (arg1));
+ }
+ return false;
+
default:
return false;
}
@@ -3787,9 +3809,26 @@ operand_compare::hash_operand (const_tree t, inchash::hash &hstate,
sflags = flags;
break;
+ case COMPONENT_REF:
+ if (sflags & OEP_ADDRESS_OF)
+ {
+ hash_operand (TREE_OPERAND (t, 0), hstate, flags);
+ if (TREE_OPERAND (t, 2))
+ hash_operand (TREE_OPERAND (t, 2), hstate,
+ flags & ~OEP_ADDRESS_OF);
+ else
+ {
+ tree field = TREE_OPERAND (t, 1);
+ hash_operand (DECL_FIELD_OFFSET (field),
+ hstate, flags & ~OEP_ADDRESS_OF);
+ hash_operand (DECL_FIELD_BIT_OFFSET (field),
+ hstate, flags & ~OEP_ADDRESS_OF);
+ }
+ return;
+ }
+ break;
case ARRAY_REF:
case ARRAY_RANGE_REF:
- case COMPONENT_REF:
case BIT_FIELD_REF:
sflags &= ~OEP_ADDRESS_OF;
break;
@@ -3822,11 +3861,25 @@ operand_compare::hash_operand (const_tree t, inchash::hash &hstate,
hash_operand (TARGET_EXPR_SLOT (t), hstate, flags);
return;
- /* Virtual table call. */
case OBJ_TYPE_REF:
+ /* Virtual table reference. */
inchash::add_expr (OBJ_TYPE_REF_EXPR (t), hstate, flags);
+ flags &= ~OEP_ADDRESS_OF;
inchash::add_expr (OBJ_TYPE_REF_TOKEN (t), hstate, flags);
inchash::add_expr (OBJ_TYPE_REF_OBJECT (t), hstate, flags);
+ if (!virtual_method_call_p (t))
+ return;
+ if (tree c = obj_type_ref_class (t))
+ {
+ c = TYPE_NAME (TYPE_MAIN_VARIANT (c));
+ /* We compute mangled names only when free_lang_data is run.
+ In that case we can hash precisely. */
+ if (TREE_CODE (c) == TYPE_DECL
+ && DECL_ASSEMBLER_NAME_SET_P (c))
+ hstate.add_object
+ (IDENTIFIER_HASH_VALUE
+ (DECL_ASSEMBLER_NAME (c)));
+ }
return;
default:
break;
@@ -7915,25 +7968,78 @@ native_encode_expr (const_tree expr, unsigned char *ptr, int len, int off)
}
}
+/* Try to find a type whose byte size is smaller or equal to LEN bytes larger
+ or equal to FIELDSIZE bytes, with underlying mode precision/size multiple
+ of BITS_PER_UNIT. As native_{interpret,encode}_int works in term of
+ machine modes, we can't just use build_nonstandard_integer_type. */
+
+tree
+find_bitfield_repr_type (int fieldsize, int len)
+{
+ machine_mode mode;
+ for (int pass = 0; pass < 2; pass++)
+ {
+ enum mode_class mclass = pass ? MODE_PARTIAL_INT : MODE_INT;
+ FOR_EACH_MODE_IN_CLASS (mode, mclass)
+ if (known_ge (GET_MODE_SIZE (mode), fieldsize)
+ && known_eq (GET_MODE_PRECISION (mode),
+ GET_MODE_BITSIZE (mode))
+ && known_le (GET_MODE_SIZE (mode), len))
+ {
+ tree ret = lang_hooks.types.type_for_mode (mode, 1);
+ if (ret && TYPE_MODE (ret) == mode)
+ return ret;
+ }
+ }
+
+ for (int i = 0; i < NUM_INT_N_ENTS; i ++)
+ if (int_n_enabled_p[i]
+ && int_n_data[i].bitsize >= (unsigned) (BITS_PER_UNIT * fieldsize)
+ && int_n_trees[i].unsigned_type)
+ {
+ tree ret = int_n_trees[i].unsigned_type;
+ mode = TYPE_MODE (ret);
+ if (known_ge (GET_MODE_SIZE (mode), fieldsize)
+ && known_eq (GET_MODE_PRECISION (mode),
+ GET_MODE_BITSIZE (mode))
+ && known_le (GET_MODE_SIZE (mode), len))
+ return ret;
+ }
+
+ return NULL_TREE;
+}
+
/* Similar to native_encode_expr, but also handle CONSTRUCTORs, VCEs,
- NON_LVALUE_EXPRs and nops. */
+ NON_LVALUE_EXPRs and nops. If MASK is non-NULL (then PTR has
+ to be non-NULL and OFF zero), then in addition to filling the
+ bytes pointed by PTR with the value also clear any bits pointed
+ by MASK that are known to be initialized, keep them as is for
+ e.g. uninitialized padding bits or uninitialized fields. */
int
native_encode_initializer (tree init, unsigned char *ptr, int len,
- int off)
+ int off, unsigned char *mask)
{
+ int r;
+
/* We don't support starting at negative offset and -1 is special. */
if (off < -1 || init == NULL_TREE)
return 0;
+ gcc_assert (mask == NULL || (off == 0 && ptr));
+
STRIP_NOPS (init);
switch (TREE_CODE (init))
{
case VIEW_CONVERT_EXPR:
case NON_LVALUE_EXPR:
- return native_encode_initializer (TREE_OPERAND (init, 0), ptr, len, off);
+ return native_encode_initializer (TREE_OPERAND (init, 0), ptr, len, off,
+ mask);
default:
- return native_encode_expr (init, ptr, len, off);
+ r = native_encode_expr (init, ptr, len, off);
+ if (mask)
+ memset (mask, 0, r);
+ return r;
case CONSTRUCTOR:
tree type = TREE_TYPE (init);
HOST_WIDE_INT total_bytes = int_size_in_bytes (type);
@@ -7946,7 +8052,7 @@ native_encode_initializer (tree init, unsigned char *ptr, int len,
{
HOST_WIDE_INT min_index;
unsigned HOST_WIDE_INT cnt;
- HOST_WIDE_INT curpos = 0, fieldsize;
+ HOST_WIDE_INT curpos = 0, fieldsize, valueinit = -1;
constructor_elt *ce;
if (TYPE_DOMAIN (type) == NULL_TREE
@@ -7961,12 +8067,22 @@ native_encode_initializer (tree init, unsigned char *ptr, int len,
if (ptr != NULL)
memset (ptr, '\0', MIN (total_bytes - off, len));
- FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (init), cnt, ce)
+ for (cnt = 0; ; cnt++)
{
- tree val = ce->value;
- tree index = ce->index;
+ tree val = NULL_TREE, index = NULL_TREE;
HOST_WIDE_INT pos = curpos, count = 0;
bool full = false;
+ if (vec_safe_iterate (CONSTRUCTOR_ELTS (init), cnt, &ce))
+ {
+ val = ce->value;
+ index = ce->index;
+ }
+ else if (mask == NULL
+ || CONSTRUCTOR_NO_CLEARING (init)
+ || curpos >= total_bytes)
+ break;
+ else
+ pos = total_bytes;
if (index && TREE_CODE (index) == RANGE_EXPR)
{
if (!tree_fits_shwi_p (TREE_OPERAND (index, 0))
@@ -7984,6 +8100,28 @@ native_encode_initializer (tree init, unsigned char *ptr, int len,
pos = (tree_to_shwi (index) - min_index) * fieldsize;
}
+ if (mask && !CONSTRUCTOR_NO_CLEARING (init) && curpos != pos)
+ {
+ if (valueinit == -1)
+ {
+ tree zero = build_constructor (TREE_TYPE (type), NULL);
+ r = native_encode_initializer (zero, ptr + curpos,
+ fieldsize, 0,
+ mask + curpos);
+ ggc_free (zero);
+ if (!r)
+ return 0;
+ valueinit = curpos;
+ curpos += fieldsize;
+ }
+ while (curpos != pos)
+ {
+ memcpy (ptr + curpos, ptr + valueinit, fieldsize);
+ memcpy (mask + curpos, mask + valueinit, fieldsize);
+ curpos += fieldsize;
+ }
+ }
+
curpos = pos;
if (val)
do
@@ -7998,6 +8136,8 @@ native_encode_initializer (tree init, unsigned char *ptr, int len,
if (ptr)
memcpy (ptr + (curpos - o), ptr + (pos - o),
fieldsize);
+ if (mask)
+ memcpy (mask + curpos, mask + pos, fieldsize);
}
else if (!native_encode_initializer (val,
ptr
@@ -8005,7 +8145,10 @@ native_encode_initializer (tree init, unsigned char *ptr, int len,
: NULL,
fieldsize,
off == -1 ? -1
- : 0))
+ : 0,
+ mask
+ ? mask + curpos
+ : NULL))
return 0;
else
{
@@ -8020,6 +8163,7 @@ native_encode_initializer (tree init, unsigned char *ptr, int len,
unsigned char *p = NULL;
int no = 0;
int l;
+ gcc_assert (mask == NULL);
if (curpos >= off)
{
if (ptr)
@@ -8033,7 +8177,7 @@ native_encode_initializer (tree init, unsigned char *ptr, int len,
no = off - curpos;
l = len;
}
- if (!native_encode_initializer (val, p, l, no))
+ if (!native_encode_initializer (val, p, l, no, NULL))
return 0;
}
curpos += fieldsize;
@@ -8047,22 +8191,74 @@ native_encode_initializer (tree init, unsigned char *ptr, int len,
{
unsigned HOST_WIDE_INT cnt;
constructor_elt *ce;
+ tree fld_base = TYPE_FIELDS (type);
+ tree to_free = NULL_TREE;
+ gcc_assert (TREE_CODE (type) == RECORD_TYPE || mask == NULL);
if (ptr != NULL)
memset (ptr, '\0', MIN (total_bytes - off, len));
- FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (init), cnt, ce)
+ for (cnt = 0; ; cnt++)
{
- tree field = ce->index;
- tree val = ce->value;
- HOST_WIDE_INT pos, fieldsize;
+ tree val = NULL_TREE, field = NULL_TREE;
+ HOST_WIDE_INT pos = 0, fieldsize;
unsigned HOST_WIDE_INT bpos = 0, epos = 0;
- if (field == NULL_TREE)
- return 0;
+ if (to_free)
+ {
+ ggc_free (to_free);
+ to_free = NULL_TREE;
+ }
- pos = int_byte_position (field);
- if (off != -1 && (HOST_WIDE_INT) off + len <= pos)
- continue;
+ if (vec_safe_iterate (CONSTRUCTOR_ELTS (init), cnt, &ce))
+ {
+ val = ce->value;
+ field = ce->index;
+ if (field == NULL_TREE)
+ return 0;
+
+ pos = int_byte_position (field);
+ if (off != -1 && (HOST_WIDE_INT) off + len <= pos)
+ continue;
+ }
+ else if (mask == NULL
+ || CONSTRUCTOR_NO_CLEARING (init))
+ break;
+ else
+ pos = total_bytes;
+
+ if (mask && !CONSTRUCTOR_NO_CLEARING (init))
+ {
+ tree fld;
+ for (fld = fld_base; fld; fld = DECL_CHAIN (fld))
+ {
+ if (TREE_CODE (fld) != FIELD_DECL)
+ continue;
+ if (fld == field)
+ break;
+ if (DECL_PADDING_P (fld))
+ continue;
+ if (DECL_SIZE_UNIT (fld) == NULL_TREE
+ || !tree_fits_shwi_p (DECL_SIZE_UNIT (fld)))
+ return 0;
+ if (integer_zerop (DECL_SIZE_UNIT (fld)))
+ continue;
+ break;
+ }
+ if (fld == NULL_TREE)
+ {
+ if (ce == NULL)
+ break;
+ return 0;
+ }
+ fld_base = DECL_CHAIN (fld);
+ if (fld != field)
+ {
+ cnt--;
+ field = fld;
+ val = build_constructor (TREE_TYPE (fld), NULL);
+ to_free = val;
+ }
+ }
if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
&& TYPE_DOMAIN (TREE_TYPE (field))
@@ -8103,30 +8299,49 @@ native_encode_initializer (tree init, unsigned char *ptr, int len,
if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
return 0;
- tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
- if (repr == NULL_TREE
- || TREE_CODE (val) != INTEGER_CST
- || !INTEGRAL_TYPE_P (TREE_TYPE (repr)))
+ if (TREE_CODE (val) != INTEGER_CST)
return 0;
- HOST_WIDE_INT rpos = int_byte_position (repr);
+ tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
+ tree repr_type = NULL_TREE;
+ HOST_WIDE_INT rpos = 0;
+ if (repr && INTEGRAL_TYPE_P (TREE_TYPE (repr)))
+ {
+ rpos = int_byte_position (repr);
+ repr_type = TREE_TYPE (repr);
+ }
+ else
+ {
+ repr_type = find_bitfield_repr_type (fieldsize, len);
+ if (repr_type == NULL_TREE)
+ return 0;
+ HOST_WIDE_INT repr_size = int_size_in_bytes (repr_type);
+ gcc_assert (repr_size > 0 && repr_size <= len);
+ if (pos + repr_size <= len)
+ rpos = pos;
+ else
+ {
+ rpos = len - repr_size;
+ gcc_assert (rpos <= pos);
+ }
+ }
+
if (rpos > pos)
return 0;
- wide_int w = wi::to_wide (val,
- TYPE_PRECISION (TREE_TYPE (repr)));
- int diff = (TYPE_PRECISION (TREE_TYPE (repr))
+ wide_int w = wi::to_wide (val, TYPE_PRECISION (repr_type));
+ int diff = (TYPE_PRECISION (repr_type)
- TYPE_PRECISION (TREE_TYPE (field)));
HOST_WIDE_INT bitoff = (pos - rpos) * BITS_PER_UNIT + bpos;
if (!BYTES_BIG_ENDIAN)
w = wi::lshift (w, bitoff);
else
w = wi::lshift (w, diff - bitoff);
- val = wide_int_to_tree (TREE_TYPE (repr), w);
+ val = wide_int_to_tree (repr_type, w);
unsigned char buf[MAX_BITSIZE_MODE_ANY_INT
/ BITS_PER_UNIT + 1];
int l = native_encode_int (val, buf, sizeof buf, 0);
- if (l * BITS_PER_UNIT != TYPE_PRECISION (TREE_TYPE (repr)))
+ if (l * BITS_PER_UNIT != TYPE_PRECISION (repr_type))
return 0;
if (ptr == NULL)
@@ -8139,15 +8354,31 @@ native_encode_initializer (tree init, unsigned char *ptr, int len,
{
if (!BYTES_BIG_ENDIAN)
{
- int mask = (1 << bpos) - 1;
- buf[pos - rpos] &= ~mask;
- buf[pos - rpos] |= ptr[pos - o] & mask;
+ int msk = (1 << bpos) - 1;
+ buf[pos - rpos] &= ~msk;
+ buf[pos - rpos] |= ptr[pos - o] & msk;
+ if (mask)
+ {
+ if (fieldsize > 1 || epos == 0)
+ mask[pos] &= msk;
+ else
+ mask[pos] &= (msk | ~((1 << epos) - 1));
+ }
}
else
{
- int mask = (1 << (BITS_PER_UNIT - bpos)) - 1;
- buf[pos - rpos] &= mask;
- buf[pos - rpos] |= ptr[pos - o] & ~mask;
+ int msk = (1 << (BITS_PER_UNIT - bpos)) - 1;
+ buf[pos - rpos] &= msk;
+ buf[pos - rpos] |= ptr[pos - o] & ~msk;
+ if (mask)
+ {
+ if (fieldsize > 1 || epos == 0)
+ mask[pos] &= ~msk;
+ else
+ mask[pos] &= (~msk
+ | ((1 << (BITS_PER_UNIT - epos))
+ - 1));
+ }
}
}
/* If the bitfield does not end at byte boundary, handle
@@ -8158,27 +8389,37 @@ native_encode_initializer (tree init, unsigned char *ptr, int len,
{
if (!BYTES_BIG_ENDIAN)
{
- int mask = (1 << epos) - 1;
- buf[pos - rpos + fieldsize - 1] &= mask;
+ int msk = (1 << epos) - 1;
+ buf[pos - rpos + fieldsize - 1] &= msk;
buf[pos - rpos + fieldsize - 1]
- |= ptr[pos + fieldsize - 1 - o] & ~mask;
+ |= ptr[pos + fieldsize - 1 - o] & ~msk;
+ if (mask && (fieldsize > 1 || bpos == 0))
+ mask[pos + fieldsize - 1] &= ~msk;
}
else
{
- int mask = (1 << (BITS_PER_UNIT - epos)) - 1;
- buf[pos - rpos + fieldsize - 1] &= ~mask;
+ int msk = (1 << (BITS_PER_UNIT - epos)) - 1;
+ buf[pos - rpos + fieldsize - 1] &= ~msk;
buf[pos - rpos + fieldsize - 1]
- |= ptr[pos + fieldsize - 1 - o] & mask;
+ |= ptr[pos + fieldsize - 1 - o] & msk;
+ if (mask && (fieldsize > 1 || bpos == 0))
+ mask[pos + fieldsize - 1] &= msk;
}
}
if (off == -1
|| (pos >= off
&& (pos + fieldsize <= (HOST_WIDE_INT) off + len)))
- memcpy (ptr + pos - o, buf + (pos - rpos), fieldsize);
+ {
+ memcpy (ptr + pos - o, buf + (pos - rpos), fieldsize);
+ if (mask && (fieldsize > (bpos != 0) + (epos != 0)))
+ memset (mask + pos + (bpos != 0), 0,
+ fieldsize - (bpos != 0) - (epos != 0));
+ }
else
{
/* Partial overlap. */
HOST_WIDE_INT fsz = fieldsize;
+ gcc_assert (mask == NULL);
if (pos < off)
{
fsz -= (off - pos);
@@ -8198,7 +8439,8 @@ native_encode_initializer (tree init, unsigned char *ptr, int len,
if (!native_encode_initializer (val, ptr ? ptr + pos - o
: NULL,
fieldsize,
- off == -1 ? -1 : 0))
+ off == -1 ? -1 : 0,
+ mask ? mask + pos : NULL))
return 0;
}
else
@@ -8207,6 +8449,7 @@ native_encode_initializer (tree init, unsigned char *ptr, int len,
unsigned char *p = NULL;
int no = 0;
int l;
+ gcc_assert (mask == NULL);
if (pos >= off)
{
if (ptr)
@@ -8220,7 +8463,7 @@ native_encode_initializer (tree init, unsigned char *ptr, int len,
no = off - pos;
l = len;
}
- if (!native_encode_initializer (val, p, l, no))
+ if (!native_encode_initializer (val, p, l, no, NULL))
return 0;
}
}
@@ -8496,6 +8739,168 @@ can_native_interpret_type_p (tree type)
}
}
+/* Attempt to interpret aggregate of TYPE from bytes encoded in target
+ byte order at PTR + OFF with LEN bytes. Does not handle unions. */
+
+tree
+native_interpret_aggregate (tree type, const unsigned char *ptr, int off,
+ int len)
+{
+ vec<constructor_elt, va_gc> *elts = NULL;
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ HOST_WIDE_INT eltsz = int_size_in_bytes (TREE_TYPE (type));
+ if (eltsz < 0 || eltsz > len || TYPE_DOMAIN (type) == NULL_TREE)
+ return NULL_TREE;
+
+ HOST_WIDE_INT cnt = 0;
+ if (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
+ {
+ if (!tree_fits_shwi_p (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
+ return NULL_TREE;
+ cnt = tree_to_shwi (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1;
+ }
+ if (eltsz == 0)
+ cnt = 0;
+ HOST_WIDE_INT pos = 0;
+ for (HOST_WIDE_INT i = 0; i < cnt; i++, pos += eltsz)
+ {
+ tree v = NULL_TREE;
+ if (pos >= len || pos + eltsz > len)
+ return NULL_TREE;
+ if (can_native_interpret_type_p (TREE_TYPE (type)))
+ {
+ v = native_interpret_expr (TREE_TYPE (type),
+ ptr + off + pos, eltsz);
+ if (v == NULL_TREE)
+ return NULL_TREE;
+ }
+ else if (TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE
+ || TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
+ v = native_interpret_aggregate (TREE_TYPE (type), ptr, off + pos,
+ eltsz);
+ if (v == NULL_TREE)
+ return NULL_TREE;
+ CONSTRUCTOR_APPEND_ELT (elts, size_int (i), v);
+ }
+ return build_constructor (type, elts);
+ }
+ if (TREE_CODE (type) != RECORD_TYPE)
+ return NULL_TREE;
+ for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ {
+ if (TREE_CODE (field) != FIELD_DECL || DECL_PADDING_P (field))
+ continue;
+ tree fld = field;
+ HOST_WIDE_INT bitoff = 0, pos = 0, sz = 0;
+ int diff = 0;
+ tree v = NULL_TREE;
+ if (DECL_BIT_FIELD (field))
+ {
+ fld = DECL_BIT_FIELD_REPRESENTATIVE (field);
+ if (fld && INTEGRAL_TYPE_P (TREE_TYPE (fld)))
+ {
+ poly_int64 bitoffset;
+ poly_uint64 field_offset, fld_offset;
+ if (poly_int_tree_p (DECL_FIELD_OFFSET (field), &field_offset)
+ && poly_int_tree_p (DECL_FIELD_OFFSET (fld), &fld_offset))
+ bitoffset = (field_offset - fld_offset) * BITS_PER_UNIT;
+ else
+ bitoffset = 0;
+ bitoffset += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
+ - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (fld)));
+ diff = (TYPE_PRECISION (TREE_TYPE (fld))
+ - TYPE_PRECISION (TREE_TYPE (field)));
+ if (!bitoffset.is_constant (&bitoff)
+ || bitoff < 0
+ || bitoff > diff)
+ return NULL_TREE;
+ }
+ else
+ {
+ if (!tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (field)))
+ return NULL_TREE;
+ int fieldsize = TYPE_PRECISION (TREE_TYPE (field));
+ int bpos = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field));
+ bpos %= BITS_PER_UNIT;
+ fieldsize += bpos;
+ fieldsize += BITS_PER_UNIT - 1;
+ fieldsize /= BITS_PER_UNIT;
+ tree repr_type = find_bitfield_repr_type (fieldsize, len);
+ if (repr_type == NULL_TREE)
+ return NULL_TREE;
+ sz = int_size_in_bytes (repr_type);
+ if (sz < 0 || sz > len)
+ return NULL_TREE;
+ pos = int_byte_position (field);
+ if (pos < 0 || pos > len || pos + fieldsize > len)
+ return NULL_TREE;
+ HOST_WIDE_INT rpos;
+ if (pos + sz <= len)
+ rpos = pos;
+ else
+ {
+ rpos = len - sz;
+ gcc_assert (rpos <= pos);
+ }
+ bitoff = (HOST_WIDE_INT) (pos - rpos) * BITS_PER_UNIT + bpos;
+ pos = rpos;
+ diff = (TYPE_PRECISION (repr_type)
+ - TYPE_PRECISION (TREE_TYPE (field)));
+ v = native_interpret_expr (repr_type, ptr + off + pos, sz);
+ if (v == NULL_TREE)
+ return NULL_TREE;
+ fld = NULL_TREE;
+ }
+ }
+
+ if (fld)
+ {
+ sz = int_size_in_bytes (TREE_TYPE (fld));
+ if (sz < 0 || sz > len)
+ return NULL_TREE;
+ tree byte_pos = byte_position (fld);
+ if (!tree_fits_shwi_p (byte_pos))
+ return NULL_TREE;
+ pos = tree_to_shwi (byte_pos);
+ if (pos < 0 || pos > len || pos + sz > len)
+ return NULL_TREE;
+ }
+ if (fld == NULL_TREE)
+ /* Already handled above. */;
+ else if (can_native_interpret_type_p (TREE_TYPE (fld)))
+ {
+ v = native_interpret_expr (TREE_TYPE (fld),
+ ptr + off + pos, sz);
+ if (v == NULL_TREE)
+ return NULL_TREE;
+ }
+ else if (TREE_CODE (TREE_TYPE (fld)) == RECORD_TYPE
+ || TREE_CODE (TREE_TYPE (fld)) == ARRAY_TYPE)
+ v = native_interpret_aggregate (TREE_TYPE (fld), ptr, off + pos, sz);
+ if (v == NULL_TREE)
+ return NULL_TREE;
+ if (fld != field)
+ {
+ if (TREE_CODE (v) != INTEGER_CST)
+ return NULL_TREE;
+
+ /* FIXME: Figure out how to handle PDP endian bitfields. */
+ if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
+ return NULL_TREE;
+ if (!BYTES_BIG_ENDIAN)
+ v = wide_int_to_tree (TREE_TYPE (field),
+ wi::lrshift (wi::to_wide (v), bitoff));
+ else
+ v = wide_int_to_tree (TREE_TYPE (field),
+ wi::lrshift (wi::to_wide (v),
+ diff - bitoff));
+ }
+ CONSTRUCTOR_APPEND_ELT (elts, field, v);
+ }
+ return build_constructor (type, elts);
+}
+
/* Routines for manipulation of native_encode_expr encoded data if the encoded
or extracted constant positions and/or sizes aren't byte aligned. */
@@ -13662,6 +14067,248 @@ multiple_of_p (tree type, const_tree top, const_tree bottom)
}
}
+/* Return true if expression X cannot be (or contain) a NaN or infinity.
+ This function returns true for integer expressions, and returns
+ false if uncertain. */
+
+bool
+tree_expr_finite_p (const_tree x)
+{
+ machine_mode mode = element_mode (x);
+ if (!HONOR_NANS (mode) && !HONOR_INFINITIES (mode))
+ return true;
+ switch (TREE_CODE (x))
+ {
+ case REAL_CST:
+ return real_isfinite (TREE_REAL_CST_PTR (x));
+ case COMPLEX_CST:
+ return tree_expr_finite_p (TREE_REALPART (x))
+ && tree_expr_finite_p (TREE_IMAGPART (x));
+ case FLOAT_EXPR:
+ return true;
+ case ABS_EXPR:
+ case CONVERT_EXPR:
+ case NON_LVALUE_EXPR:
+ case NEGATE_EXPR:
+ case SAVE_EXPR:
+ return tree_expr_finite_p (TREE_OPERAND (x, 0));
+ case MIN_EXPR:
+ case MAX_EXPR:
+ return tree_expr_finite_p (TREE_OPERAND (x, 0))
+ && tree_expr_finite_p (TREE_OPERAND (x, 1));
+ case COND_EXPR:
+ return tree_expr_finite_p (TREE_OPERAND (x, 1))
+ && tree_expr_finite_p (TREE_OPERAND (x, 2));
+ case CALL_EXPR:
+ switch (get_call_combined_fn (x))
+ {
+ CASE_CFN_FABS:
+ return tree_expr_finite_p (CALL_EXPR_ARG (x, 0));
+ CASE_CFN_FMAX:
+ CASE_CFN_FMIN:
+ return tree_expr_finite_p (CALL_EXPR_ARG (x, 0))
+ && tree_expr_finite_p (CALL_EXPR_ARG (x, 1));
+ default:
+ return false;
+ }
+
+ default:
+ return false;
+ }
+}
+
+/* Return true if expression X evaluates to an infinity.
+ This function returns false for integer expressions. */
+
+bool
+tree_expr_infinite_p (const_tree x)
+{
+ if (!HONOR_INFINITIES (x))
+ return false;
+ switch (TREE_CODE (x))
+ {
+ case REAL_CST:
+ return real_isinf (TREE_REAL_CST_PTR (x));
+ case ABS_EXPR:
+ case NEGATE_EXPR:
+ case NON_LVALUE_EXPR:
+ case SAVE_EXPR:
+ return tree_expr_infinite_p (TREE_OPERAND (x, 0));
+ case COND_EXPR:
+ return tree_expr_infinite_p (TREE_OPERAND (x, 1))
+ && tree_expr_infinite_p (TREE_OPERAND (x, 2));
+ default:
+ return false;
+ }
+}
+
+/* Return true if expression X could evaluate to an infinity.
+ This function returns false for integer expressions, and returns
+ true if uncertain. */
+
+bool
+tree_expr_maybe_infinite_p (const_tree x)
+{
+ if (!HONOR_INFINITIES (x))
+ return false;
+ switch (TREE_CODE (x))
+ {
+ case REAL_CST:
+ return real_isinf (TREE_REAL_CST_PTR (x));
+ case FLOAT_EXPR:
+ return false;
+ case ABS_EXPR:
+ case NEGATE_EXPR:
+ return tree_expr_maybe_infinite_p (TREE_OPERAND (x, 0));
+ case COND_EXPR:
+ return tree_expr_maybe_infinite_p (TREE_OPERAND (x, 1))
+ || tree_expr_maybe_infinite_p (TREE_OPERAND (x, 2));
+ default:
+ return true;
+ }
+}
+
+/* Return true if expression X evaluates to a signaling NaN.
+ This function returns false for integer expressions. */
+
+bool
+tree_expr_signaling_nan_p (const_tree x)
+{
+ if (!HONOR_SNANS (x))
+ return false;
+ switch (TREE_CODE (x))
+ {
+ case REAL_CST:
+ return real_issignaling_nan (TREE_REAL_CST_PTR (x));
+ case NON_LVALUE_EXPR:
+ case SAVE_EXPR:
+ return tree_expr_signaling_nan_p (TREE_OPERAND (x, 0));
+ case COND_EXPR:
+ return tree_expr_signaling_nan_p (TREE_OPERAND (x, 1))
+ && tree_expr_signaling_nan_p (TREE_OPERAND (x, 2));
+ default:
+ return false;
+ }
+}
+
+/* Return true if expression X could evaluate to a signaling NaN.
+ This function returns false for integer expressions, and returns
+ true if uncertain. */
+
+bool
+tree_expr_maybe_signaling_nan_p (const_tree x)
+{
+ if (!HONOR_SNANS (x))
+ return false;
+ switch (TREE_CODE (x))
+ {
+ case REAL_CST:
+ return real_issignaling_nan (TREE_REAL_CST_PTR (x));
+ case FLOAT_EXPR:
+ return false;
+ case ABS_EXPR:
+ case CONVERT_EXPR:
+ case NEGATE_EXPR:
+ case NON_LVALUE_EXPR:
+ case SAVE_EXPR:
+ return tree_expr_maybe_signaling_nan_p (TREE_OPERAND (x, 0));
+ case MIN_EXPR:
+ case MAX_EXPR:
+ return tree_expr_maybe_signaling_nan_p (TREE_OPERAND (x, 0))
+ || tree_expr_maybe_signaling_nan_p (TREE_OPERAND (x, 1));
+ case COND_EXPR:
+ return tree_expr_maybe_signaling_nan_p (TREE_OPERAND (x, 1))
+ || tree_expr_maybe_signaling_nan_p (TREE_OPERAND (x, 2));
+ case CALL_EXPR:
+ switch (get_call_combined_fn (x))
+ {
+ CASE_CFN_FABS:
+ return tree_expr_maybe_signaling_nan_p (CALL_EXPR_ARG (x, 0));
+ CASE_CFN_FMAX:
+ CASE_CFN_FMIN:
+ return tree_expr_maybe_signaling_nan_p (CALL_EXPR_ARG (x, 0))
+ || tree_expr_maybe_signaling_nan_p (CALL_EXPR_ARG (x, 1));
+ default:
+ return true;
+ }
+ default:
+ return true;
+ }
+}
+
+/* Return true if expression X evaluates to a NaN.
+ This function returns false for integer expressions. */
+
+bool
+tree_expr_nan_p (const_tree x)
+{
+ if (!HONOR_NANS (x))
+ return false;
+ switch (TREE_CODE (x))
+ {
+ case REAL_CST:
+ return real_isnan (TREE_REAL_CST_PTR (x));
+ case NON_LVALUE_EXPR:
+ case SAVE_EXPR:
+ return tree_expr_nan_p (TREE_OPERAND (x, 0));
+ case COND_EXPR:
+ return tree_expr_nan_p (TREE_OPERAND (x, 1))
+ && tree_expr_nan_p (TREE_OPERAND (x, 2));
+ default:
+ return false;
+ }
+}
+
+/* Return true if expression X could evaluate to a NaN.
+ This function returns false for integer expressions, and returns
+ true if uncertain. */
+
+bool
+tree_expr_maybe_nan_p (const_tree x)
+{
+ if (!HONOR_NANS (x))
+ return false;
+ switch (TREE_CODE (x))
+ {
+ case REAL_CST:
+ return real_isnan (TREE_REAL_CST_PTR (x));
+ case FLOAT_EXPR:
+ return false;
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ return !tree_expr_finite_p (TREE_OPERAND (x, 0))
+ || !tree_expr_finite_p (TREE_OPERAND (x, 1));
+ case ABS_EXPR:
+ case CONVERT_EXPR:
+ case NEGATE_EXPR:
+ case NON_LVALUE_EXPR:
+ case SAVE_EXPR:
+ return tree_expr_maybe_nan_p (TREE_OPERAND (x, 0));
+ case MIN_EXPR:
+ case MAX_EXPR:
+ return tree_expr_maybe_nan_p (TREE_OPERAND (x, 0))
+ || tree_expr_maybe_nan_p (TREE_OPERAND (x, 1));
+ case COND_EXPR:
+ return tree_expr_maybe_nan_p (TREE_OPERAND (x, 1))
+ || tree_expr_maybe_nan_p (TREE_OPERAND (x, 2));
+ case CALL_EXPR:
+ switch (get_call_combined_fn (x))
+ {
+ CASE_CFN_FABS:
+ return tree_expr_maybe_nan_p (CALL_EXPR_ARG (x, 0));
+ CASE_CFN_FMAX:
+ CASE_CFN_FMIN:
+ return tree_expr_maybe_nan_p (CALL_EXPR_ARG (x, 0))
+ || tree_expr_maybe_nan_p (CALL_EXPR_ARG (x, 1));
+ default:
+ return true;
+ }
+ default:
+ return true;
+ }
+}
+
#define tree_expr_nonnegative_warnv_p(X, Y) \
_Pragma ("GCC error \"Use RECURSE for recursive calls\"") 0
@@ -13839,7 +14486,13 @@ tree_binary_nonnegative_warnv_p (enum tree_code code, tree type, tree op0,
return false;
case BIT_AND_EXPR:
+ return RECURSE (op0) || RECURSE (op1);
+
case MAX_EXPR:
+ /* Usually RECURSE (op0) || RECURSE (op1) but NaNs complicate
+ things. */
+ if (tree_expr_maybe_nan_p (op0) || tree_expr_maybe_nan_p (op1))
+ return RECURSE (op0) && RECURSE (op1);
return RECURSE (op0) || RECURSE (op1);
case BIT_IOR_EXPR:
@@ -13999,8 +14652,18 @@ tree_call_nonnegative_warnv_p (tree type, combined_fn fn, tree arg0, tree arg1,
CASE_CFN_FMAX:
CASE_CFN_FMAX_FN:
- /* True if the 1st OR 2nd arguments are nonnegative. */
- return RECURSE (arg0) || RECURSE (arg1);
+ /* Usually RECURSE (arg0) || RECURSE (arg1) but NaNs complicate
+ things. In the presence of sNaNs, we're only guaranteed to be
+ non-negative if both operands are non-negative. In the presence
+ of qNaNs, we're non-negative if either operand is non-negative
+ and can't be a qNaN, or if both operands are non-negative. */
+ if (tree_expr_maybe_signaling_nan_p (arg0) ||
+ tree_expr_maybe_signaling_nan_p (arg1))
+ return RECURSE (arg0) && RECURSE (arg1);
+ return RECURSE (arg0) ? (!tree_expr_maybe_nan_p (arg0)
+ || RECURSE (arg1))
+ : (RECURSE (arg1)
+ && !tree_expr_maybe_nan_p (arg1));
CASE_CFN_FMIN:
CASE_CFN_FMIN_FN:
diff --git a/gcc/fold-const.h b/gcc/fold-const.h
index 0c0f5fd..818c3d5 100644
--- a/gcc/fold-const.h
+++ b/gcc/fold-const.h
@@ -27,9 +27,11 @@ extern int folding_initializer;
/* Convert between trees and native memory representation. */
extern int native_encode_expr (const_tree, unsigned char *, int, int off = -1);
extern int native_encode_initializer (tree, unsigned char *, int,
- int off = -1);
+ int off = -1, unsigned char * = nullptr);
extern tree native_interpret_expr (tree, const unsigned char *, int);
extern bool can_native_interpret_type_p (tree);
+extern tree native_interpret_aggregate (tree, const unsigned char *, int, int);
+extern tree find_bitfield_repr_type (int, int);
extern void shift_bytes_in_array_left (unsigned char *, unsigned int,
unsigned int);
extern void shift_bytes_in_array_right (unsigned char *, unsigned int,
@@ -186,6 +188,13 @@ extern tree non_lvalue_loc (location_t, tree);
extern bool tree_expr_nonzero_p (tree);
extern bool tree_expr_nonnegative_p (tree);
extern bool tree_expr_nonnegative_warnv_p (tree, bool *, int = 0);
+extern bool tree_expr_finite_p (const_tree);
+extern bool tree_expr_infinite_p (const_tree);
+extern bool tree_expr_maybe_infinite_p (const_tree);
+extern bool tree_expr_signaling_nan_p (const_tree);
+extern bool tree_expr_maybe_signaling_nan_p (const_tree);
+extern bool tree_expr_nan_p (const_tree);
+extern bool tree_expr_maybe_nan_p (const_tree);
extern tree make_range (tree, int *, tree *, tree *, bool *);
extern tree make_range_step (location_t, enum tree_code, tree, tree, tree,
tree *, tree *, int *, bool *);
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index f5c6066..a8e8bbb 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,138 @@
+2020-11-30 Tobias Burnus <tobias@codesourcery.com>
+
+ PR fortran/98011
+ * scanner.c (skip_free_comments, skip_fixed_comments): If only
+ -fopenacc but not -fopenmp is used, ignore OpenMP's conditional
+ compilation sentinels. Fix indentation, use 'else if' for readability.
+
+2020-11-30 Tobias Burnus <tobias@codesourcery.com>
+
+ PR fortran/98010
+ PR fortran/98013
+ * options.c (gfc_post_options): Also imply recursive with
+ -fopenacc.
+ * trans-decl.c (gfc_generate_function_code): Simplify condition.
+
+2020-11-30 Tobias Burnus <tobias@codesourcery.com>
+
+ * dump-parse-tree.c (show_expr): Use '==' not '=' for '.eq.'.
+
+2020-11-29 Harald Anlauf <anlauf@gmx.de>
+
+ * expr.c (simplify_parameter_variable): Fix up character length
+ after copying an array-valued expression.
+
+2020-11-28 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/97454
+ * trans-decl.c (gfc_get_extern_function_decl): Add argument
+ fnspec.
+ * trans-intrinsic.c (MAX_SPEC_ARG): Define.
+ (intrinsic_fnspec): New function.
+ (ADD_CHAR): Define.
+ (specific_intrinsic_symbol): Adjust comment. Pass
+ fn spec to gfc_get_extern_function_decl.
+ (gfc_conv_intrinsic_funcall): Add ANY, ALL, NORM2, PRODUCT
+ and SUM intrnisic. Add FIXME for cshift et al.
+ * trans-types.c (gfc_get_function_type): Add fnspec argument,
+ handle it.
+ * trans-types.h (gfc_get_function_type): Add optinal fnspec
+ argument.
+ * trans.h (gfc_get_extern_function_decl): Likewise.
+
+2020-11-25 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/85796
+ * resolve.c (traverse_data_list): Fix copy&paste errors; catch
+ step=0 in implied do loop.
+
+2020-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/97911
+ * Make-lang.in (fortran.serial): Change from goal to a variable.
+ (.PHONY): Drop fortran.serial and fortran.prev.
+ (f951$(exeext)): Depend on $(fortran.serial) rather than
+ fortran.serial.
+
+2020-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ * Make-lang.in (fortran.serial): New goal.
+ (.PHONY): Add fortran.serial fortran.prev.
+ (f951$(exeext)): Depend on fortran.prev. Call LINK_PROGRESS.
+
+2020-11-17 Harald Anlauf <anlauf@gmx.de>
+
+ * gfortran.texi: Fix description of GFC_RTCHECK_* to match actual
+ code.
+
+2020-11-16 Harald Anlauf <anlauf@gmx.de>
+
+ * trans-intrinsic.c (gfc_conv_intrinsic_size): Generate runtime
+ checking code for status of argument.
+
+2020-11-13 Gergö Barany <gergo@codesourcery.com>
+ Thomas Schwinge <thomas@codesourcery.com>
+
+ * lang.opt (fopenacc-kernels): Add.
+
+2020-11-12 Jakub Jelinek <jakub@redhat.com>
+
+ * f95-lang.c (ATTR_ALLOC_WARN_UNUSED_RESULT_SIZE_2_NOTHROW_LIST):
+ Define.
+ (gfc_init_builtin_functions): Add alloc_size and warn_unused_result
+ attributes to __builtin_GOMP_alloc.
+ * types.def (BT_PTRMODE): New primitive type.
+ (BT_FN_VOID_PTR_PTRMODE, BT_FN_PTR_SIZE_SIZE_PTRMODE): New function
+ types.
+
+2020-11-12 Tobias Burnus <tobias@codesourcery.com>
+
+ PR fortran/97782
+ * trans-openmp.c (gfc_trans_oacc_construct, gfc_trans_omp_parallel_do,
+ gfc_trans_omp_parallel_do_simd, gfc_trans_omp_parallel_sections,
+ gfc_trans_omp_parallel_workshare, gfc_trans_omp_sections
+ gfc_trans_omp_single, gfc_trans_omp_task, gfc_trans_omp_teams
+ gfc_trans_omp_target, gfc_trans_omp_target_data,
+ gfc_trans_omp_workshare): Use code->loc instead of input_location
+ when building the OMP_/OACC_ construct.
+
+2020-11-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/97768
+ * misc.c (gfc_typename): Use ex->value.character.length only if
+ ex->expr_type == EXPR_CONSTANT. If ex->ts.deferred, print : instead
+ of length. If ex->ts.u.cl && ex->ts.u.cl->length == NULL, print *
+ instead of length. Otherwise if character length is non-constant,
+ print just CHARACTER or CHARACTER(KIND=N).
+
+2020-11-10 Tobias Burnus <tobias@codesourcery.com>
+
+ * dump-parse-tree.c (show_omp_clauses): Handle new reduction enums.
+ * gfortran.h (OMP_LIST_REDUCTION_INSCAN, OMP_LIST_REDUCTION_TASK,
+ OMP_LIST_IN_REDUCTION, OMP_LIST_TASK_REDUCTION): Add enums.
+ * openmp.c (enum omp_mask1): Add OMP_CLAUSE_IN_REDUCTION
+ and OMP_CLAUSE_TASK_REDUCTION.
+ (gfc_match_omp_clause_reduction): Extend reduction handling;
+ moved from ...
+ (gfc_match_omp_clauses): ... here. Add calls to it.
+ (OMP_TASK_CLAUSES, OMP_TARGET_CLAUSES, OMP_TASKLOOP_CLAUSES):
+ Add OMP_CLAUSE_IN_REDUCTION.
+ (gfc_match_omp_taskgroup): Add task_reduction matching.
+ (resolve_omp_clauses): Update for new reduction clause changes;
+ remove removed nonmonotonic-schedule restrictions.
+ (gfc_resolve_omp_parallel_blocks): Add new enums to switch.
+ * trans-openmp.c (gfc_omp_clause_default_ctor,
+ gfc_trans_omp_reduction_list, gfc_trans_omp_clauses,
+ gfc_split_omp_clauses): Handle updated reduction clause.
+
+2020-11-10 Tobias Burnus <tobias@codesourcery.com>
+
+ PR fortran/95847
+ * trans-decl.c (gfc_get_symbol_decl): Do not (re)set the location
+ of an external procedure.
+ (build_entry_thunks, generate_coarray_init, create_main_function,
+ gfc_generate_function_code): Use fndecl's location in BIND_EXPR.
+
2020-11-09 Tobias Burnus <tobias@codesourcery.com>
PR fortran/90111
diff --git a/gcc/fortran/Make-lang.in b/gcc/fortran/Make-lang.in
index 977db60..4afd874 100644
--- a/gcc/fortran/Make-lang.in
+++ b/gcc/fortran/Make-lang.in
@@ -72,6 +72,7 @@ fortran_OBJS = $(F95_OBJS) fortran/gfortranspec.o
#
# Define the names for selecting gfortran in LANGUAGES.
fortran: f951$(exeext)
+fortran.serial = f951$(exeext)
# Tell GNU make to ignore files by these names if they exist.
.PHONY: fortran
@@ -92,11 +93,12 @@ gfortran-cross$(exeext): gfortran$(exeext)
cp gfortran$(exeext) gfortran-cross$(exeext)
# The compiler itself is called f951.
-f951$(exeext): $(F95_OBJS) \
- $(BACKEND) $(LIBDEPS) attribs.o
+f951$(exeext): $(F95_OBJS) $(BACKEND) $(LIBDEPS) attribs.o $(fortran.prev)
+ @$(call LINK_PROGRESS,$(INDEX.fortran),start)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(F95_OBJS) $(BACKEND) $(ZLIB) $(LIBS) attribs.o \
$(BACKENDLIBS)
+ @$(call LINK_PROGRESS,$(INDEX.fortran),end)
gt-fortran-trans.h : s-gtype; @true
#
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 93a155c..c85ae0d 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -7408,6 +7408,7 @@ gfc_match_function_decl (void)
procedure interface body. */
if (sym->attr.is_bind_c && sym->attr.module_procedure && sym->old_symbol
&& strcmp (sym->name, sym->old_symbol->name) == 0
+ && sym->binding_label && sym->old_symbol->binding_label
&& strcmp (sym->binding_label, sym->old_symbol->binding_label) != 0)
{
const char *null = "NULL", *s1, *s2;
@@ -7923,6 +7924,7 @@ gfc_match_subroutine (void)
procedure interface body. */
if (sym->attr.module_procedure && sym->old_symbol
&& strcmp (sym->name, sym->old_symbol->name) == 0
+ && sym->binding_label && sym->old_symbol->binding_label
&& strcmp (sym->binding_label, sym->old_symbol->binding_label) != 0)
{
const char *null = "NULL", *s1, *s2;
diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c
index 43b97ba..1012b11 100644
--- a/gcc/fortran/dump-parse-tree.c
+++ b/gcc/fortran/dump-parse-tree.c
@@ -648,7 +648,7 @@ show_expr (gfc_expr *p)
break;
case INTRINSIC_EQ:
case INTRINSIC_EQ_OS:
- fputs ("= ", dumpfile);
+ fputs ("== ", dumpfile);
break;
case INTRINSIC_NE:
case INTRINSIC_NE_OS:
@@ -1587,7 +1587,11 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses)
case OMP_LIST_MAP: type = "MAP"; break;
case OMP_LIST_TO: type = "TO"; break;
case OMP_LIST_FROM: type = "FROM"; break;
- case OMP_LIST_REDUCTION: type = "REDUCTION"; break;
+ case OMP_LIST_REDUCTION:
+ case OMP_LIST_REDUCTION_INSCAN:
+ case OMP_LIST_REDUCTION_TASK: type = "REDUCTION"; break;
+ case OMP_LIST_IN_REDUCTION: type = "IN_REDUCTION"; break;
+ case OMP_LIST_TASK_REDUCTION: type = "TASK_REDUCTION"; break;
case OMP_LIST_DEVICE_RESIDENT: type = "DEVICE_RESIDENT"; break;
case OMP_LIST_LINK: type = "LINK"; break;
case OMP_LIST_USE_DEVICE: type = "USE_DEVICE"; break;
@@ -1600,6 +1604,10 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses)
gcc_unreachable ();
}
fprintf (dumpfile, " %s(", type);
+ if (list_type == OMP_LIST_REDUCTION_INSCAN)
+ fputs ("inscan, ", dumpfile);
+ if (list_type == OMP_LIST_REDUCTION_TASK)
+ fputs ("task, ", dumpfile);
show_omp_namelist (list_type, omp_clauses->lists[list_type]);
fputc (')', dumpfile);
}
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 32d905a..ae9b0a7 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -2096,6 +2096,9 @@ simplify_parameter_variable (gfc_expr *p, int type)
return false;
e->rank = p->rank;
+
+ if (e->ts.type == BT_CHARACTER && p->ts.u.cl)
+ e->ts = p->ts;
}
if (e->ts.type == BT_CHARACTER && e->ts.u.cl == NULL)
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index 526b721..1a05144 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -531,7 +531,7 @@ gfc_builtin_function (tree decl)
return decl;
}
-/* So far we need just these 7 attribute types. */
+/* So far we need just these 8 attribute types. */
#define ATTR_NULL 0
#define ATTR_LEAF_LIST (ECF_LEAF)
#define ATTR_NOTHROW_LEAF_LIST (ECF_NOTHROW | ECF_LEAF)
@@ -540,6 +540,8 @@ gfc_builtin_function (tree decl)
#define ATTR_PURE_NOTHROW_LEAF_LIST (ECF_NOTHROW | ECF_LEAF | ECF_PURE)
#define ATTR_NOTHROW_LIST (ECF_NOTHROW)
#define ATTR_CONST_NOTHROW_LIST (ECF_NOTHROW | ECF_CONST)
+#define ATTR_ALLOC_WARN_UNUSED_RESULT_SIZE_2_NOTHROW_LIST \
+ (ECF_NOTHROW)
static void
gfc_define_builtin (const char *name, tree type, enum built_in_function code,
@@ -1236,6 +1238,13 @@ gfc_init_builtin_functions (void)
#undef DEF_GOACC_BUILTIN
#undef DEF_GOACC_BUILTIN_COMPILER
#undef DEF_GOMP_BUILTIN
+ tree gomp_alloc = builtin_decl_explicit (BUILT_IN_GOMP_ALLOC);
+ tree two = build_int_cst (integer_type_node, 2);
+ DECL_ATTRIBUTES (gomp_alloc)
+ = tree_cons (get_identifier ("warn_unused_result"), NULL_TREE,
+ tree_cons (get_identifier ("alloc_size"),
+ build_tree_list (NULL_TREE, two),
+ DECL_ATTRIBUTES (gomp_alloc)));
}
gfc_define_builtin ("__builtin_trap", builtin_types[BT_FN_VOID],
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index dfd7796..6467985 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1278,6 +1278,10 @@ enum
OMP_LIST_TO,
OMP_LIST_FROM,
OMP_LIST_REDUCTION,
+ OMP_LIST_REDUCTION_INSCAN,
+ OMP_LIST_REDUCTION_TASK,
+ OMP_LIST_IN_REDUCTION,
+ OMP_LIST_TASK_REDUCTION,
OMP_LIST_DEVICE_RESIDENT,
OMP_LIST_LINK,
OMP_LIST_USE_DEVICE,
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index 453b30f..3b27217 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -3866,8 +3866,8 @@ initialization using @code{_gfortran_set_args}.
Default: enabled.
@item @var{option}[6] @tab Enables run-time checking. Possible values
are (bitwise or-ed): GFC_RTCHECK_BOUNDS (1), GFC_RTCHECK_ARRAY_TEMPS (2),
-GFC_RTCHECK_RECURSION (4), GFC_RTCHECK_DO (16), GFC_RTCHECK_POINTER (32),
-GFC_RTCHECK_BITS (64).
+GFC_RTCHECK_RECURSION (4), GFC_RTCHECK_DO (8), GFC_RTCHECK_POINTER (16),
+GFC_RTCHECK_MEM (32), GFC_RTCHECK_BITS (64).
Default: disabled.
@item @var{option}[7] @tab Unused.
@item @var{option}[8] @tab Show a warning when invoking @code{STOP} and
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index da4b1aa..96ed208 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -687,6 +687,10 @@ fopenacc-dim=
Fortran LTO Joined Var(flag_openacc_dims)
; Documented in C
+fopenacc-kernels=
+Fortran RejectNegative Joined Enum(openacc_kernels) Var(flag_openacc_kernels) Init(OPENACC_KERNELS_PARLOOPS)
+; Documented in C
+
fopenmp
Fortran LTO
; Documented in C
diff --git a/gcc/fortran/misc.c b/gcc/fortran/misc.c
index 65bcfa6..e9b87aa 100644
--- a/gcc/fortran/misc.c
+++ b/gcc/fortran/misc.c
@@ -224,10 +224,32 @@ gfc_typename (gfc_expr *ex)
if (ex->ts.type == BT_CHARACTER)
{
- if (ex->ts.u.cl && ex->ts.u.cl->length)
- length = gfc_mpz_get_hwi (ex->ts.u.cl->length->value.integer);
- else
+ if (ex->expr_type == EXPR_CONSTANT)
length = ex->value.character.length;
+ else if (ex->ts.deferred)
+ {
+ if (ex->ts.kind == gfc_default_character_kind)
+ return "CHARACTER(:)";
+ sprintf (buffer, "CHARACTER(:,%d)", ex->ts.kind);
+ return buffer;
+ }
+ else if (ex->ts.u.cl && ex->ts.u.cl->length == NULL)
+ {
+ if (ex->ts.kind == gfc_default_character_kind)
+ return "CHARACTER(*)";
+ sprintf (buffer, "CHARACTER(*,%d)", ex->ts.kind);
+ return buffer;
+ }
+ else if (ex->ts.u.cl == NULL
+ || ex->ts.u.cl->length->expr_type != EXPR_CONSTANT)
+ {
+ if (ex->ts.kind == gfc_default_character_kind)
+ return "CHARACTER";
+ sprintf (buffer, "CHARACTER(KIND=%d)", ex->ts.kind);
+ return buffer;
+ }
+ else
+ length = gfc_mpz_get_hwi (ex->ts.u.cl->length->value.integer);
if (ex->ts.kind == gfc_default_character_kind)
sprintf (buffer, "CHARACTER(" HOST_WIDE_INT_PRINT_DEC ")", length);
else
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 2270c85..68d0b65 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -762,6 +762,8 @@ enum omp_mask1
OMP_CLAUSE_SHARED,
OMP_CLAUSE_COPYIN,
OMP_CLAUSE_REDUCTION,
+ OMP_CLAUSE_IN_REDUCTION,
+ OMP_CLAUSE_TASK_REDUCTION,
OMP_CLAUSE_IF,
OMP_CLAUSE_NUM_THREADS,
OMP_CLAUSE_SCHEDULE,
@@ -959,6 +961,163 @@ gfc_match_omp_map_clause (gfc_omp_namelist **list, gfc_omp_map_op map_op,
return false;
}
+/* reduction ( reduction-modifier, reduction-operator : variable-list )
+ in_reduction ( reduction-operator : variable-list )
+ task_reduction ( reduction-operator : variable-list ) */
+
+static match
+gfc_match_omp_clause_reduction (char pc, gfc_omp_clauses *c, bool openacc,
+ bool allow_derived)
+{
+ if (pc == 'r' && gfc_match ("reduction ( ") != MATCH_YES)
+ return MATCH_NO;
+ else if (pc == 'i' && gfc_match ("in_reduction ( ") != MATCH_YES)
+ return MATCH_NO;
+ else if (pc == 't' && gfc_match ("task_reduction ( ") != MATCH_YES)
+ return MATCH_NO;
+
+ locus old_loc = gfc_current_locus;
+ int list_idx = 0;
+
+ if (pc == 'r' && !openacc)
+ {
+ if (gfc_match ("inscan") == MATCH_YES)
+ list_idx = OMP_LIST_REDUCTION_INSCAN;
+ else if (gfc_match ("task") == MATCH_YES)
+ list_idx = OMP_LIST_REDUCTION_TASK;
+ else if (gfc_match ("default") == MATCH_YES)
+ list_idx = OMP_LIST_REDUCTION;
+ if (list_idx != 0 && gfc_match (", ") != MATCH_YES)
+ {
+ gfc_error ("Comma expected at %C");
+ gfc_current_locus = old_loc;
+ return MATCH_NO;
+ }
+ if (list_idx == 0)
+ list_idx = OMP_LIST_REDUCTION;
+ }
+ else if (pc == 'i')
+ list_idx = OMP_LIST_IN_REDUCTION;
+ else if (pc == 't')
+ list_idx = OMP_LIST_TASK_REDUCTION;
+ else
+ list_idx = OMP_LIST_REDUCTION;
+
+ gfc_omp_reduction_op rop = OMP_REDUCTION_NONE;
+ char buffer[GFC_MAX_SYMBOL_LEN + 3];
+ if (gfc_match_char ('+') == MATCH_YES)
+ rop = OMP_REDUCTION_PLUS;
+ else if (gfc_match_char ('*') == MATCH_YES)
+ rop = OMP_REDUCTION_TIMES;
+ else if (gfc_match_char ('-') == MATCH_YES)
+ rop = OMP_REDUCTION_MINUS;
+ else if (gfc_match (".and.") == MATCH_YES)
+ rop = OMP_REDUCTION_AND;
+ else if (gfc_match (".or.") == MATCH_YES)
+ rop = OMP_REDUCTION_OR;
+ else if (gfc_match (".eqv.") == MATCH_YES)
+ rop = OMP_REDUCTION_EQV;
+ else if (gfc_match (".neqv.") == MATCH_YES)
+ rop = OMP_REDUCTION_NEQV;
+ if (rop != OMP_REDUCTION_NONE)
+ snprintf (buffer, sizeof buffer, "operator %s",
+ gfc_op2string ((gfc_intrinsic_op) rop));
+ else if (gfc_match_defined_op_name (buffer + 1, 1) == MATCH_YES)
+ {
+ buffer[0] = '.';
+ strcat (buffer, ".");
+ }
+ else if (gfc_match_name (buffer) == MATCH_YES)
+ {
+ gfc_symbol *sym;
+ const char *n = buffer;
+
+ gfc_find_symbol (buffer, NULL, 1, &sym);
+ if (sym != NULL)
+ {
+ if (sym->attr.intrinsic)
+ n = sym->name;
+ else if ((sym->attr.flavor != FL_UNKNOWN
+ && sym->attr.flavor != FL_PROCEDURE)
+ || sym->attr.external
+ || sym->attr.generic
+ || sym->attr.entry
+ || sym->attr.result
+ || sym->attr.dummy
+ || sym->attr.subroutine
+ || sym->attr.pointer
+ || sym->attr.target
+ || sym->attr.cray_pointer
+ || sym->attr.cray_pointee
+ || (sym->attr.proc != PROC_UNKNOWN
+ && sym->attr.proc != PROC_INTRINSIC)
+ || sym->attr.if_source != IFSRC_UNKNOWN
+ || sym == sym->ns->proc_name)
+ {
+ sym = NULL;
+ n = NULL;
+ }
+ else
+ n = sym->name;
+ }
+ if (n == NULL)
+ rop = OMP_REDUCTION_NONE;
+ else if (strcmp (n, "max") == 0)
+ rop = OMP_REDUCTION_MAX;
+ else if (strcmp (n, "min") == 0)
+ rop = OMP_REDUCTION_MIN;
+ else if (strcmp (n, "iand") == 0)
+ rop = OMP_REDUCTION_IAND;
+ else if (strcmp (n, "ior") == 0)
+ rop = OMP_REDUCTION_IOR;
+ else if (strcmp (n, "ieor") == 0)
+ rop = OMP_REDUCTION_IEOR;
+ if (rop != OMP_REDUCTION_NONE
+ && sym != NULL
+ && ! sym->attr.intrinsic
+ && ! sym->attr.use_assoc
+ && ((sym->attr.flavor == FL_UNKNOWN
+ && !gfc_add_flavor (&sym->attr, FL_PROCEDURE,
+ sym->name, NULL))
+ || !gfc_add_intrinsic (&sym->attr, NULL)))
+ rop = OMP_REDUCTION_NONE;
+ }
+ else
+ buffer[0] = '\0';
+ gfc_omp_udr *udr = (buffer[0] ? gfc_find_omp_udr (gfc_current_ns, buffer, NULL)
+ : NULL);
+ gfc_omp_namelist **head = NULL;
+ if (rop == OMP_REDUCTION_NONE && udr)
+ rop = OMP_REDUCTION_USER;
+
+ if (gfc_match_omp_variable_list (" :", &c->lists[list_idx], false, NULL,
+ &head, openacc, allow_derived) != MATCH_YES)
+ {
+ gfc_current_locus = old_loc;
+ return MATCH_NO;
+ }
+ gfc_omp_namelist *n;
+ if (rop == OMP_REDUCTION_NONE)
+ {
+ n = *head;
+ *head = NULL;
+ gfc_error_now ("!$OMP DECLARE REDUCTION %s not found at %L",
+ buffer, &old_loc);
+ gfc_free_omp_namelist (n);
+ }
+ else
+ for (n = *head; n; n = n->next)
+ {
+ n->u.reduction_op = rop;
+ if (udr)
+ {
+ n->udr = gfc_get_omp_namelist_udr ();
+ n->udr->udr = udr;
+ }
+ }
+ return MATCH_YES;
+}
+
/* Match OpenMP and OpenACC directive clauses. MASK is a bitmask of
clauses that are allowed for a particular directive. */
@@ -1379,6 +1538,10 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
needs_space = true;
continue;
}
+ if ((mask & OMP_CLAUSE_IN_REDUCTION)
+ && gfc_match_omp_clause_reduction (pc, c, openacc,
+ allow_derived) == MATCH_YES)
+ continue;
if ((mask & OMP_CLAUSE_INBRANCH)
&& !c->inbranch
&& !c->notinbranch
@@ -1717,124 +1880,24 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
continue;
}
if ((mask & OMP_CLAUSE_REDUCTION)
- && gfc_match ("reduction ( ") == MATCH_YES)
+ && gfc_match_omp_clause_reduction (pc, c, openacc,
+ allow_derived) == MATCH_YES)
+ continue;
+ if ((mask & OMP_CLAUSE_MEMORDER)
+ && c->memorder == OMP_MEMORDER_UNSET
+ && gfc_match ("relaxed") == MATCH_YES)
{
- gfc_omp_reduction_op rop = OMP_REDUCTION_NONE;
- char buffer[GFC_MAX_SYMBOL_LEN + 3];
- if (gfc_match_char ('+') == MATCH_YES)
- rop = OMP_REDUCTION_PLUS;
- else if (gfc_match_char ('*') == MATCH_YES)
- rop = OMP_REDUCTION_TIMES;
- else if (gfc_match_char ('-') == MATCH_YES)
- rop = OMP_REDUCTION_MINUS;
- else if (gfc_match (".and.") == MATCH_YES)
- rop = OMP_REDUCTION_AND;
- else if (gfc_match (".or.") == MATCH_YES)
- rop = OMP_REDUCTION_OR;
- else if (gfc_match (".eqv.") == MATCH_YES)
- rop = OMP_REDUCTION_EQV;
- else if (gfc_match (".neqv.") == MATCH_YES)
- rop = OMP_REDUCTION_NEQV;
- if (rop != OMP_REDUCTION_NONE)
- snprintf (buffer, sizeof buffer, "operator %s",
- gfc_op2string ((gfc_intrinsic_op) rop));
- else if (gfc_match_defined_op_name (buffer + 1, 1) == MATCH_YES)
- {
- buffer[0] = '.';
- strcat (buffer, ".");
- }
- else if (gfc_match_name (buffer) == MATCH_YES)
- {
- gfc_symbol *sym;
- const char *n = buffer;
-
- gfc_find_symbol (buffer, NULL, 1, &sym);
- if (sym != NULL)
- {
- if (sym->attr.intrinsic)
- n = sym->name;
- else if ((sym->attr.flavor != FL_UNKNOWN
- && sym->attr.flavor != FL_PROCEDURE)
- || sym->attr.external
- || sym->attr.generic
- || sym->attr.entry
- || sym->attr.result
- || sym->attr.dummy
- || sym->attr.subroutine
- || sym->attr.pointer
- || sym->attr.target
- || sym->attr.cray_pointer
- || sym->attr.cray_pointee
- || (sym->attr.proc != PROC_UNKNOWN
- && sym->attr.proc != PROC_INTRINSIC)
- || sym->attr.if_source != IFSRC_UNKNOWN
- || sym == sym->ns->proc_name)
- {
- sym = NULL;
- n = NULL;
- }
- else
- n = sym->name;
- }
- if (n == NULL)
- rop = OMP_REDUCTION_NONE;
- else if (strcmp (n, "max") == 0)
- rop = OMP_REDUCTION_MAX;
- else if (strcmp (n, "min") == 0)
- rop = OMP_REDUCTION_MIN;
- else if (strcmp (n, "iand") == 0)
- rop = OMP_REDUCTION_IAND;
- else if (strcmp (n, "ior") == 0)
- rop = OMP_REDUCTION_IOR;
- else if (strcmp (n, "ieor") == 0)
- rop = OMP_REDUCTION_IEOR;
- if (rop != OMP_REDUCTION_NONE
- && sym != NULL
- && ! sym->attr.intrinsic
- && ! sym->attr.use_assoc
- && ((sym->attr.flavor == FL_UNKNOWN
- && !gfc_add_flavor (&sym->attr, FL_PROCEDURE,
- sym->name, NULL))
- || !gfc_add_intrinsic (&sym->attr, NULL)))
- rop = OMP_REDUCTION_NONE;
- }
- else
- buffer[0] = '\0';
- gfc_omp_udr *udr
- = (buffer[0]
- ? gfc_find_omp_udr (gfc_current_ns, buffer, NULL) : NULL);
- gfc_omp_namelist **head = NULL;
- if (rop == OMP_REDUCTION_NONE && udr)
- rop = OMP_REDUCTION_USER;
-
- if (gfc_match_omp_variable_list (" :",
- &c->lists[OMP_LIST_REDUCTION],
- false, NULL, &head, openacc,
- allow_derived) == MATCH_YES)
- {
- gfc_omp_namelist *n;
- if (rop == OMP_REDUCTION_NONE)
- {
- n = *head;
- *head = NULL;
- gfc_error_now ("!$OMP DECLARE REDUCTION %s not found "
- "at %L", buffer, &old_loc);
- gfc_free_omp_namelist (n);
- }
- else
- for (n = *head; n; n = n->next)
- {
- n->u.reduction_op = rop;
- if (udr)
- {
- n->udr = gfc_get_omp_namelist_udr ();
- n->udr->udr = udr;
- }
- }
- continue;
- }
- else
- gfc_current_locus = old_loc;
+ c->memorder = OMP_MEMORDER_RELAXED;
+ needs_space = true;
+ continue;
+ }
+ if ((mask & OMP_CLAUSE_MEMORDER)
+ && c->memorder == OMP_MEMORDER_UNSET
+ && gfc_match ("release") == MATCH_YES)
+ {
+ c->memorder = OMP_MEMORDER_RELEASE;
+ needs_space = true;
+ continue;
}
if ((mask & OMP_CLAUSE_MEMORDER)
&& c->memorder == OMP_MEMORDER_UNSET
@@ -1962,6 +2025,10 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
}
break;
case 't':
+ if ((mask & OMP_CLAUSE_TASK_REDUCTION)
+ && gfc_match_omp_clause_reduction (pc, c, openacc,
+ allow_derived) == MATCH_YES)
+ continue;
if ((mask & OMP_CLAUSE_THREAD_LIMIT)
&& c->thread_limit == NULL
&& gfc_match ("thread_limit ( %e )",
@@ -2696,18 +2763,19 @@ cleanup:
(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
| OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT \
| OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE \
- | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY)
+ | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_IN_REDUCTION)
#define OMP_TASKLOOP_CLAUSES \
(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
| OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF \
| OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL \
| OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_GRAINSIZE \
- | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_NOGROUP)
+ | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_NOGROUP \
+ | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IN_REDUCTION)
#define OMP_TARGET_CLAUSES \
(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE \
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP \
- | OMP_CLAUSE_IS_DEVICE_PTR)
+ | OMP_CLAUSE_IS_DEVICE_PTR | OMP_CLAUSE_IN_REDUCTION)
#define OMP_TARGET_DATA_CLAUSES \
(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
| OMP_CLAUSE_USE_DEVICE_PTR | OMP_CLAUSE_USE_DEVICE_ADDR)
@@ -4228,12 +4296,12 @@ gfc_match_omp_barrier (void)
match
gfc_match_omp_taskgroup (void)
{
- if (gfc_match_omp_eos () != MATCH_YES)
- {
- gfc_error ("Unexpected junk after $OMP TASKGROUP statement at %C");
- return MATCH_ERROR;
- }
+ gfc_omp_clauses *c;
+ if (gfc_match_omp_clauses (&c, OMP_CLAUSE_TASK_REDUCTION, true, true)
+ != MATCH_YES)
+ return MATCH_ERROR;
new_st.op = EXEC_OMP_TASKGROUP;
+ new_st.ext.omp_clauses = c;
return MATCH_YES;
}
@@ -4560,7 +4628,9 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
static const char *clause_names[]
= { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
"COPYIN", "UNIFORM", "ALIGNED", "LINEAR", "DEPEND", "MAP",
- "TO", "FROM", "REDUCTION", "DEVICE_RESIDENT", "LINK", "USE_DEVICE",
+ "TO", "FROM", "REDUCTION", "REDUCTION" /*inscan*/, "REDUCTION" /*task*/,
+ "IN_REDUCTION", "TASK_REDUCTION",
+ "DEVICE_RESIDENT", "LINK", "USE_DEVICE",
"CACHE", "IS_DEVICE_PTR", "USE_DEVICE_PTR", "USE_DEVICE_ADDR",
"NONTEMPORAL" };
STATIC_ASSERT (ARRAY_SIZE (clause_names) == OMP_LIST_NUM);
@@ -4727,21 +4797,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
if (omp_clauses->sched_kind != OMP_SCHED_NONE
&& omp_clauses->sched_nonmonotonic)
{
- if (omp_clauses->sched_kind != OMP_SCHED_DYNAMIC
- && omp_clauses->sched_kind != OMP_SCHED_GUIDED)
- {
- const char *p;
- switch (omp_clauses->sched_kind)
- {
- case OMP_SCHED_STATIC: p = "STATIC"; break;
- case OMP_SCHED_RUNTIME: p = "RUNTIME"; break;
- case OMP_SCHED_AUTO: p = "AUTO"; break;
- default: gcc_unreachable ();
- }
- gfc_error ("NONMONOTONIC modifier specified for %s schedule kind "
- "at %L", p, &code->loc);
- }
- else if (omp_clauses->sched_monotonic)
+ if (omp_clauses->sched_monotonic)
gfc_error ("Both MONOTONIC and NONMONOTONIC schedule modifiers "
"specified at %L", &code->loc);
else if (omp_clauses->ordered)
@@ -4818,7 +4874,11 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
&& (list != OMP_LIST_MAP || openacc)
&& list != OMP_LIST_FROM
&& list != OMP_LIST_TO
- && (list != OMP_LIST_REDUCTION || !openacc))
+ && (list != OMP_LIST_REDUCTION || !openacc)
+ && list != OMP_LIST_REDUCTION_INSCAN
+ && list != OMP_LIST_REDUCTION_TASK
+ && list != OMP_LIST_IN_REDUCTION
+ && list != OMP_LIST_TASK_REDUCTION)
for (n = omp_clauses->lists[list]; n; n = n->next)
{
bool component_ref_p = false;
@@ -5224,6 +5284,11 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
for (; n != NULL; n = n->next)
{
bool bad = false;
+ bool is_reduction = (list == OMP_LIST_REDUCTION
+ || list == OMP_LIST_REDUCTION_INSCAN
+ || list == OMP_LIST_REDUCTION_TASK
+ || list == OMP_LIST_IN_REDUCTION
+ || list == OMP_LIST_TASK_REDUCTION);
if (n->sym->attr.threadprivate)
gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
n->sym->name, name, &n->where);
@@ -5233,15 +5298,15 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
if (n->sym->attr.associate_var)
gfc_error ("ASSOCIATE name %qs in %s clause at %L",
n->sym->name, name, &n->where);
- if (list != OMP_LIST_PRIVATE)
+ if (list != OMP_LIST_PRIVATE && is_reduction)
{
- if (n->sym->attr.proc_pointer && list == OMP_LIST_REDUCTION)
+ if (n->sym->attr.proc_pointer)
gfc_error ("Procedure pointer %qs in %s clause at %L",
n->sym->name, name, &n->where);
- if (n->sym->attr.pointer && list == OMP_LIST_REDUCTION)
+ if (n->sym->attr.pointer)
gfc_error ("POINTER object %qs in %s clause at %L",
n->sym->name, name, &n->where);
- if (n->sym->attr.cray_pointer && list == OMP_LIST_REDUCTION)
+ if (n->sym->attr.cray_pointer)
gfc_error ("Cray pointer %qs in %s clause at %L",
n->sym->name, name, &n->where);
}
@@ -5253,7 +5318,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
else if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
gfc_error ("Assumed size array %qs in %s clause at %L",
n->sym->name, name, &n->where);
- if (n->sym->attr.in_namelist && list != OMP_LIST_REDUCTION)
+ if (n->sym->attr.in_namelist && !is_reduction)
gfc_error ("Variable %qs in %s clause is used in "
"NAMELIST statement at %L",
n->sym->name, name, &n->where);
@@ -5273,7 +5338,21 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
switch (list)
{
+ case OMP_LIST_REDUCTION_INSCAN:
+ case OMP_LIST_REDUCTION_TASK:
+ if (code && (code->op == EXEC_OMP_TASKLOOP
+ || code->op == EXEC_OMP_TEAMS
+ || code->op == EXEC_OMP_TEAMS_DISTRIBUTE))
+ {
+ gfc_error ("Only DEFAULT permitted as reduction-"
+ "modifier in REDUCTION clause at %L",
+ &n->where);
+ break;
+ }
+ gcc_fallthrough ();
case OMP_LIST_REDUCTION:
+ case OMP_LIST_IN_REDUCTION:
+ case OMP_LIST_TASK_REDUCTION:
switch (n->u.reduction_op)
{
case OMP_REDUCTION_PLUS:
@@ -6102,6 +6181,10 @@ gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns)
case OMP_LIST_FIRSTPRIVATE:
case OMP_LIST_LASTPRIVATE:
case OMP_LIST_REDUCTION:
+ case OMP_LIST_REDUCTION_INSCAN:
+ case OMP_LIST_REDUCTION_TASK:
+ case OMP_LIST_IN_REDUCTION:
+ case OMP_LIST_TASK_REDUCTION:
case OMP_LIST_LINEAR:
for (n = omp_clauses->lists[list]; n; n = n->next)
ctx.sharing_clauses->add (n->sym);
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index d844fa9..66be1d5 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -412,22 +412,24 @@ gfc_post_options (const char **pfilename)
else if (!flag_automatic && flag_recursive)
gfc_warning_now (OPT_Woverwrite_recursive, "Flag %<-fno-automatic%> "
"overwrites %<-frecursive%>");
- else if (!flag_automatic && flag_openmp)
- gfc_warning_now (0, "Flag %<-fno-automatic%> overwrites %<-frecursive%> implied by "
- "%<-fopenmp%>");
+ else if (!flag_automatic && (flag_openmp || flag_openacc))
+ gfc_warning_now (0, "Flag %<-fno-automatic%> overwrites %<-frecursive%> "
+ "implied by %qs", flag_openmp ? "-fopenmp" : "-fopenacc");
else if (flag_max_stack_var_size != -2 && flag_recursive)
gfc_warning_now (0, "Flag %<-frecursive%> overwrites %<-fmax-stack-var-size=%d%>",
flag_max_stack_var_size);
- else if (flag_max_stack_var_size != -2 && flag_openmp)
- gfc_warning_now (0, "Flag %<-fmax-stack-var-size=%d%> overwrites %<-frecursive%> "
- "implied by %<-fopenmp%>", flag_max_stack_var_size);
+ else if (flag_max_stack_var_size != -2 && (flag_openmp || flag_openacc))
+ gfc_warning_now (0, "Flag %<-fmax-stack-var-size=%d%> overwrites "
+ "%<-frecursive%> implied by %qs", flag_max_stack_var_size,
+ flag_openmp ? "-fopenmp" : "-fopenacc");
/* Implement -frecursive as -fmax-stack-var-size=-1. */
if (flag_recursive)
flag_max_stack_var_size = -1;
/* Implied -frecursive; implemented as -fmax-stack-var-size=-1. */
- if (flag_max_stack_var_size == -2 && flag_openmp && flag_automatic)
+ if (flag_max_stack_var_size == -2 && flag_automatic
+ && (flag_openmp || flag_openacc))
{
flag_recursive = 1;
flag_max_stack_var_size = -1;
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 1641eb6..b6d21ad 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -16327,7 +16327,7 @@ traverse_data_list (gfc_data_variable *var, locus *where)
|| end->expr_type != EXPR_CONSTANT)
{
gfc_error ("end of implied-do loop at %L could not be "
- "simplified to a constant value", &start->where);
+ "simplified to a constant value", &end->where);
retval = false;
goto cleanup;
}
@@ -16335,7 +16335,14 @@ traverse_data_list (gfc_data_variable *var, locus *where)
|| step->expr_type != EXPR_CONSTANT)
{
gfc_error ("step of implied-do loop at %L could not be "
- "simplified to a constant value", &start->where);
+ "simplified to a constant value", &step->where);
+ retval = false;
+ goto cleanup;
+ }
+ if (mpz_cmp_si (step->value.integer, 0) == 0)
+ {
+ gfc_error ("step of implied-do loop at %L shall not be zero",
+ &step->where);
retval = false;
goto cleanup;
}
diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c
index fd11f5a..304ae2d 100644
--- a/gcc/fortran/scanner.c
+++ b/gcc/fortran/scanner.c
@@ -899,21 +899,14 @@ skip_free_comments (void)
if (next_char () == '$')
{
c = next_char ();
- if (c == 'a' || c == 'A')
- {
- if (skip_free_oacc_sentinel (start, old_loc))
- return false;
- gfc_current_locus = old_loc;
- next_char();
- c = next_char();
- }
- if (continue_flag || c == ' ' || c == '\t')
- {
- gfc_current_locus = old_loc;
- next_char();
- openacc_flag = 0;
- return true;
- }
+ if (c == 'a' || c == 'A')
+ {
+ if (skip_free_oacc_sentinel (start, old_loc))
+ return false;
+ gfc_current_locus = old_loc;
+ next_char();
+ c = next_char();
+ }
}
gfc_current_locus = old_loc;
}
@@ -1076,8 +1069,7 @@ skip_fixed_comments (void)
}
gfc_current_locus = start;
}
-
- if (flag_openacc && !(flag_openmp || flag_openmp_simd))
+ else if (flag_openacc && !(flag_openmp || flag_openmp_simd))
{
if (next_char () == '$')
{
@@ -1087,13 +1079,10 @@ skip_fixed_comments (void)
if (skip_fixed_oacc_sentinel (&start))
return;
}
- else
- goto check_for_digits;
}
gfc_current_locus = start;
}
-
- if (flag_openacc || flag_openmp || flag_openmp_simd)
+ else if (flag_openacc || flag_openmp || flag_openmp_simd)
{
if (next_char () == '$')
{
@@ -1120,6 +1109,7 @@ skip_fixed_comments (void)
gcc_unreachable ();
check_for_digits:
{
+ /* Required for OpenMP's conditional compilation sentinel. */
int digit_seen = 0;
for (col = 3; col < 6; col++, c = next_char ())
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 71d5c67..37a0c85 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -2075,7 +2075,8 @@ get_proc_pointer_decl (gfc_symbol *sym)
/* Get a basic decl for an external function. */
tree
-gfc_get_extern_function_decl (gfc_symbol * sym, gfc_actual_arglist *actual_args)
+gfc_get_extern_function_decl (gfc_symbol * sym, gfc_actual_arglist *actual_args,
+ const char *fnspec)
{
tree type;
tree fndecl;
@@ -2287,7 +2288,8 @@ module_sym:
mangled_name = gfc_sym_mangled_function_id (sym);
}
- type = gfc_get_function_type (sym, actual_args);
+ type = gfc_get_function_type (sym, actual_args, fnspec);
+
fndecl = build_decl (input_location,
FUNCTION_DECL, name, type);
@@ -6965,8 +6967,7 @@ gfc_generate_function_code (gfc_namespace * ns)
gfc_init_block (&cleanup);
/* Reset recursion-check variable. */
- if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION)
- && !is_recursive && !flag_openmp && recurcheckvar != NULL_TREE)
+ if (recurcheckvar != NULL_TREE)
{
gfc_add_modify (&cleanup, recurcheckvar, logical_false_node);
recurcheckvar = NULL;
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index e0afc10..bcc13ce 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -40,6 +40,8 @@ along with GCC; see the file COPYING3. If not see
#include "trans-types.h"
#include "trans-array.h"
#include "dependency.h" /* For CAF array alias analysis. */
+#include "attribs.h"
+
/* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
/* This maps Fortran intrinsic math functions to external library or GCC
@@ -4257,10 +4259,69 @@ remove_empty_actual_arguments (gfc_actual_arglist **ap)
}
}
+#define MAX_SPEC_ARG 12
+
+/* Make up an fn spec that's right for intrinsic functions that we
+ want to call. */
+
+static char *
+intrinsic_fnspec (gfc_expr *expr)
+{
+ static char fnspec_buf[MAX_SPEC_ARG*2+1];
+ char *fp;
+ int i;
+ int num_char_args;
+
+#define ADD_CHAR(c) do { *fp++ = c; *fp++ = ' '; } while(0)
+
+ /* Set the fndecl. */
+ fp = fnspec_buf;
+ /* Function return value. FIXME: Check if the second letter could
+ be something other than a space, for further optimization. */
+ ADD_CHAR ('.');
+ if (expr->rank == 0)
+ {
+ if (expr->ts.type == BT_CHARACTER)
+ {
+ ADD_CHAR ('w'); /* Address of character. */
+ ADD_CHAR ('.'); /* Length of character. */
+ }
+ }
+ else
+ ADD_CHAR ('w'); /* Return value is a descriptor. */
+
+ num_char_args = 0;
+ for (gfc_actual_arglist *a = expr->value.function.actual; a; a = a->next)
+ {
+ if (a->expr == NULL)
+ continue;
+
+ if (a->name && strcmp (a->name,"%VAL") == 0)
+ ADD_CHAR ('.');
+ else
+ {
+ if (a->expr->rank > 0)
+ ADD_CHAR ('r');
+ else
+ ADD_CHAR ('R');
+ }
+ num_char_args += a->expr->ts.type == BT_CHARACTER;
+ gcc_assert (fp - fnspec_buf + num_char_args <= MAX_SPEC_ARG*2);
+ }
+
+ for (i = 0; i < num_char_args; i++)
+ ADD_CHAR ('.');
+
+ *fp = '\0';
+ return fnspec_buf;
+}
+
+#undef MAX_SPEC_ARG
+#undef ADD_CHAR
+
/* Generate the right symbol for the specific intrinsic function and
modify the expr accordingly. This assumes that absent optional
- arguments should be removed. FIXME: This should be extended for
- procedures which do not ignore optional arguments (PR 97454). */
+ arguments should be removed. */
gfc_symbol *
specific_intrinsic_symbol (gfc_expr *expr)
@@ -4278,14 +4339,19 @@ specific_intrinsic_symbol (gfc_expr *expr)
gfc_copy_formal_args_intr (sym, expr->value.function.isym,
expr->value.function.actual, true);
sym->backend_decl
- = gfc_get_extern_function_decl (sym, expr->value.function.actual);
+ = gfc_get_extern_function_decl (sym, expr->value.function.actual,
+ intrinsic_fnspec (expr));
}
+
remove_empty_actual_arguments (&(expr->value.function.actual));
return sym;
}
-/* Generate a call to an external intrinsic function. */
+/* Generate a call to an external intrinsic function. FIXME: So far,
+ this only works for functions which are called with well-defined
+ types; CSHIFT and friends will come later. */
+
static void
gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
{
@@ -4302,11 +4368,16 @@ gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
switch (expr->value.function.isym->id)
{
+ case GFC_ISYM_ANY:
+ case GFC_ISYM_ALL:
case GFC_ISYM_FINDLOC:
case GFC_ISYM_MAXLOC:
case GFC_ISYM_MINLOC:
case GFC_ISYM_MAXVAL:
case GFC_ISYM_MINVAL:
+ case GFC_ISYM_NORM2:
+ case GFC_ISYM_PRODUCT:
+ case GFC_ISYM_SUM:
specific_symbol = true;
break;
default:
@@ -7929,6 +8000,35 @@ gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
&& strcmp (e->ref->u.c.component->name, "_data") == 0)
sym = e->symtree->n.sym;
+ if ((gfc_option.rtcheck & GFC_RTCHECK_POINTER)
+ && e
+ && (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION))
+ {
+ symbol_attribute attr;
+ char *msg;
+
+ attr = gfc_expr_attr (e);
+ if (attr.allocatable)
+ msg = xasprintf ("Allocatable argument '%s' is not allocated",
+ e->symtree->n.sym->name);
+ else if (attr.pointer)
+ msg = xasprintf ("Pointer argument '%s' is not associated",
+ e->symtree->n.sym->name);
+ else
+ goto end_arg_check;
+
+ argse.descriptor_only = 1;
+ gfc_conv_expr_descriptor (&argse, actual->expr);
+ tree temp = gfc_conv_descriptor_data_get (argse.expr);
+ tree cond = fold_build2_loc (input_location, EQ_EXPR,
+ logical_type_node, temp,
+ fold_convert (TREE_TYPE (temp),
+ null_pointer_node));
+ gfc_trans_runtime_check (true, false, cond, &argse.pre, &e->where, msg);
+ free (msg);
+ }
+ end_arg_check:
+
argse.data_not_needed = 1;
if (gfc_is_class_array_function (e))
{
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index 1d652a0..6b4ad6a 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -626,6 +626,8 @@ gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer)
case OMP_CLAUSE_LASTPRIVATE:
case OMP_CLAUSE_LINEAR:
case OMP_CLAUSE_REDUCTION:
+ case OMP_CLAUSE_IN_REDUCTION:
+ case OMP_CLAUSE_TASK_REDUCTION:
break;
default:
gcc_unreachable ();
@@ -699,7 +701,9 @@ gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer)
then_b = gfc_finish_block (&cond_block);
/* Reduction clause requires allocated ALLOCATABLE. */
- if (OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_REDUCTION)
+ if (OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_REDUCTION
+ && OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_IN_REDUCTION
+ && OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_TASK_REDUCTION)
{
gfc_init_block (&cond_block);
if (GFC_DESCRIPTOR_TYPE_P (type))
@@ -2029,9 +2033,25 @@ gfc_trans_omp_array_reduction_or_udr (tree c, gfc_omp_namelist *n, locus where)
}
static tree
-gfc_trans_omp_reduction_list (gfc_omp_namelist *namelist, tree list,
+gfc_trans_omp_reduction_list (int kind, gfc_omp_namelist *namelist, tree list,
locus where, bool mark_addressable)
{
+ omp_clause_code clause = OMP_CLAUSE_REDUCTION;
+ switch (kind)
+ {
+ case OMP_LIST_REDUCTION:
+ case OMP_LIST_REDUCTION_INSCAN:
+ case OMP_LIST_REDUCTION_TASK:
+ break;
+ case OMP_LIST_IN_REDUCTION:
+ clause = OMP_CLAUSE_IN_REDUCTION;
+ break;
+ case OMP_LIST_TASK_REDUCTION:
+ clause = OMP_CLAUSE_TASK_REDUCTION;
+ break;
+ default:
+ gcc_unreachable ();
+ }
for (; namelist != NULL; namelist = namelist->next)
if (namelist->sym->attr.referenced)
{
@@ -2039,10 +2059,14 @@ gfc_trans_omp_reduction_list (gfc_omp_namelist *namelist, tree list,
if (t != error_mark_node)
{
tree node = build_omp_clause (gfc_get_location (&namelist->where),
- OMP_CLAUSE_REDUCTION);
+ clause);
OMP_CLAUSE_DECL (node) = t;
if (mark_addressable)
TREE_ADDRESSABLE (t) = 1;
+ if (kind == OMP_LIST_REDUCTION_INSCAN)
+ OMP_CLAUSE_REDUCTION_INSCAN (node) = 1;
+ if (kind == OMP_LIST_REDUCTION_TASK)
+ OMP_CLAUSE_REDUCTION_TASK (node) = 1;
switch (namelist->u.reduction_op)
{
case OMP_REDUCTION_PLUS:
@@ -2267,10 +2291,14 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
switch (list)
{
case OMP_LIST_REDUCTION:
+ case OMP_LIST_REDUCTION_INSCAN:
+ case OMP_LIST_REDUCTION_TASK:
+ case OMP_LIST_IN_REDUCTION:
+ case OMP_LIST_TASK_REDUCTION:
/* An OpenACC async clause indicates the need to set reduction
arguments addressable, to allow asynchronous copy-out. */
- omp_clauses = gfc_trans_omp_reduction_list (n, omp_clauses, where,
- clauses->async);
+ omp_clauses = gfc_trans_omp_reduction_list (list, n, omp_clauses,
+ where, clauses->async);
break;
case OMP_LIST_PRIVATE:
clause_code = OMP_CLAUSE_PRIVATE;
@@ -3894,8 +3922,8 @@ gfc_trans_oacc_construct (gfc_code *code)
oacc_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
code->loc, false, true);
stmt = gfc_trans_omp_code (code->block->next, true);
- stmt = build2_loc (input_location, construct_code, void_type_node, stmt,
- oacc_clauses);
+ stmt = build2_loc (gfc_get_location (&code->loc), construct_code,
+ void_type_node, stmt, oacc_clauses);
gfc_add_expr_to_block (&block, stmt);
return gfc_finish_block (&block);
}
@@ -5207,18 +5235,27 @@ gfc_split_omp_clauses (gfc_code *code,
/* Reduction is allowed on simd, do, parallel and teams.
Duplicate it on all of them, but omit on do if
parallel is present. */
- if (mask & GFC_OMP_MASK_TEAMS)
- clausesa[GFC_OMP_SPLIT_TEAMS].lists[OMP_LIST_REDUCTION]
- = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
- if (mask & GFC_OMP_MASK_PARALLEL)
- clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_REDUCTION]
- = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
- else if (mask & GFC_OMP_MASK_DO)
- clausesa[GFC_OMP_SPLIT_DO].lists[OMP_LIST_REDUCTION]
- = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
- if (mask & GFC_OMP_MASK_SIMD)
- clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_REDUCTION]
- = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
+ for (int i = OMP_LIST_REDUCTION; i <= OMP_LIST_REDUCTION_TASK; i++)
+ {
+ if (mask & GFC_OMP_MASK_TEAMS)
+ clausesa[GFC_OMP_SPLIT_TEAMS].lists[i]
+ = code->ext.omp_clauses->lists[i];
+ if (mask & GFC_OMP_MASK_PARALLEL)
+ clausesa[GFC_OMP_SPLIT_PARALLEL].lists[i]
+ = code->ext.omp_clauses->lists[i];
+ else if (mask & GFC_OMP_MASK_DO)
+ clausesa[GFC_OMP_SPLIT_DO].lists[i]
+ = code->ext.omp_clauses->lists[i];
+ if (mask & GFC_OMP_MASK_SIMD)
+ clausesa[GFC_OMP_SPLIT_SIMD].lists[i]
+ = code->ext.omp_clauses->lists[i];
+ }
+ if (mask & GFC_OMP_MASK_TARGET)
+ clausesa[GFC_OMP_SPLIT_TARGET].lists[OMP_LIST_IN_REDUCTION]
+ = code->ext.omp_clauses->lists[OMP_LIST_IN_REDUCTION];
+ if (mask & GFC_OMP_MASK_TASKLOOP)
+ clausesa[GFC_OMP_SPLIT_TASKLOOP].lists[OMP_LIST_IN_REDUCTION]
+ = code->ext.omp_clauses->lists[OMP_LIST_IN_REDUCTION];
/* Linear clause is supported on do and simd,
put it on the innermost one. */
clausesa[innermost].lists[OMP_LIST_LINEAR]
@@ -5314,8 +5351,8 @@ gfc_trans_omp_parallel_do (gfc_code *code, stmtblock_t *pblock,
}
else if (TREE_CODE (stmt) != BIND_EXPR)
stmt = build3_v (BIND_EXPR, NULL, stmt, NULL_TREE);
- stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
- omp_clauses);
+ stmt = build2_loc (gfc_get_location (&code->loc), OMP_PARALLEL,
+ void_type_node, stmt, omp_clauses);
OMP_PARALLEL_COMBINED (stmt) = 1;
gfc_add_expr_to_block (&block, stmt);
return gfc_finish_block (&block);
@@ -5357,8 +5394,8 @@ gfc_trans_omp_parallel_do_simd (gfc_code *code, stmtblock_t *pblock,
stmt = build3_v (BIND_EXPR, NULL, stmt, NULL_TREE);
if (flag_openmp)
{
- stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
- omp_clauses);
+ stmt = build2_loc (gfc_get_location (&code->loc), OMP_PARALLEL,
+ void_type_node, stmt, omp_clauses);
OMP_PARALLEL_COMBINED (stmt) = 1;
}
gfc_add_expr_to_block (&block, stmt);
@@ -5384,8 +5421,8 @@ gfc_trans_omp_parallel_sections (gfc_code *code)
stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
else
poplevel (0, 0);
- stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
- omp_clauses);
+ stmt = build2_loc (gfc_get_location (&code->loc), OMP_PARALLEL,
+ void_type_node, stmt, omp_clauses);
OMP_PARALLEL_COMBINED (stmt) = 1;
gfc_add_expr_to_block (&block, stmt);
return gfc_finish_block (&block);
@@ -5407,8 +5444,8 @@ gfc_trans_omp_parallel_workshare (gfc_code *code)
pushlevel ();
stmt = gfc_trans_omp_workshare (code, &workshare_clauses);
stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
- stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
- omp_clauses);
+ stmt = build2_loc (gfc_get_location (&code->loc), OMP_PARALLEL,
+ void_type_node, stmt, omp_clauses);
OMP_PARALLEL_COMBINED (stmt) = 1;
gfc_add_expr_to_block (&block, stmt);
return gfc_finish_block (&block);
@@ -5420,6 +5457,7 @@ gfc_trans_omp_sections (gfc_code *code, gfc_omp_clauses *clauses)
stmtblock_t block, body;
tree omp_clauses, stmt;
bool has_lastprivate = clauses->lists[OMP_LIST_LASTPRIVATE] != NULL;
+ location_t loc = gfc_get_location (&code->loc);
gfc_start_block (&block);
@@ -5440,8 +5478,7 @@ gfc_trans_omp_sections (gfc_code *code, gfc_omp_clauses *clauses)
}
stmt = gfc_finish_block (&body);
- stmt = build2_loc (input_location, OMP_SECTIONS, void_type_node, stmt,
- omp_clauses);
+ stmt = build2_loc (loc, OMP_SECTIONS, void_type_node, stmt, omp_clauses);
gfc_add_expr_to_block (&block, stmt);
return gfc_finish_block (&block);
@@ -5452,8 +5489,8 @@ gfc_trans_omp_single (gfc_code *code, gfc_omp_clauses *clauses)
{
tree omp_clauses = gfc_trans_omp_clauses (NULL, clauses, code->loc);
tree stmt = gfc_trans_omp_code (code->block->next, true);
- stmt = build2_loc (input_location, OMP_SINGLE, void_type_node, stmt,
- omp_clauses);
+ stmt = build2_loc (gfc_get_location (&code->loc), OMP_SINGLE, void_type_node,
+ stmt, omp_clauses);
return stmt;
}
@@ -5469,8 +5506,8 @@ gfc_trans_omp_task (gfc_code *code)
pushlevel ();
stmt = gfc_trans_omp_code (code->block->next, true);
stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
- stmt = build2_loc (input_location, OMP_TASK, void_type_node, stmt,
- omp_clauses);
+ stmt = build2_loc (gfc_get_location (&code->loc), OMP_TASK, void_type_node,
+ stmt, omp_clauses);
gfc_add_expr_to_block (&block, stmt);
return gfc_finish_block (&block);
}
@@ -5612,8 +5649,8 @@ gfc_trans_omp_teams (gfc_code *code, gfc_omp_clauses *clausesa,
if (flag_openmp)
{
stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
- stmt = build2_loc (input_location, OMP_TEAMS, void_type_node, stmt,
- omp_clauses);
+ stmt = build2_loc (gfc_get_location (&code->loc), OMP_TEAMS,
+ void_type_node, stmt, omp_clauses);
if (combined)
OMP_TEAMS_COMBINED (stmt) = 1;
}
@@ -5716,8 +5753,8 @@ gfc_trans_omp_target (gfc_code *code)
}
if (flag_openmp)
{
- stmt = build2_loc (input_location, OMP_TARGET, void_type_node, stmt,
- omp_clauses);
+ stmt = build2_loc (gfc_get_location (&code->loc), OMP_TARGET,
+ void_type_node, stmt, omp_clauses);
if (code->op != EXEC_OMP_TARGET)
OMP_TARGET_COMBINED (stmt) = 1;
cfun->has_omp_target = true;
@@ -5778,8 +5815,8 @@ gfc_trans_omp_target_data (gfc_code *code)
omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
code->loc);
stmt = gfc_trans_omp_code (code->block->next, true);
- stmt = build2_loc (input_location, OMP_TARGET_DATA, void_type_node, stmt,
- omp_clauses);
+ stmt = build2_loc (gfc_get_location (&code->loc), OMP_TARGET_DATA,
+ void_type_node, stmt, omp_clauses);
gfc_add_expr_to_block (&block, stmt);
return gfc_finish_block (&block);
}
@@ -5839,6 +5876,7 @@ gfc_trans_omp_workshare (gfc_code *code, gfc_omp_clauses *clauses)
bool singleblock_in_progress = false;
/* True if previous gfc_code in workshare construct is not workshared. */
bool prev_singleunit;
+ location_t loc = gfc_get_location (&code->loc);
code = code->block->next;
@@ -5929,7 +5967,7 @@ gfc_trans_omp_workshare (gfc_code *code, gfc_omp_clauses *clauses)
{
/* Finish single block and add it to pblock. */
tmp = gfc_finish_block (&singleblock);
- tmp = build2_loc (input_location, OMP_SINGLE,
+ tmp = build2_loc (loc, OMP_SINGLE,
void_type_node, tmp, NULL_TREE);
gfc_add_expr_to_block (pblock, tmp);
/* Add current gfc_code to pblock. */
@@ -5945,6 +5983,7 @@ gfc_trans_omp_workshare (gfc_code *code, gfc_omp_clauses *clauses)
gfc_init_block (&singleblock);
gfc_add_expr_to_block (&singleblock, res);
singleblock_in_progress = true;
+ loc = gfc_get_location (&code->loc);
}
else
/* Add the new statement to the block. */
@@ -5959,7 +5998,7 @@ gfc_trans_omp_workshare (gfc_code *code, gfc_omp_clauses *clauses)
{
/* Finish single block and add it to pblock. */
tmp = gfc_finish_block (&singleblock);
- tmp = build2_loc (input_location, OMP_SINGLE, void_type_node, tmp,
+ tmp = build2_loc (loc, OMP_SINGLE, void_type_node, tmp,
clauses->nowait
? build_omp_clause (input_location, OMP_CLAUSE_NOWAIT)
: NULL_TREE);
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index b7129dc..281cc7d 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -3009,7 +3009,8 @@ create_fn_spec (gfc_symbol *sym, tree fntype)
}
tree
-gfc_get_function_type (gfc_symbol * sym, gfc_actual_arglist *actual_args)
+gfc_get_function_type (gfc_symbol * sym, gfc_actual_arglist *actual_args,
+ const char *fnspec)
{
tree type;
vec<tree, va_gc> *typelist = NULL;
@@ -3193,7 +3194,19 @@ arg_type_list_done:
type = build_varargs_function_type_vec (type, typelist);
else
type = build_function_type_vec (type, typelist);
- type = create_fn_spec (sym, type);
+
+ /* If we were passed an fn spec, add it here, otherwise determine it from
+ the formal arguments. */
+ if (fnspec)
+ {
+ tree tmp;
+ int spec_len = strlen (fnspec);
+ tmp = build_tree_list (NULL_TREE, build_string (spec_len, fnspec));
+ tmp = tree_cons (get_identifier ("fn spec"), tmp, TYPE_ATTRIBUTES (type));
+ type = build_type_attribute_variant (type, tmp);
+ }
+ else
+ type = create_fn_spec (sym, type);
return type;
}
diff --git a/gcc/fortran/trans-types.h b/gcc/fortran/trans-types.h
index 56074f1..1b59287 100644
--- a/gcc/fortran/trans-types.h
+++ b/gcc/fortran/trans-types.h
@@ -88,7 +88,8 @@ tree gfc_sym_type (gfc_symbol *);
tree gfc_typenode_for_spec (gfc_typespec *, int c = 0);
int gfc_copy_dt_decls_ifequal (gfc_symbol *, gfc_symbol *, bool);
-tree gfc_get_function_type (gfc_symbol *, gfc_actual_arglist *args = NULL);
+tree gfc_get_function_type (gfc_symbol *, gfc_actual_arglist *args = NULL,
+ const char *fnspec = NULL);
tree gfc_type_for_size (unsigned, int);
tree gfc_type_for_mode (machine_mode, int);
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 16b4215..6e417c4 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -608,7 +608,8 @@ tree gfc_get_label_decl (gfc_st_label *);
/* Return the decl for an external function. */
tree gfc_get_extern_function_decl (gfc_symbol *,
- gfc_actual_arglist *args = NULL);
+ gfc_actual_arglist *args = NULL,
+ const char *fnspec = NULL);
/* Return the decl for a function. */
tree gfc_get_function_decl (gfc_symbol *);
diff --git a/gcc/fortran/types.def b/gcc/fortran/types.def
index 7b4925c..5736bba 100644
--- a/gcc/fortran/types.def
+++ b/gcc/fortran/types.def
@@ -70,6 +70,7 @@ DEF_PRIMITIVE_TYPE (BT_CONST_VOLATILE_PTR,
build_pointer_type
(build_qualified_type (void_type_node,
TYPE_QUAL_VOLATILE|TYPE_QUAL_CONST)))
+DEF_PRIMITIVE_TYPE (BT_PTRMODE, (*lang_hooks.types.type_for_mode)(ptr_mode, 0))
DEF_POINTER_TYPE (BT_PTR_LONG, BT_LONG)
DEF_POINTER_TYPE (BT_PTR_ULONGLONG, BT_ULONGLONG)
DEF_POINTER_TYPE (BT_PTR_PTR, BT_PTR)
@@ -117,6 +118,8 @@ DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_SIZE_CONST_VPTR, BT_BOOL, BT_SIZE,
BT_CONST_VOLATILE_PTR)
DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_INT_BOOL, BT_BOOL, BT_INT, BT_BOOL)
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_UINT_UINT, BT_VOID, BT_UINT, BT_UINT)
+DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_PTRMODE,
+ BT_VOID, BT_PTR, BT_PTRMODE)
DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR_PTR, BT_FN_VOID_PTR_PTR)
@@ -149,6 +152,8 @@ DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I16_INT, BT_VOID, BT_VOLATILE_PTR, BT_I16,
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_SIZE_SIZE_PTR, BT_VOID, BT_SIZE, BT_SIZE,
BT_PTR)
DEF_FUNCTION_TYPE_3 (BT_FN_UINT_UINT_PTR_PTR, BT_UINT, BT_UINT, BT_PTR, BT_PTR)
+DEF_FUNCTION_TYPE_3 (BT_FN_PTR_SIZE_SIZE_PTRMODE,
+ BT_PTR, BT_SIZE, BT_SIZE, BT_PTRMODE)
DEF_FUNCTION_TYPE_4 (BT_FN_VOID_OMPFN_PTR_UINT_UINT,
BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR, BT_UINT, BT_UINT)
diff --git a/gcc/function.c b/gcc/function.c
index 004fa38..af9618e 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -2206,13 +2206,15 @@ use_register_for_decl (const_tree decl)
/* Otherwise, if RESULT_DECL is DECL_BY_REFERENCE, it will take
the function_result_decl's assignment. Since it's a pointer,
we can short-circuit a number of the tests below, and we must
- duplicat e them because we don't have the
- function_result_decl to test. */
+ duplicate them because we don't have the function_result_decl
+ to test. */
if (!targetm.calls.allocate_stack_slots_for_args ())
return true;
/* We don't set DECL_IGNORED_P for the function_result_decl. */
if (optimize)
return true;
+ if (cfun->tail_call_marked)
+ return true;
/* We don't set DECL_REGISTER for the function_result_decl. */
return false;
}
@@ -5880,6 +5882,10 @@ gen_call_used_regs_seq (rtx_insn *ret, unsigned int zero_regs_type)
continue;
if (only_arg && !FUNCTION_ARG_REGNO_P (regno))
continue;
+#ifdef LEAF_REG_REMAP
+ if (crtl->uses_only_leaf_regs && LEAF_REG_REMAP (regno) < 0)
+ continue;
+#endif
/* Now this is a register that we might want to zero. */
SET_HARD_REG_BIT (selected_hardregs, regno);
diff --git a/gcc/gcc.c b/gcc/gcc.c
index cdf4d4f..1d32375 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -542,6 +542,12 @@ or with constant text in a single argument.
%s current argument is the name of a library or startup file of some sort.
Search for that file in a standard list of directories
and substitute the full name found.
+ %T current argument is the name of a linker script.
+ Search for that file in the current list of directories to scan for
+ libraries. If the file is located, insert a --script option into the
+ command line followed by the full path name found. If the file is
+ not found then generate an error message.
+ Note: the current working directory is not searched.
%eSTR Print STR as an error message. STR is terminated by a newline.
Use this when inconsistent options are detected.
%nSTR Print STR as a notice. STR is terminated by a newline.
@@ -743,6 +749,24 @@ proper position among the other output files. */
#define LIBASAN_EARLY_SPEC ""
#endif
+#ifndef LIBHWASAN_SPEC
+#define STATIC_LIBHWASAN_LIBS \
+ " %{static-libhwasan|static:%:include(libsanitizer.spec)%(link_libhwasan)}"
+#ifdef LIBHWASAN_EARLY_SPEC
+#define LIBHWASAN_SPEC STATIC_LIBHWASAN_LIBS
+#elif defined(HAVE_LD_STATIC_DYNAMIC)
+#define LIBHWASAN_SPEC "%{static-libhwasan:" LD_STATIC_OPTION \
+ "} -lhwasan %{static-libhwasan:" LD_DYNAMIC_OPTION "}" \
+ STATIC_LIBHWASAN_LIBS
+#else
+#define LIBHWASAN_SPEC "-lhwasan" STATIC_LIBHWASAN_LIBS
+#endif
+#endif
+
+#ifndef LIBHWASAN_EARLY_SPEC
+#define LIBHWASAN_EARLY_SPEC ""
+#endif
+
#ifndef LIBTSAN_SPEC
#define STATIC_LIBTSAN_LIBS \
" %{static-libtsan|static:%:include(libsanitizer.spec)%(link_libtsan)}"
@@ -1065,6 +1089,7 @@ proper position among the other output files. */
#ifndef SANITIZER_EARLY_SPEC
#define SANITIZER_EARLY_SPEC "\
%{!nostdlib:%{!r:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_EARLY_SPEC "} \
+ %{%:sanitize(hwaddress):" LIBHWASAN_EARLY_SPEC "} \
%{%:sanitize(thread):" LIBTSAN_EARLY_SPEC "} \
%{%:sanitize(leak):" LIBLSAN_EARLY_SPEC "}}}}"
#endif
@@ -1074,6 +1099,8 @@ proper position among the other output files. */
#define SANITIZER_SPEC "\
%{!nostdlib:%{!r:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_SPEC "\
%{static:%ecannot specify -static with -fsanitize=address}}\
+ %{%:sanitize(hwaddress):" LIBHWASAN_SPEC "\
+ %{static:%ecannot specify -static with -fsanitize=hwaddress}}\
%{%:sanitize(thread):" LIBTSAN_SPEC "\
%{static:%ecannot specify -static with -fsanitize=thread}}\
%{%:sanitize(undefined):" LIBUBSAN_SPEC "}\
@@ -1206,7 +1233,7 @@ static const char *cpp_unique_options =
%{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
%{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
%{!E:%{!M:%{!MM:%{!MT:%{!MQ:%{MD|MMD:%{o*:-MQ %*}}}}}}}\
- %{remap} %{g3|ggdb3|gstabs3|gxcoff3|gvms3:-dD}\
+ %{remap} %{%:debug-level-gt(2):-dD}\
%{!iplugindir*:%{fplugin*:%:find-plugindir()}}\
%{H} %C %{D*&U*&A*} %{i*} %Z %i\
%{E|M|MM:%W{o*}}";
@@ -3653,7 +3680,7 @@ convert_filename (const char *name, int do_exe ATTRIBUTE_UNUSED,
#if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
/* If there is no filetype, make it the executable suffix (which includes
the "."). But don't get confused if we have just "-o". */
- if (! do_exe || TARGET_EXECUTABLE_SUFFIX[0] == 0 || (len == 2 && name[0] == '-'))
+ if (! do_exe || TARGET_EXECUTABLE_SUFFIX[0] == 0 || not_actual_file_p (name))
return name;
for (i = len - 1; i >= 0; i--)
@@ -9748,6 +9775,7 @@ print_multilib_info (void)
const char *p = multilib_select;
const char *last_path = 0, *this_path;
int skip;
+ int not_arg;
unsigned int last_path_len = 0;
while (*p != '\0')
@@ -9902,9 +9930,13 @@ print_multilib_info (void)
goto invalid_select;
if (*q == '!')
- arg = NULL;
+ {
+ not_arg = 1;
+ q++;
+ }
else
- arg = q;
+ not_arg = 0;
+ arg = q;
while (*q != ' ' && *q != ';')
{
@@ -9913,11 +9945,17 @@ print_multilib_info (void)
++q;
}
- if (arg != NULL
- && default_arg (arg, q - arg))
+ if (default_arg (arg, q - arg))
{
- skip = 1;
- break;
+ /* Stop checking if any default arguments appeared in not
+ list. */
+ if (not_arg)
+ {
+ skip = 0;
+ break;
+ }
+ else
+ skip = 1;
}
if (*q == ' ')
@@ -10125,8 +10163,12 @@ sanitize_spec_function (int argc, const char **argv)
if (strcmp (argv[0], "address") == 0)
return (flag_sanitize & SANITIZE_USER_ADDRESS) ? "" : NULL;
+ if (strcmp (argv[0], "hwaddress") == 0)
+ return (flag_sanitize & SANITIZE_USER_HWADDRESS) ? "" : NULL;
if (strcmp (argv[0], "kernel-address") == 0)
return (flag_sanitize & SANITIZE_KERNEL_ADDRESS) ? "" : NULL;
+ if (strcmp (argv[0], "kernel-hwaddress") == 0)
+ return (flag_sanitize & SANITIZE_KERNEL_HWADDRESS) ? "" : NULL;
if (strcmp (argv[0], "thread") == 0)
return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL;
if (strcmp (argv[0], "undefined") == 0)
@@ -10544,7 +10586,7 @@ static bool
not_actual_file_p (const char *name)
{
return (strcmp (name, "-") == 0
- || strcmp (output_file, HOST_BIT_BUCKET) == 0);
+ || strcmp (name, HOST_BIT_BUCKET) == 0);
}
/* %:dumps spec function. Take an optional argument that overrides
diff --git a/gcc/gdbinit.in b/gcc/gdbinit.in
index e951c19..f2becb4 100644
--- a/gcc/gdbinit.in
+++ b/gcc/gdbinit.in
@@ -46,7 +46,7 @@ call debug ($debug_arg)
end
document pp
-GCC hook: pp [any]
+GCC hook: debug (<multiple overloads>)
Print a representation of any GCC data structure for which an instance of
overloaded function 'debug' is available.
See also 'help-gcc-hooks'.
@@ -58,7 +58,7 @@ call debug_rtx ($debug_arg)
end
document pr
-GCC hook: pr [rtx]
+GCC hook: debug_rtx (rtx)
Print the full structure of given rtx.
See also 'help-gcc-hooks'.
end
@@ -69,7 +69,7 @@ call debug_rtx_list ($debug_arg, debug_rtx_count)
end
document prl
-GCC hook: prl [rtx]
+GCC hook: debug_rtx_list (rtx)
Print the full structure of all rtx insns beginning at given rtx.
Uses variable debug_rtx_count to control number of insns printed:
debug_rtx_count > 0: print from given rtx on.
@@ -85,7 +85,7 @@ call debug_tree ($debug_arg)
end
document pt
-GCC hook: pt [tree]
+GCC hook: debug_tree (tree)
Print the full structure of given tree.
See also 'help-gcc-hooks'.
end
@@ -96,7 +96,7 @@ call debug_c_tree ($debug_arg)
end
document pct
-GCC hook: pct [tree]
+GCC hook: debug_c_tree (tree)
Print given tree in C syntax.
See also 'help-gcc-hooks'.
end
@@ -107,7 +107,7 @@ call debug_gimple_stmt ($debug_arg)
end
document pgg
-GCC hook: pgg [gimple]
+GCC hook: debug_gimple_stmt (gimple)
Print given GIMPLE statement in C syntax.
See also 'help-gcc-hooks'.
end
@@ -118,7 +118,7 @@ call debug_gimple_seq ($debug_arg)
end
document pgq
-GCC hook: pgq [gimple_seq]
+GCC hook: debug_gimple_seq (gimple_seq)
Print given GIMPLE sequence in C syntax.
See also 'help-gcc-hooks'.
end
@@ -129,7 +129,7 @@ call debug_generic_stmt ($debug_arg)
end
document pgs
-GCC hook: pgs [tree]
+GCC hook: debug_generic_stmt (tree)
Print given GENERIC statement in C syntax.
See also 'help-gcc-hooks'.
end
@@ -140,7 +140,7 @@ call debug_generic_expr ($debug_arg)
end
document pge
-GCC hook: pge [tree]
+GCC hook: debug_generic_expr (tree)
Print given GENERIC expression in C syntax.
See also 'help-gcc-hooks'.
end
@@ -151,7 +151,7 @@ call mpz_out_str(stderr, 10, $debug_arg)
end
document pmz
-GCC hook: pmz [mpz_t]
+GCC hook: mpz_out_str (mpz_t)
Print given mpz value.
See also 'help-gcc-hooks'.
end
@@ -163,7 +163,7 @@ echo \n
end
document ptc
-GCC hook: ptc [tree]
+GCC hook: TREE_CODE (tree)
Print the tree-code of given tree node.
See also 'help-gcc-hooks'.
end
@@ -175,7 +175,7 @@ echo \n
end
document pdn
-GCC hook: pdn [tree]
+GCC hook: IDENTIFIER_POINTER (DECL_NAME (tree))
Print the name of given decl-node.
See also 'help-gcc-hooks'.
end
@@ -187,7 +187,7 @@ echo \n
end
document ptn
-GCC hook: ptn [tree]
+GCC hook: IDENTIFIER_POINTER (DECL_NAME (TREE_TYPE (tree)))
Print the name of given type-node.
See also 'help-gcc-hooks'.
end
@@ -198,7 +198,7 @@ call debug_dwarf_die ($debug_arg)
end
document pdd
-GCC hook: pdd [dw_die_ref]
+GCC hook: debug_dwarf_die (dw_die_ref)
Print given dw_die_ref.
See also 'help-gcc-hooks'.
end
@@ -212,7 +212,7 @@ echo )\n
end
document prc
-GCC hook: prc [rtx]
+GCC hook: GET_CODE (rtx)
Print the rtx-code and machine mode of given rtx.
See also 'help-gcc-hooks'.
end
@@ -223,7 +223,7 @@ print $debug_arg.u.fld[0].rt_rtx@7
end
document pi
-GCC hook: pi [rtx_insn]
+GCC hook: X0EXP (rtx_insn)
Print the fields of given RTL instruction.
See also 'help-gcc-hooks'.
end
@@ -243,7 +243,7 @@ call bitmap_print (stderr, $debug_arg, "", "\n")
end
document pbm
-GCC hook: pbm [bitmap]
+GCC hook: bitmap_print (bitmap)
Dump given bitmap as a comma-separated list of numbers.
See also 'help-gcc-hooks'.
end
@@ -255,7 +255,7 @@ echo \n
end
document pel
-GCC hook: pel [location_t]
+GCC hook: expand_location (location_t)
Print given location.
See also 'help-gcc-hooks'.
end
@@ -275,7 +275,7 @@ print ($debug_arg.typed.type)
end
document trt
-GCC hook: trt [tree]
+GCC hook: TREE_TYPE (tree)
Print TREE_TYPE of given tree node.
See also 'help-gcc-hooks'.
end
diff --git a/gcc/genmodes.c b/gcc/genmodes.c
index bd78310..34b52fe 100644
--- a/gcc/genmodes.c
+++ b/gcc/genmodes.c
@@ -358,6 +358,14 @@ complete_mode (struct mode_data *m)
m->component = 0;
break;
+ case MODE_OPAQUE:
+ /* Opaque modes have size and precision. */
+ validate_mode (m, OPTIONAL, SET, UNSET, UNSET, UNSET);
+
+ m->ncomponents = 1;
+ m->component = 0;
+ break;
+
case MODE_PARTIAL_INT:
/* A partial integer mode uses ->component to say what the
corresponding full-size integer mode is, and may also
@@ -588,6 +596,20 @@ make_int_mode (const char *name,
m->precision = precision;
}
+#define OPAQUE_MODE(N, B) \
+ make_opaque_mode (#N, -1U, B, __FILE__, __LINE__)
+
+static void ATTRIBUTE_UNUSED
+make_opaque_mode (const char *name,
+ unsigned int precision,
+ unsigned int bytesize,
+ const char *file, unsigned int line)
+{
+ struct mode_data *m = new_mode (MODE_OPAQUE, name, file, line);
+ m->bytesize = bytesize;
+ m->precision = precision;
+}
+
#define FRACT_MODE(N, Y, F) \
make_fixed_point_mode (MODE_FRACT, #N, Y, 0, F, __FILE__, __LINE__)
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index ca38a31..3148c6b 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -2689,7 +2689,7 @@ gimple_fold_builtin_memchr (gimple_stmt_iterator *gsi)
gimple_seq stmts = NULL;
if (lhs != NULL_TREE)
{
- tree offset_cst = build_int_cst (TREE_TYPE (len), offset);
+ tree offset_cst = build_int_cst (sizetype, offset);
gassign *stmt = gimple_build_assign (lhs, POINTER_PLUS_EXPR,
arg1, offset_cst);
gimple_seq_add_stmt_without_update (&stmts, stmt);
@@ -3948,6 +3948,858 @@ gimple_fold_builtin_realloc (gimple_stmt_iterator *gsi)
return false;
}
+/* Number of bytes into which any type but aggregate or vector types
+ should fit. */
+static constexpr size_t clear_padding_unit
+ = MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT;
+/* Buffer size on which __builtin_clear_padding folding code works. */
+static const size_t clear_padding_buf_size = 32 * clear_padding_unit;
+
+/* Data passed through __builtin_clear_padding folding. */
+struct clear_padding_struct {
+ location_t loc;
+ /* 0 during __builtin_clear_padding folding, nonzero during
+ clear_type_padding_in_mask. In that case, instead of clearing the
+ non-padding bits in union_ptr array clear the padding bits in there. */
+ bool clear_in_mask;
+ tree base;
+ tree alias_type;
+ gimple_stmt_iterator *gsi;
+ /* Alignment of buf->base + 0. */
+ unsigned align;
+ /* Offset from buf->base. Should be always a multiple of UNITS_PER_WORD. */
+ HOST_WIDE_INT off;
+ /* Number of padding bytes before buf->off that don't have padding clear
+ code emitted yet. */
+ HOST_WIDE_INT padding_bytes;
+ /* The size of the whole object. Never emit code to touch
+ buf->base + buf->sz or following bytes. */
+ HOST_WIDE_INT sz;
+ /* Number of bytes recorded in buf->buf. */
+ size_t size;
+ /* When inside union, instead of emitting code we and bits inside of
+ the union_ptr array. */
+ unsigned char *union_ptr;
+ /* Set bits mean padding bits that need to be cleared by the builtin. */
+ unsigned char buf[clear_padding_buf_size + clear_padding_unit];
+};
+
+/* Emit code to clear padding requested in BUF->buf - set bits
+ in there stand for padding that should be cleared. FULL is true
+ if everything from the buffer should be flushed, otherwise
+ it can leave up to 2 * clear_padding_unit bytes for further
+ processing. */
+
+static void
+clear_padding_flush (clear_padding_struct *buf, bool full)
+{
+ gcc_assert ((clear_padding_unit % UNITS_PER_WORD) == 0);
+ if (!full && buf->size < 2 * clear_padding_unit)
+ return;
+ gcc_assert ((buf->off % UNITS_PER_WORD) == 0);
+ size_t end = buf->size;
+ if (!full)
+ end = ((end - clear_padding_unit - 1) / clear_padding_unit
+ * clear_padding_unit);
+ size_t padding_bytes = buf->padding_bytes;
+ if (buf->union_ptr)
+ {
+ if (buf->clear_in_mask)
+ {
+ /* During clear_type_padding_in_mask, clear the padding
+ bits set in buf->buf in the buf->union_ptr mask. */
+ for (size_t i = 0; i < end; i++)
+ {
+ if (buf->buf[i] == (unsigned char) ~0)
+ padding_bytes++;
+ else
+ {
+ memset (&buf->union_ptr[buf->off + i - padding_bytes],
+ 0, padding_bytes);
+ padding_bytes = 0;
+ buf->union_ptr[buf->off + i] &= ~buf->buf[i];
+ }
+ }
+ if (full)
+ {
+ memset (&buf->union_ptr[buf->off + end - padding_bytes],
+ 0, padding_bytes);
+ buf->off = 0;
+ buf->size = 0;
+ buf->padding_bytes = 0;
+ }
+ else
+ {
+ memmove (buf->buf, buf->buf + end, buf->size - end);
+ buf->off += end;
+ buf->size -= end;
+ buf->padding_bytes = padding_bytes;
+ }
+ return;
+ }
+ /* Inside of a union, instead of emitting any code, instead
+ clear all bits in the union_ptr buffer that are clear
+ in buf. Whole padding bytes don't clear anything. */
+ for (size_t i = 0; i < end; i++)
+ {
+ if (buf->buf[i] == (unsigned char) ~0)
+ padding_bytes++;
+ else
+ {
+ padding_bytes = 0;
+ buf->union_ptr[buf->off + i] &= buf->buf[i];
+ }
+ }
+ if (full)
+ {
+ buf->off = 0;
+ buf->size = 0;
+ buf->padding_bytes = 0;
+ }
+ else
+ {
+ memmove (buf->buf, buf->buf + end, buf->size - end);
+ buf->off += end;
+ buf->size -= end;
+ buf->padding_bytes = padding_bytes;
+ }
+ return;
+ }
+ size_t wordsize = UNITS_PER_WORD;
+ for (size_t i = 0; i < end; i += wordsize)
+ {
+ size_t nonzero_first = wordsize;
+ size_t nonzero_last = 0;
+ size_t zero_first = wordsize;
+ size_t zero_last = 0;
+ bool all_ones = true, bytes_only = true;
+ if ((unsigned HOST_WIDE_INT) (buf->off + i + wordsize)
+ > (unsigned HOST_WIDE_INT) buf->sz)
+ {
+ gcc_assert (wordsize > 1);
+ wordsize /= 2;
+ i -= wordsize;
+ continue;
+ }
+ for (size_t j = i; j < i + wordsize && j < end; j++)
+ {
+ if (buf->buf[j])
+ {
+ if (nonzero_first == wordsize)
+ {
+ nonzero_first = j - i;
+ nonzero_last = j - i;
+ }
+ if (nonzero_last != j - i)
+ all_ones = false;
+ nonzero_last = j + 1 - i;
+ }
+ else
+ {
+ if (zero_first == wordsize)
+ zero_first = j - i;
+ zero_last = j + 1 - i;
+ }
+ if (buf->buf[j] != 0 && buf->buf[j] != (unsigned char) ~0)
+ {
+ all_ones = false;
+ bytes_only = false;
+ }
+ }
+ size_t padding_end = i;
+ if (padding_bytes)
+ {
+ if (nonzero_first == 0
+ && nonzero_last == wordsize
+ && all_ones)
+ {
+ /* All bits are padding and we had some padding
+ before too. Just extend it. */
+ padding_bytes += wordsize;
+ continue;
+ }
+ if (all_ones && nonzero_first == 0)
+ {
+ padding_bytes += nonzero_last;
+ padding_end += nonzero_last;
+ nonzero_first = wordsize;
+ nonzero_last = 0;
+ }
+ else if (bytes_only && nonzero_first == 0)
+ {
+ gcc_assert (zero_first && zero_first != wordsize);
+ padding_bytes += zero_first;
+ padding_end += zero_first;
+ }
+ tree atype, src;
+ if (padding_bytes == 1)
+ {
+ atype = char_type_node;
+ src = build_zero_cst (char_type_node);
+ }
+ else
+ {
+ atype = build_array_type_nelts (char_type_node, padding_bytes);
+ src = build_constructor (atype, NULL);
+ }
+ tree dst = build2_loc (buf->loc, MEM_REF, atype, buf->base,
+ build_int_cst (buf->alias_type,
+ buf->off + padding_end
+ - padding_bytes));
+ gimple *g = gimple_build_assign (dst, src);
+ gimple_set_location (g, buf->loc);
+ gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
+ padding_bytes = 0;
+ buf->padding_bytes = 0;
+ }
+ if (nonzero_first == wordsize)
+ /* All bits in a word are 0, there are no padding bits. */
+ continue;
+ if (all_ones && nonzero_last == wordsize)
+ {
+ /* All bits between nonzero_first and end of word are padding
+ bits, start counting padding_bytes. */
+ padding_bytes = nonzero_last - nonzero_first;
+ continue;
+ }
+ if (bytes_only)
+ {
+ /* If bitfields aren't involved in this word, prefer storing
+ individual bytes or groups of them over performing a RMW
+ operation on the whole word. */
+ gcc_assert (i + zero_last <= end);
+ for (size_t j = padding_end; j < i + zero_last; j++)
+ {
+ if (buf->buf[j])
+ {
+ size_t k;
+ for (k = j; k < i + zero_last; k++)
+ if (buf->buf[k] == 0)
+ break;
+ HOST_WIDE_INT off = buf->off + j;
+ tree atype, src;
+ if (k - j == 1)
+ {
+ atype = char_type_node;
+ src = build_zero_cst (char_type_node);
+ }
+ else
+ {
+ atype = build_array_type_nelts (char_type_node, k - j);
+ src = build_constructor (atype, NULL);
+ }
+ tree dst = build2_loc (buf->loc, MEM_REF, atype,
+ buf->base,
+ build_int_cst (buf->alias_type, off));
+ gimple *g = gimple_build_assign (dst, src);
+ gimple_set_location (g, buf->loc);
+ gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
+ j = k;
+ }
+ }
+ if (nonzero_last == wordsize)
+ padding_bytes = nonzero_last - zero_last;
+ continue;
+ }
+ for (size_t eltsz = 1; eltsz <= wordsize; eltsz <<= 1)
+ {
+ if (nonzero_last - nonzero_first <= eltsz
+ && ((nonzero_first & ~(eltsz - 1))
+ == ((nonzero_last - 1) & ~(eltsz - 1))))
+ {
+ tree type;
+ if (eltsz == 1)
+ type = char_type_node;
+ else
+ type = lang_hooks.types.type_for_size (eltsz * BITS_PER_UNIT,
+ 0);
+ size_t start = nonzero_first & ~(eltsz - 1);
+ HOST_WIDE_INT off = buf->off + i + start;
+ tree atype = type;
+ if (eltsz > 1 && buf->align < TYPE_ALIGN (type))
+ atype = build_aligned_type (type, buf->align);
+ tree dst = build2_loc (buf->loc, MEM_REF, atype, buf->base,
+ build_int_cst (buf->alias_type, off));
+ tree src;
+ gimple *g;
+ if (all_ones
+ && nonzero_first == start
+ && nonzero_last == start + eltsz)
+ src = build_zero_cst (type);
+ else
+ {
+ src = make_ssa_name (type);
+ g = gimple_build_assign (src, unshare_expr (dst));
+ gimple_set_location (g, buf->loc);
+ gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
+ tree mask = native_interpret_expr (type,
+ buf->buf + i + start,
+ eltsz);
+ gcc_assert (mask && TREE_CODE (mask) == INTEGER_CST);
+ mask = fold_build1 (BIT_NOT_EXPR, type, mask);
+ tree src_masked = make_ssa_name (type);
+ g = gimple_build_assign (src_masked, BIT_AND_EXPR,
+ src, mask);
+ gimple_set_location (g, buf->loc);
+ gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
+ src = src_masked;
+ }
+ g = gimple_build_assign (dst, src);
+ gimple_set_location (g, buf->loc);
+ gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
+ break;
+ }
+ }
+ }
+ if (full)
+ {
+ if (padding_bytes)
+ {
+ tree atype, src;
+ if (padding_bytes == 1)
+ {
+ atype = char_type_node;
+ src = build_zero_cst (char_type_node);
+ }
+ else
+ {
+ atype = build_array_type_nelts (char_type_node, padding_bytes);
+ src = build_constructor (atype, NULL);
+ }
+ tree dst = build2_loc (buf->loc, MEM_REF, atype, buf->base,
+ build_int_cst (buf->alias_type,
+ buf->off + end
+ - padding_bytes));
+ gimple *g = gimple_build_assign (dst, src);
+ gimple_set_location (g, buf->loc);
+ gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
+ }
+ size_t end_rem = end % UNITS_PER_WORD;
+ buf->off += end - end_rem;
+ buf->size = end_rem;
+ memset (buf->buf, 0, buf->size);
+ buf->padding_bytes = 0;
+ }
+ else
+ {
+ memmove (buf->buf, buf->buf + end, buf->size - end);
+ buf->off += end;
+ buf->size -= end;
+ buf->padding_bytes = padding_bytes;
+ }
+}
+
+/* Append PADDING_BYTES padding bytes. */
+
+static void
+clear_padding_add_padding (clear_padding_struct *buf,
+ HOST_WIDE_INT padding_bytes)
+{
+ if (padding_bytes == 0)
+ return;
+ if ((unsigned HOST_WIDE_INT) padding_bytes + buf->size
+ > (unsigned HOST_WIDE_INT) clear_padding_buf_size)
+ clear_padding_flush (buf, false);
+ if ((unsigned HOST_WIDE_INT) padding_bytes + buf->size
+ > (unsigned HOST_WIDE_INT) clear_padding_buf_size)
+ {
+ memset (buf->buf + buf->size, ~0, clear_padding_buf_size - buf->size);
+ padding_bytes -= clear_padding_buf_size - buf->size;
+ buf->size = clear_padding_buf_size;
+ clear_padding_flush (buf, false);
+ gcc_assert (buf->padding_bytes);
+ /* At this point buf->buf[0] through buf->buf[buf->size - 1]
+ is guaranteed to be all ones. */
+ padding_bytes += buf->size;
+ buf->size = padding_bytes % UNITS_PER_WORD;
+ memset (buf->buf, ~0, buf->size);
+ buf->off += padding_bytes - buf->size;
+ buf->padding_bytes += padding_bytes - buf->size;
+ }
+ else
+ {
+ memset (buf->buf + buf->size, ~0, padding_bytes);
+ buf->size += padding_bytes;
+ }
+}
+
+static void clear_padding_type (clear_padding_struct *, tree, HOST_WIDE_INT);
+
+/* Clear padding bits of union type TYPE. */
+
+static void
+clear_padding_union (clear_padding_struct *buf, tree type, HOST_WIDE_INT sz)
+{
+ clear_padding_struct *union_buf;
+ HOST_WIDE_INT start_off = 0, next_off = 0;
+ size_t start_size = 0;
+ if (buf->union_ptr)
+ {
+ start_off = buf->off + buf->size;
+ next_off = start_off + sz;
+ start_size = start_off % UNITS_PER_WORD;
+ start_off -= start_size;
+ clear_padding_flush (buf, true);
+ union_buf = buf;
+ }
+ else
+ {
+ if (sz + buf->size > clear_padding_buf_size)
+ clear_padding_flush (buf, false);
+ union_buf = XALLOCA (clear_padding_struct);
+ union_buf->loc = buf->loc;
+ union_buf->clear_in_mask = buf->clear_in_mask;
+ union_buf->base = NULL_TREE;
+ union_buf->alias_type = NULL_TREE;
+ union_buf->gsi = NULL;
+ union_buf->align = 0;
+ union_buf->off = 0;
+ union_buf->padding_bytes = 0;
+ union_buf->sz = sz;
+ union_buf->size = 0;
+ if (sz + buf->size <= clear_padding_buf_size)
+ union_buf->union_ptr = buf->buf + buf->size;
+ else
+ union_buf->union_ptr = XNEWVEC (unsigned char, sz);
+ memset (union_buf->union_ptr, ~0, sz);
+ }
+
+ for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL && !DECL_PADDING_P (field))
+ {
+ if (DECL_SIZE_UNIT (field) == NULL_TREE)
+ {
+ if (TREE_TYPE (field) == error_mark_node)
+ continue;
+ gcc_assert (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
+ && !COMPLETE_TYPE_P (TREE_TYPE (field)));
+ if (!buf->clear_in_mask)
+ error_at (buf->loc, "flexible array member %qD does not have "
+ "well defined padding bits for %qs",
+ field, "__builtin_clear_padding");
+ continue;
+ }
+ HOST_WIDE_INT fldsz = tree_to_shwi (DECL_SIZE_UNIT (field));
+ gcc_assert (union_buf->size == 0);
+ union_buf->off = start_off;
+ union_buf->size = start_size;
+ memset (union_buf->buf, ~0, start_size);
+ clear_padding_type (union_buf, TREE_TYPE (field), fldsz);
+ clear_padding_add_padding (union_buf, sz - fldsz);
+ clear_padding_flush (union_buf, true);
+ }
+
+ if (buf == union_buf)
+ {
+ buf->off = next_off;
+ buf->size = next_off % UNITS_PER_WORD;
+ buf->off -= buf->size;
+ memset (buf->buf, ~0, buf->size);
+ }
+ else if (sz + buf->size <= clear_padding_buf_size)
+ buf->size += sz;
+ else
+ {
+ unsigned char *union_ptr = union_buf->union_ptr;
+ while (sz)
+ {
+ clear_padding_flush (buf, false);
+ HOST_WIDE_INT this_sz
+ = MIN ((unsigned HOST_WIDE_INT) sz,
+ clear_padding_buf_size - buf->size);
+ memcpy (buf->buf + buf->size, union_ptr, this_sz);
+ buf->size += this_sz;
+ union_ptr += this_sz;
+ sz -= this_sz;
+ }
+ XDELETE (union_buf->union_ptr);
+ }
+}
+
+/* The only known floating point formats with padding bits are the
+ IEEE extended ones. */
+
+static bool
+clear_padding_real_needs_padding_p (tree type)
+{
+ const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
+ return (fmt->b == 2
+ && fmt->signbit_ro == fmt->signbit_rw
+ && (fmt->signbit_ro == 79 || fmt->signbit_ro == 95));
+}
+
+/* Return true if TYPE might contain any padding bits. */
+
+static bool
+clear_padding_type_may_have_padding_p (tree type)
+{
+ switch (TREE_CODE (type))
+ {
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ return true;
+ case ARRAY_TYPE:
+ case COMPLEX_TYPE:
+ case VECTOR_TYPE:
+ return clear_padding_type_may_have_padding_p (TREE_TYPE (type));
+ case REAL_TYPE:
+ return clear_padding_real_needs_padding_p (type);
+ default:
+ return false;
+ }
+}
+
+/* Emit a runtime loop:
+ for (; buf.base != end; buf.base += sz)
+ __builtin_clear_padding (buf.base); */
+
+static void
+clear_padding_emit_loop (clear_padding_struct *buf, tree type, tree end)
+{
+ tree l1 = create_artificial_label (buf->loc);
+ tree l2 = create_artificial_label (buf->loc);
+ tree l3 = create_artificial_label (buf->loc);
+ gimple *g = gimple_build_goto (l2);
+ gimple_set_location (g, buf->loc);
+ gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
+ g = gimple_build_label (l1);
+ gimple_set_location (g, buf->loc);
+ gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
+ clear_padding_type (buf, type, buf->sz);
+ clear_padding_flush (buf, true);
+ g = gimple_build_assign (buf->base, POINTER_PLUS_EXPR, buf->base,
+ size_int (buf->sz));
+ gimple_set_location (g, buf->loc);
+ gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
+ g = gimple_build_label (l2);
+ gimple_set_location (g, buf->loc);
+ gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
+ g = gimple_build_cond (NE_EXPR, buf->base, end, l1, l3);
+ gimple_set_location (g, buf->loc);
+ gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
+ g = gimple_build_label (l3);
+ gimple_set_location (g, buf->loc);
+ gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
+}
+
+/* Clear padding bits for TYPE. Called recursively from
+ gimple_fold_builtin_clear_padding. */
+
+static void
+clear_padding_type (clear_padding_struct *buf, tree type, HOST_WIDE_INT sz)
+{
+ switch (TREE_CODE (type))
+ {
+ case RECORD_TYPE:
+ HOST_WIDE_INT cur_pos;
+ cur_pos = 0;
+ for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL && !DECL_PADDING_P (field))
+ {
+ tree ftype = TREE_TYPE (field);
+ if (DECL_BIT_FIELD (field))
+ {
+ HOST_WIDE_INT fldsz = TYPE_PRECISION (ftype);
+ if (fldsz == 0)
+ continue;
+ HOST_WIDE_INT pos = int_byte_position (field);
+ HOST_WIDE_INT bpos
+ = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field));
+ bpos %= BITS_PER_UNIT;
+ HOST_WIDE_INT end
+ = ROUND_UP (bpos + fldsz, BITS_PER_UNIT) / BITS_PER_UNIT;
+ if (pos + end > cur_pos)
+ {
+ clear_padding_add_padding (buf, pos + end - cur_pos);
+ cur_pos = pos + end;
+ }
+ gcc_assert (cur_pos > pos
+ && ((unsigned HOST_WIDE_INT) buf->size
+ >= (unsigned HOST_WIDE_INT) cur_pos - pos));
+ unsigned char *p = buf->buf + buf->size - (cur_pos - pos);
+ if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
+ sorry_at (buf->loc, "PDP11 bit-field handling unsupported"
+ " in %qs", "__builtin_clear_padding");
+ else if (BYTES_BIG_ENDIAN)
+ {
+ /* Big endian. */
+ if (bpos + fldsz <= BITS_PER_UNIT)
+ *p &= ~(((1 << fldsz) - 1)
+ << (BITS_PER_UNIT - bpos - fldsz));
+ else
+ {
+ if (bpos)
+ {
+ *p &= ~(((1U << BITS_PER_UNIT) - 1) >> bpos);
+ p++;
+ fldsz -= BITS_PER_UNIT - bpos;
+ }
+ memset (p, 0, fldsz / BITS_PER_UNIT);
+ p += fldsz / BITS_PER_UNIT;
+ fldsz %= BITS_PER_UNIT;
+ if (fldsz)
+ *p &= ((1U << BITS_PER_UNIT) - 1) >> fldsz;
+ }
+ }
+ else
+ {
+ /* Little endian. */
+ if (bpos + fldsz <= BITS_PER_UNIT)
+ *p &= ~(((1 << fldsz) - 1) << bpos);
+ else
+ {
+ if (bpos)
+ {
+ *p &= ~(((1 << BITS_PER_UNIT) - 1) << bpos);
+ p++;
+ fldsz -= BITS_PER_UNIT - bpos;
+ }
+ memset (p, 0, fldsz / BITS_PER_UNIT);
+ p += fldsz / BITS_PER_UNIT;
+ fldsz %= BITS_PER_UNIT;
+ if (fldsz)
+ *p &= ~((1 << fldsz) - 1);
+ }
+ }
+ }
+ else if (DECL_SIZE_UNIT (field) == NULL_TREE)
+ {
+ if (ftype == error_mark_node)
+ continue;
+ gcc_assert (TREE_CODE (ftype) == ARRAY_TYPE
+ && !COMPLETE_TYPE_P (ftype));
+ if (!buf->clear_in_mask)
+ error_at (buf->loc, "flexible array member %qD does not "
+ "have well defined padding bits for %qs",
+ field, "__builtin_clear_padding");
+ }
+ else if (is_empty_type (TREE_TYPE (field)))
+ continue;
+ else
+ {
+ HOST_WIDE_INT pos = int_byte_position (field);
+ HOST_WIDE_INT fldsz = tree_to_shwi (DECL_SIZE_UNIT (field));
+ gcc_assert (pos >= 0 && fldsz >= 0 && pos >= cur_pos);
+ clear_padding_add_padding (buf, pos - cur_pos);
+ cur_pos = pos;
+ clear_padding_type (buf, TREE_TYPE (field), fldsz);
+ cur_pos += fldsz;
+ }
+ }
+ gcc_assert (sz >= cur_pos);
+ clear_padding_add_padding (buf, sz - cur_pos);
+ break;
+ case ARRAY_TYPE:
+ HOST_WIDE_INT nelts, fldsz;
+ fldsz = int_size_in_bytes (TREE_TYPE (type));
+ if (fldsz == 0)
+ break;
+ nelts = sz / fldsz;
+ if (nelts > 1
+ && sz > 8 * UNITS_PER_WORD
+ && buf->union_ptr == NULL
+ && clear_padding_type_may_have_padding_p (TREE_TYPE (type)))
+ {
+ /* For sufficiently large array of more than one elements,
+ emit a runtime loop to keep code size manageable. */
+ tree base = buf->base;
+ unsigned int prev_align = buf->align;
+ HOST_WIDE_INT off = buf->off + buf->size;
+ HOST_WIDE_INT prev_sz = buf->sz;
+ clear_padding_flush (buf, true);
+ tree elttype = TREE_TYPE (type);
+ buf->base = create_tmp_var (build_pointer_type (elttype));
+ tree end = make_ssa_name (TREE_TYPE (buf->base));
+ gimple *g = gimple_build_assign (buf->base, POINTER_PLUS_EXPR,
+ base, size_int (off));
+ gimple_set_location (g, buf->loc);
+ gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
+ g = gimple_build_assign (end, POINTER_PLUS_EXPR, buf->base,
+ size_int (sz));
+ gimple_set_location (g, buf->loc);
+ gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
+ buf->sz = fldsz;
+ buf->align = TYPE_ALIGN (elttype);
+ buf->off = 0;
+ buf->size = 0;
+ clear_padding_emit_loop (buf, elttype, end);
+ buf->base = base;
+ buf->sz = prev_sz;
+ buf->align = prev_align;
+ buf->size = off % UNITS_PER_WORD;
+ buf->off = off - buf->size;
+ memset (buf->buf, 0, buf->size);
+ break;
+ }
+ for (HOST_WIDE_INT i = 0; i < nelts; i++)
+ clear_padding_type (buf, TREE_TYPE (type), fldsz);
+ break;
+ case UNION_TYPE:
+ clear_padding_union (buf, type, sz);
+ break;
+ case REAL_TYPE:
+ gcc_assert ((size_t) sz <= clear_padding_unit);
+ if ((unsigned HOST_WIDE_INT) sz + buf->size > clear_padding_buf_size)
+ clear_padding_flush (buf, false);
+ if (clear_padding_real_needs_padding_p (type))
+ {
+ /* Use native_interpret_expr + native_encode_expr to figure out
+ which bits are padding. */
+ memset (buf->buf + buf->size, ~0, sz);
+ tree cst = native_interpret_expr (type, buf->buf + buf->size, sz);
+ gcc_assert (cst && TREE_CODE (cst) == REAL_CST);
+ int len = native_encode_expr (cst, buf->buf + buf->size, sz);
+ gcc_assert (len > 0 && (size_t) len == (size_t) sz);
+ for (size_t i = 0; i < (size_t) sz; i++)
+ buf->buf[buf->size + i] ^= ~0;
+ }
+ else
+ memset (buf->buf + buf->size, 0, sz);
+ buf->size += sz;
+ break;
+ case COMPLEX_TYPE:
+ fldsz = int_size_in_bytes (TREE_TYPE (type));
+ clear_padding_type (buf, TREE_TYPE (type), fldsz);
+ clear_padding_type (buf, TREE_TYPE (type), fldsz);
+ break;
+ case VECTOR_TYPE:
+ nelts = TYPE_VECTOR_SUBPARTS (type).to_constant ();
+ fldsz = int_size_in_bytes (TREE_TYPE (type));
+ for (HOST_WIDE_INT i = 0; i < nelts; i++)
+ clear_padding_type (buf, TREE_TYPE (type), fldsz);
+ break;
+ case NULLPTR_TYPE:
+ gcc_assert ((size_t) sz <= clear_padding_unit);
+ if ((unsigned HOST_WIDE_INT) sz + buf->size > clear_padding_buf_size)
+ clear_padding_flush (buf, false);
+ memset (buf->buf + buf->size, ~0, sz);
+ buf->size += sz;
+ break;
+ default:
+ gcc_assert ((size_t) sz <= clear_padding_unit);
+ if ((unsigned HOST_WIDE_INT) sz + buf->size > clear_padding_buf_size)
+ clear_padding_flush (buf, false);
+ memset (buf->buf + buf->size, 0, sz);
+ buf->size += sz;
+ break;
+ }
+}
+
+/* Clear padding bits of TYPE in MASK. */
+
+void
+clear_type_padding_in_mask (tree type, unsigned char *mask)
+{
+ clear_padding_struct buf;
+ buf.loc = UNKNOWN_LOCATION;
+ buf.clear_in_mask = true;
+ buf.base = NULL_TREE;
+ buf.alias_type = NULL_TREE;
+ buf.gsi = NULL;
+ buf.align = 0;
+ buf.off = 0;
+ buf.padding_bytes = 0;
+ buf.sz = int_size_in_bytes (type);
+ buf.size = 0;
+ buf.union_ptr = mask;
+ clear_padding_type (&buf, type, buf.sz);
+ clear_padding_flush (&buf, true);
+}
+
+/* Fold __builtin_clear_padding builtin. */
+
+static bool
+gimple_fold_builtin_clear_padding (gimple_stmt_iterator *gsi)
+{
+ gimple *stmt = gsi_stmt (*gsi);
+ gcc_assert (gimple_call_num_args (stmt) == 2);
+ tree ptr = gimple_call_arg (stmt, 0);
+ tree typearg = gimple_call_arg (stmt, 1);
+ tree type = TREE_TYPE (TREE_TYPE (typearg));
+ location_t loc = gimple_location (stmt);
+ clear_padding_struct buf;
+ gimple_stmt_iterator gsiprev = *gsi;
+ /* This should be folded during the lower pass. */
+ gcc_assert (!gimple_in_ssa_p (cfun) && cfun->cfg == NULL);
+ gcc_assert (COMPLETE_TYPE_P (type));
+ gsi_prev (&gsiprev);
+
+ buf.loc = loc;
+ buf.clear_in_mask = false;
+ buf.base = ptr;
+ buf.alias_type = NULL_TREE;
+ buf.gsi = gsi;
+ buf.align = get_pointer_alignment (ptr);
+ unsigned int talign = min_align_of_type (type) * BITS_PER_UNIT;
+ buf.align = MAX (buf.align, talign);
+ buf.off = 0;
+ buf.padding_bytes = 0;
+ buf.size = 0;
+ buf.sz = int_size_in_bytes (type);
+ buf.union_ptr = NULL;
+ if (buf.sz < 0 && int_size_in_bytes (strip_array_types (type)) < 0)
+ sorry_at (loc, "%s not supported for variable length aggregates",
+ "__builtin_clear_padding");
+ /* The implementation currently assumes 8-bit host and target
+ chars which is the case for all currently supported targets
+ and hosts and is required e.g. for native_{encode,interpret}* APIs. */
+ else if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
+ sorry_at (loc, "%s not supported on this target",
+ "__builtin_clear_padding");
+ else if (!clear_padding_type_may_have_padding_p (type))
+ ;
+ else if (TREE_CODE (type) == ARRAY_TYPE && buf.sz < 0)
+ {
+ tree sz = TYPE_SIZE_UNIT (type);
+ tree elttype = type;
+ /* Only supports C/C++ VLAs and flattens all the VLA levels. */
+ while (TREE_CODE (elttype) == ARRAY_TYPE
+ && int_size_in_bytes (elttype) < 0)
+ elttype = TREE_TYPE (elttype);
+ HOST_WIDE_INT eltsz = int_size_in_bytes (elttype);
+ gcc_assert (eltsz >= 0);
+ if (eltsz)
+ {
+ buf.base = create_tmp_var (build_pointer_type (elttype));
+ tree end = make_ssa_name (TREE_TYPE (buf.base));
+ gimple *g = gimple_build_assign (buf.base, ptr);
+ gimple_set_location (g, loc);
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ g = gimple_build_assign (end, POINTER_PLUS_EXPR, buf.base, sz);
+ gimple_set_location (g, loc);
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ buf.sz = eltsz;
+ buf.align = TYPE_ALIGN (elttype);
+ buf.alias_type = build_pointer_type (elttype);
+ clear_padding_emit_loop (&buf, elttype, end);
+ }
+ }
+ else
+ {
+ if (!is_gimple_mem_ref_addr (buf.base))
+ {
+ buf.base = make_ssa_name (TREE_TYPE (ptr));
+ gimple *g = gimple_build_assign (buf.base, ptr);
+ gimple_set_location (g, loc);
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ }
+ buf.alias_type = build_pointer_type (type);
+ clear_padding_type (&buf, type, buf.sz);
+ clear_padding_flush (&buf, true);
+ }
+
+ gimple_stmt_iterator gsiprev2 = *gsi;
+ gsi_prev (&gsiprev2);
+ if (gsi_stmt (gsiprev) == gsi_stmt (gsiprev2))
+ gsi_replace (gsi, gimple_build_nop (), true);
+ else
+ {
+ gsi_remove (gsi, true);
+ *gsi = gsiprev2;
+ }
+ return true;
+}
+
/* Fold the non-target builtin at *GSI and return whether any simplification
was made. */
@@ -4105,6 +4957,9 @@ gimple_fold_builtin (gimple_stmt_iterator *gsi)
case BUILT_IN_REALLOC:
return gimple_fold_builtin_realloc (gsi);
+ case BUILT_IN_CLEAR_PADDING:
+ return gimple_fold_builtin_clear_padding (gsi);
+
default:;
}
@@ -7688,6 +8543,32 @@ gimple_build (gimple_seq *seq, location_t loc,
return res;
}
+/* Build the call FN () with a result of type TYPE (or no result if TYPE is
+ void) with a location LOC. Returns the built expression value (or NULL_TREE
+ if TYPE is void) and appends statements possibly defining it to SEQ. */
+
+tree
+gimple_build (gimple_seq *seq, location_t loc, combined_fn fn, tree type)
+{
+ tree res = NULL_TREE;
+ gcall *stmt;
+ if (internal_fn_p (fn))
+ stmt = gimple_build_call_internal (as_internal_fn (fn), 0);
+ else
+ {
+ tree decl = builtin_decl_implicit (as_builtin_fn (fn));
+ stmt = gimple_build_call (decl, 0);
+ }
+ if (!VOID_TYPE_P (type))
+ {
+ res = create_tmp_reg_or_ssa_name (type);
+ gimple_call_set_lhs (stmt, res);
+ }
+ gimple_set_location (stmt, loc);
+ gimple_seq_add_stmt_without_update (seq, stmt);
+ return res;
+}
+
/* Build the call FN (ARG0) with a result of type TYPE
(or no result if TYPE is void) with location LOC,
simplifying it first if possible. Returns the built
@@ -7877,6 +8758,26 @@ gimple_build_vector (gimple_seq *seq, location_t loc,
return builder->build ();
}
+/* Emit gimple statements into &stmts that take a value given in OLD_SIZE
+ and generate a value guaranteed to be rounded upwards to ALIGN.
+
+ Return the tree node representing this size, it is of TREE_TYPE TYPE. */
+
+tree
+gimple_build_round_up (gimple_seq *seq, location_t loc, tree type,
+ tree old_size, unsigned HOST_WIDE_INT align)
+{
+ unsigned HOST_WIDE_INT tg_mask = align - 1;
+ /* tree new_size = (old_size + tg_mask) & ~tg_mask; */
+ gcc_assert (INTEGRAL_TYPE_P (type));
+ tree tree_mask = build_int_cst (type, tg_mask);
+ tree oversize = gimple_build (seq, loc, PLUS_EXPR, type, old_size,
+ tree_mask);
+
+ tree mask = build_int_cst (type, -align);
+ return gimple_build (seq, loc, BIT_AND_EXPR, type, oversize, mask);
+}
+
/* Return true if the result of assignment STMT is known to be non-negative.
If the return value is based on the assumption that signed overflow is
undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
diff --git a/gcc/gimple-fold.h b/gcc/gimple-fold.h
index 0ed1d1f..f0f43f6 100644
--- a/gcc/gimple-fold.h
+++ b/gcc/gimple-fold.h
@@ -35,6 +35,7 @@ extern tree maybe_fold_and_comparisons (tree, enum tree_code, tree, tree,
enum tree_code, tree, tree);
extern tree maybe_fold_or_comparisons (tree, enum tree_code, tree, tree,
enum tree_code, tree, tree);
+extern void clear_type_padding_in_mask (tree, unsigned char *);
extern bool optimize_atomic_compare_exchange_p (gimple *);
extern void fold_builtin_atomic_compare_exchange (gimple_stmt_iterator *);
extern bool arith_overflowed_p (enum tree_code, const_tree, const_tree,
@@ -90,6 +91,12 @@ gimple_build (gimple_seq *seq,
{
return gimple_build (seq, UNKNOWN_LOCATION, code, type, op0, op1, op2);
}
+extern tree gimple_build (gimple_seq *, location_t, combined_fn, tree);
+inline tree
+gimple_build (gimple_seq *seq, combined_fn fn, tree type)
+{
+ return gimple_build (seq, UNKNOWN_LOCATION, fn, type);
+}
extern tree gimple_build (gimple_seq *, location_t, combined_fn, tree, tree);
inline tree
gimple_build (gimple_seq *seq, combined_fn fn, tree type, tree arg0)
@@ -144,6 +151,15 @@ gimple_build_vector (gimple_seq *seq, tree_vector_builder *builder)
return gimple_build_vector (seq, UNKNOWN_LOCATION, builder);
}
+extern tree gimple_build_round_up (gimple_seq *, location_t, tree, tree,
+ unsigned HOST_WIDE_INT);
+inline tree
+gimple_build_round_up (gimple_seq *seq, tree type, tree old_size,
+ unsigned HOST_WIDE_INT align)
+{
+ return gimple_build_round_up (seq, UNKNOWN_LOCATION, type, old_size, align);
+}
+
extern bool gimple_stmt_nonnegative_warnv_p (gimple *, bool *, int = 0);
extern bool gimple_stmt_integer_valued_real_p (gimple *, int = 0);
diff --git a/gcc/gimple-if-to-switch.cc b/gcc/gimple-if-to-switch.cc
new file mode 100644
index 0000000..8e1043a
--- /dev/null
+++ b/gcc/gimple-if-to-switch.cc
@@ -0,0 +1,569 @@
+/* If-elseif-else to switch conversion pass
+ Copyright (C) 2020 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/>. */
+
+/* Algorithm of the pass runs in the following steps:
+ a) We walk basic blocks in DOMINATOR order so that we first reach
+ a first condition of a future switch.
+ b) We follow false edges of a if-else-chain and we record chain
+ of GIMPLE conditions. These blocks are only used for comparison
+ of a common SSA_NAME and we do not allow any side effect.
+ c) We remove all basic blocks (except first) of such chain and
+ GIMPLE switch replaces the condition in the first basic block.
+ d) We move all GIMPLE statements in the removed blocks into the
+ first one. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "rtl.h"
+#include "tree.h"
+#include "gimple.h"
+#include "tree-pass.h"
+#include "ssa.h"
+#include "gimple-pretty-print.h"
+#include "fold-const.h"
+#include "gimple-iterator.h"
+#include "tree-cfg.h"
+#include "tree-dfa.h"
+#include "tree-cfgcleanup.h"
+#include "alias.h"
+#include "tree-ssa-loop.h"
+#include "diagnostic.h"
+#include "cfghooks.h"
+#include "tree-into-ssa.h"
+#include "cfganal.h"
+#include "dbgcnt.h"
+#include "target.h"
+#include "alloc-pool.h"
+#include "tree-switch-conversion.h"
+#include "tree-ssa-reassoc.h"
+
+using namespace tree_switch_conversion;
+
+struct condition_info
+{
+ typedef vec<std::pair<gphi *, tree>> mapping_vec;
+
+ condition_info (gcond *cond): m_cond (cond), m_bb (gimple_bb (cond)),
+ m_forwarder_bb (NULL), m_ranges (), m_true_edge (NULL), m_false_edge (NULL),
+ m_true_edge_phi_mapping (), m_false_edge_phi_mapping ()
+ {
+ m_ranges.create (0);
+ }
+
+ /* Recond PHI mapping for an original edge E and save these into
+ vector VEC. */
+ void record_phi_mapping (edge e, mapping_vec *vec);
+
+ gcond *m_cond;
+ basic_block m_bb;
+ basic_block m_forwarder_bb;
+ vec<range_entry> m_ranges;
+ edge m_true_edge;
+ edge m_false_edge;
+ mapping_vec m_true_edge_phi_mapping;
+ mapping_vec m_false_edge_phi_mapping;
+};
+
+/* Recond PHI mapping for an original edge E and save these into vector VEC. */
+
+void
+condition_info::record_phi_mapping (edge e, mapping_vec *vec)
+{
+ for (gphi_iterator gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi);
+ gsi_next (&gsi))
+ {
+ gphi *phi = gsi.phi ();
+ if (!virtual_operand_p (gimple_phi_result (phi)))
+ {
+ tree arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
+ vec->safe_push (std::make_pair (phi, arg));
+ }
+ }
+}
+
+/* Master structure for one if to switch conversion candidate. */
+
+struct if_chain
+{
+ /* Default constructor. */
+ if_chain (): m_entries ()
+ {
+ m_entries.create (2);
+ }
+
+ /* Default destructor. */
+ ~if_chain ()
+ {
+ m_entries.release ();
+ }
+
+ /* Verify that all case ranges do not overlap. */
+ bool check_non_overlapping_cases ();
+
+ /* Return true when the switch can be expanded with a jump table or
+ a bit test (at least partially). */
+ bool is_beneficial ();
+
+ /* If chain entries. */
+ vec<condition_info *> m_entries;
+};
+
+/* Compare two case ranges by minimum value. */
+
+static int
+range_cmp (const void *a, const void *b)
+{
+ const range_entry *re1 = *(const range_entry * const *) a;
+ const range_entry *re2 = *(const range_entry * const *) b;
+
+ return tree_int_cst_compare (re1->low, re2->low);
+}
+
+/* Verify that all case ranges do not overlap. */
+
+bool
+if_chain::check_non_overlapping_cases ()
+{
+ auto_vec<range_entry *> all_ranges;
+ for (unsigned i = 0; i < m_entries.length (); i++)
+ for (unsigned j = 0; j < m_entries[i]->m_ranges.length (); j++)
+ all_ranges.safe_push (&m_entries[i]->m_ranges[j]);
+
+ all_ranges.qsort (range_cmp);
+
+ for (unsigned i = 0; i < all_ranges.length () - 1; i++)
+ {
+ range_entry *left = all_ranges[i];
+ range_entry *right = all_ranges[i + 1];
+ if (tree_int_cst_le (left->low, right->low)
+ && tree_int_cst_le (right->low, left->high))
+ return false;
+ }
+
+ return true;
+}
+
+/* Compare clusters by minimum value. */
+
+static int
+cluster_cmp (const void *a, const void *b)
+{
+ simple_cluster *sc1 = *(simple_cluster * const *) a;
+ simple_cluster *sc2 = *(simple_cluster * const *) b;
+
+ return tree_int_cst_compare (sc1->get_low (), sc2->get_high ());
+}
+
+/* Dump constructed CLUSTERS with prefix MESSAGE. */
+
+static void
+dump_clusters (vec<cluster *> *clusters, const char *message)
+{
+ if (dump_file)
+ {
+ fprintf (dump_file, ";; %s: ", message);
+ for (unsigned i = 0; i < clusters->length (); i++)
+ (*clusters)[i]->dump (dump_file, dump_flags & TDF_DETAILS);
+ fprintf (dump_file, "\n");
+ }
+}
+
+/* Return true when the switch can be expanded with a jump table or
+ a bit test (at least partially). */
+
+bool
+if_chain::is_beneficial ()
+{
+ profile_probability prob = profile_probability::uninitialized ();
+
+ auto_vec<cluster *> clusters;
+ clusters.create (m_entries.length ());
+
+ for (unsigned i = 0; i < m_entries.length (); i++)
+ {
+ condition_info *info = m_entries[i];
+ for (unsigned j = 0; j < info->m_ranges.length (); j++)
+ {
+ range_entry *range = &info->m_ranges[j];
+ basic_block bb = info->m_true_edge->dest;
+ bool has_forwarder = !info->m_true_edge_phi_mapping.is_empty ();
+ clusters.safe_push (new simple_cluster (range->low, range->high,
+ NULL_TREE, bb, prob,
+ has_forwarder));
+ }
+ }
+
+ /* Sort clusters and merge them. */
+ auto_vec<cluster *> filtered_clusters;
+ filtered_clusters.create (16);
+ clusters.qsort (cluster_cmp);
+ simple_cluster *left = static_cast<simple_cluster *> (clusters[0]);
+ filtered_clusters.safe_push (left);
+
+ for (unsigned i = 1; i < clusters.length (); i++)
+ {
+ simple_cluster *right = static_cast<simple_cluster *> (clusters[i]);
+ tree type = TREE_TYPE (left->get_low ());
+ if (!left->m_has_forward_bb
+ && !right->m_has_forward_bb
+ && left->m_case_bb == right->m_case_bb)
+ {
+ if (wi::eq_p (wi::to_wide (right->get_low ()) - wi::to_wide
+ (left->get_high ()), wi::one (TYPE_PRECISION (type))))
+ {
+ left->set_high (right->get_high ());
+ continue;
+ }
+ }
+
+ left = static_cast<simple_cluster *> (clusters[i]);
+ filtered_clusters.safe_push (left);
+ }
+
+ dump_clusters (&filtered_clusters, "Canonical GIMPLE case clusters");
+
+ vec<cluster *> output
+ = jump_table_cluster::find_jump_tables (filtered_clusters);
+ bool r = output.length () < filtered_clusters.length ();
+ if (r)
+ dump_clusters (&output, "JT can be built");
+ output.release ();
+ if (r)
+ return true;
+
+ output = bit_test_cluster::find_bit_tests (filtered_clusters);
+ r = output.length () < filtered_clusters.length ();
+ if (r)
+ dump_clusters (&output, "BT can be built");
+ output.release ();
+ return r;
+}
+
+/* Build case label with MIN and MAX values of a given basic block DEST. */
+
+static tree
+build_case_label (tree index_type, tree min, tree max, basic_block dest)
+{
+ if (min != NULL_TREE && index_type != TREE_TYPE (min))
+ min = fold_convert (index_type, min);
+ if (max != NULL_TREE && index_type != TREE_TYPE (max))
+ max = fold_convert (index_type, max);
+
+ tree label = gimple_block_label (dest);
+ return build_case_label (min, min == max ? NULL_TREE : max, label);
+}
+
+/* Compare two integer constants. */
+
+static int
+label_cmp (const void *a, const void *b)
+{
+ const_tree l1 = *(const const_tree *) a;
+ const_tree l2 = *(const const_tree *) b;
+
+ return tree_int_cst_compare (CASE_LOW (l1), CASE_LOW (l2));
+}
+
+/* Convert a given if CHAIN into a switch GIMPLE statement. */
+
+static void
+convert_if_conditions_to_switch (if_chain *chain)
+{
+ if (!dbg_cnt (if_to_switch))
+ return;
+
+ auto_vec<tree> labels;
+ unsigned entries = chain->m_entries.length ();
+ condition_info *first_cond = chain->m_entries[0];
+ condition_info *last_cond = chain->m_entries[entries - 1];
+
+ edge default_edge = last_cond->m_false_edge;
+ basic_block default_bb = default_edge->dest;
+
+ gimple_stmt_iterator gsi = gsi_for_stmt (first_cond->m_cond);
+ tree index_type = TREE_TYPE (first_cond->m_ranges[0].exp);
+ for (unsigned i = 0; i < entries; i++)
+ {
+ condition_info *info = chain->m_entries[i];
+ basic_block case_bb = info->m_true_edge->dest;
+
+ /* Create a forwarder block if needed. */
+ if (!info->m_true_edge_phi_mapping.is_empty ())
+ {
+ info->m_forwarder_bb = split_edge (info->m_true_edge);
+ case_bb = info->m_forwarder_bb;
+ }
+
+ for (unsigned j = 0; j < info->m_ranges.length (); j++)
+ labels.safe_push (build_case_label (index_type,
+ info->m_ranges[j].low,
+ info->m_ranges[j].high,
+ case_bb));
+ default_bb = info->m_false_edge->dest;
+
+ if (i == 0)
+ {
+ remove_edge (first_cond->m_true_edge);
+ remove_edge (first_cond->m_false_edge);
+ }
+ else
+ delete_basic_block (info->m_bb);
+
+ make_edge (first_cond->m_bb, case_bb, 0);
+ }
+
+ labels.qsort (label_cmp);
+
+ edge e = find_edge (first_cond->m_bb, default_bb);
+ if (e == NULL)
+ e = make_edge (first_cond->m_bb, default_bb, 0);
+ gswitch *s
+ = gimple_build_switch (first_cond->m_ranges[0].exp,
+ build_case_label (index_type, NULL_TREE,
+ NULL_TREE, default_bb),
+ labels);
+
+ gsi_remove (&gsi, true);
+ gsi_insert_before (&gsi, s, GSI_NEW_STMT);
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "Expanded into a new gimple STMT: ");
+ print_gimple_stmt (dump_file, s, 0, TDF_SLIM);
+ putc ('\n', dump_file);
+ }
+
+ /* Fill up missing PHI node arguments. */
+ for (unsigned i = 0; i < chain->m_entries.length (); ++i)
+ {
+ condition_info *info = chain->m_entries[i];
+ for (unsigned j = 0; j < info->m_true_edge_phi_mapping.length (); ++j)
+ {
+ std::pair<gphi *, tree> item = info->m_true_edge_phi_mapping[j];
+ add_phi_arg (item.first, item.second,
+ single_succ_edge (info->m_forwarder_bb),
+ UNKNOWN_LOCATION);
+ }
+ }
+
+ /* Fill up missing PHI nodes for the default BB. */
+ for (unsigned j = 0; j < last_cond->m_false_edge_phi_mapping.length (); ++j)
+ {
+ std::pair<gphi *, tree> item = last_cond->m_false_edge_phi_mapping[j];
+ add_phi_arg (item.first, item.second, e, UNKNOWN_LOCATION);
+ }
+}
+
+/* Identify an index variable used in BB in a GIMPLE condition.
+ Save information about the condition into CONDITIONS_IN_BBS. */
+
+static void
+find_conditions (basic_block bb,
+ hash_map<basic_block, condition_info> *conditions_in_bbs)
+{
+ gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb);
+ if (gsi_end_p (gsi))
+ return;
+
+ gcond *cond = dyn_cast<gcond *> (gsi_stmt (gsi));
+ if (cond == NULL)
+ return;
+
+ if (!no_side_effect_bb (bb))
+ return;
+
+ tree lhs = gimple_cond_lhs (cond);
+ tree rhs = gimple_cond_rhs (cond);
+ tree_code code = gimple_cond_code (cond);
+
+ condition_info info (cond);
+
+ gassign *def;
+ if (code == NE_EXPR
+ && TREE_CODE (lhs) == SSA_NAME
+ && (def = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (lhs))) != NULL
+ && integer_zerop (rhs))
+ {
+ enum tree_code rhs_code = gimple_assign_rhs_code (def);
+ if (rhs_code == BIT_IOR_EXPR)
+ {
+ info.m_ranges.safe_grow (2, true);
+ init_range_entry (&info.m_ranges[0], gimple_assign_rhs1 (def), NULL);
+ init_range_entry (&info.m_ranges[1], gimple_assign_rhs2 (def), NULL);
+ }
+ }
+ else
+ {
+ info.m_ranges.safe_grow (1, true);
+ init_range_entry (&info.m_ranges[0], NULL_TREE, cond);
+ }
+
+ /* All identified ranges must have equal expression and IN_P flag. */
+ if (!info.m_ranges.is_empty ())
+ {
+ edge true_edge, false_edge;
+ tree expr = info.m_ranges[0].exp;
+ bool in_p = info.m_ranges[0].in_p;
+
+ extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
+ info.m_true_edge = in_p ? true_edge : false_edge;
+ info.m_false_edge = in_p ? false_edge : true_edge;
+
+ for (unsigned i = 0; i < info.m_ranges.length (); ++i)
+ if (info.m_ranges[i].exp == NULL_TREE
+ || !INTEGRAL_TYPE_P (TREE_TYPE (info.m_ranges[i].exp))
+ || info.m_ranges[i].low == NULL_TREE
+ || info.m_ranges[i].high == NULL_TREE
+ || (TYPE_PRECISION (TREE_TYPE (info.m_ranges[i].low))
+ != TYPE_PRECISION (TREE_TYPE (info.m_ranges[i].high))))
+ return;
+
+ for (unsigned i = 1; i < info.m_ranges.length (); ++i)
+ if (info.m_ranges[i].exp != expr
+ || info.m_ranges[i].in_p != in_p)
+ return;
+
+ info.record_phi_mapping (info.m_true_edge,
+ &info.m_true_edge_phi_mapping);
+ info.record_phi_mapping (info.m_false_edge,
+ &info.m_false_edge_phi_mapping);
+ conditions_in_bbs->put (bb, info);
+ }
+
+}
+
+namespace {
+
+const pass_data pass_data_if_to_switch =
+{
+ GIMPLE_PASS, /* type */
+ "iftoswitch", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_TREE_IF_TO_SWITCH, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_cleanup_cfg | TODO_update_ssa /* todo_flags_finish */
+};
+
+class pass_if_to_switch : public gimple_opt_pass
+{
+public:
+ pass_if_to_switch (gcc::context *ctxt)
+ : gimple_opt_pass (pass_data_if_to_switch, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ virtual bool gate (function *)
+ {
+ return (jump_table_cluster::is_enabled ()
+ || bit_test_cluster::is_enabled ());
+ }
+
+ virtual unsigned int execute (function *);
+
+}; // class pass_if_to_switch
+
+unsigned int
+pass_if_to_switch::execute (function *fun)
+{
+ auto_vec<if_chain *> all_candidates;
+ hash_map<basic_block, condition_info> conditions_in_bbs;
+
+ basic_block bb;
+ FOR_EACH_BB_FN (bb, fun)
+ find_conditions (bb, &conditions_in_bbs);
+
+ if (conditions_in_bbs.is_empty ())
+ return 0;
+
+ int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun));
+ unsigned n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false);
+
+ auto_bitmap seen_bbs;
+ for (int i = n - 1; i >= 0; --i)
+ {
+ basic_block bb = BASIC_BLOCK_FOR_FN (fun, rpo[i]);
+ if (bitmap_bit_p (seen_bbs, bb->index))
+ continue;
+
+ bitmap_set_bit (seen_bbs, bb->index);
+ condition_info *info = conditions_in_bbs.get (bb);
+ if (info)
+ {
+ if_chain *chain = new if_chain ();
+ chain->m_entries.safe_push (info);
+ /* Try to find a chain starting in this BB. */
+ while (true)
+ {
+ if (!single_pred_p (gimple_bb (info->m_cond)))
+ break;
+ edge e = single_pred_edge (gimple_bb (info->m_cond));
+ condition_info *info2 = conditions_in_bbs.get (e->src);
+ if (!info2 || info->m_ranges[0].exp != info2->m_ranges[0].exp)
+ break;
+
+ chain->m_entries.safe_push (info2);
+ bitmap_set_bit (seen_bbs, e->src->index);
+ info = info2;
+ }
+
+ chain->m_entries.reverse ();
+ if (chain->m_entries.length () >= 2
+ && chain->check_non_overlapping_cases ()
+ && chain->is_beneficial ())
+ {
+ gcond *cond = chain->m_entries[0]->m_cond;
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, cond,
+ "Condition chain with %d BBs "
+ "transformed into a switch statement.\n",
+ chain->m_entries.length ());
+ all_candidates.safe_push (chain);
+ }
+ }
+ }
+
+ for (unsigned i = 0; i < all_candidates.length (); i++)
+ {
+ convert_if_conditions_to_switch (all_candidates[i]);
+ delete all_candidates[i];
+ }
+
+ free (rpo);
+
+ if (!all_candidates.is_empty ())
+ {
+ free_dominance_info (CDI_DOMINATORS);
+ mark_virtual_operands_for_renaming (fun);
+ }
+
+ return 0;
+}
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_if_to_switch (gcc::context *ctxt)
+{
+ return new pass_if_to_switch (ctxt);
+}
diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
index 9186ff5..d79c212 100644
--- a/gcc/gimple-isel.cc
+++ b/gcc/gimple-isel.cc
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-dce.h"
#include "memmodel.h"
#include "optabs.h"
+#include "gimple-fold.h"
/* Expand all ARRAY_REF(VIEW_CONVERT_EXPR) gimple assignments into calls to
internal function based on vector type of selected expansion.
@@ -134,6 +135,25 @@ gimple_expand_vec_cond_expr (gimple_stmt_iterator *gsi,
lhs = gimple_assign_lhs (stmt);
machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
+ /* Lower mask typed, non-vector mode VEC_COND_EXPRs to bitwise operations.
+ Those can end up generated by folding and at least for integer mode masks
+ we cannot expect vcond expanders to exist. We lower a ? b : c
+ to (b & a) | (c & ~a). */
+ if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (lhs))
+ && !VECTOR_MODE_P (mode))
+ {
+ gcc_assert (types_compatible_p (TREE_TYPE (op0), TREE_TYPE (op1)));
+ gimple_seq stmts = NULL;
+ tree type = TREE_TYPE (lhs);
+ location_t loc = gimple_location (stmt);
+ tree tem0 = gimple_build (&stmts, loc, BIT_AND_EXPR, type, op1, op0);
+ tree tem1 = gimple_build (&stmts, loc, BIT_NOT_EXPR, type, op0);
+ tree tem2 = gimple_build (&stmts, loc, BIT_AND_EXPR, type, op2, tem1);
+ tree tem3 = gimple_build (&stmts, loc, BIT_IOR_EXPR, type, tem0, tem2);
+ gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+ return gimple_build_assign (lhs, tem3);
+ }
+
gcc_assert (!COMPARISON_CLASS_P (op0));
if (TREE_CODE (op0) == SSA_NAME)
{
@@ -198,10 +218,8 @@ gimple_expand_vec_cond_expr (gimple_stmt_iterator *gsi,
cmp_op_mode = TYPE_MODE (TREE_TYPE (op0a));
unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
-
- gcc_assert (known_eq (GET_MODE_SIZE (mode), GET_MODE_SIZE (cmp_op_mode))
- && known_eq (GET_MODE_NUNITS (mode),
- GET_MODE_NUNITS (cmp_op_mode)));
+ gcc_assert (known_eq (GET_MODE_NUNITS (mode),
+ GET_MODE_NUNITS (cmp_op_mode)));
icode = get_vcond_icode (mode, cmp_op_mode, unsignedp);
if (icode == CODE_FOR_nothing)
@@ -247,7 +265,6 @@ gimple_expand_vec_exprs (void)
{
gimple *g = gimple_expand_vec_cond_expr (&gsi,
&vec_cond_ssa_name_uses);
-
if (g != NULL)
{
tree lhs = gimple_assign_lhs (gsi_stmt (gsi));
@@ -256,6 +273,8 @@ gimple_expand_vec_exprs (void)
}
gimple_expand_vec_set_expr (&gsi);
+ if (gsi_end_p (gsi))
+ break;
}
}
diff --git a/gcc/gimple-loop-interchange.cc b/gcc/gimple-loop-interchange.cc
index 1656004..a36dbb4 100644
--- a/gcc/gimple-loop-interchange.cc
+++ b/gcc/gimple-loop-interchange.cc
@@ -2085,8 +2085,13 @@ pass_linterchange::execute (function *fun)
}
if (changed_p)
- scev_reset ();
- return changed_p ? (TODO_update_ssa_only_virtuals) : 0;
+ {
+ unsigned todo = TODO_update_ssa_only_virtuals;
+ todo |= loop_invariant_motion_in_fun (cfun, false);
+ scev_reset ();
+ return todo;
+ }
+ return 0;
}
} // anon namespace
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index a01bf90..075d6e5 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -753,6 +753,7 @@ dump_gimple_call_args (pretty_printer *buffer, const gcall *gs,
limit = ARRAY_SIZE (reduction_args);
break;
+ case IFN_HWASAN_MARK:
case IFN_ASAN_MARK:
#define DEF(X) #X
static const char *const asan_mark_args[] = {IFN_ASAN_MARK_FLAGS};
@@ -1700,6 +1701,15 @@ dump_gimple_omp_target (pretty_printer *buffer, const gomp_target *gs,
case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
kind = " oacc_host_data";
break;
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
+ kind = " oacc_parallel_kernels_parallelized";
+ break;
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
+ kind = " oacc_parallel_kernels_gang_single";
+ break;
+ case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
+ kind = " oacc_data_kernels";
+ break;
default:
gcc_unreachable ();
}
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 92a6335..4f5d502 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -431,8 +431,9 @@ gimple_ranger::range_of_range_op (irange &r, gimple *s)
m_cache.register_dependency (lhs, op2);
}
- if (range_of_non_trivial_assignment (r, s))
- return true;
+ if (gimple_code (s) == GIMPLE_ASSIGN
+ && gimple_assign_rhs_code (s) == ADDR_EXPR)
+ return range_of_address (r, s);
if (range_of_expr (range1, op1, s))
{
@@ -446,48 +447,84 @@ gimple_ranger::range_of_range_op (irange &r, gimple *s)
return true;
}
-// Calculate the range of a non-trivial assignment. That is, is one
-// inolving arithmetic on an SSA name (for example, an ADDR_EXPR).
+// Calculate the range of an assignment containing an ADDR_EXPR.
// Return the range in R.
-//
-// If a range cannot be calculated, return false.
+// If a range cannot be calculated, set it to VARYING and return true.
bool
-gimple_ranger::range_of_non_trivial_assignment (irange &r, gimple *stmt)
+gimple_ranger::range_of_address (irange &r, gimple *stmt)
{
- if (gimple_code (stmt) != GIMPLE_ASSIGN)
- return false;
+ gcc_checking_assert (gimple_code (stmt) == GIMPLE_ASSIGN);
+ gcc_checking_assert (gimple_assign_rhs_code (stmt) == ADDR_EXPR);
- tree base = gimple_range_base_of_assignment (stmt);
- if (base)
+ bool strict_overflow_p;
+ tree expr = gimple_assign_rhs1 (stmt);
+ poly_int64 bitsize, bitpos;
+ tree offset;
+ machine_mode mode;
+ int unsignedp, reversep, volatilep;
+ tree base = get_inner_reference (TREE_OPERAND (expr, 0), &bitsize,
+ &bitpos, &offset, &mode, &unsignedp,
+ &reversep, &volatilep);
+
+
+ if (base != NULL_TREE
+ && TREE_CODE (base) == MEM_REF
+ && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
{
- if (TREE_CODE (base) == MEM_REF)
+ tree ssa = TREE_OPERAND (base, 0);
+ gcc_checking_assert (irange::supports_type_p (TREE_TYPE (ssa)));
+ range_of_expr (r, ssa, stmt);
+ range_cast (r, TREE_TYPE (gimple_assign_rhs1 (stmt)));
+
+ poly_offset_int off = 0;
+ bool off_cst = false;
+ if (offset == NULL_TREE || TREE_CODE (offset) == INTEGER_CST)
{
- if (TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
- {
- int_range_max range1;
- tree ssa = TREE_OPERAND (base, 0);
- if (range_of_expr (range1, ssa, stmt))
- {
- tree type = TREE_TYPE (ssa);
- range_operator *op = range_op_handler (POINTER_PLUS_EXPR,
- type);
- int_range<2> offset (TREE_OPERAND (base, 1),
- TREE_OPERAND (base, 1));
- op->fold_range (r, type, range1, offset);
- return true;
- }
- }
- return false;
+ off = mem_ref_offset (base);
+ if (offset)
+ off += poly_offset_int::from (wi::to_poly_wide (offset),
+ SIGNED);
+ off <<= LOG2_BITS_PER_UNIT;
+ off += bitpos;
+ off_cst = true;
}
- if (gimple_assign_rhs_code (stmt) == ADDR_EXPR)
+ /* If &X->a is equal to X, the range of X is the result. */
+ if (off_cst && known_eq (off, 0))
+ return true;
+ else if (flag_delete_null_pointer_checks
+ && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr)))
+ {
+ /* For -fdelete-null-pointer-checks -fno-wrapv-pointer we don't
+ allow going from non-NULL pointer to NULL. */
+ if(!range_includes_zero_p (&r))
+ return true;
+ }
+ /* If MEM_REF has a "positive" offset, consider it non-NULL
+ always, for -fdelete-null-pointer-checks also "negative"
+ ones. Punt for unknown offsets (e.g. variable ones). */
+ if (!TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr))
+ && off_cst
+ && known_ne (off, 0)
+ && (flag_delete_null_pointer_checks || known_gt (off, 0)))
{
- // Handle "= &a" and return non-zero.
r = range_nonzero (TREE_TYPE (gimple_assign_rhs1 (stmt)));
return true;
}
+ r = int_range<2> (TREE_TYPE (gimple_assign_rhs1 (stmt)));
+ return true;
}
- return false;
+
+ // Handle "= &a".
+ if (tree_single_nonzero_warnv_p (expr, &strict_overflow_p))
+ {
+ r = range_nonzero (TREE_TYPE (gimple_assign_rhs1 (stmt)));
+ return true;
+ }
+
+ // Otherwise return varying.
+ r = int_range<2> (TREE_TYPE (gimple_assign_rhs1 (stmt)));
+ return true;
}
// Calculate a range for phi statement S and return it in R.
diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h
index 0aa6d46..92bb530 100644
--- a/gcc/gimple-range.h
+++ b/gcc/gimple-range.h
@@ -62,7 +62,7 @@ protected:
ranger_cache m_cache;
private:
bool range_of_phi (irange &r, gphi *phi);
- bool range_of_non_trivial_assignment (irange &r, gimple *s);
+ bool range_of_address (irange &r, gimple *s);
bool range_of_builtin_call (irange &r, gcall *call);
bool range_with_loop_info (irange &r, tree name);
void range_of_ssa_name_with_loop_info (irange &, tree, class loop *,
@@ -97,8 +97,12 @@ extern bool gimple_range_calc_op2 (irange &r, const gimple *s,
static inline range_operator *
gimple_range_handler (const gimple *s)
{
- if ((gimple_code (s) == GIMPLE_ASSIGN) || (gimple_code (s) == GIMPLE_COND))
- return range_op_handler (gimple_expr_code (s), gimple_expr_type (s));
+ if (const gassign *ass = dyn_cast<const gassign *> (s))
+ return range_op_handler (gimple_assign_rhs_code (ass),
+ TREE_TYPE (gimple_assign_lhs (ass)));
+ if (const gcond *cond = dyn_cast<const gcond *> (s))
+ return range_op_handler (gimple_cond_code (cond),
+ TREE_TYPE (gimple_cond_lhs (cond)));
return NULL;
}
diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c
index 485774d..b998e0b 100644
--- a/gcc/gimple-ssa-evrp-analyze.c
+++ b/gcc/gimple-ssa-evrp-analyze.c
@@ -218,7 +218,11 @@ evrp_range_analyzer::record_ranges_from_incoming_edge (basic_block bb)
push_value_range (vrs[i].first, vrs[i].second);
if (is_fallthru
&& m_update_global_ranges
- && all_uses_feed_or_dominated_by_stmt (vrs[i].first, stmt))
+ && all_uses_feed_or_dominated_by_stmt (vrs[i].first, stmt)
+ /* The condition must post-dominate the definition point. */
+ && (SSA_NAME_IS_DEFAULT_DEF (vrs[i].first)
+ || (gimple_bb (SSA_NAME_DEF_STMT (vrs[i].first))
+ == pred_e->src)))
{
set_ssa_range_info (vrs[i].first, vrs[i].second);
maybe_set_nonzero_bits (pred_e, vrs[i].first);
diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c
index fff034f..ca0572f 100644
--- a/gcc/gimple-ssa-sprintf.c
+++ b/gcc/gimple-ssa-sprintf.c
@@ -4032,26 +4032,22 @@ compute_format_length (call_info &info, format_result *res, range_query *query)
available, or the maximum possible size otherwise. */
static unsigned HOST_WIDE_INT
-get_destination_size (tree dest)
+get_destination_size (tree dest, pointer_query &ptr_qry)
{
/* When there is no destination return the maximum. */
if (!dest)
return HOST_WIDE_INT_MAX;
- /* Initialize object size info before trying to compute it. */
- init_object_sizes ();
+ /* Use compute_objsize to determine the size of the destination object. */
+ access_ref aref;
+ if (!ptr_qry.get_ref (dest, &aref))
+ return HOST_WIDE_INT_MAX;
- /* Use __builtin_object_size to determine the size of the destination
- object. When optimizing, determine the smallest object (such as
- a member array as opposed to the whole enclosing object), otherwise
- use type-zero object size to determine the size of the enclosing
- object (the function fails without optimization in this type). */
- int ost = optimize > 0;
- unsigned HOST_WIDE_INT size;
- if (compute_builtin_object_size (dest, ost, &size))
- return size;
+ offset_int remsize = aref.size_remaining ();
+ if (!wi::fits_uhwi_p (remsize))
+ return HOST_WIDE_INT_MAX;
- return HOST_WIDE_INT_MAX;
+ return remsize.to_uhwi ();
}
/* Return true if the call described by INFO with result RES safe to
@@ -4296,7 +4292,7 @@ get_user_idx_format (tree fndecl, unsigned *idx_args)
gsi_next should not be performed in the caller. */
bool
-handle_printf_call (gimple_stmt_iterator *gsi, range_query *query)
+handle_printf_call (gimple_stmt_iterator *gsi, pointer_query &ptr_qry)
{
init_target_to_host_charmap ();
@@ -4519,7 +4515,7 @@ handle_printf_call (gimple_stmt_iterator *gsi, range_query *query)
/* For non-bounded functions like sprintf, determine the size
of the destination from the object or pointer passed to it
as the first argument. */
- dstsize = get_destination_size (dstptr);
+ dstsize = get_destination_size (dstptr, ptr_qry);
}
else if (tree size = gimple_call_arg (info.callstmt, idx_dstsize))
{
@@ -4566,7 +4562,7 @@ handle_printf_call (gimple_stmt_iterator *gsi, range_query *query)
and use the greater of the two at level 1 and the smaller
of them at level 2. */
value_range vr;
- query->range_of_expr (vr, size, info.callstmt);
+ ptr_qry.rvals->range_of_expr (vr, size, info.callstmt);
if (!vr.undefined_p ())
{
@@ -4683,7 +4679,7 @@ handle_printf_call (gimple_stmt_iterator *gsi, range_query *query)
never set to true again). */
res.posunder4k = posunder4k && dstptr;
- bool success = compute_format_length (info, &res, query);
+ bool success = compute_format_length (info, &res, ptr_qry.rvals);
if (res.warned)
gimple_set_no_warning (info.callstmt, true);
diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c
index 6089faf..17a4250 100644
--- a/gcc/gimple-ssa-store-merging.c
+++ b/gcc/gimple-ssa-store-merging.c
@@ -1450,6 +1450,7 @@ public:
bool bit_insertion;
bool string_concatenation;
bool only_constants;
+ bool consecutive;
unsigned int first_nonmergeable_order;
int lp_nr;
@@ -1822,6 +1823,7 @@ merged_store_group::merged_store_group (store_immediate_info *info)
bit_insertion = info->rhs_code == BIT_INSERT_EXPR;
string_concatenation = info->rhs_code == STRING_CST;
only_constants = info->rhs_code == INTEGER_CST;
+ consecutive = true;
first_nonmergeable_order = ~0U;
lp_nr = info->lp_nr;
unsigned HOST_WIDE_INT align_bitpos = 0;
@@ -1957,6 +1959,9 @@ merged_store_group::do_merge (store_immediate_info *info)
first_stmt = stmt;
}
+ if (info->bitpos != start + width)
+ consecutive = false;
+
/* We need to use extraction if there is any bit-field. */
if (info->rhs_code == BIT_INSERT_EXPR)
{
@@ -1964,13 +1969,17 @@ merged_store_group::do_merge (store_immediate_info *info)
gcc_assert (!string_concatenation);
}
- /* We need to use concatenation if there is any string. */
+ /* We want to use concatenation if there is any string. */
if (info->rhs_code == STRING_CST)
{
string_concatenation = true;
gcc_assert (!bit_insertion);
}
+ /* But we cannot use it if we don't have consecutive stores. */
+ if (!consecutive)
+ string_concatenation = false;
+
if (info->rhs_code != INTEGER_CST)
only_constants = false;
}
@@ -1982,12 +1991,13 @@ merged_store_group::do_merge (store_immediate_info *info)
void
merged_store_group::merge_into (store_immediate_info *info)
{
+ do_merge (info);
+
/* Make sure we're inserting in the position we think we're inserting. */
gcc_assert (info->bitpos >= start + width
&& info->bitregion_start <= bitregion_end);
width = info->bitpos + info->bitsize - start;
- do_merge (info);
}
/* Merge a store described by INFO into this merged store.
@@ -1997,11 +2007,11 @@ merged_store_group::merge_into (store_immediate_info *info)
void
merged_store_group::merge_overlapping (store_immediate_info *info)
{
+ do_merge (info);
+
/* If the store extends the size of the group, extend the width. */
if (info->bitpos + info->bitsize > start + width)
width = info->bitpos + info->bitsize - start;
-
- do_merge (info);
}
/* Go through all the recorded stores in this group in program order and
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 1afed88..e8246b7 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -46,6 +46,8 @@ along with GCC; see the file COPYING3. If not see
#include "asan.h"
#include "langhooks.h"
#include "attr-fnspec.h"
+#include "ipa-modref-tree.h"
+#include "ipa-modref.h"
/* All the tuples have their operand vector (if present) at the very bottom
@@ -611,10 +613,6 @@ gimple_build_asm_1 (const char *string, unsigned ninputs, unsigned noutputs,
gasm *p;
int size = strlen (string);
- /* ASMs with labels cannot have outputs. This should have been
- enforced by the front end. */
- gcc_assert (nlabels == 0 || noutputs == 0);
-
p = as_a <gasm *> (
gimple_build_with_ops (GIMPLE_ASM, ERROR_MARK,
ninputs + noutputs + nclobbers + nlabels));
@@ -1532,24 +1530,45 @@ int
gimple_call_arg_flags (const gcall *stmt, unsigned arg)
{
attr_fnspec fnspec = gimple_call_fnspec (stmt);
-
- if (!fnspec.known_p ())
- return 0;
-
int flags = 0;
- if (!fnspec.arg_specified_p (arg))
- ;
- else if (!fnspec.arg_used_p (arg))
- flags = EAF_UNUSED;
- else
+ if (fnspec.known_p ())
+ {
+ if (!fnspec.arg_specified_p (arg))
+ ;
+ else if (!fnspec.arg_used_p (arg))
+ flags = EAF_UNUSED;
+ else
+ {
+ if (fnspec.arg_direct_p (arg))
+ flags |= EAF_DIRECT;
+ if (fnspec.arg_noescape_p (arg))
+ flags |= EAF_NOESCAPE | EAF_NODIRECTESCAPE;
+ if (fnspec.arg_readonly_p (arg))
+ flags |= EAF_NOCLOBBER;
+ }
+ }
+ tree callee = gimple_call_fndecl (stmt);
+ if (callee)
{
- if (fnspec.arg_direct_p (arg))
- flags |= EAF_DIRECT;
- if (fnspec.arg_noescape_p (arg))
- flags |= EAF_NOESCAPE;
- if (fnspec.arg_readonly_p (arg))
- flags |= EAF_NOCLOBBER;
+ cgraph_node *node = cgraph_node::get (callee);
+ modref_summary *summary = node ? get_modref_function_summary (node)
+ : NULL;
+
+ if (summary && summary->arg_flags.length () > arg)
+ {
+ int modref_flags = summary->arg_flags[arg];
+
+ /* We have possibly optimized out load. Be conservative here. */
+ if (!node->binds_to_current_def_p ())
+ {
+ if ((modref_flags & EAF_UNUSED) && !(flags & EAF_UNUSED))
+ modref_flags &= ~EAF_UNUSED;
+ if ((modref_flags & EAF_DIRECT) && !(flags & EAF_DIRECT))
+ modref_flags &= ~EAF_DIRECT;
+ }
+ flags |= modref_flags;
+ }
}
return flags;
}
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 62b5a8a..8a1db3c 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -175,6 +175,15 @@ enum gf_mask {
GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA = 10,
GF_OMP_TARGET_KIND_OACC_DECLARE = 11,
GF_OMP_TARGET_KIND_OACC_HOST_DATA = 12,
+ /* A 'GF_OMP_TARGET_KIND_OACC_PARALLEL' representing an OpenACC 'kernels'
+ decomposed part, parallelized. */
+ GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED = 13,
+ /* A 'GF_OMP_TARGET_KIND_OACC_PARALLEL' representing an OpenACC 'kernels'
+ decomposed part, "gang-single". */
+ GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE = 14,
+ /* A 'GF_OMP_TARGET_KIND_OACC_DATA' representing an OpenACC 'kernels'
+ decomposed parts' 'data' construct. */
+ GF_OMP_TARGET_KIND_OACC_DATA_KERNELS = 15,
GF_OMP_TEAMS_HOST = 1 << 0,
/* True on an GIMPLE_OMP_RETURN statement if the return does not require
@@ -2229,26 +2238,6 @@ gimple_set_modified (gimple *s, bool modifiedp)
}
-/* Return the tree code for the expression computed by STMT. This is
- only valid for GIMPLE_COND, GIMPLE_CALL and GIMPLE_ASSIGN. For
- GIMPLE_CALL, return CALL_EXPR as the expression code for
- consistency. This is useful when the caller needs to deal with the
- three kinds of computation that GIMPLE supports. */
-
-static inline enum tree_code
-gimple_expr_code (const gimple *stmt)
-{
- enum gimple_code code = gimple_code (stmt);
- if (code == GIMPLE_ASSIGN || code == GIMPLE_COND)
- return (enum tree_code) stmt->subcode;
- else
- {
- gcc_gimple_checking_assert (code == GIMPLE_CALL);
- return CALL_EXPR;
- }
-}
-
-
/* Return true if statement STMT contains volatile operands. */
static inline bool
@@ -3793,6 +3782,28 @@ gimple_cond_set_condition (gcond *stmt, enum tree_code code, tree lhs,
gimple_cond_set_rhs (stmt, rhs);
}
+
+/* Return the tree code for the expression computed by STMT. This is
+ only valid for GIMPLE_COND, GIMPLE_CALL and GIMPLE_ASSIGN. For
+ GIMPLE_CALL, return CALL_EXPR as the expression code for
+ consistency. This is useful when the caller needs to deal with the
+ three kinds of computation that GIMPLE supports. */
+
+static inline enum tree_code
+gimple_expr_code (const gimple *stmt)
+{
+ if (const gassign *ass = dyn_cast<const gassign *> (stmt))
+ return gimple_assign_rhs_code (ass);
+ if (const gcond *cond = dyn_cast<const gcond *> (stmt))
+ return gimple_cond_code (cond);
+ else
+ {
+ gcc_gimple_checking_assert (gimple_code (stmt) == GIMPLE_CALL);
+ return CALL_EXPR;
+ }
+}
+
+
/* Return the LABEL_DECL node used by GIMPLE_LABEL statement GS. */
static inline tree
@@ -4025,7 +4036,7 @@ static inline tree
gimple_asm_label_op (const gasm *asm_stmt, unsigned index)
{
gcc_gimple_checking_assert (index < asm_stmt->nl);
- return asm_stmt->op[index + asm_stmt->ni + asm_stmt->nc];
+ return asm_stmt->op[index + asm_stmt->no + asm_stmt->ni + asm_stmt->nc];
}
/* Set LABEL_OP to be label operand INDEX in GIMPLE_ASM ASM_STMT. */
@@ -4035,7 +4046,7 @@ gimple_asm_set_label_op (gasm *asm_stmt, unsigned index, tree label_op)
{
gcc_gimple_checking_assert (index < asm_stmt->nl
&& TREE_CODE (label_op) == TREE_LIST);
- asm_stmt->op[index + asm_stmt->ni + asm_stmt->nc] = label_op;
+ asm_stmt->op[index + asm_stmt->no + asm_stmt->ni + asm_stmt->nc] = label_op;
}
/* Return the string representing the assembly instruction in
@@ -6509,6 +6520,9 @@ is_gimple_omp_oacc (const gimple *stmt)
case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
case GF_OMP_TARGET_KIND_OACC_DECLARE:
case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
+ case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
return true;
default:
return false;
@@ -6534,6 +6548,8 @@ is_gimple_omp_offloaded (const gimple *stmt)
case GF_OMP_TARGET_KIND_OACC_PARALLEL:
case GF_OMP_TARGET_KIND_OACC_KERNELS:
case GF_OMP_TARGET_KIND_OACC_SERIAL:
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
return true;
default:
return false;
diff --git a/gcc/gimplify-me.c b/gcc/gimplify-me.c
index 47148fb..ee84c8b 100644
--- a/gcc/gimplify-me.c
+++ b/gcc/gimplify-me.c
@@ -230,10 +230,8 @@ gimple_regimplify_operands (gimple *stmt, gimple_stmt_iterator *gsi_p)
if (i == 1 && (is_gimple_call (stmt) || is_gimple_assign (stmt)))
gimplify_expr (&op, &pre, NULL, is_gimple_lvalue, fb_lvalue);
else if (i == 2
- && is_gimple_assign (stmt)
- && num_ops == 2
- && get_gimple_rhs_class (gimple_expr_code (stmt))
- == GIMPLE_SINGLE_RHS)
+ && gimple_assign_single_p (stmt)
+ && num_ops == 2)
gimplify_expr (&op, &pre, NULL,
rhs_predicate_for (gimple_assign_lhs (stmt)),
fb_rvalue);
@@ -255,10 +253,8 @@ gimple_regimplify_operands (gimple *stmt, gimple_stmt_iterator *gsi_p)
{
bool need_temp = false;
- if (is_gimple_assign (stmt)
- && num_ops == 2
- && get_gimple_rhs_class (gimple_expr_code (stmt))
- == GIMPLE_SINGLE_RHS)
+ if (gimple_assign_single_p (stmt)
+ && num_ops == 2)
gimplify_expr (gimple_assign_rhs1_ptr (stmt), &pre, NULL,
rhs_predicate_for (gimple_assign_lhs (stmt)),
fb_rvalue);
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index b2c623b..54cb66b 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -1237,8 +1237,11 @@ asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
/* It's necessary to have all stack variables aligned to ASAN granularity
bytes. */
- if (DECL_ALIGN_UNIT (decl) <= ASAN_SHADOW_GRANULARITY)
- SET_DECL_ALIGN (decl, BITS_PER_UNIT * ASAN_SHADOW_GRANULARITY);
+ gcc_assert (!hwasan_sanitize_p () || hwasan_sanitize_stack_p ());
+ unsigned shadow_granularity
+ = hwasan_sanitize_p () ? HWASAN_TAG_GRANULE_SIZE : ASAN_SHADOW_GRANULARITY;
+ if (DECL_ALIGN_UNIT (decl) <= shadow_granularity)
+ SET_DECL_ALIGN (decl, BITS_PER_UNIT * shadow_granularity);
HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
@@ -3384,6 +3387,20 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
cfun->calls_eh_return = true;
break;
+ case BUILT_IN_CLEAR_PADDING:
+ if (call_expr_nargs (*expr_p) == 1)
+ {
+ /* Remember the original type of the argument in an internal
+ dummy second argument, as in GIMPLE pointer conversions are
+ useless. */
+ p = CALL_EXPR_ARG (*expr_p, 0);
+ *expr_p
+ = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 2, p,
+ build_zero_cst (TREE_TYPE (p)));
+ return GS_OK;
+ }
+ break;
+
default:
;
}
@@ -5518,6 +5535,19 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
return GS_OK;
}
+ case NOP_EXPR:
+ /* Pull out compound literal expressions from a NOP_EXPR.
+ Those are created in the C FE to drop qualifiers during
+ lvalue conversion. */
+ if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR)
+ && tree_ssa_useless_type_conversion (*from_p))
+ {
+ *from_p = TREE_OPERAND (*from_p, 0);
+ ret = GS_OK;
+ changed = true;
+ }
+ break;
+
case COMPOUND_LITERAL_EXPR:
{
tree complit = TREE_OPERAND (*expr_p, 1);
@@ -8672,7 +8702,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
{
error_at (OMP_CLAUSE_LOCATION (c),
"invalid %<task%> reduction modifier on construct "
- "other than %<parallel%>, %<for%> or %<sections%>");
+ "other than %<parallel%>, %qs or %<sections%>",
+ lang_GNU_Fortran () ? "do" : "for");
OMP_CLAUSE_REDUCTION_TASK (c) = 0;
}
}
@@ -9903,10 +9934,12 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
remove = true;
break;
}
+ else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
+ || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
+ == INTEGER_CST))
+ ;
else if (code == OMP_TASKLOOP
- && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
- && (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
- != INTEGER_CST))
+ || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
= get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
pre_p, NULL, false);
@@ -10474,6 +10507,8 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
&& omp_shared_to_firstprivate_optimizable_decl_p (decl))
omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
}
+ else
+ n->value &= ~GOVD_EXPLICIT;
break;
case OMP_CLAUSE_LASTPRIVATE:
@@ -10773,6 +10808,41 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
&& omp_shared_to_firstprivate_optimizable_decl_p (decl))
omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
break;
+
+ case OMP_CLAUSE_ALLOCATE:
+ decl = OMP_CLAUSE_DECL (c);
+ n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
+ if (n != NULL && !(n->value & GOVD_SEEN))
+ {
+ if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR))
+ != 0
+ && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0)
+ remove = true;
+ }
+ if (!remove
+ && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
+ && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST
+ && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0
+ || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK
+ || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS))
+ {
+ tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
+ n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator);
+ if (n == NULL)
+ {
+ enum omp_clause_default_kind default_kind
+ = ctx->default_kind;
+ ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
+ omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
+ true);
+ ctx->default_kind = default_kind;
+ }
+ else
+ omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
+ true);
+ }
+ break;
+
case OMP_CLAUSE_COPYIN:
case OMP_CLAUSE_COPYPRIVATE:
case OMP_CLAUSE_IF:
@@ -10822,7 +10892,6 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
case OMP_CLAUSE_FINALIZE:
case OMP_CLAUSE_INCLUSIVE:
case OMP_CLAUSE_EXCLUSIVE:
- case OMP_CLAUSE_ALLOCATE:
break;
default:
@@ -11622,6 +11691,15 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
if (c)
tile = list_length (OMP_CLAUSE_TILE_LIST (c));
+ c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE);
+ hash_set<tree> *allocate_uids = NULL;
+ if (c)
+ {
+ allocate_uids = new hash_set<tree>;
+ for (; c; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE)
+ allocate_uids->add (OMP_CLAUSE_DECL (c));
+ }
for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
{
t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
@@ -11948,12 +12026,13 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
as an iteration counter. This is valid, since DECL cannot be
modified in the body of the loop. Similarly for any iteration vars
in simd with collapse > 1 where the iterator vars must be
- lastprivate. */
+ lastprivate. And similarly for vars mentioned in allocate clauses. */
if (orig_for_stmt != for_stmt)
var = decl;
else if (!is_gimple_reg (decl)
|| (ort == ORT_SIMD
- && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1))
+ && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
+ || (allocate_uids && allocate_uids->contains (decl)))
{
struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
/* Make sure omp_add_variable is not called on it prematurely.
@@ -12180,6 +12259,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
}
BITMAP_FREE (has_decl_expr);
+ delete allocate_uids;
if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
|| (loop_p && orig_for_stmt == for_stmt))
@@ -12413,22 +12493,22 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
/* Allocate clause we duplicate on task and inner taskloop
if the decl is lastprivate, otherwise just put on task. */
case OMP_CLAUSE_ALLOCATE:
+ if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
+ && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
+ {
+ /* Additionally, put firstprivate clause on task
+ for the allocator if it is not constant. */
+ *gtask_clauses_ptr
+ = build_omp_clause (OMP_CLAUSE_LOCATION (c),
+ OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (*gtask_clauses_ptr)
+ = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
+ gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
+ }
if (lastprivate_uids
&& bitmap_bit_p (lastprivate_uids,
DECL_UID (OMP_CLAUSE_DECL (c))))
{
- if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
- && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
- {
- /* Additionally, put firstprivate clause on task
- for the allocator if it is not constant. */
- *gtask_clauses_ptr
- = build_omp_clause (OMP_CLAUSE_LOCATION (c),
- OMP_CLAUSE_FIRSTPRIVATE);
- OMP_CLAUSE_DECL (*gtask_clauses_ptr)
- = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
- gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
- }
*gfor_clauses_ptr = c;
gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
*gtask_clauses_ptr = copy_node (c);
@@ -12703,7 +12783,8 @@ gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
{
error_at (OMP_CLAUSE_LOCATION (*pc),
"invalid %<task%> reduction modifier on construct "
- "other than %<parallel%>, %<for%> or %<sections%>");
+ "other than %<parallel%>, %qs or %<sections%>",
+ lang_GNU_Fortran () ? "do" : "for");
OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
}
pc = &OMP_CLAUSE_CHAIN (*pc);
@@ -15314,7 +15395,7 @@ gimplify_function_tree (tree fndecl)
if necessary. */
cfun->curr_properties |= PROP_gimple_lva;
- if (asan_sanitize_use_after_scope () && sanitize_flags_p (SANITIZE_ADDRESS))
+ if (asan_sanitize_use_after_scope ())
asan_poisoned_variables = new hash_set<tree> ();
bind = gimplify_body (fndecl, true);
if (asan_poisoned_variables)
diff --git a/gcc/ginclude/float.h b/gcc/ginclude/float.h
index 9c4b038..39139ee 100644
--- a/gcc/ginclude/float.h
+++ b/gcc/ginclude/float.h
@@ -248,9 +248,45 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define DBL_NORM_MAX __DBL_NORM_MAX__
#define LDBL_NORM_MAX __LDBL_NORM_MAX__
+/* Whether each type matches an IEC 60559 format (1 for format, 2 for
+ format and operations). */
+#undef FLT_IS_IEC_60559
+#undef DBL_IS_IEC_60559
+#undef LDBL_IS_IEC_60559
+#define FLT_IS_IEC_60559 __FLT_IS_IEC_60559__
+#define DBL_IS_IEC_60559 __DBL_IS_IEC_60559__
+#define LDBL_IS_IEC_60559 __LDBL_IS_IEC_60559__
+
+/* Infinity in type float, or overflow if infinity not supported. */
+#undef INFINITY
+#define INFINITY (__builtin_inff ())
+
+/* Quiet NaN, if supported for float. */
+#if __FLT_HAS_QUIET_NAN__
+#undef NAN
+#define NAN (__builtin_nanf (""))
+#endif
+
+/* Signaling NaN, if supported for each type. All formats supported
+ by GCC support either both quiet and signaling NaNs, or neither
+ kind of NaN. */
+#if __FLT_HAS_QUIET_NAN__
+#undef FLT_SNAN
+#define FLT_SNAN (__builtin_nansf (""))
+#endif
+#if __DBL_HAS_QUIET_NAN__
+#undef DBL_SNAN
+#define DBL_SNAN (__builtin_nans (""))
+#endif
+#if __LDBL_HAS_QUIET_NAN__
+#undef LDBL_SNAN
+#define LDBL_SNAN (__builtin_nansl (""))
+#endif
+
#endif /* C2X */
-#ifdef __STDC_WANT_IEC_60559_BFP_EXT__
+#if (defined __STDC_WANT_IEC_60559_BFP_EXT__ \
+ || defined __STDC_WANT_IEC_60559_EXT__)
/* Number of decimal digits for which conversions between decimal
character strings and binary formats, in both directions, are
correctly rounded. */
@@ -284,6 +320,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define FLT16_DECIMAL_DIG __FLT16_DECIMAL_DIG__
#undef FLT16_TRUE_MIN
#define FLT16_TRUE_MIN __FLT16_DENORM_MIN__
+#if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
+#undef FLT16_SNAN
+#define FLT16_SNAN (__builtin_nansf16 (""))
+#endif /* C2X */
#endif /* __FLT16_MANT_DIG__. */
#ifdef __FLT32_MANT_DIG__
@@ -309,6 +349,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define FLT32_DECIMAL_DIG __FLT32_DECIMAL_DIG__
#undef FLT32_TRUE_MIN
#define FLT32_TRUE_MIN __FLT32_DENORM_MIN__
+#if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
+#undef FLT32_SNAN
+#define FLT32_SNAN (__builtin_nansf32 (""))
+#endif /* C2X */
#endif /* __FLT32_MANT_DIG__. */
#ifdef __FLT64_MANT_DIG__
@@ -334,6 +378,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define FLT64_DECIMAL_DIG __FLT64_DECIMAL_DIG__
#undef FLT64_TRUE_MIN
#define FLT64_TRUE_MIN __FLT64_DENORM_MIN__
+#if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
+#undef FLT64_SNAN
+#define FLT64_SNAN (__builtin_nansf64 (""))
+#endif /* C2X */
#endif /* __FLT64_MANT_DIG__. */
#ifdef __FLT128_MANT_DIG__
@@ -359,6 +407,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define FLT128_DECIMAL_DIG __FLT128_DECIMAL_DIG__
#undef FLT128_TRUE_MIN
#define FLT128_TRUE_MIN __FLT128_DENORM_MIN__
+#if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
+#undef FLT128_SNAN
+#define FLT128_SNAN (__builtin_nansf128 (""))
+#endif /* C2X */
#endif /* __FLT128_MANT_DIG__. */
#ifdef __FLT32X_MANT_DIG__
@@ -384,6 +436,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define FLT32X_DECIMAL_DIG __FLT32X_DECIMAL_DIG__
#undef FLT32X_TRUE_MIN
#define FLT32X_TRUE_MIN __FLT32X_DENORM_MIN__
+#if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
+#undef FLT32X_SNAN
+#define FLT32X_SNAN (__builtin_nansf32x (""))
+#endif /* C2X */
#endif /* __FLT32X_MANT_DIG__. */
#ifdef __FLT64X_MANT_DIG__
@@ -409,6 +465,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define FLT64X_DECIMAL_DIG __FLT64X_DECIMAL_DIG__
#undef FLT64X_TRUE_MIN
#define FLT64X_TRUE_MIN __FLT64X_DENORM_MIN__
+#if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
+#undef FLT64X_SNAN
+#define FLT64X_SNAN (__builtin_nansf64x (""))
+#endif /* C2X */
#endif /* __FLT64X_MANT_DIG__. */
#ifdef __FLT128X_MANT_DIG__
@@ -434,6 +494,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define FLT128X_DECIMAL_DIG __FLT128X_DECIMAL_DIG__
#undef FLT128X_TRUE_MIN
#define FLT128X_TRUE_MIN __FLT128X_DENORM_MIN__
+#if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
+#undef FLT128X_SNAN
+#define FLT128X_SNAN (__builtin_nansf128x (""))
+#endif /* C2X */
#endif /* __FLT128X_MANT_DIG__. */
#endif /* __STDC_WANT_IEC_60559_TYPES_EXT__. */
@@ -537,6 +601,26 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#endif /* __STDC_WANT_IEC_60559_DFP_EXT__ || C2X. */
+#if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
+
+/* Infinity in type _Decimal32. */
+#undef DEC_INFINITY
+#define DEC_INFINITY (__builtin_infd32 ())
+
+/* Quiet NaN in type _Decimal32. */
+#undef DEC_NAN
+#define DEC_NAN (__builtin_nand32 (""))
+
+/* Signaling NaN in each decimal floating-point type. */
+#undef DEC32_SNAN
+#define DEC32_SNAN (__builtin_nansd32 (""))
+#undef DEC64_SNAN
+#define DEC64_SNAN (__builtin_nansd64 (""))
+#undef DEC128_SNAN
+#define DEC128_SNAN (__builtin_nansd128 (""))
+
+#endif /* C2X */
+
#endif /* __DEC32_MANT_DIG__ */
#endif /* _FLOAT_H___ */
diff --git a/gcc/ginclude/stdatomic.h b/gcc/ginclude/stdatomic.h
index b968164..7c2e08a 100644
--- a/gcc/ginclude/stdatomic.h
+++ b/gcc/ginclude/stdatomic.h
@@ -107,7 +107,7 @@ extern void atomic_signal_fence (memory_order);
#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
-/* Note that these macros require __typeof__ and __auto_type to remove
+/* Note that these macros require __auto_type to remove
_Atomic qualifiers (and const qualifiers, if those are valid on
macro operands).
@@ -122,7 +122,7 @@ extern void atomic_signal_fence (memory_order);
__extension__ \
({ \
__auto_type __atomic_store_ptr = (PTR); \
- __typeof__ (*__atomic_store_ptr) __atomic_store_tmp = (VAL); \
+ __typeof__ ((void)0, *__atomic_store_ptr) __atomic_store_tmp = (VAL); \
__atomic_store (__atomic_store_ptr, &__atomic_store_tmp, (MO)); \
})
@@ -134,7 +134,7 @@ extern void atomic_signal_fence (memory_order);
__extension__ \
({ \
__auto_type __atomic_load_ptr = (PTR); \
- __typeof__ (*__atomic_load_ptr) __atomic_load_tmp; \
+ __typeof__ ((void)0, *__atomic_load_ptr) __atomic_load_tmp; \
__atomic_load (__atomic_load_ptr, &__atomic_load_tmp, (MO)); \
__atomic_load_tmp; \
})
@@ -146,8 +146,8 @@ extern void atomic_signal_fence (memory_order);
__extension__ \
({ \
__auto_type __atomic_exchange_ptr = (PTR); \
- __typeof__ (*__atomic_exchange_ptr) __atomic_exchange_val = (VAL); \
- __typeof__ (*__atomic_exchange_ptr) __atomic_exchange_tmp; \
+ __typeof__ ((void)0, *__atomic_exchange_ptr) __atomic_exchange_val = (VAL); \
+ __typeof__ ((void)0, *__atomic_exchange_ptr) __atomic_exchange_tmp; \
__atomic_exchange (__atomic_exchange_ptr, &__atomic_exchange_val, \
&__atomic_exchange_tmp, (MO)); \
__atomic_exchange_tmp; \
@@ -161,7 +161,7 @@ extern void atomic_signal_fence (memory_order);
__extension__ \
({ \
__auto_type __atomic_compare_exchange_ptr = (PTR); \
- __typeof__ (*__atomic_compare_exchange_ptr) __atomic_compare_exchange_tmp \
+ __typeof__ ((void)0, *__atomic_compare_exchange_ptr) __atomic_compare_exchange_tmp \
= (DES); \
__atomic_compare_exchange (__atomic_compare_exchange_ptr, (VAL), \
&__atomic_compare_exchange_tmp, 0, \
@@ -176,7 +176,7 @@ extern void atomic_signal_fence (memory_order);
__extension__ \
({ \
__auto_type __atomic_compare_exchange_ptr = (PTR); \
- __typeof__ (*__atomic_compare_exchange_ptr) __atomic_compare_exchange_tmp \
+ __typeof__ ((void)0, *__atomic_compare_exchange_ptr) __atomic_compare_exchange_tmp \
= (DES); \
__atomic_compare_exchange (__atomic_compare_exchange_ptr, (VAL), \
&__atomic_compare_exchange_tmp, 1, \
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index 4229488..5ed46d6 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -1,3 +1,21 @@
+2020-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/97911
+ * Make-lang.in (go.serial): Change from goal to a variable.
+ (.PHONY): Drop go.serial and go.prev.
+ (go1$(exeext)): Depend on $(go.serial) rather than go.serial.
+
+2020-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ * Make-lang.in (go.serial): New goal.
+ (.PHONY): Add go.serial go.prev.
+ (go1$(exeext)): Depend on go.prev. Call LINK_PROGRESS.
+
+2020-11-11 Alan Modra <amodra@gmail.com>
+
+ * go-gcc.cc (Gcc_backend::global_variable_set_init): Cast NULL to
+ avoid ambiguous overloaded call.
+
2020-11-06 Nathan Sidwell <nathan@acm.org>
* go-gcc.cc (Gcc_backend::call_expression): Rename
diff --git a/gcc/go/Make-lang.in b/gcc/go/Make-lang.in
index ce711b2..a987127 100644
--- a/gcc/go/Make-lang.in
+++ b/gcc/go/Make-lang.in
@@ -27,6 +27,7 @@ GCCGO_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo gccgo|sed '$(pr
# The name for selecting go in LANGUAGES.
go: go1$(exeext)
+go.serial = go1$(exeext)
.PHONY: go
@@ -78,9 +79,11 @@ GO_OBJS = \
go_OBJS = $(GO_OBJS) go/gospec.o
-go1$(exeext): $(GO_OBJS) attribs.o $(BACKEND) $(LIBDEPS)
+go1$(exeext): $(GO_OBJS) attribs.o $(BACKEND) $(LIBDEPS) $(go.prev)
+ @$(call LINK_PROGRESS,$(INDEX.go),start)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(GO_OBJS) attribs.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
+ @$(call LINK_PROGRESS,$(INDEX.go),end)
# Documentation.
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index ba286fa..d8d9c3f 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -2756,7 +2756,7 @@ Gcc_backend::global_variable_set_init(Bvariable* var, Bexpression* expr)
if (symtab_node::get(var_decl)
&& symtab_node::get(var_decl)->implicit_section)
{
- set_decl_section_name (var_decl, NULL);
+ set_decl_section_name (var_decl, (const char *) NULL);
resolve_unique_section (var_decl,
compute_reloc_for_constant (expr_tree),
1);
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index e62578f..cd1a396 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-893fa057e36ae6c9b2ac5ffdf74634c35b3489c6
+b3a0b068f7fa2d65ba781271b2c0479d103b7d7b
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/ast-dump.cc b/gcc/go/gofrontend/ast-dump.cc
index a3cbda9..eca0bf1 100644
--- a/gcc/go/gofrontend/ast-dump.cc
+++ b/gcc/go/gofrontend/ast-dump.cc
@@ -226,7 +226,11 @@ Ast_dump_context::dump_type(const Type* t)
// FIXME: write a type pretty printer instead of
// using mangled names.
if (this->gogo_ != NULL)
- this->ostream() << "(" << t->mangled_name(this->gogo_) << ")";
+ {
+ Backend_name bname;
+ t->backend_name(this->gogo_, &bname);
+ this->ostream() << "(" << bname.name() << ")";
+ }
}
// Dump a textual representation of a block to the
diff --git a/gcc/go/gofrontend/export.cc b/gcc/go/gofrontend/export.cc
index 90a5f6d..e99c680 100644
--- a/gcc/go/gofrontend/export.cc
+++ b/gcc/go/gofrontend/export.cc
@@ -461,7 +461,7 @@ should_export(Named_object* no)
return false;
// We don't export various special functions.
- if (Gogo::is_special_name(no->name()))
+ if (Gogo::special_name_pos(no->name()) != std::string::npos)
return false;
// Methods are exported with the type, not here.
@@ -524,7 +524,11 @@ struct Sort_types
if (t1->classification() != t2->classification())
return t1->classification() < t2->classification();
Gogo* gogo = go_get_gogo();
- return gogo->type_descriptor_name(t1, NULL).compare(gogo->type_descriptor_name(t2, NULL)) < 0;
+ Backend_name b1;
+ gogo->type_descriptor_backend_name(t1, NULL, &b1);
+ Backend_name b2;
+ gogo->type_descriptor_backend_name(t2, NULL, &b2);
+ return b1.name() < b2.name();
}
};
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index e76bc69..ebe1b36 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -1596,7 +1596,8 @@ Func_descriptor_expression::do_get_backend(Translate_context* context)
return context->backend()->var_expression(this->dvar_, loc);
Gogo* gogo = context->gogo();
- std::string var_name(gogo->function_descriptor_name(no));
+ Backend_name bname;
+ gogo->function_descriptor_backend_name(no, &bname);
bool is_descriptor = false;
if (no->is_function_declaration()
&& !no->func_declaration_value()->asm_name().empty()
@@ -1616,10 +1617,11 @@ Func_descriptor_expression::do_get_backend(Translate_context* context)
Btype* btype = this->type()->get_backend(gogo);
Bvariable* bvar;
- std::string asm_name(go_selectively_encode_id(var_name));
if (no->package() != NULL || is_descriptor)
- bvar = context->backend()->immutable_struct_reference(var_name, asm_name,
- btype, loc);
+ bvar =
+ context->backend()->immutable_struct_reference(bname.name(),
+ bname.optional_asm_name(),
+ btype, loc);
else
{
Location bloc = Linemap::predeclared_location();
@@ -1644,7 +1646,8 @@ Func_descriptor_expression::do_get_backend(Translate_context* context)
if (no->is_function() && no->func_value()->is_referenced_by_inline())
is_hidden = false;
- bvar = context->backend()->immutable_struct(var_name, asm_name,
+ bvar = context->backend()->immutable_struct(bname.name(),
+ bname.optional_asm_name(),
is_hidden, false,
btype, bloc);
Expression_list* vals = new Expression_list();
@@ -1654,8 +1657,9 @@ Func_descriptor_expression::do_get_backend(Translate_context* context)
Translate_context bcontext(gogo, NULL, NULL, NULL);
bcontext.set_is_const();
Bexpression* binit = init->get_backend(&bcontext);
- context->backend()->immutable_struct_set_init(bvar, var_name, is_hidden,
- false, btype, bloc, binit);
+ context->backend()->immutable_struct_set_init(bvar, bname.name(),
+ is_hidden, false, btype,
+ bloc, binit);
}
this->dvar_ = bvar;
@@ -4020,8 +4024,16 @@ Type_conversion_expression::do_string_constant_value(std::string* val) const
unsigned long ival;
if (nc.to_unsigned_long(&ival) == Numeric_constant::NC_UL_VALID)
{
+ unsigned int cval = static_cast<unsigned int>(ival);
+ if (static_cast<unsigned long>(cval) != ival)
+ {
+ go_warning_at(this->location(), 0,
+ "unicode code point 0x%lx out of range",
+ ival);
+ cval = 0xfffd; // Unicode "replacement character."
+ }
val->clear();
- Lex::append_char(ival, true, val, this->location());
+ Lex::append_char(cval, true, val, this->location());
return true;
}
}
@@ -5190,11 +5202,9 @@ Unary_expression::do_get_backend(Translate_context* context)
copy_to_heap = (context->function() != NULL
|| context->is_const());
}
- std::string asm_name(go_selectively_encode_id(var_name));
Bvariable* implicit =
- gogo->backend()->implicit_variable(var_name, asm_name,
- btype, true, copy_to_heap,
- false, 0);
+ gogo->backend()->implicit_variable(var_name, "", btype, true,
+ copy_to_heap, false, 0);
gogo->backend()->implicit_variable_set_init(implicit, var_name, btype,
true, copy_to_heap, false,
bexpr);
@@ -5219,10 +5229,9 @@ Unary_expression::do_get_backend(Translate_context* context)
&& this->expr_->is_static_initializer())
{
std::string var_name(gogo->initializer_name());
- std::string asm_name(go_selectively_encode_id(var_name));
Bvariable* decl =
- gogo->backend()->immutable_struct(var_name, asm_name,
- true, false, btype, loc);
+ gogo->backend()->immutable_struct(var_name, "", true, false,
+ btype, loc);
gogo->backend()->immutable_struct_set_init(decl, var_name, true,
false, btype, loc, bexpr);
bexpr = gogo->backend()->var_expression(decl, loc);
@@ -5230,9 +5239,8 @@ Unary_expression::do_get_backend(Translate_context* context)
else if (this->expr_->is_constant())
{
std::string var_name(gogo->initializer_name());
- std::string asm_name(go_selectively_encode_id(var_name));
Bvariable* decl =
- gogo->backend()->implicit_variable(var_name, asm_name, btype,
+ gogo->backend()->implicit_variable(var_name, "", btype,
true, true, false, 0);
gogo->backend()->implicit_variable_set_init(decl, var_name, btype,
true, true, false,
@@ -6279,8 +6287,21 @@ Binary_expression::lower_array_comparison(Gogo* gogo,
args->push_back(this->operand_address(inserter, this->left_));
args->push_back(this->operand_address(inserter, this->right_));
- Expression* ret = Expression::make_call(func, args, false, loc);
-
+ Call_expression* ce = Expression::make_call(func, args, false, loc);
+
+ // Record that this is a call to a generated equality function. We
+ // need to do this because a comparison returns an abstract boolean
+ // type, but the function necessarily returns "bool". The
+ // difference shows up in code like
+ // type mybool bool
+ // var b mybool = [10]string{} == [10]string{}
+ // The comparison function returns "bool", but since a comparison
+ // has an abstract boolean type we need an implicit conversion to
+ // "mybool". The implicit conversion is inserted in
+ // Call_expression::do_flatten.
+ ce->set_is_equal_function();
+
+ Expression* ret = ce;
if (this->op_ == OPERATOR_NOTEQ)
ret = Expression::make_unary(OPERATOR_NOT, ret, loc);
@@ -6971,27 +6992,6 @@ Binary_expression::do_get_backend(Translate_context* context)
// been converted to a String_concat_expression in do_lower.
go_assert(!left_type->is_string_type());
- // For complex division Go might want slightly different results than the
- // backend implementation provides, so we have our own runtime routine.
- if (this->op_ == OPERATOR_DIV && this->left_->type()->complex_type() != NULL)
- {
- Runtime::Function complex_code;
- switch (this->left_->type()->complex_type()->bits())
- {
- case 64:
- complex_code = Runtime::COMPLEX64_DIV;
- break;
- case 128:
- complex_code = Runtime::COMPLEX128_DIV;
- break;
- default:
- go_unreachable();
- }
- Expression* complex_div =
- Runtime::make_call(complex_code, loc, 2, this->left_, this->right_);
- return complex_div->get_backend(context);
- }
-
Bexpression* left = this->left_->get_backend(context);
Bexpression* right = this->right_->get_backend(context);
@@ -8885,8 +8885,8 @@ Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function,
// We will optimize this to directly zeroing the tail,
// instead of allocating a new slice then copy.
- // Retrieve the length. Cannot reference s2 as we will remove
- // the makeslice call.
+ // Retrieve the length and capacity. Cannot reference s2 as
+ // we will remove the makeslice call.
Expression* len_arg = makecall->args()->at(1);
len_arg = Expression::make_cast(int_type, len_arg, loc);
l2tmp = Statement::make_temporary(int_type, len_arg, loc);
@@ -8899,28 +8899,19 @@ Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function,
inserter->insert(c2tmp);
// Check bad len/cap here.
- // if len2 < 0 { panicmakeslicelen(); }
+ // checkmakeslice(type, len, cap)
+ // (Note that if len and cap are constants, we won't see a
+ // makeslice call here, as it will be rewritten to a stack
+ // allocated array by Mark_address_taken::expression.)
+ Expression* elem = Expression::make_type_descriptor(element_type,
+ loc);
len2 = Expression::make_temporary_reference(l2tmp, loc);
- Expression* zero = Expression::make_integer_ul(0, int_type, loc);
- Expression* cond = Expression::make_binary(OPERATOR_LT, len2,
- zero, loc);
- Expression* call = Runtime::make_call(Runtime::PANIC_MAKE_SLICE_LEN,
- loc, 0);
- cond = Expression::make_conditional(cond, call, zero->copy(), loc);
- gogo->lower_expression(function, inserter, &cond);
- gogo->flatten_expression(function, inserter, &cond);
- Statement* s = Statement::make_statement(cond, false);
- inserter->insert(s);
-
- // if cap2 < 0 { panicmakeslicecap(); }
Expression* cap2 = Expression::make_temporary_reference(c2tmp, loc);
- cond = Expression::make_binary(OPERATOR_LT, cap2,
- zero->copy(), loc);
- call = Runtime::make_call(Runtime::PANIC_MAKE_SLICE_CAP, loc, 0);
- cond = Expression::make_conditional(cond, call, zero->copy(), loc);
- gogo->lower_expression(function, inserter, &cond);
- gogo->flatten_expression(function, inserter, &cond);
- s = Statement::make_statement(cond, false);
+ Expression* check = Runtime::make_call(Runtime::CHECK_MAKE_SLICE,
+ loc, 3, elem, len2, cap2);
+ gogo->lower_expression(function, inserter, &check);
+ gogo->flatten_expression(function, inserter, &check);
+ Statement* s = Statement::make_statement(check, false);
inserter->insert(s);
// Remove the original makeslice call.
@@ -11185,6 +11176,13 @@ Call_expression::do_flatten(Gogo* gogo, Named_object*,
return ret;
}
+ // Add an implicit conversion to a boolean type, if needed. See the
+ // comment in Binary_expression::lower_array_comparison.
+ if (this->is_equal_function_
+ && this->type_ != NULL
+ && this->type_ != Type::lookup_bool_type())
+ return Expression::make_cast(this->type_, this, this->location());
+
return this;
}
@@ -11960,7 +11958,7 @@ Call_expression::do_type()
// parameter types to set the types of the arguments.
void
-Call_expression::do_determine_type(const Type_context*)
+Call_expression::do_determine_type(const Type_context* context)
{
if (!this->determining_types())
return;
@@ -12007,6 +12005,22 @@ Call_expression::do_determine_type(const Type_context*)
(*pa)->determine_type_no_context();
}
}
+
+ // If this is a call to a generated equality function, we determine
+ // the type based on the context. See the comment in
+ // Binary_expression::lower_array_comparison.
+ if (this->is_equal_function_
+ && !context->may_be_abstract
+ && context->type != NULL
+ && context->type->is_boolean_type()
+ && context->type != Type::lookup_bool_type())
+ {
+ go_assert(this->type_ == NULL
+ || this->type_ == Type::lookup_bool_type()
+ || this->type_ == context->type
+ || this->type_->is_error());
+ this->type_ = context->type;
+ }
}
// Called when determining types for a Call_expression. Return true
@@ -12794,24 +12808,11 @@ Array_index_expression::do_determine_type(const Type_context*)
this->array_->determine_type_no_context();
Type_context index_context(Type::lookup_integer_type("int"), false);
- if (this->start_->is_constant())
- this->start_->determine_type(&index_context);
- else
- this->start_->determine_type_no_context();
+ this->start_->determine_type(&index_context);
if (this->end_ != NULL)
- {
- if (this->end_->is_constant())
- this->end_->determine_type(&index_context);
- else
- this->end_->determine_type_no_context();
- }
+ this->end_->determine_type(&index_context);
if (this->cap_ != NULL)
- {
- if (this->cap_->is_constant())
- this->cap_->determine_type(&index_context);
- else
- this->cap_->determine_type_no_context();
- }
+ this->cap_->determine_type(&index_context);
}
// Check types of an array index.
@@ -13480,17 +13481,9 @@ String_index_expression::do_determine_type(const Type_context*)
this->string_->determine_type_no_context();
Type_context index_context(Type::lookup_integer_type("int"), false);
- if (this->start_->is_constant())
- this->start_->determine_type(&index_context);
- else
- this->start_->determine_type_no_context();
+ this->start_->determine_type(&index_context);
if (this->end_ != NULL)
- {
- if (this->end_->is_constant())
- this->end_->determine_type(&index_context);
- else
- this->end_->determine_type_no_context();
- }
+ this->end_->determine_type(&index_context);
}
// Check types of a string index.
@@ -15295,9 +15288,22 @@ Array_construction_expression::do_is_static_initializer() const
void
Array_construction_expression::do_determine_type(const Type_context*)
{
+ if (this->is_error_expression())
+ {
+ go_assert(saw_errors());
+ return;
+ }
+
if (this->vals() == NULL)
return;
- Type_context subcontext(this->type_->array_type()->element_type(), false);
+ Array_type* at = this->type_->array_type();
+ if (at == NULL || at->is_error() || at->element_type()->is_error())
+ {
+ go_assert(saw_errors());
+ this->set_is_error();
+ return;
+ }
+ Type_context subcontext(at->element_type(), false);
for (Expression_list::const_iterator pv = this->vals()->begin();
pv != this->vals()->end();
++pv)
@@ -15312,10 +15318,22 @@ Array_construction_expression::do_determine_type(const Type_context*)
void
Array_construction_expression::do_check_types(Gogo*)
{
+ if (this->is_error_expression())
+ {
+ go_assert(saw_errors());
+ return;
+ }
+
if (this->vals() == NULL)
return;
Array_type* at = this->type_->array_type();
+ if (at == NULL || at->is_error() || at->element_type()->is_error())
+ {
+ go_assert(saw_errors());
+ this->set_is_error();
+ return;
+ }
int i = 0;
Type* element_type = at->element_type();
for (Expression_list::const_iterator pv = this->vals()->begin();
@@ -15340,6 +15358,12 @@ Expression*
Array_construction_expression::do_flatten(Gogo*, Named_object*,
Statement_inserter* inserter)
{
+ if (this->is_error_expression())
+ {
+ go_assert(saw_errors());
+ return this;
+ }
+
if (this->vals() == NULL)
return this;
@@ -15376,6 +15400,12 @@ Array_construction_expression::do_flatten(Gogo*, Named_object*,
void
Array_construction_expression::do_add_conversions()
{
+ if (this->is_error_expression())
+ {
+ go_assert(saw_errors());
+ return;
+ }
+
if (this->vals() == NULL)
return;
@@ -18251,9 +18281,8 @@ Interface_mtable_expression::do_get_backend(Translate_context* context)
{
// The interface conversion table is defined elsewhere.
Btype* btype = this->type()->get_backend(gogo);
- std::string asm_name(go_selectively_encode_id(mangled_name));
this->bvar_ =
- gogo->backend()->immutable_struct_reference(mangled_name, asm_name,
+ gogo->backend()->immutable_struct_reference(mangled_name, "",
btype, loc);
return gogo->backend()->var_expression(this->bvar_, this->location());
}
@@ -18323,8 +18352,7 @@ Interface_mtable_expression::do_get_backend(Translate_context* context)
Bexpression* ctor =
gogo->backend()->constructor_expression(btype, ctor_bexprs, loc);
- std::string asm_name(go_selectively_encode_id(mangled_name));
- this->bvar_ = gogo->backend()->immutable_struct(mangled_name, asm_name, false,
+ this->bvar_ = gogo->backend()->immutable_struct(mangled_name, "", false,
!is_public, btype, loc);
gogo->backend()->immutable_struct_set_init(this->bvar_, mangled_name, false,
!is_public, btype, loc, ctor);
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h
index d297523..259eeb6 100644
--- a/gcc/go/gofrontend/expressions.h
+++ b/gcc/go/gofrontend/expressions.h
@@ -2326,8 +2326,8 @@ class Call_expression : public Expression
fn_(fn), args_(args), type_(NULL), call_(NULL), call_temp_(NULL)
, expected_result_count_(0), is_varargs_(is_varargs),
varargs_are_lowered_(false), types_are_determined_(false),
- is_deferred_(false), is_concurrent_(false), issued_error_(false),
- is_multi_value_arg_(false), is_flattened_(false)
+ is_deferred_(false), is_concurrent_(false), is_equal_function_(false),
+ issued_error_(false), is_multi_value_arg_(false), is_flattened_(false)
{ }
// The function to call.
@@ -2408,6 +2408,11 @@ class Call_expression : public Expression
set_is_concurrent()
{ this->is_concurrent_ = true; }
+ // Note that this is a call to a generated equality function.
+ void
+ set_is_equal_function()
+ { this->is_equal_function_ = true; }
+
// We have found an error with this call expression; return true if
// we should report it.
bool
@@ -2545,6 +2550,8 @@ class Call_expression : public Expression
bool is_deferred_;
// True if the call is an argument to a go statement.
bool is_concurrent_;
+ // True if this is a call to a generated equality function.
+ bool is_equal_function_;
// True if we reported an error about a mismatch between call
// results and uses. This is to avoid producing multiple errors
// when there are multiple Call_result_expressions.
diff --git a/gcc/go/gofrontend/go-encode-id.cc b/gcc/go/gofrontend/go-encode-id.cc
index 550da97..7ab65f5 100644
--- a/gcc/go/gofrontend/go-encode-id.cc
+++ b/gcc/go/gofrontend/go-encode-id.cc
@@ -12,8 +12,8 @@
#include "go-encode-id.h"
#include "lex.h"
-// Return whether the character c is OK to use in the assembler. We
-// only permit ASCII alphanumeric characters, underscore, and dot.
+// Return whether the character c can appear in a name that we are
+// encoding. We only permit ASCII alphanumeric characters.
static bool
char_needs_encoding(char c)
@@ -32,7 +32,6 @@ char_needs_encoding(char c)
case 'y': case 'z':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
- case '_': case '.':
return false;
default:
return true;
@@ -53,6 +52,52 @@ go_id_needs_encoding(const std::string& str)
return false;
}
+// Map from characters to the underscore encoding for them.
+
+class Special_char_code
+{
+ public:
+ Special_char_code();
+
+ // Return the simple underscore encoding for C, or 0 if none.
+ char
+ code_for(unsigned int c) const
+ {
+ if (c <= 127)
+ return this->codes_[c];
+ return 0;
+ }
+
+ private:
+ // Encodings for characters.
+ char codes_[128];
+};
+
+// Construct the underscore encoding map.
+
+Special_char_code::Special_char_code()
+{
+ memset(this->codes_, 0, sizeof this->codes_);
+ this->codes_['_'] = '_';
+ this->codes_['.'] = '0';
+ this->codes_['/'] = '1';
+ this->codes_['*'] = '2';
+ this->codes_[','] = '3';
+ this->codes_['{'] = '4';
+ this->codes_['}'] = '5';
+ this->codes_['['] = '6';
+ this->codes_[']'] = '7';
+ this->codes_['('] = '8';
+ this->codes_[')'] = '9';
+ this->codes_['"'] = 'a';
+ this->codes_[' '] = 'b';
+ this->codes_[';'] = 'c';
+}
+
+// The singleton Special_char_code.
+
+static const Special_char_code special_char_code;
+
// Pull the next UTF-8 character out of P and store it in *PC. Return
// the number of bytes read.
@@ -82,10 +127,9 @@ fetch_utf8_char(const char* p, unsigned int* pc)
return len;
}
-// Encode an identifier using assembler-friendly characters. The encoding is
-// described in detail near the end of the long comment at the start of
-// names.cc. Short version: translate all non-ASCII-alphanumeric characters into
-// ..uXXXX or ..UXXXXXXXX, translate ASCII non-alphanumerics into ".zXX".
+// Encode an identifier using assembler-friendly characters. The
+// encoding is described in detail near the end of the long comment at
+// the start of names.cc.
std::string
go_encode_id(const std::string &id)
@@ -96,50 +140,57 @@ go_encode_id(const std::string &id)
return id;
}
- // The encoding is only unambiguous if the input string does not
- // contain ..z, ..u or ..U.
- go_assert(id.find("..z") == std::string::npos);
- go_assert(id.find("..u") == std::string::npos);
- go_assert(id.find("..U") == std::string::npos);
-
std::string ret;
const char* p = id.c_str();
const char* pend = p + id.length();
- // A leading ".0" is a space introduced before a mangled type name
- // that starts with a 'u' or 'U', to avoid confusion with the
- // mangling used here. We don't need a leading ".0", and we don't
- // want symbols that start with '.', so remove it.
- if (p[0] == '.' && p[1] == '0')
- p += 2;
+ // We encode a leading digit, to ensure that no identifier starts
+ // with a digit.
+ if (pend > p && p[0] >= '0' && p[0] <= '9')
+ {
+ char buf[8];
+ snprintf(buf, sizeof buf, "_x%02x", p[0]);
+ ret.append(buf);
+ ++p;
+ }
while (p < pend)
{
unsigned int c;
size_t len = fetch_utf8_char(p, &c);
- if (len == 1 && !char_needs_encoding(c))
+ if (len == 1)
{
- ret += c;
+ if (!char_needs_encoding(c))
+ ret.push_back(c);
+ else
+ {
+ char code = special_char_code.code_for(c);
+ if (code != 0)
+ {
+ ret.push_back('_');
+ ret.push_back(code);
+ }
+ else
+ {
+ char buf[8];
+ snprintf(buf, sizeof buf, "_x%02x", c);
+ ret.append(buf);
+ }
+ }
}
else
{
char buf[16];
- if (len == 1)
- snprintf(buf, sizeof buf, "..z%02x", c);
- else if (c < 0x10000)
- snprintf(buf, sizeof buf, "..u%04x", c);
+ if (c < 0x10000)
+ snprintf(buf, sizeof buf, "_u%04x", c);
else
- snprintf(buf, sizeof buf, "..U%08x", c);
-
- // We don't want a symbol to start with '.', so add a prefix
- // if needed.
- if (ret.empty())
- ret += '_';
-
- ret += buf;
+ snprintf(buf, sizeof buf, "_U%08x", c);
+ ret.append(buf);
}
+
p += len;
}
+
return ret;
}
@@ -170,64 +221,116 @@ go_decode_id(const std::string &encoded)
const char* pend = p + encoded.length();
const Location loc = Linemap::predeclared_location();
- // Special case for initial "_", in case it was introduced
- // as a way to prevent encoded symbol starting with ".".
- if (*p == '_' && (strncmp(p+1, "..u", 3) == 0 || strncmp(p+1, "..U", 3) == 0))
- p++;
-
while (p < pend)
{
- if (strncmp(p, "..z", 3) == 0)
- {
- const char* digits = p+3;
- if (strlen(digits) < 2)
- return "";
- unsigned rune = hex_digits_to_unicode_codepoint(digits, 2);
- Lex::append_char(rune, true, &ret, loc);
- p += 5;
- }
- else if (strncmp(p, "..u", 3) == 0)
- {
- const char* digits = p+3;
- if (strlen(digits) < 4)
- return "";
- unsigned rune = hex_digits_to_unicode_codepoint(digits, 4);
- Lex::append_char(rune, true, &ret, loc);
- p += 7;
- }
- else if (strncmp(p, "..U", 3) == 0)
- {
- const char* digits = p+3;
- if (strlen(digits) < 8)
- return "";
- unsigned rune = hex_digits_to_unicode_codepoint(digits, 8);
- Lex::append_char(rune, true, &ret, loc);
- p += 11;
- }
- else
- {
- ret += *p;
- p += 1;
- }
+ if (*p != '_' || p + 1 == pend)
+ {
+ ret.push_back(*p);
+ p++;
+ continue;
+ }
+
+ switch (p[1])
+ {
+ case '_':
+ ret.push_back('_');
+ p += 2;
+ break;
+ case '0':
+ ret.push_back('.');
+ p += 2;
+ break;
+ case '1':
+ ret.push_back('/');
+ p += 2;
+ break;
+ case '2':
+ ret.push_back('*');
+ p += 2;
+ break;
+ case '3':
+ ret.push_back(',');
+ p += 2;
+ break;
+ case '4':
+ ret.push_back('{');
+ p += 2;
+ break;
+ case '5':
+ ret.push_back('}');
+ p += 2;
+ break;
+ case '6':
+ ret.push_back('[');
+ p += 2;
+ break;
+ case '7':
+ ret.push_back(']');
+ p += 2;
+ break;
+ case '8':
+ ret.push_back('(');
+ p += 2;
+ break;
+ case '9':
+ ret.push_back(')');
+ p += 2;
+ break;
+ case 'a':
+ ret.push_back('"');
+ p += 2;
+ break;
+ case 'b':
+ ret.push_back(' ');
+ p += 2;
+ break;
+ case 'c':
+ ret.push_back(';');
+ p += 2;
+ break;
+ case 'x':
+ {
+ const char* digits = p + 2;
+ if (strlen(digits) < 2)
+ return "";
+ unsigned int rune = hex_digits_to_unicode_codepoint(digits, 2);
+ Lex::append_char(rune, true, &ret, loc);
+ p += 4;
+ }
+ break;
+ case 'u':
+ {
+ const char* digits = p + 2;
+ if (strlen(digits) < 4)
+ return "";
+ unsigned int rune = hex_digits_to_unicode_codepoint(digits, 4);
+ Lex::append_char(rune, true, &ret, loc);
+ p += 6;
+ }
+ break;
+ case 'U':
+ {
+ const char* digits = p + 2;
+ if (strlen(digits) < 8)
+ return "";
+ unsigned int rune = hex_digits_to_unicode_codepoint(digits, 8);
+ Lex::append_char(rune, true, &ret, loc);
+ p += 10;
+ }
+ break;
+ default:
+ return "";
+ }
}
return ret;
}
-std::string
-go_selectively_encode_id(const std::string &id)
-{
- if (go_id_needs_encoding(id))
- return go_encode_id(id);
- return std::string();
-}
-
// Encode a struct field tag. This is only used when we need to
// create a type descriptor for an anonymous struct type with field
-// tags. This mangling is applied before go_encode_id. We skip
-// alphanumerics and underscore, replace every other single byte
-// character with .xNN, and leave larger UTF-8 characters for
-// go_encode_id.
+// tags. Underscore encoding will be applied to the returned string.
+// The tag will appear between curly braces, so that is all we have to
+// avoid.
std::string
go_mangle_struct_tag(const std::string& tag)
@@ -241,28 +344,14 @@ go_mangle_struct_tag(const std::string& tag)
size_t len = fetch_utf8_char(p, &c);
if (len > 1)
ret.append(p, len);
- else if (!char_needs_encoding(c) && c != '.')
- ret += c;
+ else if (c != '{' && c != '}' && c != '\\')
+ ret.push_back(c);
else
{
- char buf[16];
- snprintf(buf, sizeof buf, ".x%02x", c);
- ret += buf;
+ ret.push_back('\\');
+ ret.push_back(c);
}
p += len;
}
return ret;
}
-
-// Encode a package path.
-
-std::string
-go_mangle_pkgpath(const std::string& pkgpath)
-{
- std::string s = pkgpath;
- for (size_t i = s.find('.');
- i != std::string::npos;
- i = s.find('.', i + 1))
- s.replace(i, 1, ".x2e"); // 0x2e is the ASCII encoding for '.'
- return s;
-}
diff --git a/gcc/go/gofrontend/go-encode-id.h b/gcc/go/gofrontend/go-encode-id.h
index 2d09b0c..cbafd54 100644
--- a/gcc/go/gofrontend/go-encode-id.h
+++ b/gcc/go/gofrontend/go-encode-id.h
@@ -25,21 +25,8 @@ go_encode_id(const std::string &id);
extern std::string
go_decode_id(const std::string &id);
-// Returns the empty string if the specified name needs encoding,
-// otherwise invokes go_encode_id on the name and returns the result.
-extern std::string
-go_selectively_encode_id(const std::string &id);
-
// Encodes a struct tag that appears in a type literal encoding.
extern std::string
go_mangle_struct_tag(const std::string& tag);
-// Encode a package path. A package path can contain any arbitrary
-// character, including '.'. go_encode_id expects that any '.' will
-// be inserted by name mangling in a controlled manner. So first
-// translate any '.' using the same .x encoding as used by
-// go_mangle_struct_tag.
-extern std::string
-go_mangle_pkgpath(const std::string& pkgpath);
-
#endif // !defined(GO_ENCODE_ID_H)
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index f40f131..a5e4521 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -299,7 +299,7 @@ void
Gogo::set_pkgpath(const std::string& arg)
{
go_assert(!this->pkgpath_set_);
- this->pkgpath_ = go_mangle_pkgpath(arg);
+ this->pkgpath_ = arg;
this->pkgpath_set_ = true;
this->pkgpath_from_option_ = true;
}
@@ -324,32 +324,6 @@ Gogo::set_prefix(const std::string& arg)
this->prefix_from_option_ = true;
}
-// Given a name which may or may not have been hidden, append the
-// appropriate version of the name to the result string. Take care
-// to avoid creating a sequence that will be rejected by go_encode_id
-// (avoid ..u, ..U, ..z).
-void
-Gogo::append_possibly_hidden_name(std::string *result, const std::string& name)
-{
- // FIXME: This adds in pkgpath twice for hidden symbols, which is
- // less than ideal.
- if (!Gogo::is_hidden_name(name))
- (*result) += name;
- else
- {
- std::string n = ".";
- std::string pkgpath = Gogo::hidden_name_pkgpath(name);
- char lastR = result->at(result->length() - 1);
- char firstP = pkgpath.at(0);
- if (lastR == '.' && (firstP == 'u' || firstP == 'U' || firstP == 'z'))
- n = "_.";
- n.append(pkgpath);
- n.append(1, '.');
- n.append(Gogo::unpack_hidden_name(name));
- (*result) += n;
- }
-}
-
// Munge name for use in an error message.
std::string
@@ -397,8 +371,7 @@ Gogo::set_package_name(const std::string& package_name,
{
if (!this->prefix_from_option_)
this->prefix_ = "go";
- this->pkgpath_ = (go_mangle_pkgpath(this->prefix_) + '.'
- + package_name);
+ this->pkgpath_ = this->prefix_ + '.' + package_name;
this->pkgpath_symbol_ = (Gogo::pkgpath_for_symbol(this->prefix_) + '.'
+ Gogo::pkgpath_for_symbol(package_name));
}
@@ -997,9 +970,9 @@ Gogo::register_type_descriptors(std::vector<Bstatement*>& init_stmts,
it != this->imported_init_fns_.end();
++it)
{
- std::string pkgpath =
- this->pkgpath_from_init_fn_name((*it)->init_name());
- list_names.push_back(this->type_descriptor_list_symbol(pkgpath));
+ std::string pkgpath_symbol =
+ this->pkgpath_symbol_from_init_fn_name((*it)->init_name());
+ list_names.push_back(this->type_descriptor_list_symbol(pkgpath_symbol));
}
// Add the main package itself.
list_names.push_back(this->type_descriptor_list_symbol("main"));
@@ -2746,8 +2719,7 @@ Gogo::clear_file_scope()
// parse tree is lowered.
void
-Gogo::queue_hash_function(Type* type, int64_t size,
- const std::string& hash_name,
+Gogo::queue_hash_function(Type* type, int64_t size, Backend_name* bname,
Function_type* hash_fntype)
{
go_assert(!this->specific_type_functions_are_written_);
@@ -2755,7 +2727,7 @@ Gogo::queue_hash_function(Type* type, int64_t size,
Specific_type_function::Specific_type_function_kind kind =
Specific_type_function::SPECIFIC_HASH;
Specific_type_function* tsf = new Specific_type_function(type, NULL, size,
- kind, hash_name,
+ kind, bname,
hash_fntype);
this->specific_type_functions_.push_back(tsf);
}
@@ -2766,15 +2738,14 @@ Gogo::queue_hash_function(Type* type, int64_t size,
void
Gogo::queue_equal_function(Type* type, Named_type* name, int64_t size,
- const std::string& equal_name,
- Function_type* equal_fntype)
+ Backend_name* bname, Function_type* equal_fntype)
{
go_assert(!this->specific_type_functions_are_written_);
go_assert(!this->in_global_scope());
Specific_type_function::Specific_type_function_kind kind =
Specific_type_function::SPECIFIC_EQUAL;
Specific_type_function* tsf = new Specific_type_function(type, name, size,
- kind, equal_name,
+ kind, bname,
equal_fntype);
this->specific_type_functions_.push_back(tsf);
}
@@ -2872,11 +2843,11 @@ Gogo::write_specific_type_functions()
Specific_type_function* tsf = this->specific_type_functions_.back();
this->specific_type_functions_.pop_back();
if (tsf->kind == Specific_type_function::SPECIFIC_HASH)
- tsf->type->write_hash_function(this, tsf->size, tsf->fnname,
+ tsf->type->write_hash_function(this, tsf->size, &tsf->bname,
tsf->fntype);
else
tsf->type->write_equal_function(this, tsf->name, tsf->size,
- tsf->fnname, tsf->fntype);
+ &tsf->bname, tsf->fntype);
delete tsf;
}
this->specific_type_functions_are_written_ = true;
@@ -3773,7 +3744,7 @@ Check_types_traverse::variable(Named_object* named_object)
&& !var->type()->is_error()
&& (init == NULL || !init->is_error_expression())
&& !Lex::is_invalid_identifier(named_object->name()))
- go_error_at(var->location(), "%qs declared and not used",
+ go_error_at(var->location(), "%qs declared but not used",
named_object->message_name().c_str());
}
return TRAVERSE_CONTINUE;
@@ -6218,6 +6189,56 @@ Function::import_func(Import* imp, std::string* pname,
return true;
}
+// Get the backend name.
+
+void
+Function::backend_name(Gogo* gogo, Named_object* no, Backend_name *bname)
+{
+ if (!this->asm_name_.empty())
+ bname->set_asm_name(this->asm_name_);
+ else if (no->package() == NULL && no->name() == gogo->get_init_fn_name())
+ {
+ // These names appear in the export data and are used
+ // directly in the assembler code. If we change this here
+ // we need to change Gogo::init_imports.
+ bname->set_asm_name(no->name());
+ }
+ else if (this->enclosing_ != NULL)
+ {
+ // Rewrite the nested name to use the enclosing function name.
+ // We don't do this earlier because we just store simple names
+ // in a Named_object, not Backend_names.
+
+ // The name was set by nested_function_name, which always
+ // appends ..funcNNN. We want that to be our suffix.
+ size_t pos = no->name().find("..func");
+ go_assert(pos != std::string::npos);
+
+ Named_object* enclosing = this->enclosing_;
+ while (true)
+ {
+ Named_object* parent = enclosing->func_value()->enclosing();
+ if (parent == NULL)
+ break;
+ enclosing = parent;
+ }
+
+ Type* rtype = NULL;
+ if (enclosing->func_value()->type()->is_method())
+ rtype = enclosing->func_value()->type()->receiver()->type();
+ gogo->function_backend_name(enclosing->name(), enclosing->package(),
+ rtype, bname);
+ bname->append_suffix(no->name().substr(pos));
+ }
+ else
+ {
+ Type* rtype = NULL;
+ if (this->type_->is_method())
+ rtype = this->type_->receiver()->type();
+ gogo->function_backend_name(no->name(), no->package(), rtype, bname);
+ }
+}
+
// Get the backend representation.
Bfunction*
@@ -6226,7 +6247,6 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
if (this->fndecl_ == NULL)
{
unsigned int flags = 0;
- bool is_init_fn = false;
if (no->package() != NULL)
{
// Functions defined in other packages must be visible.
@@ -6238,10 +6258,7 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
&& !this->type_->is_method())
;
else if (no->name() == gogo->get_init_fn_name())
- {
- flags |= Backend::function_is_visible;
- is_init_fn = true;
- }
+ flags |= Backend::function_is_visible;
else if (Gogo::unpack_hidden_name(no->name()) == "main"
&& gogo->is_main_package())
flags |= Backend::function_is_visible;
@@ -6255,29 +6272,13 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
flags |= Backend::function_is_visible;
}
- Type* rtype = NULL;
- if (this->type_->is_method())
- rtype = this->type_->receiver()->type();
-
- std::string asm_name;
if (!this->asm_name_.empty())
{
- asm_name = this->asm_name_;
-
// If an assembler name is explicitly specified, there must
// be some reason to refer to the symbol from a different
// object file.
flags |= Backend::function_is_visible;
}
- else if (is_init_fn)
- {
- // These names appear in the export data and are used
- // directly in the assembler code. If we change this here
- // we need to change Gogo::init_imports.
- asm_name = no->name();
- }
- else
- asm_name = gogo->function_asm_name(no->name(), no->package(), rtype);
// If an inline body refers to this function, then it
// needs to be visible in the symbol table.
@@ -6337,13 +6338,36 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
flags |= Backend::function_only_inline;
Btype* functype = this->type_->get_backend_fntype(gogo);
- this->fndecl_ =
- gogo->backend()->function(functype, no->get_id(gogo), asm_name,
- flags, this->location());
+
+ Backend_name bname;
+ this->backend_name(gogo, no, &bname);
+
+ this->fndecl_ = gogo->backend()->function(functype,
+ bname.name(),
+ bname.optional_asm_name(),
+ flags,
+ this->location());
}
return this->fndecl_;
}
+// Get the backend name.
+
+void
+Function_declaration::backend_name(Gogo* gogo, Named_object* no,
+ Backend_name* bname)
+{
+ if (!this->asm_name_.empty())
+ bname->set_asm_name(this->asm_name_);
+ else
+ {
+ Type* rtype = NULL;
+ if (this->fntype_->is_method())
+ rtype = this->fntype_->receiver()->type();
+ gogo->function_backend_name(no->name(), no->package(), rtype, bname);
+ }
+}
+
// Get the backend representation.
Bfunction*
@@ -6375,21 +6399,16 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no)
flags |= Backend::function_does_not_return;
}
- std::string asm_name;
- if (this->asm_name_.empty())
- {
- Type* rtype = NULL;
- if (this->fntype_->is_method())
- rtype = this->fntype_->receiver()->type();
- asm_name = gogo->function_asm_name(no->name(), no->package(), rtype);
- }
- else if (go_id_needs_encoding(no->get_id(gogo)))
- asm_name = go_encode_id(no->get_id(gogo));
-
Btype* functype = this->fntype_->get_backend_fntype(gogo);
- this->fndecl_ =
- gogo->backend()->function(functype, no->get_id(gogo), asm_name,
- flags, this->location());
+
+ Backend_name bname;
+ this->backend_name(gogo, no, &bname);
+
+ this->fndecl_ = gogo->backend()->function(functype,
+ bname.name(),
+ bname.optional_asm_name(),
+ flags,
+ this->location());
}
return this->fndecl_;
@@ -7993,7 +8012,6 @@ Variable::get_backend_variable(Gogo* gogo, Named_object* function,
type = Type::make_pointer_type(type);
}
- const std::string n = Gogo::unpack_hidden_name(name);
Btype* btype = type->get_backend(gogo);
Bvariable* bvar;
@@ -8001,19 +8019,14 @@ Variable::get_backend_variable(Gogo* gogo, Named_object* function,
bvar = Map_type::backend_zero_value(gogo);
else if (this->is_global_)
{
- std::string var_name(package != NULL
- ? package->package_name()
- : gogo->package_name());
- var_name.push_back('.');
- var_name.append(n);
-
- std::string asm_name(gogo->global_var_asm_name(name, package));
+ Backend_name bname;
+ gogo->global_var_backend_name(name, package, &bname);
bool is_hidden = Gogo::is_hidden_name(name);
// Hack to export runtime.writeBarrier. FIXME.
// This is because go:linkname doesn't work on variables.
if (gogo->compiling_runtime()
- && var_name == "runtime.writeBarrier")
+ && bname.name() == "runtime.writeBarrier")
is_hidden = false;
// If an inline body refers to this variable, then it
@@ -8028,8 +8041,12 @@ Variable::get_backend_variable(Gogo* gogo, Named_object* function,
if (package != NULL)
is_hidden = false;
- bvar = backend->global_variable(var_name,
- asm_name,
+ // For some reason asm_name can't be the empty string
+ // for global_variable, so we call asm_name rather than
+ // optional_asm_name here. FIXME.
+
+ bvar = backend->global_variable(bname.name(),
+ bname.asm_name(),
btype,
package != NULL,
is_hidden,
@@ -8043,6 +8060,7 @@ Variable::get_backend_variable(Gogo* gogo, Named_object* function,
}
else
{
+ const std::string n = Gogo::unpack_hidden_name(name);
Bfunction* bfunction = function->func_value()->get_decl();
bool is_address_taken = (this->is_non_escaping_address_taken_
&& !this->is_in_heap());
@@ -8216,7 +8234,13 @@ Named_constant::get_backend(Gogo* gogo, Named_object* const_no)
if (type != NULL && type->is_numeric_type())
{
Btype* btype = type->get_backend(gogo);
- std::string name = const_no->get_id(gogo);
+ std::string name;
+ if (const_no->package() == NULL)
+ name = gogo->pkgpath();
+ else
+ name = const_no->package()->pkgpath();
+ name.push_back('.');
+ name.append(Gogo::unpack_hidden_name(const_no->name()));
const_decl =
gogo->backend()->named_constant_expression(btype, name,
const_decl, loc);
@@ -8637,54 +8661,6 @@ Named_object::get_backend_variable(Gogo* gogo, Named_object* function)
go_unreachable();
}
-// Return the external identifier for this object.
-
-std::string
-Named_object::get_id(Gogo* gogo)
-{
- go_assert(!this->is_variable()
- && !this->is_result_variable()
- && !this->is_type());
- std::string decl_name;
- if (this->is_function_declaration()
- && !this->func_declaration_value()->asm_name().empty())
- decl_name = this->func_declaration_value()->asm_name();
- else
- {
- std::string package_name;
- if (this->package_ == NULL)
- package_name = gogo->package_name();
- else
- package_name = this->package_->package_name();
-
- // Note that this will be misleading if this is an unexported
- // method generated for an embedded imported type. In that case
- // the unexported method should have the package name of the
- // package from which it is imported, but we are going to give
- // it our package name. Fixing this would require knowing the
- // package name, but we only know the package path. It might be
- // better to use package paths here anyhow. This doesn't affect
- // the assembler code, because we always set that name in
- // Function::get_or_make_decl anyhow. FIXME.
-
- decl_name = package_name + '.' + Gogo::unpack_hidden_name(this->name_);
-
- Function_type* fntype;
- if (this->is_function())
- fntype = this->func_value()->type();
- else if (this->is_function_declaration())
- fntype = this->func_declaration_value()->type();
- else
- fntype = NULL;
- if (fntype != NULL && fntype->is_method())
- {
- decl_name.push_back('.');
- decl_name.append(fntype->receiver()->type()->mangled_name(gogo));
- }
- }
- return decl_name;
-}
-
void
debug_go_named_object(Named_object* no)
{
diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h
index 45be173..f22d476 100644
--- a/gcc/go/gofrontend/gogo.h
+++ b/gcc/go/gofrontend/gogo.h
@@ -57,6 +57,101 @@ class Node;
// This file declares the basic classes used to hold the internal
// representation of Go which is built by the parser.
+// The name of some backend object. Backend objects have a
+// user-visible name and an assembler name. The user visible name
+// might include arbitrary Unicode characters. The assembler name
+// will not.
+
+class Backend_name
+{
+ public:
+ Backend_name()
+ : prefix_(NULL), components_(), count_(0), suffix_(),
+ is_asm_name_(false)
+ {}
+
+ // Set the prefix. Prefixes are always constant strings.
+ void
+ set_prefix(const char* p)
+ {
+ go_assert(this->prefix_ == NULL && !this->is_asm_name_);
+ this->prefix_ = p;
+ }
+
+ // Set the suffix.
+ void
+ set_suffix(const std::string& s)
+ {
+ go_assert(this->suffix_.empty() && !this->is_asm_name_);
+ this->suffix_ = s;
+ }
+
+ // Append to the suffix.
+ void
+ append_suffix(const std::string& s)
+ {
+ if (this->is_asm_name_)
+ this->components_[0].append(s);
+ else
+ this->suffix_.append(s);
+ }
+
+ // Add a component.
+ void
+ add(const std::string& c)
+ {
+ go_assert(this->count_ < Backend_name::max_components
+ && !this->is_asm_name_);
+ this->components_[this->count_] = c;
+ ++this->count_;
+ }
+
+ // Set an assembler name specified by the user. This overrides both
+ // the user-visible name and the assembler name. No further
+ // encoding is applied.
+ void
+ set_asm_name(const std::string& n)
+ {
+ go_assert(this->prefix_ == NULL
+ && this->count_ == 0
+ && this->suffix_.empty()
+ && !this->is_asm_name_);
+ this->components_[0] = n;
+ this->is_asm_name_ = true;
+ }
+
+ // Get the user visible name.
+ std::string
+ name() const;
+
+ // Get the assembler name. This may be the same as the user visible
+ // name.
+ std::string
+ asm_name() const;
+
+ // Get an optional assembler name: if it would be the same as the
+ // user visible name, this returns the empty string.
+ std::string
+ optional_asm_name() const;
+
+ private:
+ // The maximum number of components.
+ static const int max_components = 4;
+
+ // An optional prefix that does not require encoding.
+ const char *prefix_;
+ // Up to four components. The name will include these components
+ // separated by dots. Each component will be underscore-encoded
+ // (see the long comment near the top of names.cc).
+ std::string components_[Backend_name::max_components];
+ // Number of components.
+ int count_;
+ // An optional suffix that does not require encoding.
+ std::string suffix_;
+ // True if components_[0] is an assembler name specified by the user.
+ bool is_asm_name_;
+};
+
// An initialization function for an imported package. This is a
// magic function which initializes variables and runs the "init"
// function.
@@ -613,7 +708,7 @@ class Gogo
// is used when a type-specific hash function is needed when not at
// top level.
void
- queue_hash_function(Type* type, int64_t size, const std::string& hash_name,
+ queue_hash_function(Type* type, int64_t size, Backend_name*,
Function_type* hash_fntype);
// Queue up a type-specific equal function to be written out. This
@@ -621,8 +716,7 @@ class Gogo
// top level.
void
queue_equal_function(Type* type, Named_type* name, int64_t size,
- const std::string& equal_name,
- Function_type* equal_fntype);
+ Backend_name*, Function_type* equal_fntype);
// Write out queued specific type functions.
void
@@ -869,31 +963,32 @@ class Gogo
Expression*
allocate_memory(Type *type, Location);
- // Return the assembler name to use for an exported function, a
- // method, or a function/method declaration.
- std::string
- function_asm_name(const std::string& go_name, const Package*,
- const Type* receiver);
+ // Get the backend name to use for an exported function, a method,
+ // or a function/method declaration.
+ void
+ function_backend_name(const std::string& go_name, const Package*,
+ const Type* receiver, Backend_name*);
// Return the name to use for a function descriptor.
- std::string
- function_descriptor_name(Named_object*);
+ void
+ function_descriptor_backend_name(Named_object*, Backend_name*);
// Return the name to use for a generated stub method.
std::string
stub_method_name(const Package*, const std::string& method_name);
- // Return the name of the hash function for TYPE.
- std::string
- hash_function_name(const Type*);
+ // Get the backend name of the hash function for TYPE.
+ void
+ hash_function_name(const Type*, Backend_name*);
- // Return the name of the equal function for TYPE.
- std::string
- equal_function_name(const Type*, const Named_type*);
+ // Get the backend name of the equal function for TYPE.
+ void
+ equal_function_name(const Type*, const Named_type*, Backend_name*);
- // Return the assembler name to use for a global variable.
- std::string
- global_var_asm_name(const std::string& go_name, const Package*);
+ // Get the backend name to use for a global variable.
+ void
+ global_var_backend_name(const std::string& go_name, const Package*,
+ Backend_name*);
// Return a name to use for an error case. This should only be used
// after reporting an error, and is used to avoid useless knockon
@@ -961,13 +1056,14 @@ class Gogo
// Return the package path symbol from an init function name, which
// can be a real init function or a dummy one.
std::string
- pkgpath_from_init_fn_name(std::string);
+ pkgpath_symbol_from_init_fn_name(std::string);
- // Return the name for a type descriptor symbol.
- std::string
- type_descriptor_name(const Type*, Named_type*);
+ // Get the backend name for a type descriptor symbol.
+ void
+ type_descriptor_backend_name(const Type*, Named_type*, Backend_name*);
// Return the name of the type descriptor list symbol of a package.
+ // The argument is an encoded pkgpath, as with pkgpath_symbol.
std::string
type_descriptor_list_symbol(const std::string&);
@@ -987,11 +1083,11 @@ class Gogo
std::string
interface_method_table_name(Interface_type*, Type*, bool is_pointer);
- // Return whether NAME is a special name that can not be passed to
- // unpack_hidden_name. This is needed because various special names
- // use "..SUFFIX", but unpack_hidden_name just looks for '.'.
- static bool
- is_special_name(const std::string& name);
+ // If NAME is a special name used as a Go identifier, return the
+ // position within the string where the special part of the name
+ // occurs.
+ static size_t
+ special_name_pos(const std::string& name);
private:
// During parsing, we keep a stack of functions. Each function on
@@ -1056,6 +1152,9 @@ class Gogo
Named_object*
write_barrier_variable();
+ static bool
+ is_digits(const std::string&);
+
// Type used to map import names to packages.
typedef std::map<std::string, Package*> Imports;
@@ -1079,15 +1178,15 @@ class Gogo
Named_type* name;
int64_t size;
Specific_type_function_kind kind;
- std::string fnname;
+ Backend_name bname;
Function_type* fntype;
Specific_type_function(Type* atype, Named_type* aname, int64_t asize,
Specific_type_function_kind akind,
- const std::string& afnname,
+ Backend_name* abname,
Function_type* afntype)
: type(atype), name(aname), size(asize), kind(akind),
- fnname(afnname), fntype(afntype)
+ bname(*abname), fntype(afntype)
{ }
};
@@ -1631,6 +1730,10 @@ class Function
Bstatement*
return_value(Gogo*, Named_object*, Location) const;
+ // Get the backend name of this function.
+ void
+ backend_name(Gogo*, Named_object*, Backend_name*);
+
// Get an expression for the variable holding the defer stack.
Expression*
defer_stack(Location);
@@ -1872,6 +1975,10 @@ class Function_declaration
void
build_backend_descriptor(Gogo*);
+ // Get the backend name of this function declaration.
+ void
+ backend_name(Gogo*, Named_object*, Backend_name*);
+
// Export a function declaration.
void
export_func(Export* exp, const Named_object* no) const
@@ -2863,10 +2970,6 @@ class Named_object
Bvariable*
get_backend_variable(Gogo*, Named_object* function);
- // Return the external identifier for this object.
- std::string
- get_id(Gogo*);
-
// Get the backend representation of this object.
void
get_backend(Gogo*, std::vector<Bexpression*>&, std::vector<Btype*>&,
diff --git a/gcc/go/gofrontend/names.cc b/gcc/go/gofrontend/names.cc
index 1f0a545..0097417 100644
--- a/gcc/go/gofrontend/names.cc
+++ b/gcc/go/gofrontend/names.cc
@@ -15,53 +15,68 @@
// assembly code. This is not used for names that appear only in the
// debug info.
-// Our external names contain only ASCII alphanumeric characters,
+// Our external names may contain only ASCII alphanumeric characters,
// underscore, and dot. (According to the GCC sources, dot is not
// permitted in assembler symbols on VxWorks and MMIX. We will not
-// support those systems.) Go names can not contain dot, so we rely
-// on using dot to encode Unicode characters, and to separate Go
-// symbols by package, and so forth. We assume that none of the
-// non-Go symbols in the final link will contain a dot, so we don't
-// worry about conflicts.
+// support those systems.) Go identifiers cannot contain dot, but Go
+// package paths can. Both Go identifiers and package paths can, of
+// course, contain all sorts of Unicode characters.
+//
+// The gc compiler uses names like "pkg.F", and it seems convenient to
+// emulate that. Therefore, we will use dot to separate different
+// components of names.
+//
+// Since package paths can contain dot, to avoid ambiguity we must
+// encode package paths such that they do not contain any dot. The
+// natural way to do this is to encode forbidden characters, including
+// dot, using a notation based on underscore. We will, of course,
+// have to encode underscore itself.
+//
+// Since we will be using an underscore encoding for the package path,
+// it seems reasonable to use the same encoding for Go identifiers.
+// This has the disadvantage that encoded Go identifiers will appear
+// to be valid Go identifiers with funny spellings, but it seems like
+// the best available approach.
+//
+// Therefore, in the following discussion we may assume that none of
+// the names under discussion contain a dot. All of the names we
+// generate for Go identifiers (that don't use //export or
+// //go:linkname) will contain at least one dot, as discussed below.
+// We assume that none of the non-Go symbols in the final link will
+// contain a dot, so we don't worry about conflicts.
//
// We first describe the basic symbol names, used to represent Go
-// functions and variables. These never start with a dot, never end
-// with a dot, never contain two consecutive dots, and never contain a
-// dot followed by a digit.
+// functions and variables.
//
// The external name for a normal Go symbol NAME, a function or
// variable, is simply "PKGPATH.NAME". Note that NAME is not the
// packed form used for the "hidden" name internally in the compiler;
-// it is the name that appears in the source code. PKGPATH is the
-// -fgo-pkgpath option as adjusted by Gogo::pkgpath_for_symbol. Note
-// that PKGPATH can not contain a dot and neither can NAME. Also,
-// NAME may not begin with a digit. NAME may require further encoding
-// for non-ASCII characters as described below, but until that
-// encoding these symbols contain exactly one dot, and they do not
-// start with a dot.
+// it is the name that appears in the source code. Both PKGPATH and
+// NAME will be encoded as described below. The encoding process
+// ensures that neither encoded string can contain a dot, and neither
+// will start with a digit (NAME is a Go identifier that can't contain
+// a dot or start with a digit anyhow). The encoding process means
+// that these external names contain exactly one dot and do not start
+// with a dot.
//
// The external name for a method NAME for a named type TYPE is
-// "PKGPATH.TYPE.NAME". Unlike the gc compiler, the external name
-// does not indicate whether this is a pointer method or a value
-// method; a named type can not have both a pointer and value method
-// with the same name, so there is no ambiguity. PKGPATH is the
-// package path of the package in which TYPE is defined. Here none of
-// PKGPATH, TYPE, or NAME can be empty or contain a dot, and neither
-// TYPE nor NAME may begin with a digit. Before encoding these names
-// contain exactly two dots, not consecutive, and they do not start
-// with a dot.
+// "PKGPATH.TYPE.NAME". Both NAME and TYPE are simple Go identifiers.
+// Unlike the gc compiler, the external name does not indicate whether
+// this is a pointer method or a value method; a named type can not
+// have both a pointer and value method with the same name, so there
+// is no ambiguity. PKGPATH is the package path of the package in
+// which TYPE is defined. PKGPATH, TYPE, and NAME are encoded, and
+// cannot be empty or contain a dot or start with a digit. These
+// external names contain exactly two dots, not consecutive, and they
+// do not start with a dot.
//
// It's uncommon, but the use of type literals with embedded fields
// can cause us to have methods on unnamed types. The external names
-// for these are also PKGPATH.TYPE.NAME, where TYPE is an
+// for these are also PKGPATH.TYPELIT.NAME, where TYPELIT is an
// approximately readable version of the type literal, described
-// below. As the type literal encoding always contains multiple dots,
-// these names always contain more than two dots. Although the type
-// literal encoding contains dots, neither PKGPATH nor NAME can
-// contain a dot, and neither TYPE nor NAME can begin with a digit.
-// The effect is that PKGPATH is always the portion of the name before
-// the first dot and NAME is always the portion after the last dot.
-// There is no ambiguity as long as encoded type literals are
+// below. A TYPELIT will always contain characters that cannot appear
+// in a Go identifier, so TYPELIT can never be confused with a TYPE
+// name. There is no ambiguity as long as encoded type literals are
// unambiguous.
//
// Also uncommon is an external name that must refer to a named type
@@ -91,46 +106,51 @@
// the function with an added suffix "..f".
//
// A thunk for a go or defer statement is treated as a function whose
-// name is ".thunkNN" where NN is a sequence of digits (these
-// functions are never globally visible). Thus the final name of a
-// thunk will be PKGPATH..thunkNN.
+// name is ".thunkNN", unencoded, where NN is a sequence of digits
+// (these functions are never globally visible). Thus the final name
+// of a thunk will be PKGPATH..thunkNN (PKGPATH is encoded).
//
-// An init function is treated as a function whose name is ".initNN"
-// where NN is a sequence of digits (these functions are never
-// globally visible). Thus the final name of an init function will be
-// PKGPATH..initNN.
+// An init function is treated as a function whose name is ".initNN",
+// unencoded, where NN is a sequence of digits (these functions are
+// never globally visible). Thus the final name of an init function
+// will be PKGPATH..initNN (PKGPATH is encoded).
//
// A nested function is given the name of outermost enclosing function
-// or method with an added suffix "..funcNN" where NN is a sequence of
-// digits. Note that the function descriptor of a nested function, if
-// needed, will end with "..funcNN..f".
+// or method with an added suffix "..funcNN", unencoded, where NN is a
+// sequence of digits. Note that the function descriptor of a nested
+// function, if needed, will end with "..funcNN..f".
//
// A recover thunk is the same as the name of the function with an
// added suffix "..r".
//
-// The name of a type descriptor for a named type is PKGPATH.TYPE..d.
+// The name of a type descriptor for a named type is
+// PKGPATH.TYPENAME..d (PKGPATH and TYPENAME are encoded).
//
-// The name of a type descriptor for an unnamed type is type..TYPE.
-// That is, the string "type.." followed by the type literal encoding.
+// The name of a type descriptor for a pointer to a named type is
+// PKGPATH.TYPENAME..p (PKGPATH and TYPENAME are encoded).
+//
+// The name of a type descriptor for an unnamed type is type..TYPELIT.
+// That is, the string "type.." followed by the encoded type literal.
// These names are common symbols, in the linker's sense of the word
// common: in the final executable there is only one instance of the
-// type descriptor for a given unnamed type. The type literal
-// encoding can never start with a digit or with 'u' or 'U'.
+// type descriptor for a given unnamed type.
//
-// The name of the GC symbol for a named type is PKGPATH.TYPE..g.
+// The name of the GC symbol for a named type is PKGPATH.TYPE..g
+// (PKGPATH and TYPE are encoded).
//
-// The name of the GC symbol for an unnamed type is typeg..TYPE.
+// The name of the GC symbol for an unnamed type is type..TYPELIT..g.
// These are common symbols.
//
// The name of a ptrmask symbol is gcbits..B32 where B32 is an
-// encoding of the ptrmask bits using only ASCII letters without 'u'
-// or 'U'. These are common symbols.
+// encoding of the ptrmask bits using only ASCII letters. These are
+// common symbols.
//
// An interface method table for assigning the non-interface type TYPE
// to the interface type ITYPE is named imt..ITYPE..TYPE. If ITYPE or
-// TYPE is a named type, they are written as PKGPATH.TYPE. Otherwise
-// they are written as a type literal. An interface method table for
-// a pointer method set uses pimt instead of imt.
+// TYPE is a named type, they are written as PKGPATH.TYPE (where both
+// PKGPATH and TYPE are encoded). Otherwise they are written as a
+// type literal. An interface method table for a pointer method set
+// uses pimt instead of imt.
//
// The names of composite literal initializers, including the GC root
// variable, are not referenced. They must not conflict with any C
@@ -147,7 +167,7 @@
// PKGPATH..import. If a package doesn't need an init function, it
// will have a dummy one, named ~PKGPATH.
//
-// In each pacakge there is a list of all the type descriptors defined
+// In each package there is a list of all the type descriptors defined
// in this package. The name of the list is PKGPATH..types.
//
// In the main package it gathers all the type descriptor lists in a
@@ -161,109 +181,109 @@
// The type literal encoding is not quite valid Go, as some aspects of
// compiler generated types can not be represented. For example,
// incomparable struct types have an extra field "{x}". Struct tags
-// are quoted inside curly braces, rather than introduce an encoding
-// for quotes. Struct tags can contain any character, so any single
-// byte Unicode character that is not alphanumeric or underscore is
-// replaced with .xNN where NN is the hex encoding.
+// can contain any character, which will be underscore encoded as
+// usual. In the unusual case of a curly brace or a backslash in a
+// struct tag, the brace or backslash will be backslash quoted, before
+// underscore encoding.
+//
+// The underscore encoding is, naturally, an underscore followed by
+// other characters. As there are various characters that commonly
+// appear in type literals and in package paths, we have a set of
+// short encodings. Then we have general encodings for other
+// characters.
//
-// There is a simple encoding for glue characters in type literals:
-// .0 - ' '
-// .1 - '*'
-// .2 - ';'
-// .3 - ','
-// .4 - '{'
-// .5 - '}'
-// .6 - '['
-// .7 - ']'
-// .8 - '('
-// .9 - ')'
-// This is unambiguous as, although the type literal can contain a dot
-// as shown above, those dots are always followed by a name and names
-// can not begin with a digit. A dot is always followed by a name or
-// a digit, and a type literal can neither start nor end with a dot,
-// so this never introduces consecutive dots.
+// __ - '_'
+// _0 - '.'
+// _1 - '/'
+// _2 - '*'
+// _3 - ','
+// _4 - '{'
+// _5 - '}'
+// _6 - '['
+// _7 - ']'
+// _8 - '('
+// _9 - ')'
+// _a - '"'
+// _b - ' '
+// _c - ';'
//
-// Struct tags can contain any character, so they need special
-// treatment. Alphanumerics, underscores, and Unicode characters that
-// require more than a single byte are left alone (Unicode characters
-// will be encoded later, as described below). Other single bytes
-// characters are replace with .xNN where NN is the hex encoding.
+// Other non-alphanumeric ASCII characters are encoded as _xNN, where
+// NN is the hex value for the character. If an encoded name would
+// otherwise start with a digit, this encoding is also used for the
+// leading digit.
//
-// Since Go identifiers can contain Unicode characters, we must encode
-// them into ASCII. We do this last, after the name is generated as
-// described above and after type literals are encoded. To make the
-// encoding unambiguous, we introduce it with two consecutive dots.
-// This is followed by the letter u and four hex digits or the letter
-// U and eight digits, just as in the language only using ..u and ..U
-// instead of \u and \U. The compiler also produces identifiers that
-// are qualified by package path, which means that there may also be ASCII
-// characters that are not assembler-friendly (ex: '=', '/'). The encoding
-// scheme translates such characters into the "..zNN" where NN is the
-// hex value for the character. Since before this encoding names can never
-// contain consecutive dots followed by 'z', 'u' or 'U', and after this
-// encoding "..z", "..u" and "..U" are followed by a known number of
-// characters, this is unambiguous.
+// Non-ASCII Unicode characters are encoded as _u and four hex digits
+// or _U and eight digits, just as in the language only using _u and
+// _U instead of \u and \U.
//
// Demangling these names is straightforward:
-// - replace ..zXX with an ASCII character
-// - replace ..uXXXX with a unicode character
-// - replace ..UXXXXXXXX with a unicode character
-// - replace .D, where D is a digit, with the character from the above
+// - replace _xXX with an ASCII character
+// - replace _uXXXX with a unicode character
+// - replace _UXXXXXXXX with a unicode character
+// - replace _C per the table above
// That will get you as close as possible to a readable name.
-// Return the assembler name to use for an exported function, a
-// method, or a function/method declaration. This is not called if
-// the function has been given an explicit name via a magic //extern
-// or //go:linkname comment. GO_NAME is the name that appears in the
-// Go code. PACKAGE is the package where the function is defined, and
-// is NULL for the package being compiled. For a method, RTYPE is
+// Set BNAME to the name to use for an exported function, a method, or
+// a function/method declaration. GO_NAME is the name that appears in
+// the Go code. PACKAGE is the package where the function is defined,
+// and is NULL for the package being compiled. For a method, RTYPE is
// the method's receiver type; for a function, RTYPE is NULL.
-std::string
-Gogo::function_asm_name(const std::string& go_name, const Package* package,
- const Type* rtype)
+void
+Gogo::function_backend_name(const std::string& go_name,
+ const Package* package, const Type* rtype,
+ Backend_name* bname)
{
- std::string ret;
if (rtype != NULL)
- ret = rtype->deref()->mangled_name(this);
+ rtype->deref()->backend_name(this, bname);
else if (package == NULL)
- ret = this->pkgpath();
+ bname->add(this->pkgpath());
else
- ret = package->pkgpath();
- ret.push_back('.');
- // Check for special names that will break if we use
- // Gogo::unpack_hidden_name.
- if (Gogo::is_special_name(go_name))
- ret.append(go_name);
+ bname->add(package->pkgpath());
+
+ size_t pos = Gogo::special_name_pos(go_name);
+ if (pos == std::string::npos)
+ bname->add(Gogo::unpack_hidden_name(go_name));
else
- ret.append(Gogo::unpack_hidden_name(go_name));
- return go_encode_id(ret);
+ {
+ if (pos > 0)
+ bname->add(go_name.substr(0, pos));
+ bname->set_suffix(go_name.substr(pos));
+ }
}
-// Return the name to use for a function descriptor. These symbols
-// are globally visible.
+// Set BNAME to the name to use for a function descriptor. These
+// symbols are globally visible.
-std::string
-Gogo::function_descriptor_name(Named_object* no)
+void
+Gogo::function_descriptor_backend_name(Named_object* no,
+ Backend_name* bname)
{
- if (no->is_function() && !no->func_value()->asm_name().empty())
- return no->func_value()->asm_name() + "..f";
- else if (no->is_function_declaration()
- && !no->func_declaration_value()->asm_name().empty())
- return no->func_declaration_value()->asm_name() + "..f";
- std::string ret = this->function_asm_name(no->name(), no->package(), NULL);
- ret.append("..f");
- return ret;
+ if (no->is_function())
+ no->func_value()->backend_name(this, no, bname);
+ else if (no->is_function_declaration())
+ no->func_declaration_value()->backend_name(this, no, bname);
+ else
+ go_unreachable();
+ bname->append_suffix("..f");
}
-// Return the name to use for a generated stub method. MNAME is the
-// method name. PACKAGE is the package where the type that needs this
-// stub method is defined. These functions are globally visible.
-// Note that this is the function name that corresponds to the name
-// used for the method in Go source code, if this stub method were
-// written in Go. The assembler name will be generated by
-// Gogo::function_asm_name, and because this is a method that name
-// will include the receiver type.
+// Return the name to use for a generated stub method. A stub method
+// is used as the method table entry for a promoted method of an
+// embedded type. MNAME is the method name. PACKAGE is the package
+// where the type that needs this stub method is defined. These
+// functions are globally visible.
+//
+// This returns a name that acts like a Go identifier, as though the
+// stub method were written in Go as an explicitly defined method that
+// simply calls the promoted method. The name we return here will
+// eventually be passed to function_backend_name, which will return a
+// name that includes the receiver type.
+//
+// We construct a unique method name and append "..stub".
+// function_backend_name will look for the "..stub" and turn that into
+// an unencoded suffix. The rest of the name will be encoded as
+// usual.
std::string
Gogo::stub_method_name(const Package* package, const std::string& mname)
@@ -279,56 +299,70 @@ Gogo::stub_method_name(const Package* package, const std::string& mname)
return Gogo::unpack_hidden_name(mname) + "..stub";
// We are creating a stub method for an unexported method of an
- // imported embedded type. We need to disambiguate the method name.
- std::string ret = mpkgpath;
+ // imported embedded type. A single type can have multiple promoted
+ // methods with the same unexported name, if it embeds types from
+ // different packages. We need to disambiguate the method name.
+ // This produces an unambiguous name because even though MPKGPATH
+ // can be anything, we know that MNAME does not contain a dot. The
+ // dot we return here, between MPKGPATH and MNAME, will wind up
+ // being underscore encoded.
+ std::string ret(mpkgpath);
ret.push_back('.');
ret.append(Gogo::unpack_hidden_name(mname));
ret.append("..stub");
return ret;
}
-// Return the name of the hash function for TYPE.
+// Set BNAME to the name of the hash function for TYPE.
-std::string
-Gogo::hash_function_name(const Type* type)
+void
+Gogo::hash_function_name(const Type* type, Backend_name* bname)
{
- std::string tname = type->mangled_name(this);
- return tname + "..hash";
+ if (type->named_type() != NULL)
+ type->backend_name(this, bname);
+ else
+ {
+ bname->add(this->pkgpath());
+ type->backend_name(this, bname);
+ }
+ bname->set_suffix("..hash");
}
-// Return the name of the equal function for TYPE. If NAME is not
-// NULL it is the name of the type.
+// Set BNAME to the name of the equal function for TYPE. If NAME is
+// not NULL it is the name of the type.
-std::string
-Gogo::equal_function_name(const Type* type, const Named_type* name)
+void
+Gogo::equal_function_name(const Type* type, const Named_type* name,
+ Backend_name* bname)
{
- const Type* rtype = type;
if (name != NULL)
- rtype = name;
- std::string tname = rtype->mangled_name(this);
- return tname + "..eq";
+ name->backend_name(this, bname);
+ else
+ {
+ bname->add(this->pkgpath());
+ type->backend_name(this, bname);
+ }
+ bname->set_suffix("..eq");
}
-// Return the assembler name to use for a global variable. GO_NAME is
-// the name that appears in the Go code. PACKAGE is the package where
-// the variable is defined, and is NULL for the package being
-// compiled.
+// Set BNAME to the name to use for a global variable. GO_NAME is the
+// name that appears in the Go code. PACKAGE is the package where the
+// variable is defined, and is NULL for the package being compiled.
-std::string
-Gogo::global_var_asm_name(const std::string& go_name, const Package* package)
+void
+Gogo::global_var_backend_name(const std::string& go_name,
+ const Package* package,
+ Backend_name* bname)
{
- std::string ret;
if (package == NULL)
- ret = this->pkgpath();
+ bname->add(this->pkgpath());
else
- ret = package->pkgpath();
- ret.append(1, '.');
- ret.append(Gogo::unpack_hidden_name(go_name));
- return go_encode_id(ret);
+ bname->add(package->pkgpath());
+ bname->add(Gogo::unpack_hidden_name(go_name));
}
// Return an erroneous name that indicates that an error has already
-// been reported.
+// been reported. This name will act like a Go identifier.
std::string
Gogo::erroneous_name()
@@ -349,7 +383,10 @@ Gogo::is_erroneous_name(const std::string& name)
return name.compare(0, 10, ".erroneous") == 0;
}
-// Return a name for a thunk object.
+// Return a name for a thunk object. This name will act like a Go
+// identifier. The name returned here will eventually be passed to
+// function_backend_name, which will pull off the ..thunk as an
+// unencoded suffix.
std::string
Gogo::thunk_name()
@@ -358,7 +395,12 @@ Gogo::thunk_name()
char thunk_name[50];
snprintf(thunk_name, sizeof thunk_name, "..thunk%d", thunk_count);
++thunk_count;
- std::string ret = this->pkgpath();
+ // We don't want to return a name that starts with a dot, as that
+ // will confuse Gogo::is_hidden_name. And we don't want to change
+ // ..thunk, which fits our general theme and is used by code like
+ // runtime.Callers. But the prefix doesn't matter, as the actual
+ // name will include the package path.
+ std::string ret = "go";
return ret + thunk_name;
}
@@ -368,13 +410,10 @@ bool
Gogo::is_thunk(const Named_object* no)
{
const std::string& name(no->name());
- size_t i = name.find("..thunk");
+ size_t i = name.rfind("..thunk");
if (i == std::string::npos)
return false;
- for (i += 7; i < name.size(); ++i)
- if (name[i] < '0' || name[i] > '9')
- return false;
- return true;
+ return Gogo::is_digits(name.substr(i + 7));
}
// Return the name to use for an init function. There can be multiple
@@ -387,11 +426,12 @@ Gogo::init_function_name()
char buf[30];
snprintf(buf, sizeof buf, "..init%d", init_count);
++init_count;
- std::string ret = this->pkgpath();
- return ret + buf;
+ return this->pkgpath() + buf;
}
-// Return the name to use for a nested function.
+// Return the name to use for a nested function. This name acts like
+// a Go identifier. This name will be rewritten by
+// Function::backend_name.
std::string
Gogo::nested_function_name(Named_object* enclosing)
@@ -420,7 +460,9 @@ Gogo::nested_function_name(Named_object* enclosing)
enclosing->func_value()->type()->receiver();
if (rcvr != NULL)
{
- prefix = rcvr->type()->mangled_name(this);
+ Backend_name bname;
+ rcvr->type()->backend_name(this, &bname);
+ prefix = bname.name();
prefix.push_back('.');
}
prefix.append(Gogo::unpack_hidden_name(enclosing->name()));
@@ -460,7 +502,8 @@ Gogo::redefined_function_name()
}
// Return the name to use for a recover thunk for the function NAME.
-// If the function is a method, RTYPE is the receiver type.
+// If the function is a method, RTYPE is the receiver type. This is a
+// name that acts like a Go identifier.
std::string
Gogo::recover_thunk_name(const std::string& name, const Type* rtype)
@@ -468,10 +511,12 @@ Gogo::recover_thunk_name(const std::string& name, const Type* rtype)
std::string ret;
if (rtype != NULL)
{
- ret = rtype->mangled_name(this);
+ Backend_name bname;
+ rtype->backend_name(this, &bname);
+ ret = bname.name();
ret.append(1, '.');
}
- if (Gogo::is_special_name(name))
+ if (Gogo::special_name_pos(name) != std::string::npos)
ret.append(name);
else
ret.append(Gogo::unpack_hidden_name(name));
@@ -504,8 +549,8 @@ Gogo::initializer_name()
return buf;
}
-// Return the name of the variable used to represent the zero value of
-// a map. This is a globally visible common symbol.
+// Return the assembler name of the variable used to represent the
+// zero value of a map. This is a globally visible common symbol.
std::string
Gogo::map_zero_value_name()
@@ -513,7 +558,9 @@ Gogo::map_zero_value_name()
return "go..zerovalue";
}
-// Return the name to use for the import control function.
+// Return the name to use for the import control function. This name
+// is handled specially by Function::backend_name. It is not encoded
+// further.
const std::string&
Gogo::get_init_fn_name()
@@ -550,7 +597,7 @@ Gogo::dummy_init_fn_name()
// can be a real init function or a dummy one.
std::string
-Gogo::pkgpath_from_init_fn_name(std::string name)
+Gogo::pkgpath_symbol_from_init_fn_name(std::string name)
{
go_assert(!name.empty());
if (name[0] == '~')
@@ -561,60 +608,38 @@ Gogo::pkgpath_from_init_fn_name(std::string name)
go_unreachable();
}
-// Return a mangled name for a type. These names appear in symbol
-// names in the assembler file for things like type descriptors and
-// methods.
+// Set BNAME to a name for a type to use in a symbol. Return a name
+// for a type to use in a symbol. These names appear in symbol names
+// in the assembler file for things like type descriptors and methods.
-std::string
-Type::mangled_name(Gogo* gogo) const
+void
+Type::backend_name(Gogo* gogo, Backend_name* bname) const
{
- std::string ret;
-
- // The do_mangled_name virtual function will set RET to the mangled
- // name before glue character mapping.
- this->do_mangled_name(gogo, &ret);
-
- // Type descriptor names and interface method table names use a ".."
- // before the mangled name of a type, so to avoid ambiguity the
- // mangled name must not start with 'u' or 'U' or a digit.
- go_assert((ret[0] < '0' || ret[0] > '9') && ret[0] != ' ');
- if (ret[0] == 'u' || ret[0] == 'U')
- ret = " " + ret;
-
- // Map glue characters as described above.
-
- // The mapping is only unambiguous if there is no .DIGIT in the
- // string, so check that.
- for (size_t i = ret.find('.');
- i != std::string::npos;
- i = ret.find('.', i + 1))
+ // Special case top level named types to get nicer name encodings
+ // for this common case.
+ const Named_type* nt = this->unalias()->named_type();
+ if (nt != NULL && !nt->is_builtin())
{
- if (i + 1 < ret.size())
+ unsigned int index;
+ if (nt->in_function(&index) == NULL)
{
- char c = ret[i + 1];
- go_assert(c < '0' || c > '9');
+ const Named_object* no = nt->named_object();
+ if (no->package() == NULL)
+ bname->add(gogo->pkgpath());
+ else
+ bname->add(no->package()->pkgpath());
+ bname->add(Gogo::unpack_hidden_name(no->name()));
+ return;
}
}
- // The order of these characters is the replacement code.
- const char * const replace = " *;,{}[]()";
+ std::string name;
- const size_t rlen = strlen(replace);
- char buf[2];
- buf[0] = '.';
- for (size_t ri = 0; ri < rlen; ++ri)
- {
- buf[1] = '0' + ri;
- while (true)
- {
- size_t i = ret.find(replace[ri]);
- if (i == std::string::npos)
- break;
- ret.replace(i, 1, buf, 2);
- }
- }
+ // The do_symbol_name virtual function will set RET to the mangled
+ // name before encoding.
+ this->do_mangled_name(gogo, &name);
- return ret;
+ bname->add(name);
}
// The mangled name is implemented as a method on each instance of
@@ -701,12 +726,7 @@ Function_type::do_mangled_name(Gogo* gogo, std::string* ret) const
else
ret->push_back(',');
if (this->is_varargs_ && p + 1 == params->end())
- {
- // We can't use "..." here because the mangled name
- // might start with 'u' or 'U', which would be ambiguous
- // with the encoding of Unicode characters.
- ret->append(",,,");
- }
+ ret->append("...");
this->append_mangled_name(p->type(), gogo, ret);
}
}
@@ -776,15 +796,15 @@ Struct_type::do_mangled_name(Gogo* gogo, std::string* ret) const
if (p->is_anonymous()
&& p->type()->named_type() != NULL
&& p->type()->named_type()->is_alias())
- p->type()->named_type()->append_mangled_type_name(gogo, true, ret);
+ p->type()->named_type()->append_symbol_type_name(gogo, true, ret);
else
this->append_mangled_name(p->type(), gogo, ret);
if (p->has_tag())
{
// Use curly braces around a struct tag, since they are
- // unambiguous here and we have no encoding for
- // quotation marks.
+ // unambiguous here and struct tags rarely contain curly
+ // braces.
ret->push_back('{');
ret->append(go_mangle_struct_tag(p->tag()));
ret->push_back('}');
@@ -837,10 +857,10 @@ void
Channel_type::do_mangled_name(Gogo* gogo, std::string* ret) const
{
if (!this->may_send_)
- ret->append("{}");
+ ret->append("<-");
ret->append("chan");
if (!this->may_receive_)
- ret->append("{}");
+ ret->append("<-");
ret->push_back(' ');
this->append_mangled_name(this->element_type_, gogo, ret);
}
@@ -883,7 +903,7 @@ Interface_type::do_mangled_name(Gogo* gogo, std::string* ret) const
void
Named_type::do_mangled_name(Gogo* gogo, std::string* ret) const
{
- this->append_mangled_type_name(gogo, false, ret);
+ this->append_symbol_type_name(gogo, false, ret);
}
void
@@ -903,13 +923,13 @@ Forward_declaration_type::do_mangled_name(Gogo* gogo, std::string* ret) const
}
}
-// Append the mangled name for a named type to RET. For an alias we
+// Append the symbol name for a named type to RET. For an alias we
// normally use the real name, but if USE_ALIAS is true we use the
// alias name itself.
void
-Named_type::append_mangled_type_name(Gogo* gogo, bool use_alias,
- std::string* ret) const
+Named_type::append_symbol_type_name(Gogo* gogo, bool use_alias,
+ std::string* ret) const
{
if (this->is_error_)
return;
@@ -933,7 +953,11 @@ Named_type::append_mangled_type_name(Gogo* gogo, bool use_alias,
const Typed_identifier* rcvr =
this->in_function_->func_value()->type()->receiver();
if (rcvr != NULL)
- ret->append(rcvr->type()->deref()->mangled_name(gogo));
+ {
+ Backend_name bname;
+ rcvr->type()->deref()->backend_name(gogo, &bname);
+ ret->append(bname.name());
+ }
else if (this->in_function_->package() == NULL)
ret->append(gogo->pkgpath());
else
@@ -956,23 +980,46 @@ Named_type::append_mangled_type_name(Gogo* gogo, bool use_alias,
if (this->in_function_ != NULL && this->in_function_index_ > 0)
{
char buf[30];
- snprintf(buf, sizeof buf, "..i%u", this->in_function_index_);
+ snprintf(buf, sizeof buf, ".i%u", this->in_function_index_);
ret->append(buf);
}
}
-// Return the name for the type descriptor symbol for TYPE. This can
-// be a global, common, or local symbol, depending. NT is not NULL if
-// it is the name to use.
+// Given a name which may or may not have been hidden, append the
+// appropriate version of the name to the result string.
-std::string
-Gogo::type_descriptor_name(const Type* type, Named_type* nt)
+void
+Gogo::append_possibly_hidden_name(std::string *result, const std::string& name)
+{
+ if (!Gogo::is_hidden_name(name))
+ *result += name;
+ else
+ *result += name.substr(1);
+}
+
+// Set BNAME to the name for the type descriptor symbol for TYPE.
+// This can be a global, common, or local symbol, depending. NT is
+// not NULL if it is the name to use.
+
+void
+Gogo::type_descriptor_backend_name(const Type* type, Named_type* nt,
+ Backend_name* bname)
{
// The type descriptor symbol for the unsafe.Pointer type is defined
// in libgo/runtime/go-unsafe-pointer.c, so just use a reference to
// that symbol for all unsafe pointer types.
if (type->is_unsafe_pointer_type())
- return "unsafe.Pointer..d";
+ {
+ bname->set_asm_name("unsafe.Pointer..d");
+ return;
+ }
+
+ bool is_pointer = false;
+ if (nt == NULL && type->points_to() != NULL)
+ {
+ nt = type->points_to()->named_type();
+ is_pointer = true;
+ }
if (nt == NULL)
{
@@ -981,63 +1028,28 @@ Gogo::type_descriptor_name(const Type* type, Named_type* nt)
// using a named type, like "int".
go_assert(!type->is_basic_type());
- return "type.." + type->mangled_name(this);
+ type->backend_name(this, bname);
+ bname->set_prefix("type..");
}
-
- std::string ret;
- Named_object* no = nt->named_object();
- unsigned int index;
- const Named_object* in_function = nt->in_function(&index);
- if (nt->is_builtin())
- go_assert(in_function == NULL);
else
{
- if (in_function != NULL)
- {
- const Typed_identifier* rcvr =
- in_function->func_value()->type()->receiver();
- if (rcvr != NULL)
- ret.append(rcvr->type()->deref()->mangled_name(this));
- else if (in_function->package() == NULL)
- ret.append(this->pkgpath());
- else
- ret.append(in_function->package()->pkgpath());
- ret.push_back('.');
- ret.append(Gogo::unpack_hidden_name(in_function->name()));
- ret.push_back('.');
- }
-
- if (no->package() == NULL)
- ret.append(this->pkgpath());
- else
- ret.append(no->package()->pkgpath());
- ret.push_back('.');
+ nt->backend_name(this, bname);
+ bname->set_suffix(is_pointer ? "..p" : "..d");
}
-
- Gogo::append_possibly_hidden_name(&ret, no->name());
-
- if (in_function != NULL && index > 0)
- {
- char buf[30];
- snprintf(buf, sizeof buf, "..i%u", index);
- ret.append(buf);
- }
-
- ret.append("..d");
-
- return ret;
}
// Return the name of the type descriptor list symbol of a package.
+// This is passed directly to the backend without further encoding.
std::string
-Gogo::type_descriptor_list_symbol(const std::string& pkgpath)
+Gogo::type_descriptor_list_symbol(const std::string& pkgpath_symbol)
{
- return pkgpath + "..types";
+ return pkgpath_symbol + "..types";
}
// Return the name of the list of all type descriptor lists. This is
-// only used in the main package.
+// only used in the main package. This is passed directly to the
+// backend without further encoding.
std::string
Gogo::typelists_symbol()
@@ -1045,24 +1057,30 @@ Gogo::typelists_symbol()
return "go..typelists";
}
-// Return the name for the GC symbol for a type. This is used to
-// initialize the gcdata field of a type descriptor. This is a local
-// name never referenced outside of this assembly file. (Note that
-// some type descriptors will initialize the gcdata field with a name
-// generated by ptrmask_symbol_name rather than this method.)
+// Return the assembler name for the GC symbol for a type. This is
+// used to initialize the gcdata field of a type descriptor. This is
+// a local name never referenced outside of this assembly file. (Note
+// that some type descriptors will initialize the gcdata field with a
+// name generated by ptrmask_symbol_name rather than this method.)
+// This is passed directly to the backend without further encoding.
std::string
Gogo::gc_symbol_name(Type* type)
{
- return this->type_descriptor_name(type, type->named_type()) + "..g";
+ Backend_name bname;
+ this->type_descriptor_backend_name(type, type->named_type(), &bname);
+ bname.append_suffix("..g");
+ return bname.asm_name();
}
-// Return the name for a ptrmask variable. PTRMASK_SYM_NAME is a
-// base32 string encoding the ptrmask (as returned by Ptrmask::symname
-// in types.cc). This name is used to intialize the gcdata field of a
-// type descriptor. These names are globally visible. (Note that
-// some type descriptors will initialize the gcdata field with a name
-// generated by gc_symbol_name rather than this method.)
+// Return the assembler name for a ptrmask variable. PTRMASK_SYM_NAME
+// is a base32 string encoding the ptrmask (as returned by
+// Ptrmask::symname in types.cc). This name is used to intialize the
+// gcdata field of a type descriptor. These names are globally
+// visible. (Note that some type descriptors will initialize the
+// gcdata field with a name generated by gc_symbol_name rather than
+// this method.) This is passed directly to the backend without
+// further encoding.
std::string
Gogo::ptrmask_symbol_name(const std::string& ptrmask_sym_name)
@@ -1070,34 +1088,123 @@ Gogo::ptrmask_symbol_name(const std::string& ptrmask_sym_name)
return "gcbits.." + ptrmask_sym_name;
}
-// Return the name to use for an interface method table used for the
-// ordinary type TYPE converted to the interface type ITYPE.
+// Return the assembler name to use for an interface method table used
+// for the ordinary type TYPE converted to the interface type ITYPE.
// IS_POINTER is true if this is for the method set for a pointer
-// receiver.
+// receiver. This is passed directly to the backend without further
+// encoding.
std::string
Gogo::interface_method_table_name(Interface_type* itype, Type* type,
bool is_pointer)
{
+ Backend_name iname;
+ itype->backend_name(this, &iname);
+ Backend_name tname;
+ type->backend_name(this, &tname);
return ((is_pointer ? "pimt.." : "imt..")
- + itype->mangled_name(this)
+ + iname.asm_name()
+ ".."
- + type->mangled_name(this));
+ + tname.asm_name());
}
-// Return whether NAME is a special name that can not be passed to
-// unpack_hidden_name. This is needed because various special names
-// use "..SUFFIX", but unpack_hidden_name just looks for '.'.
+// If NAME is a special name with a ".." suffix, return the position
+// of that suffix. This is needed because various special names use
+// "..SUFFIX", but unpack_hidden_name just looks for '.', and because
+// we don't want to encode the suffix.
+
+size_t
+Gogo::special_name_pos(const std::string& name)
+{
+ size_t pos = name.rfind("..");
+ if (pos == std::string::npos)
+ return pos;
+ std::string suffix(name.substr(pos));
+ if (suffix == "..hash"
+ || suffix == "..eq"
+ || suffix == "..stub"
+ || suffix == "..d"
+ || suffix == "..f"
+ || suffix == "..r"
+ || suffix == "..import")
+ return pos;
+ if ((suffix.compare(2, 4, "func") == 0
+ || suffix.compare(2, 4, "init") == 0)
+ && Gogo::is_digits(suffix.substr(6)))
+ return pos;
+ if (suffix.compare(2, 5, "thunk") == 0
+ && Gogo::is_digits(suffix.substr(7)))
+ return pos;
+ return std::string::npos;
+}
+
+// Return whether the string is non-empty and contains only digits.
bool
-Gogo::is_special_name(const std::string& name)
+Gogo::is_digits(const std::string& s)
+{
+ if (s.empty())
+ return false;
+ for (size_t i = 0; i < s.size(); ++i)
+ if (s[i] < '0' || s[i] > '9')
+ return false;
+ return true;
+}
+
+// Class Backend_name.
+
+// Get the user visible name.
+
+std::string
+Backend_name::name() const
+{
+ if (this->is_asm_name_)
+ return this->components_[0];
+ std::string ret;
+ if (this->prefix_ != NULL)
+ ret.append(this->prefix_);
+ for (int i = 0; i < this->count_; i++)
+ {
+ if (i > 0)
+ ret.push_back('.');
+ ret.append(this->components_[i]);
+ }
+ if (!this->suffix_.empty())
+ ret.append(this->suffix_);
+ return ret;
+}
+
+// Get the assembler name.
+
+std::string
+Backend_name::asm_name() const
+{
+ if (this->is_asm_name_)
+ return this->components_[0];
+ std::string ret;
+ if (this->prefix_ != NULL)
+ ret.append(this->prefix_);
+ for (int i = 0; i < this->count_; i++)
+ {
+ if (i > 0)
+ ret.push_back('.');
+ ret.append(go_encode_id(this->components_[i]));
+ }
+ if (!this->suffix_.empty())
+ ret.append(this->suffix_);
+ return ret;
+}
+
+// Get the assembler name, or the empty string if it is the same as
+// the user visible name.
+
+std::string
+Backend_name::optional_asm_name() const
{
- return (name.find("..hash") != std::string::npos
- || name.find("..eq") != std::string::npos
- || name.find("..stub") != std::string::npos
- || name.find("..func") != std::string::npos
- || name.find("..r") != std::string::npos
- || name.find("..init") != std::string::npos
- || name.find("..thunk") != std::string::npos
- || name.find("..import") != std::string::npos);
+ if (this->is_asm_name_)
+ return "";
+ for (int i = 0; i < this->count_; i++)
+ if (go_id_needs_encoding(this->components_[i]))
+ return this->asm_name();
+ return "";
}
diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc
index ef59415..b1925ed 100644
--- a/gcc/go/gofrontend/parse.cc
+++ b/gcc/go/gofrontend/parse.cc
@@ -995,7 +995,7 @@ Parse::parameter_list(bool* is_varargs)
}
if (mix_error)
{
- go_error_at(location, "invalid named/anonymous mix");
+ go_error_at(location, "mixed named and unnamed function parameters");
saw_error = true;
}
if (saw_error)
@@ -1567,7 +1567,6 @@ Parse::type_spec(void*, unsigned int pragmas)
go_error_at(this->location(),
"unexpected semicolon or newline in type declaration");
type = Type::make_error_type();
- this->advance_token();
}
if (type->is_error_type())
@@ -2165,8 +2164,12 @@ Parse::simple_var_decl_or_assignment(const std::string& name,
id = this->gogo_->pack_hidden_name(id, is_id_exported);
ins = uniq_idents.insert(id);
if (!ins.second && !Gogo::is_sink_name(id))
- go_error_at(id_location, "multiple assignments to %s",
- Gogo::message_name(id).c_str());
+ {
+ // Use %s to print := to avoid -Wformat-diag warning.
+ go_error_at(id_location,
+ "%qs repeated on left side of %s",
+ Gogo::message_name(id).c_str(), ":=");
+ }
til.push_back(Typed_identifier(id, NULL, location));
}
else
@@ -2219,7 +2222,11 @@ Parse::simple_var_decl_or_assignment(const std::string& name,
const Token* token = this->advance_token();
if (!dup_name.empty())
- go_error_at(dup_loc, "multiple assignments to %s", dup_name.c_str());
+ {
+ // Use %s to print := to avoid -Wformat-diag warning.
+ go_error_at(dup_loc, "%qs repeated on left side of %s",
+ dup_name.c_str(), ":=");
+ }
if (p_range_clause != NULL && token->is_keyword(KEYWORD_RANGE))
{
@@ -4414,7 +4421,7 @@ Parse::if_stat()
{
Location semi_loc = this->location();
if (this->advance_token()->is_op(OPERATOR_LCURLY))
- go_error_at(semi_loc, "missing %<{%> after if clause");
+ go_error_at(semi_loc, "unexpected semicolon or newline, expecting %<{%> after if clause");
// Otherwise we will get an error when we call this->block
// below.
}
@@ -4810,7 +4817,7 @@ Parse::type_switch_body(Label* label, const Type_switch& type_switch,
}
}
if (!used)
- go_error_at(type_switch.location, "%qs declared and not used",
+ go_error_at(type_switch.location, "%qs declared but not used",
Gogo::message_name(var_name).c_str());
}
return statement;
@@ -5351,7 +5358,7 @@ Parse::for_stat(Label* label)
{
Location semi_loc = this->location();
if (this->advance_token()->is_op(OPERATOR_LCURLY))
- go_error_at(semi_loc, "missing %<{%> after for clause");
+ go_error_at(semi_loc, "unexpected semicolon or newline, expecting %<{%> after for clause");
// Otherwise we will get an error when we call this->block
// below.
}
@@ -5422,7 +5429,7 @@ Parse::for_clause(Expression** cond, Block** post)
*cond = NULL;
else if (this->peek_token()->is_op(OPERATOR_LCURLY))
{
- go_error_at(this->location(), "missing %<{%> after for clause");
+ go_error_at(this->location(), "unexpected semicolon or newline, expecting %<{%> after for clause");
*cond = NULL;
*post = NULL;
return;
@@ -5780,7 +5787,7 @@ Parse::import_spec(void*, unsigned int pragmas)
if (!token->is_string())
{
- go_error_at(this->location(), "import statement not a string");
+ go_error_at(this->location(), "import path must be a string");
this->advance_token();
return;
}
diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def
index 0796cba..4b606a6 100644
--- a/gcc/go/gofrontend/runtime.def
+++ b/gcc/go/gofrontend/runtime.def
@@ -62,12 +62,6 @@ DEF_GO_RUNTIME(STRINGTOSLICERUNE, "runtime.stringtoslicerune",
P2(POINTER, STRING), R1(SLICE))
-// Complex division.
-DEF_GO_RUNTIME(COMPLEX64_DIV, "__go_complex64_div",
- P2(COMPLEX64, COMPLEX64), R1(COMPLEX64))
-DEF_GO_RUNTIME(COMPLEX128_DIV, "__go_complex128_div",
- P2(COMPLEX128, COMPLEX128), R1(COMPLEX128))
-
// Make a slice.
DEF_GO_RUNTIME(MAKESLICE, "runtime.makeslice", P3(TYPE, INT, INT),
R1(POINTER))
@@ -83,7 +77,7 @@ DEF_GO_RUNTIME(MAKEMAP64, "runtime.makemap64", P3(TYPE, INT64, POINTER),
R1(MAP))
// Make a map with no hint, or a small constant hint.
-DEF_GO_RUNTIME(MAKEMAP_SMALL, "runtime.makemap_small", P0(), R1(MAP))
+DEF_GO_RUNTIME(MAKEMAP_SMALL, "runtime.makemap__small", P0(), R1(MAP))
// Build a map from a composite literal.
DEF_GO_RUNTIME(CONSTRUCT_MAP, "__go_construct_map",
@@ -95,19 +89,19 @@ DEF_GO_RUNTIME(MAPACCESS1, "runtime.mapaccess1", P3(TYPE, MAP, POINTER),
R1(POINTER))
// Look up a uint32 key in a map.
-DEF_GO_RUNTIME(MAPACCESS1_FAST32, "runtime.mapaccess1_fast32",
+DEF_GO_RUNTIME(MAPACCESS1_FAST32, "runtime.mapaccess1__fast32",
P3(TYPE, MAP, UINT32), R1(POINTER))
// Look up a uint64 key in a map.
-DEF_GO_RUNTIME(MAPACCESS1_FAST64, "runtime.mapaccess1_fast64",
+DEF_GO_RUNTIME(MAPACCESS1_FAST64, "runtime.mapaccess1__fast64",
P3(TYPE, MAP, UINT64), R1(POINTER))
// Look up a string key in a map.
-DEF_GO_RUNTIME(MAPACCESS1_FASTSTR, "runtime.mapaccess1_faststr",
+DEF_GO_RUNTIME(MAPACCESS1_FASTSTR, "runtime.mapaccess1__faststr",
P3(TYPE, MAP, STRING), R1(POINTER))
// Look up a key in a map when the value is large.
-DEF_GO_RUNTIME(MAPACCESS1_FAT, "runtime.mapaccess1_fat",
+DEF_GO_RUNTIME(MAPACCESS1_FAT, "runtime.mapaccess1__fat",
P4(TYPE, MAP, POINTER, POINTER), R1(POINTER))
// Look up a key in a map returning the value and whether it is
@@ -117,22 +111,22 @@ DEF_GO_RUNTIME(MAPACCESS2, "runtime.mapaccess2", P3(TYPE, MAP, POINTER),
// Look up a uint32 key in a map returning the value and whether
// it is present.
-DEF_GO_RUNTIME(MAPACCESS2_FAST32, "runtime.mapaccess2_fast32",
+DEF_GO_RUNTIME(MAPACCESS2_FAST32, "runtime.mapaccess2__fast32",
P3(TYPE, MAP, UINT32), R2(POINTER, BOOL))
// Look up a uint64 key in a map returning the value and whether
// it is present.
-DEF_GO_RUNTIME(MAPACCESS2_FAST64, "runtime.mapaccess2_fast64",
+DEF_GO_RUNTIME(MAPACCESS2_FAST64, "runtime.mapaccess2__fast64",
P3(TYPE, MAP, UINT64), R2(POINTER, BOOL))
// Look up a string key in a map returning the value and whether
// it is present.
-DEF_GO_RUNTIME(MAPACCESS2_FASTSTR, "runtime.mapaccess2_faststr",
+DEF_GO_RUNTIME(MAPACCESS2_FASTSTR, "runtime.mapaccess2__faststr",
P3(TYPE, MAP, STRING), R2(POINTER, BOOL))
// Look up a key in a map, returning the value and whether it is
// present, when the value is large.
-DEF_GO_RUNTIME(MAPACCESS2_FAT, "runtime.mapaccess2_fat",
+DEF_GO_RUNTIME(MAPACCESS2_FAT, "runtime.mapaccess2__fat",
P4(TYPE, MAP, POINTER, POINTER), R2(POINTER, BOOL))
// Assignment to a key in a map.
@@ -140,38 +134,38 @@ DEF_GO_RUNTIME(MAPASSIGN, "runtime.mapassign", P3(TYPE, MAP, POINTER),
R1(POINTER))
// Assignment to a uint32 key in a map.
-DEF_GO_RUNTIME(MAPASSIGN_FAST32, "runtime.mapassign_fast32",
+DEF_GO_RUNTIME(MAPASSIGN_FAST32, "runtime.mapassign__fast32",
P3(TYPE, MAP, UINT32), R1(POINTER))
// Assignment to a uint64 key in a map.
-DEF_GO_RUNTIME(MAPASSIGN_FAST64, "runtime.mapassign_fast64",
+DEF_GO_RUNTIME(MAPASSIGN_FAST64, "runtime.mapassign__fast64",
P3(TYPE, MAP, UINT64), R1(POINTER))
// Assignment to a 32-bit pointer key in a map.
-DEF_GO_RUNTIME(MAPASSIGN_FAST32PTR, "runtime.mapassign_fast32ptr",
+DEF_GO_RUNTIME(MAPASSIGN_FAST32PTR, "runtime.mapassign__fast32ptr",
P3(TYPE, MAP, POINTER), R1(POINTER))
// Assignment to a 64-bit pointer key in a map.
-DEF_GO_RUNTIME(MAPASSIGN_FAST64PTR, "runtime.mapassign_fast64ptr",
+DEF_GO_RUNTIME(MAPASSIGN_FAST64PTR, "runtime.mapassign__fast64ptr",
P3(TYPE, MAP, POINTER), R1(POINTER))
// Assignment to a string key in a map.
-DEF_GO_RUNTIME(MAPASSIGN_FASTSTR, "runtime.mapassign_faststr",
+DEF_GO_RUNTIME(MAPASSIGN_FASTSTR, "runtime.mapassign__faststr",
P3(TYPE, MAP, STRING), R1(POINTER))
// Delete a key from a map.
DEF_GO_RUNTIME(MAPDELETE, "runtime.mapdelete", P3(TYPE, MAP, POINTER), R0())
// Delete a uint32 key from a map.
-DEF_GO_RUNTIME(MAPDELETE_FAST32, "runtime.mapdelete_fast32",
+DEF_GO_RUNTIME(MAPDELETE_FAST32, "runtime.mapdelete__fast32",
P3(TYPE, MAP, UINT32), R0())
// Delete a uint64 key from a map.
-DEF_GO_RUNTIME(MAPDELETE_FAST64, "runtime.mapdelete_fast64",
+DEF_GO_RUNTIME(MAPDELETE_FAST64, "runtime.mapdelete__fast64",
P3(TYPE, MAP, UINT64), R0())
// Delete a string key from a map.
-DEF_GO_RUNTIME(MAPDELETE_FASTSTR, "runtime.mapdelete_faststr",
+DEF_GO_RUNTIME(MAPDELETE_FASTSTR, "runtime.mapdelete__faststr",
P3(TYPE, MAP, STRING), R0())
// Begin a range over a map.
@@ -265,6 +259,11 @@ DEF_GO_RUNTIME(GROWSLICE, "runtime.growslice",
P5(TYPE, POINTER, INT, INT, INT), R1(SLICE))
+// Check the length and cap passed to make, without making a slice.
+// This is used for apend(s, make([]T, len)...).
+DEF_GO_RUNTIME(CHECK_MAKE_SLICE, "runtime.checkMakeSlice", P3(TYPE, INT, INT),
+ R1(UINTPTR))
+
// Register roots (global variables) for the garbage collector.
DEF_GO_RUNTIME(REGISTER_GC_ROOTS, "runtime.registerGCRoots", P1(POINTER), R0())
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index ad89807..25e2536 100644
--- a/gcc/go/gofrontend/statements.cc
+++ b/gcc/go/gofrontend/statements.cc
@@ -1985,18 +1985,42 @@ Tuple_type_guard_assignment_statement::lower_to_object_type(
NULL, loc);
b->add_statement(val_temp);
- // ok = CODE(type_descriptor, expr, &val_temp)
+ // var ok_temp bool
+ Temporary_statement* ok_temp = NULL;
+ if (!this->ok_->is_sink_expression())
+ {
+ ok_temp = Statement::make_temporary(this->ok_->type(),
+ NULL, loc);
+ b->add_statement(ok_temp);
+ }
+
+ // ok_temp = CODE(type_descriptor, expr, &val_temp)
Expression* p1 = Expression::make_type_descriptor(this->type_, loc);
Expression* ref = Expression::make_temporary_reference(val_temp, loc);
Expression* p3 = Expression::make_unary(OPERATOR_AND, ref, loc);
Expression* call = Runtime::make_call(code, loc, 3, p1, this->expr_, p3);
- Statement* s = Statement::make_assignment(this->ok_, call, loc);
+ Statement* s;
+ if (ok_temp == NULL)
+ s = Statement::make_statement(call, true);
+ else
+ {
+ Expression* ok_ref = Expression::make_temporary_reference(ok_temp, loc);
+ s = Statement::make_assignment(ok_ref, call, loc);
+ }
b->add_statement(s);
// val = val_temp
ref = Expression::make_temporary_reference(val_temp, loc);
s = Statement::make_assignment(this->val_, ref, loc);
b->add_statement(s);
+
+ // ok = ok_temp
+ if (ok_temp != NULL)
+ {
+ ref = Expression::make_temporary_reference(ok_temp, loc);
+ s = Statement::make_assignment(this->ok_, ref, loc);
+ b->add_statement(s);
+ }
}
// Dump the AST representation for a tuple type guard statement.
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index f3bcf2e..23d1647 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -261,6 +261,15 @@ Type::is_error_type() const
}
}
+// Note that this type is an error. This is called by children when
+// they discover an error during the verify_types pass.
+
+void
+Type::set_is_error()
+{
+ this->classification_ = TYPE_ERROR;
+}
+
// If this is a pointer type, return the type to which it points.
// Otherwise, return NULL.
@@ -1342,19 +1351,21 @@ Type::make_type_descriptor_var(Gogo* gogo)
Type* td_type = Type::make_type_descriptor_type();
Btype* td_btype = td_type->get_backend(gogo);
- std::string name = gogo->type_descriptor_name(this, nt);
- std::string asm_name(go_selectively_encode_id(name));
+ Backend_name bname;
+ gogo->type_descriptor_backend_name(this, nt, &bname);
this->type_descriptor_var_ =
- gogo->backend()->immutable_struct_reference(name, asm_name,
- td_btype,
- bloc);
+ gogo->backend()->immutable_struct_reference(bname.name(),
+ bname.optional_asm_name(),
+ td_btype,
+ bloc);
if (phash != NULL)
*phash = this->type_descriptor_var_;
return;
}
- std::string var_name = gogo->type_descriptor_name(this, nt);
+ Backend_name bname;
+ gogo->type_descriptor_backend_name(this, nt, &bname);
// Build the contents of the type descriptor.
Expression* initializer = this->do_type_descriptor(gogo, NULL);
@@ -1366,11 +1377,11 @@ Type::make_type_descriptor_var(Gogo* gogo)
const Package* dummy;
if (this->type_descriptor_defined_elsewhere(nt, &dummy))
{
- std::string asm_name(go_selectively_encode_id(var_name));
this->type_descriptor_var_ =
- gogo->backend()->immutable_struct_reference(var_name, asm_name,
- initializer_btype,
- loc);
+ gogo->backend()->immutable_struct_reference(bname.name(),
+ bname.optional_asm_name(),
+ initializer_btype,
+ loc);
if (phash != NULL)
*phash = this->type_descriptor_var_;
return;
@@ -1399,10 +1410,10 @@ Type::make_type_descriptor_var(Gogo* gogo)
// ensure that type_descriptor_pointer will work if called while
// converting INITIALIZER.
- std::string asm_name(go_selectively_encode_id(var_name));
this->type_descriptor_var_ =
- gogo->backend()->immutable_struct(var_name, asm_name, false, is_common,
- initializer_btype, loc);
+ gogo->backend()->immutable_struct(bname.name(), bname.optional_asm_name(),
+ false, is_common, initializer_btype,
+ loc);
if (phash != NULL)
*phash = this->type_descriptor_var_;
@@ -1411,7 +1422,7 @@ Type::make_type_descriptor_var(Gogo* gogo)
Bexpression* binitializer = initializer->get_backend(&context);
gogo->backend()->immutable_struct_set_init(this->type_descriptor_var_,
- var_name, false, is_common,
+ bname.name(), false, is_common,
initializer_btype, loc,
binitializer);
@@ -1924,19 +1935,20 @@ Type::build_hash_function(Gogo* gogo, int64_t size, Function_type* hash_fntype)
return ins.first->second;
}
- std::string hash_name = gogo->hash_function_name(type);
+ Backend_name bname;
+ gogo->hash_function_name(type, &bname);
Location bloc = Linemap::predeclared_location();
- Named_object* hash_fn = gogo->declare_package_function(hash_name,
+ Named_object* hash_fn = gogo->declare_package_function(bname.name(),
hash_fntype, bloc);
ins.first->second = hash_fn;
if (gogo->in_global_scope())
- type->write_hash_function(gogo, size, hash_name, hash_fntype);
+ type->write_hash_function(gogo, size, &bname, hash_fntype);
else
- gogo->queue_hash_function(type, size, hash_name, hash_fntype);
+ gogo->queue_hash_function(type, size, &bname, hash_fntype);
return hash_fn;
}
@@ -1944,8 +1956,7 @@ Type::build_hash_function(Gogo* gogo, int64_t size, Function_type* hash_fntype)
// Write the hash function for a type that needs it written specially.
void
-Type::write_hash_function(Gogo* gogo, int64_t size,
- const std::string& hash_name,
+Type::write_hash_function(Gogo* gogo, int64_t size, const Backend_name* bname,
Function_type* hash_fntype)
{
Location bloc = Linemap::predeclared_location();
@@ -1958,8 +1969,9 @@ Type::write_hash_function(Gogo* gogo, int64_t size,
go_assert(this->is_comparable());
- Named_object* hash_fn = gogo->start_function(hash_name, hash_fntype, false,
- bloc);
+ Named_object* hash_fn = gogo->start_function(bname->name(), hash_fntype,
+ false, bloc);
+ hash_fn->func_value()->set_asm_name(bname->asm_name());
hash_fn->func_value()->set_is_type_specific_function();
gogo->start_block(bloc);
@@ -2245,7 +2257,8 @@ Type::build_equal_function(Gogo* gogo, Named_type* name, int64_t size,
return ins.first->second;
}
- std::string equal_name = gogo->equal_function_name(this, name);
+ Backend_name bname;
+ gogo->equal_function_name(this, name, &bname);
Location bloc = Linemap::predeclared_location();
@@ -2255,19 +2268,21 @@ Type::build_equal_function(Gogo* gogo, Named_type* name, int64_t size,
Named_object* equal_fn;
if (is_defined_elsewhere)
- equal_fn = Named_object::make_function_declaration(equal_name, package,
+ equal_fn = Named_object::make_function_declaration(bname.name(), package,
equal_fntype, bloc);
else
- equal_fn = gogo->declare_package_function(equal_name, equal_fntype, bloc);
+ equal_fn = gogo->declare_package_function(bname.name(), equal_fntype, bloc);
ins.first->second = equal_fn;
- if (!is_defined_elsewhere)
+ if (is_defined_elsewhere)
+ equal_fn->func_declaration_value()->set_asm_name(bname.asm_name());
+ else
{
if (gogo->in_global_scope())
- this->write_equal_function(gogo, name, size, equal_name, equal_fntype);
+ this->write_equal_function(gogo, name, size, &bname, equal_fntype);
else
- gogo->queue_equal_function(this, name, size, equal_name, equal_fntype);
+ gogo->queue_equal_function(this, name, size, &bname, equal_fntype);
}
return equal_fn;
@@ -2278,7 +2293,7 @@ Type::build_equal_function(Gogo* gogo, Named_type* name, int64_t size,
void
Type::write_equal_function(Gogo* gogo, Named_type* name, int64_t size,
- const std::string& equal_name,
+ const Backend_name* bname,
Function_type* equal_fntype)
{
Location bloc = Linemap::predeclared_location();
@@ -2291,8 +2306,9 @@ Type::write_equal_function(Gogo* gogo, Named_type* name, int64_t size,
go_assert(this->is_comparable());
- Named_object* equal_fn = gogo->start_function(equal_name, equal_fntype,
+ Named_object* equal_fn = gogo->start_function(bname->name(), equal_fntype,
false, bloc);
+ equal_fn->func_value()->set_asm_name(bname->asm_name());
equal_fn->func_value()->set_is_type_specific_function();
gogo->start_block(bloc);
@@ -2671,9 +2687,8 @@ Type::make_gc_symbol_var(Gogo* gogo)
const Package* dummy;
if (this->type_descriptor_defined_elsewhere(nt, &dummy))
{
- std::string asm_name(go_selectively_encode_id(sym_name));
this->gc_symbol_var_ =
- gogo->backend()->implicit_variable_reference(sym_name, asm_name,
+ gogo->backend()->implicit_variable_reference(sym_name, "",
sym_btype);
if (phash != NULL)
*phash = this->gc_symbol_var_;
@@ -2699,10 +2714,9 @@ Type::make_gc_symbol_var(Gogo* gogo)
// Since we are building the GC symbol in this package, we must create the
// variable before converting the initializer to its backend representation
// because the initializer may refer to the GC symbol for this type.
- std::string asm_name(go_selectively_encode_id(sym_name));
this->gc_symbol_var_ =
- gogo->backend()->implicit_variable(sym_name, asm_name,
- sym_btype, false, true, is_common, 0);
+ gogo->backend()->implicit_variable(sym_name, "", sym_btype, false, true,
+ is_common, 0);
if (phash != NULL)
*phash = this->gc_symbol_var_;
@@ -2876,14 +2890,17 @@ Ptrmask::set_from(Gogo* gogo, Type* type, int64_t ptrsize, int64_t offset)
}
}
-// Return a symbol name for this ptrmask. This is used to coalesce identical
-// ptrmasks, which are common. The symbol name must use only characters that are
-// valid in symbols. It's nice if it's short. For smaller ptrmasks, we convert
-// it to a string that uses only 32 characters, avoiding digits and u and U. For
-// longer pointer masks, apply the same process to the SHA1 digest of the bits,
-// so as to avoid pathologically long symbol names (see related Go issues #32083
-// and #11583 for more on this). To avoid collisions between the two encoding
-// schemes, use a prefix ("X") for the SHA form to disambiguate.
+// Return a symbol name for this ptrmask. This is used to coalesce
+// identical ptrmasks, which are common. The symbol name must use
+// only characters that are valid in symbols. It's nice if it's
+// short. For smaller ptrmasks, we convert it to a string that uses
+// only 32 characters. For longer pointer masks, apply the same
+// process to the SHA1 digest of the bits, so as to avoid
+// pathologically long symbol names (see related Go issues #32083 and
+// #11583 for more on this). To avoid collisions between the two
+// encoding schemes, use a prefix ("X") for the SHA form to
+// disambiguate.
+
std::string
Ptrmask::symname() const
{
@@ -2911,7 +2928,7 @@ Ptrmask::symname() const
bits = &shabits;
}
- const char chars[33] = "abcdefghijklmnopqrstvwxyzABCDEFG";
+ const char chars[33] = "abcdefghijklmnopqrstuvwxyzABCDEF";
go_assert(chars[32] == '\0');
std::string ret(prefix);
unsigned int b = 0;
@@ -2995,9 +3012,8 @@ Type::gc_ptrmask_var(Gogo* gogo, int64_t ptrsize, int64_t ptrdata)
context.set_is_const();
Bexpression* bval = val->get_backend(&context);
- std::string asm_name(go_selectively_encode_id(sym_name));
Btype *btype = val->type()->get_backend(gogo);
- Bvariable* ret = gogo->backend()->implicit_variable(sym_name, asm_name,
+ Bvariable* ret = gogo->backend()->implicit_variable(sym_name, "",
btype, false, true,
true, 0);
gogo->backend()->implicit_variable_set_init(ret, sym_name, btype, false,
@@ -5864,6 +5880,7 @@ Struct_type::do_verify()
{
go_error_at(p->location(), "embedded type may not be a pointer");
p->set_type(Type::make_error_type());
+ this->set_is_error();
}
else if (t->points_to() != NULL
&& t->points_to()->interface_type() != NULL)
@@ -5871,6 +5888,7 @@ Struct_type::do_verify()
go_error_at(p->location(),
"embedded type may not be pointer to interface");
p->set_type(Type::make_error_type());
+ this->set_is_error();
}
}
}
@@ -7229,6 +7247,13 @@ Array_type::verify_length()
Type_context context(Type::lookup_integer_type("int"), false);
this->length_->determine_type(&context);
+ if (this->length_->is_error_expression()
+ || this->length_->type()->is_error())
+ {
+ go_assert(saw_errors());
+ return false;
+ }
+
if (!this->length_->is_constant())
{
go_error_at(this->length_->location(), "array bound is not constant");
@@ -7303,7 +7328,10 @@ Array_type::do_verify()
if (this->element_type()->is_error_type())
return false;
if (!this->verify_length())
- this->length_ = Expression::make_error(this->length_->location());
+ {
+ this->length_ = Expression::make_error(this->length_->location());
+ this->set_is_error();
+ }
return true;
}
@@ -8092,11 +8120,9 @@ Map_type::backend_zero_value(Gogo* gogo)
Btype* barray_type = gogo->backend()->array_type(buint8_type, blength);
std::string zname = Map_type::zero_value->name();
- std::string asm_name(go_selectively_encode_id(zname));
Bvariable* zvar =
- gogo->backend()->implicit_variable(zname, asm_name,
- barray_type, false, false, true,
- Map_type::zero_value_align);
+ gogo->backend()->implicit_variable(zname, "", barray_type, false, false,
+ true, Map_type::zero_value_align);
gogo->backend()->implicit_variable_set_init(zvar, zname, barray_type,
false, false, true, NULL);
return zvar;
@@ -8120,11 +8146,20 @@ Map_type::do_verify()
{
// The runtime support uses "map[void]void".
if (!this->key_type_->is_comparable() && !this->key_type_->is_void_type())
- go_error_at(this->location_, "invalid map key type");
+ {
+ go_error_at(this->location_, "invalid map key type");
+ this->set_is_error();
+ }
if (!this->key_type_->in_heap())
- go_error_at(this->location_, "go:notinheap map key not allowed");
+ {
+ go_error_at(this->location_, "go:notinheap map key not allowed");
+ this->set_is_error();
+ }
if (!this->val_type_->in_heap())
- go_error_at(this->location_, "go:notinheap map value not allowed");
+ {
+ go_error_at(this->location_, "go:notinheap map value not allowed");
+ this->set_is_error();
+ }
return true;
}
@@ -8655,8 +8690,11 @@ Channel_type::do_verify()
// We have no location for this error, but this is not something the
// ordinary user will see.
if (!this->element_type_->in_heap())
- go_error_at(Linemap::unknown_location(),
- "chan of go:notinheap type not allowed");
+ {
+ go_error_at(Linemap::unknown_location(),
+ "chan of go:notinheap type not allowed");
+ this->set_is_error();
+ }
return true;
}
@@ -12014,6 +12052,15 @@ Type::bind_field_or_method(Gogo* gogo, const Type* type, Expression* expr,
ambig2.c_str());
else if (found_pointer_method)
go_error_at(location, "method requires a pointer receiver");
+ else if (it != NULL && it->is_empty())
+ go_error_at(location,
+ "reference to method %qs in interface with no methods",
+ Gogo::message_name(name).c_str());
+ else if (it == NULL && type->deref()->interface_type() != NULL)
+ go_error_at(location,
+ ("reference to method %qs in type that is "
+ "pointer to interface, not interface"),
+ Gogo::message_name(name).c_str());
else if (nt == NULL && st == NULL && it == NULL)
go_error_at(location,
("reference to field %qs in object which "
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index 9ac8516..d097029 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -49,6 +49,7 @@ class Function;
class Translate_context;
class Export;
class Import;
+class Backend_name;
class Btype;
class Bexpression;
class Bvariable;
@@ -1008,11 +1009,11 @@ class Type
std::string
reflection(Gogo*) const;
- // Return a mangled name for the type. This is a name which can be
- // used in assembler code. Identical types should have the same
- // manged name.
- std::string
- mangled_name(Gogo*) const;
+ // Add the backend name for the type to BNAME. This will add one or
+ // two name components. Identical types should have the same
+ // backend name.
+ void
+ backend_name(Gogo*, Backend_name* bname) const;
// If the size of the type can be determined, set *PSIZE to the size
// in bytes and return true. Otherwise, return false. This queries
@@ -1066,12 +1067,11 @@ class Type
// Write the equal function for a type.
void
write_equal_function(Gogo*, Named_type*, int64_t size,
- const std::string& equal_name,
- Function_type* equal_fntype);
+ const Backend_name*, Function_type* equal_fntype);
// Write the hash function for a type.
void
- write_hash_function(Gogo*, int64_t size, const std::string& hash_name,
+ write_hash_function(Gogo*, int64_t size, const Backend_name*,
Function_type* hash_fntype);
// Return the alignment required by the memequalN function.
@@ -1141,6 +1141,10 @@ class Type
virtual void
do_export(Export*) const;
+ // For children to call when they detect that they are in error.
+ void
+ set_is_error();
+
// Return whether a method expects a pointer as the receiver.
static bool
method_expects_pointer(const Named_object*);
@@ -3557,10 +3561,10 @@ class Named_type : public Type
void
append_reflection_type_name(Gogo*, bool use_alias, std::string*) const;
- // Append the mangled type name as for Type::append_mangled_name,
+ // Append the symbol type name as for Type::append_mangled_name,
// but if USE_ALIAS use the alias name rather than the alias target.
void
- append_mangled_type_name(Gogo*, bool use_alias, std::string*) const;
+ append_symbol_type_name(Gogo*, bool use_alias, std::string*) const;
// Import a named type.
static void
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 792d2ca..41223ff 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -469,6 +469,111 @@ expand_UBSAN_OBJECT_SIZE (internal_fn, gcall *)
/* This should get expanded in the sanopt pass. */
static void
+expand_HWASAN_CHECK (internal_fn, gcall *)
+{
+ gcc_unreachable ();
+}
+
+/* For hwasan stack tagging:
+ Clear tags on the dynamically allocated space.
+ For use after an object dynamically allocated on the stack goes out of
+ scope. */
+static void
+expand_HWASAN_ALLOCA_UNPOISON (internal_fn, gcall *gc)
+{
+ gcc_assert (Pmode == ptr_mode);
+ tree restored_position = gimple_call_arg (gc, 0);
+ rtx restored_rtx = expand_expr (restored_position, NULL_RTX, VOIDmode,
+ EXPAND_NORMAL);
+ rtx func = init_one_libfunc ("__hwasan_tag_memory");
+ rtx off = expand_simple_binop (Pmode, MINUS, restored_rtx,
+ stack_pointer_rtx, NULL_RTX, 0,
+ OPTAB_WIDEN);
+ emit_library_call_value (func, NULL_RTX, LCT_NORMAL, VOIDmode,
+ virtual_stack_dynamic_rtx, Pmode,
+ HWASAN_STACK_BACKGROUND, QImode,
+ off, Pmode);
+}
+
+/* For hwasan stack tagging:
+ Return a tag to be used for a dynamic allocation. */
+static void
+expand_HWASAN_CHOOSE_TAG (internal_fn, gcall *gc)
+{
+ tree tag = gimple_call_lhs (gc);
+ rtx target = expand_expr (tag, NULL_RTX, VOIDmode, EXPAND_NORMAL);
+ machine_mode mode = GET_MODE (target);
+ gcc_assert (mode == QImode);
+
+ rtx base_tag = targetm.memtag.extract_tag (hwasan_frame_base (), NULL_RTX);
+ gcc_assert (base_tag);
+ rtx tag_offset = gen_int_mode (hwasan_current_frame_tag (), QImode);
+ rtx chosen_tag = expand_simple_binop (QImode, PLUS, base_tag, tag_offset,
+ target, /* unsignedp = */1,
+ OPTAB_WIDEN);
+ chosen_tag = hwasan_truncate_to_tag_size (chosen_tag, target);
+
+ /* Really need to put the tag into the `target` RTX. */
+ if (chosen_tag != target)
+ {
+ rtx temp = chosen_tag;
+ gcc_assert (GET_MODE (chosen_tag) == mode);
+ emit_move_insn (target, temp);
+ }
+
+ hwasan_increment_frame_tag ();
+}
+
+/* For hwasan stack tagging:
+ Tag a region of space in the shadow stack according to the base pointer of
+ an object on the stack. N.b. the length provided in the internal call is
+ required to be aligned to HWASAN_TAG_GRANULE_SIZE. */
+static void
+expand_HWASAN_MARK (internal_fn, gcall *gc)
+{
+ gcc_assert (ptr_mode == Pmode);
+ HOST_WIDE_INT flag = tree_to_shwi (gimple_call_arg (gc, 0));
+ bool is_poison = ((asan_mark_flags)flag) == ASAN_MARK_POISON;
+
+ tree base = gimple_call_arg (gc, 1);
+ gcc_checking_assert (TREE_CODE (base) == ADDR_EXPR);
+ rtx base_rtx = expand_normal (base);
+
+ rtx tag = is_poison ? HWASAN_STACK_BACKGROUND
+ : targetm.memtag.extract_tag (base_rtx, NULL_RTX);
+ rtx address = targetm.memtag.untagged_pointer (base_rtx, NULL_RTX);
+
+ tree len = gimple_call_arg (gc, 2);
+ rtx r_len = expand_normal (len);
+
+ rtx func = init_one_libfunc ("__hwasan_tag_memory");
+ emit_library_call (func, LCT_NORMAL, VOIDmode, address, Pmode,
+ tag, QImode, r_len, Pmode);
+}
+
+/* For hwasan stack tagging:
+ Store a tag into a pointer. */
+static void
+expand_HWASAN_SET_TAG (internal_fn, gcall *gc)
+{
+ gcc_assert (ptr_mode == Pmode);
+ tree g_target = gimple_call_lhs (gc);
+ tree g_ptr = gimple_call_arg (gc, 0);
+ tree g_tag = gimple_call_arg (gc, 1);
+
+ rtx ptr = expand_normal (g_ptr);
+ rtx tag = expand_expr (g_tag, NULL_RTX, QImode, EXPAND_NORMAL);
+ rtx target = expand_normal (g_target);
+
+ rtx untagged = targetm.memtag.untagged_pointer (ptr, target);
+ rtx tagged_value = targetm.memtag.set_tag (untagged, tag, target);
+ if (tagged_value != target)
+ emit_move_insn (target, tagged_value);
+}
+
+/* This should get expanded in the sanopt pass. */
+
+static void
expand_ASAN_CHECK (internal_fn, gcall *)
{
gcc_unreachable ();
@@ -553,6 +658,16 @@ get_min_precision (tree arg, signop sign)
if (++cnt > 30)
return prec + (orig_sign != sign);
}
+ if (CONVERT_EXPR_P (arg)
+ && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
+ && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) > prec)
+ {
+ /* We have e.g. (unsigned short) y_2 where int y_2 = (int) x_1(D);
+ If y_2's min precision is smaller than prec, return that. */
+ int oprec = get_min_precision (TREE_OPERAND (arg, 0), sign);
+ if (oprec < prec)
+ return oprec + (orig_sign != sign);
+ }
if (TREE_CODE (arg) != SSA_NAME)
return prec + (orig_sign != sign);
wide_int arg_min, arg_max;
@@ -683,7 +798,7 @@ expand_ubsan_result_store (rtx target, rtx res)
/* Add sub/add overflow checking to the statement STMT.
CODE says whether the operation is +, or -. */
-static void
+void
expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
tree arg0, tree arg1, bool unsr_p, bool uns0_p,
bool uns1_p, bool is_ubsan, tree *datap)
@@ -1357,6 +1472,37 @@ expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
NULL, done_label, profile_probability::very_likely ());
goto do_error_label;
case 3:
+ if (get_min_precision (arg1, UNSIGNED)
+ + get_min_precision (arg0, SIGNED) <= GET_MODE_PRECISION (mode))
+ {
+ /* If the first operand is sign extended from narrower type, the
+ second operand is zero extended from narrower type and
+ the sum of the two precisions is smaller or equal to the
+ result precision: if the first argument is at runtime
+ non-negative, maximum result will be 0x7e81 or 0x7f..fe80..01
+ and there will be no overflow, if the first argument is
+ negative and the second argument zero, the result will be
+ 0 and there will be no overflow, if the first argument is
+ negative and the second argument positive, the result when
+ treated as signed will be negative (minimum -0x7f80 or
+ -0x7f..f80..0) there there will be always overflow. So, do
+ res = (U) (s1 * u2)
+ ovf = (S) res < 0 */
+ struct separate_ops ops;
+ ops.code = MULT_EXPR;
+ ops.type
+ = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
+ 1);
+ ops.op0 = make_tree (ops.type, op0);
+ ops.op1 = make_tree (ops.type, op1);
+ ops.op2 = NULL_TREE;
+ ops.location = loc;
+ res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
+ do_compare_rtx_and_jump (res, const0_rtx, GE, false,
+ mode, NULL_RTX, NULL, done_label,
+ profile_probability::very_likely ());
+ goto do_error_label;
+ }
rtx_code_label *do_main_label;
do_main_label = gen_label_rtx ();
do_compare_rtx_and_jump (op0, const0_rtx, GE, false, mode, NULL_RTX,
@@ -1374,7 +1520,16 @@ expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
/* u1 * u2 -> sr */
if (uns0_p && uns1_p && !unsr_p)
{
- uns = true;
+ if ((pos_neg0 | pos_neg1) == 1)
+ {
+ /* If both arguments are zero extended from narrower types,
+ the MSB will be clear on both and so we can pretend it is
+ a normal s1 * s2 -> sr multiplication. */
+ uns0_p = false;
+ uns1_p = false;
+ }
+ else
+ uns = true;
/* Rest of handling of this case after res is computed. */
goto do_main;
}
@@ -1455,6 +1610,37 @@ expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
profile_probability::very_likely ());
goto do_error_label;
}
+ if (get_min_precision (arg0, SIGNED)
+ + get_min_precision (arg1, SIGNED) <= GET_MODE_PRECISION (mode))
+ {
+ /* If both operands are sign extended from narrower types and
+ the sum of the two precisions is smaller or equal to the
+ result precision: if both arguments are at runtime
+ non-negative, maximum result will be 0x3f01 or 0x3f..f0..01
+ and there will be no overflow, if both arguments are negative,
+ maximum result will be 0x40..00 and there will be no overflow
+ either, if one argument is positive and the other argument
+ negative, the result when treated as signed will be negative
+ and there will be always overflow, and if one argument is
+ zero and the other negative the result will be zero and no
+ overflow. So, do
+ res = (U) (s1 * s2)
+ ovf = (S) res < 0 */
+ struct separate_ops ops;
+ ops.code = MULT_EXPR;
+ ops.type
+ = build_nonstandard_integer_type (GET_MODE_PRECISION (mode),
+ 1);
+ ops.op0 = make_tree (ops.type, op0);
+ ops.op1 = make_tree (ops.type, op1);
+ ops.op2 = NULL_TREE;
+ ops.location = loc;
+ res = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
+ do_compare_rtx_and_jump (res, const0_rtx, GE, false,
+ mode, NULL_RTX, NULL, done_label,
+ profile_probability::very_likely ());
+ goto do_error_label;
+ }
/* The general case, do all the needed comparisons at runtime. */
rtx_code_label *do_main_label, *after_negate_label;
rtx rop0, rop1;
@@ -3044,27 +3230,68 @@ expand_DIVMOD (internal_fn, gcall *call_stmt)
the division and modulo and if it emits any library calls or any
{,U}{DIV,MOD} rtxes throw it away and use a divmod optab or
divmod libcall. */
- struct separate_ops ops;
- ops.code = TRUNC_DIV_EXPR;
- ops.type = type;
- ops.op0 = make_tree (ops.type, op0);
- ops.op1 = arg1;
- ops.op2 = NULL_TREE;
- ops.location = gimple_location (call_stmt);
- start_sequence ();
- quotient = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
- if (contains_call_div_mod (get_insns ()))
- quotient = NULL_RTX;
- else
+ scalar_int_mode int_mode;
+ if (remainder == NULL_RTX
+ && optimize
+ && CONST_INT_P (op1)
+ && !pow2p_hwi (INTVAL (op1))
+ && is_int_mode (TYPE_MODE (type), &int_mode)
+ && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
+ && optab_handler (and_optab, word_mode) != CODE_FOR_nothing
+ && optab_handler (add_optab, word_mode) != CODE_FOR_nothing
+ && optimize_insn_for_speed_p ())
{
- ops.code = TRUNC_MOD_EXPR;
- remainder = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
+ rtx_insn *last = get_last_insn ();
+ remainder = NULL_RTX;
+ quotient = expand_doubleword_divmod (int_mode, op0, op1, &remainder,
+ TYPE_UNSIGNED (type));
+ if (quotient != NULL_RTX)
+ {
+ if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing)
+ {
+ rtx_insn *move = emit_move_insn (quotient, quotient);
+ set_dst_reg_note (move, REG_EQUAL,
+ gen_rtx_fmt_ee (TYPE_UNSIGNED (type)
+ ? UDIV : DIV, int_mode,
+ copy_rtx (op0), op1),
+ quotient);
+ move = emit_move_insn (remainder, remainder);
+ set_dst_reg_note (move, REG_EQUAL,
+ gen_rtx_fmt_ee (TYPE_UNSIGNED (type)
+ ? UMOD : MOD, int_mode,
+ copy_rtx (op0), op1),
+ quotient);
+ }
+ }
+ else
+ delete_insns_since (last);
+ }
+
+ if (remainder == NULL_RTX)
+ {
+ struct separate_ops ops;
+ ops.code = TRUNC_DIV_EXPR;
+ ops.type = type;
+ ops.op0 = make_tree (ops.type, op0);
+ ops.op1 = arg1;
+ ops.op2 = NULL_TREE;
+ ops.location = gimple_location (call_stmt);
+ start_sequence ();
+ quotient = expand_expr_real_2 (&ops, NULL_RTX, mode, EXPAND_NORMAL);
if (contains_call_div_mod (get_insns ()))
- remainder = NULL_RTX;
+ quotient = NULL_RTX;
+ else
+ {
+ ops.code = TRUNC_MOD_EXPR;
+ remainder = expand_expr_real_2 (&ops, NULL_RTX, mode,
+ EXPAND_NORMAL);
+ if (contains_call_div_mod (get_insns ()))
+ remainder = NULL_RTX;
+ }
+ if (remainder)
+ insns = get_insns ();
+ end_sequence ();
}
- if (remainder)
- insns = get_insns ();
- end_sequence ();
}
if (remainder)
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index 310d37a..91a7bfe 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -321,6 +321,13 @@ DEF_INTERNAL_FN (UBSAN_PTR, ECF_LEAF | ECF_NOTHROW, ". R . ")
DEF_INTERNAL_FN (UBSAN_OBJECT_SIZE, ECF_LEAF | ECF_NOTHROW, NULL)
DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN, NULL)
DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (HWASAN_ALLOCA_UNPOISON, ECF_LEAF | ECF_NOTHROW, ". R ")
+DEF_INTERNAL_FN (HWASAN_CHOOSE_TAG, ECF_LEAF | ECF_NOTHROW, ". ")
+DEF_INTERNAL_FN (HWASAN_CHECK, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW,
+ ". . R . . ")
+DEF_INTERNAL_FN (HWASAN_MARK, ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (HWASAN_SET_TAG,
+ ECF_TM_PURE | ECF_PURE | ECF_LEAF | ECF_NOTHROW, ". R R ")
DEF_INTERNAL_FN (ASAN_CHECK, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW,
". . R . . ")
DEF_INTERNAL_FN (ASAN_MARK, ECF_LEAF | ECF_NOTHROW, NULL)
diff --git a/gcc/internal-fn.h b/gcc/internal-fn.h
index ac970e9..2a96b2b 100644
--- a/gcc/internal-fn.h
+++ b/gcc/internal-fn.h
@@ -224,6 +224,8 @@ extern bool internal_gather_scatter_fn_supported_p (internal_fn, tree,
extern bool internal_check_ptrs_fn_supported_p (internal_fn, tree,
poly_uint64, unsigned int);
+extern void expand_addsub_overflow (location_t, tree_code, tree, tree, tree,
+ bool, bool, bool, bool, tree *);
extern void expand_internal_call (gcall *);
extern void expand_internal_call (internal_fn, gcall *);
extern void expand_PHI (internal_fn, gcall *);
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 465b072..a06b4d1 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -156,16 +156,22 @@ public:
class ipcp_value_base
{
public:
- /* Time benefit and size cost that specializing the function for this value
- would bring about in this function alone. */
- int local_time_benefit, local_size_cost;
- /* Time benefit and size cost that specializing the function for this value
- can bring about in it's callees (transitively). */
- int prop_time_benefit, prop_size_cost;
+ /* Time benefit and that specializing the function for this value would bring
+ about in this function alone. */
+ sreal local_time_benefit;
+ /* Time benefit that specializing the function for this value can bring about
+ in it's callees. */
+ sreal prop_time_benefit;
+ /* Size cost that specializing the function for this value would bring about
+ in this function alone. */
+ int local_size_cost;
+ /* Size cost that specializing the function for this value can bring about in
+ it's callees. */
+ int prop_size_cost;
ipcp_value_base ()
- : local_time_benefit (0), local_size_cost (0),
- prop_time_benefit (0), prop_size_cost (0) {}
+ : local_time_benefit (0), prop_time_benefit (0),
+ local_size_cost (0), prop_size_cost (0) {}
};
/* Describes one particular value stored in struct ipcp_lattice. */
@@ -499,10 +505,10 @@ ipcp_lattice<valtype>::print (FILE * f, bool dump_sources, bool dump_benefits)
}
if (dump_benefits)
- fprintf (f, " [loc_time: %i, loc_size: %i, "
- "prop_time: %i, prop_size: %i]\n",
- val->local_time_benefit, val->local_size_cost,
- val->prop_time_benefit, val->prop_size_cost);
+ fprintf (f, " [loc_time: %g, loc_size: %i, "
+ "prop_time: %g, prop_size: %i]\n",
+ val->local_time_benefit.to_double (), val->local_size_cost,
+ val->prop_time_benefit.to_double (), val->prop_size_cost);
}
if (!dump_benefits)
fprintf (f, "\n");
@@ -668,7 +674,8 @@ ipcp_versionable_function_p (struct cgraph_node *node)
struct caller_statistics
{
profile_count count_sum;
- int n_calls, n_hot_calls, freq_sum;
+ sreal freq_sum;
+ int n_calls, n_hot_calls;
};
/* Initialize fields of STAT to zeroes. */
@@ -696,7 +703,7 @@ gather_caller_stats (struct cgraph_node *node, void *data)
{
if (cs->count.ipa ().initialized_p ())
stats->count_sum += cs->count.ipa ();
- stats->freq_sum += cs->frequency ();
+ stats->freq_sum += cs->sreal_frequency ();
stats->n_calls++;
if (cs->maybe_hot_p ())
stats->n_hot_calls ++;
@@ -1297,6 +1304,26 @@ initialize_node_lattices (struct cgraph_node *node)
}
}
+/* Return true iff X and Y should be considered equal values by IPA-CP. */
+
+static bool
+values_equal_for_ipcp_p (tree x, tree y)
+{
+ gcc_checking_assert (x != NULL_TREE && y != NULL_TREE);
+
+ if (x == y)
+ return true;
+
+ if (TREE_CODE (x) == ADDR_EXPR
+ && TREE_CODE (y) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (x, 0)) == CONST_DECL
+ && TREE_CODE (TREE_OPERAND (y, 0)) == CONST_DECL)
+ return operand_equal_p (DECL_INITIAL (TREE_OPERAND (x, 0)),
+ DECL_INITIAL (TREE_OPERAND (y, 0)), 0);
+ else
+ return operand_equal_p (x, y, 0);
+}
+
/* Return the result of a (possibly arithmetic) operation on the constant
value INPUT. OPERAND is 2nd operand for binary operation. RES_TYPE is
the type of the parameter to which the result is passed. Return
@@ -1314,6 +1341,14 @@ ipa_get_jf_arith_result (enum tree_code opcode, tree input, tree operand,
if (!is_gimple_ip_invariant (input))
return NULL_TREE;
+ if (opcode == ASSERT_EXPR)
+ {
+ if (values_equal_for_ipcp_p (input, operand))
+ return input;
+ else
+ return NULL_TREE;
+ }
+
if (!res_type)
{
if (TREE_CODE_CLASS (opcode) == tcc_comparison)
@@ -1746,26 +1781,6 @@ ipcp_verify_propagated_values (void)
}
}
-/* Return true iff X and Y should be considered equal values by IPA-CP. */
-
-static bool
-values_equal_for_ipcp_p (tree x, tree y)
-{
- gcc_checking_assert (x != NULL_TREE && y != NULL_TREE);
-
- if (x == y)
- return true;
-
- if (TREE_CODE (x) == ADDR_EXPR
- && TREE_CODE (y) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (x, 0)) == CONST_DECL
- && TREE_CODE (TREE_OPERAND (y, 0)) == CONST_DECL)
- return operand_equal_p (DECL_INITIAL (TREE_OPERAND (x, 0)),
- DECL_INITIAL (TREE_OPERAND (y, 0)), 0);
- else
- return operand_equal_p (x, y, 0);
-}
-
/* Return true iff X and Y should be considered equal contexts by IPA-CP. */
static bool
@@ -3224,9 +3239,9 @@ hint_time_bonus (cgraph_node *node, const ipa_call_estimates &estimates)
/* If there is a reason to penalize the function described by INFO in the
cloning goodness evaluation, do so. */
-static inline int64_t
+static inline sreal
incorporate_penalties (cgraph_node *node, ipa_node_params *info,
- int64_t evaluation)
+ sreal evaluation)
{
if (info->node_within_scc && !info->node_is_self_scc)
evaluation = (evaluation
@@ -3247,8 +3262,9 @@ incorporate_penalties (cgraph_node *node, ipa_node_params *info,
potential new clone in FREQUENCIES. */
static bool
-good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
- int freq_sum, profile_count count_sum, int size_cost)
+good_cloning_opportunity_p (struct cgraph_node *node, sreal time_benefit,
+ sreal freq_sum, profile_count count_sum,
+ int size_cost)
{
if (time_benefit == 0
|| !opt_for_fn (node->decl, flag_ipa_cp_clone)
@@ -3256,50 +3272,56 @@ good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
return false;
gcc_assert (size_cost > 0);
+ if (size_cost == INT_MAX)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " good_cloning_opportunity_p returning "
+ "false because of size overflow.\n");
+ return false;
+ }
class ipa_node_params *info = IPA_NODE_REF (node);
int eval_threshold = opt_for_fn (node->decl, param_ipa_cp_eval_threshold);
if (max_count > profile_count::zero ())
{
- int factor = RDIV (count_sum.probability_in
- (max_count).to_reg_br_prob_base ()
- * 1000, REG_BR_PROB_BASE);
- int64_t evaluation = (((int64_t) time_benefit * factor)
- / size_cost);
+
+ sreal factor = count_sum.probability_in (max_count).to_sreal ();
+ sreal evaluation = (time_benefit * factor) / size_cost;
evaluation = incorporate_penalties (node, info, evaluation);
+ evaluation *= 1000;
if (dump_file && (dump_flags & TDF_DETAILS))
{
- fprintf (dump_file, " good_cloning_opportunity_p (time: %i, "
- "size: %i, count_sum: ", time_benefit, size_cost);
+ fprintf (dump_file, " good_cloning_opportunity_p (time: %g, "
+ "size: %i, count_sum: ", time_benefit.to_double (),
+ size_cost);
count_sum.dump (dump_file);
- fprintf (dump_file, "%s%s) -> evaluation: " "%" PRId64
- ", threshold: %i\n",
+ fprintf (dump_file, "%s%s) -> evaluation: %.2f, threshold: %i\n",
info->node_within_scc
? (info->node_is_self_scc ? ", self_scc" : ", scc") : "",
info->node_calling_single_call ? ", single_call" : "",
- evaluation, eval_threshold);
+ evaluation.to_double (), eval_threshold);
}
- return evaluation >= eval_threshold;
+ return evaluation.to_int () >= eval_threshold;
}
else
{
- int64_t evaluation = (((int64_t) time_benefit * freq_sum)
- / size_cost);
+ sreal evaluation = (time_benefit * freq_sum) / size_cost;
evaluation = incorporate_penalties (node, info, evaluation);
+ evaluation *= 1000;
if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, " good_cloning_opportunity_p (time: %i, "
- "size: %i, freq_sum: %i%s%s) -> evaluation: "
- "%" PRId64 ", threshold: %i\n",
- time_benefit, size_cost, freq_sum,
+ fprintf (dump_file, " good_cloning_opportunity_p (time: %g, "
+ "size: %i, freq_sum: %g%s%s) -> evaluation: %.2f, "
+ "threshold: %i\n",
+ time_benefit.to_double (), size_cost, freq_sum.to_double (),
info->node_within_scc
? (info->node_is_self_scc ? ", self_scc" : ", scc") : "",
info->node_calling_single_call ? ", single_call" : "",
- evaluation, eval_threshold);
+ evaluation.to_double (), eval_threshold);
- return evaluation >= eval_threshold;
+ return evaluation.to_int () >= eval_threshold;
}
}
@@ -3411,13 +3433,10 @@ perform_estimation_of_a_value (cgraph_node *node,
int removable_params_cost, int est_move_cost,
ipcp_value_base *val)
{
- int time_benefit;
+ sreal time_benefit;
ipa_call_estimates estimates;
estimate_ipcp_clone_size_and_time (node, avals, &estimates);
- sreal time_delta = estimates.nonspecialized_time - estimates.time;
- if (time_delta > 65535)
- time_delta = 65535;
/* Extern inline functions have no cloning local time benefits because they
will be inlined anyway. The only reason to clone them is if it enables
@@ -3425,10 +3444,10 @@ perform_estimation_of_a_value (cgraph_node *node,
if (DECL_EXTERNAL (node->decl) && DECL_DECLARED_INLINE_P (node->decl))
time_benefit = 0;
else
- time_benefit = time_delta.to_int ()
- + devirtualization_time_bonus (node, avals)
- + hint_time_bonus (node, estimates)
- + removable_params_cost + est_move_cost;
+ time_benefit = (estimates.nonspecialized_time - estimates.time)
+ + (devirtualization_time_bonus (node, avals)
+ + hint_time_bonus (node, estimates)
+ + removable_params_cost + est_move_cost);
int size = estimates.size;
gcc_checking_assert (size >=0);
@@ -3509,10 +3528,8 @@ estimate_local_effects (struct cgraph_node *node)
fprintf (dump_file, " Decided to specialize for all "
"known contexts, code not going to grow.\n");
}
- else if (good_cloning_opportunity_p (node,
- MIN ((time).to_int (), 65536),
- stats.freq_sum, stats.count_sum,
- size))
+ else if (good_cloning_opportunity_p (node, time, stats.freq_sum,
+ stats.count_sum, size))
{
if (size + overall_size <= get_max_overall_size (node))
{
@@ -3561,8 +3578,9 @@ estimate_local_effects (struct cgraph_node *node)
print_ipcp_constant_value (dump_file, val->value);
fprintf (dump_file, " for ");
ipa_dump_param (dump_file, info, i);
- fprintf (dump_file, ": time_benefit: %i, size: %i\n",
- val->local_time_benefit, val->local_size_cost);
+ fprintf (dump_file, ": time_benefit: %g, size: %i\n",
+ val->local_time_benefit.to_double (),
+ val->local_size_cost);
}
}
avals.m_known_vals[i] = NULL_TREE;
@@ -3595,8 +3613,9 @@ estimate_local_effects (struct cgraph_node *node)
print_ipcp_constant_value (dump_file, val->value);
fprintf (dump_file, " for ");
ipa_dump_param (dump_file, info, i);
- fprintf (dump_file, ": time_benefit: %i, size: %i\n",
- val->local_time_benefit, val->local_size_cost);
+ fprintf (dump_file, ": time_benefit: %g, size: %i\n",
+ val->local_time_benefit.to_double (),
+ val->local_size_cost);
}
}
avals.m_known_contexts[i] = ipa_polymorphic_call_context ();
@@ -3637,10 +3656,11 @@ estimate_local_effects (struct cgraph_node *node)
fprintf (dump_file, " for ");
ipa_dump_param (dump_file, info, i);
fprintf (dump_file, "[%soffset: " HOST_WIDE_INT_PRINT_DEC
- "]: time_benefit: %i, size: %i\n",
+ "]: time_benefit: %g, size: %i\n",
plats->aggs_by_ref ? "ref " : "",
aglat->offset,
- val->local_time_benefit, val->local_size_cost);
+ val->local_time_benefit.to_double (),
+ val->local_size_cost);
}
agg->items.pop ();
@@ -3830,13 +3850,13 @@ propagate_constants_topo (class ipa_topo_info *topo)
/* Return the sum of A and B if none of them is bigger than INT_MAX/2, return
- the bigger one if otherwise. */
+ INT_MAX. */
static int
safe_add (int a, int b)
{
if (a > INT_MAX/2 || b > INT_MAX/2)
- return a > b ? a : b;
+ return INT_MAX;
else
return a + b;
}
@@ -3855,13 +3875,14 @@ value_topo_info<valtype>::propagate_effects ()
{
ipcp_value_source<valtype> *src;
ipcp_value<valtype> *val;
- int time = 0, size = 0;
+ sreal time = 0;
+ int size = 0;
for (val = base; val; val = val->scc_next)
{
- time = safe_add (time,
- val->local_time_benefit + val->prop_time_benefit);
- size = safe_add (size, val->local_size_cost + val->prop_size_cost);
+ time = time + val->local_time_benefit + val->prop_time_benefit;
+ size = safe_add (size, safe_add (val->local_size_cost,
+ val->prop_size_cost));
}
for (val = base; val; val = val->scc_next)
@@ -3869,8 +3890,7 @@ value_topo_info<valtype>::propagate_effects ()
if (src->val
&& src->cs->maybe_hot_p ())
{
- src->val->prop_time_benefit = safe_add (time,
- src->val->prop_time_benefit);
+ src->val->prop_time_benefit = time + src->val->prop_time_benefit;
src->val->prop_size_cost = safe_add (size,
src->val->prop_size_cost);
}
@@ -4162,11 +4182,12 @@ get_next_cgraph_edge_clone (struct cgraph_edge *cs)
template <typename valtype>
static bool
get_info_about_necessary_edges (ipcp_value<valtype> *val, cgraph_node *dest,
- int *freq_sum,
- profile_count *count_sum, int *caller_count)
+ sreal *freq_sum, profile_count *count_sum,
+ int *caller_count)
{
ipcp_value_source<valtype> *src;
- int freq = 0, count = 0;
+ sreal freq = 0;
+ int count = 0;
profile_count cnt = profile_count::zero ();
bool hot = false;
bool non_self_recursive = false;
@@ -4179,7 +4200,7 @@ get_info_about_necessary_edges (ipcp_value<valtype> *val, cgraph_node *dest,
if (cgraph_edge_brings_value_p (cs, src, dest, val))
{
count++;
- freq += cs->frequency ();
+ freq += cs->sreal_frequency ();
if (cs->count.ipa ().initialized_p ())
cnt += cs->count.ipa ();
hot |= cs->maybe_hot_p ();
@@ -5448,7 +5469,8 @@ decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset,
ipcp_value<valtype> *val, ipa_auto_call_arg_values *avals)
{
struct ipa_agg_replacement_value *aggvals;
- int freq_sum, caller_count;
+ int caller_count;
+ sreal freq_sum;
profile_count count_sum;
vec<cgraph_edge *> callers;
@@ -5487,8 +5509,8 @@ decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset,
freq_sum, count_sum,
val->local_size_cost)
&& !good_cloning_opportunity_p (node,
- safe_add (val->local_time_benefit,
- val->prop_time_benefit),
+ val->local_time_benefit
+ + val->prop_time_benefit,
freq_sum, count_sum,
safe_add (val->local_size_cost,
val->prop_size_cost)))
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 067ed5b..0f2b814 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -1521,6 +1521,7 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
break;
}
case VOID_TYPE:
+ case OPAQUE_TYPE:
case NULLPTR_TYPE:
break;
@@ -2032,6 +2033,8 @@ odr_based_tbaa_p (const_tree type)
{
if (!RECORD_OR_UNION_TYPE_P (type))
return false;
+ if (!odr_hash)
+ return false;
odr_type t = get_odr_type (const_cast <tree> (type), false);
if (!t || !t->tbaa_enabled)
return false;
diff --git a/gcc/ipa-icf-gimple.c b/gcc/ipa-icf-gimple.c
index d5423a7..7e2b3c4 100644
--- a/gcc/ipa-icf-gimple.c
+++ b/gcc/ipa-icf-gimple.c
@@ -38,7 +38,9 @@ along with GCC; see the file COPYING3. If not see
#include "builtins.h"
#include "cfgloop.h"
#include "attribs.h"
+#include "gimple-walk.h"
+#include "tree-ssa-alias-compare.h"
#include "ipa-icf-gimple.h"
namespace ipa_icf_gimple {
@@ -51,13 +53,13 @@ namespace ipa_icf_gimple {
of declarations that can be skipped. */
func_checker::func_checker (tree source_func_decl, tree target_func_decl,
- bool ignore_labels,
+ bool ignore_labels, bool tbaa,
hash_set<symtab_node *> *ignored_source_nodes,
hash_set<symtab_node *> *ignored_target_nodes)
: m_source_func_decl (source_func_decl), m_target_func_decl (target_func_decl),
m_ignored_source_nodes (ignored_source_nodes),
m_ignored_target_nodes (ignored_target_nodes),
- m_ignore_labels (ignore_labels)
+ m_ignore_labels (ignore_labels), m_tbaa (tbaa)
{
function *source_func = DECL_STRUCT_FUNCTION (source_func_decl);
function *target_func = DECL_STRUCT_FUNCTION (target_func_decl);
@@ -109,7 +111,7 @@ func_checker::compare_ssa_name (const_tree t1, const_tree t2)
tree b1 = SSA_NAME_VAR (t1);
tree b2 = SSA_NAME_VAR (t2);
- return compare_operand (b1, b2);
+ return compare_operand (b1, b2, OP_NORMAL);
}
return true;
@@ -151,8 +153,21 @@ func_checker::compare_decl (const_tree t1, const_tree t2)
&& DECL_BY_REFERENCE (t1) != DECL_BY_REFERENCE (t2))
return return_false_with_msg ("DECL_BY_REFERENCE flags are different");
- if (!compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2)))
- return return_false ();
+ /* We do not really need to check types of variables, since they are just
+ blocks of memory and we verify types of the accesses to them.
+ However do compare types of other kinds of decls
+ (parm decls and result decl types may affect ABI convetions). */
+ if (t != VAR_DECL)
+ {
+ if (!compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+ return return_false ();
+ }
+ else
+ {
+ if (!operand_equal_p (DECL_SIZE (t1), DECL_SIZE (t2),
+ OEP_MATCH_SIDE_EFFECTS))
+ return return_false_with_msg ("DECL_SIZEs are different");
+ }
bool existed_p;
const_tree &slot = m_decl_map.get_or_insert (t1, &existed_p);
@@ -212,8 +227,8 @@ func_checker::compatible_types_p (tree t1, tree t2)
return true;
}
-/* Function compare for equality given trees T1 and T2 which
- can be either a constant or a declaration type. */
+/* Add hash of ARG to HSTATE. FLAGS have same meaning
+ as for operand_equal_p. Works only if operand acces type is OP_NORMAL. */
void
func_checker::hash_operand (const_tree arg, inchash::hash &hstate,
@@ -227,13 +242,29 @@ func_checker::hash_operand (const_tree arg, inchash::hash &hstate,
switch (TREE_CODE (arg))
{
+ case PARM_DECL:
+ {
+ unsigned int index = 0;
+ if (DECL_CONTEXT (arg))
+ for (tree p = DECL_ARGUMENTS (DECL_CONTEXT (arg));
+ p && index < 32; p = DECL_CHAIN (p), index++)
+ if (p == arg)
+ break;
+ hstate.add_int (PARM_DECL);
+ hstate.add_int (index);
+ }
+ return;
case FUNCTION_DECL:
case VAR_DECL:
case LABEL_DECL:
- case PARM_DECL:
case RESULT_DECL:
case CONST_DECL:
+ hstate.add_int (TREE_CODE (arg));
+ return;
case SSA_NAME:
+ hstate.add_int (SSA_NAME);
+ if (SSA_NAME_IS_DEFAULT_DEF (arg))
+ hash_operand (SSA_NAME_VAR (arg), hstate, flags);
return;
case FIELD_DECL:
inchash::add_expr (DECL_FIELD_OFFSET (arg), hstate, flags);
@@ -243,9 +274,36 @@ func_checker::hash_operand (const_tree arg, inchash::hash &hstate,
break;
}
+ /* In gimple all clobbers can be considered equal: while comparaing two
+ gimple clobbers we match the left hand memory accesses. */
+ if (TREE_CLOBBER_P (arg))
+ {
+ hstate.add_int (0xc10bbe5);
+ return;
+ }
+ gcc_assert (!DECL_P (arg));
+ gcc_assert (!TYPE_P (arg));
+
return operand_compare::hash_operand (arg, hstate, flags);
}
+/* Add hash of ARG accesses according to ACCESS to HSTATE.
+ FLAGS have same meaning as for operand_equal_p. */
+
+void
+func_checker::hash_operand (const_tree arg, inchash::hash &hstate,
+ unsigned int flags, operand_access_type access)
+{
+ if (access == OP_MEMORY)
+ {
+ ao_ref ref;
+ ao_ref_init (&ref, const_cast <tree> (arg));
+ return hash_ao_ref (&ref, lto_streaming_expected_p (), m_tbaa, hstate);
+ }
+ else
+ return hash_operand (arg, hstate, flags);
+}
+
bool
func_checker::operand_equal_p (const_tree t1, const_tree t2,
unsigned int flags)
@@ -287,28 +345,65 @@ func_checker::operand_equal_p (const_tree t1, const_tree t2,
default:
break;
}
+ /* In gimple all clobbers can be considered equal. We match the left hand
+ memory accesses. */
+ if (TREE_CLOBBER_P (t1) || TREE_CLOBBER_P (t2))
+ return TREE_CLOBBER_P (t1) == TREE_CLOBBER_P (t2);
return operand_compare::operand_equal_p (t1, t2, flags);
}
-/* Function responsible for comparison of various operands T1 and T2.
+/* Function responsible for comparison of various operands T1 and T2
+ which are accessed as ACCESS.
If these components, from functions FUNC1 and FUNC2, are equal, true
is returned. */
bool
-func_checker::compare_operand (tree t1, tree t2)
+func_checker::compare_operand (tree t1, tree t2, operand_access_type access)
{
if (!t1 && !t2)
return true;
else if (!t1 || !t2)
return false;
- if (operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS))
- return true;
- return return_false_with_msg ("operand_equal_p failed");
+ if (access == OP_MEMORY)
+ {
+ ao_ref ref1, ref2;
+ ao_ref_init (&ref1, const_cast <tree> (t1));
+ ao_ref_init (&ref2, const_cast <tree> (t2));
+ int flags = compare_ao_refs (&ref1, &ref2,
+ lto_streaming_expected_p (), m_tbaa);
+
+ if (!flags)
+ return true;
+ if (flags & SEMANTICS)
+ return return_false_with_msg
+ ("compare_ao_refs failed (semantic difference)");
+ if (flags & BASE_ALIAS_SET)
+ return return_false_with_msg
+ ("compare_ao_refs failed (base alias set difference)");
+ if (flags & REF_ALIAS_SET)
+ return return_false_with_msg
+ ("compare_ao_refs failed (ref alias set difference)");
+ if (flags & ACCESS_PATH)
+ return return_false_with_msg
+ ("compare_ao_refs failed (access path difference)");
+ if (flags & DEPENDENCE_CLIQUE)
+ return return_false_with_msg
+ ("compare_ao_refs failed (dependence clique difference)");
+ gcc_unreachable ();
+ }
+ else
+ {
+ if (operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS))
+ return true;
+ return return_false_with_msg
+ ("operand_equal_p failed");
+ }
}
bool
-func_checker::compare_asm_inputs_outputs (tree t1, tree t2)
+func_checker::compare_asm_inputs_outputs (tree t1, tree t2,
+ operand_access_type_map *map)
{
gcc_assert (TREE_CODE (t1) == TREE_LIST);
gcc_assert (TREE_CODE (t2) == TREE_LIST);
@@ -318,7 +413,8 @@ func_checker::compare_asm_inputs_outputs (tree t1, tree t2)
if (!t2)
return false;
- if (!compare_operand (TREE_VALUE (t1), TREE_VALUE (t2)))
+ if (!compare_operand (TREE_VALUE (t1), TREE_VALUE (t2),
+ get_operand_access_type (map, t1)))
return return_false ();
tree p1 = TREE_PURPOSE (t1);
@@ -545,9 +641,12 @@ func_checker::compare_gimple_call (gcall *s1, gcall *s2)
if (gimple_call_num_args (s1) != gimple_call_num_args (s2))
return false;
+ operand_access_type_map map (5);
+ classify_operands (s1, &map);
+
t1 = gimple_call_fn (s1);
t2 = gimple_call_fn (s2);
- if (!compare_operand (t1, t2))
+ if (!compare_operand (t1, t2, get_operand_access_type (&map, t1)))
return return_false ();
/* Compare flags. */
@@ -567,10 +666,17 @@ func_checker::compare_gimple_call (gcall *s1, gcall *s2)
tree fntype1 = gimple_call_fntype (s1);
tree fntype2 = gimple_call_fntype (s2);
- if ((fntype1 && !fntype2)
- || (!fntype1 && fntype2)
- || (fntype1 && !types_compatible_p (fntype1, fntype2)))
- return return_false_with_msg ("call function types are not compatible");
+
+ /* For direct calls we verify that types are comopatible so if we matced
+ callees, callers must match, too. For indirect calls however verify
+ function type. */
+ if (!gimple_call_fndecl (s1))
+ {
+ if ((fntype1 && !fntype2)
+ || (!fntype1 && fntype2)
+ || (fntype1 && !types_compatible_p (fntype1, fntype2)))
+ return return_false_with_msg ("call function types are not compatible");
+ }
if (fntype1 && fntype2 && comp_type_attributes (fntype1, fntype2) != 1)
return return_false_with_msg ("different fntype attributes");
@@ -579,7 +685,8 @@ func_checker::compare_gimple_call (gcall *s1, gcall *s2)
tree chain2 = gimple_call_chain (s2);
if ((chain1 && !chain2)
|| (!chain1 && chain2)
- || !compare_operand (chain1, chain2))
+ || !compare_operand (chain1, chain2,
+ get_operand_access_type (&map, chain1)))
return return_false_with_msg ("static call chains are different");
/* Checking of argument. */
@@ -588,7 +695,7 @@ func_checker::compare_gimple_call (gcall *s1, gcall *s2)
t1 = gimple_call_arg (s1, i);
t2 = gimple_call_arg (s2, i);
- if (!compare_operand (t1, t2))
+ if (!compare_operand (t1, t2, get_operand_access_type (&map, t1)))
return return_false_with_msg ("GIMPLE call operands are different");
}
@@ -596,7 +703,7 @@ func_checker::compare_gimple_call (gcall *s1, gcall *s2)
t1 = gimple_get_lhs (s1);
t2 = gimple_get_lhs (s2);
- return compare_operand (t1, t2);
+ return compare_operand (t1, t2, get_operand_access_type (&map, t1));
}
@@ -610,31 +717,28 @@ func_checker::compare_gimple_assign (gimple *s1, gimple *s2)
tree_code code1, code2;
unsigned i;
- code1 = gimple_expr_code (s1);
- code2 = gimple_expr_code (s2);
-
- if (code1 != code2)
- return false;
-
code1 = gimple_assign_rhs_code (s1);
code2 = gimple_assign_rhs_code (s2);
if (code1 != code2)
return false;
+ operand_access_type_map map (5);
+ classify_operands (s1, &map);
+
for (i = 0; i < gimple_num_ops (s1); i++)
{
arg1 = gimple_op (s1, i);
arg2 = gimple_op (s2, i);
/* Compare types for LHS. */
- if (i == 0)
+ if (i == 0 && !gimple_store_p (s1))
{
if (!compatible_types_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
- return return_false_with_msg ("GIMPLE NOP LHS type mismatch");
+ return return_false_with_msg ("GIMPLE LHS type mismatch");
}
- if (!compare_operand (arg1, arg2))
+ if (!compare_operand (arg1, arg2, get_operand_access_type (&map, arg1)))
return return_false_with_msg ("GIMPLE assignment operands "
"are different");
}
@@ -652,8 +756,8 @@ func_checker::compare_gimple_cond (gimple *s1, gimple *s2)
tree t1, t2;
tree_code code1, code2;
- code1 = gimple_expr_code (s1);
- code2 = gimple_expr_code (s2);
+ code1 = gimple_cond_code (s1);
+ code2 = gimple_cond_code (s2);
if (code1 != code2)
return false;
@@ -661,13 +765,13 @@ func_checker::compare_gimple_cond (gimple *s1, gimple *s2)
t1 = gimple_cond_lhs (s1);
t2 = gimple_cond_lhs (s2);
- if (!compare_operand (t1, t2))
+ if (!compare_operand (t1, t2, OP_NORMAL))
return false;
t1 = gimple_cond_rhs (s1);
t2 = gimple_cond_rhs (s2);
- return compare_operand (t1, t2);
+ return compare_operand (t1, t2, OP_NORMAL);
}
/* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
@@ -706,7 +810,7 @@ func_checker::compare_gimple_switch (const gswitch *g1, const gswitch *g2)
tree t1 = gimple_switch_index (g1);
tree t2 = gimple_switch_index (g2);
- if (!compare_operand (t1, t2))
+ if (!compare_operand (t1, t2, OP_NORMAL))
return false;
for (i = 0; i < lsize1; i++)
@@ -733,7 +837,7 @@ func_checker::compare_gimple_switch (const gswitch *g1, const gswitch *g2)
label1 = CASE_LABEL (label1);
label2 = CASE_LABEL (label2);
- if (!compare_operand (label1, label2))
+ if (!compare_operand (label1, label2, OP_NORMAL))
return return_false_with_msg ("switch label_exprs are different");
}
else if (!tree_int_cst_equal (label1, label2))
@@ -758,7 +862,10 @@ func_checker::compare_gimple_return (const greturn *g1, const greturn *g2)
if (t1 == NULL && t2 == NULL)
return true;
else
- return compare_operand (t1, t2);
+ {
+ operand_access_type_map map (3);
+ return compare_operand (t1, t2, get_operand_access_type (&map, t1));
+ }
}
/* Verifies for given GIMPLEs S1 and S2 that
@@ -775,7 +882,7 @@ func_checker::compare_gimple_goto (gimple *g1, gimple *g2)
if (TREE_CODE (dest1) != TREE_CODE (dest2) || TREE_CODE (dest1) != SSA_NAME)
return false;
- return compare_operand (dest1, dest2);
+ return compare_operand (dest1, dest2, OP_NORMAL);
}
/* Verifies for given GIMPLE_RESX stmts S1 and S2 that
@@ -819,12 +926,15 @@ func_checker::compare_gimple_asm (const gasm *g1, const gasm *g2)
if (strcmp (gimple_asm_string (g1), gimple_asm_string (g2)) != 0)
return return_false_with_msg ("ASM strings are different");
+ operand_access_type_map map (5);
+ classify_operands (g1, &map);
+
for (unsigned i = 0; i < gimple_asm_ninputs (g1); i++)
{
tree input1 = gimple_asm_input_op (g1, i);
tree input2 = gimple_asm_input_op (g2, i);
- if (!compare_asm_inputs_outputs (input1, input2))
+ if (!compare_asm_inputs_outputs (input1, input2, &map))
return return_false_with_msg ("ASM input is different");
}
@@ -833,7 +943,7 @@ func_checker::compare_gimple_asm (const gasm *g1, const gasm *g2)
tree output1 = gimple_asm_output_op (g1, i);
tree output2 = gimple_asm_output_op (g2, i);
- if (!compare_asm_inputs_outputs (output1, output2))
+ if (!compare_asm_inputs_outputs (output1, output2, &map))
return return_false_with_msg ("ASM output is different");
}
@@ -850,4 +960,35 @@ func_checker::compare_gimple_asm (const gasm *g1, const gasm *g2)
return true;
}
+/* Helper for func_checker::classify_operands. Record that T is a load. */
+
+static bool
+visit_load_store (gimple *, tree, tree t, void *data)
+{
+ func_checker::operand_access_type_map *map =
+ (func_checker::operand_access_type_map *) data;
+ map->add (t);
+ return false;
+}
+
+/* Compute hash map determining access types of operands. */
+
+void
+func_checker::classify_operands (const gimple *stmt,
+ operand_access_type_map *map)
+{
+ walk_stmt_load_store_ops (const_cast <gimple *> (stmt),
+ (void *)map, visit_load_store, visit_load_store);
+}
+
+/* Return access type of a given operand. */
+
+func_checker::operand_access_type
+func_checker::get_operand_access_type (operand_access_type_map *map, tree t)
+{
+ if (map->contains (t))
+ return OP_MEMORY;
+ return OP_NORMAL;
+}
+
} // ipa_icf_gimple namespace
diff --git a/gcc/ipa-icf-gimple.h b/gcc/ipa-icf-gimple.h
index 28459d2..40f7474 100644
--- a/gcc/ipa-icf-gimple.h
+++ b/gcc/ipa-icf-gimple.h
@@ -118,14 +118,14 @@ public:
/* A class aggregating all connections and semantic equivalents
for a given pair of semantic function candidates. */
-class func_checker : operand_compare
+class func_checker : ao_compare
{
public:
/* Default constructor. */
func_checker ():
m_source_func_decl (NULL_TREE), m_target_func_decl (NULL_TREE),
m_ignored_source_nodes (NULL), m_ignored_target_nodes (NULL),
- m_ignore_labels (false)
+ m_ignore_labels (false), m_tbaa (true)
{
m_source_ssa_names.create (0);
m_target_ssa_names.create (0);
@@ -139,6 +139,7 @@ public:
of declarations that can be skipped. */
func_checker (tree source_func_decl, tree target_func_decl,
bool ignore_labels = false,
+ bool tbaa = true,
hash_set<symtab_node *> *ignored_source_nodes = NULL,
hash_set<symtab_node *> *ignored_target_nodes = NULL);
@@ -200,14 +201,19 @@ public:
/* Verification function for declaration trees T1 and T2. */
bool compare_decl (const_tree t1, const_tree t2);
+ /* Compute hash map MAP that determines loads and stores of STMT. */
+ enum operand_access_type {OP_MEMORY, OP_NORMAL};
+ typedef hash_set<tree> operand_access_type_map;
+
/* Function responsible for comparison of various operands T1 and T2.
If these components, from functions FUNC1 and FUNC2, are equal, true
is returned. */
- bool compare_operand (tree t1, tree t2);
+ bool compare_operand (tree t1, tree t2, operand_access_type type);
/* Compares GIMPLE ASM inputs (or outputs) where we iterate tree chain
and compare both TREE_PURPOSEs and TREE_VALUEs. */
- bool compare_asm_inputs_outputs (tree t1, tree t2);
+ bool compare_asm_inputs_outputs (tree t1, tree t2,
+ operand_access_type_map *map);
/* Verifies that trees T1 and T2, representing function declarations
are equivalent from perspective of ICF. */
@@ -230,7 +236,13 @@ public:
first parameter of a function. */
static bool compatible_types_p (tree t1, tree t2);
+ /* Compute hash map determining access types of operands. */
+ static void classify_operands (const gimple *stmt,
+ operand_access_type_map *map);
+ /* Return access type of a given operand. */
+ static operand_access_type get_operand_access_type
+ (operand_access_type_map *map, tree);
private:
/* Vector mapping source SSA names to target ones. */
vec <int> m_source_ssa_names;
@@ -264,6 +276,9 @@ private:
/* Flag if ignore labels in comparison. */
bool m_ignore_labels;
+ /* Flag if we should compare type based alias analysis info. */
+ bool m_tbaa;
+
public:
/* Return true if two operands are equal. The flags fields can be used
to specify OEP flags described above. */
@@ -272,6 +287,8 @@ public:
/* Generate a hash value for an expression. This can be used iteratively
by passing a previous result as the HSTATE argument. */
virtual void hash_operand (const_tree, inchash::hash &, unsigned flags);
+ void hash_operand (const_tree, inchash::hash &, unsigned flags,
+ operand_access_type access);
};
} // ipa_icf_gimple namespace
diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index 8cae076..5bbbec6 100644
--- a/gcc/ipa-icf.c
+++ b/gcc/ipa-icf.c
@@ -66,6 +66,7 @@ along with GCC; see the file COPYING3. If not see
#include "coverage.h"
#include "gimple-pretty-print.h"
#include "data-streamer.h"
+#include "tree-streamer.h"
#include "fold-const.h"
#include "calls.h"
#include "varasm.h"
@@ -78,6 +79,7 @@ along with GCC; see the file COPYING3. If not see
#include "attribs.h"
#include "print-tree.h"
#include "ipa-utils.h"
+#include "tree-ssa-alias-compare.h"
#include "ipa-icf-gimple.h"
#include "fibonacci_heap.h"
#include "ipa-icf.h"
@@ -85,6 +87,7 @@ along with GCC; see the file COPYING3. If not see
#include "dbgcnt.h"
#include "tree-vector-builder.h"
#include "symtab-thunks.h"
+#include "alias.h"
using namespace ipa_icf_gimple;
@@ -226,14 +229,16 @@ hash_map<const_tree, hashval_t> sem_item::m_type_hash_cache;
/* Semantic function constructor that uses STACK as bitmap memory stack. */
sem_function::sem_function (bitmap_obstack *stack)
-: sem_item (FUNC, stack), m_checker (NULL), m_compared_func (NULL)
+ : sem_item (FUNC, stack), memory_access_types (), m_alias_sets_hash (0),
+ m_checker (NULL), m_compared_func (NULL)
{
bb_sizes.create (0);
bb_sorted.create (0);
}
sem_function::sem_function (cgraph_node *node, bitmap_obstack *stack)
-: sem_item (FUNC, node, stack), m_checker (NULL), m_compared_func (NULL)
+ : sem_item (FUNC, node, stack), memory_access_types (),
+ m_alias_sets_hash (0), m_checker (NULL), m_compared_func (NULL)
{
bb_sizes.create (0);
bb_sorted.create (0);
@@ -570,6 +575,7 @@ sem_function::equals_wpa (sem_item *item,
type memory location for ipa-polymorphic-call and we do not want
it to get confused by wrong type. */
if (DECL_CXX_CONSTRUCTOR_P (decl)
+ && opt_for_fn (decl, flag_devirtualize)
&& TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
{
if (TREE_CODE (TREE_TYPE (item->decl)) != METHOD_TYPE)
@@ -843,6 +849,8 @@ sem_function::equals_private (sem_item *item)
m_checker = new func_checker (decl, m_compared_func->decl,
false,
+ opt_for_fn (m_compared_func->decl,
+ flag_strict_aliasing),
&refs_set,
&m_compared_func->refs_set);
arg1 = DECL_ARGUMENTS (decl);
@@ -1419,33 +1427,53 @@ sem_function::hash_stmt (gimple *stmt, inchash::hash &hstate)
{
case GIMPLE_SWITCH:
m_checker->hash_operand (gimple_switch_index (as_a <gswitch *> (stmt)),
- hstate, 0);
+ hstate, 0, func_checker::OP_NORMAL);
break;
case GIMPLE_ASSIGN:
hstate.add_int (gimple_assign_rhs_code (stmt));
- if (commutative_tree_code (gimple_assign_rhs_code (stmt))
- || commutative_ternary_tree_code (gimple_assign_rhs_code (stmt)))
- {
- m_checker->hash_operand (gimple_assign_rhs1 (stmt), hstate, 0);
- m_checker->hash_operand (gimple_assign_rhs2 (stmt), hstate, 0);
- if (commutative_ternary_tree_code (gimple_assign_rhs_code (stmt)))
- m_checker->hash_operand (gimple_assign_rhs3 (stmt), hstate, 0);
- m_checker->hash_operand (gimple_assign_lhs (stmt), hstate, 0);
- }
/* fall through */
case GIMPLE_CALL:
case GIMPLE_ASM:
case GIMPLE_COND:
case GIMPLE_GOTO:
case GIMPLE_RETURN:
- /* All these statements are equivalent if their operands are. */
- for (unsigned i = 0; i < gimple_num_ops (stmt); ++i)
- m_checker->hash_operand (gimple_op (stmt, i), hstate, 0);
- /* Consider nocf_check attribute in hash as it affects code
- generation. */
- if (code == GIMPLE_CALL
- && flag_cf_protection & CF_BRANCH)
- hstate.add_flag (gimple_call_nocf_check_p (as_a <gcall *> (stmt)));
+ {
+ func_checker::operand_access_type_map map (5);
+ func_checker::classify_operands (stmt, &map);
+
+ /* All these statements are equivalent if their operands are. */
+ for (unsigned i = 0; i < gimple_num_ops (stmt); ++i)
+ {
+ func_checker::operand_access_type
+ access_type = func_checker::get_operand_access_type
+ (&map, gimple_op (stmt, i));
+ m_checker->hash_operand (gimple_op (stmt, i), hstate, 0,
+ access_type);
+ /* For memory accesses when hasing for LTO stremaing record
+ base and ref alias ptr types so we can compare them at WPA
+ time without having to read actual function body. */
+ if (access_type == func_checker::OP_MEMORY
+ && lto_streaming_expected_p ()
+ && flag_strict_aliasing)
+ {
+ ao_ref ref;
+
+ ao_ref_init (&ref, gimple_op (stmt, i));
+ tree t = ao_ref_alias_ptr_type (&ref);
+ if (!variably_modified_type_p (t, NULL_TREE))
+ memory_access_types.safe_push (t);
+ t = ao_ref_base_alias_ptr_type (&ref);
+ if (!variably_modified_type_p (t, NULL_TREE))
+ memory_access_types.safe_push (t);
+ }
+ }
+ /* Consider nocf_check attribute in hash as it affects code
+ generation. */
+ if (code == GIMPLE_CALL
+ && flag_cf_protection & CF_BRANCH)
+ hstate.add_flag (gimple_call_nocf_check_p (as_a <gcall *> (stmt)));
+ }
+ break;
default:
break;
}
@@ -1534,7 +1562,8 @@ sem_function::compare_phi_node (basic_block bb1, basic_block bb2)
tree phi_result1 = gimple_phi_result (phi1);
tree phi_result2 = gimple_phi_result (phi2);
- if (!m_checker->compare_operand (phi_result1, phi_result2))
+ if (!m_checker->compare_operand (phi_result1, phi_result2,
+ func_checker::OP_NORMAL))
return return_false_with_msg ("PHI results are different");
size1 = gimple_phi_num_args (phi1);
@@ -1548,7 +1577,7 @@ sem_function::compare_phi_node (basic_block bb1, basic_block bb2)
t1 = gimple_phi_arg (phi1, i)->def;
t2 = gimple_phi_arg (phi2, i)->def;
- if (!m_checker->compare_operand (t1, t2))
+ if (!m_checker->compare_operand (t1, t2, func_checker::OP_NORMAL))
return return_false ();
e1 = gimple_phi_arg_edge (phi1, i);
@@ -2126,6 +2155,14 @@ sem_item_optimizer::write_summary (void)
streamer_write_uhwi_stream (ob->main_stream, node_ref);
streamer_write_uhwi (ob, (*item)->get_hash ());
+
+ if ((*item)->type == FUNC)
+ {
+ sem_function *fn = static_cast<sem_function *> (*item);
+ streamer_write_uhwi (ob, fn->memory_access_types.length ());
+ for (unsigned i = 0; i < fn->memory_access_types.length (); i++)
+ stream_write_tree (ob, fn->memory_access_types[i], true);
+ }
}
}
@@ -2177,6 +2214,18 @@ sem_item_optimizer::read_section (lto_file_decl_data *file_data,
cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
sem_function *fn = new sem_function (cnode, &m_bmstack);
+ unsigned count = streamer_read_uhwi (&ib_main);
+ inchash::hash hstate (0);
+ if (flag_incremental_link == INCREMENTAL_LINK_LTO)
+ fn->memory_access_types.reserve_exact (count);
+ for (unsigned i = 0; i < count; i++)
+ {
+ tree type = stream_read_tree (&ib_main, data_in);
+ hstate.add_int (get_deref_alias_set (type));
+ if (flag_incremental_link == INCREMENTAL_LINK_LTO)
+ fn->memory_access_types.quick_push (type);
+ }
+ fn->m_alias_sets_hash = hstate.end ();
fn->set_hash (hash);
m_items.safe_push (fn);
}
@@ -2373,6 +2422,7 @@ sem_item_optimizer::execute (void)
build_graph ();
update_hash_by_addr_refs ();
+ update_hash_by_memory_access_type ();
build_hash_based_classes ();
if (dump_file)
@@ -2487,11 +2537,24 @@ sem_item_optimizer::update_hash_by_addr_refs ()
= TYPE_METHOD_BASETYPE (TREE_TYPE (m_items[i]->decl));
inchash::hash hstate (m_items[i]->get_hash ());
+ /* Hash ODR types by mangled name if it is defined.
+ If not we know that type is anonymous of free_lang_data
+ was not run and in that case type main variants are
+ unique. */
if (TYPE_NAME (class_type)
- && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (class_type)))
+ && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (class_type))
+ && !type_in_anonymous_namespace_p
+ (class_type))
hstate.add_hwi
(IDENTIFIER_HASH_VALUE
(DECL_ASSEMBLER_NAME (TYPE_NAME (class_type))));
+ else
+ {
+ gcc_checking_assert
+ (!in_lto_p
+ || type_in_anonymous_namespace_p (class_type));
+ hstate.add_hwi (TYPE_UID (TYPE_MAIN_VARIANT (class_type)));
+ }
m_items[i]->set_hash (hstate.end ());
}
@@ -2510,6 +2573,21 @@ sem_item_optimizer::update_hash_by_addr_refs ()
m_items[i]->set_hash (m_items[i]->global_hash);
}
+void
+sem_item_optimizer::update_hash_by_memory_access_type ()
+{
+ for (unsigned i = 0; i < m_items.length (); i++)
+ {
+ if (m_items[i]->type == FUNC)
+ {
+ sem_function *fn = static_cast<sem_function *> (m_items[i]);
+ inchash::hash hstate (fn->get_hash ());
+ hstate.add_int (fn->m_alias_sets_hash);
+ fn->set_hash (hstate.end ());
+ }
+ }
+}
+
/* Congruence classes are built by hash value. */
void
diff --git a/gcc/ipa-icf.h b/gcc/ipa-icf.h
index 6dc1a13..3e0e724 100644
--- a/gcc/ipa-icf.h
+++ b/gcc/ipa-icf.h
@@ -371,12 +371,19 @@ public:
/* GIMPLE codes hash value. */
hashval_t gcode_hash;
+ /* Vector of subpart of memory access types. */
+ vec<tree> memory_access_types;
+
/* Total number of SSA names used in the function. */
unsigned ssa_names_size;
/* Array of structures for all basic blocks. */
vec <ipa_icf_gimple::sem_bb *> bb_sorted;
+ /* Hash of canonical types used for memory references in the
+ function. */
+ hashval_t m_alias_sets_hash;
+
/* Return true if parameter I may be used. */
bool param_used_p (unsigned int i);
@@ -541,6 +548,9 @@ private:
/* For each semantic item, append hash values of references. */
void update_hash_by_addr_refs ();
+ /* Update hash by canonical types of memory accesses. */
+ void update_hash_by_memory_access_type ();
+
/* Congruence classes are built by hash value. */
void build_hash_based_classes (void);
diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
index 3f46beb..388b229 100644
--- a/gcc/ipa-modref.c
+++ b/gcc/ipa-modref.c
@@ -20,8 +20,7 @@ along with GCC; see the file COPYING3. If not see
/* Mod/ref pass records summary about loads and stores performed by the
function. This is later used by alias analysis to disambiguate memory
- accesses across function calls. The summary has a form of decision tree
- described in ipa-modref-tree.h.
+ accesses across function calls.
This file contains a tree pass and an IPA pass. Both performs the same
analysis however tree pass is executed during early and late optimization
@@ -32,8 +31,27 @@ along with GCC; see the file COPYING3. If not see
LTO mode differs from the local mode by not recording alias sets but types
that are translated to alias sets later. This is necessary in order stream
the information because the alias sets are rebuild at stream-in time and may
- not correspond to ones seen during analysis. For this reason part of analysis
- is duplicated. */
+ not correspond to ones seen during analysis. For this reason part of
+ analysis is duplicated.
+
+ The following information is computed
+ 1) load/store access tree described in ipa-modref-tree.h
+ This is used by tree-ssa-alias to disambiguate load/dtores
+ 2) EAF flags used by points-to analysis (in tree-ssa-structlias).
+ and defined in tree-core.h.
+ and stored to optimization_summaries.
+
+ There are multiple summaries computed and used during the propagation:
+ - summaries holds summaries from analysis to IPA propagation
+ time.
+ - summaries_lto is same as summaries but holds them in a format
+ that can be streamed (as described above).
+ - fnspec_summary holds fnspec strings for call. This is
+ necessary because gimple_call_fnspec performs additional
+ analysis except for looking callee fndecl.
+ - escape_summary holds escape points for given call edge.
+ That is a vector recording what function parmaeters
+ may escape to a function call (and with what parameter index). */
#include "config.h"
#include "system.h"
@@ -61,6 +79,14 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-fnsummary.h"
#include "attr-fnspec.h"
#include "symtab-clones.h"
+#include "gimple-ssa.h"
+#include "tree-phinodes.h"
+#include "tree-ssa-operands.h"
+#include "ssa-iterators.h"
+#include "stringpool.h"
+#include "tree-ssanames.h"
+
+namespace {
/* We record fnspec specifiers for call edges since they depends on actual
gimple statements. */
@@ -100,6 +126,76 @@ public:
static fnspec_summaries_t *fnspec_summaries = NULL;
+/* Escape summary holds a vector of param indexes that escape to
+ a given call. */
+struct escape_entry
+{
+ /* Parameter that escapes at a given call. */
+ unsigned int parm_index;
+ /* Argument it escapes to. */
+ unsigned int arg;
+ /* Minimal flags known about the argument. */
+ char min_flags;
+ /* Does it escape directly or indirectly? */
+ bool direct;
+};
+
+/* Dump EAF flags. */
+
+static void
+dump_eaf_flags (FILE *out, int flags, bool newline = true)
+{
+ if (flags & EAF_DIRECT)
+ fprintf (out, " direct");
+ if (flags & EAF_NOCLOBBER)
+ fprintf (out, " noclobber");
+ if (flags & EAF_NOESCAPE)
+ fprintf (out, " noescape");
+ if (flags & EAF_NODIRECTESCAPE)
+ fprintf (out, " nodirectescape");
+ if (flags & EAF_UNUSED)
+ fprintf (out, " unused");
+ if (newline)
+ fprintf (out, "\n");
+}
+
+struct escape_summary
+{
+ auto_vec <escape_entry> esc;
+ void dump (FILE *out)
+ {
+ for (unsigned int i = 0; i < esc.length (); i++)
+ {
+ fprintf (out, " parm %i arg %i %s min:",
+ esc[i].parm_index,
+ esc[i].arg,
+ esc[i].direct ? "(direct)" : "(indirect)");
+ dump_eaf_flags (out, esc[i].min_flags, false);
+ }
+ fprintf (out, "\n");
+ }
+};
+
+class escape_summaries_t : public call_summary <escape_summary *>
+{
+public:
+ escape_summaries_t (symbol_table *symtab)
+ : call_summary <escape_summary *> (symtab) {}
+ /* Hook that is called by summary when an edge is duplicated. */
+ virtual void duplicate (cgraph_edge *,
+ cgraph_edge *,
+ escape_summary *src,
+ escape_summary *dst)
+ {
+ dst->esc = src->esc.copy ();
+ }
+};
+
+static escape_summaries_t *escape_summaries = NULL;
+
+} /* ANON namespace: GTY annotated summaries can not be anonymous. */
+
+
/* Class (from which there is one global instance) that holds modref summaries
for all analyzed functions. */
@@ -179,13 +275,38 @@ modref_summary::~modref_summary ()
ggc_delete (stores);
}
-/* Return true if summary is potentially useful for optimization. */
+/* Return true if FLAGS holds some useful information. */
+
+static bool
+eaf_flags_useful_p (vec <unsigned char> &flags, int ecf_flags)
+{
+ for (unsigned i = 0; i < flags.length (); i++)
+ if (ecf_flags & ECF_PURE)
+ {
+ if (flags[i] & (EAF_UNUSED | EAF_DIRECT))
+ return true;
+ }
+ else
+ {
+ if (flags[i])
+ return true;
+ }
+ return false;
+}
+
+/* Return true if summary is potentially useful for optimization.
+ If CHECK_FLAGS is false assume that arg_flags are useful. */
bool
-modref_summary::useful_p (int ecf_flags)
+modref_summary::useful_p (int ecf_flags, bool check_flags)
{
if (ecf_flags & (ECF_CONST | ECF_NOVOPS))
return false;
+ if (arg_flags.length () && !check_flags)
+ return true;
+ if (check_flags && eaf_flags_useful_p (arg_flags, ecf_flags))
+ return true;
+ arg_flags.release ();
if (loads && !loads->every_base)
return true;
if (ecf_flags & ECF_PURE)
@@ -204,12 +325,13 @@ struct GTY(()) modref_summary_lto
more verbose and thus more likely to hit the limits. */
modref_records_lto *loads;
modref_records_lto *stores;
+ auto_vec<unsigned char> GTY((skip)) arg_flags;
bool writes_errno;
modref_summary_lto ();
~modref_summary_lto ();
void dump (FILE *);
- bool useful_p (int ecf_flags);
+ bool useful_p (int ecf_flags, bool check_flags = true);
};
/* Summary for a single function which this pass produces. */
@@ -228,13 +350,19 @@ modref_summary_lto::~modref_summary_lto ()
}
-/* Return true if lto summary is potentially useful for optimization. */
+/* Return true if lto summary is potentially useful for optimization.
+ If CHECK_FLAGS is false assume that arg_flags are useful. */
bool
-modref_summary_lto::useful_p (int ecf_flags)
+modref_summary_lto::useful_p (int ecf_flags, bool check_flags)
{
if (ecf_flags & (ECF_CONST | ECF_NOVOPS))
return false;
+ if (arg_flags.length () && !check_flags)
+ return true;
+ if (check_flags && eaf_flags_useful_p (arg_flags, ecf_flags))
+ return true;
+ arg_flags.release ();
if (loads && !loads->every_base)
return true;
if (ecf_flags & ECF_PURE)
@@ -355,6 +483,64 @@ dump_lto_records (modref_records_lto *tt, FILE *out)
}
}
+/* Dump all escape points of NODE to OUT. */
+
+static void
+dump_modref_edge_summaries (FILE *out, cgraph_node *node, int depth)
+{
+ int i = 0;
+ if (!escape_summaries)
+ return;
+ for (cgraph_edge *e = node->indirect_calls; e; e = e->next_callee)
+ {
+ class escape_summary *sum = escape_summaries->get (e);
+ if (sum)
+ {
+ fprintf (out, "%*sIndirect call %i in %s escapes:",
+ depth, "", i, node->dump_name ());
+ sum->dump (out);
+ }
+ i++;
+ }
+ for (cgraph_edge *e = node->callees; e; e = e->next_callee)
+ {
+ if (!e->inline_failed)
+ dump_modref_edge_summaries (out, e->callee, depth + 1);
+ class escape_summary *sum = escape_summaries->get (e);
+ if (sum)
+ {
+ fprintf (out, "%*sCall %s->%s escapes:", depth, "",
+ node->dump_name (), e->callee->dump_name ());
+ sum->dump (out);
+ }
+ class fnspec_summary *fsum = fnspec_summaries->get (e);
+ if (fsum)
+ {
+ fprintf (out, "%*sCall %s->%s fnspec: %s\n", depth, "",
+ node->dump_name (), e->callee->dump_name (),
+ fsum->fnspec);
+ }
+ }
+}
+
+/* Remove all call edge summaries associated with NODE. */
+
+static void
+remove_modref_edge_summaries (cgraph_node *node)
+{
+ if (!escape_summaries)
+ return;
+ for (cgraph_edge *e = node->indirect_calls; e; e = e->next_callee)
+ escape_summaries->remove (e);
+ for (cgraph_edge *e = node->callees; e; e = e->next_callee)
+ {
+ if (!e->inline_failed)
+ remove_modref_edge_summaries (e->callee);
+ escape_summaries->remove (e);
+ fnspec_summaries->remove (e);
+ }
+}
+
/* Dump summary. */
void
@@ -372,6 +558,15 @@ modref_summary::dump (FILE *out)
}
if (writes_errno)
fprintf (out, " Writes errno\n");
+ if (arg_flags.length ())
+ {
+ for (unsigned int i = 0; i < arg_flags.length (); i++)
+ if (arg_flags[i])
+ {
+ fprintf (out, " parm %i flags:", i);
+ dump_eaf_flags (out, arg_flags[i]);
+ }
+ }
}
/* Dump summary. */
@@ -385,6 +580,15 @@ modref_summary_lto::dump (FILE *out)
dump_lto_records (stores, out);
if (writes_errno)
fprintf (out, " Writes errno\n");
+ if (arg_flags.length ())
+ {
+ for (unsigned int i = 0; i < arg_flags.length (); i++)
+ if (arg_flags[i])
+ {
+ fprintf (out, " parm %i flags:", i);
+ dump_eaf_flags (out, arg_flags[i]);
+ }
+ }
}
/* Get function summary for FUNC if it exists, return NULL otherwise. */
@@ -402,7 +606,8 @@ get_modref_function_summary (cgraph_node *func)
function. */
enum availability avail;
func = func->function_or_virtual_thunk_symbol
- (&avail, cgraph_node::get (current_function_decl));
+ (&avail, current_function_decl ?
+ cgraph_node::get (current_function_decl) : NULL);
if (avail <= AVAIL_INTERPOSABLE)
return NULL;
@@ -554,12 +759,23 @@ record_access_p (tree expr)
return true;
}
+/* Return true if ECF flags says that return value can be ignored. */
+
+static bool
+ignore_retval_p (tree caller, int flags)
+{
+ if ((flags & (ECF_NORETURN | ECF_NOTHROW)) == (ECF_NORETURN | ECF_NOTHROW)
+ || (!opt_for_fn (caller, flag_exceptions) && (flags & ECF_NORETURN)))
+ return true;
+ return false;
+}
+
/* Return true if ECF flags says that stores can be ignored. */
static bool
ignore_stores_p (tree caller, int flags)
{
- if (flags & ECF_PURE)
+ if (flags & (ECF_PURE | ECF_CONST | ECF_NOVOPS))
return true;
if ((flags & (ECF_NORETURN | ECF_NOTHROW)) == (ECF_NORETURN | ECF_NOTHROW)
|| (!opt_for_fn (caller, flag_exceptions) && (flags & ECF_NORETURN)))
@@ -634,7 +850,7 @@ merge_call_side_effects (modref_summary *cur_summary,
cur_summary->loads->collapse ();
}
- parm_map.safe_grow_cleared (gimple_call_num_args (stmt));
+ parm_map.safe_grow_cleared (gimple_call_num_args (stmt), true);
for (unsigned i = 0; i < gimple_call_num_args (stmt); i++)
{
parm_map[i] = parm_map_for_arg (stmt, i);
@@ -1061,12 +1277,623 @@ remove_summary (bool lto, bool nolto, bool ipa)
summaries->remove (fnode);
if (lto)
summaries_lto->remove (fnode);
+ remove_modref_edge_summaries (fnode);
}
if (dump_file)
fprintf (dump_file,
" - modref done with result: not tracked.\n");
}
+/* Return true if OP accesses memory pointed to by SSA_NAME. */
+
+bool
+memory_access_to (tree op, tree ssa_name)
+{
+ tree base = get_base_address (op);
+ if (!base)
+ return false;
+ if (TREE_CODE (base) != MEM_REF && TREE_CODE (base) != TARGET_MEM_REF)
+ return false;
+ return TREE_OPERAND (base, 0) == ssa_name;
+}
+
+/* Consider statement val = *arg.
+ return EAF flags of ARG that can be determined from EAF flags of VAL
+ (which are known to be FLAGS). If IGNORE_STORES is true we can ignore
+ all stores to VAL, i.e. when handling noreturn function. */
+
+static int
+deref_flags (int flags, bool ignore_stores)
+{
+ int ret = EAF_NODIRECTESCAPE;
+ if (flags & EAF_UNUSED)
+ ret |= EAF_DIRECT | EAF_NOCLOBBER | EAF_NOESCAPE;
+ else
+ {
+ if ((flags & EAF_NOCLOBBER) || ignore_stores)
+ ret |= EAF_NOCLOBBER;
+ if ((flags & EAF_NOESCAPE) || ignore_stores)
+ ret |= EAF_NOESCAPE;
+ }
+ return ret;
+}
+
+namespace {
+
+/* Description of an escape point. */
+
+struct escape_point
+{
+ /* Value escapes to this call. */
+ gcall *call;
+ /* Argument it escapes to. */
+ int arg;
+ /* Flags already known about the argument (this can save us from recording
+ esape points if local analysis did good job already). */
+ char min_flags;
+ /* Does value escape directly or indiretly? */
+ bool direct;
+};
+
+class modref_lattice
+{
+public:
+ /* EAF flags of the SSA name. */
+ int flags;
+ /* DFS bookkkeeping: we don't do real dataflow yet. */
+ bool known;
+ bool open;
+
+ /* When doing IPA analysis we can not merge in callee escape points;
+ Only remember them and do the merging at IPA propagation time. */
+ vec <escape_point, va_heap, vl_ptr> escape_points;
+
+ void init ();
+ void release ();
+ bool merge (const modref_lattice &with);
+ bool merge (int flags);
+ bool merge_deref (const modref_lattice &with, bool ignore_stores);
+ bool merge_direct_load ();
+ bool merge_direct_store ();
+ bool add_escape_point (gcall *call, int arg, int min_flags, bool diret);
+ void dump (FILE *out, int indent = 0) const;
+};
+
+/* Lattices are saved to vectors, so keep them PODs. */
+void
+modref_lattice::init ()
+{
+ flags = EAF_DIRECT | EAF_NOCLOBBER | EAF_NOESCAPE | EAF_UNUSED
+ | EAF_NODIRECTESCAPE;
+ open = true;
+ known = false;
+}
+
+/* Release memory. */
+void
+modref_lattice::release ()
+{
+ escape_points.release ();
+}
+
+/* Dump lattice to OUT; indent with INDENT spaces. */
+
+void
+modref_lattice::dump (FILE *out, int indent) const
+{
+ dump_eaf_flags (out, flags);
+ if (escape_points.length ())
+ {
+ fprintf (out, "%*sEscapes:\n", indent, "");
+ for (unsigned int i = 0; i < escape_points.length (); i++)
+ {
+ fprintf (out, "%*s Arg %i (%s) min flags", indent, "",
+ escape_points[i].arg,
+ escape_points[i].direct ? "direct" : "indirect");
+ dump_eaf_flags (out, flags, false);
+ fprintf (out, " in call ");
+ print_gimple_stmt (out, escape_points[i].call, 0);
+ }
+ }
+}
+
+/* Add escape point CALL, ARG, MIN_FLAGS, DIRECT. Return false if such escape
+ point exists. */
+
+bool
+modref_lattice::add_escape_point (gcall *call, int arg, int min_flags,
+ bool direct)
+{
+ escape_point *ep;
+ unsigned int i;
+
+ /* If we already determined flags to be bad enough,
+ * we do not need to record. */
+ if ((flags & min_flags) == flags)
+ return false;
+
+ FOR_EACH_VEC_ELT (escape_points, i, ep)
+ if (ep->call == call && ep->arg == arg && ep->direct == direct)
+ {
+ if ((ep->min_flags & min_flags) == min_flags)
+ return false;
+ ep->min_flags &= min_flags;
+ return true;
+ }
+ /* Give up if max escape points is met. */
+ if ((int)escape_points.length () > param_modref_max_escape_points)
+ {
+ if (dump_file)
+ fprintf (dump_file, "--param modref-max-escape-points limit reached\n");
+ merge (0);
+ return true;
+ }
+ escape_point new_ep = {call, arg, min_flags, direct};
+ escape_points.safe_push (new_ep);
+ return true;
+}
+
+/* Merge in flags from F. */
+bool
+modref_lattice::merge (int f)
+{
+ if (f & EAF_UNUSED)
+ return false;
+ if ((flags & f) != flags)
+ {
+ flags &= f;
+ /* Only NOCLOBBER or DIRECT flags alone are not useful (see comments
+ in tree-ssa-alias.c). Give up earlier. */
+ if ((flags & ~(EAF_DIRECT | EAF_NOCLOBBER)) == 0)
+ flags = 0;
+ if (!flags)
+ escape_points.release ();
+ return true;
+ }
+ return false;
+}
+
+/* Merge in WITH. Return true if anyting changed. */
+
+bool
+modref_lattice::merge (const modref_lattice &with)
+{
+ if (!with.known)
+ return merge (0);
+
+ bool changed = merge (with.flags);
+
+ if (!flags)
+ return changed;
+ for (unsigned int i = 0; i < with.escape_points.length (); i++)
+ changed |= add_escape_point (with.escape_points[i].call,
+ with.escape_points[i].arg,
+ with.escape_points[i].min_flags,
+ with.escape_points[i].direct);
+ return changed;
+}
+
+/* Merge in deref of WITH. If IGNORE_STORES is true do not consider
+ stores. Return true if anyting changed. */
+
+bool
+modref_lattice::merge_deref (const modref_lattice &with, bool ignore_stores)
+{
+ if (!with.known)
+ return merge (0);
+
+ bool changed = merge (deref_flags (with.flags, ignore_stores));
+
+ if (!flags)
+ return changed;
+ for (unsigned int i = 0; i < with.escape_points.length (); i++)
+ changed |= add_escape_point (with.escape_points[i].call,
+ with.escape_points[i].arg,
+ with.escape_points[i].min_flags,
+ false);
+ return changed;
+}
+
+/* Merge in flags for direct load. */
+
+bool
+modref_lattice::merge_direct_load ()
+{
+ return merge (~EAF_UNUSED);
+}
+
+/* Merge in flags for direct store. */
+
+bool
+modref_lattice::merge_direct_store ()
+{
+ return merge (~(EAF_UNUSED | EAF_NOCLOBBER));
+}
+
+} /* ANON namespace. */
+
+static void analyze_ssa_name_flags (tree name,
+ vec<modref_lattice> &lattice,
+ int depth, bool ipa);
+
+/* Call statements may return their parameters. Consider argument number
+ ARG of USE_STMT and determine flags that can needs to be cleared
+ in case pointer possibly indirectly references from ARG I is returned.
+ LATTICE, DEPTH and ipa are same as in analyze_ssa_name_flags. */
+
+static void
+merge_call_lhs_flags (gcall *call, int arg, int index, bool deref,
+ vec<modref_lattice> &lattice,
+ int depth, bool ipa)
+{
+ /* If there is no return value, no flags are affected. */
+ if (!gimple_call_lhs (call))
+ return;
+
+ /* If we know that function returns given argument and it is not ARG
+ we can still be happy. */
+ int flags = gimple_call_return_flags (call);
+ if ((flags & ERF_RETURNS_ARG)
+ && (flags & ERF_RETURN_ARG_MASK) != arg)
+ return;
+
+ /* If return value is SSA name determine its flags. */
+ if (TREE_CODE (gimple_call_lhs (call)) == SSA_NAME)
+ {
+ tree lhs = gimple_call_lhs (call);
+ analyze_ssa_name_flags (lhs, lattice, depth + 1, ipa);
+ if (deref)
+ lattice[index].merge (lattice[SSA_NAME_VERSION (lhs)]);
+ else
+ lattice[index].merge_deref (lattice[SSA_NAME_VERSION (lhs)], false);
+ }
+ /* In the case of memory store we can do nothing. */
+ else
+ lattice[index].merge (0);
+}
+
+/* Analyze EAF flags for SSA name NAME and store result to LATTICE.
+ LATTICE is an array of modref_lattices.
+ DEPTH is a recursion depth used to make debug output prettier.
+ If IPA is true we analyze for IPA propagation (and thus call escape points
+ are processed later) */
+
+static void
+analyze_ssa_name_flags (tree name, vec<modref_lattice> &lattice, int depth,
+ bool ipa)
+{
+ imm_use_iterator ui;
+ gimple *use_stmt;
+ int index = SSA_NAME_VERSION (name);
+
+ /* See if value is already computed. */
+ if (lattice[index].known)
+ return;
+ if (lattice[index].open)
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "%*sGiving up on a cycle in SSA graph\n", depth * 4, "");
+ return;
+ }
+ if (depth == param_modref_max_depth)
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "%*sGiving up on max depth\n", depth * 4, "");
+ return;
+ }
+ /* Recursion guard. */
+ lattice[index].init ();
+
+ if (dump_file)
+ {
+ fprintf (dump_file,
+ "%*sAnalyzing flags of ssa name: ", depth * 4, "");
+ print_generic_expr (dump_file, name);
+ fprintf (dump_file, "\n");
+ }
+
+ FOR_EACH_IMM_USE_STMT (use_stmt, ui, name)
+ {
+ if (lattice[index].flags == 0)
+ {
+ BREAK_FROM_IMM_USE_STMT (ui);
+ }
+ if (is_gimple_debug (use_stmt))
+ continue;
+ if (dump_file)
+ {
+ fprintf (dump_file, "%*s Analyzing stmt:", depth * 4, "");
+ print_gimple_stmt (dump_file, use_stmt, 0);
+ }
+
+ /* Gimple return may load the return value.
+ Returning name counts as an use by tree-ssa-structalias.c */
+ if (greturn *ret = dyn_cast <greturn *> (use_stmt))
+ {
+ if (gimple_return_retval (ret) == name)
+ lattice[index].merge (~EAF_UNUSED);
+ else if (memory_access_to (gimple_return_retval (ret), name))
+ lattice[index].merge_direct_load ();
+ }
+ /* Account for LHS store, arg loads and flags from callee function. */
+ else if (gcall *call = dyn_cast <gcall *> (use_stmt))
+ {
+ tree callee = gimple_call_fndecl (call);
+
+ /* Recursion would require bit of propagation; give up for now. */
+ if (callee && !ipa && recursive_call_p (current_function_decl,
+ callee))
+ lattice[index].merge (0);
+ else
+ {
+ int ecf_flags = gimple_call_flags (call);
+ bool ignore_stores = ignore_stores_p (current_function_decl,
+ ecf_flags);
+ bool ignore_retval = ignore_retval_p (current_function_decl,
+ ecf_flags);
+
+ /* Handle *name = func (...). */
+ if (gimple_call_lhs (call)
+ && memory_access_to (gimple_call_lhs (call), name))
+ lattice[index].merge_direct_store ();
+
+ /* We do not track accesses to the static chain (we could)
+ so give up. */
+ if (gimple_call_chain (call)
+ && (gimple_call_chain (call) == name))
+ lattice[index].merge (0);
+
+ /* Process internal functions and right away. */
+ bool record_ipa = ipa && !gimple_call_internal_p (call);
+
+ /* Handle all function parameters. */
+ for (unsigned i = 0;
+ i < gimple_call_num_args (call) && lattice[index].flags; i++)
+ /* Name is directly passed to the callee. */
+ if (gimple_call_arg (call, i) == name)
+ {
+ if (!(ecf_flags & (ECF_CONST | ECF_NOVOPS)))
+ {
+ int call_flags = gimple_call_arg_flags (call, i);
+ if (ignore_stores)
+ call_flags |= EAF_NOCLOBBER | EAF_NOESCAPE
+ | EAF_NODIRECTESCAPE;
+
+ if (!record_ipa)
+ lattice[index].merge (call_flags);
+ if (record_ipa)
+ lattice[index].add_escape_point (call, i,
+ call_flags, true);
+ }
+ if (!ignore_retval)
+ merge_call_lhs_flags (call, i, index, false,
+ lattice, depth, ipa);
+ }
+ /* Name is dereferenced and passed to a callee. */
+ else if (memory_access_to (gimple_call_arg (call, i), name))
+ {
+ if (ecf_flags & (ECF_CONST | ECF_NOVOPS))
+ lattice[index].merge_direct_load ();
+ else
+ {
+ int call_flags = deref_flags
+ (gimple_call_arg_flags (call, i), ignore_stores);
+ if (!record_ipa)
+ lattice[index].merge (call_flags);
+ if (record_ipa)
+ lattice[index].add_escape_point (call, i,
+ call_flags, false);
+ }
+ if (!ignore_retval)
+ merge_call_lhs_flags (call, i, index, true,
+ lattice, depth, ipa);
+ }
+ }
+ }
+ else if (gimple_assign_load_p (use_stmt))
+ {
+ gassign *assign = as_a <gassign *> (use_stmt);
+ /* Memory to memory copy. */
+ if (gimple_store_p (assign))
+ {
+ /* Handle *lhs = *name.
+
+ We do not track memory locations, so assume that value
+ is used arbitrarily. */
+ if (memory_access_to (gimple_assign_rhs1 (assign), name))
+ lattice[index].merge (0);
+ /* Handle *name = *exp. */
+ else if (memory_access_to (gimple_assign_lhs (assign), name))
+ lattice[index].merge_direct_store ();
+ }
+ /* Handle lhs = *name. */
+ else if (memory_access_to (gimple_assign_rhs1 (assign), name))
+ {
+ tree lhs = gimple_assign_lhs (assign);
+ analyze_ssa_name_flags (lhs, lattice, depth + 1, ipa);
+ lattice[index].merge_deref (lattice[SSA_NAME_VERSION (lhs)],
+ false);
+ }
+ }
+ else if (gimple_store_p (use_stmt))
+ {
+ gassign *assign = dyn_cast <gassign *> (use_stmt);
+
+ /* Handle *lhs = name. */
+ if (assign && gimple_assign_rhs1 (assign) == name)
+ {
+ if (dump_file)
+ fprintf (dump_file, "%*s ssa name saved to memory\n",
+ depth * 4, "");
+ lattice[index].merge (0);
+ }
+ /* Handle *name = exp. */
+ else if (assign
+ && memory_access_to (gimple_assign_lhs (assign), name))
+ {
+ /* In general we can not ignore clobbers because they are
+ barriers for code motion, however after inlining it is safe to
+ do because local optimization passes do not consider clobbers
+ from other functions. Similar logic is in ipa-pure-const.c. */
+ if (!cfun->after_inlining || !gimple_clobber_p (assign))
+ lattice[index].merge_direct_store ();
+ }
+ /* ASM statements etc. */
+ else if (!assign)
+ {
+ if (dump_file)
+ fprintf (dump_file, "%*s Unhandled store\n",
+ depth * 4, "");
+ lattice[index].merge (0);
+ }
+ }
+ else if (gassign *assign = dyn_cast <gassign *> (use_stmt))
+ {
+ enum tree_code code = gimple_assign_rhs_code (assign);
+
+ /* See if operation is a merge as considered by
+ tree-ssa-structalias.c:find_func_aliases. */
+ if (!truth_value_p (code)
+ && code != POINTER_DIFF_EXPR
+ && (code != POINTER_PLUS_EXPR
+ || gimple_assign_rhs1 (assign) == name))
+ {
+ tree lhs = gimple_assign_lhs (assign);
+ analyze_ssa_name_flags (lhs, lattice, depth + 1, ipa);
+ lattice[index].merge (lattice[SSA_NAME_VERSION (lhs)]);
+ }
+ }
+ else if (gphi *phi = dyn_cast <gphi *> (use_stmt))
+ {
+ tree result = gimple_phi_result (phi);
+ analyze_ssa_name_flags (result, lattice, depth + 1, ipa);
+ lattice[index].merge (lattice[SSA_NAME_VERSION (result)]);
+ }
+ /* Conditions are not considered escape points
+ by tree-ssa-structalias. */
+ else if (gimple_code (use_stmt) == GIMPLE_COND)
+ ;
+ else
+ {
+ if (dump_file)
+ fprintf (dump_file, "%*s Unhandled stmt\n", depth * 4, "");
+ lattice[index].merge (0);
+ }
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "%*s current flags of ", depth * 4, "");
+ print_generic_expr (dump_file, name);
+ lattice[index].dump (dump_file, depth * 4 + 4);
+ }
+ }
+ if (dump_file)
+ {
+ fprintf (dump_file, "%*sflags of ssa name ", depth * 4, "");
+ print_generic_expr (dump_file, name);
+ lattice[index].dump (dump_file, depth * 4 + 2);
+ }
+ lattice[index].open = false;
+ lattice[index].known = true;
+}
+
+/* Determine EAF flags for function parameters. */
+
+static void
+analyze_parms (modref_summary *summary, modref_summary_lto *summary_lto,
+ bool ipa)
+{
+ unsigned int parm_index = 0;
+ unsigned int count = 0;
+ int ecf_flags = flags_from_decl_or_type (current_function_decl);
+
+ /* For const functions we have nothing to gain by EAF flags. */
+ if (ecf_flags & (ECF_CONST | ECF_NOVOPS))
+ return;
+
+ for (tree parm = DECL_ARGUMENTS (current_function_decl); parm;
+ parm = TREE_CHAIN (parm))
+ count++;
+
+ if (!count)
+ return;
+
+ auto_vec<modref_lattice> lattice;
+ lattice.safe_grow_cleared (num_ssa_names, true);
+
+ for (tree parm = DECL_ARGUMENTS (current_function_decl); parm; parm_index++,
+ parm = TREE_CHAIN (parm))
+ {
+ tree name = ssa_default_def (cfun, parm);
+ if (!name || has_zero_uses (name))
+ {
+ /* We do not track non-SSA parameters,
+ but we want to track unused gimple_regs. */
+ if (!is_gimple_reg (parm))
+ continue;
+ if (summary)
+ {
+ if (parm_index >= summary->arg_flags.length ())
+ summary->arg_flags.safe_grow_cleared (count, true);
+ summary->arg_flags[parm_index] = EAF_UNUSED;
+ }
+ else if (summary_lto)
+ {
+ if (parm_index >= summary_lto->arg_flags.length ())
+ summary_lto->arg_flags.safe_grow_cleared (count, true);
+ summary_lto->arg_flags[parm_index] = EAF_UNUSED;
+ }
+ continue;
+ }
+ analyze_ssa_name_flags (name, lattice, 0, ipa);
+ int flags = lattice[SSA_NAME_VERSION (name)].flags;
+
+ /* For pure functions we have implicit NOCLOBBER
+ and NOESCAPE. */
+ if (ecf_flags & ECF_PURE)
+ flags &= ~(EAF_NOCLOBBER | EAF_NOESCAPE | EAF_NODIRECTESCAPE);
+
+ if (flags)
+ {
+ if (summary)
+ {
+ if (parm_index >= summary->arg_flags.length ())
+ summary->arg_flags.safe_grow_cleared (count, true);
+ summary->arg_flags[parm_index] = flags;
+ }
+ else if (summary_lto)
+ {
+ if (parm_index >= summary_lto->arg_flags.length ())
+ summary_lto->arg_flags.safe_grow_cleared (count, true);
+ summary_lto->arg_flags[parm_index] = flags;
+ }
+ if (lattice[SSA_NAME_VERSION (name)].escape_points.length ())
+ {
+ escape_point *ep;
+ unsigned int ip;
+ cgraph_node *node = cgraph_node::get (current_function_decl);
+
+ gcc_checking_assert (ipa);
+ FOR_EACH_VEC_ELT
+ (lattice[SSA_NAME_VERSION (name)].escape_points, ip, ep)
+ if ((ep->min_flags & flags) != flags)
+ {
+ cgraph_edge *e = node->get_edge (ep->call);
+ struct escape_entry ee = {parm_index, ep->arg,
+ ep->min_flags, ep->direct};
+
+ escape_summaries->get_create (e)->esc.safe_push (ee);
+ }
+ }
+ }
+ }
+ if (ipa)
+ for (unsigned int i = 0; i < num_ssa_names; i++)
+ lattice[i].release ();
+}
+
/* Analyze function F. IPA indicates whether we're running in local mode
(false) or the IPA mode (true). */
@@ -1142,6 +1969,8 @@ analyze_function (function *f, bool ipa)
}
if (!fnspec_summaries)
fnspec_summaries = new fnspec_summaries_t (symtab);
+ if (!escape_summaries)
+ escape_summaries = new escape_summaries_t (symtab);
}
@@ -1174,6 +2003,9 @@ analyze_function (function *f, bool ipa)
param_modref_max_accesses);
summary_lto->writes_errno = false;
}
+
+ analyze_parms (summary, summary_lto, ipa);
+
int ecf_flags = flags_from_decl_or_type (current_function_decl);
auto_vec <gimple *, 32> recursive_calls;
@@ -1188,11 +2020,13 @@ analyze_function (function *f, bool ipa)
{
if (!analyze_stmt (summary, summary_lto,
gsi_stmt (si), ipa, &recursive_calls)
- || ((!summary || !summary->useful_p (ecf_flags))
- && (!summary_lto || !summary_lto->useful_p (ecf_flags))))
+ || ((!summary || !summary->useful_p (ecf_flags, false))
+ && (!summary_lto
+ || !summary_lto->useful_p (ecf_flags, false))))
{
- remove_summary (lto, nolto, ipa);
- return;
+ collapse_loads (summary, summary_lto);
+ collapse_stores (summary, summary_lto);
+ break;
}
}
}
@@ -1213,7 +2047,7 @@ analyze_function (function *f, bool ipa)
gimple_call_flags
(recursive_calls[i])),
fnode);
- if (!summary->useful_p (ecf_flags))
+ if (!summary->useful_p (ecf_flags, false))
{
remove_summary (lto, nolto, ipa);
return;
@@ -1234,6 +2068,8 @@ analyze_function (function *f, bool ipa)
summaries_lto->remove (fnode);
summary_lto = NULL;
}
+ if (ipa && !summary && !summary_lto)
+ remove_modref_edge_summaries (fnode);
if (dump_file)
{
@@ -1242,6 +2078,7 @@ analyze_function (function *f, bool ipa)
summary->dump (dump_file);
if (summary_lto)
summary_lto->dump (dump_file);
+ dump_modref_edge_summaries (dump_file, fnode, 2);
}
}
@@ -1273,7 +2110,8 @@ modref_summaries::insert (struct cgraph_node *node, modref_summary *)
optimization_summaries->remove (node);
return;
}
- if (!DECL_STRUCT_FUNCTION (node->decl))
+ if (!DECL_STRUCT_FUNCTION (node->decl)
+ || !opt_for_fn (node->decl, flag_ipa_modref))
{
summaries->remove (node);
return;
@@ -1292,6 +2130,7 @@ modref_summaries_lto::insert (struct cgraph_node *node, modref_summary_lto *)
propagated. This is done only by SIMD cloning that is not very
critical. */
if (!DECL_STRUCT_FUNCTION (node->decl)
+ || !opt_for_fn (node->decl, flag_ipa_modref)
|| propagated)
{
summaries_lto->remove (node);
@@ -1327,6 +2166,8 @@ modref_summaries::duplicate (cgraph_node *, cgraph_node *dst,
src_data->loads->max_accesses);
dst_data->loads->copy_from (src_data->loads);
dst_data->writes_errno = src_data->writes_errno;
+ if (src_data->arg_flags.length ())
+ dst_data->arg_flags = src_data->arg_flags.copy ();
}
/* Called when new clone is inserted to callgraph late. */
@@ -1350,6 +2191,8 @@ modref_summaries_lto::duplicate (cgraph_node *, cgraph_node *,
src_data->loads->max_accesses);
dst_data->loads->copy_from (src_data->loads);
dst_data->writes_errno = src_data->writes_errno;
+ if (src_data->arg_flags.length ())
+ dst_data->arg_flags = src_data->arg_flags.copy ();
}
namespace
@@ -1574,6 +2417,49 @@ read_modref_records (lto_input_block *ib, struct data_in *data_in,
(*nolto_ret)->cleanup ();
}
+/* Write ESUM to BP. */
+
+static void
+modref_write_escape_summary (struct bitpack_d *bp, escape_summary *esum)
+{
+ if (!esum)
+ {
+ bp_pack_var_len_unsigned (bp, 0);
+ return;
+ }
+ bp_pack_var_len_unsigned (bp, esum->esc.length ());
+ unsigned int i;
+ escape_entry *ee;
+ FOR_EACH_VEC_ELT (esum->esc, i, ee)
+ {
+ bp_pack_var_len_unsigned (bp, ee->parm_index);
+ bp_pack_var_len_unsigned (bp, ee->arg);
+ bp_pack_var_len_unsigned (bp, ee->min_flags);
+ bp_pack_value (bp, ee->direct, 1);
+ }
+}
+
+/* Read escape summary for E from BP. */
+
+static void
+modref_read_escape_summary (struct bitpack_d *bp, cgraph_edge *e)
+{
+ unsigned int n = bp_unpack_var_len_unsigned (bp);
+ if (!n)
+ return;
+ escape_summary *esum = escape_summaries->get_create (e);
+ esum->esc.reserve_exact (n);
+ for (unsigned int i = 0; i < n; i++)
+ {
+ escape_entry ee;
+ ee.parm_index = bp_unpack_var_len_unsigned (bp);
+ ee.arg = bp_unpack_var_len_unsigned (bp);
+ ee.min_flags = bp_unpack_var_len_unsigned (bp);
+ ee.direct = bp_unpack_value (bp, 1);
+ esum->esc.quick_push (ee);
+ }
+}
+
/* Callback for write_summary. */
static void
@@ -1620,6 +2506,10 @@ modref_write ()
streamer_write_uhwi (ob, lto_symtab_encoder_encode (encoder, cnode));
+ streamer_write_uhwi (ob, r->arg_flags.length ());
+ for (unsigned int i = 0; i < r->arg_flags.length (); i++)
+ streamer_write_char_stream (ob->main_stream, r->arg_flags[i]);
+
write_modref_records (r->loads, ob);
write_modref_records (r->stores, ob);
@@ -1634,6 +2524,8 @@ modref_write ()
bp_pack_value (&bp, sum != NULL, 1);
if (sum)
bp_pack_string (ob, &bp, sum->fnspec, true);
+ class escape_summary *esum = escape_summaries->get (e);
+ modref_write_escape_summary (&bp,esum);
}
for (cgraph_edge *e = cnode->callees; e; e = e->next_callee)
{
@@ -1641,6 +2533,8 @@ modref_write ()
bp_pack_value (&bp, sum != NULL, 1);
if (sum)
bp_pack_string (ob, &bp, sum->fnspec, true);
+ class escape_summary *esum = escape_summaries->get (e);
+ modref_write_escape_summary (&bp,esum);
}
}
streamer_write_bitpack (&bp);
@@ -1698,6 +2592,19 @@ read_section (struct lto_file_decl_data *file_data, const char *data,
&& !modref_sum->stores));
gcc_assert (!modref_sum_lto || (!modref_sum_lto->loads
&& !modref_sum_lto->stores));
+ unsigned int args = streamer_read_uhwi (&ib);
+ if (args && modref_sum)
+ modref_sum->arg_flags.reserve_exact (args);
+ if (args && modref_sum_lto)
+ modref_sum_lto->arg_flags.reserve_exact (args);
+ for (unsigned int i = 0; i < args; i++)
+ {
+ unsigned char flags = streamer_read_uchar (&ib);
+ if (modref_sum)
+ modref_sum->arg_flags.quick_push (flags);
+ if (modref_sum_lto)
+ modref_sum_lto->arg_flags.quick_push (flags);
+ }
read_modref_records (&ib, data_in,
modref_sum ? &modref_sum->loads : NULL,
modref_sum_lto ? &modref_sum_lto->loads : NULL);
@@ -1721,6 +2628,7 @@ read_section (struct lto_file_decl_data *file_data, const char *data,
class fnspec_summary *sum = fnspec_summaries->get_create (e);
sum->fnspec = xstrdup (bp_unpack_string (data_in, &bp));
}
+ modref_read_escape_summary (&bp, e);
}
for (cgraph_edge *e = node->callees; e; e = e->next_callee)
{
@@ -1729,6 +2637,7 @@ read_section (struct lto_file_decl_data *file_data, const char *data,
class fnspec_summary *sum = fnspec_summaries->get_create (e);
sum->fnspec = xstrdup (bp_unpack_string (data_in, &bp));
}
+ modref_read_escape_summary (&bp, e);
}
}
if (dump_file)
@@ -1739,6 +2648,7 @@ read_section (struct lto_file_decl_data *file_data, const char *data,
modref_sum->dump (dump_file);
if (modref_sum_lto)
modref_sum_lto->dump (dump_file);
+ dump_modref_edge_summaries (dump_file, node, 4);
}
}
@@ -1769,6 +2679,8 @@ modref_read (void)
summaries = modref_summaries::create_ggc (symtab);
if (!fnspec_summaries)
fnspec_summaries = new fnspec_summaries_t (symtab);
+ if (!escape_summaries)
+ escape_summaries = new escape_summaries_t (symtab);
}
while ((file_data = file_data_vec[j++]))
@@ -1788,6 +2700,34 @@ modref_read (void)
}
}
+/* Recompute arg_flags for param adjustments in INFO. */
+
+static void
+remap_arg_flags (auto_vec <unsigned char> &arg_flags, clone_info *info)
+{
+ auto_vec<unsigned char> old = arg_flags.copy ();
+ int max = -1;
+ size_t i;
+ ipa_adjusted_param *p;
+
+ arg_flags.release ();
+
+ FOR_EACH_VEC_SAFE_ELT (info->param_adjustments->m_adj_params, i, p)
+ {
+ int o = info->param_adjustments->get_original_index (i);
+ if (o >= 0 && (int)old.length () > o && old[o])
+ max = i;
+ }
+ if (max >= 0)
+ arg_flags.safe_grow_cleared (max + 1, true);
+ FOR_EACH_VEC_SAFE_ELT (info->param_adjustments->m_adj_params, i, p)
+ {
+ int o = info->param_adjustments->get_original_index (i);
+ if (o >= 0 && (int)old.length () > o && old[o])
+ arg_flags[i] = old[o];
+ }
+}
+
/* If signature changed, update the summary. */
static void
@@ -1807,7 +2747,10 @@ update_signature (struct cgraph_node *node)
{
fprintf (dump_file, "Updating summary for %s from:\n",
node->dump_name ());
- r->dump (dump_file);
+ if (r)
+ r->dump (dump_file);
+ if (r_lto)
+ r_lto->dump (dump_file);
}
size_t i, max = 0;
@@ -1835,11 +2778,15 @@ update_signature (struct cgraph_node *node)
{
r->loads->remap_params (&map);
r->stores->remap_params (&map);
+ if (r->arg_flags.length ())
+ remap_arg_flags (r->arg_flags, info);
}
if (r_lto)
{
r_lto->loads->remap_params (&map);
r_lto->stores->remap_params (&map);
+ if (r_lto->arg_flags.length ())
+ remap_arg_flags (r_lto->arg_flags, info);
}
if (dump_file)
{
@@ -1957,7 +2904,7 @@ compute_parm_map (cgraph_edge *callee_edge, vec<modref_parm_map> *parm_map)
: callee_edge->caller);
callee_pi = IPA_NODE_REF (callee);
- (*parm_map).safe_grow_cleared (count);
+ (*parm_map).safe_grow_cleared (count, true);
for (i = 0; i < count; i++)
{
@@ -2007,7 +2954,7 @@ compute_parm_map (cgraph_edge *callee_edge, vec<modref_parm_map> *parm_map)
(!(ipa_get_jf_ancestor_offset (jf) & (BITS_PER_UNIT - 1)));
(*parm_map)[i].parm_offset
= ipa_get_jf_ancestor_offset (jf) >> LOG2_BITS_PER_UNIT;
- }
+ }
else
(*parm_map)[i].parm_index = -1;
}
@@ -2023,6 +2970,65 @@ compute_parm_map (cgraph_edge *callee_edge, vec<modref_parm_map> *parm_map)
return false;
}
+/* Map used to translate escape infos. */
+
+struct escape_map
+{
+ int parm_index;
+ bool direct;
+};
+
+/* Update escape map fo E. */
+
+static void
+update_escape_summary_1 (cgraph_edge *e,
+ vec <vec <escape_map>> &map)
+{
+ escape_summary *sum = escape_summaries->get (e);
+ if (!sum)
+ return;
+ auto_vec <escape_entry> old = sum->esc.copy ();
+ sum->esc.release ();
+
+ unsigned int i;
+ escape_entry *ee;
+ FOR_EACH_VEC_ELT (old, i, ee)
+ {
+ unsigned int j;
+ struct escape_map *em;
+ if (ee->parm_index >= map.length ())
+ continue;
+ FOR_EACH_VEC_ELT (map[ee->parm_index], j, em)
+ {
+ struct escape_entry entry = {em->parm_index, ee->arg,
+ ee->min_flags,
+ ee->direct & em->direct};
+ sum->esc.safe_push (entry);
+ }
+ }
+ if (!sum->esc.length ())
+ escape_summaries->remove (e);
+}
+
+/* Update escape map fo NODE. */
+
+static void
+update_escape_summary (cgraph_node *node,
+ vec <vec <escape_map>> &map)
+{
+ if (!escape_summaries)
+ return;
+ for (cgraph_edge *e = node->indirect_calls; e; e = e->next_callee)
+ update_escape_summary_1 (e, map);
+ for (cgraph_edge *e = node->callees; e; e = e->next_callee)
+ {
+ if (!e->inline_failed)
+ update_escape_summary (e->callee, map);
+ else
+ update_escape_summary_1 (e, map);
+ }
+}
+
/* Call EDGE was inlined; merge summary from callee to the caller. */
void
@@ -2043,6 +3049,7 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge *edge)
summaries->remove (edge->callee);
if (summaries_lto)
summaries_lto->remove (edge->callee);
+ remove_modref_edge_summaries (edge->callee);
return;
}
@@ -2051,26 +3058,21 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge *edge)
class modref_summary_lto *callee_info_lto
= summaries_lto ? summaries_lto->get (edge->callee) : NULL;
int flags = flags_from_decl_or_type (edge->callee->decl);
+ bool ignore_stores = ignore_stores_p (edge->caller->decl, flags);
if (!callee_info && to_info)
{
- if (ignore_stores_p (edge->caller->decl, flags))
+ if (!(flags & (ECF_CONST | ECF_NOVOPS)))
to_info->loads->collapse ();
- else
- {
- summaries->remove (to);
- to_info = NULL;
- }
+ if (!ignore_stores)
+ to_info->stores->collapse ();
}
if (!callee_info_lto && to_info_lto)
{
- if (ignore_stores_p (edge->caller->decl, flags))
+ if (!(flags & (ECF_CONST | ECF_NOVOPS)))
to_info_lto->loads->collapse ();
- else
- {
- summaries_lto->remove (to);
- to_info_lto = NULL;
- }
+ if (!ignore_stores)
+ to_info_lto->stores->collapse ();
}
if (callee_info || callee_info_lto)
{
@@ -2078,18 +3080,82 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge *edge)
compute_parm_map (edge, &parm_map);
- if (!ignore_stores_p (edge->caller->decl, flags))
+ if (!ignore_stores)
{
if (to_info && callee_info)
to_info->stores->merge (callee_info->stores, &parm_map);
if (to_info_lto && callee_info_lto)
to_info_lto->stores->merge (callee_info_lto->stores, &parm_map);
}
- if (to_info && callee_info)
- to_info->loads->merge (callee_info->loads, &parm_map);
- if (to_info_lto && callee_info_lto)
- to_info_lto->loads->merge (callee_info_lto->loads, &parm_map);
+ if (!(flags & (ECF_CONST | ECF_NOVOPS)))
+ {
+ if (to_info && callee_info)
+ to_info->loads->merge (callee_info->loads, &parm_map);
+ if (to_info_lto && callee_info_lto)
+ to_info_lto->loads->merge (callee_info_lto->loads, &parm_map);
+ }
}
+
+ /* Now merge escape summaries.
+ For every escape to the callee we need to merge calle flags
+ and remap calees escapes. */
+ class escape_summary *sum = escape_summaries->get (edge);
+ int max_escape = -1;
+ escape_entry *ee;
+ unsigned int i;
+
+ if (sum && !(flags & (ECF_CONST | ECF_NOVOPS)))
+ FOR_EACH_VEC_ELT (sum->esc, i, ee)
+ if ((int)ee->arg > max_escape)
+ max_escape = ee->arg;
+
+ auto_vec <vec <struct escape_map>, 32> emap (max_escape + 1);
+ emap.safe_grow (max_escape + 1, true);
+ for (i = 0; (int)i < max_escape + 1; i++)
+ emap[i] = vNULL;
+
+ if (sum && !(flags & (ECF_CONST | ECF_NOVOPS)))
+ FOR_EACH_VEC_ELT (sum->esc, i, ee)
+ {
+ bool needed = false;
+ if (to_info && to_info->arg_flags.length () > ee->parm_index)
+ {
+ int flags = callee_info
+ && callee_info->arg_flags.length () > ee->arg
+ ? callee_info->arg_flags[ee->arg] : 0;
+ if (!ee->direct)
+ flags = deref_flags (flags, ignore_stores);
+ else if (ignore_stores)
+ flags |= EAF_NOCLOBBER | EAF_NOESCAPE | EAF_NODIRECTESCAPE;
+ flags |= ee->min_flags;
+ to_info->arg_flags[ee->parm_index] &= flags;
+ if (to_info->arg_flags[ee->parm_index])
+ needed = true;
+ }
+ if (to_info_lto && to_info_lto->arg_flags.length () > ee->parm_index)
+ {
+ int flags = callee_info_lto
+ && callee_info_lto->arg_flags.length () > ee->arg
+ ? callee_info_lto->arg_flags[ee->arg] : 0;
+ if (!ee->direct)
+ flags = deref_flags (flags, ignore_stores);
+ else if (ignore_stores)
+ flags |= EAF_NOCLOBBER | EAF_NOESCAPE | EAF_NODIRECTESCAPE;
+ flags |= ee->min_flags;
+ to_info_lto->arg_flags[ee->parm_index] &= flags;
+ if (to_info_lto->arg_flags[ee->parm_index])
+ needed = true;
+ }
+ struct escape_map entry = {ee->parm_index, ee->direct};
+ if (needed)
+ emap[ee->arg].safe_push (entry);
+ }
+ update_escape_summary (edge->callee, emap);
+ for (i = 0; (int)i < max_escape + 1; i++)
+ emap[i].release ();
+ if (sum)
+ escape_summaries->remove (edge);
+
if (summaries)
{
if (to_info && !to_info->useful_p (flags))
@@ -2098,6 +3164,7 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge *edge)
fprintf (dump_file, "Removed mod-ref summary for %s\n",
to->dump_name ());
summaries->remove (to);
+ to_info = NULL;
}
else if (to_info && dump_file)
{
@@ -2124,10 +3191,13 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge *edge)
fprintf (dump_file, "Updated mod-ref summary for %s\n",
to->dump_name ());
to_info_lto->dump (dump_file);
+ to_info_lto = NULL;
}
if (callee_info_lto)
summaries_lto->remove (edge->callee);
}
+ if (!to_info && !to_info_lto)
+ remove_modref_edge_summaries (to);
return;
}
@@ -2191,13 +3261,10 @@ get_access_for_fnspec (cgraph_edge *e, attr_fnspec &fnspec,
static bool
propagate_unknown_call (cgraph_node *node,
cgraph_edge *e, int ecf_flags,
- modref_summary **cur_summary_ptr,
- modref_summary_lto **cur_summary_lto_ptr)
+ modref_summary *cur_summary,
+ modref_summary_lto *cur_summary_lto)
{
bool changed = false;
- modref_summary *cur_summary = cur_summary_ptr ? *cur_summary_ptr : NULL;
- modref_summary_lto *cur_summary_lto = cur_summary_lto_ptr
- ? *cur_summary_lto_ptr : NULL;
class fnspec_summary *fnspec_sum = fnspec_summaries->get (e);
auto_vec <modref_parm_map, 32> parm_map;
if (fnspec_sum
@@ -2279,26 +3346,42 @@ propagate_unknown_call (cgraph_node *node,
}
return changed;
}
- if (ignore_stores_p (node->decl, ecf_flags))
+ if (dump_file)
+ fprintf (dump_file, " collapsing loads\n");
+ changed |= collapse_loads (cur_summary, cur_summary_lto);
+ if (!ignore_stores_p (node->decl, ecf_flags))
{
if (dump_file)
- fprintf (dump_file, " collapsing loads\n");
- return collapse_loads (cur_summary, cur_summary_lto);
+ fprintf (dump_file, " collapsing stores\n");
+ changed |= collapse_stores (cur_summary, cur_summary_lto);
}
- if (optimization_summaries)
- optimization_summaries->remove (node);
- if (summaries_lto)
- summaries_lto->remove (node);
- if (cur_summary_ptr)
- *cur_summary_ptr = NULL;
- if (cur_summary_lto_ptr)
- *cur_summary_lto_ptr = NULL;
- if (dump_file)
- fprintf (dump_file, " Giving up\n");
- return true;
+ return changed;
}
-/* Perform iterative dataflow on SCC component starting in COMPONENT_NODE. */
+/* Maybe remove summaies of NODE pointed to by CUR_SUMMARY_PTR
+ and CUR_SUMMARY_LTO_PTR if they are useless according to ECF_FLAGS. */
+
+static void
+remove_useless_summaries (cgraph_node *node,
+ modref_summary **cur_summary_ptr,
+ modref_summary_lto **cur_summary_lto_ptr,
+ int ecf_flags)
+{
+ if (*cur_summary_ptr && !(*cur_summary_ptr)->useful_p (ecf_flags, false))
+ {
+ optimization_summaries->remove (node);
+ *cur_summary_ptr = NULL;
+ }
+ if (*cur_summary_lto_ptr
+ && !(*cur_summary_lto_ptr)->useful_p (ecf_flags, false))
+ {
+ summaries_lto->remove (node);
+ *cur_summary_lto_ptr = NULL;
+ }
+}
+
+/* Perform iterative dataflow on SCC component starting in COMPONENT_NODE
+ and propagate loads/stores. */
static void
modref_propagate_in_scc (cgraph_node *component_node)
@@ -2323,6 +3406,8 @@ modref_propagate_in_scc (cgraph_node *component_node)
if (!cur_summary && !cur_summary_lto)
continue;
+ int cur_ecf_flags = flags_from_decl_or_type (node->decl);
+
if (dump_file)
fprintf (dump_file, " Processing %s%s%s\n",
cur->dump_name (),
@@ -2336,11 +3421,17 @@ modref_propagate_in_scc (cgraph_node *component_node)
if (dump_file)
fprintf (dump_file, " Indirect call"
"collapsing loads\n");
- changed |= propagate_unknown_call
+ if (propagate_unknown_call
(node, e, e->indirect_info->ecf_flags,
- &cur_summary, &cur_summary_lto);
- if (!cur_summary && !cur_summary_lto)
- break;
+ cur_summary, cur_summary_lto))
+ {
+ changed = true;
+ remove_useless_summaries (node, &cur_summary,
+ &cur_summary_lto,
+ cur_ecf_flags);
+ if (!cur_summary && !cur_summary_lto)
+ break;
+ }
}
if (!cur_summary && !cur_summary_lto)
@@ -2384,7 +3475,7 @@ modref_propagate_in_scc (cgraph_node *component_node)
" or not available\n");
changed |= propagate_unknown_call
(node, callee_edge, flags,
- &cur_summary, &cur_summary_lto);
+ cur_summary, cur_summary_lto);
if (!cur_summary && !cur_summary_lto)
break;
continue;
@@ -2400,9 +3491,7 @@ modref_propagate_in_scc (cgraph_node *component_node)
fprintf (dump_file, " No call target summary\n");
changed |= propagate_unknown_call
(node, callee_edge, flags,
- &cur_summary, NULL);
- if (!cur_summary && !cur_summary_lto)
- break;
+ cur_summary, NULL);
}
if (cur_summary_lto
&& !(callee_summary_lto = summaries_lto->get (callee)))
@@ -2411,9 +3500,7 @@ modref_propagate_in_scc (cgraph_node *component_node)
fprintf (dump_file, " No call target summary\n");
changed |= propagate_unknown_call
(node, callee_edge, flags,
- NULL, &cur_summary_lto);
- if (!cur_summary && !cur_summary_lto)
- break;
+ NULL, cur_summary_lto);
}
/* We can not safely optimize based on summary of callee if it
@@ -2466,52 +3553,249 @@ modref_propagate_in_scc (cgraph_node *component_node)
}
}
}
+ if (changed)
+ remove_useless_summaries (node, &cur_summary,
+ &cur_summary_lto,
+ cur_ecf_flags);
+ if (!cur_summary && !cur_summary_lto)
+ break;
if (dump_file && changed)
{
if (cur_summary)
cur_summary->dump (dump_file);
if (cur_summary_lto)
cur_summary_lto->dump (dump_file);
+ dump_modref_edge_summaries (dump_file, node, 4);
}
}
}
iteration++;
}
if (dump_file)
+ fprintf (dump_file,
+ "Propagation finished in %i iterations\n", iteration);
+}
+
+/* Dump results of propagation in SCC rooted in COMPONENT_NODE. */
+
+static void
+modref_propagate_dump_scc (cgraph_node *component_node)
+{
+ for (struct cgraph_node *cur = component_node; cur;
+ cur = ((struct ipa_dfs_info *) cur->aux)->next_cycle)
+ if (!cur->inlined_to)
+ {
+ modref_summary *cur_summary = optimization_summaries
+ ? optimization_summaries->get (cur)
+ : NULL;
+ modref_summary_lto *cur_summary_lto = summaries_lto
+ ? summaries_lto->get (cur)
+ : NULL;
+
+ fprintf (dump_file, "Propagated modref for %s%s%s\n",
+ cur->dump_name (),
+ TREE_READONLY (cur->decl) ? " (const)" : "",
+ DECL_PURE_P (cur->decl) ? " (pure)" : "");
+ if (optimization_summaries)
+ {
+ if (cur_summary)
+ cur_summary->dump (dump_file);
+ else
+ fprintf (dump_file, " Not tracked\n");
+ }
+ if (summaries_lto)
+ {
+ if (cur_summary_lto)
+ cur_summary_lto->dump (dump_file);
+ else
+ fprintf (dump_file, " Not tracked (lto)\n");
+ }
+ }
+}
+
+/* Process escapes in SUM and merge SUMMARY to CUR_SUMMARY
+ and SUMMARY_LTO to CUR_SUMMARY_LTO.
+ Return true if something changed. */
+
+static bool
+modref_merge_call_site_flags (escape_summary *sum,
+ modref_summary *cur_summary,
+ modref_summary_lto *cur_summary_lto,
+ modref_summary *summary,
+ modref_summary_lto *summary_lto,
+ bool ignore_stores)
+{
+ escape_entry *ee;
+ unsigned int i;
+ bool changed = false;
+
+ /* If we have no useful info to propagate. */
+ if ((!cur_summary || !cur_summary->arg_flags.length ())
+ && (!cur_summary_lto || !cur_summary_lto->arg_flags.length ()))
+ return false;
+
+ FOR_EACH_VEC_ELT (sum->esc, i, ee)
{
- fprintf (dump_file,
- "Propagation finished in %i iterations\n", iteration);
+ int flags = 0;
+ int flags_lto = 0;
+
+ if (summary && ee->arg < summary->arg_flags.length ())
+ flags = summary->arg_flags[ee->arg];
+ if (summary_lto
+ && ee->arg < summary_lto->arg_flags.length ())
+ flags_lto = summary_lto->arg_flags[ee->arg];
+ if (!ee->direct)
+ {
+ flags = deref_flags (flags, ignore_stores);
+ flags_lto = deref_flags (flags_lto, ignore_stores);
+ }
+ else if (ignore_stores)
+ {
+ flags |= EAF_NOESCAPE | EAF_NOCLOBBER | EAF_NODIRECTESCAPE;
+ flags_lto |= EAF_NOESCAPE | EAF_NOCLOBBER | EAF_NODIRECTESCAPE;
+ }
+ flags |= ee->min_flags;
+ flags_lto |= ee->min_flags;
+ if (!(flags & EAF_UNUSED)
+ && cur_summary && ee->parm_index < cur_summary->arg_flags.length ())
+ {
+ int f = cur_summary->arg_flags[ee->parm_index];
+ if ((f & flags) != f)
+ {
+ f = f & flags;
+ if ((f & ~(EAF_DIRECT | EAF_NOCLOBBER)) == 0)
+ f = 0;
+ cur_summary->arg_flags[ee->parm_index] = f;
+ changed = true;
+ }
+ }
+ if (!(flags_lto & EAF_UNUSED)
+ && cur_summary_lto
+ && ee->parm_index < cur_summary_lto->arg_flags.length ())
+ {
+ int f = cur_summary_lto->arg_flags[ee->parm_index];
+ if ((f & flags_lto) != f)
+ {
+ f = f & flags;
+ if ((f & ~(EAF_DIRECT | EAF_NOCLOBBER)) == 0)
+ f = 0;
+ cur_summary_lto->arg_flags[ee->parm_index] = f;
+ changed = true;
+ }
+ }
+ }
+ return changed;
+}
+
+/* Perform iterative dataflow on SCC component starting in COMPONENT_NODE
+ and propagate arg flags. */
+
+static void
+modref_propagate_flags_in_scc (cgraph_node *component_node)
+{
+ bool changed = true;
+ int iteration = 0;
+
+ while (changed)
+ {
+ changed = false;
for (struct cgraph_node *cur = component_node; cur;
cur = ((struct ipa_dfs_info *) cur->aux)->next_cycle)
- if (!cur->inlined_to)
- {
- modref_summary *cur_summary = optimization_summaries
- ? optimization_summaries->get (cur)
- : NULL;
- modref_summary_lto *cur_summary_lto = summaries_lto
- ? summaries_lto->get (cur)
- : NULL;
-
- fprintf (dump_file, "Propagated modref for %s%s%s\n",
+ {
+ cgraph_node *node = cur->inlined_to ? cur->inlined_to : cur;
+ modref_summary *cur_summary = optimization_summaries
+ ? optimization_summaries->get (node)
+ : NULL;
+ modref_summary_lto *cur_summary_lto = summaries_lto
+ ? summaries_lto->get (node)
+ : NULL;
+
+ if (!cur_summary && !cur_summary_lto)
+ continue;
+
+ if (dump_file)
+ fprintf (dump_file, " Processing %s%s%s\n",
cur->dump_name (),
TREE_READONLY (cur->decl) ? " (const)" : "",
DECL_PURE_P (cur->decl) ? " (pure)" : "");
- if (optimization_summaries)
- {
- if (cur_summary)
- cur_summary->dump (dump_file);
- else
- fprintf (dump_file, " Not tracked\n");
- }
- if (summaries_lto)
- {
- if (cur_summary_lto)
- cur_summary_lto->dump (dump_file);
- else
- fprintf (dump_file, " Not tracked (lto)\n");
- }
- }
- }
+
+ for (cgraph_edge *e = cur->indirect_calls; e; e = e->next_callee)
+ {
+ escape_summary *sum = escape_summaries->get (e);
+
+ if (!sum || (e->indirect_info->ecf_flags
+ & (ECF_CONST | ECF_NOVOPS)))
+ continue;
+
+ changed |= modref_merge_call_site_flags
+ (sum, cur_summary, cur_summary_lto,
+ NULL, NULL, ignore_stores_p (node->decl,
+ e->indirect_info->ecf_flags));
+ }
+
+ if (!cur_summary && !cur_summary_lto)
+ continue;
+
+ for (cgraph_edge *callee_edge = cur->callees; callee_edge;
+ callee_edge = callee_edge->next_callee)
+ {
+ int flags = flags_from_decl_or_type (callee_edge->callee->decl);
+ modref_summary *callee_summary = NULL;
+ modref_summary_lto *callee_summary_lto = NULL;
+ struct cgraph_node *callee;
+
+ if (flags & (ECF_CONST | ECF_NOVOPS)
+ || !callee_edge->inline_failed)
+ continue;
+ /* Get the callee and its summary. */
+ enum availability avail;
+ callee = callee_edge->callee->function_or_virtual_thunk_symbol
+ (&avail, cur);
+
+ /* It is not necessary to re-process calls outside of the
+ SCC component. */
+ if (iteration > 0
+ && (!callee->aux
+ || ((struct ipa_dfs_info *)cur->aux)->scc_no
+ != ((struct ipa_dfs_info *)callee->aux)->scc_no))
+ continue;
+
+ escape_summary *sum = escape_summaries->get (callee_edge);
+ if (!sum)
+ continue;
+
+ if (dump_file)
+ fprintf (dump_file, " Call to %s\n",
+ callee_edge->callee->dump_name ());
+
+ if (avail <= AVAIL_INTERPOSABLE
+ || callee_edge->call_stmt_cannot_inline_p)
+ ;
+ else
+ {
+ if (cur_summary)
+ callee_summary = optimization_summaries->get (callee);
+ if (cur_summary_lto)
+ callee_summary_lto = summaries_lto->get (callee);
+ }
+ changed |= modref_merge_call_site_flags
+ (sum, cur_summary, cur_summary_lto,
+ callee_summary, callee_summary_lto,
+ ignore_stores_p (node->decl, flags));
+ if (dump_file && changed)
+ {
+ if (cur_summary)
+ cur_summary->dump (dump_file);
+ if (cur_summary_lto)
+ cur_summary_lto->dump (dump_file);
+ }
+ }
+ }
+ iteration++;
+ }
+ if (dump_file)
+ fprintf (dump_file,
+ "Propagation of flags finished in %i iterations\n", iteration);
}
/* Run the IPA pass. This will take a function's summaries and calls and
@@ -2547,6 +3831,9 @@ pass_ipa_modref::execute (function *)
fprintf (dump_file, "\n\nStart of SCC component\n");
modref_propagate_in_scc (component_node);
+ modref_propagate_flags_in_scc (component_node);
+ if (dump_file)
+ modref_propagate_dump_scc (component_node);
}
cgraph_node *node;
FOR_EACH_FUNCTION (node)
@@ -2557,6 +3844,8 @@ pass_ipa_modref::execute (function *)
free (order);
delete fnspec_summaries;
fnspec_summaries = NULL;
+ delete escape_summaries;
+ escape_summaries = NULL;
return 0;
}
@@ -2570,13 +3859,14 @@ ipa_modref_c_finalize ()
optimization_summaries = NULL;
gcc_checking_assert (!summaries);
if (summaries_lto)
- {
- ggc_delete (summaries_lto);
- summaries_lto = NULL;
- }
+ ggc_delete (summaries_lto);
+ summaries_lto = NULL;
if (fnspec_summaries)
delete fnspec_summaries;
fnspec_summaries = NULL;
+ if (escape_summaries)
+ delete escape_summaries;
+ escape_summaries = NULL;
}
#include "gt-ipa-modref.h"
diff --git a/gcc/ipa-modref.h b/gcc/ipa-modref.h
index 31ceffa..7decabd 100644
--- a/gcc/ipa-modref.h
+++ b/gcc/ipa-modref.h
@@ -29,12 +29,13 @@ struct GTY(()) modref_summary
/* Load and stores in function (transitively closed to all callees) */
modref_records *loads;
modref_records *stores;
+ auto_vec<unsigned char> GTY((skip)) arg_flags;
+ bool writes_errno;
modref_summary ();
~modref_summary ();
void dump (FILE *);
- bool useful_p (int ecf_flags);
- bool writes_errno;
+ bool useful_p (int ecf_flags, bool check_flags = true);
};
modref_summary *get_modref_function_summary (cgraph_node *func);
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 7a5fa59..130b2f8 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -1682,7 +1682,7 @@ build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
int value_count, HOST_WIDE_INT arg_offset,
struct ipa_jump_func *jfunc)
{
- vec_alloc (jfunc->agg.items, value_count);
+ vec_safe_reserve (jfunc->agg.items, value_count, true);
for (; list; list = list->next)
{
struct ipa_agg_jf_item item;
@@ -1775,75 +1775,123 @@ analyze_agg_content_value (struct ipa_func_body_info *fbi,
stmt = SSA_NAME_DEF_STMT (rhs1);
if (!is_gimple_assign (stmt))
- return;
+ break;
rhs1 = gimple_assign_rhs1 (stmt);
}
- code = gimple_assign_rhs_code (stmt);
- switch (gimple_assign_rhs_class (stmt))
+ if (gphi *phi = dyn_cast<gphi *> (stmt))
{
- case GIMPLE_SINGLE_RHS:
- if (is_gimple_ip_invariant (rhs1))
- {
- agg_value->pass_through.operand = rhs1;
- return;
- }
- code = NOP_EXPR;
- break;
+ /* Also special case like the following (a is a formal parameter):
- case GIMPLE_UNARY_RHS:
- /* NOTE: A GIMPLE_UNARY_RHS operation might not be tcc_unary
- (truth_not_expr is example), GIMPLE_BINARY_RHS does not imply
- tcc_binary, this subtleness is somewhat misleading.
+ _12 = *a_11(D).dim[0].stride;
+ ...
+ # iftmp.22_9 = PHI <_12(2), 1(3)>
+ ...
+ parm.6.dim[0].stride = iftmp.22_9;
+ ...
+ __x_MOD_foo (&parm.6, b_31(D));
- Since tcc_unary is widely used in IPA-CP code to check an operation
- with one operand, here we only allow tc_unary operation to avoid
- possible problem. Then we can use (opclass == tc_unary) or not to
- distinguish unary and binary. */
- if (TREE_CODE_CLASS (code) != tcc_unary || CONVERT_EXPR_CODE_P (code))
+ The aggregate function describing parm.6.dim[0].stride is encoded as a
+ PASS-THROUGH jump function with ASSERT_EXPR operation whith operand 1
+ (the constant from the PHI node). */
+
+ if (gimple_phi_num_args (phi) != 2)
+ return;
+ tree arg0 = gimple_phi_arg_def (phi, 0);
+ tree arg1 = gimple_phi_arg_def (phi, 1);
+ tree operand;
+
+ if (is_gimple_ip_invariant (arg1))
+ {
+ operand = arg1;
+ rhs1 = arg0;
+ }
+ else if (is_gimple_ip_invariant (arg0))
+ {
+ operand = arg0;
+ rhs1 = arg1;
+ }
+ else
return;
rhs1 = get_ssa_def_if_simple_copy (rhs1, &stmt);
- break;
+ if (!is_gimple_assign (stmt))
+ return;
- case GIMPLE_BINARY_RHS:
- {
- gimple *rhs1_stmt = stmt;
- gimple *rhs2_stmt = stmt;
- tree rhs2 = gimple_assign_rhs2 (stmt);
+ code = ASSERT_EXPR;
+ agg_value->pass_through.operand = operand;
+ }
+ else if (is_gimple_assign (stmt))
+ {
+ code = gimple_assign_rhs_code (stmt);
+ switch (gimple_assign_rhs_class (stmt))
+ {
+ case GIMPLE_SINGLE_RHS:
+ if (is_gimple_ip_invariant (rhs1))
+ {
+ agg_value->pass_through.operand = rhs1;
+ return;
+ }
+ code = NOP_EXPR;
+ break;
- rhs1 = get_ssa_def_if_simple_copy (rhs1, &rhs1_stmt);
- rhs2 = get_ssa_def_if_simple_copy (rhs2, &rhs2_stmt);
+ case GIMPLE_UNARY_RHS:
+ /* NOTE: A GIMPLE_UNARY_RHS operation might not be tcc_unary
+ (truth_not_expr is example), GIMPLE_BINARY_RHS does not imply
+ tcc_binary, this subtleness is somewhat misleading.
+
+ Since tcc_unary is widely used in IPA-CP code to check an operation
+ with one operand, here we only allow tc_unary operation to avoid
+ possible problem. Then we can use (opclass == tc_unary) or not to
+ distinguish unary and binary. */
+ if (TREE_CODE_CLASS (code) != tcc_unary || CONVERT_EXPR_CODE_P (code))
+ return;
- if (is_gimple_ip_invariant (rhs2))
- {
- agg_value->pass_through.operand = rhs2;
- stmt = rhs1_stmt;
- }
- else if (is_gimple_ip_invariant (rhs1))
+ rhs1 = get_ssa_def_if_simple_copy (rhs1, &stmt);
+ break;
+
+ case GIMPLE_BINARY_RHS:
{
- if (TREE_CODE_CLASS (code) == tcc_comparison)
- code = swap_tree_comparison (code);
- else if (!commutative_tree_code (code))
+ gimple *rhs1_stmt = stmt;
+ gimple *rhs2_stmt = stmt;
+ tree rhs2 = gimple_assign_rhs2 (stmt);
+
+ rhs1 = get_ssa_def_if_simple_copy (rhs1, &rhs1_stmt);
+ rhs2 = get_ssa_def_if_simple_copy (rhs2, &rhs2_stmt);
+
+ if (is_gimple_ip_invariant (rhs2))
+ {
+ agg_value->pass_through.operand = rhs2;
+ stmt = rhs1_stmt;
+ }
+ else if (is_gimple_ip_invariant (rhs1))
+ {
+ if (TREE_CODE_CLASS (code) == tcc_comparison)
+ code = swap_tree_comparison (code);
+ else if (!commutative_tree_code (code))
+ return;
+
+ agg_value->pass_through.operand = rhs1;
+ stmt = rhs2_stmt;
+ rhs1 = rhs2;
+ }
+ else
return;
- agg_value->pass_through.operand = rhs1;
- stmt = rhs2_stmt;
- rhs1 = rhs2;
+ if (TREE_CODE_CLASS (code) != tcc_comparison
+ && !useless_type_conversion_p (TREE_TYPE (lhs),
+ TREE_TYPE (rhs1)))
+ return;
}
- else
- return;
+ break;
- if (TREE_CODE_CLASS (code) != tcc_comparison
- && !useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs1)))
+ default:
return;
- }
- break;
-
- default:
- return;
- }
+ }
+ }
+ else
+ return;
if (TREE_CODE (rhs1) != SSA_NAME)
index = load_from_unmodified_param_or_agg (fbi, fbi->info, stmt,
@@ -4745,7 +4793,10 @@ ipa_read_jump_function (class lto_input_block *ib,
count = streamer_read_uhwi (ib);
if (prevails)
- vec_alloc (jump_func->agg.items, count);
+ {
+ jump_func->agg.items = NULL;
+ vec_safe_reserve (jump_func->agg.items, count, true);
+ }
if (count)
{
struct bitpack_d bp = streamer_read_bitpack (ib);
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 77e92b0..112a1ba 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -94,9 +94,14 @@ struct GTY(()) ipa_pass_through_data
/* Number of the caller's formal parameter being passed. */
int formal_id;
/* Operation that is performed on the argument before it is passed on.
- NOP_EXPR means no operation. Otherwise oper must be a simple binary
- arithmetic operation where the caller's parameter is the first operand and
- operand field from this structure is the second one. */
+ Special values which have other meaning than in normal contexts:
+ - NOP_EXPR means no operation, not even type conversion.
+ - ASSERT_EXPR means that only the value in operand is allowed to pass
+ through (without any change), for all other values the result is
+ unknown.
+ Otherwise operation must be a simple binary or unary arithmetic operation
+ where the caller's parameter is the first operand and (for binary
+ operations) the operand field from this structure is the second one. */
enum tree_code operation;
/* When the passed value is a pointer, it is set to true only when we are
certain that no write to the object it points to has occurred since the
@@ -620,6 +625,7 @@ inline
ipa_node_params::~ipa_node_params ()
{
free (lattices);
+ vec_free (descriptors);
known_csts.release ();
known_contexts.release ();
}
@@ -895,6 +901,10 @@ class GTY((for_user)) ipa_edge_args
/* Destructor. */
~ipa_edge_args ()
{
+ unsigned int i;
+ ipa_jump_func *jf;
+ FOR_EACH_VEC_SAFE_ELT (jump_functions, i, jf)
+ vec_free (jf->agg.items);
vec_free (jump_functions);
vec_free (polymorphic_call_contexts);
}
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index 054f359..4c47eec 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -1973,7 +1973,8 @@ propagate_malloc (void)
funct_state l = funct_state_summaries->get (node);
if (!node->alias
&& l->malloc_state == STATE_MALLOC
- && !node->inlined_to)
+ && !node->inlined_to
+ && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (node->decl))))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Function %s found to be malloc\n",
diff --git a/gcc/ipa-utils.h b/gcc/ipa-utils.h
index 178c2cb..91571d8 100644
--- a/gcc/ipa-utils.h
+++ b/gcc/ipa-utils.h
@@ -211,8 +211,6 @@ type_with_linkage_p (const_tree t)
if (!TYPE_CONTEXT (t))
return false;
- gcc_checking_assert (TREE_CODE (t) == ENUMERAL_TYPE || TYPE_CXX_ODR_P (t));
-
return true;
}
@@ -265,4 +263,16 @@ get_odr_name_for_type (tree type)
return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (type_name));
}
+/* Return true if we are going to do LTO streaming. */
+
+inline bool
+lto_streaming_expected_p ()
+{
+ /* Compilation before LTO stremaing. */
+ if (flag_lto && !in_lto_p && symtab->state < IPA_SSA_AFTER_INLINING)
+ return true;
+ /* WPA or incremental link. */
+ return (flag_wpa || flag_incremental_link == INCREMENTAL_LINK_LTO);
+}
+
#endif /* GCC_IPA_UTILS_H */
diff --git a/gcc/ira.c b/gcc/ira.c
index 5443031..89b5df4 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -4666,7 +4666,9 @@ find_moveable_pseudos (void)
|| !DF_REF_INSN_INFO (def)
|| HARD_REGISTER_NUM_P (regno)
|| DF_REG_EQ_USE_COUNT (regno) > 0
- || (!INTEGRAL_MODE_P (mode) && !FLOAT_MODE_P (mode)))
+ || (!INTEGRAL_MODE_P (mode)
+ && !FLOAT_MODE_P (mode)
+ && !OPAQUE_MODE_P (mode)))
continue;
def_insn = DF_REF_INSN (def);
@@ -5401,6 +5403,48 @@ ira (FILE *f)
int ira_max_point_before_emit;
bool saved_flag_caller_saves = flag_caller_saves;
enum ira_region saved_flag_ira_region = flag_ira_region;
+ basic_block bb;
+ edge_iterator ei;
+ edge e;
+ bool output_jump_reload_p = false;
+
+ if (ira_use_lra_p)
+ {
+ /* First put potential jump output reloads on the output edges
+ as USE which will be removed at the end of LRA. The major
+ goal is actually to create BBs for critical edges for LRA and
+ populate them later by live info. In LRA it will be
+ difficult to do this. */
+ FOR_EACH_BB_FN (bb, cfun)
+ {
+ rtx_insn *end = BB_END (bb);
+ if (!JUMP_P (end))
+ continue;
+ extract_insn (end);
+ for (int i = 0; i < recog_data.n_operands; i++)
+ if (recog_data.operand_type[i] != OP_IN)
+ {
+ output_jump_reload_p = true;
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (EDGE_CRITICAL_P (e)
+ && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
+ {
+ ira_assert (!(e->flags & EDGE_ABNORMAL));
+ start_sequence ();
+ /* We need to put some no-op insn here. We can
+ not put a note as commit_edges insertion will
+ fail. */
+ emit_insn (gen_rtx_USE (VOIDmode, const1_rtx));
+ rtx_insn *insns = get_insns ();
+ end_sequence ();
+ insert_insn_on_edge (insns, e);
+ }
+ break;
+ }
+ }
+ if (output_jump_reload_p)
+ commit_edge_insertions ();
+ }
if (flag_ira_verbose < 10)
{
@@ -5709,6 +5753,21 @@ ira (FILE *f)
}
}
+/* Modify asm goto to avoid further trouble with this insn. We can
+ not replace the insn by USE as in other asm insns as we still
+ need to keep CFG consistency. */
+void
+ira_nullify_asm_goto (rtx_insn *insn)
+{
+ ira_assert (JUMP_P (insn) && INSN_CODE (insn) < 0);
+ rtx tmp = extract_asm_operands (PATTERN (insn));
+ PATTERN (insn) = gen_rtx_ASM_OPERANDS (VOIDmode, ggc_strdup (""), "", 0,
+ rtvec_alloc (0),
+ rtvec_alloc (0),
+ ASM_OPERANDS_LABEL_VEC (tmp),
+ ASM_OPERANDS_SOURCE_LOCATION(tmp));
+}
+
static void
do_reload (void)
{
diff --git a/gcc/ira.h b/gcc/ira.h
index c30f36a..0da06ee 100644
--- a/gcc/ira.h
+++ b/gcc/ira.h
@@ -213,6 +213,7 @@ extern void ira_register_new_scratch_op (rtx_insn *insn, int nop, int icode);
extern bool ira_remove_insn_scratches (rtx_insn *insn, bool all_p, FILE *dump_file,
rtx (*get_reg) (rtx original));
extern void ira_restore_scratches (FILE *dump_file);
+extern void ira_nullify_asm_goto (rtx_insn *insn);
/* ira-costs.c */
extern void ira_costs_c_finalize (void);
diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog
index 48bd54d..dafb480 100644
--- a/gcc/jit/ChangeLog
+++ b/gcc/jit/ChangeLog
@@ -1,3 +1,157 @@
+2020-11-25 Martin Sebor <msebor@redhat.com>
+
+ PR bootstrap/94982
+ * jit-recording.c (recording::function::dump_to_dot): Avoid
+ -Wformat-diag.
+ (recording::block::dump_to_dot): Same.
+
+2020-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/97911
+ * Make-lang.in (jit.serial): Change from goal to a
+ variable.
+ (.PHONY): Drop jit.serial and jit.prev.
+ ($(LIBGCCJIT_FILENAME)): Depend on $(jit.serial) rather than
+ jit.serial.
+
+2020-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ * Make-lang.in (jit.serial): New goal.
+ (.PHONY): Add jit.serial jit.prev.
+ ($(LIBGCCJIT_FILENAME)): Depend on jit.prev. Call LINK_PROGRESS.
+
+2020-11-12 David Malcolm <dmalcolm@redhat.com>
+
+ PR jit/87291
+ * docs/cp/topics/asm.rst: New file.
+ * docs/cp/topics/index.rst (Topic Reference): Add it.
+ * docs/topics/asm.rst: New file.
+ * docs/topics/compatibility.rst (LIBGCCJIT_ABI_15): New.
+ * docs/topics/functions.rst (Statements): Add link to extended
+ asm.
+ * docs/topics/index.rst (Topic Reference): Add asm.rst.
+ * docs/topics/objects.rst: Add gcc_jit_extended_asm to ASCII art.
+ * docs/_build/texinfo/Makefile: Regenerate.
+ * docs/_build/texinfo/libgccjit.texi: Regenerate.
+ * jit-common.h (gcc::jit::recording::extended_asm): New forward
+ decl.
+ (gcc::jit::recording::top_level_asm): Likewise.
+ * jit-playback.c: Include "stmt.h".
+ (build_string): New.
+ (gcc::jit::playback::context::new_string_literal): Disambiguate
+ build_string call.
+ (gcc::jit::playback::context::add_top_level_asm): New.
+ (build_operand_chain): New.
+ (build_clobbers): New.
+ (build_goto_operands): New.
+ (gcc::jit::playback::block::add_extended_asm): New.
+ * jit-playback.h (gcc::jit::playback::context::add_top_level_asm):
+ New decl.
+ (struct gcc::jit::playback::asm_operand): New struct.
+ (gcc::jit::playback::block::add_extended_asm): New decl.
+ * jit-recording.c (gcc::jit::recording::context::dump_to_file):
+ Dump top-level asms.
+ (gcc::jit::recording::context::add_top_level_asm): New.
+ (gcc::jit::recording::block::add_extended_asm): New.
+ (gcc::jit::recording::block::end_with_extended_asm_goto): New.
+ (gcc::jit::recording::asm_operand::asm_operand): New.
+ (gcc::jit::recording::asm_operand::print): New.
+ (gcc::jit::recording::asm_operand::make_debug_string): New.
+ (gcc::jit::recording::output_asm_operand::write_reproducer): New.
+ (gcc::jit::recording::output_asm_operand::print): New.
+ (gcc::jit::recording::input_asm_operand::write_reproducer): New.
+ (gcc::jit::recording::input_asm_operand::print): New.
+ (gcc::jit::recording::extended_asm::add_output_operand): New.
+ (gcc::jit::recording::extended_asm::add_input_operand): New.
+ (gcc::jit::recording::extended_asm::add_clobber): New.
+ (gcc::jit::recording::extended_asm::replay_into): New.
+ (gcc::jit::recording::extended_asm::make_debug_string): New.
+ (gcc::jit::recording::extended_asm::write_flags): New.
+ (gcc::jit::recording::extended_asm::write_clobbers): New.
+ (gcc::jit::recording::extended_asm_simple::write_reproducer): New.
+ (gcc::jit::recording::extended_asm::maybe_populate_playback_blocks):
+ New.
+ (gcc::jit::recording::extended_asm_goto::extended_asm_goto): New.
+ (gcc::jit::recording::extended_asm_goto::replay_into): New.
+ (gcc::jit::recording::extended_asm_goto::write_reproducer): New.
+ (gcc::jit::recording::extended_asm_goto::get_successor_blocks):
+ New.
+ (gcc::jit::recording::extended_asm_goto::maybe_print_gotos): New.
+ (gcc::jit::recording::extended_asm_goto::maybe_populate_playback_blocks):
+ New.
+ (gcc::jit::recording::top_level_asm::top_level_asm): New.
+ (gcc::jit::recording::top_level_asm::replay_into): New.
+ (gcc::jit::recording::top_level_asm::make_debug_string): New.
+ (gcc::jit::recording::top_level_asm::write_to_dump): New.
+ (gcc::jit::recording::top_level_asm::write_reproducer): New.
+ * jit-recording.h
+ (gcc::jit::recording::context::add_top_level_asm): New decl.
+ (gcc::jit::recording::context::m_top_level_asms): New field.
+ (gcc::jit::recording::block::add_extended_asm): New decl.
+ (gcc::jit::recording::block::end_with_extended_asm_goto): New
+ decl.
+ (gcc::jit::recording::asm_operand): New class.
+ (gcc::jit::recording::output_asm_operand): New class.
+ (gcc::jit::recording::input_asm_operand): New class.
+ (gcc::jit::recording::extended_asm): New class.
+ (gcc::jit::recording::extended_asm_simple): New class.
+ (gcc::jit::recording::extended_asm_goto): New class.
+ (gcc::jit::recording::top_level_asm): New class.
+ * libgccjit++.h (gccjit::extended_asm): New forward decl.
+ (gccjit::context::add_top_level_asm): New.
+ (gccjit::block::add_extended_asm): New.
+ (gccjit::block::end_with_extended_asm_goto): New.
+ (gccjit::extended_asm): New class.
+ (gccjit::extended_asm::extended_asm): New ctors.
+ (gccjit::extended_asm::set_volatile_flag): New.
+ (gccjit::extended_asm::set_inline_flag): New.
+ (gccjit::extended_asm::add_output_operand): New.
+ (gccjit::extended_asm::add_input_operand): New.
+ (gccjit::extended_asm::add_clobber): New.
+ (gccjit::extended_asm::get_inner_extended_asm): New.
+ * libgccjit.c (struct gcc_jit_extended_asm): New.
+ (jit_error): Make "loc" param take a gcc::jit::recording::location *
+ rather than a gcc_jit_location *.
+ (gcc_jit_block_add_extended_asm): New entrypoint.
+ (gcc_jit_block_end_with_extended_asm_goto): New entrypoint.
+ (gcc_jit_extended_asm_as_object): New entrypoint.
+ (gcc_jit_extended_asm_set_volatile_flag): New entrypoint.
+ (gcc_jit_extended_asm_set_inline_flag): New entrypoint.
+ (gcc_jit_extended_asm_add_output_operand): New entrypoint.
+ (gcc_jit_extended_asm_add_clobber): New entrypoint.
+ (gcc_jit_context_add_top_level_asm): New entrypoint.
+ * libgccjit.h: Add gcc_jit_extended_asm to ASCII art.
+ (gcc_jit_extended_asm): New typedef.
+ (LIBGCCJIT_HAVE_ASM_STATEMENTS): New define.
+ (gcc_jit_block_add_extended_asm): New entrypoint.
+ (gcc_jit_block_end_with_extended_asm_goto): New entrypoint.
+ (gcc_jit_extended_asm_as_object): New entrypoint.
+ (gcc_jit_extended_asm_set_volatile_flag): New entrypoint.
+ (gcc_jit_extended_asm_set_inline_flag): New entrypoint.
+ (gcc_jit_extended_asm_add_output_operand): New entrypoint.
+ (gcc_jit_extended_asm_add_input_operand): New entrypoint.
+ (gcc_jit_extended_asm_add_clobber): New entrypoint.
+ (gcc_jit_context_add_top_level_asm): New entrypoint.
+ * libgccjit.map (LIBGCCJIT_ABI_15): New.
+
+2020-11-12 David Malcolm <dmalcolm@redhat.com>
+
+ * jit-recording.c (recording::context::new_string): Add "escaped"
+ param and use it when creating the new recording::string instance.
+ (recording::string::string): Add "escaped" param and use it to
+ initialize m_escaped.
+ (recording::string::make_debug_string): Replace check that first
+ char is double-quote with use of m_escaped. Fix escaping of
+ '\t' and '\n'. Set "escaped" on the result.
+ * jit-recording.h (recording::context::new_string): Add "escaped"
+ param.
+ (recording::string::string): Add "escaped" param.
+ (recording::string::m_escaped): New field.
+
+2020-11-12 David Malcolm <dmalcolm@redhat.com>
+
+ * libgccjit.h: Fix typo in comment.
+
2020-09-14 Andrea Corallo <andrea.corallo@arm.com>
* docs/_build/texinfo/libgccjit.texi: Regenerate.
diff --git a/gcc/jit/Make-lang.in b/gcc/jit/Make-lang.in
index 3b54392..1d34d2a0 100644
--- a/gcc/jit/Make-lang.in
+++ b/gcc/jit/Make-lang.in
@@ -81,6 +81,8 @@ jit: $(LIBGCCJIT_FILENAME) \
$(FULL_DRIVER_NAME)
endif
+jit.serial = $(LIBGCCJIT_FILENAME)
+
# Tell GNU make to ignore these if they exist.
.PHONY: jit
@@ -117,12 +119,14 @@ $(LIBGCCJIT_FILENAME): $(jit_OBJS) \
libbackend.a libcommon-target.a libcommon.a \
$(CPPLIB) $(LIBDECNUMBER) \
$(LIBDEPS) $(srcdir)/jit/libgccjit.map \
- $(EXTRA_GCC_OBJS)
+ $(EXTRA_GCC_OBJS) $(jit.prev)
+ @$(call LINK_PROGRESS,$(INDEX.jit),start)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ -shared \
$(jit_OBJS) libbackend.a libcommon-target.a libcommon.a \
$(CPPLIB) $(LIBDECNUMBER) $(EXTRA_GCC_LIBS) $(LIBS) $(BACKENDLIBS) \
$(EXTRA_GCC_OBJS) \
$(LIBGCCJIT_EXTRA_OPTS)
+ @$(call LINK_PROGRESS,$(INDEX.jit),end)
# Create symlinks when not building for Windows
ifeq (,$(findstring mingw,$(target)))
diff --git a/gcc/jit/docs/_build/texinfo/Makefile b/gcc/jit/docs/_build/texinfo/Makefile
index 81c60f5..e3b732c 100644
--- a/gcc/jit/docs/_build/texinfo/Makefile
+++ b/gcc/jit/docs/_build/texinfo/Makefile
@@ -18,13 +18,20 @@ pdf: $(addsuffix .pdf,$(ALLDOCS))
install-info: info
for f in *.info; do \
- cp -t $(infodir) "$$f" && \
- $(INSTALL_INFO) --info-dir=$(infodir) "$$f" ; \
+ mkdir -p $(infodir) && \
+ cp "$$f" $(infodir) && \
+ $(INSTALL_INFO) --info-dir=$(infodir) "$$f" && \
+ \
+ FIGURE_DIR="`basename \"$$f\" .info`-figures" && \
+ if [ -e "$$FIGURE_DIR" ]; then \
+ cp -r "$$FIGURE_DIR" $(infodir) ; \
+ fi; \
done
uninstall-info: info
for f in *.info; do \
rm -f "$(infodir)/$$f" ; \
+ rm -rf "$(infodir)/`basename '$$f' .info`-figures" && \
$(INSTALL_INFO) --delete --info-dir=$(infodir) "$$f" ; \
done
diff --git a/gcc/jit/docs/_build/texinfo/libgccjit.texi b/gcc/jit/docs/_build/texinfo/libgccjit.texi
index 57aca7a..7b957b7 100644
--- a/gcc/jit/docs/_build/texinfo/libgccjit.texi
+++ b/gcc/jit/docs/_build/texinfo/libgccjit.texi
@@ -3,7 +3,7 @@
@setfilename libgccjit.info
@documentencoding UTF-8
@ifinfo
-@*Generated by Sphinx 1.6.7.@*
+@*Generated by Sphinx 2.2.2.@*
@end ifinfo
@settitle libgccjit Documentation
@defindex ge
@@ -21,7 +21,7 @@
@copying
@quotation
-libgccjit 11.0.0 (experimental 20200914), Sep 14, 2020
+libgccjit 11.0.0 (experimental 20201112), Nov 12, 2020
David Malcolm
@@ -173,6 +173,7 @@ Topic Reference
* Compiling a context::
* ABI and API compatibility::
* Performance::
+* Using Assembly Language with libgccjit::
Compilation contexts
@@ -256,11 +257,17 @@ ABI symbol tags
* LIBGCCJIT_ABI_12::
* LIBGCCJIT_ABI_13::
* LIBGCCJIT_ABI_14::
+* LIBGCCJIT_ABI_15::
Performance
* The timing API::
+Using Assembly Language with libgccjit
+
+* Adding assembler instructions within a function::
+* Adding top-level assembler statements::
+
C++ bindings for libgccjit
* Tutorial: Tutorial<2>.
@@ -312,6 +319,7 @@ Topic Reference
* Creating and using functions: Creating and using functions<2>.
* Source Locations: Source Locations<2>.
* Compiling a context: Compiling a context<2>.
+* Using Assembly Language with libgccjit++::
Compilation contexts
@@ -372,6 +380,11 @@ Compiling a context
* In-memory compilation: In-memory compilation<2>.
* Ahead-of-time compilation: Ahead-of-time compilation<2>.
+Using Assembly Language with libgccjit++
+
+* Adding assembler instructions within a function: Adding assembler instructions within a function<2>.
+* Adding top-level assembler statements: Adding top-level assembler statements<2>.
+
Internals
* Working on the JIT library::
@@ -390,7 +403,7 @@ Running the test suite
@end menu
@node Tutorial,Topic Reference,Top,Top
-@anchor{intro/index libgccjit}@anchor{1}@anchor{intro/index doc}@anchor{2}@anchor{intro/index tutorial}@anchor{3}
+@anchor{intro/index doc}@anchor{1}@anchor{intro/index libgccjit}@anchor{2}@anchor{intro/index tutorial}@anchor{3}
@chapter Tutorial
@@ -1122,7 +1135,7 @@ result: 25
@c <http://www.gnu.org/licenses/>.
@node Tutorial part 3 Loops and variables,Tutorial part 4 Adding JIT-compilation to a toy interpreter,Tutorial part 2 Creating a trivial machine code function,Tutorial
-@anchor{intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{21}@anchor{intro/tutorial03 doc}@anchor{22}
+@anchor{intro/tutorial03 doc}@anchor{21}@anchor{intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{22}
@section Tutorial part 3: Loops and variables
@@ -1171,7 +1184,7 @@ Here’s what the final control flow graph will look like:
@float Figure
-@image{sum-of-squares1,,,image of a control flow graph,png}
+@image{libgccjit-figures/sum-of-squares1,,,image of a control flow graph,png}
@end float
@@ -1520,7 +1533,7 @@ install it with @cite{yum install python-xdot}):
@float Figure
-@image{sum-of-squares1,,,image of a control flow graph,png}
+@image{libgccjit-figures/sum-of-squares1,,,image of a control flow graph,png}
@end float
@@ -1740,7 +1753,7 @@ loop_test returned: 285
@c <http://www.gnu.org/licenses/>.
@node Tutorial part 4 Adding JIT-compilation to a toy interpreter,Tutorial part 5 Implementing an Ahead-of-Time compiler,Tutorial part 3 Loops and variables,Tutorial
-@anchor{intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{35}@anchor{intro/tutorial04 doc}@anchor{36}
+@anchor{intro/tutorial04 doc}@anchor{35}@anchor{intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{36}
@section Tutorial part 4: Adding JIT-compilation to a toy interpreter
@@ -2716,7 +2729,7 @@ errors in our compiler.
@float Figure
-@image{factorial1,,,image of a control flow graph,png}
+@image{libgccjit-figures/factorial1,,,image of a control flow graph,png}
@end float
@@ -4435,11 +4448,12 @@ and to a dynamic library. See the documentation of
* Compiling a context::
* ABI and API compatibility::
* Performance::
+* Using Assembly Language with libgccjit::
@end menu
@node Compilation contexts,Objects,,Topic Reference
-@anchor{topics/contexts compilation-contexts}@anchor{51}@anchor{topics/contexts doc}@anchor{52}
+@anchor{topics/contexts doc}@anchor{51}@anchor{topics/contexts compilation-contexts}@anchor{52}
@section Compilation contexts
@@ -5130,7 +5144,7 @@ its presence using
@c <http://www.gnu.org/licenses/>.
@node Objects,Types,Compilation contexts,Topic Reference
-@anchor{topics/objects objects}@anchor{76}@anchor{topics/objects doc}@anchor{77}
+@anchor{topics/objects doc}@anchor{76}@anchor{topics/objects objects}@anchor{77}
@section Objects
@@ -5175,6 +5189,7 @@ looks like this:
+- gcc_jit_lvalue
+- gcc_jit_param
+- gcc_jit_case
+ +- gcc_jit_extended_asm
@end example
There are casting methods for upcasting from subclasses to parent classes.
@@ -5875,7 +5890,7 @@ Function pointer types can be created using
@c <http://www.gnu.org/licenses/>.
@node Expressions,Creating and using functions,Types,Topic Reference
-@anchor{topics/expressions expressions}@anchor{96}@anchor{topics/expressions doc}@anchor{97}
+@anchor{topics/expressions doc}@anchor{96}@anchor{topics/expressions expressions}@anchor{97}
@section Expressions
@@ -7520,6 +7535,9 @@ create_code (gcc_jit_context *ctxt, void *user_data)
@end quotation
@end deffn
+See also @ref{f1,,gcc_jit_extended_asm} for entrypoints for adding inline
+assembler statements to a function.
+
@c Copyright (C) 2017-2020 Free Software Foundation, Inc.
@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
@c
@@ -7538,7 +7556,7 @@ create_code (gcc_jit_context *ctxt, void *user_data)
@c <http://www.gnu.org/licenses/>.
@node Function pointers<2>,Source Locations,Creating and using functions,Topic Reference
-@anchor{topics/function-pointers doc}@anchor{f1}@anchor{topics/function-pointers function-pointers}@anchor{f2}
+@anchor{topics/function-pointers doc}@anchor{f2}@anchor{topics/function-pointers function-pointers}@anchor{f3}
@section Function pointers
@@ -7557,7 +7575,7 @@ via @ref{c0,,gcc_jit_function_get_address()}.
Get the address of a function as an rvalue, of function pointer
type.
-This entrypoint was added in @ref{f3,,LIBGCCJIT_ABI_9}; you can test
+This entrypoint was added in @ref{f4,,LIBGCCJIT_ABI_9}; you can test
for its presence using
@example
@@ -7619,7 +7637,7 @@ Each of @cite{param_types} must be non-@cite{void}; @cite{return_type} may be @c
@c <http://www.gnu.org/licenses/>.
@node Source Locations,Compiling a context,Function pointers<2>,Topic Reference
-@anchor{topics/locations source-locations}@anchor{f4}@anchor{topics/locations doc}@anchor{f5}
+@anchor{topics/locations doc}@anchor{f5}@anchor{topics/locations source-locations}@anchor{f6}
@section Source Locations
@@ -7667,7 +7685,7 @@ on-stack buffer.
@end menu
@node Faking it,,,Source Locations
-@anchor{topics/locations faking-it}@anchor{f6}
+@anchor{topics/locations faking-it}@anchor{f7}
@subsection Faking it
@@ -7703,7 +7721,7 @@ file, giving you @emph{something} you can step through in the debugger.
@c <http://www.gnu.org/licenses/>.
@node Compiling a context,ABI and API compatibility,Source Locations,Topic Reference
-@anchor{topics/compilation compiling-a-context}@anchor{f7}@anchor{topics/compilation doc}@anchor{f8}
+@anchor{topics/compilation doc}@anchor{f8}@anchor{topics/compilation compiling-a-context}@anchor{f9}
@section Compiling a context
@@ -7722,7 +7740,7 @@ prevent any future compilation of that context.
@end menu
@node In-memory compilation,Ahead-of-time compilation,,Compiling a context
-@anchor{topics/compilation in-memory-compilation}@anchor{f9}
+@anchor{topics/compilation in-memory-compilation}@anchor{fa}
@subsection In-memory compilation
@@ -7842,7 +7860,7 @@ by calling @ref{17,,gcc_jit_result_get_code()} or
@end deffn
@node Ahead-of-time compilation,,In-memory compilation,Compiling a context
-@anchor{topics/compilation ahead-of-time-compilation}@anchor{fa}
+@anchor{topics/compilation ahead-of-time-compilation}@anchor{fb}
@subsection Ahead-of-time compilation
@@ -7871,7 +7889,7 @@ suffix of the output file when determining what to do.
@end cartouche
@geindex gcc_jit_output_kind (C type)
-@anchor{topics/compilation c gcc_jit_output_kind}@anchor{fb}
+@anchor{topics/compilation c gcc_jit_output_kind}@anchor{fc}
@deffn {C Type} enum gcc_jit_output_kind
@end deffn
@@ -7889,7 +7907,7 @@ Typical suffix
@item
-@ref{fc,,GCC_JIT_OUTPUT_KIND_ASSEMBLER}
+@ref{fd,,GCC_JIT_OUTPUT_KIND_ASSEMBLER}
@tab
@@ -7897,7 +7915,7 @@ Typical suffix
@item
-@ref{fd,,GCC_JIT_OUTPUT_KIND_OBJECT_FILE}
+@ref{fe,,GCC_JIT_OUTPUT_KIND_OBJECT_FILE}
@tab
@@ -7905,7 +7923,7 @@ Typical suffix
@item
-@ref{fe,,GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY}
+@ref{ff,,GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY}
@tab
@@ -7913,7 +7931,7 @@ Typical suffix
@item
-@ref{ff,,GCC_JIT_OUTPUT_KIND_EXECUTABLE}
+@ref{100,,GCC_JIT_OUTPUT_KIND_EXECUTABLE}
@tab
@@ -7923,21 +7941,21 @@ None, or .exe
@geindex GCC_JIT_OUTPUT_KIND_ASSEMBLER (C macro)
-@anchor{topics/compilation c GCC_JIT_OUTPUT_KIND_ASSEMBLER}@anchor{fc}
+@anchor{topics/compilation c GCC_JIT_OUTPUT_KIND_ASSEMBLER}@anchor{fd}
@deffn {C Macro} GCC_JIT_OUTPUT_KIND_ASSEMBLER
Compile the context to an assembler file.
@end deffn
@geindex GCC_JIT_OUTPUT_KIND_OBJECT_FILE (C macro)
-@anchor{topics/compilation c GCC_JIT_OUTPUT_KIND_OBJECT_FILE}@anchor{fd}
+@anchor{topics/compilation c GCC_JIT_OUTPUT_KIND_OBJECT_FILE}@anchor{fe}
@deffn {C Macro} GCC_JIT_OUTPUT_KIND_OBJECT_FILE
Compile the context to an object file.
@end deffn
@geindex GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY (C macro)
-@anchor{topics/compilation c GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY}@anchor{fe}
+@anchor{topics/compilation c GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY}@anchor{ff}
@deffn {C Macro} GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY
Compile the context to a dynamic library.
@@ -7947,7 +7965,7 @@ against.
@end deffn
@geindex GCC_JIT_OUTPUT_KIND_EXECUTABLE (C macro)
-@anchor{topics/compilation c GCC_JIT_OUTPUT_KIND_EXECUTABLE}@anchor{ff}
+@anchor{topics/compilation c GCC_JIT_OUTPUT_KIND_EXECUTABLE}@anchor{100}
@deffn {C Macro} GCC_JIT_OUTPUT_KIND_EXECUTABLE
Compile the context to an executable.
@@ -7974,7 +7992,7 @@ against.
@c <http://www.gnu.org/licenses/>.
@node ABI and API compatibility,Performance,Compiling a context,Topic Reference
-@anchor{topics/compatibility abi-and-api-compatibility}@anchor{100}@anchor{topics/compatibility doc}@anchor{101}
+@anchor{topics/compatibility doc}@anchor{101}@anchor{topics/compatibility abi-and-api-compatibility}@anchor{102}
@section ABI and API compatibility
@@ -8030,21 +8048,21 @@ Version definitions:
@end menu
@node Programmatically checking version,ABI symbol tags,,ABI and API compatibility
-@anchor{topics/compatibility programmatically-checking-version}@anchor{102}
+@anchor{topics/compatibility programmatically-checking-version}@anchor{103}
@subsection Programmatically checking version
Client code can programmatically check libgccjit version using:
@geindex gcc_jit_version_major (C function)
-@anchor{topics/compatibility c gcc_jit_version_major}@anchor{103}
+@anchor{topics/compatibility c gcc_jit_version_major}@anchor{104}
@deffn {C Function} int gcc_jit_version_major (void)
Return libgccjit major version. This is analogous to __GNUC__ in C code.
@end deffn
@geindex gcc_jit_version_minor (C function)
-@anchor{topics/compatibility c gcc_jit_version_minor}@anchor{104}
+@anchor{topics/compatibility c gcc_jit_version_minor}@anchor{105}
@deffn {C Function} int gcc_jit_version_minor (void)
Return libgccjit minor version. This is analogous to
@@ -8052,7 +8070,7 @@ __GNUC_MINOR__ in C code.
@end deffn
@geindex gcc_jit_version_patchlevel (C function)
-@anchor{topics/compatibility c gcc_jit_version_patchlevel}@anchor{105}
+@anchor{topics/compatibility c gcc_jit_version_patchlevel}@anchor{106}
@deffn {C Function} int gcc_jit_version_patchlevel (void)
Return libgccjit patchlevel version. This is analogous to
@@ -8067,7 +8085,7 @@ These entry points has been added with @code{LIBGCCJIT_ABI_13}
@end cartouche
@node ABI symbol tags,,Programmatically checking version,ABI and API compatibility
-@anchor{topics/compatibility abi-symbol-tags}@anchor{106}
+@anchor{topics/compatibility abi-symbol-tags}@anchor{107}
@subsection ABI symbol tags
@@ -8091,11 +8109,12 @@ Newer releases use the following tags.
* LIBGCCJIT_ABI_12::
* LIBGCCJIT_ABI_13::
* LIBGCCJIT_ABI_14::
+* LIBGCCJIT_ABI_15::
@end menu
@node LIBGCCJIT_ABI_0,LIBGCCJIT_ABI_1,,ABI symbol tags
-@anchor{topics/compatibility libgccjit-abi-0}@anchor{107}@anchor{topics/compatibility id1}@anchor{108}
+@anchor{topics/compatibility id1}@anchor{108}@anchor{topics/compatibility libgccjit-abi-0}@anchor{109}
@subsubsection @code{LIBGCCJIT_ABI_0}
@@ -8107,7 +8126,7 @@ continue to work, with this being handled transparently by the linker
(see this post@footnote{https://gcc.gnu.org/ml/gcc-patches/2015-06/msg02126.html})
@node LIBGCCJIT_ABI_1,LIBGCCJIT_ABI_2,LIBGCCJIT_ABI_0,ABI symbol tags
-@anchor{topics/compatibility libgccjit-abi-1}@anchor{73}@anchor{topics/compatibility id2}@anchor{109}
+@anchor{topics/compatibility id2}@anchor{10a}@anchor{topics/compatibility libgccjit-abi-1}@anchor{73}
@subsubsection @code{LIBGCCJIT_ABI_1}
@@ -8115,7 +8134,7 @@ continue to work, with this being handled transparently by the linker
@ref{72,,gcc_jit_context_add_command_line_option()}
@node LIBGCCJIT_ABI_2,LIBGCCJIT_ABI_3,LIBGCCJIT_ABI_1,ABI symbol tags
-@anchor{topics/compatibility libgccjit-abi-2}@anchor{6c}@anchor{topics/compatibility id3}@anchor{10a}
+@anchor{topics/compatibility id3}@anchor{10b}@anchor{topics/compatibility libgccjit-abi-2}@anchor{6c}
@subsubsection @code{LIBGCCJIT_ABI_2}
@@ -8123,7 +8142,7 @@ continue to work, with this being handled transparently by the linker
@ref{6b,,gcc_jit_context_set_bool_allow_unreachable_blocks()}
@node LIBGCCJIT_ABI_3,LIBGCCJIT_ABI_4,LIBGCCJIT_ABI_2,ABI symbol tags
-@anchor{topics/compatibility libgccjit-abi-3}@anchor{ef}@anchor{topics/compatibility id4}@anchor{10b}
+@anchor{topics/compatibility id4}@anchor{10c}@anchor{topics/compatibility libgccjit-abi-3}@anchor{ef}
@subsubsection @code{LIBGCCJIT_ABI_3}
@@ -8147,7 +8166,7 @@ entrypoints:
@end quotation
@node LIBGCCJIT_ABI_4,LIBGCCJIT_ABI_5,LIBGCCJIT_ABI_3,ABI symbol tags
-@anchor{topics/compatibility id5}@anchor{10c}@anchor{topics/compatibility libgccjit-abi-4}@anchor{10d}
+@anchor{topics/compatibility id5}@anchor{10d}@anchor{topics/compatibility libgccjit-abi-4}@anchor{10e}
@subsubsection @code{LIBGCCJIT_ABI_4}
@@ -8160,30 +8179,30 @@ entrypoints:
@itemize *
@item
-@ref{10e,,gcc_jit_context_get_timer()}
+@ref{10f,,gcc_jit_context_get_timer()}
@item
-@ref{10f,,gcc_jit_context_set_timer()}
+@ref{110,,gcc_jit_context_set_timer()}
@item
-@ref{110,,gcc_jit_timer_new()}
+@ref{111,,gcc_jit_timer_new()}
@item
-@ref{111,,gcc_jit_timer_release()}
+@ref{112,,gcc_jit_timer_release()}
@item
-@ref{112,,gcc_jit_timer_push()}
+@ref{113,,gcc_jit_timer_push()}
@item
-@ref{113,,gcc_jit_timer_pop()}
+@ref{114,,gcc_jit_timer_pop()}
@item
-@ref{114,,gcc_jit_timer_print()}
+@ref{115,,gcc_jit_timer_print()}
@end itemize
@end quotation
@node LIBGCCJIT_ABI_5,LIBGCCJIT_ABI_6,LIBGCCJIT_ABI_4,ABI symbol tags
-@anchor{topics/compatibility id6}@anchor{115}@anchor{topics/compatibility libgccjit-abi-5}@anchor{6e}
+@anchor{topics/compatibility id6}@anchor{116}@anchor{topics/compatibility libgccjit-abi-5}@anchor{6e}
@subsubsection @code{LIBGCCJIT_ABI_5}
@@ -8191,7 +8210,7 @@ entrypoints:
@ref{6d,,gcc_jit_context_set_bool_use_external_driver()}
@node LIBGCCJIT_ABI_6,LIBGCCJIT_ABI_7,LIBGCCJIT_ABI_5,ABI symbol tags
-@anchor{topics/compatibility id7}@anchor{116}@anchor{topics/compatibility libgccjit-abi-6}@anchor{be}
+@anchor{topics/compatibility id7}@anchor{117}@anchor{topics/compatibility libgccjit-abi-6}@anchor{be}
@subsubsection @code{LIBGCCJIT_ABI_6}
@@ -8199,7 +8218,7 @@ entrypoints:
@ref{bd,,gcc_jit_rvalue_set_bool_require_tail_call()}
@node LIBGCCJIT_ABI_7,LIBGCCJIT_ABI_8,LIBGCCJIT_ABI_6,ABI symbol tags
-@anchor{topics/compatibility libgccjit-abi-7}@anchor{83}@anchor{topics/compatibility id8}@anchor{117}
+@anchor{topics/compatibility id8}@anchor{118}@anchor{topics/compatibility libgccjit-abi-7}@anchor{83}
@subsubsection @code{LIBGCCJIT_ABI_7}
@@ -8207,7 +8226,7 @@ entrypoints:
@ref{82,,gcc_jit_type_get_aligned()}
@node LIBGCCJIT_ABI_8,LIBGCCJIT_ABI_9,LIBGCCJIT_ABI_7,ABI symbol tags
-@anchor{topics/compatibility libgccjit-abi-8}@anchor{86}@anchor{topics/compatibility id9}@anchor{118}
+@anchor{topics/compatibility id9}@anchor{119}@anchor{topics/compatibility libgccjit-abi-8}@anchor{86}
@subsubsection @code{LIBGCCJIT_ABI_8}
@@ -8215,7 +8234,7 @@ entrypoints:
@ref{85,,gcc_jit_type_get_vector()}
@node LIBGCCJIT_ABI_9,LIBGCCJIT_ABI_10,LIBGCCJIT_ABI_8,ABI symbol tags
-@anchor{topics/compatibility id10}@anchor{119}@anchor{topics/compatibility libgccjit-abi-9}@anchor{f3}
+@anchor{topics/compatibility id10}@anchor{11a}@anchor{topics/compatibility libgccjit-abi-9}@anchor{f4}
@subsubsection @code{LIBGCCJIT_ABI_9}
@@ -8223,7 +8242,7 @@ entrypoints:
@ref{c0,,gcc_jit_function_get_address()}
@node LIBGCCJIT_ABI_10,LIBGCCJIT_ABI_11,LIBGCCJIT_ABI_9,ABI symbol tags
-@anchor{topics/compatibility id11}@anchor{11a}@anchor{topics/compatibility libgccjit-abi-10}@anchor{a0}
+@anchor{topics/compatibility id11}@anchor{11b}@anchor{topics/compatibility libgccjit-abi-10}@anchor{a0}
@subsubsection @code{LIBGCCJIT_ABI_10}
@@ -8231,7 +8250,7 @@ entrypoints:
@ref{87,,gcc_jit_context_new_rvalue_from_vector()}
@node LIBGCCJIT_ABI_11,LIBGCCJIT_ABI_12,LIBGCCJIT_ABI_10,ABI symbol tags
-@anchor{topics/compatibility id12}@anchor{11b}@anchor{topics/compatibility libgccjit-abi-11}@anchor{75}
+@anchor{topics/compatibility id12}@anchor{11c}@anchor{topics/compatibility libgccjit-abi-11}@anchor{75}
@subsubsection @code{LIBGCCJIT_ABI_11}
@@ -8239,7 +8258,7 @@ entrypoints:
@ref{74,,gcc_jit_context_add_driver_option()}
@node LIBGCCJIT_ABI_12,LIBGCCJIT_ABI_13,LIBGCCJIT_ABI_11,ABI symbol tags
-@anchor{topics/compatibility id13}@anchor{11c}@anchor{topics/compatibility libgccjit-abi-12}@anchor{8d}
+@anchor{topics/compatibility id13}@anchor{11d}@anchor{topics/compatibility libgccjit-abi-12}@anchor{8d}
@subsubsection @code{LIBGCCJIT_ABI_12}
@@ -8247,7 +8266,7 @@ entrypoints:
@ref{8c,,gcc_jit_context_new_bitfield()}
@node LIBGCCJIT_ABI_13,LIBGCCJIT_ABI_14,LIBGCCJIT_ABI_12,ABI symbol tags
-@anchor{topics/compatibility id14}@anchor{11d}@anchor{topics/compatibility libgccjit-abi-13}@anchor{11e}
+@anchor{topics/compatibility id14}@anchor{11e}@anchor{topics/compatibility libgccjit-abi-13}@anchor{11f}
@subsubsection @code{LIBGCCJIT_ABI_13}
@@ -8260,24 +8279,66 @@ entrypoints:
@itemize *
@item
-@ref{103,,gcc_jit_version_major()}
+@ref{104,,gcc_jit_version_major()}
@item
-@ref{104,,gcc_jit_version_minor()}
+@ref{105,,gcc_jit_version_minor()}
@item
-@ref{105,,gcc_jit_version_patchlevel()}
+@ref{106,,gcc_jit_version_patchlevel()}
@end itemize
@end quotation
-@node LIBGCCJIT_ABI_14,,LIBGCCJIT_ABI_13,ABI symbol tags
-@anchor{topics/compatibility libgccjit-abi-14}@anchor{cf}@anchor{topics/compatibility id15}@anchor{11f}
+@node LIBGCCJIT_ABI_14,LIBGCCJIT_ABI_15,LIBGCCJIT_ABI_13,ABI symbol tags
+@anchor{topics/compatibility id15}@anchor{120}@anchor{topics/compatibility libgccjit-abi-14}@anchor{cf}
@subsubsection @code{LIBGCCJIT_ABI_14}
@code{LIBGCCJIT_ABI_14} covers the addition of
@ref{ce,,gcc_jit_global_set_initializer()}
+@node LIBGCCJIT_ABI_15,,LIBGCCJIT_ABI_14,ABI symbol tags
+@anchor{topics/compatibility id16}@anchor{121}@anchor{topics/compatibility libgccjit-abi-15}@anchor{122}
+@subsubsection @code{LIBGCCJIT_ABI_15}
+
+
+@code{LIBGCCJIT_ABI_15} covers the addition of API entrypoints for directly
+embedding assembler instructions:
+
+@quotation
+
+
+@itemize *
+
+@item
+@ref{123,,gcc_jit_block_add_extended_asm()}
+
+@item
+@ref{124,,gcc_jit_block_end_with_extended_asm_goto()}
+
+@item
+@ref{125,,gcc_jit_extended_asm_as_object()}
+
+@item
+@ref{126,,gcc_jit_extended_asm_set_volatile_flag()}
+
+@item
+@ref{127,,gcc_jit_extended_asm_set_inline_flag()}
+
+@item
+@ref{128,,gcc_jit_extended_asm_add_output_operand()}
+
+@item
+@ref{129,,gcc_jit_extended_asm_add_input_operand()}
+
+@item
+@ref{12a,,gcc_jit_extended_asm_add_clobber()}
+
+@item
+@ref{12b,,gcc_jit_context_add_top_level_asm()}
+@end itemize
+@end quotation
+
@c Copyright (C) 2015-2020 Free Software Foundation, Inc.
@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
@c
@@ -8295,8 +8356,8 @@ entrypoints:
@c along with this program. If not, see
@c <http://www.gnu.org/licenses/>.
-@node Performance,,ABI and API compatibility,Topic Reference
-@anchor{topics/performance performance}@anchor{120}@anchor{topics/performance doc}@anchor{121}
+@node Performance,Using Assembly Language with libgccjit,ABI and API compatibility,Topic Reference
+@anchor{topics/performance doc}@anchor{12c}@anchor{topics/performance performance}@anchor{12d}
@section Performance
@@ -8306,14 +8367,14 @@ entrypoints:
@end menu
@node The timing API,,,Performance
-@anchor{topics/performance the-timing-api}@anchor{122}
+@anchor{topics/performance the-timing-api}@anchor{12e}
@subsection The timing API
As of GCC 6, libgccjit exposes a timing API, for printing reports on
how long was spent in different parts of code.
-You can create a @ref{123,,gcc_jit_timer} instance, which will
+You can create a @ref{12f,,gcc_jit_timer} instance, which will
measure time spent since its creation. The timer maintains a stack
of “timer items”: as control flow moves through your code, you can push
and pop named items relating to your code onto the stack, and the timer
@@ -8411,7 +8472,7 @@ Client items:
The exact format is intended to be human-readable, and is subject to change.
@geindex LIBGCCJIT_HAVE_TIMING_API (C macro)
-@anchor{topics/performance c LIBGCCJIT_HAVE_TIMING_API}@anchor{124}
+@anchor{topics/performance c LIBGCCJIT_HAVE_TIMING_API}@anchor{130}
@deffn {C Macro} LIBGCCJIT_HAVE_TIMING_API
The timer API was added to libgccjit in GCC 6.
@@ -8428,21 +8489,21 @@ gcc_jit_context_set_timer (ctxt, t);
@end deffn
@geindex gcc_jit_timer (C type)
-@anchor{topics/performance c gcc_jit_timer}@anchor{123}
+@anchor{topics/performance c gcc_jit_timer}@anchor{12f}
@deffn {C Type} gcc_jit_timer
@end deffn
@geindex gcc_jit_timer_new (C function)
-@anchor{topics/performance c gcc_jit_timer_new}@anchor{110}
+@anchor{topics/performance c gcc_jit_timer_new}@anchor{111}
@deffn {C Function} gcc_jit_timer * gcc_jit_timer_new (void)
-Create a @ref{123,,gcc_jit_timer} instance, and start timing:
+Create a @ref{12f,,gcc_jit_timer} instance, and start timing:
@example
gcc_jit_timer *t = gcc_jit_timer_new ();
@end example
-This API entrypoint was added in @ref{10d,,LIBGCCJIT_ABI_4}; you can test
+This API entrypoint was added in @ref{10e,,LIBGCCJIT_ABI_4}; you can test
for its presence using
@example
@@ -8451,10 +8512,10 @@ for its presence using
@end deffn
@geindex gcc_jit_timer_release (C function)
-@anchor{topics/performance c gcc_jit_timer_release}@anchor{111}
+@anchor{topics/performance c gcc_jit_timer_release}@anchor{112}
@deffn {C Function} void gcc_jit_timer_release (gcc_jit_timer@w{ }*timer)
-Release a @ref{123,,gcc_jit_timer} instance:
+Release a @ref{12f,,gcc_jit_timer} instance:
@example
gcc_jit_timer_release (t);
@@ -8462,7 +8523,7 @@ gcc_jit_timer_release (t);
This should be called exactly once on a timer.
-This API entrypoint was added in @ref{10d,,LIBGCCJIT_ABI_4}; you can test
+This API entrypoint was added in @ref{10e,,LIBGCCJIT_ABI_4}; you can test
for its presence using
@example
@@ -8471,10 +8532,10 @@ for its presence using
@end deffn
@geindex gcc_jit_context_set_timer (C function)
-@anchor{topics/performance c gcc_jit_context_set_timer}@anchor{10f}
+@anchor{topics/performance c gcc_jit_context_set_timer}@anchor{110}
@deffn {C Function} void gcc_jit_context_set_timer (gcc_jit_context@w{ }*ctxt, gcc_jit_timer@w{ }*timer)
-Associate a @ref{123,,gcc_jit_timer} instance with a context:
+Associate a @ref{12f,,gcc_jit_timer} instance with a context:
@example
gcc_jit_context_set_timer (ctxt, t);
@@ -8487,7 +8548,7 @@ Timers have no locking, so if you have a multithreaded program, you
must provide your own locks if more than one thread could be working
with the same timer via timer-associated contexts.
-This API entrypoint was added in @ref{10d,,LIBGCCJIT_ABI_4}; you can test
+This API entrypoint was added in @ref{10e,,LIBGCCJIT_ABI_4}; you can test
for its presence using
@example
@@ -8496,12 +8557,12 @@ for its presence using
@end deffn
@geindex gcc_jit_context_get_timer (C function)
-@anchor{topics/performance c gcc_jit_context_get_timer}@anchor{10e}
+@anchor{topics/performance c gcc_jit_context_get_timer}@anchor{10f}
@deffn {C Function} gcc_jit_timer *gcc_jit_context_get_timer (gcc_jit_context@w{ }*ctxt)
Get the timer associated with a context (if any).
-This API entrypoint was added in @ref{10d,,LIBGCCJIT_ABI_4}; you can test
+This API entrypoint was added in @ref{10e,,LIBGCCJIT_ABI_4}; you can test
for its presence using
@example
@@ -8510,7 +8571,7 @@ for its presence using
@end deffn
@geindex gcc_jit_timer_push (C function)
-@anchor{topics/performance c gcc_jit_timer_push}@anchor{112}
+@anchor{topics/performance c gcc_jit_timer_push}@anchor{113}
@deffn {C Function} void gcc_jit_timer_push (gcc_jit_timer@w{ }*timer, const char@w{ }*item_name)
Push the given item onto the timer’s stack:
@@ -8521,7 +8582,7 @@ run_the_code (ctxt, result);
gcc_jit_timer_pop (t, "running code");
@end example
-This API entrypoint was added in @ref{10d,,LIBGCCJIT_ABI_4}; you can test
+This API entrypoint was added in @ref{10e,,LIBGCCJIT_ABI_4}; you can test
for its presence using
@example
@@ -8530,7 +8591,7 @@ for its presence using
@end deffn
@geindex gcc_jit_timer_pop (C function)
-@anchor{topics/performance c gcc_jit_timer_pop}@anchor{113}
+@anchor{topics/performance c gcc_jit_timer_pop}@anchor{114}
@deffn {C Function} void gcc_jit_timer_pop (gcc_jit_timer@w{ }*timer, const char@w{ }*item_name)
Pop the top item from the timer’s stack.
@@ -8538,7 +8599,7 @@ Pop the top item from the timer’s stack.
If “item_name” is provided, it must match that of the top item.
Alternatively, @code{NULL} can be passed in, to suppress checking.
-This API entrypoint was added in @ref{10d,,LIBGCCJIT_ABI_4}; you can test
+This API entrypoint was added in @ref{10e,,LIBGCCJIT_ABI_4}; you can test
for its presence using
@example
@@ -8547,13 +8608,13 @@ for its presence using
@end deffn
@geindex gcc_jit_timer_print (C function)
-@anchor{topics/performance c gcc_jit_timer_print}@anchor{114}
+@anchor{topics/performance c gcc_jit_timer_print}@anchor{115}
@deffn {C Function} void gcc_jit_timer_print (gcc_jit_timer@w{ }*timer, FILE@w{ }*f_out)
Print timing information to the given stream about activity since
the timer was started.
-This API entrypoint was added in @ref{10d,,LIBGCCJIT_ABI_4}; you can test
+This API entrypoint was added in @ref{10e,,LIBGCCJIT_ABI_4}; you can test
for its presence using
@example
@@ -8561,6 +8622,403 @@ for its presence using
@end example
@end deffn
+@c Copyright (C) 2020 Free Software Foundation, Inc.
+@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
+@c
+@c This is free software: you can redistribute it and/or modify it
+@c under the terms of the GNU General Public License as published by
+@c the Free Software Foundation, either version 3 of the License, or
+@c (at your option) any later version.
+@c
+@c This program is distributed in the hope that it will be useful, but
+@c WITHOUT ANY WARRANTY; without even the implied warranty of
+@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+@c General Public License for more details.
+@c
+@c You should have received a copy of the GNU General Public License
+@c along with this program. If not, see
+@c <http://www.gnu.org/licenses/>.
+
+@node Using Assembly Language with libgccjit,,Performance,Topic Reference
+@anchor{topics/asm doc}@anchor{131}@anchor{topics/asm using-assembly-language-with-libgccjit}@anchor{132}
+@section Using Assembly Language with libgccjit
+
+
+libgccjit has some support for directly embedding assembler instructions.
+This is based on GCC’s support for inline @code{asm} in C code, and the
+following assumes a familiarity with that functionality. See
+How to Use Inline Assembly Language in C Code@footnote{https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html}
+in GCC’s documentation, the “Extended Asm” section in particular.
+
+These entrypoints were added in @ref{122,,LIBGCCJIT_ABI_15}; you can test
+for their presence using
+
+@quotation
+
+@example
+#ifdef LIBGCCJIT_HAVE_ASM_STATEMENTS
+@end example
+@end quotation
+
+@menu
+* Adding assembler instructions within a function::
+* Adding top-level assembler statements::
+
+@end menu
+
+@node Adding assembler instructions within a function,Adding top-level assembler statements,,Using Assembly Language with libgccjit
+@anchor{topics/asm adding-assembler-instructions-within-a-function}@anchor{133}
+@subsection Adding assembler instructions within a function
+
+
+@geindex gcc_jit_extended_asm (C type)
+@anchor{topics/asm c gcc_jit_extended_asm}@anchor{f1}
+@deffn {C Type} gcc_jit_extended_asm
+
+A @cite{gcc_jit_extended_asm} represents an extended @code{asm} statement: a
+series of low-level instructions inside a function that convert inputs
+to outputs.
+
+To avoid having an API entrypoint with a very large number of
+parameters, an extended @code{asm} statement is made in stages:
+an initial call to create the @ref{f1,,gcc_jit_extended_asm},
+followed by calls to add operands and set other properties of the
+statement.
+
+There are two API entrypoints for creating a @ref{f1,,gcc_jit_extended_asm}:
+
+
+@itemize *
+
+@item
+@ref{123,,gcc_jit_block_add_extended_asm()} for an @code{asm} statement with
+no control flow, and
+
+@item
+@ref{124,,gcc_jit_block_end_with_extended_asm_goto()} for an @code{asm goto}.
+@end itemize
+
+For example, to create the equivalent of:
+
+@example
+ asm ("mov %1, %0\n\t"
+ "add $1, %0"
+ : "=r" (dst)
+ : "r" (src));
+@end example
+
+the following API calls could be used:
+
+@example
+ gcc_jit_extended_asm *ext_asm
+ = gcc_jit_block_add_extended_asm (block, NULL,
+ "mov %1, %0\n\t"
+ "add $1, %0");
+ gcc_jit_extended_asm_add_output_operand (ext_asm, NULL, "=r", dst);
+ gcc_jit_extended_asm_add_input_operand (ext_asm, NULL, "r",
+ gcc_jit_lvalue_as_rvalue (src));
+@end example
+
+@cartouche
+@quotation Warning
+When considering the numbering of operands within an
+extended @code{asm} statement (e.g. the @code{%0} and @code{%1}
+above), the equivalent to the C syntax is followed i.e. all
+output operands, then all input operands, regardless of
+what order the calls to
+@ref{128,,gcc_jit_extended_asm_add_output_operand()} and
+@ref{129,,gcc_jit_extended_asm_add_input_operand()} were made in.
+@end quotation
+@end cartouche
+
+As in the C syntax, operands can be given symbolic names to avoid having
+to number them. For example, to create the equivalent of:
+
+@example
+ asm ("bsfl %[aMask], %[aIndex]"
+ : [aIndex] "=r" (Index)
+ : [aMask] "r" (Mask)
+ : "cc");
+@end example
+
+the following API calls could be used:
+
+@example
+ gcc_jit_extended_asm *ext_asm
+ = gcc_jit_block_add_extended_asm (block, NULL,
+ "bsfl %[aMask], %[aIndex]");
+ gcc_jit_extended_asm_add_output_operand (ext_asm, "aIndex", "=r", index);
+ gcc_jit_extended_asm_add_input_operand (ext_asm, "aMask", "r",
+ gcc_jit_param_as_rvalue (mask));
+ gcc_jit_extended_asm_add_clobber (ext_asm, "cc");
+@end example
+@end deffn
+
+@geindex gcc_jit_block_add_extended_asm (C function)
+@anchor{topics/asm c gcc_jit_block_add_extended_asm}@anchor{123}
+@deffn {C Function} gcc_jit_extended_asm * gcc_jit_block_add_extended_asm (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, const char@w{ }*asm_template)
+
+Create a @ref{f1,,gcc_jit_extended_asm} for an extended @code{asm} statement
+with no control flow (i.e. without the @code{goto} qualifier).
+
+The parameter @code{asm_template} corresponds to the @cite{AssemblerTemplate}
+within C’s extended @code{asm} syntax. It must be non-NULL. The call takes
+a copy of the underlying string, so it is valid to pass in a pointer to
+an on-stack buffer.
+@end deffn
+
+@geindex gcc_jit_block_end_with_extended_asm_goto (C function)
+@anchor{topics/asm c gcc_jit_block_end_with_extended_asm_goto}@anchor{124}
+@deffn {C Function} gcc_jit_extended_asm * gcc_jit_block_end_with_extended_asm_goto (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, const char@w{ }*asm_template, int@w{ }num_goto_blocks, gcc_jit_block@w{ }**goto_blocks, gcc_jit_block@w{ }*fallthrough_block)
+
+Create a @ref{f1,,gcc_jit_extended_asm} for an extended @code{asm} statement
+that may perform jumps, and use it to terminate the given block.
+This is equivalent to the @code{goto} qualifier in C’s extended @code{asm}
+syntax.
+
+For example, to create the equivalent of:
+
+@example
+ asm goto ("btl %1, %0\n\t"
+ "jc %l[carry]"
+ : // No outputs
+ : "r" (p1), "r" (p2)
+ : "cc"
+ : carry);
+@end example
+
+the following API calls could be used:
+
+@example
+ const char *asm_template =
+ (use_name
+ ? /* Label referred to by name: "%l[carry]". */
+ ("btl %1, %0\n\t"
+ "jc %l[carry]")
+ : /* Label referred to numerically: "%l2". */
+ ("btl %1, %0\n\t"
+ "jc %l2"));
+
+ gcc_jit_extended_asm *ext_asm
+ = gcc_jit_block_end_with_extended_asm_goto (b_start, NULL,
+ asm_template,
+ 1, &b_carry,
+ b_fallthru);
+ gcc_jit_extended_asm_add_input_operand (ext_asm, NULL, "r",
+ gcc_jit_param_as_rvalue (p1));
+ gcc_jit_extended_asm_add_input_operand (ext_asm, NULL, "r",
+ gcc_jit_param_as_rvalue (p2));
+ gcc_jit_extended_asm_add_clobber (ext_asm, "cc");
+@end example
+
+here referencing a @ref{28,,gcc_jit_block} named “carry”.
+
+@code{num_goto_blocks} must be >= 0.
+
+@code{goto_blocks} must be non-NULL. This corresponds to the @code{GotoLabels}
+parameter within C’s extended @code{asm} syntax. The block names can be
+referenced within the assembler template.
+
+@code{fallthrough_block} can be NULL. If non-NULL, it specifies the block
+to fall through to after the statement.
+
+@cartouche
+@quotation Note
+This is needed since each @ref{28,,gcc_jit_block} must have a
+single exit point, as a basic block: you can’t jump from the
+middle of a block. A “goto” is implicitly added after the
+asm to handle the fallthrough case, which is equivalent to what
+would have happened in the C case.
+@end quotation
+@end cartouche
+@end deffn
+
+@geindex gcc_jit_extended_asm_set_volatile_flag (C function)
+@anchor{topics/asm c gcc_jit_extended_asm_set_volatile_flag}@anchor{126}
+@deffn {C Function} void gcc_jit_extended_asm_set_volatile_flag (gcc_jit_extended_asm@w{ }*ext_asm, int@w{ }flag)
+
+Set whether the @ref{f1,,gcc_jit_extended_asm} has side-effects, equivalent to the
+volatile@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile}
+qualifier in C’s extended asm syntax.
+
+For example, to create the equivalent of:
+
+@example
+asm volatile ("rdtsc\n\t" // Returns the time in EDX:EAX.
+ "shl $32, %%rdx\n\t" // Shift the upper bits left.
+ "or %%rdx, %0" // 'Or' in the lower bits.
+ : "=a" (msr)
+ :
+ : "rdx");
+@end example
+
+the following API calls could be used:
+
+@example
+ gcc_jit_extended_asm *ext_asm
+ = gcc_jit_block_add_extended_asm
+ (block, NULL,
+ "rdtsc\n\t" /* Returns the time in EDX:EAX. */
+ "shl $32, %%rdx\n\t" /* Shift the upper bits left. */
+ "or %%rdx, %0"); /* 'Or' in the lower bits. */
+ gcc_jit_extended_asm_set_volatile_flag (ext_asm, 1);
+ gcc_jit_extended_asm_add_output_operand (ext_asm, NULL, "=a", msr);
+ gcc_jit_extended_asm_add_clobber (ext_asm, "rdx");
+@end example
+
+where the @ref{f1,,gcc_jit_extended_asm} is flagged as volatile.
+@end deffn
+
+@geindex gcc_jit_extended_asm_set_inline_flag (C function)
+@anchor{topics/asm c gcc_jit_extended_asm_set_inline_flag}@anchor{127}
+@deffn {C Function} void gcc_jit_extended_asm_set_inline_flag (gcc_jit_extended_asm@w{ }*ext_asm, int@w{ }flag)
+
+Set the equivalent of the
+inline@footnote{https://gcc.gnu.org/onlinedocs/gcc/Size-of-an-asm.html#Size-of-an-asm}
+qualifier in C’s extended @code{asm} syntax.
+@end deffn
+
+@geindex gcc_jit_extended_asm_add_output_operand (C function)
+@anchor{topics/asm c gcc_jit_extended_asm_add_output_operand}@anchor{128}
+@deffn {C Function} void gcc_jit_extended_asm_add_output_operand (gcc_jit_extended_asm@w{ }*ext_asm, const char@w{ }*asm_symbolic_name, const char@w{ }*constraint, gcc_jit_lvalue@w{ }*dest)
+
+Add an output operand to the extended @code{asm} statement. See the
+Output Operands@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#OutputOperands}
+section of the documentation of the C syntax.
+
+@code{asm_symbolic_name} corresponds to the @code{asmSymbolicName} component of C’s
+extended @code{asm} syntax. It can be NULL. If non-NULL it specifies the
+symbolic name for the operand.
+
+@code{constraint} corresponds to the @code{constraint} component of C’s extended
+@code{asm} syntax. It must be non-NULL.
+
+@code{dest} corresponds to the @code{cvariablename} component of C’s extended
+@code{asm} syntax. It must be non-NULL.
+
+@example
+// Example with a NULL symbolic name, the equivalent of:
+// : "=r" (dst)
+gcc_jit_extended_asm_add_output_operand (ext_asm, NULL, "=r", dst);
+
+// Example with a symbolic name ("aIndex"), the equivalent of:
+// : [aIndex] "=r" (index)
+gcc_jit_extended_asm_add_output_operand (ext_asm, "aIndex", "=r", index);
+@end example
+
+This function can’t be called on an @code{asm goto} as such instructions can’t
+have outputs; see the
+Goto Labels@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#GotoLabels}
+section of GCC’s “Extended Asm” documentation.
+@end deffn
+
+@geindex gcc_jit_extended_asm_add_input_operand (C function)
+@anchor{topics/asm c gcc_jit_extended_asm_add_input_operand}@anchor{129}
+@deffn {C Function} void gcc_jit_extended_asm_add_input_operand (gcc_jit_extended_asm@w{ }*ext_asm, const char@w{ }*asm_symbolic_name, const char@w{ }*constraint, gcc_jit_rvalue@w{ }*src)
+
+Add an input operand to the extended @code{asm} statement. See the
+Input Operands@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#InputOperands}
+section of the documentation of the C syntax.
+
+@code{asm_symbolic_name} corresponds to the @code{asmSymbolicName} component of C’s
+extended @code{asm} syntax. It can be NULL. If non-NULL it specifies the
+symbolic name for the operand.
+
+@code{constraint} corresponds to the @code{constraint} component of C’s extended
+@code{asm} syntax. It must be non-NULL.
+
+@code{src} corresponds to the @code{cexpression} component of C’s extended
+@code{asm} syntax. It must be non-NULL.
+
+@example
+// Example with a NULL symbolic name, the equivalent of:
+// : "r" (src)
+gcc_jit_extended_asm_add_input_operand (ext_asm, NULL, "r",
+ gcc_jit_lvalue_as_rvalue (src));
+
+// Example with a symbolic name ("aMask"), the equivalent of:
+// : [aMask] "r" (Mask)
+gcc_jit_extended_asm_add_input_operand (ext_asm, "aMask", "r",
+ gcc_jit_lvalue_as_rvalue (mask));
+@end example
+@end deffn
+
+@geindex gcc_jit_extended_asm_add_clobber (C function)
+@anchor{topics/asm c gcc_jit_extended_asm_add_clobber}@anchor{12a}
+@deffn {C Function} void gcc_jit_extended_asm_add_clobber (gcc_jit_extended_asm@w{ }*ext_asm, const char@w{ }*victim)
+
+Add @cite{victim} to the list of registers clobbered by the extended @code{asm}
+statement. It must be non-NULL. See the
+Clobbers and Scratch Registers@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Clobbers-and-Scratch-Registers#}
+section of the documentation of the C syntax.
+
+Statements with multiple clobbers will require multiple calls, one per
+clobber.
+
+For example:
+
+@example
+gcc_jit_extended_asm_add_clobber (ext_asm, "r0");
+gcc_jit_extended_asm_add_clobber (ext_asm, "cc");
+gcc_jit_extended_asm_add_clobber (ext_asm, "memory");
+@end example
+@end deffn
+
+A @ref{f1,,gcc_jit_extended_asm} is a @ref{e,,gcc_jit_object} “owned” by
+the block’s context. The following upcast is available:
+
+@geindex gcc_jit_extended_asm_as_object (C function)
+@anchor{topics/asm c gcc_jit_extended_asm_as_object}@anchor{125}
+@deffn {C Function} gcc_jit_object * gcc_jit_extended_asm_as_object (gcc_jit_extended_asm@w{ }*ext_asm)
+
+Upcast from extended @code{asm} to object.
+@end deffn
+
+@node Adding top-level assembler statements,,Adding assembler instructions within a function,Using Assembly Language with libgccjit
+@anchor{topics/asm adding-top-level-assembler-statements}@anchor{134}
+@subsection Adding top-level assembler statements
+
+
+In addition to creating extended @code{asm} instructions within a function,
+there is support for creating “top-level” assembler statements, outside
+of any function.
+
+@geindex gcc_jit_context_add_top_level_asm (C function)
+@anchor{topics/asm c gcc_jit_context_add_top_level_asm}@anchor{12b}
+@deffn {C Function} void gcc_jit_context_add_top_level_asm (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, const char@w{ }*asm_stmts)
+
+Create a set of top-level asm statements, analogous to those created
+by GCC’s “basic” @code{asm} syntax in C at file scope.
+
+For example, to create the equivalent of:
+
+@example
+ asm ("\t.pushsection .text\n"
+ "\t.globl add_asm\n"
+ "\t.type add_asm, @@function\n"
+ "add_asm:\n"
+ "\tmovq %rdi, %rax\n"
+ "\tadd %rsi, %rax\n"
+ "\tret\n"
+ "\t.popsection\n");
+@end example
+
+the following API calls could be used:
+
+@example
+ gcc_jit_context_add_top_level_asm (ctxt, NULL,
+ "\t.pushsection .text\n"
+ "\t.globl add_asm\n"
+ "\t.type add_asm, @@function\n"
+ "add_asm:\n"
+ "\tmovq %rdi, %rax\n"
+ "\tadd %rsi, %rax\n"
+ "\tret\n"
+ "\t# some asm here\n"
+ "\t.popsection\n");
+@end example
+@end deffn
+
@c Copyright (C) 2014-2020 Free Software Foundation, Inc.
@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
@c
@@ -8579,7 +9037,7 @@ for its presence using
@c <http://www.gnu.org/licenses/>.
@node C++ bindings for libgccjit,Internals,Topic Reference,Top
-@anchor{cp/index c-bindings-for-libgccjit}@anchor{125}@anchor{cp/index doc}@anchor{126}
+@anchor{cp/index doc}@anchor{135}@anchor{cp/index c-bindings-for-libgccjit}@anchor{136}
@chapter C++ bindings for libgccjit
@@ -8623,7 +9081,7 @@ Contents:
@end menu
@node Tutorial<2>,Topic Reference<2>,,C++ bindings for libgccjit
-@anchor{cp/intro/index doc}@anchor{127}@anchor{cp/intro/index tutorial}@anchor{128}
+@anchor{cp/intro/index doc}@anchor{137}@anchor{cp/intro/index tutorial}@anchor{138}
@section Tutorial
@@ -8653,7 +9111,7 @@ Contents:
@end menu
@node Tutorial part 1 “Hello world”<2>,Tutorial part 2 Creating a trivial machine code function<2>,,Tutorial<2>
-@anchor{cp/intro/tutorial01 doc}@anchor{129}@anchor{cp/intro/tutorial01 tutorial-part-1-hello-world}@anchor{12a}
+@anchor{cp/intro/tutorial01 doc}@anchor{139}@anchor{cp/intro/tutorial01 tutorial-part-1-hello-world}@anchor{13a}
@subsection Tutorial part 1: “Hello world”
@@ -8816,7 +9274,7 @@ hello world
@c <http://www.gnu.org/licenses/>.
@node Tutorial part 2 Creating a trivial machine code function<2>,Tutorial part 3 Loops and variables<2>,Tutorial part 1 “Hello world”<2>,Tutorial<2>
-@anchor{cp/intro/tutorial02 doc}@anchor{12b}@anchor{cp/intro/tutorial02 tutorial-part-2-creating-a-trivial-machine-code-function}@anchor{12c}
+@anchor{cp/intro/tutorial02 doc}@anchor{13b}@anchor{cp/intro/tutorial02 tutorial-part-2-creating-a-trivial-machine-code-function}@anchor{13c}
@subsection Tutorial part 2: Creating a trivial machine code function
@@ -8838,10 +9296,10 @@ First we need to include the relevant header:
@end example
All state associated with compilation is associated with a
-@ref{12d,,gccjit;;context}, which is a thin C++ wrapper around the C API’s
+@ref{13d,,gccjit;;context}, which is a thin C++ wrapper around the C API’s
@ref{8,,gcc_jit_context *}.
-Create one using @ref{12e,,gccjit;;context;;acquire()}:
+Create one using @ref{13e,,gccjit;;context;;acquire()}:
@example
gccjit::context ctxt;
@@ -8851,19 +9309,19 @@ ctxt = gccjit::context::acquire ();
The JIT library has a system of types. It is statically-typed: every
expression is of a specific type, fixed at compile-time. In our example,
all of the expressions are of the C @cite{int} type, so let’s obtain this from
-the context, as a @ref{12f,,gccjit;;type}, using
-@ref{130,,gccjit;;context;;get_type()}:
+the context, as a @ref{13f,,gccjit;;type}, using
+@ref{140,,gccjit;;context;;get_type()}:
@example
gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT);
@end example
-@ref{12f,,gccjit;;type} is an example of a “contextual” object: every
-entity in the API is associated with a @ref{12d,,gccjit;;context}.
+@ref{13f,,gccjit;;type} is an example of a “contextual” object: every
+entity in the API is associated with a @ref{13d,,gccjit;;context}.
Memory management is easy: all such “contextual” objects are automatically
cleaned up for you when the context is released, using
-@ref{131,,gccjit;;context;;release()}:
+@ref{141,,gccjit;;context;;release()}:
@example
ctxt.release ();
@@ -8890,9 +9348,9 @@ The C++ class hierarchy within the @code{gccjit} namespace looks like this:
+- param
@end example
-One thing you can do with a @ref{132,,gccjit;;object} is
+One thing you can do with a @ref{142,,gccjit;;object} is
to ask it for a human-readable description as a @code{std::string}, using
-@ref{133,,gccjit;;object;;get_debug_string()}:
+@ref{143,,gccjit;;object;;get_debug_string()}:
@example
printf ("obj: %s\n", obj.get_debug_string ().c_str ());
@@ -8908,7 +9366,7 @@ This is invaluable when debugging.
Let’s create the function. To do so, we first need to construct
its single parameter, specifying its type and giving it a name,
-using @ref{134,,gccjit;;context;;new_param()}:
+using @ref{144,,gccjit;;context;;new_param()}:
@example
gccjit::param param_i = ctxt.new_param (int_type, "i");
@@ -8949,7 +9407,7 @@ gccjit::block block = func.new_block ();
Our basic block is relatively simple: it immediately terminates by
returning the value of an expression.
-We can build the expression using @ref{135,,gccjit;;context;;new_binary_op()}:
+We can build the expression using @ref{145,,gccjit;;context;;new_binary_op()}:
@example
gccjit::rvalue expr =
@@ -8958,9 +9416,9 @@ gccjit::rvalue expr =
param_i, param_i);
@end example
-A @ref{136,,gccjit;;rvalue} is another example of a
-@ref{132,,gccjit;;object} subclass. As before, we can print it with
-@ref{133,,gccjit;;object;;get_debug_string()}.
+A @ref{146,,gccjit;;rvalue} is another example of a
+@ref{142,,gccjit;;object} subclass. As before, we can print it with
+@ref{143,,gccjit;;object;;get_debug_string()}.
@example
printf ("expr: %s\n", expr.get_debug_string ().c_str ());
@@ -8972,7 +9430,7 @@ giving this output:
expr: i * i
@end example
-Note that @ref{136,,gccjit;;rvalue} provides numerous overloaded operators
+Note that @ref{146,,gccjit;;rvalue} provides numerous overloaded operators
which can be used to dramatically reduce the amount of typing needed.
We can build the above binary operation more directly with this one-liner:
@@ -8989,7 +9447,7 @@ block.end_with_return (expr);
@end example
OK, we’ve populated the context. We can now compile it using
-@ref{137,,gccjit;;context;;compile()}:
+@ref{147,,gccjit;;context;;compile()}:
@example
gcc_jit_result *result;
@@ -9031,12 +9489,12 @@ result: 25
@end menu
@node Options<3>,Full example<3>,,Tutorial part 2 Creating a trivial machine code function<2>
-@anchor{cp/intro/tutorial02 options}@anchor{138}
+@anchor{cp/intro/tutorial02 options}@anchor{148}
@subsubsection Options
To get more information on what’s going on, you can set debugging flags
-on the context using @ref{139,,gccjit;;context;;set_bool_option()}.
+on the context using @ref{149,,gccjit;;context;;set_bool_option()}.
@c (I'm deliberately not mentioning
@c :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think
@@ -9100,7 +9558,7 @@ square:
By default, no optimizations are performed, the equivalent of GCC’s
@cite{-O0} option. We can turn things up to e.g. @cite{-O3} by calling
-@ref{13a,,gccjit;;context;;set_int_option()} with
+@ref{14a,,gccjit;;context;;set_int_option()} with
@ref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}:
@example
@@ -9130,7 +9588,7 @@ square:
Naturally this has only a small effect on such a trivial function.
@node Full example<3>,,Options<3>,Tutorial part 2 Creating a trivial machine code function<2>
-@anchor{cp/intro/tutorial02 full-example}@anchor{13b}
+@anchor{cp/intro/tutorial02 full-example}@anchor{14b}
@subsubsection Full example
@@ -9268,7 +9726,7 @@ result: 25
@c <http://www.gnu.org/licenses/>.
@node Tutorial part 3 Loops and variables<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>,Tutorial part 2 Creating a trivial machine code function<2>,Tutorial<2>
-@anchor{cp/intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{13c}@anchor{cp/intro/tutorial03 doc}@anchor{13d}
+@anchor{cp/intro/tutorial03 doc}@anchor{14c}@anchor{cp/intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{14d}
@subsection Tutorial part 3: Loops and variables
@@ -9317,14 +9775,14 @@ Here’s what the final control flow graph will look like:
@float Figure
-@image{sum-of-squares,,,image of a control flow graph,png}
+@image{libgccjit-figures/sum-of-squares,,,image of a control flow graph,png}
@end float
@end quotation
As before, we include the libgccjit++ header and make a
-@ref{12d,,gccjit;;context}.
+@ref{13d,,gccjit;;context}.
@example
#include <libgccjit++.h>
@@ -9378,18 +9836,18 @@ gccjit::function func =
@end menu
@node Expressions lvalues and rvalues<2>,Control flow<2>,,Tutorial part 3 Loops and variables<2>
-@anchor{cp/intro/tutorial03 expressions-lvalues-and-rvalues}@anchor{13e}
+@anchor{cp/intro/tutorial03 expressions-lvalues-and-rvalues}@anchor{14e}
@subsubsection Expressions: lvalues and rvalues
-The base class of expression is the @ref{136,,gccjit;;rvalue},
+The base class of expression is the @ref{146,,gccjit;;rvalue},
representing an expression that can be on the @emph{right}-hand side of
an assignment: a value that can be computed somehow, and assigned
@emph{to} a storage area (such as a variable). It has a specific
-@ref{12f,,gccjit;;type}.
+@ref{13f,,gccjit;;type}.
-Anothe important class is @ref{13f,,gccjit;;lvalue}.
-A @ref{13f,,gccjit;;lvalue}. is something that can of the @emph{left}-hand
+Anothe important class is @ref{14f,,gccjit;;lvalue}.
+A @ref{14f,,gccjit;;lvalue}. is something that can of the @emph{left}-hand
side of an assignment: a storage area (such as a variable).
In other words, every assignment can be thought of as:
@@ -9398,8 +9856,8 @@ In other words, every assignment can be thought of as:
LVALUE = RVALUE;
@end example
-Note that @ref{13f,,gccjit;;lvalue} is a subclass of
-@ref{136,,gccjit;;rvalue}, where in an assignment of the form:
+Note that @ref{14f,,gccjit;;lvalue} is a subclass of
+@ref{146,,gccjit;;rvalue}, where in an assignment of the form:
@example
LVALUE_A = LVALUE_B;
@@ -9429,7 +9887,7 @@ gccjit::rvalue expr =
gccjit::rvalue expr = param_i * param_i;
@end example
-which is a @ref{136,,gccjit;;rvalue}, and
+which is a @ref{146,,gccjit;;rvalue}, and
@end quotation
@@ -9437,15 +9895,15 @@ which is a @ref{136,,gccjit;;rvalue}, and
@item
the various function parameters: @cite{param_i} and @cite{param_n}, instances of
-@ref{140,,gccjit;;param}, which is a subclass of @ref{13f,,gccjit;;lvalue}
-(and, in turn, of @ref{136,,gccjit;;rvalue}):
+@ref{150,,gccjit;;param}, which is a subclass of @ref{14f,,gccjit;;lvalue}
+(and, in turn, of @ref{146,,gccjit;;rvalue}):
we can both read from and write to function parameters within the
body of a function.
@end enumerate
Our new example has a new kind of expression: we have two local
variables. We create them by calling
-@ref{141,,gccjit;;function;;new_local()}, supplying a type and a name:
+@ref{151,,gccjit;;function;;new_local()}, supplying a type and a name:
@example
/* Build locals: */
@@ -9453,7 +9911,7 @@ gccjit::lvalue i = func.new_local (the_type, "i");
gccjit::lvalue sum = func.new_local (the_type, "sum");
@end example
-These are instances of @ref{13f,,gccjit;;lvalue} - they can be read from
+These are instances of @ref{14f,,gccjit;;lvalue} - they can be read from
and written to.
Note that there is no precanned way to create @emph{and} initialize a variable
@@ -9467,7 +9925,7 @@ Instead, having added the local to the function, we have to separately add
an assignment of @cite{0} to @cite{local_i} at the beginning of the function.
@node Control flow<2>,Visualizing the control flow graph<2>,Expressions lvalues and rvalues<2>,Tutorial part 3 Loops and variables<2>
-@anchor{cp/intro/tutorial03 control-flow}@anchor{142}
+@anchor{cp/intro/tutorial03 control-flow}@anchor{152}
@subsubsection Control flow
@@ -9490,8 +9948,8 @@ the body of the loop
after the loop terminates (@cite{return sum})
@end enumerate
-so we create these as @ref{143,,gccjit;;block} instances within the
-@ref{144,,gccjit;;function}:
+so we create these as @ref{153,,gccjit;;block} instances within the
+@ref{154,,gccjit;;function}:
@example
gccjit::block b_initial = func.new_block ("initial");
@@ -9504,8 +9962,8 @@ We now populate each block with statements.
The entry block @cite{b_initial} consists of initializations followed by a jump
to the conditional. We assign @cite{0} to @cite{i} and to @cite{sum}, using
-@ref{145,,gccjit;;block;;add_assignment()} to add
-an assignment statement, and using @ref{146,,gccjit;;context;;zero()} to get
+@ref{155,,gccjit;;block;;add_assignment()} to add
+an assignment statement, and using @ref{156,,gccjit;;context;;zero()} to get
the constant value @cite{0} for the relevant type for the right-hand side of
the assignment:
@@ -9526,9 +9984,9 @@ b_initial.end_with_jump (b_loop_cond);
The conditional block is equivalent to the line @cite{while (i < n)} from our
C example. It contains a single statement: a conditional, which jumps to
one of two destination blocks depending on a boolean
-@ref{136,,gccjit;;rvalue}, in this case the comparison of @cite{i} and @cite{n}.
+@ref{146,,gccjit;;rvalue}, in this case the comparison of @cite{i} and @cite{n}.
-We could build the comparison using @ref{147,,gccjit;;context;;new_comparison()}:
+We could build the comparison using @ref{157,,gccjit;;context;;new_comparison()}:
@example
gccjit::rvalue guard =
@@ -9537,7 +9995,7 @@ gccjit::rvalue guard =
@end example
and can then use this to add @cite{b_loop_cond}’s sole statement, via
-@ref{148,,gccjit;;block;;end_with_conditional()}:
+@ref{158,,gccjit;;block;;end_with_conditional()}:
@example
b_loop_cond.end_with_conditional (guard,
@@ -9545,7 +10003,7 @@ b_loop_cond.end_with_conditional (guard,
b_loop_body); // on_false
@end example
-However @ref{136,,gccjit;;rvalue} has overloaded operators for this, so we
+However @ref{146,,gccjit;;rvalue} has overloaded operators for this, so we
express the conditional as
@example
@@ -9565,7 +10023,7 @@ Next, we populate the body of the loop.
The C statement @cite{sum += i * i;} is an assignment operation, where an
lvalue is modified “in-place”. We use
-@ref{149,,gccjit;;block;;add_assignment_op()} to handle these operations:
+@ref{159,,gccjit;;block;;add_assignment_op()} to handle these operations:
@example
/* sum += i * i */
@@ -9589,7 +10047,7 @@ b_loop_body.add_assignment_op (i,
@cartouche
@quotation Note
For numeric constants other than 0 or 1, we could use
-@ref{14a,,gccjit;;context;;new_rvalue()}, which has overloads
+@ref{15a,,gccjit;;context;;new_rvalue()}, which has overloads
for both @code{int} and @code{double}.
@end quotation
@end cartouche
@@ -9655,12 +10113,12 @@ result: 285
@end example
@node Visualizing the control flow graph<2>,Full example<4>,Control flow<2>,Tutorial part 3 Loops and variables<2>
-@anchor{cp/intro/tutorial03 visualizing-the-control-flow-graph}@anchor{14b}
+@anchor{cp/intro/tutorial03 visualizing-the-control-flow-graph}@anchor{15b}
@subsubsection Visualizing the control flow graph
You can see the control flow graph of a function using
-@ref{14c,,gccjit;;function;;dump_to_dot()}:
+@ref{15c,,gccjit;;function;;dump_to_dot()}:
@example
func.dump_to_dot ("/tmp/sum-of-squares.dot");
@@ -9683,14 +10141,14 @@ install it with @cite{yum install python-xdot}):
@float Figure
-@image{sum-of-squares,,,image of a control flow graph,png}
+@image{libgccjit-figures/sum-of-squares,,,image of a control flow graph,png}
@end float
@end quotation
@node Full example<4>,,Visualizing the control flow graph<2>,Tutorial part 3 Loops and variables<2>
-@anchor{cp/intro/tutorial03 full-example}@anchor{14d}
+@anchor{cp/intro/tutorial03 full-example}@anchor{15d}
@subsubsection Full example
@@ -9868,7 +10326,7 @@ loop_test returned: 285
@c <http://www.gnu.org/licenses/>.
@node Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>,,Tutorial part 3 Loops and variables<2>,Tutorial<2>
-@anchor{cp/intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{14e}@anchor{cp/intro/tutorial04 doc}@anchor{14f}
+@anchor{cp/intro/tutorial04 doc}@anchor{15e}@anchor{cp/intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{15f}
@subsection Tutorial part 4: Adding JIT-compilation to a toy interpreter
@@ -9890,7 +10348,7 @@ to it.
@end menu
@node Our toy interpreter<2>,Compiling to machine code<2>,,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 our-toy-interpreter}@anchor{150}
+@anchor{cp/intro/tutorial04 our-toy-interpreter}@anchor{160}
@subsubsection Our toy interpreter
@@ -10292,7 +10750,7 @@ toyvm_function::interpret (int arg, FILE *trace)
@end quotation
@node Compiling to machine code<2>,Setting things up<2>,Our toy interpreter<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 compiling-to-machine-code}@anchor{151}
+@anchor{cp/intro/tutorial04 compiling-to-machine-code}@anchor{161}
@subsubsection Compiling to machine code
@@ -10362,7 +10820,7 @@ This means our compiler has the following state:
@end quotation
@node Setting things up<2>,Populating the function<2>,Compiling to machine code<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 setting-things-up}@anchor{152}
+@anchor{cp/intro/tutorial04 setting-things-up}@anchor{162}
@subsubsection Setting things up
@@ -10452,7 +10910,7 @@ compilation_state::add_pop (gccjit::block block,
@end quotation
We will support single-stepping through the generated code in the
-debugger, so we need to create @ref{153,,gccjit;;location} instances, one
+debugger, so we need to create @ref{163,,gccjit;;location} instances, one
per operation in the source code. These will reference the lines of
e.g. @code{factorial.toy}.
@@ -10512,7 +10970,7 @@ We create the locals within the function.
@end quotation
@node Populating the function<2>,Verifying the control flow graph<2>,Setting things up<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 populating-the-function}@anchor{154}
+@anchor{cp/intro/tutorial04 populating-the-function}@anchor{164}
@subsubsection Populating the function
@@ -10625,7 +11083,7 @@ stack into @code{y} instead erroneously assigned it to @code{x}, leaving @code{y
uninitialized.
To track this kind of thing down, we can use
-@ref{155,,gccjit;;block;;add_comment()} to add descriptive comments
+@ref{165,,gccjit;;block;;add_comment()} to add descriptive comments
to the internal representation. This is invaluable when looking through
the generated IR for, say @code{factorial}:
@@ -10765,14 +11223,14 @@ to the next block.
This is analogous to simply incrementing the program counter.
@node Verifying the control flow graph<2>,Compiling the context<2>,Populating the function<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 verifying-the-control-flow-graph}@anchor{156}
+@anchor{cp/intro/tutorial04 verifying-the-control-flow-graph}@anchor{166}
@subsubsection Verifying the control flow graph
Having finished looping over the blocks, the context is complete.
As before, we can verify that the control flow and statements are sane by
-using @ref{14c,,gccjit;;function;;dump_to_dot()}:
+using @ref{15c,,gccjit;;function;;dump_to_dot()}:
@example
fn.dump_to_dot ("/tmp/factorial.dot");
@@ -10787,14 +11245,14 @@ errors in our compiler.
@float Figure
-@image{factorial,,,image of a control flow graph,png}
+@image{libgccjit-figures/factorial,,,image of a control flow graph,png}
@end float
@end quotation
@node Compiling the context<2>,Single-stepping through the generated code<2>,Verifying the control flow graph<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 compiling-the-context}@anchor{157}
+@anchor{cp/intro/tutorial04 compiling-the-context}@anchor{167}
@subsubsection Compiling the context
@@ -10845,7 +11303,7 @@ private:
@end quotation
@node Single-stepping through the generated code<2>,Examining the generated code<2>,Compiling the context<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 single-stepping-through-the-generated-code}@anchor{158}
+@anchor{cp/intro/tutorial04 single-stepping-through-the-generated-code}@anchor{168}
@subsubsection Single-stepping through the generated code
@@ -10859,14 +11317,14 @@ It’s possible to debug the generated code. To do this we need to both:
@item
Set up source code locations for our statements, so that we can
meaningfully step through the code. We did this above by
-calling @ref{159,,gccjit;;context;;new_location()} and using the
+calling @ref{169,,gccjit;;context;;new_location()} and using the
results.
@item
Enable the generation of debugging information, by setting
@ref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the
-@ref{12d,,gccjit;;context} via
-@ref{139,,gccjit;;context;;set_bool_option()}:
+@ref{13d,,gccjit;;context} via
+@ref{149,,gccjit;;context;;set_bool_option()}:
@example
ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1);
@@ -10930,14 +11388,14 @@ optimization level in a regular compiler.
@end cartouche
@node Examining the generated code<2>,Putting it all together<2>,Single-stepping through the generated code<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 examining-the-generated-code}@anchor{15a}
+@anchor{cp/intro/tutorial04 examining-the-generated-code}@anchor{16a}
@subsubsection Examining the generated code
How good is the optimized code?
We can turn up optimizations, by calling
-@ref{13a,,gccjit;;context;;set_int_option()} with
+@ref{14a,,gccjit;;context;;set_int_option()} with
@ref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}:
@example
@@ -11105,7 +11563,7 @@ Note that the stack pushing and popping have been eliminated, as has the
recursive call (in favor of an iteration).
@node Putting it all together<2>,Behind the curtain How does our code get optimized?<2>,Examining the generated code<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 putting-it-all-together}@anchor{15b}
+@anchor{cp/intro/tutorial04 putting-it-all-together}@anchor{16b}
@subsubsection Putting it all together
@@ -11136,7 +11594,7 @@ compiler result: 55
@end example
@node Behind the curtain How does our code get optimized?<2>,,Putting it all together<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 behind-the-curtain-how-does-our-code-get-optimized}@anchor{15c}
+@anchor{cp/intro/tutorial04 behind-the-curtain-how-does-our-code-get-optimized}@anchor{16c}
@subsubsection Behind the curtain: How does our code get optimized?
@@ -11314,7 +11772,7 @@ instr9:
@}
@end example
-Note in the above how all the @ref{143,,gccjit;;block} instances we
+Note in the above how all the @ref{153,,gccjit;;block} instances we
created have been consolidated into just 3 blocks in GCC’s internal
representation: @code{initial}, @code{instr4} and @code{instr9}.
@@ -11325,7 +11783,7 @@ representation: @code{initial}, @code{instr4} and @code{instr9}.
@end menu
@node Optimizing away stack manipulation<2>,Elimination of tail recursion<2>,,Behind the curtain How does our code get optimized?<2>
-@anchor{cp/intro/tutorial04 optimizing-away-stack-manipulation}@anchor{15d}
+@anchor{cp/intro/tutorial04 optimizing-away-stack-manipulation}@anchor{16d}
@subsubsection Optimizing away stack manipulation
@@ -11589,7 +12047,7 @@ instr9:
@end example
@node Elimination of tail recursion<2>,,Optimizing away stack manipulation<2>,Behind the curtain How does our code get optimized?<2>
-@anchor{cp/intro/tutorial04 elimination-of-tail-recursion}@anchor{15e}
+@anchor{cp/intro/tutorial04 elimination-of-tail-recursion}@anchor{16e}
@subsubsection Elimination of tail recursion
@@ -11672,7 +12130,7 @@ instr9:
@c <http://www.gnu.org/licenses/>.
@node Topic Reference<2>,,Tutorial<2>,C++ bindings for libgccjit
-@anchor{cp/topics/index doc}@anchor{15f}@anchor{cp/topics/index topic-reference}@anchor{160}
+@anchor{cp/topics/index doc}@anchor{16f}@anchor{cp/topics/index topic-reference}@anchor{170}
@section Topic Reference
@@ -11701,26 +12159,27 @@ instr9:
* Creating and using functions: Creating and using functions<2>.
* Source Locations: Source Locations<2>.
* Compiling a context: Compiling a context<2>.
+* Using Assembly Language with libgccjit++::
@end menu
@node Compilation contexts<2>,Objects<2>,,Topic Reference<2>
-@anchor{cp/topics/contexts compilation-contexts}@anchor{161}@anchor{cp/topics/contexts doc}@anchor{162}
+@anchor{cp/topics/contexts doc}@anchor{171}@anchor{cp/topics/contexts compilation-contexts}@anchor{172}
@subsection Compilation contexts
@geindex gccjit;;context (C++ class)
-@anchor{cp/topics/contexts _CPPv2N6gccjit7contextE}@anchor{12d}@anchor{cp/topics/contexts gccjit context}@anchor{163}
+@anchor{cp/topics/contexts _CPPv4N6gccjit7contextE}@anchor{13d}@anchor{cp/topics/contexts _CPPv3N6gccjit7contextE}@anchor{173}@anchor{cp/topics/contexts _CPPv2N6gccjit7contextE}@anchor{174}@anchor{cp/topics/contexts gccjit context}@anchor{175}
@deffn {C++ Class} gccjit::context
@end deffn
-The top-level of the C++ API is the @ref{12d,,gccjit;;context} type.
+The top-level of the C++ API is the @ref{13d,,gccjit;;context} type.
-A @ref{12d,,gccjit;;context} instance encapsulates the state of a
+A @ref{13d,,gccjit;;context} instance encapsulates the state of a
compilation.
You can set up options on it, and add types, functions and code.
-Invoking @ref{137,,gccjit;;context;;compile()} on it gives you a
+Invoking @ref{147,,gccjit;;context;;compile()} on it gives you a
@ref{16,,gcc_jit_result *}.
It is a thin wrapper around the C API’s @ref{8,,gcc_jit_context *}.
@@ -11735,7 +12194,7 @@ It is a thin wrapper around the C API’s @ref{8,,gcc_jit_context *}.
@end menu
@node Lifetime-management<2>,Thread-safety<2>,,Compilation contexts<2>
-@anchor{cp/topics/contexts lifetime-management}@anchor{164}
+@anchor{cp/topics/contexts lifetime-management}@anchor{176}
@subsubsection Lifetime-management
@@ -11744,17 +12203,17 @@ have their lifetime bounded by the context they are created within, and
cleanup of such objects is done for you when the context is released.
@geindex gccjit;;context;;acquire (C++ function)
-@anchor{cp/topics/contexts _CPPv2N6gccjit7context7acquireEv}@anchor{12e}@anchor{cp/topics/contexts gccjit context acquire}@anchor{165}
-@deffn {C++ Function} gccjit::@ref{12d,,context} gccjit::context::acquire ()
+@anchor{cp/topics/contexts _CPPv4N6gccjit7context7acquireEv}@anchor{13e}@anchor{cp/topics/contexts _CPPv3N6gccjit7context7acquireEv}@anchor{177}@anchor{cp/topics/contexts _CPPv2N6gccjit7context7acquireEv}@anchor{178}@anchor{cp/topics/contexts gccjit context acquire}@anchor{179}
+@deffn {C++ Function} gccjit::@ref{13d,,context} gccjit::@ref{13d,,context}::acquire ()
-This function acquires a new @ref{12d,,gccjit;;context} instance,
+This function acquires a new @ref{13d,,gccjit;;context} instance,
which is independent of any others that may be present within this
process.
@end deffn
@geindex gccjit;;context;;release (C++ function)
-@anchor{cp/topics/contexts _CPPv2N6gccjit7context7releaseEv}@anchor{131}@anchor{cp/topics/contexts gccjit context release}@anchor{166}
-@deffn {C++ Function} void gccjit::context::release ()
+@anchor{cp/topics/contexts _CPPv4N6gccjit7context7releaseEv}@anchor{141}@anchor{cp/topics/contexts _CPPv3N6gccjit7context7releaseEv}@anchor{17a}@anchor{cp/topics/contexts _CPPv2N6gccjit7context7releaseEv}@anchor{17b}@anchor{cp/topics/contexts gccjit context release}@anchor{17c}
+@deffn {C++ Function} void gccjit::@ref{13d,,context}::release ()
This function releases all resources associated with the given context.
Both the context itself and all of its @code{gccjit::object *}
@@ -11770,8 +12229,8 @@ ctxt.release ();
@end deffn
@geindex gccjit;;context;;new_child_context (C++ function)
-@anchor{cp/topics/contexts _CPPv2N6gccjit7context17new_child_contextEv}@anchor{167}@anchor{cp/topics/contexts gccjit context new_child_context}@anchor{168}
-@deffn {C++ Function} gccjit::@ref{12d,,context} gccjit::context::new_child_context ()
+@anchor{cp/topics/contexts _CPPv4N6gccjit7context17new_child_contextEv}@anchor{17d}@anchor{cp/topics/contexts _CPPv3N6gccjit7context17new_child_contextEv}@anchor{17e}@anchor{cp/topics/contexts _CPPv2N6gccjit7context17new_child_contextEv}@anchor{17f}@anchor{cp/topics/contexts gccjit context new_child_context}@anchor{180}
+@deffn {C++ Function} gccjit::@ref{13d,,context} gccjit::@ref{13d,,context}::new_child_context ()
Given an existing JIT context, create a child context.
@@ -11802,16 +12261,16 @@ there will likely be a performance hit for such nesting.
@end deffn
@node Thread-safety<2>,Error-handling<3>,Lifetime-management<2>,Compilation contexts<2>
-@anchor{cp/topics/contexts thread-safety}@anchor{169}
+@anchor{cp/topics/contexts thread-safety}@anchor{181}
@subsubsection Thread-safety
-Instances of @ref{12d,,gccjit;;context} created via
-@ref{12e,,gccjit;;context;;acquire()} are independent from each other:
+Instances of @ref{13d,,gccjit;;context} created via
+@ref{13e,,gccjit;;context;;acquire()} are independent from each other:
only one thread may use a given context at once, but multiple threads
could each have their own contexts without needing locks.
-Contexts created via @ref{167,,gccjit;;context;;new_child_context()} are
+Contexts created via @ref{17d,,gccjit;;context;;new_child_context()} are
related to their parent context. They can be partitioned by their
ultimate ancestor into independent “family trees”. Only one thread
within a process may use a given “family tree” of such contexts at once,
@@ -11819,7 +12278,7 @@ and if you’re using multiple threads you should provide your own locking
around entire such context partitions.
@node Error-handling<3>,Debugging<2>,Thread-safety<2>,Compilation contexts<2>
-@anchor{cp/topics/contexts error-handling}@anchor{16a}
+@anchor{cp/topics/contexts error-handling}@anchor{182}
@subsubsection Error-handling
@@ -11832,11 +12291,11 @@ NULL. You don’t have to check everywhere for NULL results, since the
API gracefully handles a NULL being passed in for any argument.
Errors are printed on stderr and can be queried using
-@ref{16b,,gccjit;;context;;get_first_error()}.
+@ref{183,,gccjit;;context;;get_first_error()}.
@geindex gccjit;;context;;get_first_error (C++ function)
-@anchor{cp/topics/contexts _CPPv2N6gccjit7context15get_first_errorEPN6gccjit7contextE}@anchor{16b}@anchor{cp/topics/contexts gccjit context get_first_error__gccjit contextP}@anchor{16c}
-@deffn {C++ Function} const char *gccjit::context::get_first_error (gccjit::context *ctxt)
+@anchor{cp/topics/contexts _CPPv4N6gccjit7context15get_first_errorEPN6gccjit7contextE}@anchor{183}@anchor{cp/topics/contexts _CPPv3N6gccjit7context15get_first_errorEPN6gccjit7contextE}@anchor{184}@anchor{cp/topics/contexts _CPPv2N6gccjit7context15get_first_errorEPN6gccjit7contextE}@anchor{185}@anchor{cp/topics/contexts gccjit context get_first_error__gccjit contextP}@anchor{186}
+@deffn {C++ Function} const char *gccjit::@ref{13d,,context}::get_first_error (gccjit::context *ctxt)
Returns the first error message that occurred on the context.
@@ -11847,18 +12306,18 @@ If no errors occurred, this will be NULL.
@end deffn
@node Debugging<2>,Options<4>,Error-handling<3>,Compilation contexts<2>
-@anchor{cp/topics/contexts debugging}@anchor{16d}
+@anchor{cp/topics/contexts debugging}@anchor{187}
@subsubsection Debugging
@geindex gccjit;;context;;dump_to_file (C++ function)
-@anchor{cp/topics/contexts _CPPv2N6gccjit7context12dump_to_fileERKNSt6stringEi}@anchor{16e}@anchor{cp/topics/contexts gccjit context dump_to_file__ssCR i}@anchor{16f}
-@deffn {C++ Function} void gccjit::context::dump_to_file (const std::string &path, int update_locations)
+@anchor{cp/topics/contexts _CPPv4N6gccjit7context12dump_to_fileERKNSt6stringEi}@anchor{188}@anchor{cp/topics/contexts _CPPv3N6gccjit7context12dump_to_fileERKNSt6stringEi}@anchor{189}@anchor{cp/topics/contexts _CPPv2N6gccjit7context12dump_to_fileERKNSt6stringEi}@anchor{18a}@anchor{cp/topics/contexts gccjit context dump_to_file__ssCR i}@anchor{18b}
+@deffn {C++ Function} void gccjit::@ref{13d,,context}::dump_to_file (const std::string &path, int update_locations)
To help with debugging: dump a C-like representation to the given path,
describing what’s been set up on the context.
-If “update_locations” is true, then also set up @ref{153,,gccjit;;location}
+If “update_locations” is true, then also set up @ref{163,,gccjit;;location}
information throughout the context, pointing at the dump file as if it
were a source file. This may be of use in conjunction with
@code{GCCJIT::BOOL_OPTION_DEBUGINFO} to allow stepping through the
@@ -11866,8 +12325,8 @@ code in a debugger.
@end deffn
@geindex gccjit;;context;;dump_reproducer_to_file (C++ function)
-@anchor{cp/topics/contexts _CPPv2N6gccjit7context23dump_reproducer_to_fileEP15gcc_jit_contextPKc}@anchor{170}@anchor{cp/topics/contexts gccjit context dump_reproducer_to_file__gcc_jit_contextP cCP}@anchor{171}
-@deffn {C++ Function} void gccjit::context::dump_reproducer_to_file (gcc_jit_context *ctxt, const char *path)
+@anchor{cp/topics/contexts _CPPv4N6gccjit7context23dump_reproducer_to_fileEP15gcc_jit_contextPKc}@anchor{18c}@anchor{cp/topics/contexts _CPPv3N6gccjit7context23dump_reproducer_to_fileEP15gcc_jit_contextPKc}@anchor{18d}@anchor{cp/topics/contexts _CPPv2N6gccjit7context23dump_reproducer_to_fileEP15gcc_jit_contextPKc}@anchor{18e}@anchor{cp/topics/contexts gccjit context dump_reproducer_to_file__gcc_jit_contextP cCP}@anchor{18f}
+@deffn {C++ Function} void gccjit::@ref{13d,,context}::dump_reproducer_to_file (gcc_jit_context *ctxt, const char *path)
This is a thin wrapper around the C API
@ref{5d,,gcc_jit_context_dump_reproducer_to_file()}, and hence works the
@@ -11878,7 +12337,7 @@ for seeing what the C++ bindings are doing at the C level.
@end deffn
@node Options<4>,,Debugging<2>,Compilation contexts<2>
-@anchor{cp/topics/contexts options}@anchor{172}
+@anchor{cp/topics/contexts options}@anchor{190}
@subsubsection Options
@@ -11891,13 +12350,13 @@ for seeing what the C++ bindings are doing at the C level.
@end menu
@node String Options<2>,Boolean options<2>,,Options<4>
-@anchor{cp/topics/contexts string-options}@anchor{173}
+@anchor{cp/topics/contexts string-options}@anchor{191}
@subsubsection String Options
@geindex gccjit;;context;;set_str_option (C++ function)
-@anchor{cp/topics/contexts _CPPv2N6gccjit7context14set_str_optionE18gcc_jit_str_optionPKc}@anchor{174}@anchor{cp/topics/contexts gccjit context set_str_option__gcc_jit_str_option cCP}@anchor{175}
-@deffn {C++ Function} void gccjit::context::set_str_option (enum gcc_jit_str_option, const char *value)
+@anchor{cp/topics/contexts _CPPv4N6gccjit7context14set_str_optionE18gcc_jit_str_optionPKc}@anchor{192}@anchor{cp/topics/contexts _CPPv3N6gccjit7context14set_str_optionE18gcc_jit_str_optionPKc}@anchor{193}@anchor{cp/topics/contexts _CPPv2N6gccjit7context14set_str_optionE18gcc_jit_str_optionPKc}@anchor{194}@anchor{cp/topics/contexts gccjit context set_str_option__gcc_jit_str_option cCP}@anchor{195}
+@deffn {C++ Function} void gccjit::@ref{13d,,context}::set_str_option (enum gcc_jit_str_option, const char *value)
Set a string option of the context.
@@ -11907,13 +12366,13 @@ meaning.
@end deffn
@node Boolean options<2>,Integer options<2>,String Options<2>,Options<4>
-@anchor{cp/topics/contexts boolean-options}@anchor{176}
+@anchor{cp/topics/contexts boolean-options}@anchor{196}
@subsubsection Boolean options
@geindex gccjit;;context;;set_bool_option (C++ function)
-@anchor{cp/topics/contexts _CPPv2N6gccjit7context15set_bool_optionE19gcc_jit_bool_optioni}@anchor{139}@anchor{cp/topics/contexts gccjit context set_bool_option__gcc_jit_bool_option i}@anchor{177}
-@deffn {C++ Function} void gccjit::context::set_bool_option (enum gcc_jit_bool_option, int value)
+@anchor{cp/topics/contexts _CPPv4N6gccjit7context15set_bool_optionE19gcc_jit_bool_optioni}@anchor{149}@anchor{cp/topics/contexts _CPPv3N6gccjit7context15set_bool_optionE19gcc_jit_bool_optioni}@anchor{197}@anchor{cp/topics/contexts _CPPv2N6gccjit7context15set_bool_optionE19gcc_jit_bool_optioni}@anchor{198}@anchor{cp/topics/contexts gccjit context set_bool_option__gcc_jit_bool_option i}@anchor{199}
+@deffn {C++ Function} void gccjit::@ref{13d,,context}::set_bool_option (enum gcc_jit_bool_option, int value)
Set a boolean option of the context.
@@ -11923,8 +12382,8 @@ meaning.
@end deffn
@geindex gccjit;;context;;set_bool_allow_unreachable_blocks (C++ function)
-@anchor{cp/topics/contexts _CPPv2N6gccjit7context33set_bool_allow_unreachable_blocksEi}@anchor{178}@anchor{cp/topics/contexts gccjit context set_bool_allow_unreachable_blocks__i}@anchor{179}
-@deffn {C++ Function} void gccjit::context::set_bool_allow_unreachable_blocks (int bool_value)
+@anchor{cp/topics/contexts _CPPv4N6gccjit7context33set_bool_allow_unreachable_blocksEi}@anchor{19a}@anchor{cp/topics/contexts _CPPv3N6gccjit7context33set_bool_allow_unreachable_blocksEi}@anchor{19b}@anchor{cp/topics/contexts _CPPv2N6gccjit7context33set_bool_allow_unreachable_blocksEi}@anchor{19c}@anchor{cp/topics/contexts gccjit context set_bool_allow_unreachable_blocks__i}@anchor{19d}
+@deffn {C++ Function} void gccjit::@ref{13d,,context}::set_bool_allow_unreachable_blocks (int bool_value)
By default, libgccjit will issue an error about unreachable blocks
within a function.
@@ -11942,8 +12401,8 @@ its presence using
@end deffn
@geindex gccjit;;context;;set_bool_use_external_driver (C++ function)
-@anchor{cp/topics/contexts _CPPv2N6gccjit7context28set_bool_use_external_driverEi}@anchor{17a}@anchor{cp/topics/contexts gccjit context set_bool_use_external_driver__i}@anchor{17b}
-@deffn {C++ Function} void gccjit::context::set_bool_use_external_driver (int bool_value)
+@anchor{cp/topics/contexts _CPPv4N6gccjit7context28set_bool_use_external_driverEi}@anchor{19e}@anchor{cp/topics/contexts _CPPv3N6gccjit7context28set_bool_use_external_driverEi}@anchor{19f}@anchor{cp/topics/contexts _CPPv2N6gccjit7context28set_bool_use_external_driverEi}@anchor{1a0}@anchor{cp/topics/contexts gccjit context set_bool_use_external_driver__i}@anchor{1a1}
+@deffn {C++ Function} void gccjit::@ref{13d,,context}::set_bool_use_external_driver (int bool_value)
libgccjit internally generates assembler, and uses “driver” code
for converting it to other formats (e.g. shared libraries).
@@ -11964,13 +12423,13 @@ its presence using
@end deffn
@node Integer options<2>,Additional command-line options<2>,Boolean options<2>,Options<4>
-@anchor{cp/topics/contexts integer-options}@anchor{17c}
+@anchor{cp/topics/contexts integer-options}@anchor{1a2}
@subsubsection Integer options
@geindex gccjit;;context;;set_int_option (C++ function)
-@anchor{cp/topics/contexts _CPPv2N6gccjit7context14set_int_optionE18gcc_jit_int_optioni}@anchor{13a}@anchor{cp/topics/contexts gccjit context set_int_option__gcc_jit_int_option i}@anchor{17d}
-@deffn {C++ Function} void gccjit::context::set_int_option (enum gcc_jit_int_option, int value)
+@anchor{cp/topics/contexts _CPPv4N6gccjit7context14set_int_optionE18gcc_jit_int_optioni}@anchor{14a}@anchor{cp/topics/contexts _CPPv3N6gccjit7context14set_int_optionE18gcc_jit_int_optioni}@anchor{1a3}@anchor{cp/topics/contexts _CPPv2N6gccjit7context14set_int_optionE18gcc_jit_int_optioni}@anchor{1a4}@anchor{cp/topics/contexts gccjit context set_int_option__gcc_jit_int_option i}@anchor{1a5}
+@deffn {C++ Function} void gccjit::@ref{13d,,context}::set_int_option (enum gcc_jit_int_option, int value)
Set an integer option of the context.
@@ -11980,13 +12439,13 @@ meaning.
@end deffn
@node Additional command-line options<2>,,Integer options<2>,Options<4>
-@anchor{cp/topics/contexts additional-command-line-options}@anchor{17e}
+@anchor{cp/topics/contexts additional-command-line-options}@anchor{1a6}
@subsubsection Additional command-line options
@geindex gccjit;;context;;add_command_line_option (C++ function)
-@anchor{cp/topics/contexts _CPPv2N6gccjit7context23add_command_line_optionEPKc}@anchor{17f}@anchor{cp/topics/contexts gccjit context add_command_line_option__cCP}@anchor{180}
-@deffn {C++ Function} void gccjit::context::add_command_line_option (const char *optname)
+@anchor{cp/topics/contexts _CPPv4N6gccjit7context23add_command_line_optionEPKc}@anchor{1a7}@anchor{cp/topics/contexts _CPPv3N6gccjit7context23add_command_line_optionEPKc}@anchor{1a8}@anchor{cp/topics/contexts _CPPv2N6gccjit7context23add_command_line_optionEPKc}@anchor{1a9}@anchor{cp/topics/contexts gccjit context add_command_line_option__cCP}@anchor{1aa}
+@deffn {C++ Function} void gccjit::@ref{13d,,context}::add_command_line_option (const char *optname)
Add an arbitrary gcc command-line option to the context for use
when compiling.
@@ -12020,18 +12479,18 @@ its presence using
@c <http://www.gnu.org/licenses/>.
@node Objects<2>,Types<2>,Compilation contexts<2>,Topic Reference<2>
-@anchor{cp/topics/objects objects}@anchor{181}@anchor{cp/topics/objects doc}@anchor{182}
+@anchor{cp/topics/objects doc}@anchor{1ab}@anchor{cp/topics/objects objects}@anchor{1ac}
@subsection Objects
@geindex gccjit;;object (C++ class)
-@anchor{cp/topics/objects _CPPv2N6gccjit6objectE}@anchor{132}@anchor{cp/topics/objects gccjit object}@anchor{183}
+@anchor{cp/topics/objects _CPPv4N6gccjit6objectE}@anchor{142}@anchor{cp/topics/objects _CPPv3N6gccjit6objectE}@anchor{1ad}@anchor{cp/topics/objects _CPPv2N6gccjit6objectE}@anchor{1ae}@anchor{cp/topics/objects gccjit object}@anchor{1af}
@deffn {C++ Class} gccjit::object
@end deffn
Almost every entity in the API (with the exception of
-@ref{12d,,gccjit;;context} and @ref{16,,gcc_jit_result *}) is a
-“contextual” object, a @ref{132,,gccjit;;object}.
+@ref{13d,,gccjit;;context} and @ref{16,,gcc_jit_result *}) is a
+“contextual” object, a @ref{142,,gccjit;;object}.
A JIT object:
@@ -12041,7 +12500,7 @@ A JIT object:
@itemize *
@item
-is associated with a @ref{12d,,gccjit;;context}.
+is associated with a @ref{13d,,gccjit;;context}.
@item
is automatically cleaned up for you when its context is released so
@@ -12066,18 +12525,18 @@ The C++ class hierarchy within the @code{gccjit} namespace looks like this:
+- case_
@end example
-The @ref{132,,gccjit;;object} base class has the following operations:
+The @ref{142,,gccjit;;object} base class has the following operations:
@geindex gccjit;;object;;get_context (C++ function)
-@anchor{cp/topics/objects _CPPv2NK6gccjit6object11get_contextEv}@anchor{184}@anchor{cp/topics/objects gccjit object get_contextC}@anchor{185}
-@deffn {C++ Function} gccjit::@ref{12d,,context} gccjit::object::get_context () const
+@anchor{cp/topics/objects _CPPv4NK6gccjit6object11get_contextEv}@anchor{1b0}@anchor{cp/topics/objects _CPPv3NK6gccjit6object11get_contextEv}@anchor{1b1}@anchor{cp/topics/objects _CPPv2NK6gccjit6object11get_contextEv}@anchor{1b2}@anchor{cp/topics/objects gccjit object get_contextC}@anchor{1b3}
+@deffn {C++ Function} gccjit::@ref{13d,,context} gccjit::@ref{142,,object}::get_context () const
Which context is the obj within?
@end deffn
@geindex gccjit;;object;;get_debug_string (C++ function)
-@anchor{cp/topics/objects _CPPv2NK6gccjit6object16get_debug_stringEv}@anchor{133}@anchor{cp/topics/objects gccjit object get_debug_stringC}@anchor{186}
-@deffn {C++ Function} std::string gccjit::object::get_debug_string () const
+@anchor{cp/topics/objects _CPPv4NK6gccjit6object16get_debug_stringEv}@anchor{143}@anchor{cp/topics/objects _CPPv3NK6gccjit6object16get_debug_stringEv}@anchor{1b4}@anchor{cp/topics/objects _CPPv2NK6gccjit6object16get_debug_stringEv}@anchor{1b5}@anchor{cp/topics/objects gccjit object get_debug_stringC}@anchor{1b6}
+@deffn {C++ Function} std::string gccjit::@ref{142,,object}::get_debug_string () const
Generate a human-readable description for the given object.
@@ -12112,16 +12571,16 @@ obj: 4.0 * (float)i
@c <http://www.gnu.org/licenses/>.
@node Types<2>,Expressions<2>,Objects<2>,Topic Reference<2>
-@anchor{cp/topics/types doc}@anchor{187}@anchor{cp/topics/types types}@anchor{188}
+@anchor{cp/topics/types doc}@anchor{1b7}@anchor{cp/topics/types types}@anchor{1b8}
@subsection Types
@geindex gccjit;;type (C++ class)
-@anchor{cp/topics/types _CPPv2N6gccjit4typeE}@anchor{12f}@anchor{cp/topics/types gccjit type}@anchor{189}
+@anchor{cp/topics/types _CPPv4N6gccjit4typeE}@anchor{13f}@anchor{cp/topics/types _CPPv3N6gccjit4typeE}@anchor{1b9}@anchor{cp/topics/types _CPPv2N6gccjit4typeE}@anchor{1ba}@anchor{cp/topics/types gccjit type}@anchor{1bb}
@deffn {C++ Class} gccjit::type
gccjit::type represents a type within the library. It is a subclass
-of @ref{132,,gccjit;;object}.
+of @ref{142,,gccjit;;object}.
@end deffn
Types can be created in several ways:
@@ -12131,7 +12590,7 @@ Types can be created in several ways:
@item
fundamental types can be accessed using
-@ref{130,,gccjit;;context;;get_type()}:
+@ref{140,,gccjit;;context;;get_type()}:
@example
gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT);
@@ -12147,7 +12606,7 @@ See @ref{b,,gcc_jit_context_get_type()} for the available types.
@item
derived types can be accessed by using functions such as
-@ref{18a,,gccjit;;type;;get_pointer()} and @ref{18b,,gccjit;;type;;get_const()}:
+@ref{1bc,,gccjit;;type;;get_pointer()} and @ref{1bd,,gccjit;;type;;get_const()}:
@example
gccjit::type const_int_star = int_type.get_const ().get_pointer ();
@@ -12167,28 +12626,28 @@ by creating structures (see below).
@end menu
@node Standard types<2>,Pointers const and volatile<2>,,Types<2>
-@anchor{cp/topics/types standard-types}@anchor{18c}
+@anchor{cp/topics/types standard-types}@anchor{1be}
@subsubsection Standard types
@geindex gccjit;;context;;get_type (C++ function)
-@anchor{cp/topics/types _CPPv2N6gccjit7context8get_typeE13gcc_jit_types}@anchor{130}@anchor{cp/topics/types gccjit context get_type__gcc_jit_types}@anchor{18d}
-@deffn {C++ Function} gccjit::@ref{12f,,type} gccjit::context::get_type (enum gcc_jit_types)
+@anchor{cp/topics/types _CPPv4N6gccjit7context8get_typeE13gcc_jit_types}@anchor{140}@anchor{cp/topics/types _CPPv3N6gccjit7context8get_typeE13gcc_jit_types}@anchor{1bf}@anchor{cp/topics/types _CPPv2N6gccjit7context8get_typeE13gcc_jit_types}@anchor{1c0}@anchor{cp/topics/types gccjit context get_type__gcc_jit_types}@anchor{1c1}
+@deffn {C++ Function} gccjit::@ref{13f,,type} gccjit::@ref{13d,,context}::get_type (enum gcc_jit_types)
Access a specific type. This is a thin wrapper around
@ref{b,,gcc_jit_context_get_type()}; the parameter has the same meaning.
@end deffn
@geindex gccjit;;context;;get_int_type (C++ function)
-@anchor{cp/topics/types _CPPv2N6gccjit7context12get_int_typeE6size_ti}@anchor{18e}@anchor{cp/topics/types gccjit context get_int_type__s i}@anchor{18f}
-@deffn {C++ Function} gccjit::@ref{12f,,type} gccjit::context::get_int_type (size_t num_bytes, int is_signed)
+@anchor{cp/topics/types _CPPv4N6gccjit7context12get_int_typeE6size_ti}@anchor{1c2}@anchor{cp/topics/types _CPPv3N6gccjit7context12get_int_typeE6size_ti}@anchor{1c3}@anchor{cp/topics/types _CPPv2N6gccjit7context12get_int_typeE6size_ti}@anchor{1c4}@anchor{cp/topics/types gccjit context get_int_type__s i}@anchor{1c5}
+@deffn {C++ Function} gccjit::@ref{13f,,type} gccjit::@ref{13d,,context}::get_int_type (size_t num_bytes, int is_signed)
Access the integer type of the given size.
@end deffn
@geindex gccjit;;context;;get_int_type<T> (C++ function)
-@anchor{cp/topics/types _CPPv2IEN6gccjit7context12get_int_typeI1TEEv}@anchor{190}
-@deffn {C++ Function} template<>gccjit::@ref{12f,,type} gccjit::context::get_int_type<T> ()
+@anchor{cp/topics/types _CPPv4IEN6gccjit7context12get_int_typeI1TEEN6gccjit4typeEv}@anchor{1c6}@anchor{cp/topics/types _CPPv3IEN6gccjit7context12get_int_typeI1TEEv}@anchor{1c7}@anchor{cp/topics/types _CPPv2IEN6gccjit7context12get_int_typeI1TEEv}@anchor{1c8}
+@deffn {C++ Function} template<>gccjit::@ref{13f,,type} gccjit::@ref{13d,,context}::get_int_type<T> ()
Access the given integer type. For example, you could map the
@code{unsigned short} type into a gccjit::type via:
@@ -12199,34 +12658,34 @@ gccjit::type t = ctxt.get_int_type <unsigned short> ();
@end deffn
@node Pointers const and volatile<2>,Vector types<2>,Standard types<2>,Types<2>
-@anchor{cp/topics/types pointers-const-and-volatile}@anchor{191}
+@anchor{cp/topics/types pointers-const-and-volatile}@anchor{1c9}
@subsubsection Pointers, @cite{const}, and @cite{volatile}
@geindex gccjit;;type;;get_pointer (C++ function)
-@anchor{cp/topics/types _CPPv2N6gccjit4type11get_pointerEv}@anchor{18a}@anchor{cp/topics/types gccjit type get_pointer}@anchor{192}
-@deffn {C++ Function} gccjit::@ref{12f,,type} gccjit::type::get_pointer ()
+@anchor{cp/topics/types _CPPv4N6gccjit4type11get_pointerEv}@anchor{1bc}@anchor{cp/topics/types _CPPv3N6gccjit4type11get_pointerEv}@anchor{1ca}@anchor{cp/topics/types _CPPv2N6gccjit4type11get_pointerEv}@anchor{1cb}@anchor{cp/topics/types gccjit type get_pointer}@anchor{1cc}
+@deffn {C++ Function} gccjit::@ref{13f,,type} gccjit::@ref{13f,,type}::get_pointer ()
Given type “T”, get type “T*”.
@end deffn
@geindex gccjit;;type;;get_const (C++ function)
-@anchor{cp/topics/types _CPPv2N6gccjit4type9get_constEv}@anchor{18b}@anchor{cp/topics/types gccjit type get_const}@anchor{193}
-@deffn {C++ Function} gccjit::@ref{12f,,type} gccjit::type::get_const ()
+@anchor{cp/topics/types _CPPv4N6gccjit4type9get_constEv}@anchor{1bd}@anchor{cp/topics/types _CPPv3N6gccjit4type9get_constEv}@anchor{1cd}@anchor{cp/topics/types _CPPv2N6gccjit4type9get_constEv}@anchor{1ce}@anchor{cp/topics/types gccjit type get_const}@anchor{1cf}
+@deffn {C++ Function} gccjit::@ref{13f,,type} gccjit::@ref{13f,,type}::get_const ()
Given type “T”, get type “const T”.
@end deffn
@geindex gccjit;;type;;get_volatile (C++ function)
-@anchor{cp/topics/types _CPPv2N6gccjit4type12get_volatileEv}@anchor{194}@anchor{cp/topics/types gccjit type get_volatile}@anchor{195}
-@deffn {C++ Function} gccjit::@ref{12f,,type} gccjit::type::get_volatile ()
+@anchor{cp/topics/types _CPPv4N6gccjit4type12get_volatileEv}@anchor{1d0}@anchor{cp/topics/types _CPPv3N6gccjit4type12get_volatileEv}@anchor{1d1}@anchor{cp/topics/types _CPPv2N6gccjit4type12get_volatileEv}@anchor{1d2}@anchor{cp/topics/types gccjit type get_volatile}@anchor{1d3}
+@deffn {C++ Function} gccjit::@ref{13f,,type} gccjit::@ref{13f,,type}::get_volatile ()
Given type “T”, get type “volatile T”.
@end deffn
@geindex gccjit;;type;;get_aligned (C++ function)
-@anchor{cp/topics/types _CPPv2N6gccjit4type11get_alignedE6size_t}@anchor{196}@anchor{cp/topics/types gccjit type get_aligned__s}@anchor{197}
-@deffn {C++ Function} gccjit::@ref{12f,,type} gccjit::type::get_aligned (size_t alignment_in_bytes)
+@anchor{cp/topics/types _CPPv4N6gccjit4type11get_alignedE6size_t}@anchor{1d4}@anchor{cp/topics/types _CPPv3N6gccjit4type11get_alignedE6size_t}@anchor{1d5}@anchor{cp/topics/types _CPPv2N6gccjit4type11get_alignedE6size_t}@anchor{1d6}@anchor{cp/topics/types gccjit type get_aligned__s}@anchor{1d7}
+@deffn {C++ Function} gccjit::@ref{13f,,type} gccjit::@ref{13f,,type}::get_aligned (size_t alignment_in_bytes)
Given type “T”, get type:
@@ -12238,21 +12697,21 @@ The alignment must be a power of two.
@end deffn
@geindex gccjit;;context;;new_array_type (C++ function)
-@anchor{cp/topics/types _CPPv2N6gccjit7context14new_array_typeEN6gccjit4typeEiN6gccjit8locationE}@anchor{198}@anchor{cp/topics/types gccjit context new_array_type__gccjit type i gccjit location}@anchor{199}
-@deffn {C++ Function} gccjit::@ref{12f,,type} gccjit::context::new_array_type (gccjit::type element_type, int num_elements, gccjit::location loc)
+@anchor{cp/topics/types _CPPv4N6gccjit7context14new_array_typeEN6gccjit4typeEiN6gccjit8locationE}@anchor{1d8}@anchor{cp/topics/types _CPPv3N6gccjit7context14new_array_typeEN6gccjit4typeEiN6gccjit8locationE}@anchor{1d9}@anchor{cp/topics/types _CPPv2N6gccjit7context14new_array_typeEN6gccjit4typeEiN6gccjit8locationE}@anchor{1da}@anchor{cp/topics/types gccjit context new_array_type__gccjit type i gccjit location}@anchor{1db}
+@deffn {C++ Function} gccjit::@ref{13f,,type} gccjit::@ref{13d,,context}::new_array_type (gccjit::type element_type, int num_elements, gccjit::location loc)
Given type “T”, get type “T[N]” (for a constant N).
Param “loc” is optional.
@end deffn
@node Vector types<2>,Structures and unions<2>,Pointers const and volatile<2>,Types<2>
-@anchor{cp/topics/types vector-types}@anchor{19a}
+@anchor{cp/topics/types vector-types}@anchor{1dc}
@subsubsection Vector types
@geindex gccjit;;type;;get_vector (C++ function)
-@anchor{cp/topics/types _CPPv2N6gccjit4type10get_vectorE6size_t}@anchor{19b}@anchor{cp/topics/types gccjit type get_vector__s}@anchor{19c}
-@deffn {C++ Function} gccjit::@ref{12f,,type} gccjit::type::get_vector (size_t num_units)
+@anchor{cp/topics/types _CPPv4N6gccjit4type10get_vectorE6size_t}@anchor{1dd}@anchor{cp/topics/types _CPPv3N6gccjit4type10get_vectorE6size_t}@anchor{1de}@anchor{cp/topics/types _CPPv2N6gccjit4type10get_vectorE6size_t}@anchor{1df}@anchor{cp/topics/types gccjit type get_vector__s}@anchor{1e0}
+@deffn {C++ Function} gccjit::@ref{13f,,type} gccjit::@ref{13f,,type}::get_vector (size_t num_units)
Given type “T”, get type:
@@ -12264,31 +12723,31 @@ T must be integral or floating point; num_units must be a power of two.
@end deffn
@node Structures and unions<2>,,Vector types<2>,Types<2>
-@anchor{cp/topics/types structures-and-unions}@anchor{19d}
+@anchor{cp/topics/types structures-and-unions}@anchor{1e1}
@subsubsection Structures and unions
@geindex gccjit;;struct_ (C++ class)
-@anchor{cp/topics/types _CPPv2N6gccjit7struct_E}@anchor{19e}@anchor{cp/topics/types gccjit struct_}@anchor{19f}
+@anchor{cp/topics/types _CPPv4N6gccjit7struct_E}@anchor{1e2}@anchor{cp/topics/types _CPPv3N6gccjit7struct_E}@anchor{1e3}@anchor{cp/topics/types _CPPv2N6gccjit7struct_E}@anchor{1e4}@anchor{cp/topics/types gccjit struct_}@anchor{1e5}
@deffn {C++ Class} gccjit::struct_
@end deffn
A compound type analagous to a C @cite{struct}.
-@ref{19e,,gccjit;;struct_} is a subclass of @ref{12f,,gccjit;;type} (and thus
-of @ref{132,,gccjit;;object} in turn).
+@ref{1e2,,gccjit;;struct_} is a subclass of @ref{13f,,gccjit;;type} (and thus
+of @ref{142,,gccjit;;object} in turn).
@geindex gccjit;;field (C++ class)
-@anchor{cp/topics/types _CPPv2N6gccjit5fieldE}@anchor{1a0}@anchor{cp/topics/types gccjit field}@anchor{1a1}
+@anchor{cp/topics/types _CPPv4N6gccjit5fieldE}@anchor{1e6}@anchor{cp/topics/types _CPPv3N6gccjit5fieldE}@anchor{1e7}@anchor{cp/topics/types _CPPv2N6gccjit5fieldE}@anchor{1e8}@anchor{cp/topics/types gccjit field}@anchor{1e9}
@deffn {C++ Class} gccjit::field
@end deffn
-A field within a @ref{19e,,gccjit;;struct_}.
+A field within a @ref{1e2,,gccjit;;struct_}.
-@ref{1a0,,gccjit;;field} is a subclass of @ref{132,,gccjit;;object}.
+@ref{1e6,,gccjit;;field} is a subclass of @ref{142,,gccjit;;object}.
-You can model C @cite{struct} types by creating @ref{19e,,gccjit;;struct_} and
-@ref{1a0,,gccjit;;field} instances, in either order:
+You can model C @cite{struct} types by creating @ref{1e2,,gccjit;;struct_} and
+@ref{1e6,,gccjit;;field} instances, in either order:
@itemize *
@@ -12336,15 +12795,15 @@ node.set_fields (fields);
@c FIXME: the above API doesn't seem to exist yet
@geindex gccjit;;context;;new_field (C++ function)
-@anchor{cp/topics/types _CPPv2N6gccjit7context9new_fieldEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{1a2}@anchor{cp/topics/types gccjit context new_field__gccjit type cCP gccjit location}@anchor{1a3}
-@deffn {C++ Function} gccjit::@ref{1a0,,field} gccjit::context::new_field (gccjit::type type, const char *name, gccjit::location loc)
+@anchor{cp/topics/types _CPPv4N6gccjit7context9new_fieldEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{1ea}@anchor{cp/topics/types _CPPv3N6gccjit7context9new_fieldEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{1eb}@anchor{cp/topics/types _CPPv2N6gccjit7context9new_fieldEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{1ec}@anchor{cp/topics/types gccjit context new_field__gccjit type cCP gccjit location}@anchor{1ed}
+@deffn {C++ Function} gccjit::@ref{1e6,,field} gccjit::@ref{13d,,context}::new_field (gccjit::type type, const char *name, gccjit::location loc)
Construct a new field, with the given type and name.
@end deffn
@geindex gccjit;;context;;new_struct_type (C++ function)
-@anchor{cp/topics/types _CPPv2N6gccjit7context15new_struct_typeERKNSt6stringERNSt6vectorI5fieldEEN6gccjit8locationE}@anchor{1a4}@anchor{cp/topics/types gccjit context new_struct_type__ssCR std vector field R gccjit location}@anchor{1a5}
-@deffn {C++ Function} gccjit::@ref{19e,,struct_} gccjit::context::new_struct_type (const std::string &name, std::vector<field> &fields, gccjit::location loc)
+@anchor{cp/topics/types _CPPv4N6gccjit7context15new_struct_typeERKNSt6stringERNSt6vectorI5fieldEEN6gccjit8locationE}@anchor{1ee}@anchor{cp/topics/types _CPPv3N6gccjit7context15new_struct_typeERKNSt6stringERNSt6vectorI5fieldEEN6gccjit8locationE}@anchor{1ef}@anchor{cp/topics/types _CPPv2N6gccjit7context15new_struct_typeERKNSt6stringERNSt6vectorI5fieldEEN6gccjit8locationE}@anchor{1f0}@anchor{cp/topics/types gccjit context new_struct_type__ssCR std vector field R gccjit location}@anchor{1f1}
+@deffn {C++ Function} gccjit::@ref{1e2,,struct_} gccjit::@ref{13d,,context}::new_struct_type (const std::string &name, std::vector<field> &fields, gccjit::location loc)
@quotation
@@ -12353,8 +12812,8 @@ Construct a new struct type, with the given name and fields.
@end deffn
@geindex gccjit;;context;;new_opaque_struct (C++ function)
-@anchor{cp/topics/types _CPPv2N6gccjit7context17new_opaque_structERKNSt6stringEN6gccjit8locationE}@anchor{1a6}@anchor{cp/topics/types gccjit context new_opaque_struct__ssCR gccjit location}@anchor{1a7}
-@deffn {C++ Function} gccjit::@ref{19e,,struct_} gccjit::context::new_opaque_struct (const std::string &name, gccjit::location loc)
+@anchor{cp/topics/types _CPPv4N6gccjit7context17new_opaque_structERKNSt6stringEN6gccjit8locationE}@anchor{1f2}@anchor{cp/topics/types _CPPv3N6gccjit7context17new_opaque_structERKNSt6stringEN6gccjit8locationE}@anchor{1f3}@anchor{cp/topics/types _CPPv2N6gccjit7context17new_opaque_structERKNSt6stringEN6gccjit8locationE}@anchor{1f4}@anchor{cp/topics/types gccjit context new_opaque_struct__ssCR gccjit location}@anchor{1f5}
+@deffn {C++ Function} gccjit::@ref{1e2,,struct_} gccjit::@ref{13d,,context}::new_opaque_struct (const std::string &name, gccjit::location loc)
Construct a new struct type, with the given name, but without
specifying the fields. The fields can be omitted (in which case the
@@ -12380,7 +12839,7 @@ size of the struct is not known), or later specified using
@c <http://www.gnu.org/licenses/>.
@node Expressions<2>,Creating and using functions<2>,Types<2>,Topic Reference<2>
-@anchor{cp/topics/expressions expressions}@anchor{1a8}@anchor{cp/topics/expressions doc}@anchor{1a9}
+@anchor{cp/topics/expressions doc}@anchor{1f6}@anchor{cp/topics/expressions expressions}@anchor{1f7}
@subsection Expressions
@@ -12392,17 +12851,17 @@ size of the struct is not known), or later specified using
@end menu
@node Rvalues<2>,Lvalues<2>,,Expressions<2>
-@anchor{cp/topics/expressions rvalues}@anchor{1aa}
+@anchor{cp/topics/expressions rvalues}@anchor{1f8}
@subsubsection Rvalues
@geindex gccjit;;rvalue (C++ class)
-@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalueE}@anchor{136}@anchor{cp/topics/expressions gccjit rvalue}@anchor{1ab}
+@anchor{cp/topics/expressions _CPPv4N6gccjit6rvalueE}@anchor{146}@anchor{cp/topics/expressions _CPPv3N6gccjit6rvalueE}@anchor{1f9}@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalueE}@anchor{1fa}@anchor{cp/topics/expressions gccjit rvalue}@anchor{1fb}
@deffn {C++ Class} gccjit::rvalue
@end deffn
-A @ref{136,,gccjit;;rvalue} is an expression that can be computed. It is a
-subclass of @ref{132,,gccjit;;object}, and is a thin wrapper around
+A @ref{146,,gccjit;;rvalue} is an expression that can be computed. It is a
+subclass of @ref{142,,gccjit;;object}, and is a thin wrapper around
@ref{13,,gcc_jit_rvalue *} from the C API.
It can be simple, e.g.:
@@ -12448,8 +12907,8 @@ Every rvalue has an associated type, and the API will check to ensure
that types match up correctly (otherwise the context will emit an error).
@geindex gccjit;;rvalue;;get_type (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalue8get_typeEv}@anchor{1ac}@anchor{cp/topics/expressions gccjit rvalue get_type}@anchor{1ad}
-@deffn {C++ Function} gccjit::@ref{12f,,type} gccjit::rvalue::get_type ()
+@anchor{cp/topics/expressions _CPPv4N6gccjit6rvalue8get_typeEv}@anchor{1fc}@anchor{cp/topics/expressions _CPPv3N6gccjit6rvalue8get_typeEv}@anchor{1fd}@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalue8get_typeEv}@anchor{1fe}@anchor{cp/topics/expressions gccjit rvalue get_type}@anchor{1ff}
+@deffn {C++ Function} gccjit::@ref{13f,,type} gccjit::@ref{146,,rvalue}::get_type ()
Get the type of this rvalue.
@end deffn
@@ -12467,29 +12926,29 @@ Get the type of this rvalue.
@end menu
@node Simple expressions<2>,Vector expressions<2>,,Rvalues<2>
-@anchor{cp/topics/expressions simple-expressions}@anchor{1ae}
+@anchor{cp/topics/expressions simple-expressions}@anchor{200}
@subsubsection Simple expressions
@geindex gccjit;;context;;new_rvalue (C++ function)
-@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeEi}@anchor{14a}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type iC}@anchor{1af}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_rvalue (gccjit::type numeric_type, int value) const
+@anchor{cp/topics/expressions _CPPv4NK6gccjit7context10new_rvalueEN6gccjit4typeEi}@anchor{15a}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context10new_rvalueEN6gccjit4typeEi}@anchor{201}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeEi}@anchor{202}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type iC}@anchor{203}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_rvalue (gccjit::type numeric_type, int value) const
Given a numeric type (integer or floating point), build an rvalue for
the given constant @code{int} value.
@end deffn
@geindex gccjit;;context;;new_rvalue (C++ function)
-@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeEl}@anchor{1b0}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type lC}@anchor{1b1}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_rvalue (gccjit::type numeric_type, long value) const
+@anchor{cp/topics/expressions _CPPv4NK6gccjit7context10new_rvalueEN6gccjit4typeEl}@anchor{204}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context10new_rvalueEN6gccjit4typeEl}@anchor{205}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeEl}@anchor{206}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type lC}@anchor{207}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_rvalue (gccjit::type numeric_type, long value) const
Given a numeric type (integer or floating point), build an rvalue for
the given constant @code{long} value.
@end deffn
@geindex gccjit;;context;;zero (C++ function)
-@anchor{cp/topics/expressions _CPPv2NK6gccjit7context4zeroEN6gccjit4typeE}@anchor{146}@anchor{cp/topics/expressions gccjit context zero__gccjit typeC}@anchor{1b2}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::zero (gccjit::type numeric_type) const
+@anchor{cp/topics/expressions _CPPv4NK6gccjit7context4zeroEN6gccjit4typeE}@anchor{156}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context4zeroEN6gccjit4typeE}@anchor{208}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context4zeroEN6gccjit4typeE}@anchor{209}@anchor{cp/topics/expressions gccjit context zero__gccjit typeC}@anchor{20a}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::zero (gccjit::type numeric_type) const
Given a numeric type (integer or floating point), get the rvalue for
zero. Essentially this is just a shortcut for:
@@ -12500,8 +12959,8 @@ ctxt.new_rvalue (numeric_type, 0)
@end deffn
@geindex gccjit;;context;;one (C++ function)
-@anchor{cp/topics/expressions _CPPv2NK6gccjit7context3oneEN6gccjit4typeE}@anchor{1b3}@anchor{cp/topics/expressions gccjit context one__gccjit typeC}@anchor{1b4}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::one (gccjit::type numeric_type) const
+@anchor{cp/topics/expressions _CPPv4NK6gccjit7context3oneEN6gccjit4typeE}@anchor{20b}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context3oneEN6gccjit4typeE}@anchor{20c}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context3oneEN6gccjit4typeE}@anchor{20d}@anchor{cp/topics/expressions gccjit context one__gccjit typeC}@anchor{20e}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::one (gccjit::type numeric_type) const
Given a numeric type (integer or floating point), get the rvalue for
one. Essentially this is just a shortcut for:
@@ -12512,36 +12971,36 @@ ctxt.new_rvalue (numeric_type, 1)
@end deffn
@geindex gccjit;;context;;new_rvalue (C++ function)
-@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeEd}@anchor{1b5}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type doubleC}@anchor{1b6}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_rvalue (gccjit::type numeric_type, double value) const
+@anchor{cp/topics/expressions _CPPv4NK6gccjit7context10new_rvalueEN6gccjit4typeEd}@anchor{20f}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context10new_rvalueEN6gccjit4typeEd}@anchor{210}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeEd}@anchor{211}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type doubleC}@anchor{212}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_rvalue (gccjit::type numeric_type, double value) const
Given a numeric type (integer or floating point), build an rvalue for
the given constant @code{double} value.
@end deffn
@geindex gccjit;;context;;new_rvalue (C++ function)
-@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeEPv}@anchor{1b7}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type voidPC}@anchor{1b8}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_rvalue (gccjit::type pointer_type, void *value) const
+@anchor{cp/topics/expressions _CPPv4NK6gccjit7context10new_rvalueEN6gccjit4typeEPv}@anchor{213}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context10new_rvalueEN6gccjit4typeEPv}@anchor{214}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeEPv}@anchor{215}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type voidPC}@anchor{216}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_rvalue (gccjit::type pointer_type, void *value) const
Given a pointer type, build an rvalue for the given address.
@end deffn
@geindex gccjit;;context;;new_rvalue (C++ function)
-@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueERKNSt6stringE}@anchor{1b9}@anchor{cp/topics/expressions gccjit context new_rvalue__ssCRC}@anchor{1ba}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_rvalue (const std::string &value) const
+@anchor{cp/topics/expressions _CPPv4NK6gccjit7context10new_rvalueERKNSt6stringE}@anchor{217}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context10new_rvalueERKNSt6stringE}@anchor{218}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueERKNSt6stringE}@anchor{219}@anchor{cp/topics/expressions gccjit context new_rvalue__ssCRC}@anchor{21a}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_rvalue (const std::string &value) const
Generate an rvalue of type @code{GCC_JIT_TYPE_CONST_CHAR_PTR} for
the given string. This is akin to a string literal.
@end deffn
@node Vector expressions<2>,Unary Operations<2>,Simple expressions<2>,Rvalues<2>
-@anchor{cp/topics/expressions vector-expressions}@anchor{1bb}
+@anchor{cp/topics/expressions vector-expressions}@anchor{21b}
@subsubsection Vector expressions
@geindex gccjit;;context;;new_rvalue (C++ function)
-@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeENSt6vectorIN6gccjit6rvalueEEE}@anchor{1bc}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type std vector gccjit rvalue C}@anchor{1bd}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_rvalue (gccjit::type vector_type, std::vector<gccjit::rvalue> elements) const
+@anchor{cp/topics/expressions _CPPv4NK6gccjit7context10new_rvalueEN6gccjit4typeENSt6vectorIN6gccjit6rvalueEEE}@anchor{21c}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context10new_rvalueEN6gccjit4typeENSt6vectorIN6gccjit6rvalueEEE}@anchor{21d}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeENSt6vectorIN6gccjit6rvalueEEE}@anchor{21e}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type std vector gccjit rvalue C}@anchor{21f}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_rvalue (gccjit::type vector_type, std::vector<gccjit::rvalue> elements) const
Given a vector type, and a vector of scalar rvalue elements, generate a
vector rvalue.
@@ -12550,13 +13009,13 @@ The number of elements needs to match that of the vector type.
@end deffn
@node Unary Operations<2>,Binary Operations<2>,Vector expressions<2>,Rvalues<2>
-@anchor{cp/topics/expressions unary-operations}@anchor{1be}
+@anchor{cp/topics/expressions unary-operations}@anchor{220}
@subsubsection Unary Operations
@geindex gccjit;;context;;new_unary_op (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context12new_unary_opE16gcc_jit_unary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{1bf}@anchor{cp/topics/expressions gccjit context new_unary_op__gcc_jit_unary_op gccjit type gccjit rvalue gccjit location}@anchor{1c0}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_unary_op (enum gcc_jit_unary_op, gccjit::type result_type, gccjit::rvalue rvalue, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context12new_unary_opE16gcc_jit_unary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{221}@anchor{cp/topics/expressions _CPPv3N6gccjit7context12new_unary_opE16gcc_jit_unary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{222}@anchor{cp/topics/expressions _CPPv2N6gccjit7context12new_unary_opE16gcc_jit_unary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{223}@anchor{cp/topics/expressions gccjit context new_unary_op__gcc_jit_unary_op gccjit type gccjit rvalue gccjit location}@anchor{224}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_unary_op (enum gcc_jit_unary_op, gccjit::type result_type, gccjit::rvalue rvalue, gccjit::location loc)
Build a unary operation out of an input rvalue.
@@ -12571,8 +13030,8 @@ There are shorter ways to spell the various specific kinds of unary
operation:
@geindex gccjit;;context;;new_minus (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{1c1}@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit location}@anchor{1c2}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{225}@anchor{cp/topics/expressions _CPPv3N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{226}@anchor{cp/topics/expressions _CPPv2N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{227}@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit location}@anchor{228}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc)
Negate an arithmetic value; for example:
@@ -12588,8 +13047,8 @@ builds the equivalent of this C expression:
@end deffn
@geindex new_bitwise_negate (C++ function)
-@anchor{cp/topics/expressions _CPPv218new_bitwise_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{1c3}@anchor{cp/topics/expressions new_bitwise_negate__gccjit type gccjit rvalue gccjit location}@anchor{1c4}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} new_bitwise_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv418new_bitwise_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{229}@anchor{cp/topics/expressions _CPPv318new_bitwise_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{22a}@anchor{cp/topics/expressions _CPPv218new_bitwise_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{22b}@anchor{cp/topics/expressions new_bitwise_negate__gccjit type gccjit rvalue gccjit location}@anchor{22c}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} new_bitwise_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc)
Bitwise negation of an integer value (one’s complement); for example:
@@ -12605,8 +13064,8 @@ builds the equivalent of this C expression:
@end deffn
@geindex new_logical_negate (C++ function)
-@anchor{cp/topics/expressions _CPPv218new_logical_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{1c5}@anchor{cp/topics/expressions new_logical_negate__gccjit type gccjit rvalue gccjit location}@anchor{1c6}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} new_logical_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv418new_logical_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{22d}@anchor{cp/topics/expressions _CPPv318new_logical_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{22e}@anchor{cp/topics/expressions _CPPv218new_logical_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{22f}@anchor{cp/topics/expressions new_logical_negate__gccjit type gccjit rvalue gccjit location}@anchor{230}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} new_logical_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc)
Logical negation of an arithmetic or pointer value; for example:
@@ -12624,8 +13083,8 @@ builds the equivalent of this C expression:
The most concise way to spell them is with overloaded operators:
@geindex operator- (C++ function)
-@anchor{cp/topics/expressions _CPPv2miN6gccjit6rvalueE}@anchor{1c7}@anchor{cp/topics/expressions sub-operator__gccjit rvalue}@anchor{1c8}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator@w{-} (gccjit::rvalue a)
+@anchor{cp/topics/expressions _CPPv4miN6gccjit6rvalueE}@anchor{231}@anchor{cp/topics/expressions _CPPv3miN6gccjit6rvalueE}@anchor{232}@anchor{cp/topics/expressions _CPPv2miN6gccjit6rvalueE}@anchor{233}@anchor{cp/topics/expressions sub-operator__gccjit rvalue}@anchor{234}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator@w{-} (gccjit::rvalue a)
@example
gccjit::rvalue negpi = -pi;
@@ -12633,8 +13092,8 @@ gccjit::rvalue negpi = -pi;
@end deffn
@geindex operator~ (C++ function)
-@anchor{cp/topics/expressions _CPPv2coN6gccjit6rvalueE}@anchor{1c9}@anchor{cp/topics/expressions inv-operator__gccjit rvalue}@anchor{1ca}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator~ (gccjit::rvalue a)
+@anchor{cp/topics/expressions _CPPv4coN6gccjit6rvalueE}@anchor{235}@anchor{cp/topics/expressions _CPPv3coN6gccjit6rvalueE}@anchor{236}@anchor{cp/topics/expressions _CPPv2coN6gccjit6rvalueE}@anchor{237}@anchor{cp/topics/expressions inv-operator__gccjit rvalue}@anchor{238}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator~ (gccjit::rvalue a)
@example
gccjit::rvalue mask = ~a;
@@ -12642,8 +13101,8 @@ gccjit::rvalue mask = ~a;
@end deffn
@geindex operator! (C++ function)
-@anchor{cp/topics/expressions _CPPv2ntN6gccjit6rvalueE}@anchor{1cb}@anchor{cp/topics/expressions not-operator__gccjit rvalue}@anchor{1cc}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator! (gccjit::rvalue a)
+@anchor{cp/topics/expressions _CPPv4ntN6gccjit6rvalueE}@anchor{239}@anchor{cp/topics/expressions _CPPv3ntN6gccjit6rvalueE}@anchor{23a}@anchor{cp/topics/expressions _CPPv2ntN6gccjit6rvalueE}@anchor{23b}@anchor{cp/topics/expressions not-operator__gccjit rvalue}@anchor{23c}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator! (gccjit::rvalue a)
@example
gccjit::rvalue guard = !cond;
@@ -12651,13 +13110,13 @@ gccjit::rvalue guard = !cond;
@end deffn
@node Binary Operations<2>,Comparisons<2>,Unary Operations<2>,Rvalues<2>
-@anchor{cp/topics/expressions binary-operations}@anchor{1cd}
+@anchor{cp/topics/expressions binary-operations}@anchor{23d}
@subsubsection Binary Operations
@geindex gccjit;;context;;new_binary_op (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context13new_binary_opE17gcc_jit_binary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{135}@anchor{cp/topics/expressions gccjit context new_binary_op__gcc_jit_binary_op gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{1ce}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_binary_op (enum gcc_jit_binary_op, gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context13new_binary_opE17gcc_jit_binary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{145}@anchor{cp/topics/expressions _CPPv3N6gccjit7context13new_binary_opE17gcc_jit_binary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{23e}@anchor{cp/topics/expressions _CPPv2N6gccjit7context13new_binary_opE17gcc_jit_binary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{23f}@anchor{cp/topics/expressions gccjit context new_binary_op__gcc_jit_binary_op gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{240}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_binary_op (enum gcc_jit_binary_op, gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
Build a binary operation out of two constituent rvalues.
@@ -12672,60 +13131,60 @@ There are shorter ways to spell the various specific kinds of binary
operation:
@geindex gccjit;;context;;new_plus (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context8new_plusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{1cf}@anchor{cp/topics/expressions gccjit context new_plus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{1d0}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_plus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context8new_plusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{241}@anchor{cp/topics/expressions _CPPv3N6gccjit7context8new_plusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{242}@anchor{cp/topics/expressions _CPPv2N6gccjit7context8new_plusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{243}@anchor{cp/topics/expressions gccjit context new_plus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{244}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_plus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_minus (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{1d1}@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{1d2}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{245}@anchor{cp/topics/expressions _CPPv3N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{246}@anchor{cp/topics/expressions _CPPv2N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{247}@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{248}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_mult (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context8new_multEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{1d3}@anchor{cp/topics/expressions gccjit context new_mult__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{1d4}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_mult (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context8new_multEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{249}@anchor{cp/topics/expressions _CPPv3N6gccjit7context8new_multEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{24a}@anchor{cp/topics/expressions _CPPv2N6gccjit7context8new_multEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{24b}@anchor{cp/topics/expressions gccjit context new_mult__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{24c}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_mult (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_divide (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context10new_divideEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{1d5}@anchor{cp/topics/expressions gccjit context new_divide__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{1d6}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_divide (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context10new_divideEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{24d}@anchor{cp/topics/expressions _CPPv3N6gccjit7context10new_divideEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{24e}@anchor{cp/topics/expressions _CPPv2N6gccjit7context10new_divideEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{24f}@anchor{cp/topics/expressions gccjit context new_divide__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{250}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_divide (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_modulo (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context10new_moduloEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{1d7}@anchor{cp/topics/expressions gccjit context new_modulo__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{1d8}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_modulo (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context10new_moduloEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{251}@anchor{cp/topics/expressions _CPPv3N6gccjit7context10new_moduloEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{252}@anchor{cp/topics/expressions _CPPv2N6gccjit7context10new_moduloEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{253}@anchor{cp/topics/expressions gccjit context new_modulo__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{254}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_modulo (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_bitwise_and (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context15new_bitwise_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{1d9}@anchor{cp/topics/expressions gccjit context new_bitwise_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{1da}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_bitwise_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context15new_bitwise_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{255}@anchor{cp/topics/expressions _CPPv3N6gccjit7context15new_bitwise_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{256}@anchor{cp/topics/expressions _CPPv2N6gccjit7context15new_bitwise_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{257}@anchor{cp/topics/expressions gccjit context new_bitwise_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{258}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_bitwise_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_bitwise_xor (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context15new_bitwise_xorEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{1db}@anchor{cp/topics/expressions gccjit context new_bitwise_xor__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{1dc}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_bitwise_xor (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context15new_bitwise_xorEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{259}@anchor{cp/topics/expressions _CPPv3N6gccjit7context15new_bitwise_xorEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{25a}@anchor{cp/topics/expressions _CPPv2N6gccjit7context15new_bitwise_xorEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{25b}@anchor{cp/topics/expressions gccjit context new_bitwise_xor__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{25c}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_bitwise_xor (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_bitwise_or (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context14new_bitwise_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{1dd}@anchor{cp/topics/expressions gccjit context new_bitwise_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{1de}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_bitwise_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context14new_bitwise_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{25d}@anchor{cp/topics/expressions _CPPv3N6gccjit7context14new_bitwise_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{25e}@anchor{cp/topics/expressions _CPPv2N6gccjit7context14new_bitwise_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{25f}@anchor{cp/topics/expressions gccjit context new_bitwise_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{260}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_bitwise_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_logical_and (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context15new_logical_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{1df}@anchor{cp/topics/expressions gccjit context new_logical_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{1e0}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_logical_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context15new_logical_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{261}@anchor{cp/topics/expressions _CPPv3N6gccjit7context15new_logical_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{262}@anchor{cp/topics/expressions _CPPv2N6gccjit7context15new_logical_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{263}@anchor{cp/topics/expressions gccjit context new_logical_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{264}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_logical_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_logical_or (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context14new_logical_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{1e1}@anchor{cp/topics/expressions gccjit context new_logical_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{1e2}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_logical_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context14new_logical_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{265}@anchor{cp/topics/expressions _CPPv3N6gccjit7context14new_logical_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{266}@anchor{cp/topics/expressions _CPPv2N6gccjit7context14new_logical_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{267}@anchor{cp/topics/expressions gccjit context new_logical_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{268}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_logical_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
The most concise way to spell them is with overloaded operators:
@geindex operator+ (C++ function)
-@anchor{cp/topics/expressions _CPPv2plN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{1e3}@anchor{cp/topics/expressions add-operator__gccjit rvalue gccjit rvalue}@anchor{1e4}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator+ (gccjit::rvalue a, gccjit::rvalue b)
+@anchor{cp/topics/expressions _CPPv4plN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{269}@anchor{cp/topics/expressions _CPPv3plN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{26a}@anchor{cp/topics/expressions _CPPv2plN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{26b}@anchor{cp/topics/expressions add-operator__gccjit rvalue gccjit rvalue}@anchor{26c}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator+ (gccjit::rvalue a, gccjit::rvalue b)
@example
gccjit::rvalue sum = a + b;
@@ -12733,8 +13192,8 @@ gccjit::rvalue sum = a + b;
@end deffn
@geindex operator- (C++ function)
-@anchor{cp/topics/expressions _CPPv2miN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{1e5}@anchor{cp/topics/expressions sub-operator__gccjit rvalue gccjit rvalue}@anchor{1e6}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator@w{-} (gccjit::rvalue a, gccjit::rvalue b)
+@anchor{cp/topics/expressions _CPPv4miN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{26d}@anchor{cp/topics/expressions _CPPv3miN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{26e}@anchor{cp/topics/expressions _CPPv2miN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{26f}@anchor{cp/topics/expressions sub-operator__gccjit rvalue gccjit rvalue}@anchor{270}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator@w{-} (gccjit::rvalue a, gccjit::rvalue b)
@example
gccjit::rvalue diff = a - b;
@@ -12742,8 +13201,8 @@ gccjit::rvalue diff = a - b;
@end deffn
@geindex operator* (C++ function)
-@anchor{cp/topics/expressions _CPPv2mlN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{1e7}@anchor{cp/topics/expressions mul-operator__gccjit rvalue gccjit rvalue}@anchor{1e8}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator* (gccjit::rvalue a, gccjit::rvalue b)
+@anchor{cp/topics/expressions _CPPv4mlN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{271}@anchor{cp/topics/expressions _CPPv3mlN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{272}@anchor{cp/topics/expressions _CPPv2mlN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{273}@anchor{cp/topics/expressions mul-operator__gccjit rvalue gccjit rvalue}@anchor{274}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator* (gccjit::rvalue a, gccjit::rvalue b)
@example
gccjit::rvalue prod = a * b;
@@ -12751,8 +13210,8 @@ gccjit::rvalue prod = a * b;
@end deffn
@geindex operator/ (C++ function)
-@anchor{cp/topics/expressions _CPPv2dvN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{1e9}@anchor{cp/topics/expressions div-operator__gccjit rvalue gccjit rvalue}@anchor{1ea}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator/ (gccjit::rvalue a, gccjit::rvalue b)
+@anchor{cp/topics/expressions _CPPv4dvN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{275}@anchor{cp/topics/expressions _CPPv3dvN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{276}@anchor{cp/topics/expressions _CPPv2dvN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{277}@anchor{cp/topics/expressions div-operator__gccjit rvalue gccjit rvalue}@anchor{278}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator/ (gccjit::rvalue a, gccjit::rvalue b)
@example
gccjit::rvalue result = a / b;
@@ -12760,8 +13219,8 @@ gccjit::rvalue result = a / b;
@end deffn
@geindex operator% (C++ function)
-@anchor{cp/topics/expressions _CPPv2rmN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{1eb}@anchor{cp/topics/expressions mod-operator__gccjit rvalue gccjit rvalue}@anchor{1ec}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator% (gccjit::rvalue a, gccjit::rvalue b)
+@anchor{cp/topics/expressions _CPPv4rmN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{279}@anchor{cp/topics/expressions _CPPv3rmN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{27a}@anchor{cp/topics/expressions _CPPv2rmN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{27b}@anchor{cp/topics/expressions mod-operator__gccjit rvalue gccjit rvalue}@anchor{27c}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator% (gccjit::rvalue a, gccjit::rvalue b)
@example
gccjit::rvalue mod = a % b;
@@ -12769,8 +13228,8 @@ gccjit::rvalue mod = a % b;
@end deffn
@geindex operator& (C++ function)
-@anchor{cp/topics/expressions _CPPv2anN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{1ed}@anchor{cp/topics/expressions and-operator__gccjit rvalue gccjit rvalue}@anchor{1ee}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator& (gccjit::rvalue a, gccjit::rvalue b)
+@anchor{cp/topics/expressions _CPPv4anN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{27d}@anchor{cp/topics/expressions _CPPv3anN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{27e}@anchor{cp/topics/expressions _CPPv2anN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{27f}@anchor{cp/topics/expressions and-operator__gccjit rvalue gccjit rvalue}@anchor{280}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator& (gccjit::rvalue a, gccjit::rvalue b)
@example
gccjit::rvalue x = a & b;
@@ -12778,8 +13237,8 @@ gccjit::rvalue x = a & b;
@end deffn
@geindex operator^ (C++ function)
-@anchor{cp/topics/expressions _CPPv2eoN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{1ef}@anchor{cp/topics/expressions xor-operator__gccjit rvalue gccjit rvalue}@anchor{1f0}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator^ (gccjit::rvalue a, gccjit::rvalue b)
+@anchor{cp/topics/expressions _CPPv4eoN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{281}@anchor{cp/topics/expressions _CPPv3eoN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{282}@anchor{cp/topics/expressions _CPPv2eoN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{283}@anchor{cp/topics/expressions xor-operator__gccjit rvalue gccjit rvalue}@anchor{284}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator^ (gccjit::rvalue a, gccjit::rvalue b)
@example
gccjit::rvalue x = a ^ b;
@@ -12787,8 +13246,8 @@ gccjit::rvalue x = a ^ b;
@end deffn
@geindex operator| (C++ function)
-@anchor{cp/topics/expressions _CPPv2orN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{1f1}@anchor{cp/topics/expressions or-operator__gccjit rvalue gccjit rvalue}@anchor{1f2}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator| (gccjit::rvalue a, gccjit::rvalue b)
+@anchor{cp/topics/expressions _CPPv4orN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{285}@anchor{cp/topics/expressions _CPPv3orN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{286}@anchor{cp/topics/expressions _CPPv2orN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{287}@anchor{cp/topics/expressions or-operator__gccjit rvalue gccjit rvalue}@anchor{288}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator| (gccjit::rvalue a, gccjit::rvalue b)
@example
gccjit::rvalue x = a | b;
@@ -12796,8 +13255,8 @@ gccjit::rvalue x = a | b;
@end deffn
@geindex operator&& (C++ function)
-@anchor{cp/topics/expressions _CPPv2aaN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{1f3}@anchor{cp/topics/expressions sand-operator__gccjit rvalue gccjit rvalue}@anchor{1f4}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator&& (gccjit::rvalue a, gccjit::rvalue b)
+@anchor{cp/topics/expressions _CPPv4aaN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{289}@anchor{cp/topics/expressions _CPPv3aaN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{28a}@anchor{cp/topics/expressions _CPPv2aaN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{28b}@anchor{cp/topics/expressions sand-operator__gccjit rvalue gccjit rvalue}@anchor{28c}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator&& (gccjit::rvalue a, gccjit::rvalue b)
@example
gccjit::rvalue cond = a && b;
@@ -12805,8 +13264,8 @@ gccjit::rvalue cond = a && b;
@end deffn
@geindex operator|| (C++ function)
-@anchor{cp/topics/expressions _CPPv2ooN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{1f5}@anchor{cp/topics/expressions sor-operator__gccjit rvalue gccjit rvalue}@anchor{1f6}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator|| (gccjit::rvalue a, gccjit::rvalue b)
+@anchor{cp/topics/expressions _CPPv4ooN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{28d}@anchor{cp/topics/expressions _CPPv3ooN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{28e}@anchor{cp/topics/expressions _CPPv2ooN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{28f}@anchor{cp/topics/expressions sor-operator__gccjit rvalue gccjit rvalue}@anchor{290}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator|| (gccjit::rvalue a, gccjit::rvalue b)
@example
gccjit::rvalue cond = a || b;
@@ -12824,13 +13283,13 @@ gccjit::rvalue discriminant = (b * b) - (four * a * c);
@end quotation
@node Comparisons<2>,Function calls<2>,Binary Operations<2>,Rvalues<2>
-@anchor{cp/topics/expressions comparisons}@anchor{1f7}
+@anchor{cp/topics/expressions comparisons}@anchor{291}
@subsubsection Comparisons
@geindex gccjit;;context;;new_comparison (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context14new_comparisonE18gcc_jit_comparisonN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{147}@anchor{cp/topics/expressions gccjit context new_comparison__gcc_jit_comparison gccjit rvalue gccjit rvalue gccjit location}@anchor{1f8}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_comparison (enum gcc_jit_comparison, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context14new_comparisonE18gcc_jit_comparisonN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{157}@anchor{cp/topics/expressions _CPPv3N6gccjit7context14new_comparisonE18gcc_jit_comparisonN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{292}@anchor{cp/topics/expressions _CPPv2N6gccjit7context14new_comparisonE18gcc_jit_comparisonN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{293}@anchor{cp/topics/expressions gccjit context new_comparison__gcc_jit_comparison gccjit rvalue gccjit rvalue gccjit location}@anchor{294}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_comparison (enum gcc_jit_comparison, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
Build a boolean rvalue out of the comparison of two other rvalues.
@@ -12845,40 +13304,40 @@ There are shorter ways to spell the various specific kinds of binary
operation:
@geindex gccjit;;context;;new_eq (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_eqEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{1f9}@anchor{cp/topics/expressions gccjit context new_eq__gccjit rvalue gccjit rvalue gccjit location}@anchor{1fa}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_eq (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context6new_eqEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{295}@anchor{cp/topics/expressions _CPPv3N6gccjit7context6new_eqEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{296}@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_eqEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{297}@anchor{cp/topics/expressions gccjit context new_eq__gccjit rvalue gccjit rvalue gccjit location}@anchor{298}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_eq (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_ne (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_neEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{1fb}@anchor{cp/topics/expressions gccjit context new_ne__gccjit rvalue gccjit rvalue gccjit location}@anchor{1fc}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_ne (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context6new_neEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{299}@anchor{cp/topics/expressions _CPPv3N6gccjit7context6new_neEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{29a}@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_neEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{29b}@anchor{cp/topics/expressions gccjit context new_ne__gccjit rvalue gccjit rvalue gccjit location}@anchor{29c}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_ne (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_lt (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_ltEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{1fd}@anchor{cp/topics/expressions gccjit context new_lt__gccjit rvalue gccjit rvalue gccjit location}@anchor{1fe}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_lt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context6new_ltEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{29d}@anchor{cp/topics/expressions _CPPv3N6gccjit7context6new_ltEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{29e}@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_ltEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{29f}@anchor{cp/topics/expressions gccjit context new_lt__gccjit rvalue gccjit rvalue gccjit location}@anchor{2a0}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_lt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_le (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_leEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{1ff}@anchor{cp/topics/expressions gccjit context new_le__gccjit rvalue gccjit rvalue gccjit location}@anchor{200}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_le (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context6new_leEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2a1}@anchor{cp/topics/expressions _CPPv3N6gccjit7context6new_leEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2a2}@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_leEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2a3}@anchor{cp/topics/expressions gccjit context new_le__gccjit rvalue gccjit rvalue gccjit location}@anchor{2a4}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_le (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_gt (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_gtEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{201}@anchor{cp/topics/expressions gccjit context new_gt__gccjit rvalue gccjit rvalue gccjit location}@anchor{202}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_gt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context6new_gtEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2a5}@anchor{cp/topics/expressions _CPPv3N6gccjit7context6new_gtEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2a6}@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_gtEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2a7}@anchor{cp/topics/expressions gccjit context new_gt__gccjit rvalue gccjit rvalue gccjit location}@anchor{2a8}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_gt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_ge (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_geEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{203}@anchor{cp/topics/expressions gccjit context new_ge__gccjit rvalue gccjit rvalue gccjit location}@anchor{204}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_ge (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context6new_geEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2a9}@anchor{cp/topics/expressions _CPPv3N6gccjit7context6new_geEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2aa}@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_geEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2ab}@anchor{cp/topics/expressions gccjit context new_ge__gccjit rvalue gccjit rvalue gccjit location}@anchor{2ac}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_ge (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
The most concise way to spell them is with overloaded operators:
@geindex operator== (C++ function)
-@anchor{cp/topics/expressions _CPPv2eqN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{205}@anchor{cp/topics/expressions eq-operator__gccjit rvalue gccjit rvalue}@anchor{206}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator== (gccjit::rvalue a, gccjit::rvalue b)
+@anchor{cp/topics/expressions _CPPv4eqN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2ad}@anchor{cp/topics/expressions _CPPv3eqN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2ae}@anchor{cp/topics/expressions _CPPv2eqN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2af}@anchor{cp/topics/expressions eq-operator__gccjit rvalue gccjit rvalue}@anchor{2b0}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator== (gccjit::rvalue a, gccjit::rvalue b)
@example
gccjit::rvalue cond = (a == ctxt.zero (t_int));
@@ -12886,8 +13345,8 @@ gccjit::rvalue cond = (a == ctxt.zero (t_int));
@end deffn
@geindex operator!= (C++ function)
-@anchor{cp/topics/expressions _CPPv2neN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{207}@anchor{cp/topics/expressions neq-operator__gccjit rvalue gccjit rvalue}@anchor{208}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator!= (gccjit::rvalue a, gccjit::rvalue b)
+@anchor{cp/topics/expressions _CPPv4neN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b1}@anchor{cp/topics/expressions _CPPv3neN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b2}@anchor{cp/topics/expressions _CPPv2neN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b3}@anchor{cp/topics/expressions neq-operator__gccjit rvalue gccjit rvalue}@anchor{2b4}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator!= (gccjit::rvalue a, gccjit::rvalue b)
@example
gccjit::rvalue cond = (i != j);
@@ -12895,8 +13354,8 @@ gccjit::rvalue cond = (i != j);
@end deffn
@geindex operator< (C++ function)
-@anchor{cp/topics/expressions _CPPv2ltN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{209}@anchor{cp/topics/expressions lt-operator__gccjit rvalue gccjit rvalue}@anchor{20a}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator< (gccjit::rvalue a, gccjit::rvalue b)
+@anchor{cp/topics/expressions _CPPv4ltN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b5}@anchor{cp/topics/expressions _CPPv3ltN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b6}@anchor{cp/topics/expressions _CPPv2ltN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b7}@anchor{cp/topics/expressions lt-operator__gccjit rvalue gccjit rvalue}@anchor{2b8}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator< (gccjit::rvalue a, gccjit::rvalue b)
@example
gccjit::rvalue cond = i < n;
@@ -12904,8 +13363,8 @@ gccjit::rvalue cond = i < n;
@end deffn
@geindex operator<= (C++ function)
-@anchor{cp/topics/expressions _CPPv2leN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{20b}@anchor{cp/topics/expressions lte-operator__gccjit rvalue gccjit rvalue}@anchor{20c}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator<= (gccjit::rvalue a, gccjit::rvalue b)
+@anchor{cp/topics/expressions _CPPv4leN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b9}@anchor{cp/topics/expressions _CPPv3leN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2ba}@anchor{cp/topics/expressions _CPPv2leN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2bb}@anchor{cp/topics/expressions lte-operator__gccjit rvalue gccjit rvalue}@anchor{2bc}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator<= (gccjit::rvalue a, gccjit::rvalue b)
@example
gccjit::rvalue cond = i <= n;
@@ -12913,8 +13372,8 @@ gccjit::rvalue cond = i <= n;
@end deffn
@geindex operator> (C++ function)
-@anchor{cp/topics/expressions _CPPv2gtN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{20d}@anchor{cp/topics/expressions gt-operator__gccjit rvalue gccjit rvalue}@anchor{20e}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator> (gccjit::rvalue a, gccjit::rvalue b)
+@anchor{cp/topics/expressions _CPPv4gtN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2bd}@anchor{cp/topics/expressions _CPPv3gtN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2be}@anchor{cp/topics/expressions _CPPv2gtN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2bf}@anchor{cp/topics/expressions gt-operator__gccjit rvalue gccjit rvalue}@anchor{2c0}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator> (gccjit::rvalue a, gccjit::rvalue b)
@example
gccjit::rvalue cond = (ch > limit);
@@ -12922,8 +13381,8 @@ gccjit::rvalue cond = (ch > limit);
@end deffn
@geindex operator>= (C++ function)
-@anchor{cp/topics/expressions _CPPv2geN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{20f}@anchor{cp/topics/expressions gte-operator__gccjit rvalue gccjit rvalue}@anchor{210}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} operator>= (gccjit::rvalue a, gccjit::rvalue b)
+@anchor{cp/topics/expressions _CPPv4geN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2c1}@anchor{cp/topics/expressions _CPPv3geN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2c2}@anchor{cp/topics/expressions _CPPv2geN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2c3}@anchor{cp/topics/expressions gte-operator__gccjit rvalue gccjit rvalue}@anchor{2c4}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} operator>= (gccjit::rvalue a, gccjit::rvalue b)
@example
gccjit::rvalue cond = (score >= ctxt.new_rvalue (t_int, 100));
@@ -12933,12 +13392,12 @@ gccjit::rvalue cond = (score >= ctxt.new_rvalue (t_int, 100));
@c TODO: beyond this point
@node Function calls<2>,Function pointers<3>,Comparisons<2>,Rvalues<2>
-@anchor{cp/topics/expressions function-calls}@anchor{211}
+@anchor{cp/topics/expressions function-calls}@anchor{2c5}
@subsubsection Function calls
@geindex gcc_jit_context_new_call (C++ function)
-@anchor{cp/topics/expressions _CPPv224gcc_jit_context_new_callP15gcc_jit_contextP16gcc_jit_locationP16gcc_jit_functioniPP14gcc_jit_rvalue}@anchor{212}@anchor{cp/topics/expressions gcc_jit_context_new_call__gcc_jit_contextP gcc_jit_locationP gcc_jit_functionP i gcc_jit_rvaluePP}@anchor{213}
+@anchor{cp/topics/expressions _CPPv424gcc_jit_context_new_callP15gcc_jit_contextP16gcc_jit_locationP16gcc_jit_functioniPP14gcc_jit_rvalue}@anchor{2c6}@anchor{cp/topics/expressions _CPPv324gcc_jit_context_new_callP15gcc_jit_contextP16gcc_jit_locationP16gcc_jit_functioniPP14gcc_jit_rvalue}@anchor{2c7}@anchor{cp/topics/expressions _CPPv224gcc_jit_context_new_callP15gcc_jit_contextP16gcc_jit_locationP16gcc_jit_functioniPP14gcc_jit_rvalue}@anchor{2c8}@anchor{cp/topics/expressions gcc_jit_context_new_call__gcc_jit_contextP gcc_jit_locationP gcc_jit_functionP i gcc_jit_rvaluePP}@anchor{2c9}
@deffn {C++ Function} gcc_jit_rvalue *gcc_jit_context_new_call (gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_function *func, int numargs, gcc_jit_rvalue **args)
Given a function and the given table of argument rvalues, construct a
@@ -12947,14 +13406,14 @@ call to the function, with the result as an rvalue.
@cartouche
@quotation Note
@code{gccjit::context::new_call()} merely builds a
-@ref{136,,gccjit;;rvalue} i.e. an expression that can be evaluated,
+@ref{146,,gccjit;;rvalue} i.e. an expression that can be evaluated,
perhaps as part of a more complicated expression.
The call @emph{won’t} happen unless you add a statement to a function
that evaluates the expression.
For example, if you want to call a function and discard the result
(or to call a function with @code{void} return type), use
-@ref{214,,gccjit;;block;;add_eval()}:
+@ref{2ca,,gccjit;;block;;add_eval()}:
@example
/* Add "(void)printf (arg0, arg1);". */
@@ -12965,26 +13424,26 @@ block.add_eval (ctxt.new_call (printf_func, arg0, arg1));
@end deffn
@node Function pointers<3>,Type-coercion<2>,Function calls<2>,Rvalues<2>
-@anchor{cp/topics/expressions function-pointers}@anchor{215}
+@anchor{cp/topics/expressions function-pointers}@anchor{2cb}
@subsubsection Function pointers
@geindex gccjit;;function;;get_address (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit8function11get_addressEN6gccjit8locationE}@anchor{216}@anchor{cp/topics/expressions gccjit function get_address__gccjit location}@anchor{217}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::function::get_address (gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit8function11get_addressEN6gccjit8locationE}@anchor{2cc}@anchor{cp/topics/expressions _CPPv3N6gccjit8function11get_addressEN6gccjit8locationE}@anchor{2cd}@anchor{cp/topics/expressions _CPPv2N6gccjit8function11get_addressEN6gccjit8locationE}@anchor{2ce}@anchor{cp/topics/expressions gccjit function get_address__gccjit location}@anchor{2cf}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{154,,function}::get_address (gccjit::location loc)
Get the address of a function as an rvalue, of function pointer
type.
@end deffn
@node Type-coercion<2>,,Function pointers<3>,Rvalues<2>
-@anchor{cp/topics/expressions type-coercion}@anchor{218}
+@anchor{cp/topics/expressions type-coercion}@anchor{2d0}
@subsubsection Type-coercion
@geindex gccjit;;context;;new_cast (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context8new_castEN6gccjit6rvalueEN6gccjit4typeEN6gccjit8locationE}@anchor{219}@anchor{cp/topics/expressions gccjit context new_cast__gccjit rvalue gccjit type gccjit location}@anchor{21a}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::context::new_cast (gccjit::rvalue rvalue, gccjit::type type, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context8new_castEN6gccjit6rvalueEN6gccjit4typeEN6gccjit8locationE}@anchor{2d1}@anchor{cp/topics/expressions _CPPv3N6gccjit7context8new_castEN6gccjit6rvalueEN6gccjit4typeEN6gccjit8locationE}@anchor{2d2}@anchor{cp/topics/expressions _CPPv2N6gccjit7context8new_castEN6gccjit6rvalueEN6gccjit4typeEN6gccjit8locationE}@anchor{2d3}@anchor{cp/topics/expressions gccjit context new_cast__gccjit rvalue gccjit type gccjit location}@anchor{2d4}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{13d,,context}::new_cast (gccjit::rvalue rvalue, gccjit::type type, gccjit::location loc)
Given an rvalue of T, construct another rvalue of another type.
@@ -13008,25 +13467,25 @@ P* <-> Q*, for pointer types P and Q
@end deffn
@node Lvalues<2>,Working with pointers structs and unions<2>,Rvalues<2>,Expressions<2>
-@anchor{cp/topics/expressions lvalues}@anchor{21b}
+@anchor{cp/topics/expressions lvalues}@anchor{2d5}
@subsubsection Lvalues
@geindex gccjit;;lvalue (C++ class)
-@anchor{cp/topics/expressions _CPPv2N6gccjit6lvalueE}@anchor{13f}@anchor{cp/topics/expressions gccjit lvalue}@anchor{21c}
+@anchor{cp/topics/expressions _CPPv4N6gccjit6lvalueE}@anchor{14f}@anchor{cp/topics/expressions _CPPv3N6gccjit6lvalueE}@anchor{2d6}@anchor{cp/topics/expressions _CPPv2N6gccjit6lvalueE}@anchor{2d7}@anchor{cp/topics/expressions gccjit lvalue}@anchor{2d8}
@deffn {C++ Class} gccjit::lvalue
@end deffn
An lvalue is something that can of the @emph{left}-hand side of an assignment:
a storage area (such as a variable). It is a subclass of
-@ref{136,,gccjit;;rvalue}, where the rvalue is computed by reading from the
+@ref{146,,gccjit;;rvalue}, where the rvalue is computed by reading from the
storage area.
It iss a thin wrapper around @ref{24,,gcc_jit_lvalue *} from the C API.
@geindex gccjit;;lvalue;;get_address (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit6lvalue11get_addressEN6gccjit8locationE}@anchor{21d}@anchor{cp/topics/expressions gccjit lvalue get_address__gccjit location}@anchor{21e}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::lvalue::get_address (gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit6lvalue11get_addressEN6gccjit8locationE}@anchor{2d9}@anchor{cp/topics/expressions _CPPv3N6gccjit6lvalue11get_addressEN6gccjit8locationE}@anchor{2da}@anchor{cp/topics/expressions _CPPv2N6gccjit6lvalue11get_addressEN6gccjit8locationE}@anchor{2db}@anchor{cp/topics/expressions gccjit lvalue get_address__gccjit location}@anchor{2dc}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{14f,,lvalue}::get_address (gccjit::location loc)
Take the address of an lvalue; analogous to:
@@ -13045,13 +13504,13 @@ Parameter “loc” is optional.
@end menu
@node Global variables<2>,,,Lvalues<2>
-@anchor{cp/topics/expressions global-variables}@anchor{21f}
+@anchor{cp/topics/expressions global-variables}@anchor{2dd}
@subsubsection Global variables
@geindex gccjit;;context;;new_global (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context10new_globalE19gcc_jit_global_kindN6gccjit4typeEPKcN6gccjit8locationE}@anchor{220}@anchor{cp/topics/expressions gccjit context new_global__gcc_jit_global_kind gccjit type cCP gccjit location}@anchor{221}
-@deffn {C++ Function} gccjit::@ref{13f,,lvalue} gccjit::context::new_global (enum gcc_jit_global_kind, gccjit::type type, const char *name, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context10new_globalE19gcc_jit_global_kindN6gccjit4typeEPKcN6gccjit8locationE}@anchor{2de}@anchor{cp/topics/expressions _CPPv3N6gccjit7context10new_globalE19gcc_jit_global_kindN6gccjit4typeEPKcN6gccjit8locationE}@anchor{2df}@anchor{cp/topics/expressions _CPPv2N6gccjit7context10new_globalE19gcc_jit_global_kindN6gccjit4typeEPKcN6gccjit8locationE}@anchor{2e0}@anchor{cp/topics/expressions gccjit context new_global__gcc_jit_global_kind gccjit type cCP gccjit location}@anchor{2e1}
+@deffn {C++ Function} gccjit::@ref{14f,,lvalue} gccjit::@ref{13d,,context}::new_global (enum gcc_jit_global_kind, gccjit::type type, const char *name, gccjit::location loc)
Add a new global variable of the given type and name to the context.
@@ -13060,13 +13519,13 @@ the C API; the “kind” parameter has the same meaning as there.
@end deffn
@node Working with pointers structs and unions<2>,,Lvalues<2>,Expressions<2>
-@anchor{cp/topics/expressions working-with-pointers-structs-and-unions}@anchor{222}
+@anchor{cp/topics/expressions working-with-pointers-structs-and-unions}@anchor{2e2}
@subsubsection Working with pointers, structs and unions
@geindex gccjit;;rvalue;;dereference (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalue11dereferenceEN6gccjit8locationE}@anchor{223}@anchor{cp/topics/expressions gccjit rvalue dereference__gccjit location}@anchor{224}
-@deffn {C++ Function} gccjit::@ref{13f,,lvalue} gccjit::rvalue::dereference (gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit6rvalue11dereferenceEN6gccjit8locationE}@anchor{2e3}@anchor{cp/topics/expressions _CPPv3N6gccjit6rvalue11dereferenceEN6gccjit8locationE}@anchor{2e4}@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalue11dereferenceEN6gccjit8locationE}@anchor{2e5}@anchor{cp/topics/expressions gccjit rvalue dereference__gccjit location}@anchor{2e6}
+@deffn {C++ Function} gccjit::@ref{14f,,lvalue} gccjit::@ref{146,,rvalue}::dereference (gccjit::location loc)
Given an rvalue of pointer type @code{T *}, dereferencing the pointer,
getting an lvalue of type @code{T}. Analogous to:
@@ -13084,8 +13543,8 @@ If you don’t need to specify the location, this can also be expressed using
an overloaded operator:
@geindex gccjit;;rvalue;;operator* (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit6rvaluemlEv}@anchor{225}@anchor{cp/topics/expressions gccjit rvalue mul-operator}@anchor{226}
-@deffn {C++ Function} gccjit::@ref{13f,,lvalue} gccjit::rvalue::operator* ()
+@anchor{cp/topics/expressions _CPPv4N6gccjit6rvaluemlEv}@anchor{2e7}@anchor{cp/topics/expressions _CPPv3N6gccjit6rvaluemlEv}@anchor{2e8}@anchor{cp/topics/expressions _CPPv2N6gccjit6rvaluemlEv}@anchor{2e9}@anchor{cp/topics/expressions gccjit rvalue mul-operator}@anchor{2ea}
+@deffn {C++ Function} gccjit::@ref{14f,,lvalue} gccjit::@ref{146,,rvalue}::operator* ()
@example
gccjit::lvalue content = *ptr;
@@ -13095,8 +13554,8 @@ gccjit::lvalue content = *ptr;
Field access is provided separately for both lvalues and rvalues:
@geindex gccjit;;lvalue;;access_field (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit6lvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{227}@anchor{cp/topics/expressions gccjit lvalue access_field__gccjit field gccjit location}@anchor{228}
-@deffn {C++ Function} gccjit::@ref{13f,,lvalue} gccjit::lvalue::access_field (gccjit::field field, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit6lvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{2eb}@anchor{cp/topics/expressions _CPPv3N6gccjit6lvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{2ec}@anchor{cp/topics/expressions _CPPv2N6gccjit6lvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{2ed}@anchor{cp/topics/expressions gccjit lvalue access_field__gccjit field gccjit location}@anchor{2ee}
+@deffn {C++ Function} gccjit::@ref{14f,,lvalue} gccjit::@ref{14f,,lvalue}::access_field (gccjit::field field, gccjit::location loc)
Given an lvalue of struct or union type, access the given field,
getting an lvalue of the field’s type. Analogous to:
@@ -13109,8 +13568,8 @@ in C.
@end deffn
@geindex gccjit;;rvalue;;access_field (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{229}@anchor{cp/topics/expressions gccjit rvalue access_field__gccjit field gccjit location}@anchor{22a}
-@deffn {C++ Function} gccjit::@ref{136,,rvalue} gccjit::rvalue::access_field (gccjit::field field, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit6rvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{2ef}@anchor{cp/topics/expressions _CPPv3N6gccjit6rvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{2f0}@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{2f1}@anchor{cp/topics/expressions gccjit rvalue access_field__gccjit field gccjit location}@anchor{2f2}
+@deffn {C++ Function} gccjit::@ref{146,,rvalue} gccjit::@ref{146,,rvalue}::access_field (gccjit::field field, gccjit::location loc)
Given an rvalue of struct or union type, access the given field
as an rvalue. Analogous to:
@@ -13123,8 +13582,8 @@ in C.
@end deffn
@geindex gccjit;;rvalue;;dereference_field (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalue17dereference_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{22b}@anchor{cp/topics/expressions gccjit rvalue dereference_field__gccjit field gccjit location}@anchor{22c}
-@deffn {C++ Function} gccjit::@ref{13f,,lvalue} gccjit::rvalue::dereference_field (gccjit::field field, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit6rvalue17dereference_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{2f3}@anchor{cp/topics/expressions _CPPv3N6gccjit6rvalue17dereference_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{2f4}@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalue17dereference_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{2f5}@anchor{cp/topics/expressions gccjit rvalue dereference_field__gccjit field gccjit location}@anchor{2f6}
+@deffn {C++ Function} gccjit::@ref{14f,,lvalue} gccjit::@ref{146,,rvalue}::dereference_field (gccjit::field field, gccjit::location loc)
Given an rvalue of pointer type @code{T *} where T is of struct or union
type, access the given field as an lvalue. Analogous to:
@@ -13137,8 +13596,8 @@ in C, itself equivalent to @code{(*EXPR).FIELD}.
@end deffn
@geindex gccjit;;context;;new_array_access (C++ function)
-@anchor{cp/topics/expressions _CPPv2N6gccjit7context16new_array_accessEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{22d}@anchor{cp/topics/expressions gccjit context new_array_access__gccjit rvalue gccjit rvalue gccjit location}@anchor{22e}
-@deffn {C++ Function} gccjit::@ref{13f,,lvalue} gccjit::context::new_array_access (gccjit::rvalue ptr, gccjit::rvalue index, gccjit::location loc)
+@anchor{cp/topics/expressions _CPPv4N6gccjit7context16new_array_accessEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2f7}@anchor{cp/topics/expressions _CPPv3N6gccjit7context16new_array_accessEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2f8}@anchor{cp/topics/expressions _CPPv2N6gccjit7context16new_array_accessEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2f9}@anchor{cp/topics/expressions gccjit context new_array_access__gccjit rvalue gccjit rvalue gccjit location}@anchor{2fa}
+@deffn {C++ Function} gccjit::@ref{14f,,lvalue} gccjit::@ref{13d,,context}::new_array_access (gccjit::rvalue ptr, gccjit::rvalue index, gccjit::location loc)
Given an rvalue of pointer type @code{T *}, get at the element @cite{T} at
the given index, using standard C array indexing rules i.e. each
@@ -13154,7 +13613,7 @@ in C (or, indeed, to @code{PTR + INDEX}).
Parameter “loc” is optional.
@end deffn
-For array accesses where you don’t need to specify a @ref{153,,gccjit;;location},
+For array accesses where you don’t need to specify a @ref{163,,gccjit;;location},
two overloaded operators are available:
@quotation
@@ -13190,7 +13649,7 @@ gccjit::lvalue element = array[0];
@c <http://www.gnu.org/licenses/>.
@node Creating and using functions<2>,Source Locations<2>,Expressions<2>,Topic Reference<2>
-@anchor{cp/topics/functions doc}@anchor{22f}@anchor{cp/topics/functions creating-and-using-functions}@anchor{230}
+@anchor{cp/topics/functions doc}@anchor{2fb}@anchor{cp/topics/functions creating-and-using-functions}@anchor{2fc}
@subsection Creating and using functions
@@ -13203,36 +13662,36 @@ gccjit::lvalue element = array[0];
@end menu
@node Params<2>,Functions<2>,,Creating and using functions<2>
-@anchor{cp/topics/functions params}@anchor{231}
+@anchor{cp/topics/functions params}@anchor{2fd}
@subsubsection Params
@geindex gccjit;;param (C++ class)
-@anchor{cp/topics/functions _CPPv2N6gccjit5paramE}@anchor{140}@anchor{cp/topics/functions gccjit param}@anchor{232}
+@anchor{cp/topics/functions _CPPv4N6gccjit5paramE}@anchor{150}@anchor{cp/topics/functions _CPPv3N6gccjit5paramE}@anchor{2fe}@anchor{cp/topics/functions _CPPv2N6gccjit5paramE}@anchor{2ff}@anchor{cp/topics/functions gccjit param}@anchor{300}
@deffn {C++ Class} gccjit::param
A @cite{gccjit::param} represents a parameter to a function.
@end deffn
@geindex gccjit;;context;;new_param (C++ function)
-@anchor{cp/topics/functions _CPPv2N6gccjit7context9new_paramEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{134}@anchor{cp/topics/functions gccjit context new_param__gccjit type cCP gccjit location}@anchor{233}
-@deffn {C++ Function} gccjit::@ref{140,,param} gccjit::context::new_param (gccjit::type type, const char *name, gccjit::location loc)
+@anchor{cp/topics/functions _CPPv4N6gccjit7context9new_paramEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{144}@anchor{cp/topics/functions _CPPv3N6gccjit7context9new_paramEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{301}@anchor{cp/topics/functions _CPPv2N6gccjit7context9new_paramEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{302}@anchor{cp/topics/functions gccjit context new_param__gccjit type cCP gccjit location}@anchor{303}
+@deffn {C++ Function} gccjit::@ref{150,,param} gccjit::@ref{13d,,context}::new_param (gccjit::type type, const char *name, gccjit::location loc)
In preparation for creating a function, create a new parameter of the
given type and name.
@end deffn
-@ref{140,,gccjit;;param} is a subclass of @ref{13f,,gccjit;;lvalue} (and thus
-of @ref{136,,gccjit;;rvalue} and @ref{132,,gccjit;;object}). It is a thin
+@ref{150,,gccjit;;param} is a subclass of @ref{14f,,gccjit;;lvalue} (and thus
+of @ref{146,,gccjit;;rvalue} and @ref{142,,gccjit;;object}). It is a thin
wrapper around the C API’s @ref{25,,gcc_jit_param *}.
@node Functions<2>,Blocks<2>,Params<2>,Creating and using functions<2>
-@anchor{cp/topics/functions functions}@anchor{234}
+@anchor{cp/topics/functions functions}@anchor{304}
@subsubsection Functions
@geindex gccjit;;function (C++ class)
-@anchor{cp/topics/functions _CPPv2N6gccjit8functionE}@anchor{144}@anchor{cp/topics/functions gccjit function}@anchor{235}
+@anchor{cp/topics/functions _CPPv4N6gccjit8functionE}@anchor{154}@anchor{cp/topics/functions _CPPv3N6gccjit8functionE}@anchor{305}@anchor{cp/topics/functions _CPPv2N6gccjit8functionE}@anchor{306}@anchor{cp/topics/functions gccjit function}@anchor{307}
@deffn {C++ Class} gccjit::function
A @cite{gccjit::function} represents a function - either one that we’re
@@ -13240,8 +13699,8 @@ creating ourselves, or one that we’re referencing.
@end deffn
@geindex gccjit;;context;;new_function (C++ function)
-@anchor{cp/topics/functions _CPPv2N6gccjit7context12new_functionE21gcc_jit_function_kindN6gccjit4typeEPKcRNSt6vectorI5paramEEiN6gccjit8locationE}@anchor{236}@anchor{cp/topics/functions gccjit context new_function__gcc_jit_function_kind gccjit type cCP std vector param R i gccjit location}@anchor{237}
-@deffn {C++ Function} gccjit::@ref{144,,function} gccjit::context::new_function (enum gcc_jit_function_kind, gccjit::type return_type, const char *name, std::vector<param> &params, int is_variadic, gccjit::location loc)
+@anchor{cp/topics/functions _CPPv4N6gccjit7context12new_functionE21gcc_jit_function_kindN6gccjit4typeEPKcRNSt6vectorI5paramEEiN6gccjit8locationE}@anchor{308}@anchor{cp/topics/functions _CPPv3N6gccjit7context12new_functionE21gcc_jit_function_kindN6gccjit4typeEPKcRNSt6vectorI5paramEEiN6gccjit8locationE}@anchor{309}@anchor{cp/topics/functions _CPPv2N6gccjit7context12new_functionE21gcc_jit_function_kindN6gccjit4typeEPKcRNSt6vectorI5paramEEiN6gccjit8locationE}@anchor{30a}@anchor{cp/topics/functions gccjit context new_function__gcc_jit_function_kind gccjit type cCP std vector param R i gccjit location}@anchor{30b}
+@deffn {C++ Function} gccjit::@ref{154,,function} gccjit::@ref{13d,,context}::new_function (enum gcc_jit_function_kind, gccjit::type return_type, const char *name, std::vector<param> &params, int is_variadic, gccjit::location loc)
Create a gcc_jit_function with the given name and parameters.
@@ -13251,49 +13710,49 @@ This is a wrapper around the C API’s @ref{11,,gcc_jit_context_new_function()}.
@end deffn
@geindex gccjit;;context;;get_builtin_function (C++ function)
-@anchor{cp/topics/functions _CPPv2N6gccjit7context20get_builtin_functionEPKc}@anchor{238}@anchor{cp/topics/functions gccjit context get_builtin_function__cCP}@anchor{239}
-@deffn {C++ Function} gccjit::@ref{144,,function} gccjit::context::get_builtin_function (const char *name)
+@anchor{cp/topics/functions _CPPv4N6gccjit7context20get_builtin_functionEPKc}@anchor{30c}@anchor{cp/topics/functions _CPPv3N6gccjit7context20get_builtin_functionEPKc}@anchor{30d}@anchor{cp/topics/functions _CPPv2N6gccjit7context20get_builtin_functionEPKc}@anchor{30e}@anchor{cp/topics/functions gccjit context get_builtin_function__cCP}@anchor{30f}
+@deffn {C++ Function} gccjit::@ref{154,,function} gccjit::@ref{13d,,context}::get_builtin_function (const char *name)
This is a wrapper around the C API’s
@ref{e1,,gcc_jit_context_get_builtin_function()}.
@end deffn
@geindex gccjit;;function;;get_param (C++ function)
-@anchor{cp/topics/functions _CPPv2NK6gccjit8function9get_paramEi}@anchor{23a}@anchor{cp/topics/functions gccjit function get_param__iC}@anchor{23b}
-@deffn {C++ Function} gccjit::@ref{140,,param} gccjit::function::get_param (int index) const
+@anchor{cp/topics/functions _CPPv4NK6gccjit8function9get_paramEi}@anchor{310}@anchor{cp/topics/functions _CPPv3NK6gccjit8function9get_paramEi}@anchor{311}@anchor{cp/topics/functions _CPPv2NK6gccjit8function9get_paramEi}@anchor{312}@anchor{cp/topics/functions gccjit function get_param__iC}@anchor{313}
+@deffn {C++ Function} gccjit::@ref{150,,param} gccjit::@ref{154,,function}::get_param (int index) const
Get the param of the given index (0-based).
@end deffn
@geindex gccjit;;function;;dump_to_dot (C++ function)
-@anchor{cp/topics/functions _CPPv2N6gccjit8function11dump_to_dotEPKc}@anchor{14c}@anchor{cp/topics/functions gccjit function dump_to_dot__cCP}@anchor{23c}
-@deffn {C++ Function} void gccjit::function::dump_to_dot (const char *path)
+@anchor{cp/topics/functions _CPPv4N6gccjit8function11dump_to_dotEPKc}@anchor{15c}@anchor{cp/topics/functions _CPPv3N6gccjit8function11dump_to_dotEPKc}@anchor{314}@anchor{cp/topics/functions _CPPv2N6gccjit8function11dump_to_dotEPKc}@anchor{315}@anchor{cp/topics/functions gccjit function dump_to_dot__cCP}@anchor{316}
+@deffn {C++ Function} void gccjit::@ref{154,,function}::dump_to_dot (const char *path)
Emit the function in graphviz format to the given path.
@end deffn
@geindex gccjit;;function;;new_local (C++ function)
-@anchor{cp/topics/functions _CPPv2N6gccjit8function9new_localEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{141}@anchor{cp/topics/functions gccjit function new_local__gccjit type cCP gccjit location}@anchor{23d}
-@deffn {C++ Function} gccjit::@ref{13f,,lvalue} gccjit::function::new_local (gccjit::type type, const char *name, gccjit::location loc)
+@anchor{cp/topics/functions _CPPv4N6gccjit8function9new_localEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{151}@anchor{cp/topics/functions _CPPv3N6gccjit8function9new_localEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{317}@anchor{cp/topics/functions _CPPv2N6gccjit8function9new_localEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{318}@anchor{cp/topics/functions gccjit function new_local__gccjit type cCP gccjit location}@anchor{319}
+@deffn {C++ Function} gccjit::@ref{14f,,lvalue} gccjit::@ref{154,,function}::new_local (gccjit::type type, const char *name, gccjit::location loc)
Create a new local variable within the function, of the given type and
name.
@end deffn
@node Blocks<2>,Statements<2>,Functions<2>,Creating and using functions<2>
-@anchor{cp/topics/functions blocks}@anchor{23e}
+@anchor{cp/topics/functions blocks}@anchor{31a}
@subsubsection Blocks
@geindex gccjit;;block (C++ class)
-@anchor{cp/topics/functions _CPPv2N6gccjit5blockE}@anchor{143}@anchor{cp/topics/functions gccjit block}@anchor{23f}
+@anchor{cp/topics/functions _CPPv4N6gccjit5blockE}@anchor{153}@anchor{cp/topics/functions _CPPv3N6gccjit5blockE}@anchor{31b}@anchor{cp/topics/functions _CPPv2N6gccjit5blockE}@anchor{31c}@anchor{cp/topics/functions gccjit block}@anchor{31d}
@deffn {C++ Class} gccjit::block
A @cite{gccjit::block} represents a basic block within a function i.e. a
sequence of statements with a single entry point and a single exit
point.
-@ref{143,,gccjit;;block} is a subclass of @ref{132,,gccjit;;object}.
+@ref{153,,gccjit;;block} is a subclass of @ref{142,,gccjit;;object}.
The first basic block that you create within a function will
be the entrypoint.
@@ -13307,8 +13766,8 @@ one function.
@end deffn
@geindex gccjit;;function;;new_block (C++ function)
-@anchor{cp/topics/functions _CPPv2N6gccjit8function9new_blockEPKc}@anchor{240}@anchor{cp/topics/functions gccjit function new_block__cCP}@anchor{241}
-@deffn {C++ Function} gccjit::@ref{143,,block} gccjit::function::new_block (const char *name)
+@anchor{cp/topics/functions _CPPv4N6gccjit8function9new_blockEPKc}@anchor{31e}@anchor{cp/topics/functions _CPPv3N6gccjit8function9new_blockEPKc}@anchor{31f}@anchor{cp/topics/functions _CPPv2N6gccjit8function9new_blockEPKc}@anchor{320}@anchor{cp/topics/functions gccjit function new_block__cCP}@anchor{321}
+@deffn {C++ Function} gccjit::@ref{153,,block} gccjit::@ref{154,,function}::new_block (const char *name)
Create a basic block of the given name. The name may be NULL, but
providing meaningful names is often helpful when debugging: it may
@@ -13317,13 +13776,13 @@ messages.
@end deffn
@node Statements<2>,,Blocks<2>,Creating and using functions<2>
-@anchor{cp/topics/functions statements}@anchor{242}
+@anchor{cp/topics/functions statements}@anchor{322}
@subsubsection Statements
@geindex gccjit;;block;;add_eval (C++ function)
-@anchor{cp/topics/functions _CPPv2N6gccjit5block8add_evalEN6gccjit6rvalueEN6gccjit8locationE}@anchor{214}@anchor{cp/topics/functions gccjit block add_eval__gccjit rvalue gccjit location}@anchor{243}
-@deffn {C++ Function} void gccjit::block::add_eval (gccjit::rvalue rvalue, gccjit::location loc)
+@anchor{cp/topics/functions _CPPv4N6gccjit5block8add_evalEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2ca}@anchor{cp/topics/functions _CPPv3N6gccjit5block8add_evalEN6gccjit6rvalueEN6gccjit8locationE}@anchor{323}@anchor{cp/topics/functions _CPPv2N6gccjit5block8add_evalEN6gccjit6rvalueEN6gccjit8locationE}@anchor{324}@anchor{cp/topics/functions gccjit block add_eval__gccjit rvalue gccjit location}@anchor{325}
+@deffn {C++ Function} void gccjit::@ref{153,,block}::add_eval (gccjit::rvalue rvalue, gccjit::location loc)
Add evaluation of an rvalue, discarding the result
(e.g. a function call that “returns” void).
@@ -13336,8 +13795,8 @@ This is equivalent to this C code:
@end deffn
@geindex gccjit;;block;;add_assignment (C++ function)
-@anchor{cp/topics/functions _CPPv2N6gccjit5block14add_assignmentEN6gccjit6lvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{145}@anchor{cp/topics/functions gccjit block add_assignment__gccjit lvalue gccjit rvalue gccjit location}@anchor{244}
-@deffn {C++ Function} void gccjit::block::add_assignment (gccjit::lvalue lvalue, gccjit::rvalue rvalue, gccjit::location loc)
+@anchor{cp/topics/functions _CPPv4N6gccjit5block14add_assignmentEN6gccjit6lvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{155}@anchor{cp/topics/functions _CPPv3N6gccjit5block14add_assignmentEN6gccjit6lvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{326}@anchor{cp/topics/functions _CPPv2N6gccjit5block14add_assignmentEN6gccjit6lvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{327}@anchor{cp/topics/functions gccjit block add_assignment__gccjit lvalue gccjit rvalue gccjit location}@anchor{328}
+@deffn {C++ Function} void gccjit::@ref{153,,block}::add_assignment (gccjit::lvalue lvalue, gccjit::rvalue rvalue, gccjit::location loc)
Add evaluation of an rvalue, assigning the result to the given
lvalue.
@@ -13350,8 +13809,8 @@ lvalue = rvalue;
@end deffn
@geindex gccjit;;block;;add_assignment_op (C++ function)
-@anchor{cp/topics/functions _CPPv2N6gccjit5block17add_assignment_opEN6gccjit6lvalueE17gcc_jit_binary_opN6gccjit6rvalueEN6gccjit8locationE}@anchor{149}@anchor{cp/topics/functions gccjit block add_assignment_op__gccjit lvalue gcc_jit_binary_op gccjit rvalue gccjit location}@anchor{245}
-@deffn {C++ Function} void gccjit::block::add_assignment_op (gccjit::lvalue lvalue, enum gcc_jit_binary_op, gccjit::rvalue rvalue, gccjit::location loc)
+@anchor{cp/topics/functions _CPPv4N6gccjit5block17add_assignment_opEN6gccjit6lvalueE17gcc_jit_binary_opN6gccjit6rvalueEN6gccjit8locationE}@anchor{159}@anchor{cp/topics/functions _CPPv3N6gccjit5block17add_assignment_opEN6gccjit6lvalueE17gcc_jit_binary_opN6gccjit6rvalueEN6gccjit8locationE}@anchor{329}@anchor{cp/topics/functions _CPPv2N6gccjit5block17add_assignment_opEN6gccjit6lvalueE17gcc_jit_binary_opN6gccjit6rvalueEN6gccjit8locationE}@anchor{32a}@anchor{cp/topics/functions gccjit block add_assignment_op__gccjit lvalue gcc_jit_binary_op gccjit rvalue gccjit location}@anchor{32b}
+@deffn {C++ Function} void gccjit::@ref{153,,block}::add_assignment_op (gccjit::lvalue lvalue, enum gcc_jit_binary_op, gccjit::rvalue rvalue, gccjit::location loc)
Add evaluation of an rvalue, using the result to modify an
lvalue.
@@ -13376,8 +13835,8 @@ loop_body.add_assignment_op (
@end deffn
@geindex gccjit;;block;;add_comment (C++ function)
-@anchor{cp/topics/functions _CPPv2N6gccjit5block11add_commentEPKcN6gccjit8locationE}@anchor{155}@anchor{cp/topics/functions gccjit block add_comment__cCP gccjit location}@anchor{246}
-@deffn {C++ Function} void gccjit::block::add_comment (const char *text, gccjit::location loc)
+@anchor{cp/topics/functions _CPPv4N6gccjit5block11add_commentEPKcN6gccjit8locationE}@anchor{165}@anchor{cp/topics/functions _CPPv3N6gccjit5block11add_commentEPKcN6gccjit8locationE}@anchor{32c}@anchor{cp/topics/functions _CPPv2N6gccjit5block11add_commentEPKcN6gccjit8locationE}@anchor{32d}@anchor{cp/topics/functions gccjit block add_comment__cCP gccjit location}@anchor{32e}
+@deffn {C++ Function} void gccjit::@ref{153,,block}::add_comment (const char *text, gccjit::location loc)
Add a no-op textual comment to the internal representation of the
code. It will be optimized away, but will be visible in the dumps
@@ -13390,8 +13849,8 @@ Parameter “loc” is optional.
@end deffn
@geindex gccjit;;block;;end_with_conditional (C++ function)
-@anchor{cp/topics/functions _CPPv2N6gccjit5block20end_with_conditionalEN6gccjit6rvalueEN6gccjit5blockEN6gccjit5blockEN6gccjit8locationE}@anchor{148}@anchor{cp/topics/functions gccjit block end_with_conditional__gccjit rvalue gccjit block gccjit block gccjit location}@anchor{247}
-@deffn {C++ Function} void gccjit::block::end_with_conditional (gccjit::rvalue boolval, gccjit::block on_true, gccjit::block on_false, gccjit::location loc)
+@anchor{cp/topics/functions _CPPv4N6gccjit5block20end_with_conditionalEN6gccjit6rvalueEN6gccjit5blockEN6gccjit5blockEN6gccjit8locationE}@anchor{158}@anchor{cp/topics/functions _CPPv3N6gccjit5block20end_with_conditionalEN6gccjit6rvalueEN6gccjit5blockEN6gccjit5blockEN6gccjit8locationE}@anchor{32f}@anchor{cp/topics/functions _CPPv2N6gccjit5block20end_with_conditionalEN6gccjit6rvalueEN6gccjit5blockEN6gccjit5blockEN6gccjit8locationE}@anchor{330}@anchor{cp/topics/functions gccjit block end_with_conditional__gccjit rvalue gccjit block gccjit block gccjit location}@anchor{331}
+@deffn {C++ Function} void gccjit::@ref{153,,block}::end_with_conditional (gccjit::rvalue boolval, gccjit::block on_true, gccjit::block on_false, gccjit::location loc)
Terminate a block by adding evaluation of an rvalue, branching on the
result to the appropriate successor block.
@@ -13409,8 +13868,8 @@ block, boolval, on_true, and on_false must be non-NULL.
@end deffn
@geindex gccjit;;block;;end_with_jump (C++ function)
-@anchor{cp/topics/functions _CPPv2N6gccjit5block13end_with_jumpEN6gccjit5blockEN6gccjit8locationE}@anchor{248}@anchor{cp/topics/functions gccjit block end_with_jump__gccjit block gccjit location}@anchor{249}
-@deffn {C++ Function} void gccjit::block::end_with_jump (gccjit::block target, gccjit::location loc)
+@anchor{cp/topics/functions _CPPv4N6gccjit5block13end_with_jumpEN6gccjit5blockEN6gccjit8locationE}@anchor{332}@anchor{cp/topics/functions _CPPv3N6gccjit5block13end_with_jumpEN6gccjit5blockEN6gccjit8locationE}@anchor{333}@anchor{cp/topics/functions _CPPv2N6gccjit5block13end_with_jumpEN6gccjit5blockEN6gccjit8locationE}@anchor{334}@anchor{cp/topics/functions gccjit block end_with_jump__gccjit block gccjit location}@anchor{335}
+@deffn {C++ Function} void gccjit::@ref{153,,block}::end_with_jump (gccjit::block target, gccjit::location loc)
Terminate a block by adding a jump to the given target block.
@@ -13422,8 +13881,8 @@ goto target;
@end deffn
@geindex gccjit;;block;;end_with_return (C++ function)
-@anchor{cp/topics/functions _CPPv2N6gccjit5block15end_with_returnEN6gccjit6rvalueEN6gccjit8locationE}@anchor{24a}@anchor{cp/topics/functions gccjit block end_with_return__gccjit rvalue gccjit location}@anchor{24b}
-@deffn {C++ Function} void gccjit::block::end_with_return (gccjit::rvalue rvalue, gccjit::location loc)
+@anchor{cp/topics/functions _CPPv4N6gccjit5block15end_with_returnEN6gccjit6rvalueEN6gccjit8locationE}@anchor{336}@anchor{cp/topics/functions _CPPv3N6gccjit5block15end_with_returnEN6gccjit6rvalueEN6gccjit8locationE}@anchor{337}@anchor{cp/topics/functions _CPPv2N6gccjit5block15end_with_returnEN6gccjit6rvalueEN6gccjit8locationE}@anchor{338}@anchor{cp/topics/functions gccjit block end_with_return__gccjit rvalue gccjit location}@anchor{339}
+@deffn {C++ Function} void gccjit::@ref{153,,block}::end_with_return (gccjit::rvalue rvalue, gccjit::location loc)
Terminate a block.
@@ -13452,8 +13911,8 @@ return;
@end deffn
@geindex gccjit;;block;;end_with_switch (C++ function)
-@anchor{cp/topics/functions _CPPv2N6gccjit5block15end_with_switchEN6gccjit6rvalueEN6gccjit5blockENSt6vectorIN6gccjit5case_EEEN6gccjit8locationE}@anchor{24c}@anchor{cp/topics/functions gccjit block end_with_switch__gccjit rvalue gccjit block std vector gccjit case_ gccjit location}@anchor{24d}
-@deffn {C++ Function} void gccjit::block::end_with_switch (gccjit::rvalue expr, gccjit::block default_block, std::vector<gccjit::case_> cases, gccjit::location loc)
+@anchor{cp/topics/functions _CPPv4N6gccjit5block15end_with_switchEN6gccjit6rvalueEN6gccjit5blockENSt6vectorIN6gccjit5case_EEEN6gccjit8locationE}@anchor{33a}@anchor{cp/topics/functions _CPPv3N6gccjit5block15end_with_switchEN6gccjit6rvalueEN6gccjit5blockENSt6vectorIN6gccjit5case_EEEN6gccjit8locationE}@anchor{33b}@anchor{cp/topics/functions _CPPv2N6gccjit5block15end_with_switchEN6gccjit6rvalueEN6gccjit5blockENSt6vectorIN6gccjit5case_EEEN6gccjit8locationE}@anchor{33c}@anchor{cp/topics/functions gccjit block end_with_switch__gccjit rvalue gccjit block std vector gccjit case_ gccjit location}@anchor{33d}
+@deffn {C++ Function} void gccjit::@ref{153,,block}::end_with_switch (gccjit::rvalue expr, gccjit::block default_block, std::vector<gccjit::case_> cases, gccjit::location loc)
Terminate a block by adding evalation of an rvalue, then performing
a multiway branch.
@@ -13493,10 +13952,10 @@ The API entrypoints relating to switch statements and cases:
@itemize *
@item
-@code{gccjit::block::end_with_switch()}
+@ref{33a,,gccjit;;block;;end_with_switch()}
@item
-@ref{24e,,gccjit;;context;;new_case()}
+@code{gccjit::context::new_case()}
@end itemize
@end quotation
@@ -13507,32 +13966,15 @@ using
#ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS
@end example
-@geindex gccjit;;block;;end_with_switch;;gccjit;;case_ (C++ class)
-@anchor{cp/topics/functions _CPPv2N6gccjit5block15end_with_switch6gccjit5case_E}@anchor{24f}@anchor{cp/topics/functions gccjit block end_with_switch gccjit case_}@anchor{250}
-@deffn {C++ Class} gccjit::case_
-@end deffn
-
A @cite{gccjit::case_} represents a case within a switch statement, and
-is created within a particular @code{gccjit::context} using
-@ref{24e,,gccjit;;context;;new_case()}. It is a subclass of
-@code{gccjit::object}.
+is created within a particular @ref{13d,,gccjit;;context} using
+@code{gccjit::context::new_case()}. It is a subclass of
+@ref{142,,gccjit;;object}.
Each case expresses a multivalued range of integer values. You
can express single-valued cases by passing in the same value for
both @cite{min_value} and @cite{max_value}.
-@geindex gccjit;;block;;end_with_switch;;gccjit;;context;;new_case (C++ function)
-@anchor{cp/topics/functions _CPPv2N6gccjit5block15end_with_switch6gccjit7context8new_caseEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit5blockE}@anchor{24e}@anchor{cp/topics/functions gccjit block end_with_switch gccjit context new_case__gccjit rvalue gccjit rvalue gccjit block}@anchor{251}
-@deffn {C++ Function} gccjit::@ref{24f,,case_} *gccjit::context::new_case (gccjit::rvalue min_value, gccjit::rvalue max_value, gccjit::block dest_block)
-
-Create a new gccjit::case for use in a switch statement.
-@cite{min_value} and @cite{max_value} must be constants of an integer type,
-which must match that of the expression of the switch statement.
-
-@cite{dest_block} must be within the same function as the switch
-statement.
-@end deffn
-
Here’s an example of creating a switch statement:
@quotation
@@ -13630,12 +14072,12 @@ create_code (gcc_jit_context *c_ctxt, void *user_data)
@c <http://www.gnu.org/licenses/>.
@node Source Locations<2>,Compiling a context<2>,Creating and using functions<2>,Topic Reference<2>
-@anchor{cp/topics/locations source-locations}@anchor{252}@anchor{cp/topics/locations doc}@anchor{253}
+@anchor{cp/topics/locations doc}@anchor{33e}@anchor{cp/topics/locations source-locations}@anchor{33f}
@subsection Source Locations
@geindex gccjit;;location (C++ class)
-@anchor{cp/topics/locations _CPPv2N6gccjit8locationE}@anchor{153}@anchor{cp/topics/locations gccjit location}@anchor{254}
+@anchor{cp/topics/locations _CPPv4N6gccjit8locationE}@anchor{163}@anchor{cp/topics/locations _CPPv3N6gccjit8locationE}@anchor{340}@anchor{cp/topics/locations _CPPv2N6gccjit8locationE}@anchor{341}@anchor{cp/topics/locations gccjit location}@anchor{342}
@deffn {C++ Class} gccjit::location
A @cite{gccjit::location} encapsulates a source code location, so that
@@ -13646,10 +14088,10 @@ single-step through your language.
@cite{gccjit::location} instances are optional: you can always omit them
from any C++ API entrypoint accepting one.
-You can construct them using @ref{159,,gccjit;;context;;new_location()}.
+You can construct them using @ref{169,,gccjit;;context;;new_location()}.
You need to enable @ref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the
-@ref{12d,,gccjit;;context} for these locations to actually be usable by
+@ref{13d,,gccjit;;context} for these locations to actually be usable by
the debugger:
@example
@@ -13658,8 +14100,8 @@ ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1);
@end deffn
@geindex gccjit;;context;;new_location (C++ function)
-@anchor{cp/topics/locations _CPPv2N6gccjit7context12new_locationEPKcii}@anchor{159}@anchor{cp/topics/locations gccjit context new_location__cCP i i}@anchor{255}
-@deffn {C++ Function} gccjit::@ref{153,,location} gccjit::context::new_location (const char *filename, int line, int column)
+@anchor{cp/topics/locations _CPPv4N6gccjit7context12new_locationEPKcii}@anchor{169}@anchor{cp/topics/locations _CPPv3N6gccjit7context12new_locationEPKcii}@anchor{343}@anchor{cp/topics/locations _CPPv2N6gccjit7context12new_locationEPKcii}@anchor{344}@anchor{cp/topics/locations gccjit context new_location__cCP i i}@anchor{345}
+@deffn {C++ Function} gccjit::@ref{163,,location} gccjit::@ref{13d,,context}::new_location (const char *filename, int line, int column)
Create a @cite{gccjit::location} instance representing the given source
location.
@@ -13671,13 +14113,13 @@ location.
@end menu
@node Faking it<2>,,,Source Locations<2>
-@anchor{cp/topics/locations faking-it}@anchor{256}
+@anchor{cp/topics/locations faking-it}@anchor{346}
@subsubsection Faking it
If you don’t have source code for your internal representation, but need
to debug, you can generate a C-like representation of the functions in
-your context using @ref{16e,,gccjit;;context;;dump_to_file()}:
+your context using @ref{188,,gccjit;;context;;dump_to_file()}:
@example
ctxt.dump_to_file ("/tmp/something.c",
@@ -13706,14 +14148,14 @@ file, giving you @emph{something} you can step through in the debugger.
@c along with this program. If not, see
@c <http://www.gnu.org/licenses/>.
-@node Compiling a context<2>,,Source Locations<2>,Topic Reference<2>
-@anchor{cp/topics/compilation compiling-a-context}@anchor{257}@anchor{cp/topics/compilation doc}@anchor{258}
+@node Compiling a context<2>,Using Assembly Language with libgccjit++,Source Locations<2>,Topic Reference<2>
+@anchor{cp/topics/compilation doc}@anchor{347}@anchor{cp/topics/compilation compiling-a-context}@anchor{348}
@subsection Compiling a context
-Once populated, a @ref{12d,,gccjit;;context} can be compiled to
-machine code, either in-memory via @ref{137,,gccjit;;context;;compile()} or
-to disk via @ref{259,,gccjit;;context;;compile_to_file()}.
+Once populated, a @ref{13d,,gccjit;;context} can be compiled to
+machine code, either in-memory via @ref{147,,gccjit;;context;;compile()} or
+to disk via @ref{349,,gccjit;;context;;compile_to_file()}.
You can compile a context multiple times (using either form of
compilation), although any errors that occur on the context will
@@ -13726,13 +14168,13 @@ prevent any future compilation of that context.
@end menu
@node In-memory compilation<2>,Ahead-of-time compilation<2>,,Compiling a context<2>
-@anchor{cp/topics/compilation in-memory-compilation}@anchor{25a}
+@anchor{cp/topics/compilation in-memory-compilation}@anchor{34a}
@subsubsection In-memory compilation
@geindex gccjit;;context;;compile (C++ function)
-@anchor{cp/topics/compilation _CPPv2N6gccjit7context7compileEv}@anchor{137}@anchor{cp/topics/compilation gccjit context compile}@anchor{25b}
-@deffn {C++ Function} gcc_jit_result *gccjit::context::compile ()
+@anchor{cp/topics/compilation _CPPv4N6gccjit7context7compileEv}@anchor{147}@anchor{cp/topics/compilation _CPPv3N6gccjit7context7compileEv}@anchor{34b}@anchor{cp/topics/compilation _CPPv2N6gccjit7context7compileEv}@anchor{34c}@anchor{cp/topics/compilation gccjit context compile}@anchor{34d}
+@deffn {C++ Function} gcc_jit_result *gccjit::@ref{13d,,context}::compile ()
This calls into GCC and builds the code, returning a
@cite{gcc_jit_result *}.
@@ -13742,25 +14184,418 @@ This is a thin wrapper around the
@end deffn
@node Ahead-of-time compilation<2>,,In-memory compilation<2>,Compiling a context<2>
-@anchor{cp/topics/compilation ahead-of-time-compilation}@anchor{25c}
+@anchor{cp/topics/compilation ahead-of-time-compilation}@anchor{34e}
@subsubsection Ahead-of-time compilation
Although libgccjit is primarily aimed at just-in-time compilation, it
can also be used for implementing more traditional ahead-of-time
-compilers, via the @ref{259,,gccjit;;context;;compile_to_file()} method.
+compilers, via the @ref{349,,gccjit;;context;;compile_to_file()} method.
@geindex gccjit;;context;;compile_to_file (C++ function)
-@anchor{cp/topics/compilation _CPPv2N6gccjit7context15compile_to_fileE19gcc_jit_output_kindPKc}@anchor{259}@anchor{cp/topics/compilation gccjit context compile_to_file__gcc_jit_output_kind cCP}@anchor{25d}
-@deffn {C++ Function} void gccjit::context::compile_to_file (enum gcc_jit_output_kind, const char *output_path)
+@anchor{cp/topics/compilation _CPPv4N6gccjit7context15compile_to_fileE19gcc_jit_output_kindPKc}@anchor{349}@anchor{cp/topics/compilation _CPPv3N6gccjit7context15compile_to_fileE19gcc_jit_output_kindPKc}@anchor{34f}@anchor{cp/topics/compilation _CPPv2N6gccjit7context15compile_to_fileE19gcc_jit_output_kindPKc}@anchor{350}@anchor{cp/topics/compilation gccjit context compile_to_file__gcc_jit_output_kind cCP}@anchor{351}
+@deffn {C++ Function} void gccjit::@ref{13d,,context}::compile_to_file (enum gcc_jit_output_kind, const char *output_path)
-Compile the @ref{12d,,gccjit;;context} to a file of the given
+Compile the @ref{13d,,gccjit;;context} to a file of the given
kind.
This is a thin wrapper around the
@ref{4a,,gcc_jit_context_compile_to_file()} API entrypoint.
@end deffn
+@c Copyright (C) 2020 Free Software Foundation, Inc.
+@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
+@c
+@c This is free software: you can redistribute it and/or modify it
+@c under the terms of the GNU General Public License as published by
+@c the Free Software Foundation, either version 3 of the License, or
+@c (at your option) any later version.
+@c
+@c This program is distributed in the hope that it will be useful, but
+@c WITHOUT ANY WARRANTY; without even the implied warranty of
+@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+@c General Public License for more details.
+@c
+@c You should have received a copy of the GNU General Public License
+@c along with this program. If not, see
+@c <http://www.gnu.org/licenses/>.
+
+@node Using Assembly Language with libgccjit++,,Compiling a context<2>,Topic Reference<2>
+@anchor{cp/topics/asm doc}@anchor{352}@anchor{cp/topics/asm using-assembly-language-with-libgccjit}@anchor{353}
+@subsection Using Assembly Language with libgccjit++
+
+
+libgccjit has some support for directly embedding assembler instructions.
+This is based on GCC’s support for inline @code{asm} in C code, and the
+following assumes a familiarity with that functionality. See
+How to Use Inline Assembly Language in C Code@footnote{https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html}
+in GCC’s documentation, the “Extended Asm” section in particular.
+
+These entrypoints were added in @ref{122,,LIBGCCJIT_ABI_15}; you can test
+for their presence using
+
+@quotation
+
+@example
+#ifdef LIBGCCJIT_HAVE_ASM_STATEMENTS
+@end example
+@end quotation
+
+@menu
+* Adding assembler instructions within a function: Adding assembler instructions within a function<2>.
+* Adding top-level assembler statements: Adding top-level assembler statements<2>.
+
+@end menu
+
+@node Adding assembler instructions within a function<2>,Adding top-level assembler statements<2>,,Using Assembly Language with libgccjit++
+@anchor{cp/topics/asm adding-assembler-instructions-within-a-function}@anchor{354}
+@subsubsection Adding assembler instructions within a function
+
+
+@geindex gccjit;;extended_asm (C++ class)
+@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asmE}@anchor{355}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asmE}@anchor{356}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asmE}@anchor{357}@anchor{cp/topics/asm gccjit extended_asm}@anchor{358}
+@deffn {C++ Class} gccjit::extended_asm
+
+A @cite{gccjit::extended_asm} represents an extended @code{asm} statement: a
+series of low-level instructions inside a function that convert inputs
+to outputs.
+
+@ref{355,,gccjit;;extended_asm} is a subclass of @ref{142,,gccjit;;object}.
+It is a thin wrapper around the C API’s @ref{f1,,gcc_jit_extended_asm *}.
+
+To avoid having an API entrypoint with a very large number of
+parameters, an extended @code{asm} statement is made in stages:
+an initial call to create the @ref{355,,gccjit;;extended_asm},
+followed by calls to add operands and set other properties of the
+statement.
+
+There are two API entrypoints for creating a @ref{355,,gccjit;;extended_asm}:
+
+
+@itemize *
+
+@item
+@ref{359,,gccjit;;block;;add_extended_asm()} for an @code{asm} statement with
+no control flow, and
+
+@item
+@ref{35a,,gccjit;;block;;end_with_extended_asm_goto()} for an @code{asm goto}.
+@end itemize
+
+For example, to create the equivalent of:
+
+@example
+ asm ("mov %1, %0\n\t"
+ "add $1, %0"
+ : "=r" (dst)
+ : "r" (src));
+@end example
+
+the following API calls could be used:
+
+@example
+ block.add_extended_asm ("mov %1, %0\n\t"
+ "add $1, %0")
+ .add_output_operand ("=r", dst)
+ .add_input_operand ("r", src);
+@end example
+
+@cartouche
+@quotation Warning
+When considering the numbering of operands within an
+extended @code{asm} statement (e.g. the @code{%0} and @code{%1}
+above), the equivalent to the C syntax is followed i.e. all
+output operands, then all input operands, regardless of
+what order the calls to
+@ref{35b,,gccjit;;extended_asm;;add_output_operand()} and
+@ref{35c,,gccjit;;extended_asm;;add_input_operand()} were made in.
+@end quotation
+@end cartouche
+
+As in the C syntax, operands can be given symbolic names to avoid having
+to number them. For example, to create the equivalent of:
+
+@example
+ asm ("bsfl %[aMask], %[aIndex]"
+ : [aIndex] "=r" (Index)
+ : [aMask] "r" (Mask)
+ : "cc");
+@end example
+
+the following API calls could be used:
+
+@example
+ block.add_extended_asm ("bsfl %[aMask], %[aIndex]")
+ .add_output_operand ("aIndex", "=r", index)
+ .add_input_operand ("aMask", "r", mask)
+ .add_clobber ("cc");
+@end example
+@end deffn
+
+@geindex gccjit;;block;;add_extended_asm (C++ function)
+@anchor{cp/topics/asm _CPPv4N6gccjit5block16add_extended_asmERKNSt6stringEN6gccjit8locationE}@anchor{359}@anchor{cp/topics/asm _CPPv3N6gccjit5block16add_extended_asmERKNSt6stringEN6gccjit8locationE}@anchor{35d}@anchor{cp/topics/asm _CPPv2N6gccjit5block16add_extended_asmERKNSt6stringEN6gccjit8locationE}@anchor{35e}@anchor{cp/topics/asm gccjit block add_extended_asm__ssCR gccjit location}@anchor{35f}
+@deffn {C++ Function} @ref{355,,extended_asm} gccjit::@ref{153,,block}::add_extended_asm (const std::string &asm_template, gccjit::location loc = location())
+
+Create a @ref{355,,gccjit;;extended_asm} for an extended @code{asm} statement
+with no control flow (i.e. without the @code{goto} qualifier).
+
+The parameter @code{asm_template} corresponds to the @cite{AssemblerTemplate}
+within C’s extended @code{asm} syntax. It must be non-NULL. The call takes
+a copy of the underlying string, so it is valid to pass in a pointer to
+an on-stack buffer.
+@end deffn
+
+@geindex gccjit;;block;;end_with_extended_asm_goto (C++ function)
+@anchor{cp/topics/asm _CPPv4N6gccjit5block26end_with_extended_asm_gotoERKNSt6stringENSt6vectorI5blockEEP5block8location}@anchor{35a}@anchor{cp/topics/asm _CPPv3N6gccjit5block26end_with_extended_asm_gotoERKNSt6stringENSt6vectorI5blockEEP5block8location}@anchor{360}@anchor{cp/topics/asm _CPPv2N6gccjit5block26end_with_extended_asm_gotoERKNSt6stringENSt6vectorI5blockEEP5block8location}@anchor{361}@anchor{cp/topics/asm gccjit block end_with_extended_asm_goto__ssCR std vector block blockP location}@anchor{362}
+@deffn {C++ Function} @ref{355,,extended_asm} gccjit::@ref{153,,block}::end_with_extended_asm_goto (const std::string &asm_template, std::vector<block> goto_blocks, block *fallthrough_block, location loc = location())
+
+Create a @ref{355,,gccjit;;extended_asm} for an extended @code{asm} statement
+that may perform jumps, and use it to terminate the given block.
+This is equivalent to the @code{goto} qualifier in C’s extended @code{asm}
+syntax.
+
+For example, to create the equivalent of:
+
+@example
+ asm goto ("btl %1, %0\n\t"
+ "jc %l[carry]"
+ : // No outputs
+ : "r" (p1), "r" (p2)
+ : "cc"
+ : carry);
+@end example
+
+the following API calls could be used:
+
+@example
+ const char *asm_template =
+ (use_name
+ ? /* Label referred to by name: "%l[carry]". */
+ ("btl %1, %0\n\t"
+ "jc %l[carry]")
+ : /* Label referred to numerically: "%l2". */
+ ("btl %1, %0\n\t"
+ "jc %l2"));
+
+ std::vector<gccjit::block> goto_blocks (@{b_carry@});
+ gccjit::extended_asm ext_asm
+ = (b_start.end_with_extended_asm_goto (asm_template,
+ goto_blocks,
+ &b_fallthru)
+ .add_input_operand ("r", p1)
+ .add_input_operand ("r", p2)
+ .add_clobber ("cc"));
+@end example
+
+here referencing a @code{gcc_jit_block} named “carry”.
+
+@code{num_goto_blocks} corresponds to the @code{GotoLabels} parameter within C’s
+extended @code{asm} syntax. The block names can be referenced within the
+assembler template.
+
+@code{fallthrough_block} can be NULL. If non-NULL, it specifies the block
+to fall through to after the statement.
+
+@cartouche
+@quotation Note
+This is needed since each @ref{153,,gccjit;;block} must have a
+single exit point, as a basic block: you can’t jump from the
+middle of a block. A “goto” is implicitly added after the
+asm to handle the fallthrough case, which is equivalent to what
+would have happened in the C case.
+@end quotation
+@end cartouche
+@end deffn
+
+@geindex gccjit;;extended_asm;;set_volatile_flag (C++ function)
+@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm17set_volatile_flagEb}@anchor{363}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm17set_volatile_flagEb}@anchor{364}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm17set_volatile_flagEb}@anchor{365}@anchor{cp/topics/asm gccjit extended_asm set_volatile_flag__b}@anchor{366}
+@deffn {C++ Function} gccjit::@ref{355,,extended_asm} &gccjit::@ref{355,,extended_asm}::set_volatile_flag (bool flag)
+
+Set whether the @ref{355,,gccjit;;extended_asm} has side-effects, equivalent to the
+volatile@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile}
+qualifier in C’s extended asm syntax.
+
+For example, to create the equivalent of:
+
+@example
+asm volatile ("rdtsc\n\t" // Returns the time in EDX:EAX.
+ "shl $32, %%rdx\n\t" // Shift the upper bits left.
+ "or %%rdx, %0" // 'Or' in the lower bits.
+ : "=a" (msr)
+ :
+ : "rdx");
+@end example
+
+the following API calls could be used:
+
+@example
+ gccjit::extended_asm ext_asm
+ = block.add_extended_asm
+ ("rdtsc\n\t" /* Returns the time in EDX:EAX. */
+ "shl $32, %%rdx\n\t" /* Shift the upper bits left. */
+ "or %%rdx, %0") /* 'Or' in the lower bits. */
+ .set_volatile_flag (true)
+ .add_output_operand ("=a", msr)
+ .add_clobber ("rdx");
+@end example
+
+where the @ref{355,,gccjit;;extended_asm} is flagged as volatile.
+@end deffn
+
+@geindex gccjit;;extended_asm;;set_inline_flag (C++ function)
+@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm15set_inline_flagEb}@anchor{367}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm15set_inline_flagEb}@anchor{368}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm15set_inline_flagEb}@anchor{369}@anchor{cp/topics/asm gccjit extended_asm set_inline_flag__b}@anchor{36a}
+@deffn {C++ Function} gccjit::@ref{355,,extended_asm} &gccjit::@ref{355,,extended_asm}::set_inline_flag (bool flag)
+
+Set the equivalent of the
+inline@footnote{https://gcc.gnu.org/onlinedocs/gcc/Size-of-an-asm.html#Size-of-an-asm}
+qualifier in C’s extended @code{asm} syntax.
+@end deffn
+
+@geindex gccjit;;extended_asm;;add_output_operand (C++ function)
+@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm18add_output_operandERKNSt6stringERKNSt6stringEN6gccjit6lvalueE}@anchor{35b}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm18add_output_operandERKNSt6stringERKNSt6stringEN6gccjit6lvalueE}@anchor{36b}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm18add_output_operandERKNSt6stringERKNSt6stringEN6gccjit6lvalueE}@anchor{36c}@anchor{cp/topics/asm gccjit extended_asm add_output_operand__ssCR ssCR gccjit lvalue}@anchor{36d}
+@deffn {C++ Function} gccjit::@ref{355,,extended_asm} &gccjit::@ref{355,,extended_asm}::add_output_operand (const std::string &asm_symbolic_name, const std::string &constraint, gccjit::lvalue dest)
+
+Add an output operand to the extended @code{asm} statement. See the
+Output Operands@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#OutputOperands}
+section of the documentation of the C syntax.
+
+@code{asm_symbolic_name} corresponds to the @code{asmSymbolicName} component of
+C’s extended @code{asm} syntax, and specifies the symbolic name for the operand.
+See the overload below for an alternative that does not supply a symbolic
+name.
+
+@code{constraint} corresponds to the @code{constraint} component of C’s extended
+@code{asm} syntax.
+
+@code{dest} corresponds to the @code{cvariablename} component of C’s extended
+@code{asm} syntax.
+
+@example
+// Example with a symbolic name ("aIndex"), the equivalent of:
+// : [aIndex] "=r" (index)
+ext_asm.add_output_operand ("aIndex", "=r", index);
+@end example
+
+This function can’t be called on an @code{asm goto} as such instructions can’t
+have outputs; see the
+Goto Labels@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#GotoLabels}
+section of GCC’s “Extended Asm” documentation.
+@end deffn
+
+@geindex gccjit;;extended_asm;;add_output_operand (C++ function)
+@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm18add_output_operandERKNSt6stringEN6gccjit6lvalueE}@anchor{36e}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm18add_output_operandERKNSt6stringEN6gccjit6lvalueE}@anchor{36f}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm18add_output_operandERKNSt6stringEN6gccjit6lvalueE}@anchor{370}@anchor{cp/topics/asm gccjit extended_asm add_output_operand__ssCR gccjit lvalue}@anchor{371}
+@deffn {C++ Function} gccjit::@ref{355,,extended_asm} &gccjit::@ref{355,,extended_asm}::add_output_operand (const std::string &constraint, gccjit::lvalue dest)
+
+As above, but don’t supply a symbolic name for the operand.
+
+@example
+// Example without a symbolic name, the equivalent of:
+// : "=r" (dst)
+ext_asm.add_output_operand ("=r", dst);
+@end example
+@end deffn
+
+@geindex gccjit;;extended_asm;;add_input_operand (C++ function)
+@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm17add_input_operandERKNSt6stringERKNSt6stringEN6gccjit6rvalueE}@anchor{35c}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm17add_input_operandERKNSt6stringERKNSt6stringEN6gccjit6rvalueE}@anchor{372}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm17add_input_operandERKNSt6stringERKNSt6stringEN6gccjit6rvalueE}@anchor{373}@anchor{cp/topics/asm gccjit extended_asm add_input_operand__ssCR ssCR gccjit rvalue}@anchor{374}
+@deffn {C++ Function} gccjit::@ref{355,,extended_asm} &gccjit::@ref{355,,extended_asm}::add_input_operand (const std::string &asm_symbolic_name, const std::string &constraint, gccjit::rvalue src)
+
+Add an input operand to the extended @code{asm} statement. See the
+Input Operands@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#InputOperands}
+section of the documentation of the C syntax.
+
+@code{asm_symbolic_name} corresponds to the @code{asmSymbolicName} component
+of C’s extended @code{asm} syntax. See the overload below for an alternative
+that does not supply a symbolic name.
+
+@code{constraint} corresponds to the @code{constraint} component of C’s extended
+@code{asm} syntax.
+
+@code{src} corresponds to the @code{cexpression} component of C’s extended
+@code{asm} syntax.
+
+@example
+// Example with a symbolic name ("aMask"), the equivalent of:
+// : [aMask] "r" (Mask)
+ext_asm.add_input_operand ("aMask", "r", mask);
+@end example
+@end deffn
+
+@geindex gccjit;;extended_asm;;add_input_operand (C++ function)
+@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm17add_input_operandERKNSt6stringEN6gccjit6rvalueE}@anchor{375}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm17add_input_operandERKNSt6stringEN6gccjit6rvalueE}@anchor{376}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm17add_input_operandERKNSt6stringEN6gccjit6rvalueE}@anchor{377}@anchor{cp/topics/asm gccjit extended_asm add_input_operand__ssCR gccjit rvalue}@anchor{378}
+@deffn {C++ Function} gccjit::@ref{355,,extended_asm} &gccjit::@ref{355,,extended_asm}::add_input_operand (const std::string &constraint, gccjit::rvalue src)
+
+As above, but don’t supply a symbolic name for the operand.
+
+@example
+// Example without a symbolic name, the equivalent of:
+// : "r" (src)
+ext_asm.add_input_operand ("r", src);
+@end example
+@end deffn
+
+@geindex gccjit;;extended_asm;;add_clobber (C++ function)
+@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm11add_clobberERKNSt6stringE}@anchor{379}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm11add_clobberERKNSt6stringE}@anchor{37a}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm11add_clobberERKNSt6stringE}@anchor{37b}@anchor{cp/topics/asm gccjit extended_asm add_clobber__ssCR}@anchor{37c}
+@deffn {C++ Function} gccjit::@ref{355,,extended_asm} &gccjit::@ref{355,,extended_asm}::add_clobber (const std::string &victim)
+
+Add @cite{victim} to the list of registers clobbered by the extended @code{asm}
+statement. See the
+Clobbers and Scratch Registers@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Clobbers-and-Scratch-Registers#}
+section of the documentation of the C syntax.
+
+Statements with multiple clobbers will require multiple calls, one per
+clobber.
+
+For example:
+
+@example
+ext_asm.add_clobber ("r0").add_clobber ("cc").add_clobber ("memory");
+@end example
+@end deffn
+
+@node Adding top-level assembler statements<2>,,Adding assembler instructions within a function<2>,Using Assembly Language with libgccjit++
+@anchor{cp/topics/asm adding-top-level-assembler-statements}@anchor{37d}
+@subsubsection Adding top-level assembler statements
+
+
+In addition to creating extended @code{asm} instructions within a function,
+there is support for creating “top-level” assembler statements, outside
+of any function.
+
+@geindex gccjit;;context;;add_top_level_asm (C++ function)
+@anchor{cp/topics/asm _CPPv4N6gccjit7context17add_top_level_asmEPKcN6gccjit8locationE}@anchor{37e}@anchor{cp/topics/asm _CPPv3N6gccjit7context17add_top_level_asmEPKcN6gccjit8locationE}@anchor{37f}@anchor{cp/topics/asm _CPPv2N6gccjit7context17add_top_level_asmEPKcN6gccjit8locationE}@anchor{380}@anchor{cp/topics/asm gccjit context add_top_level_asm__cCP gccjit location}@anchor{381}
+@deffn {C++ Function} void gccjit::@ref{13d,,context}::add_top_level_asm (const char *asm_stmts, gccjit::location loc = location())
+
+Create a set of top-level asm statements, analogous to those created
+by GCC’s “basic” @code{asm} syntax in C at file scope.
+
+For example, to create the equivalent of:
+
+@example
+ asm ("\t.pushsection .text\n"
+ "\t.globl add_asm\n"
+ "\t.type add_asm, @@function\n"
+ "add_asm:\n"
+ "\tmovq %rdi, %rax\n"
+ "\tadd %rsi, %rax\n"
+ "\tret\n"
+ "\t.popsection\n");
+@end example
+
+the following API calls could be used:
+
+@example
+ ctxt.add_top_level_asm ("\t.pushsection .text\n"
+ "\t.globl add_asm\n"
+ "\t.type add_asm, @@function\n"
+ "add_asm:\n"
+ "\tmovq %rdi, %rax\n"
+ "\tadd %rsi, %rax\n"
+ "\tret\n"
+ "\t# some asm here\n"
+ "\t.popsection\n");
+@end example
+@end deffn
+
@c Copyright (C) 2014-2020 Free Software Foundation, Inc.
@c Originally contributed by David Malcolm <dmalcolm@redhat.com>
@c
@@ -13779,7 +14614,7 @@ This is a thin wrapper around the
@c <http://www.gnu.org/licenses/>.
@node Internals,Indices and tables,C++ bindings for libgccjit,Top
-@anchor{internals/index internals}@anchor{25e}@anchor{internals/index doc}@anchor{25f}
+@anchor{internals/index doc}@anchor{382}@anchor{internals/index internals}@anchor{383}
@chapter Internals
@@ -13795,7 +14630,7 @@ This is a thin wrapper around the
@end menu
@node Working on the JIT library,Running the test suite,,Internals
-@anchor{internals/index working-on-the-jit-library}@anchor{260}
+@anchor{internals/index working-on-the-jit-library}@anchor{384}
@section Working on the JIT library
@@ -13828,7 +14663,7 @@ gcc/libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV),
Here’s what those configuration options mean:
@geindex command line option; --enable-host-shared
-@anchor{internals/index cmdoption-enable-host-shared}@anchor{261}
+@anchor{internals/index cmdoption-enable-host-shared}@anchor{385}
@deffn {Option} @w{-}@w{-}enable@w{-}host@w{-}shared
Configuring with this option means that the compiler is built as
@@ -13837,7 +14672,7 @@ but it necessary for a shared library.
@end deffn
@geindex command line option; --enable-languages=jit@comma{}c++
-@anchor{internals/index cmdoption-enable-languages}@anchor{262}
+@anchor{internals/index cmdoption-enable-languages}@anchor{386}
@deffn {Option} @w{-}@w{-}enable@w{-}languages=jit,c++
This specifies which frontends to build. The JIT library looks like
@@ -13854,7 +14689,7 @@ c++: error trying to exec 'cc1plus': execvp: No such file or directory
@end deffn
@geindex command line option; --disable-bootstrap
-@anchor{internals/index cmdoption-disable-bootstrap}@anchor{263}
+@anchor{internals/index cmdoption-disable-bootstrap}@anchor{387}
@deffn {Option} @w{-}@w{-}disable@w{-}bootstrap
For hacking on the “jit” subdirectory, performing a full
@@ -13864,7 +14699,7 @@ the compiler can still bootstrap itself.
@end deffn
@geindex command line option; --enable-checking=release
-@anchor{internals/index cmdoption-enable-checking}@anchor{264}
+@anchor{internals/index cmdoption-enable-checking}@anchor{388}
@deffn {Option} @w{-}@w{-}enable@w{-}checking=release
The compile can perform extensive self-checking as it runs, useful when
@@ -13875,7 +14710,7 @@ disable this self-checking.
@end deffn
@node Running the test suite,Environment variables,Working on the JIT library,Internals
-@anchor{internals/index running-the-test-suite}@anchor{265}
+@anchor{internals/index running-the-test-suite}@anchor{389}
@section Running the test suite
@@ -13933,7 +14768,7 @@ and once a test has been compiled, you can debug it directly:
@end menu
@node Running under valgrind,,,Running the test suite
-@anchor{internals/index running-under-valgrind}@anchor{266}
+@anchor{internals/index running-under-valgrind}@anchor{38a}
@subsection Running under valgrind
@@ -13982,7 +14817,7 @@ When running under valgrind, it’s best to have configured gcc with
various known false positives.
@node Environment variables,Packaging notes,Running the test suite,Internals
-@anchor{internals/index environment-variables}@anchor{267}
+@anchor{internals/index environment-variables}@anchor{38b}
@section Environment variables
@@ -13990,7 +14825,7 @@ When running client code against a locally-built libgccjit, three
environment variables need to be set up:
@geindex environment variable; LD_LIBRARY_PATH
-@anchor{internals/index envvar-LD_LIBRARY_PATH}@anchor{268}
+@anchor{internals/index envvar-LD_LIBRARY_PATH}@anchor{38c}
@deffn {Environment Variable} LD_LIBRARY_PATH
@quotation
@@ -14010,7 +14845,7 @@ libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux),
@end deffn
@geindex environment variable; PATH
-@anchor{internals/index envvar-PATH}@anchor{269}
+@anchor{internals/index envvar-PATH}@anchor{38d}
@deffn {Environment Variable} PATH
The library uses a driver executable for converting from .s assembler
@@ -14029,7 +14864,7 @@ of development.
@end deffn
@geindex environment variable; LIBRARY_PATH
-@anchor{internals/index envvar-LIBRARY_PATH}@anchor{26a}
+@anchor{internals/index envvar-LIBRARY_PATH}@anchor{38e}
@deffn {Environment Variable} LIBRARY_PATH
The driver executable invokes the linker, and the latter needs to locate
@@ -14061,11 +14896,11 @@ hello world
@end example
@node Packaging notes,Overview of code structure,Environment variables,Internals
-@anchor{internals/index packaging-notes}@anchor{26b}
+@anchor{internals/index packaging-notes}@anchor{38f}
@section Packaging notes
-The configure-time option @ref{261,,--enable-host-shared} is needed when
+The configure-time option @ref{385,,--enable-host-shared} is needed when
building the jit in order to get position-independent code. This will
slow down the regular compiler by a few percent. Hence when packaging gcc
with libgccjit, please configure and build twice:
@@ -14076,10 +14911,10 @@ with libgccjit, please configure and build twice:
@itemize *
@item
-once without @ref{261,,--enable-host-shared} for most languages, and
+once without @ref{385,,--enable-host-shared} for most languages, and
@item
-once with @ref{261,,--enable-host-shared} for the jit
+once with @ref{385,,--enable-host-shared} for the jit
@end itemize
@end quotation
@@ -14121,7 +14956,7 @@ popd
@end example
@node Overview of code structure,Design notes,Packaging notes,Internals
-@anchor{internals/index overview-of-code-structure}@anchor{26c}
+@anchor{internals/index overview-of-code-structure}@anchor{390}
@section Overview of code structure
@@ -14168,7 +15003,9 @@ The gcc::jit::recording classes (within @code{jit-recording.c} and
class base_call;
class function_pointer;
class statement;
+ class extended_asm;
class case_;
+ class top_level_asm;
@end example
@end quotation
@@ -14588,7 +15425,7 @@ JIT: gcc::jit::logger::~logger()
@end example
@node Design notes,Submitting patches,Overview of code structure,Internals
-@anchor{internals/index design-notes}@anchor{26d}
+@anchor{internals/index design-notes}@anchor{391}
@section Design notes
@@ -14601,7 +15438,7 @@ close as possible to the error; failing that, a good place is within
@code{recording::context::validate ()} in jit-recording.c.
@node Submitting patches,,Design notes,Internals
-@anchor{internals/index submitting-patches}@anchor{26e}
+@anchor{internals/index submitting-patches}@anchor{392}
@section Submitting patches
@@ -14735,7 +15572,7 @@ large and inconsequential (e.g. anchor renumbering), rather like generated
committing to svn.
@node Indices and tables,Index,Internals,Top
-@anchor{index indices-and-tables}@anchor{26f}
+@anchor{index indices-and-tables}@anchor{393}
@unnumbered Indices and tables
diff --git a/gcc/jit/docs/cp/topics/asm.rst b/gcc/jit/docs/cp/topics/asm.rst
new file mode 100644
index 0000000..69e2d1e
--- /dev/null
+++ b/gcc/jit/docs/cp/topics/asm.rst
@@ -0,0 +1,308 @@
+.. Copyright (C) 2020 Free Software Foundation, Inc.
+ Originally contributed by David Malcolm <dmalcolm@redhat.com>
+
+ This 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 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, see
+ <http://www.gnu.org/licenses/>.
+
+.. default-domain:: cpp
+
+Using Assembly Language with libgccjit++
+========================================
+
+libgccjit has some support for directly embedding assembler instructions.
+This is based on GCC's support for inline ``asm`` in C code, and the
+following assumes a familiarity with that functionality. See
+`How to Use Inline Assembly Language in C Code <https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html>`_
+in GCC's documentation, the "Extended Asm" section in particular.
+
+These entrypoints were added in :ref:`LIBGCCJIT_ABI_15`; you can test
+for their presence using
+
+ .. code-block:: c
+
+ #ifdef LIBGCCJIT_HAVE_ASM_STATEMENTS
+
+Adding assembler instructions within a function
+***********************************************
+
+.. class:: gccjit::extended_asm
+
+ A `gccjit::extended_asm` represents an extended ``asm`` statement: a
+ series of low-level instructions inside a function that convert inputs
+ to outputs.
+
+ :class:`gccjit::extended_asm` is a subclass of :class:`gccjit::object`.
+ It is a thin wrapper around the C API's :c:type:`gcc_jit_extended_asm *`.
+
+ To avoid having an API entrypoint with a very large number of
+ parameters, an extended ``asm`` statement is made in stages:
+ an initial call to create the :type:`gccjit::extended_asm`,
+ followed by calls to add operands and set other properties of the
+ statement.
+
+ There are two API entrypoints for creating a :type:`gccjit::extended_asm`:
+
+ * :func:`gccjit::block::add_extended_asm` for an ``asm`` statement with
+ no control flow, and
+
+ * :func:`gccjit::block::end_with_extended_asm_goto` for an ``asm goto``.
+
+ For example, to create the equivalent of:
+
+ .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
+ :start-after: // Quote from here in docs/cp/topics/asm.rst: example 1: C
+ :end-before: // Quote up to here in docs/cp/topics/asm.rst: example 1: C
+ :language: c
+
+ the following API calls could be used:
+
+ .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
+ :start-after: /* Quote from here in docs/cp/topics/asm.rst: example 1: jit. */
+ :end-before: /* Quote up to here in docs/cp/topics/asm.rst: example 1: jit. */
+ :language: c
+
+ .. warning:: When considering the numbering of operands within an
+ extended ``asm`` statement (e.g. the ``%0`` and ``%1``
+ above), the equivalent to the C syntax is followed i.e. all
+ output operands, then all input operands, regardless of
+ what order the calls to
+ :func:`gccjit::extended_asm::add_output_operand` and
+ :func:`gccjit::extended_asm::add_input_operand` were made in.
+
+ As in the C syntax, operands can be given symbolic names to avoid having
+ to number them. For example, to create the equivalent of:
+
+ .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
+ :start-after: // Quote from here in docs/cp/topics/asm.rst: example 2: C
+ :end-before: // Quote up to here in docs/cp/topics/asm.rst: example 2: C
+ :language: c
+
+ the following API calls could be used:
+
+ .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
+ :start-after: /* Quote from here in docs/cp/topics/asm.rst: example 2: jit. */
+ :end-before: /* Quote up to here in docs/cp/topics/asm.rst: example 2: jit. */
+ :language: c
+
+.. function:: extended_asm \
+ gccjit::block::add_extended_asm (const std::string &asm_template,\
+ gccjit::location loc = location ())
+
+ Create a :type:`gccjit::extended_asm` for an extended ``asm`` statement
+ with no control flow (i.e. without the ``goto`` qualifier).
+
+ The parameter ``asm_template`` corresponds to the `AssemblerTemplate`
+ within C's extended ``asm`` syntax. It must be non-NULL. The call takes
+ a copy of the underlying string, so it is valid to pass in a pointer to
+ an on-stack buffer.
+
+.. function:: extended_asm\
+ gccjit::block::end_with_extended_asm_goto (const std::string &asm_template,\
+ std::vector<block> goto_blocks,\
+ block *fallthrough_block,\
+ location loc = location ())
+
+ Create a :type:`gccjit::extended_asm` for an extended ``asm`` statement
+ that may perform jumps, and use it to terminate the given block.
+ This is equivalent to the ``goto`` qualifier in C's extended ``asm``
+ syntax.
+
+ For example, to create the equivalent of:
+
+ .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
+ :start-after: // Quote from here in docs/cp/topics/asm.rst: example 3b: C
+ :end-before: // Quote up to here in docs/cp/topics/asm.rst: example 3b: C
+ :language: c
+
+ the following API calls could be used:
+
+ .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
+ :start-after: /* Quote from here in docs/cp/topics/asm.rst: example 3: jit. */
+ :end-before: /* Quote up to here in docs/cp/topics/asm.rst: example 3: jit. */
+ :language: c
+
+ here referencing a :type:`gcc_jit_block` named "carry".
+
+ ``num_goto_blocks`` corresponds to the ``GotoLabels`` parameter within C's
+ extended ``asm`` syntax. The block names can be referenced within the
+ assembler template.
+
+ ``fallthrough_block`` can be NULL. If non-NULL, it specifies the block
+ to fall through to after the statement.
+
+ .. note:: This is needed since each :type:`gccjit::block` must have a
+ single exit point, as a basic block: you can't jump from the
+ middle of a block. A "goto" is implicitly added after the
+ asm to handle the fallthrough case, which is equivalent to what
+ would have happened in the C case.
+
+.. function:: gccjit::extended_asm &\
+ gccjit::extended_asm::set_volatile_flag (bool flag)
+
+ Set whether the :type:`gccjit::extended_asm` has side-effects, equivalent to the
+ `volatile <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile>`_
+ qualifier in C's extended asm syntax.
+
+ For example, to create the equivalent of:
+
+ .. code-block:: c
+
+ asm volatile ("rdtsc\n\t" // Returns the time in EDX:EAX.
+ "shl $32, %%rdx\n\t" // Shift the upper bits left.
+ "or %%rdx, %0" // 'Or' in the lower bits.
+ : "=a" (msr)
+ :
+ : "rdx");
+
+ the following API calls could be used:
+
+ .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
+ :start-after: /* Quote from here in docs/cp/topics/asm.rst: example 4: jit. */
+ :end-before: /* Quote up to here in docs/cp/topics/asm.rst: example 4: jit. */
+ :language: c
+
+ where the :type:`gccjit::extended_asm` is flagged as volatile.
+
+.. function:: gccjit::extended_asm &\
+ gccjit::extended_asm::set_inline_flag (bool flag)
+
+ Set the equivalent of the
+ `inline <https://gcc.gnu.org/onlinedocs/gcc/Size-of-an-asm.html#Size-of-an-asm>`_
+ qualifier in C's extended ``asm`` syntax.
+
+.. function:: gccjit::extended_asm&\
+ gccjit::extended_asm::add_output_operand (const std::string &asm_symbolic_name,\
+ const std::string &constraint,\
+ gccjit::lvalue dest)
+
+ Add an output operand to the extended ``asm`` statement. See the
+ `Output Operands <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#OutputOperands>`_
+ section of the documentation of the C syntax.
+
+ ``asm_symbolic_name`` corresponds to the ``asmSymbolicName`` component of
+ C's extended ``asm`` syntax, and specifies the symbolic name for the operand.
+ See the overload below for an alternative that does not supply a symbolic
+ name.
+
+ ``constraint`` corresponds to the ``constraint`` component of C's extended
+ ``asm`` syntax.
+
+ ``dest`` corresponds to the ``cvariablename`` component of C's extended
+ ``asm`` syntax.
+
+ .. code-block:: c++
+
+ // Example with a symbolic name ("aIndex"), the equivalent of:
+ // : [aIndex] "=r" (index)
+ ext_asm.add_output_operand ("aIndex", "=r", index);
+
+ This function can't be called on an ``asm goto`` as such instructions can't
+ have outputs; see the
+ `Goto Labels <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#GotoLabels>`_
+ section of GCC's "Extended Asm" documentation.
+
+.. function:: gccjit::extended_asm&\
+ gccjit::extended_asm::add_output_operand (const std::string &constraint,\
+ gccjit::lvalue dest)
+
+ As above, but don't supply a symbolic name for the operand.
+
+ .. code-block:: c++
+
+ // Example without a symbolic name, the equivalent of:
+ // : "=r" (dst)
+ ext_asm.add_output_operand ("=r", dst);
+
+.. function:: gccjit::extended_asm&\
+ gccjit::extended_asm::add_input_operand (const std::string &asm_symbolic_name, \
+ const std::string &constraint, \
+ gccjit::rvalue src)
+
+ Add an input operand to the extended ``asm`` statement. See the
+ `Input Operands <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#InputOperands>`_
+ section of the documentation of the C syntax.
+
+ ``asm_symbolic_name`` corresponds to the ``asmSymbolicName`` component
+ of C's extended ``asm`` syntax. See the overload below for an alternative
+ that does not supply a symbolic name.
+
+ ``constraint`` corresponds to the ``constraint`` component of C's extended
+ ``asm`` syntax.
+
+ ``src`` corresponds to the ``cexpression`` component of C's extended
+ ``asm`` syntax.
+
+ .. code-block:: c++
+
+ // Example with a symbolic name ("aMask"), the equivalent of:
+ // : [aMask] "r" (Mask)
+ ext_asm.add_input_operand ("aMask", "r", mask);
+
+.. function:: gccjit::extended_asm&\
+ gccjit::extended_asm::add_input_operand (const std::string &constraint,\
+ gccjit::rvalue src)
+
+ As above, but don't supply a symbolic name for the operand.
+
+ .. code-block:: c++
+
+ // Example without a symbolic name, the equivalent of:
+ // : "r" (src)
+ ext_asm.add_input_operand ("r", src);
+
+.. function:: gccjit::extended_asm&\
+ gccjit::extended_asm::add_clobber (const std::string &victim)
+
+ Add `victim` to the list of registers clobbered by the extended ``asm``
+ statement. See the
+ `Clobbers and Scratch Registers <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Clobbers-and-Scratch-Registers#>`_
+ section of the documentation of the C syntax.
+
+ Statements with multiple clobbers will require multiple calls, one per
+ clobber.
+
+ For example:
+
+ .. code-block:: c++
+
+ ext_asm.add_clobber ("r0").add_clobber ("cc").add_clobber ("memory");
+
+
+Adding top-level assembler statements
+*************************************
+
+In addition to creating extended ``asm`` instructions within a function,
+there is support for creating "top-level" assembler statements, outside
+of any function.
+
+.. function:: void\
+ gccjit::context::add_top_level_asm (const char *asm_stmts,\
+ gccjit::location loc = location ())
+
+ Create a set of top-level asm statements, analogous to those created
+ by GCC's "basic" ``asm`` syntax in C at file scope.
+
+ For example, to create the equivalent of:
+
+ .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
+ :start-after: // Quote from here in docs/cp/topics/asm.rst: example 5: C
+ :end-before: // Quote up to here in docs/cp/topics/asm.rst: example 5: C
+ :language: c
+
+ the following API calls could be used:
+
+ .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
+ :start-after: /* Quote from here in docs/cp/topics/asm.rst: example 5: jit. */
+ :end-before: /* Quote up to here in docs/cp/topics/asm.rst: example 5: jit. */
+ :language: c
diff --git a/gcc/jit/docs/cp/topics/index.rst b/gcc/jit/docs/cp/topics/index.rst
index 187a20d..721e70c 100644
--- a/gcc/jit/docs/cp/topics/index.rst
+++ b/gcc/jit/docs/cp/topics/index.rst
@@ -28,3 +28,4 @@ Topic Reference
functions.rst
locations.rst
compilation.rst
+ asm.rst
diff --git a/gcc/jit/docs/topics/asm.rst b/gcc/jit/docs/topics/asm.rst
new file mode 100644
index 0000000..b91514d
--- /dev/null
+++ b/gcc/jit/docs/topics/asm.rst
@@ -0,0 +1,311 @@
+.. Copyright (C) 2020 Free Software Foundation, Inc.
+ Originally contributed by David Malcolm <dmalcolm@redhat.com>
+
+ This 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 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, see
+ <http://www.gnu.org/licenses/>.
+
+.. default-domain:: c
+
+Using Assembly Language with libgccjit
+======================================
+
+libgccjit has some support for directly embedding assembler instructions.
+This is based on GCC's support for inline ``asm`` in C code, and the
+following assumes a familiarity with that functionality. See
+`How to Use Inline Assembly Language in C Code <https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html>`_
+in GCC's documentation, the "Extended Asm" section in particular.
+
+These entrypoints were added in :ref:`LIBGCCJIT_ABI_15`; you can test
+for their presence using
+
+ .. code-block:: c
+
+ #ifdef LIBGCCJIT_HAVE_ASM_STATEMENTS
+
+Adding assembler instructions within a function
+***********************************************
+
+.. type:: gcc_jit_extended_asm
+
+ A `gcc_jit_extended_asm` represents an extended ``asm`` statement: a
+ series of low-level instructions inside a function that convert inputs
+ to outputs.
+
+ To avoid having an API entrypoint with a very large number of
+ parameters, an extended ``asm`` statement is made in stages:
+ an initial call to create the :type:`gcc_jit_extended_asm`,
+ followed by calls to add operands and set other properties of the
+ statement.
+
+ There are two API entrypoints for creating a :type:`gcc_jit_extended_asm`:
+
+ * :func:`gcc_jit_block_add_extended_asm` for an ``asm`` statement with
+ no control flow, and
+
+ * :func:`gcc_jit_block_end_with_extended_asm_goto` for an ``asm goto``.
+
+ For example, to create the equivalent of:
+
+ .. literalinclude:: ../../../testsuite/jit.dg/test-asm.c
+ :start-after: // Quote from here in docs/topics/asm.rst: example 1: C
+ :end-before: // Quote up to here in docs/topics/asm.rst: example 1: C
+ :language: c
+
+ the following API calls could be used:
+
+ .. literalinclude:: ../../../testsuite/jit.dg/test-asm.c
+ :start-after: /* Quote from here in docs/topics/asm.rst: example 1: jit. */
+ :end-before: /* Quote up to here in docs/topics/asm.rst: example 1: jit. */
+ :language: c
+
+ .. warning:: When considering the numbering of operands within an
+ extended ``asm`` statement (e.g. the ``%0`` and ``%1``
+ above), the equivalent to the C syntax is followed i.e. all
+ output operands, then all input operands, regardless of
+ what order the calls to
+ :func:`gcc_jit_extended_asm_add_output_operand` and
+ :func:`gcc_jit_extended_asm_add_input_operand` were made in.
+
+ As in the C syntax, operands can be given symbolic names to avoid having
+ to number them. For example, to create the equivalent of:
+
+ .. literalinclude:: ../../../testsuite/jit.dg/test-asm.c
+ :start-after: // Quote from here in docs/topics/asm.rst: example 2: C
+ :end-before: // Quote up to here in docs/topics/asm.rst: example 2: C
+ :language: c
+
+ the following API calls could be used:
+
+ .. literalinclude:: ../../../testsuite/jit.dg/test-asm.c
+ :start-after: /* Quote from here in docs/topics/asm.rst: example 2: jit. */
+ :end-before: /* Quote up to here in docs/topics/asm.rst: example 2: jit. */
+ :language: c
+
+.. function:: gcc_jit_extended_asm *\
+ gcc_jit_block_add_extended_asm (gcc_jit_block *block,\
+ gcc_jit_location *loc,\
+ const char *asm_template)
+
+ Create a :type:`gcc_jit_extended_asm` for an extended ``asm`` statement
+ with no control flow (i.e. without the ``goto`` qualifier).
+
+ The parameter ``asm_template`` corresponds to the `AssemblerTemplate`
+ within C's extended ``asm`` syntax. It must be non-NULL. The call takes
+ a copy of the underlying string, so it is valid to pass in a pointer to
+ an on-stack buffer.
+
+.. function:: gcc_jit_extended_asm *\
+ gcc_jit_block_end_with_extended_asm_goto (gcc_jit_block *block,\
+ gcc_jit_location *loc,\
+ const char *asm_template,\
+ int num_goto_blocks,\
+ gcc_jit_block **goto_blocks,\
+ gcc_jit_block *fallthrough_block)
+
+ Create a :type:`gcc_jit_extended_asm` for an extended ``asm`` statement
+ that may perform jumps, and use it to terminate the given block.
+ This is equivalent to the ``goto`` qualifier in C's extended ``asm``
+ syntax.
+
+ For example, to create the equivalent of:
+
+ .. literalinclude:: ../../../testsuite/jit.dg/test-asm.c
+ :start-after: // Quote from here in docs/topics/asm.rst: example 3b: C
+ :end-before: // Quote up to here in docs/topics/asm.rst: example 3b: C
+ :language: c
+
+ the following API calls could be used:
+
+ .. literalinclude:: ../../../testsuite/jit.dg/test-asm.c
+ :start-after: /* Quote from here in docs/topics/asm.rst: example 3: jit. */
+ :end-before: /* Quote up to here in docs/topics/asm.rst: example 3: jit. */
+ :language: c
+
+ here referencing a :type:`gcc_jit_block` named "carry".
+
+ ``num_goto_blocks`` must be >= 0.
+
+ ``goto_blocks`` must be non-NULL. This corresponds to the ``GotoLabels``
+ parameter within C's extended ``asm`` syntax. The block names can be
+ referenced within the assembler template.
+
+ ``fallthrough_block`` can be NULL. If non-NULL, it specifies the block
+ to fall through to after the statement.
+
+ .. note:: This is needed since each :type:`gcc_jit_block` must have a
+ single exit point, as a basic block: you can't jump from the
+ middle of a block. A "goto" is implicitly added after the
+ asm to handle the fallthrough case, which is equivalent to what
+ would have happened in the C case.
+
+.. function:: void\
+ gcc_jit_extended_asm_set_volatile_flag (gcc_jit_extended_asm *ext_asm,\
+ int flag)
+
+ Set whether the :type:`gcc_jit_extended_asm` has side-effects, equivalent to the
+ `volatile <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile>`_
+ qualifier in C's extended asm syntax.
+
+ For example, to create the equivalent of:
+
+ .. code-block:: c
+
+ asm volatile ("rdtsc\n\t" // Returns the time in EDX:EAX.
+ "shl $32, %%rdx\n\t" // Shift the upper bits left.
+ "or %%rdx, %0" // 'Or' in the lower bits.
+ : "=a" (msr)
+ :
+ : "rdx");
+
+ the following API calls could be used:
+
+ .. literalinclude:: ../../../testsuite/jit.dg/test-asm.c
+ :start-after: /* Quote from here in docs/topics/asm.rst: example 4: jit. */
+ :end-before: /* Quote up to here in docs/topics/asm.rst: example 4: jit. */
+ :language: c
+
+ where the :type:`gcc_jit_extended_asm` is flagged as volatile.
+
+.. function:: void\
+ gcc_jit_extended_asm_set_inline_flag (gcc_jit_extended_asm *ext_asm,\
+ int flag)
+
+ Set the equivalent of the
+ `inline <https://gcc.gnu.org/onlinedocs/gcc/Size-of-an-asm.html#Size-of-an-asm>`_
+ qualifier in C's extended ``asm`` syntax.
+
+.. function:: void\
+ gcc_jit_extended_asm_add_output_operand (gcc_jit_extended_asm *ext_asm,\
+ const char *asm_symbolic_name,\
+ const char *constraint,\
+ gcc_jit_lvalue *dest)
+
+ Add an output operand to the extended ``asm`` statement. See the
+ `Output Operands <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#OutputOperands>`_
+ section of the documentation of the C syntax.
+
+ ``asm_symbolic_name`` corresponds to the ``asmSymbolicName`` component of C's
+ extended ``asm`` syntax. It can be NULL. If non-NULL it specifies the
+ symbolic name for the operand.
+
+ ``constraint`` corresponds to the ``constraint`` component of C's extended
+ ``asm`` syntax. It must be non-NULL.
+
+ ``dest`` corresponds to the ``cvariablename`` component of C's extended
+ ``asm`` syntax. It must be non-NULL.
+
+ .. code-block:: c
+
+ // Example with a NULL symbolic name, the equivalent of:
+ // : "=r" (dst)
+ gcc_jit_extended_asm_add_output_operand (ext_asm, NULL, "=r", dst);
+
+ // Example with a symbolic name ("aIndex"), the equivalent of:
+ // : [aIndex] "=r" (index)
+ gcc_jit_extended_asm_add_output_operand (ext_asm, "aIndex", "=r", index);
+
+ This function can't be called on an ``asm goto`` as such instructions can't
+ have outputs; see the
+ `Goto Labels <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#GotoLabels>`_
+ section of GCC's "Extended Asm" documentation.
+
+.. function:: void\
+ gcc_jit_extended_asm_add_input_operand (gcc_jit_extended_asm *ext_asm,\
+ const char *asm_symbolic_name,\
+ const char *constraint,\
+ gcc_jit_rvalue *src)
+
+ Add an input operand to the extended ``asm`` statement. See the
+ `Input Operands <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#InputOperands>`_
+ section of the documentation of the C syntax.
+
+ ``asm_symbolic_name`` corresponds to the ``asmSymbolicName`` component of C's
+ extended ``asm`` syntax. It can be NULL. If non-NULL it specifies the
+ symbolic name for the operand.
+
+ ``constraint`` corresponds to the ``constraint`` component of C's extended
+ ``asm`` syntax. It must be non-NULL.
+
+ ``src`` corresponds to the ``cexpression`` component of C's extended
+ ``asm`` syntax. It must be non-NULL.
+
+ .. code-block:: c
+
+ // Example with a NULL symbolic name, the equivalent of:
+ // : "r" (src)
+ gcc_jit_extended_asm_add_input_operand (ext_asm, NULL, "r",
+ gcc_jit_lvalue_as_rvalue (src));
+
+ // Example with a symbolic name ("aMask"), the equivalent of:
+ // : [aMask] "r" (Mask)
+ gcc_jit_extended_asm_add_input_operand (ext_asm, "aMask", "r",
+ gcc_jit_lvalue_as_rvalue (mask));
+
+.. function:: void\
+ gcc_jit_extended_asm_add_clobber (gcc_jit_extended_asm *ext_asm,\
+ const char *victim)
+
+ Add `victim` to the list of registers clobbered by the extended ``asm``
+ statement. It must be non-NULL. See the
+ `Clobbers and Scratch Registers <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Clobbers-and-Scratch-Registers#>`_
+ section of the documentation of the C syntax.
+
+ Statements with multiple clobbers will require multiple calls, one per
+ clobber.
+
+ For example:
+
+ .. code-block:: c
+
+ gcc_jit_extended_asm_add_clobber (ext_asm, "r0");
+ gcc_jit_extended_asm_add_clobber (ext_asm, "cc");
+ gcc_jit_extended_asm_add_clobber (ext_asm, "memory");
+
+A :type:`gcc_jit_extended_asm` is a :type:`gcc_jit_object` "owned" by
+the block's context. The following upcast is available:
+
+.. function:: gcc_jit_object *\
+ gcc_jit_extended_asm_as_object (gcc_jit_extended_asm *ext_asm)
+
+ Upcast from extended ``asm`` to object.
+
+
+Adding top-level assembler statements
+*************************************
+
+In addition to creating extended ``asm`` instructions within a function,
+there is support for creating "top-level" assembler statements, outside
+of any function.
+
+.. function:: void \
+ gcc_jit_context_add_top_level_asm (gcc_jit_context *ctxt,\
+ gcc_jit_location *loc,\
+ const char *asm_stmts)
+
+ Create a set of top-level asm statements, analogous to those created
+ by GCC's "basic" ``asm`` syntax in C at file scope.
+
+ For example, to create the equivalent of:
+
+ .. literalinclude:: ../../../testsuite/jit.dg/test-asm.c
+ :start-after: // Quote from here in docs/topics/asm.rst: example 5: C
+ :end-before: // Quote up to here in docs/topics/asm.rst: example 5: C
+ :language: c
+
+ the following API calls could be used:
+
+ .. literalinclude:: ../../../testsuite/jit.dg/test-asm.c
+ :start-after: /* Quote from here in docs/topics/asm.rst: example 5: jit. */
+ :end-before: /* Quote up to here in docs/topics/asm.rst: example 5: jit. */
+ :language: c
diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst
index 6bfa101..b953da5 100644
--- a/gcc/jit/docs/topics/compatibility.rst
+++ b/gcc/jit/docs/topics/compatibility.rst
@@ -226,3 +226,20 @@ entrypoints:
--------------------
``LIBGCCJIT_ABI_14`` covers the addition of
:func:`gcc_jit_global_set_initializer`
+
+.. _LIBGCCJIT_ABI_15:
+
+``LIBGCCJIT_ABI_15``
+-----------------------
+``LIBGCCJIT_ABI_15`` covers the addition of API entrypoints for directly
+embedding assembler instructions:
+
+ * :func:`gcc_jit_block_add_extended_asm`
+ * :func:`gcc_jit_block_end_with_extended_asm_goto`
+ * :func:`gcc_jit_extended_asm_as_object`
+ * :func:`gcc_jit_extended_asm_set_volatile_flag`
+ * :func:`gcc_jit_extended_asm_set_inline_flag`
+ * :func:`gcc_jit_extended_asm_add_output_operand`
+ * :func:`gcc_jit_extended_asm_add_input_operand`
+ * :func:`gcc_jit_extended_asm_add_clobber`
+ * :func:`gcc_jit_context_add_top_level_asm`
diff --git a/gcc/jit/docs/topics/functions.rst b/gcc/jit/docs/topics/functions.rst
index eb40d64..b869256 100644
--- a/gcc/jit/docs/topics/functions.rst
+++ b/gcc/jit/docs/topics/functions.rst
@@ -458,3 +458,6 @@ Statements
:start-after: /* Quote from here in docs/topics/functions.rst. */
:end-before: /* Quote up to here in docs/topics/functions.rst. */
:language: c
+
+See also :type:`gcc_jit_extended_asm` for entrypoints for adding inline
+assembler statements to a function.
diff --git a/gcc/jit/docs/topics/index.rst b/gcc/jit/docs/topics/index.rst
index 8352ca2..d7cb86a 100644
--- a/gcc/jit/docs/topics/index.rst
+++ b/gcc/jit/docs/topics/index.rst
@@ -31,3 +31,4 @@ Topic Reference
compilation.rst
compatibility.rst
performance.rst
+ asm.rst
diff --git a/gcc/jit/docs/topics/objects.rst b/gcc/jit/docs/topics/objects.rst
index 12d3c9f..cdee2c0 100644
--- a/gcc/jit/docs/topics/objects.rst
+++ b/gcc/jit/docs/topics/objects.rst
@@ -48,6 +48,7 @@ looks like this::
+- gcc_jit_lvalue
+- gcc_jit_param
+- gcc_jit_case
+ +- gcc_jit_extended_asm
There are casting methods for upcasting from subclasses to parent classes.
For example, :c:func:`gcc_jit_type_as_object`:
diff --git a/gcc/jit/jit-common.h b/gcc/jit/jit-common.h
index 4570bd2..b8c3685 100644
--- a/gcc/jit/jit-common.h
+++ b/gcc/jit/jit-common.h
@@ -131,7 +131,9 @@ namespace recording {
class base_call;
class function_pointer;
class statement;
+ class extended_asm;
class case_;
+ class top_level_asm;
/* End of recording types. */
}
diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
index 4fac64d..5bccf59 100644
--- a/gcc/jit/jit-playback.c
+++ b/gcc/jit/jit-playback.c
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "opt-suggestions.h"
#include "gcc.h"
#include "diagnostic.h"
+#include "stmt.h"
#include <pthread.h>
@@ -86,6 +87,18 @@ namespace jit {
Playback.
**********************************************************************/
+/* Build a STRING_CST tree for STR, or return NULL if it is NULL.
+ The TREE_TYPE is not initialized. */
+
+static tree
+build_string (const char *str)
+{
+ if (str)
+ return ::build_string (strlen (str), str);
+ else
+ return NULL_TREE;
+}
+
/* The constructor for gcc::jit::playback::context. */
playback::context::context (recording::context *ctxt)
@@ -774,7 +787,7 @@ new_string_literal (const char *value)
tree a_type = build_array_type (char_type_node, i_type);
/* build_string len parameter must include NUL terminator when
building C strings. */
- tree t_str = build_string (len + 1, value);
+ tree t_str = ::build_string (len + 1, value);
TREE_TYPE (t_str) = a_type;
/* Convert to (const char*), loosely based on
@@ -821,6 +834,18 @@ as_truth_value (tree expr, location *loc)
return expr;
}
+/* Add a "top-level" basic asm statement (i.e. one outside of any functions)
+ containing ASM_STMTS.
+
+ Compare with c_parser_asm_definition. */
+
+void
+playback::context::add_top_level_asm (const char *asm_stmts)
+{
+ tree asm_str = build_string (asm_stmts);
+ symtab->finalize_toplevel_asm (asm_str);
+}
+
/* Construct a playback::rvalue instance (wrapping a tree) for a
unary op. */
@@ -1897,6 +1922,104 @@ add_switch (location *loc,
add_stmt (switch_stmt);
}
+/* Convert OPERANDS to a tree-based chain suitable for creating an
+ extended asm stmt.
+ Compare with c_parser_asm_operands. */
+
+static tree
+build_operand_chain (const auto_vec <playback::asm_operand> *operands)
+{
+ tree result = NULL_TREE;
+ unsigned i;
+ playback::asm_operand *asm_op;
+ FOR_EACH_VEC_ELT (*operands, i, asm_op)
+ {
+ tree name = build_string (asm_op->m_asm_symbolic_name);
+ tree str = build_string (asm_op->m_constraint);
+ tree value = asm_op->m_expr;
+ result = chainon (result,
+ build_tree_list (build_tree_list (name, str),
+ value));
+ }
+ return result;
+}
+
+/* Convert CLOBBERS to a tree-based list suitable for creating an
+ extended asm stmt.
+ Compare with c_parser_asm_clobbers. */
+
+static tree
+build_clobbers (const auto_vec <const char *> *clobbers)
+{
+ tree list = NULL_TREE;
+ unsigned i;
+ const char *clobber;
+ FOR_EACH_VEC_ELT (*clobbers, i, clobber)
+ {
+ tree str = build_string (clobber);
+ list = tree_cons (NULL_TREE, str, list);
+ }
+ return list;
+}
+
+/* Convert BLOCKS to a tree-based list suitable for creating an
+ extended asm stmt.
+ Compare with c_parser_asm_goto_operands. */
+
+static tree
+build_goto_operands (const auto_vec <playback::block *> *blocks)
+{
+ tree list = NULL_TREE;
+ unsigned i;
+ playback::block *b;
+ FOR_EACH_VEC_ELT (*blocks, i, b)
+ {
+ tree label = b->as_label_decl ();
+ tree name = build_string (IDENTIFIER_POINTER (DECL_NAME (label)));
+ TREE_USED (label) = 1;
+ list = tree_cons (name, label, list);
+ }
+ return nreverse (list);
+}
+
+/* Add an extended asm statement to this block.
+
+ Compare with c_parser_asm_statement (in c/c-parser.c)
+ and build_asm_expr (in c/c-typeck.c). */
+
+void
+playback::block::add_extended_asm (location *loc,
+ const char *asm_template,
+ bool is_volatile,
+ bool is_inline,
+ const auto_vec <asm_operand> *outputs,
+ const auto_vec <asm_operand> *inputs,
+ const auto_vec <const char *> *clobbers,
+ const auto_vec <block *> *goto_blocks)
+{
+ tree t_string = build_string (asm_template);
+ tree t_outputs = build_operand_chain (outputs);
+ tree t_inputs = build_operand_chain (inputs);
+ tree t_clobbers = build_clobbers (clobbers);
+ tree t_labels = build_goto_operands (goto_blocks);
+ t_string
+ = resolve_asm_operand_names (t_string, t_outputs, t_inputs, t_labels);
+ tree asm_stmt
+ = build5 (ASM_EXPR, void_type_node,
+ t_string, t_outputs, t_inputs, t_clobbers, t_labels);
+
+ /* asm statements without outputs, including simple ones, are treated
+ as volatile. */
+ ASM_VOLATILE_P (asm_stmt) = (outputs->length () == 0);
+ ASM_INPUT_P (asm_stmt) = 0; /* extended asm stmts are not "simple". */
+ ASM_INLINE_P (asm_stmt) = is_inline;
+ if (is_volatile)
+ ASM_VOLATILE_P (asm_stmt) = 1;
+ if (loc)
+ set_tree_location (asm_stmt, loc);
+ add_stmt (asm_stmt);
+}
+
/* Constructor for gcc::jit::playback::block. */
playback::block::
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index 50b6975..ff1f778 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -252,6 +252,8 @@ public:
timer *get_timer () const { return m_recording_ctxt->get_timer (); }
+ void add_top_level_asm (const char *asm_stmts);
+
private:
void dump_generated_code ();
@@ -514,6 +516,21 @@ struct case_
block *m_dest_block;
};
+struct asm_operand
+{
+ asm_operand (const char *asm_symbolic_name,
+ const char *constraint,
+ tree expr)
+ : m_asm_symbolic_name (asm_symbolic_name),
+ m_constraint (constraint),
+ m_expr (expr)
+ {}
+
+ const char *m_asm_symbolic_name;
+ const char *m_constraint;
+ tree m_expr;
+};
+
class block : public wrapper
{
public:
@@ -563,6 +580,16 @@ public:
block *default_block,
const auto_vec <case_> *cases);
+ void
+ add_extended_asm (location *loc,
+ const char *asm_template,
+ bool is_volatile,
+ bool is_inline,
+ const auto_vec <asm_operand> *outputs,
+ const auto_vec <asm_operand> *inputs,
+ const auto_vec <const char *> *clobbers,
+ const auto_vec <block *> *goto_blocks);
+
private:
void
set_tree_location (tree t, location *loc)
diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c
index 3cbeba0..a237d57 100644
--- a/gcc/jit/jit-recording.c
+++ b/gcc/jit/jit-recording.c
@@ -724,12 +724,12 @@ recording::context::disassociate_from_playback ()
This creates a fresh copy of the given 0-terminated buffer. */
recording::string *
-recording::context::new_string (const char *text)
+recording::context::new_string (const char *text, bool escaped)
{
if (!text)
return NULL;
- recording::string *result = new string (this, text);
+ recording::string *result = new string (this, text, escaped);
record (result);
return result;
}
@@ -1578,6 +1578,10 @@ recording::context::dump_to_file (const char *path, bool update_locations)
{
fn->write_to_dump (d);
}
+
+ top_level_asm *tla;
+ FOR_EACH_VEC_ELT (m_top_level_asms, i, tla)
+ tla->write_to_dump (d);
}
static const char * const
@@ -1904,6 +1908,22 @@ recording::context::get_all_requested_dumps (vec <recording::requested_dump> *ou
out->splice (m_requested_dumps);
}
+/* Create a recording::top_level_asm instance and add it to this
+ context's list of mementos and to m_top_level_asms.
+
+ Implements the post-error-checking part of
+ gcc_jit_context_add_top_level_asm. */
+
+void
+recording::context::add_top_level_asm (recording::location *loc,
+ const char *asm_stmts)
+{
+ recording::top_level_asm *asm_obj
+ = new recording::top_level_asm (this, loc, new_string (asm_stmts));
+ record (asm_obj);
+ m_top_level_asms.safe_push (asm_obj);
+}
+
/* This is a pre-compilation check for the context (and any parents).
Detect errors within the context, adding errors if any are found. */
@@ -1954,8 +1974,9 @@ recording::memento::write_to_dump (dump &d)
/* Constructor for gcc::jit::recording::string::string, allocating a
copy of the given text using new char[]. */
-recording::string::string (context *ctxt, const char *text)
- : memento (ctxt)
+recording::string::string (context *ctxt, const char *text, bool escaped)
+: memento (ctxt),
+ m_escaped (escaped)
{
m_len = strlen (text);
m_buffer = new char[m_len + 1];
@@ -2005,9 +2026,9 @@ recording::string::from_printf (context *ctxt, const char *fmt, ...)
recording::string *
recording::string::make_debug_string ()
{
- /* Hack to avoid infinite recursion into strings when logging all
- mementos: don't re-escape strings: */
- if (m_buffer[0] == '"')
+ /* Avoid infinite recursion into strings when logging all mementos:
+ don't re-escape strings: */
+ if (m_escaped)
return this;
/* Wrap in quotes and do escaping etc */
@@ -2024,15 +2045,31 @@ recording::string::make_debug_string ()
for (size_t i = 0; i < m_len ; i++)
{
char ch = m_buffer[i];
- if (ch == '\t' || ch == '\n' || ch == '\\' || ch == '"')
- APPEND('\\');
- APPEND(ch);
+ switch (ch)
+ {
+ default:
+ APPEND(ch);
+ break;
+ case '\t':
+ APPEND('\\');
+ APPEND('t');
+ break;
+ case '\n':
+ APPEND('\\');
+ APPEND('n');
+ break;
+ case '\\':
+ case '"':
+ APPEND('\\');
+ APPEND(ch);
+ break;
+ }
}
APPEND('"'); /* closing quote */
#undef APPEND
tmp[len] = '\0'; /* nil termintator */
- string *result = m_ctxt->new_string (tmp);
+ string *result = m_ctxt->new_string (tmp, true);
delete[] tmp;
return result;
@@ -4001,8 +4038,8 @@ recording::function::dump_to_dot (const char *path)
pretty_printer *pp = &the_pp;
- pp_printf (pp,
- "digraph %s {\n", get_debug_string ());
+ pp_printf (pp, "digraph %s", get_debug_string ());
+ pp_string (pp, " {\n");
/* Blocks: */
{
@@ -4020,7 +4057,7 @@ recording::function::dump_to_dot (const char *path)
b->dump_edges_to_dot (pp);
}
- pp_printf (pp, "}\n");
+ pp_string (pp, "}\n");
pp_flush (pp);
fclose (fp);
}
@@ -4189,6 +4226,23 @@ recording::block::add_comment (recording::location *loc,
return result;
}
+/* Create a recording::extended_asm_simple instance and add it to
+ the block's context's list of mementos, and to the block's
+ list of statements.
+
+ Implements the heart of gcc_jit_block_add_extended_asm. */
+
+recording::extended_asm *
+recording::block::add_extended_asm (location *loc,
+ const char *asm_template)
+{
+ extended_asm *result
+ = new extended_asm_simple (this, loc, new_string (asm_template));
+ m_ctxt->record (result);
+ m_statements.safe_push (result);
+ return result;
+}
+
/* Create a recording::end_with_conditional instance and add it to
the block's context's list of mementos, and to the block's
list of statements.
@@ -4271,6 +4325,30 @@ recording::block::end_with_switch (recording::location *loc,
return result;
}
+/* Create a recording::extended_asm_goto instance and add it to
+ the block's context's list of mementos, and to the block's
+ list of statements.
+
+ Implements the heart of gcc_jit_block_end_with_extended_asm_goto. */
+
+
+recording::extended_asm *
+recording::block::end_with_extended_asm_goto (location *loc,
+ const char *asm_template,
+ int num_goto_blocks,
+ block **goto_blocks,
+ block *fallthrough_block)
+{
+ extended_asm *result
+ = new extended_asm_goto (this, loc, new_string (asm_template),
+ num_goto_blocks, goto_blocks,
+ fallthrough_block);
+ m_ctxt->record (result);
+ m_statements.safe_push (result);
+ m_has_been_terminated = true;
+ return result;
+}
+
/* Override the default implementation of
recording::memento::write_to_dump for blocks by writing
an unindented block name as a label, followed by the indented
@@ -4401,6 +4479,14 @@ recording::block::write_reproducer (reproducer &r)
m_name ? m_name->get_debug_string () : "NULL");
}
+/* Disable warnings about missing quoting in GCC diagnostics for
+ the pp_printf calls. Their format strings deliberately don't
+ follow GCC diagnostic conventions. */
+#if __GNUC__ >= 10
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wformat-diag"
+#endif
+
/* Dump a block in graphviz form into PP, capturing the block name (if
any) and the statements. */
@@ -4429,7 +4515,7 @@ recording::block::dump_to_dot (pretty_printer *pp)
pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/);
}
- pp_printf (pp,
+ pp_string (pp,
"}\"];\n\n");
pp_flush (pp);
}
@@ -4449,6 +4535,10 @@ recording::block::dump_edges_to_dot (pretty_printer *pp)
successors.release ();
}
+#if __GNUC__ >= 10
+# pragma GCC diagnostic pop
+#endif
+
/* The implementation of class gcc::jit::recording::global. */
/* Implementation of pure virtual hook recording::memento::replay_into
@@ -6491,6 +6581,459 @@ recording::switch_::write_reproducer (reproducer &r)
cases_id);
}
+/* class asm_operand : public memento. */
+
+recording::asm_operand::asm_operand (extended_asm *ext_asm,
+ string *asm_symbolic_name,
+ string *constraint)
+: memento (ext_asm->get_context ()),
+ m_ext_asm (ext_asm),
+ m_asm_symbolic_name (asm_symbolic_name),
+ m_constraint (constraint)
+{
+}
+
+void
+recording::asm_operand::print (pretty_printer *pp) const
+{
+ if (m_asm_symbolic_name)
+ {
+ pp_character (pp, '[');
+ pp_string (pp, m_asm_symbolic_name->c_str ());
+ pp_character (pp, ']');
+ pp_space (pp);
+ }
+ pp_string (pp, m_constraint->get_debug_string ());
+ /* Subclass will add lvalue/rvalue. */
+}
+
+recording::string *
+recording::asm_operand::make_debug_string ()
+{
+ pretty_printer pp;
+ print (&pp);
+ return m_ctxt->new_string (pp_formatted_text (&pp), false);
+}
+
+/* class output_asm_operand : public asm_operand. */
+
+void
+recording::output_asm_operand::write_reproducer (reproducer &r)
+{
+ const char *fmt =
+ " gcc_jit_extended_asm_add_output_operand (%s, /* gcc_jit_extended_asm *ext_asm */\n"
+ " %s, /* const char *asm_symbolic_name */\n"
+ " %s, /* const char *constraint */\n"
+ " %s); /* gcc_jit_lvalue *dest */\n";
+ r.write (fmt,
+ r.get_identifier (m_ext_asm),
+ (m_asm_symbolic_name
+ ? m_asm_symbolic_name->get_debug_string () : "NULL"),
+ m_constraint->get_debug_string (),
+ r.get_identifier (m_dest));
+}
+
+void
+recording::output_asm_operand::print (pretty_printer *pp) const
+{
+ asm_operand::print (pp);
+ pp_string (pp, " (");
+ pp_string (pp, m_dest->get_debug_string ());
+ pp_string (pp, ")");
+}
+
+/* class input_asm_operand : public asm_operand. */
+
+void
+recording::input_asm_operand::write_reproducer (reproducer &r)
+{
+ const char *fmt =
+ " gcc_jit_extended_asm_add_input_operand (%s, /* gcc_jit_extended_asm *ext_asm */\n"
+ " %s, /* const char *asm_symbolic_name */\n"
+ " %s, /* const char *constraint */\n"
+ " %s); /* gcc_jit_rvalue *src */\n";
+ r.write (fmt,
+ r.get_identifier (m_ext_asm),
+ (m_asm_symbolic_name
+ ? m_asm_symbolic_name->get_debug_string () : "NULL"),
+ m_constraint->get_debug_string (),
+ r.get_identifier_as_rvalue (m_src));
+}
+
+void
+recording::input_asm_operand::print (pretty_printer *pp) const
+{
+ asm_operand::print (pp);
+ pp_string (pp, " (");
+ pp_string (pp, m_src->get_debug_string ());
+ pp_string (pp, ")");
+}
+
+/* The implementation of class gcc::jit::recording::extended_asm. */
+
+void
+recording::extended_asm::add_output_operand (const char *asm_symbolic_name,
+ const char *constraint,
+ lvalue *dest)
+{
+ output_asm_operand *op
+ = new output_asm_operand (this,
+ new_string (asm_symbolic_name),
+ new_string (constraint),
+ dest);
+ m_ctxt->record (op);
+ m_output_ops.safe_push (op);
+}
+
+void
+recording::extended_asm::add_input_operand (const char *asm_symbolic_name,
+ const char *constraint,
+ rvalue *src)
+{
+ input_asm_operand *op
+ = new input_asm_operand (this,
+ new_string (asm_symbolic_name),
+ new_string (constraint),
+ src);
+ m_ctxt->record (op);
+ m_input_ops.safe_push (op);
+}
+
+void
+recording::extended_asm::add_clobber (const char *victim)
+{
+ m_clobbers.safe_push (new_string (victim));
+}
+
+/* Implementation of recording::memento::replay_into
+ for recording::extended_asm. */
+
+void
+recording::extended_asm::replay_into (replayer *r)
+{
+ auto_vec<playback::asm_operand> playback_output_ops;
+ auto_vec<playback::asm_operand> playback_input_ops;
+ auto_vec<const char *> playback_clobbers;
+ auto_vec<playback::block *> playback_goto_blocks;
+
+ /* Populate outputs. */
+ {
+ output_asm_operand *rec_asm_op;
+ unsigned i;
+ FOR_EACH_VEC_ELT (m_output_ops, i, rec_asm_op)
+ {
+ playback::asm_operand playback_asm_op
+ (rec_asm_op->get_symbolic_name (),
+ rec_asm_op->get_constraint (),
+ rec_asm_op->get_lvalue ()->playback_lvalue ()->as_tree ());
+ playback_output_ops.safe_push (playback_asm_op);
+ }
+ }
+
+ /* Populate inputs. */
+ {
+ input_asm_operand *rec_asm_op;
+ unsigned i;
+ FOR_EACH_VEC_ELT (m_input_ops, i, rec_asm_op)
+ {
+ playback::asm_operand playback_asm_op
+ (rec_asm_op->get_symbolic_name (),
+ rec_asm_op->get_constraint (),
+ rec_asm_op->get_rvalue ()->playback_rvalue ()->as_tree ());
+ playback_input_ops.safe_push (playback_asm_op);
+ }
+ }
+
+ /* Populate clobbers. */
+ {
+ string *rec_clobber;
+ unsigned i;
+ FOR_EACH_VEC_ELT (m_clobbers, i, rec_clobber)
+ playback_clobbers.safe_push (rec_clobber->c_str ());
+ }
+
+ /* Populate playback blocks if an "asm goto". */
+ maybe_populate_playback_blocks (&playback_goto_blocks);
+
+ playback_block (get_block ())
+ ->add_extended_asm (playback_location (r),
+ m_asm_template->c_str (),
+ m_is_volatile, m_is_inline,
+ &playback_output_ops,
+ &playback_input_ops,
+ &playback_clobbers,
+ &playback_goto_blocks);
+}
+
+/* Implementation of recording::memento::make_debug_string for
+ an extended_asm "statement". */
+
+recording::string *
+recording::extended_asm::make_debug_string ()
+{
+ pretty_printer pp;
+ pp_string (&pp, "asm ");
+ if (m_is_volatile)
+ pp_string (&pp, "volatile ");
+ if (m_is_inline)
+ pp_string (&pp, "inline ");
+ if (is_goto ())
+ pp_string (&pp, "goto ");
+ pp_character (&pp, '(');
+ pp_string (&pp, m_asm_template->get_debug_string ());
+ pp_string (&pp, " : ");
+ unsigned i;
+ {
+ output_asm_operand *asm_op;
+ FOR_EACH_VEC_ELT (m_output_ops, i, asm_op)
+ {
+ if (i > 0)
+ pp_string (&pp, ", ");
+ asm_op->print (&pp);
+ }
+ }
+ pp_string (&pp, " : ");
+ {
+ input_asm_operand *asm_op;
+ FOR_EACH_VEC_ELT (m_input_ops, i, asm_op)
+ {
+ if (i > 0)
+ pp_string (&pp, ", ");
+ asm_op->print (&pp);
+ }
+ }
+ pp_string (&pp, " : ");
+ string *rec_clobber;
+ FOR_EACH_VEC_ELT (m_clobbers, i, rec_clobber)
+ {
+ if (i > 0)
+ pp_string (&pp, ", ");
+ pp_string (&pp, rec_clobber->get_debug_string ());
+ }
+ maybe_print_gotos (&pp);
+ pp_character (&pp, ')');
+ return new_string (pp_formatted_text (&pp));
+}
+
+void
+recording::extended_asm::write_flags (reproducer &r)
+{
+ if (m_is_volatile)
+ r.write (" gcc_jit_extended_asm_set_volatile_flag (%s, 1);\n",
+ r.get_identifier (this));
+ if (m_is_inline)
+ r.write (" gcc_jit_extended_asm_set_inline_flag (%s, 1);\n",
+ r.get_identifier (this));
+}
+
+void
+recording::extended_asm::write_clobbers (reproducer &r)
+{
+ string *clobber;
+ unsigned i;
+ FOR_EACH_VEC_ELT (m_clobbers, i, clobber)
+ r.write (" gcc_jit_extended_asm_add_clobber (%s, %s);\n",
+ r.get_identifier (this),
+ clobber->get_debug_string ());
+}
+
+/* Implementation of recording::memento::write_reproducer for
+ extended_asm_simple. */
+
+void
+recording::extended_asm_simple::write_reproducer (reproducer &r)
+{
+ const char *id = r.make_identifier (this, "extended_asm");
+ r.write (" gcc_jit_extended_asm *%s =\n"
+ " gcc_jit_block_add_extended_asm (%s, /*gcc_jit_block *block */\n"
+ " %s, /* gcc_jit_location *loc */\n"
+ " %s); /* const char *asm_template */\n",
+ id,
+ r.get_identifier (get_block ()),
+ r.get_identifier (get_loc ()),
+ m_asm_template->get_debug_string ());
+ write_flags (r);
+ write_clobbers (r);
+}
+
+void
+recording::extended_asm::
+maybe_populate_playback_blocks (auto_vec <playback::block *> *)
+{
+ /* Do nothing; not an "asm goto". */
+}
+
+/* The implementation of class gcc::jit::recording::extended_asm_goto. */
+
+/* recording::extended_asm_goto's ctor. */
+
+recording::extended_asm_goto::extended_asm_goto (block *b,
+ location *loc,
+ string *asm_template,
+ int num_goto_blocks,
+ block **goto_blocks,
+ block *fallthrough_block)
+: extended_asm (b, loc, asm_template),
+ m_goto_blocks (num_goto_blocks),
+ m_fallthrough_block (fallthrough_block)
+{
+ for (int i = 0; i < num_goto_blocks; i++)
+ m_goto_blocks.quick_push (goto_blocks[i]);
+}
+
+/* Implementation of recording::memento::replay_into
+ for recording::extended_asm_goto. */
+
+void
+recording::extended_asm_goto::replay_into (replayer *r)
+{
+ /* Chain up to base class impl. */
+ recording::extended_asm::replay_into (r);
+
+ /* ...and potentially add a goto for the fallthrough. */
+ if (m_fallthrough_block)
+ playback_block (get_block ())
+ ->add_jump (playback_location (r),
+ m_fallthrough_block->playback_block ());
+}
+
+/* Implementation of recording::memento::write_reproducer for
+ extended_asm_goto. */
+
+void
+recording::extended_asm_goto::write_reproducer (reproducer &r)
+{
+ const char *id = r.make_identifier (this, "extended_asm");
+ const char *blocks_id = r.make_tmp_identifier ("blocks_for", this);
+ r.write (" gcc_jit_block *%s[%i] = {\n",
+ blocks_id,
+ m_goto_blocks.length ());
+ int i;
+ block *b;
+ FOR_EACH_VEC_ELT (m_goto_blocks, i, b)
+ r.write (" %s,\n", r.get_identifier (b));
+ r.write (" };\n");
+ r.write (" gcc_jit_extended_asm *%s =\n"
+ " gcc_jit_block_end_with_extended_asm_goto (%s, /*gcc_jit_block *block */\n"
+ " %s, /* gcc_jit_location *loc */\n"
+ " %s, /* const char *asm_template */\n"
+ " %i, /* int num_goto_blocks */\n"
+ " %s, /* gcc_jit_block **goto_blocks */\n"
+ " %s); /* gcc_jit_block *fallthrough_block */\n",
+ id,
+ r.get_identifier (get_block ()),
+ r.get_identifier (get_loc ()),
+ m_asm_template->get_debug_string (),
+ m_goto_blocks.length (),
+ blocks_id,
+ (m_fallthrough_block
+ ? r.get_identifier (m_fallthrough_block)
+ : "NULL"));
+ write_flags (r);
+ write_clobbers (r);
+}
+
+/* Override the poisoned default implementation of
+ gcc::jit::recording::statement::get_successor_blocks
+
+ An extended_asm_goto can jump to the m_goto_blocks, and to
+ the (optional) m_fallthrough_block. */
+
+vec <recording::block *>
+recording::extended_asm_goto::get_successor_blocks () const
+{
+ vec <block *> result;
+ result.create (m_goto_blocks.length () + 1);
+ if (m_fallthrough_block)
+ result.quick_push (m_fallthrough_block);
+ result.splice (m_goto_blocks);
+ return result;
+}
+
+/* Vfunc for use by recording::extended_asm::make_debug_string. */
+
+void
+recording::extended_asm_goto::maybe_print_gotos (pretty_printer *pp) const
+{
+ pp_string (pp, " : ");
+ unsigned i;
+ block *b;
+ FOR_EACH_VEC_ELT (m_goto_blocks, i, b)
+ {
+ if (i > 0)
+ pp_string (pp, ", ");
+ pp_string (pp, b->get_debug_string ());
+ }
+ /* Non-C syntax here. */
+ if (m_fallthrough_block)
+ pp_printf (pp, " [fallthrough: %s]",
+ m_fallthrough_block->get_debug_string ());
+}
+
+/* Vfunc for use by recording::extended_asm::replay_into. */
+
+void
+recording::extended_asm_goto::
+maybe_populate_playback_blocks (auto_vec <playback::block *> *out)
+{
+ unsigned i;
+ block *b;
+ FOR_EACH_VEC_ELT (m_goto_blocks, i, b)
+ out->safe_push (b->playback_block ());
+}
+
+/* class top_level_asm : public memento. */
+
+recording::top_level_asm::top_level_asm (context *ctxt,
+ location *loc,
+ string *asm_stmts)
+: memento (ctxt),
+ m_loc (loc),
+ m_asm_stmts (asm_stmts)
+{
+}
+
+/* Implementation of recording::memento::replay_into for top-level asm. */
+
+void
+recording::top_level_asm::replay_into (replayer *r)
+{
+ r->add_top_level_asm (m_asm_stmts->c_str ());
+}
+
+/* Implementation of recording::memento::make_debug_string for
+ top-level asm. */
+
+recording::string *
+recording::top_level_asm::make_debug_string ()
+{
+ return string::from_printf (m_ctxt, "asm (%s)",
+ m_asm_stmts->get_debug_string ());
+}
+
+/* Override the default implementation of
+ recording::memento::write_to_dump.
+ Don't indent the string. */
+
+void
+recording::top_level_asm::write_to_dump (dump &d)
+{
+ d.write ("%s;\n", get_debug_string ());
+}
+
+/* Implementation of recording::memento::write_reproducer for top-level asm. */
+
+void
+recording::top_level_asm::write_reproducer (reproducer &r)
+{
+ r.write (" gcc_jit_context_add_top_level_asm (%s, /* gcc_jit_context *ctxt */\n"
+ " %s, /* gcc_jit_location *loc */\n"
+ " %s); /* const char *asm_stmts */\n",
+ r.get_identifier (get_context ()),
+ r.get_identifier (m_loc),
+ m_asm_stmts->get_debug_string ());
+}
+
} // namespace gcc::jit
} // namespace gcc
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 30e37af..e694882 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -74,7 +74,7 @@ public:
void disassociate_from_playback ();
string *
- new_string (const char *text);
+ new_string (const char *text, bool escaped = false);
location *
new_location (const char *filename,
@@ -301,6 +301,8 @@ public:
void set_timer (timer *t) { m_timer = t; }
timer *get_timer () const { return m_timer; }
+ void add_top_level_asm (location *loc, const char *asm_stmts);
+
private:
void log_all_options () const;
void log_str_option (enum gcc_jit_str_option opt) const;
@@ -344,6 +346,7 @@ private:
auto_vec<compound_type *> m_compound_types;
auto_vec<global *> m_globals;
auto_vec<function *> m_functions;
+ auto_vec<top_level_asm *> m_top_level_asms;
type *m_basic_types[NUM_GCC_JIT_TYPES];
type *m_FILE_type;
@@ -414,7 +417,7 @@ private:
class string : public memento
{
public:
- string (context *ctxt, const char *text);
+ string (context *ctxt, const char *text, bool escaped);
~string ();
const char *c_str () { return m_buffer; }
@@ -431,6 +434,11 @@ private:
private:
size_t m_len;
char *m_buffer;
+
+ /* Flag to track if this string is the result of string::make_debug_string,
+ to avoid infinite recursion when logging all mementos: don't re-escape
+ such strings. */
+ bool m_escaped;
};
class location : public memento
@@ -1270,6 +1278,10 @@ public:
add_comment (location *loc,
const char *text);
+ extended_asm *
+ add_extended_asm (location *loc,
+ const char *asm_template);
+
statement *
end_with_conditional (location *loc,
rvalue *boolval,
@@ -1291,6 +1303,13 @@ public:
int num_cases,
case_ **cases);
+ extended_asm *
+ end_with_extended_asm_goto (location *loc,
+ const char *asm_template,
+ int num_goto_blocks,
+ block **goto_blocks,
+ block *fallthrough_block);
+
playback::block *
playback_block () const
{
@@ -2107,6 +2126,207 @@ private:
auto_vec <case_ *> m_cases;
};
+class asm_operand : public memento
+{
+public:
+ asm_operand (extended_asm *ext_asm,
+ string *asm_symbolic_name,
+ string *constraint);
+
+ const char *get_symbolic_name () const
+ {
+ if (m_asm_symbolic_name)
+ return m_asm_symbolic_name->c_str ();
+ else
+ return NULL;
+ }
+
+ const char *get_constraint () const
+ {
+ return m_constraint->c_str ();
+ }
+
+ virtual void print (pretty_printer *pp) const;
+
+private:
+ string * make_debug_string () FINAL OVERRIDE;
+
+protected:
+ extended_asm *m_ext_asm;
+ string *m_asm_symbolic_name;
+ string *m_constraint;
+};
+
+class output_asm_operand : public asm_operand
+{
+public:
+ output_asm_operand (extended_asm *ext_asm,
+ string *asm_symbolic_name,
+ string *constraint,
+ lvalue *dest)
+ : asm_operand (ext_asm, asm_symbolic_name, constraint),
+ m_dest (dest)
+ {}
+
+ lvalue *get_lvalue () const { return m_dest; }
+
+ void replay_into (replayer *) FINAL OVERRIDE {}
+
+ void print (pretty_printer *pp) const FINAL OVERRIDE;
+
+private:
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+
+private:
+ lvalue *m_dest;
+};
+
+class input_asm_operand : public asm_operand
+{
+public:
+ input_asm_operand (extended_asm *ext_asm,
+ string *asm_symbolic_name,
+ string *constraint,
+ rvalue *src)
+ : asm_operand (ext_asm, asm_symbolic_name, constraint),
+ m_src (src)
+ {}
+
+ rvalue *get_rvalue () const { return m_src; }
+
+ void replay_into (replayer *) FINAL OVERRIDE {}
+
+ void print (pretty_printer *pp) const FINAL OVERRIDE;
+
+private:
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+
+private:
+ rvalue *m_src;
+};
+
+/* Abstract base class for extended_asm statements. */
+
+class extended_asm : public statement
+{
+public:
+ extended_asm (block *b,
+ location *loc,
+ string *asm_template)
+ : statement (b, loc),
+ m_asm_template (asm_template),
+ m_is_volatile (false),
+ m_is_inline (false)
+ {}
+
+ void set_volatile_flag (bool flag) { m_is_volatile = flag; }
+ void set_inline_flag (bool flag) { m_is_inline = flag; }
+
+ void add_output_operand (const char *asm_symbolic_name,
+ const char *constraint,
+ lvalue *dest);
+ void add_input_operand (const char *asm_symbolic_name,
+ const char *constraint,
+ rvalue *src);
+ void add_clobber (const char *victim);
+
+ void replay_into (replayer *r) OVERRIDE;
+
+ string *get_asm_template () const { return m_asm_template; }
+
+ virtual bool is_goto () const = 0;
+ virtual void maybe_print_gotos (pretty_printer *) const = 0;
+
+protected:
+ void write_flags (reproducer &r);
+ void write_clobbers (reproducer &r);
+
+private:
+ string * make_debug_string () FINAL OVERRIDE;
+ virtual void maybe_populate_playback_blocks
+ (auto_vec <playback::block *> *out) = 0;
+
+protected:
+ string *m_asm_template;
+ bool m_is_volatile;
+ bool m_is_inline;
+ auto_vec<output_asm_operand *> m_output_ops;
+ auto_vec<input_asm_operand *> m_input_ops;
+ auto_vec<string *> m_clobbers;
+};
+
+/* An extended_asm that's not a goto, as created by
+ gcc_jit_block_add_extended_asm. */
+
+class extended_asm_simple : public extended_asm
+{
+public:
+ extended_asm_simple (block *b,
+ location *loc,
+ string *asm_template)
+ : extended_asm (b, loc, asm_template)
+ {}
+
+ void write_reproducer (reproducer &r) OVERRIDE;
+ bool is_goto () const FINAL OVERRIDE { return false; }
+ void maybe_print_gotos (pretty_printer *) const FINAL OVERRIDE {}
+
+private:
+ void maybe_populate_playback_blocks
+ (auto_vec <playback::block *> *) FINAL OVERRIDE
+ {}
+};
+
+/* An extended_asm that's a asm goto, as created by
+ gcc_jit_block_end_with_extended_asm_goto. */
+
+class extended_asm_goto : public extended_asm
+{
+public:
+ extended_asm_goto (block *b,
+ location *loc,
+ string *asm_template,
+ int num_goto_blocks,
+ block **goto_blocks,
+ block *fallthrough_block);
+
+ void replay_into (replayer *r) FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) OVERRIDE;
+
+ vec <block *> get_successor_blocks () const FINAL OVERRIDE;
+
+ bool is_goto () const FINAL OVERRIDE { return true; }
+ void maybe_print_gotos (pretty_printer *) const FINAL OVERRIDE;
+
+private:
+ void maybe_populate_playback_blocks
+ (auto_vec <playback::block *> *out) FINAL OVERRIDE;
+
+private:
+ auto_vec <block *> m_goto_blocks;
+ block *m_fallthrough_block;
+};
+
+/* A group of top-level asm statements, as created by
+ gcc_jit_context_add_top_level_asm. */
+
+class top_level_asm : public memento
+{
+public:
+ top_level_asm (context *ctxt, location *loc, string *asm_stmts);
+
+ void write_to_dump (dump &d) FINAL OVERRIDE;
+
+private:
+ void replay_into (replayer *r) FINAL OVERRIDE;
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+
+private:
+ location *m_loc;
+ string *m_asm_stmts;
+};
+
} // namespace gcc::jit::recording
/* Create a recording::memento_of_new_rvalue_from_const instance and add
diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h
index 1b9ef1a..b4901ce 100644
--- a/gcc/jit/libgccjit++.h
+++ b/gcc/jit/libgccjit++.h
@@ -46,6 +46,7 @@ namespace gccjit
class lvalue;
class param;
class case_;
+ class extended_asm;
class timer;
class auto_time;
@@ -316,6 +317,9 @@ namespace gccjit
rvalue max_value,
block dest_block);
+ void add_top_level_asm (const char *asm_stmts,
+ location loc = location ());
+
private:
gcc_jit_context *m_inner_ctxt;
};
@@ -449,6 +453,13 @@ namespace gccjit
block default_block,
std::vector <case_> cases,
location loc = location ());
+
+ extended_asm add_extended_asm (const std::string &asm_template,
+ location loc = location ());
+ extended_asm end_with_extended_asm_goto (const std::string &asm_template,
+ std::vector<block> goto_blocks,
+ block *fallthrough_block,
+ location loc = location ());
};
class rvalue : public object
@@ -509,6 +520,40 @@ namespace gccjit
gcc_jit_case *get_inner_case () const;
};
+ class extended_asm : public object
+ {
+ public:
+ extended_asm ();
+ extended_asm (gcc_jit_extended_asm *inner);
+
+ extended_asm &
+ set_volatile_flag (bool flag);
+
+ extended_asm &
+ set_inline_flag (bool flag);
+
+ extended_asm&
+ add_output_operand (const std::string &asm_symbolic_name,
+ const std::string &constraint,
+ gccjit::lvalue dest);
+ extended_asm&
+ add_output_operand (const std::string &constraint,
+ gccjit::lvalue dest);
+
+ extended_asm&
+ add_input_operand (const std::string &asm_symbolic_name,
+ const std::string &constraint,
+ gccjit::rvalue src);
+ extended_asm&
+ add_input_operand (const std::string &constraint,
+ gccjit::rvalue src);
+
+ extended_asm&
+ add_clobber (const std::string &victim);
+
+ gcc_jit_extended_asm *get_inner_extended_asm () const;
+ };
+
/* Overloaded operators, for those who want the most terse API
(at the possible risk of being a little too magical).
@@ -1259,6 +1304,14 @@ context::new_case (rvalue min_value,
dest_block.get_inner_block ()));
}
+inline void
+context::add_top_level_asm (const char *asm_stmts, location loc)
+{
+ gcc_jit_context_add_top_level_asm (m_inner_ctxt,
+ loc.get_inner_location (),
+ asm_stmts);
+}
+
// class object
inline context
object::get_context () const
@@ -1554,6 +1607,37 @@ block::end_with_switch (rvalue expr,
as_array_of_ptrs);
}
+inline extended_asm
+block::add_extended_asm (const std::string &asm_template,
+ location loc)
+{
+ return gcc_jit_block_add_extended_asm (get_inner_block (),
+ loc.get_inner_location (),
+ asm_template.c_str ());
+}
+
+inline extended_asm
+block::end_with_extended_asm_goto (const std::string &asm_template,
+ std::vector<block> goto_blocks,
+ block *fallthrough_block,
+ location loc)
+{
+ /* Treat std::vector as an array, relying on it not being resized: */
+ block *as_array_of_wrappers = &goto_blocks[0];
+
+ /* Treat the array as being of the underlying pointers, relying on
+ the wrapper type being such a pointer internally. */
+ gcc_jit_block **as_array_of_ptrs =
+ reinterpret_cast<gcc_jit_block **> (as_array_of_wrappers);
+ return gcc_jit_block_end_with_extended_asm_goto
+ (get_inner_block (),
+ loc.get_inner_location (),
+ asm_template.c_str (),
+ goto_blocks.size (),
+ as_array_of_ptrs,
+ fallthrough_block ? fallthrough_block->get_inner_block () : NULL);
+}
+
inline rvalue
block::add_call (function other,
location loc)
@@ -1767,6 +1851,92 @@ case_::get_inner_case () const
return reinterpret_cast<gcc_jit_case *> (get_inner_object ());
}
+// class extended_asm : public object
+inline extended_asm::extended_asm () : object () {}
+inline extended_asm::extended_asm (gcc_jit_extended_asm *inner)
+ : object (gcc_jit_extended_asm_as_object (inner))
+{
+}
+
+inline extended_asm&
+extended_asm::set_volatile_flag (bool flag)
+{
+ gcc_jit_extended_asm_set_volatile_flag (get_inner_extended_asm (), flag);
+ return *this;
+}
+
+inline extended_asm&
+extended_asm::set_inline_flag (bool flag)
+{
+ gcc_jit_extended_asm_set_inline_flag (get_inner_extended_asm (), flag);
+ return *this;
+}
+
+inline extended_asm&
+extended_asm::add_output_operand (const std::string &asm_symbolic_name,
+ const std::string &constraint,
+ gccjit::lvalue dest)
+{
+ gcc_jit_extended_asm_add_output_operand
+ (get_inner_extended_asm (),
+ asm_symbolic_name.c_str (),
+ constraint.c_str (),
+ dest.get_inner_lvalue ());
+ return *this;
+}
+
+inline extended_asm&
+extended_asm::add_output_operand (const std::string &constraint,
+ gccjit::lvalue dest)
+{
+ gcc_jit_extended_asm_add_output_operand
+ (get_inner_extended_asm (),
+ NULL, /* asm_symbolic_name */
+ constraint.c_str (),
+ dest.get_inner_lvalue ());
+ return *this;
+}
+
+inline extended_asm&
+extended_asm::add_input_operand (const std::string &asm_symbolic_name,
+ const std::string &constraint,
+ gccjit::rvalue src)
+{
+ gcc_jit_extended_asm_add_input_operand
+ (get_inner_extended_asm (),
+ asm_symbolic_name.c_str (),
+ constraint.c_str (),
+ src.get_inner_rvalue ());
+ return *this;
+}
+
+inline extended_asm&
+extended_asm::add_input_operand (const std::string &constraint,
+ gccjit::rvalue src)
+{
+ gcc_jit_extended_asm_add_input_operand
+ (get_inner_extended_asm (),
+ NULL, /* asm_symbolic_name */
+ constraint.c_str (),
+ src.get_inner_rvalue ());
+ return *this;
+}
+
+inline extended_asm&
+extended_asm::add_clobber (const std::string &victim)
+{
+ gcc_jit_extended_asm_add_clobber (get_inner_extended_asm (),
+ victim.c_str ());
+ return *this;
+}
+
+inline gcc_jit_extended_asm *
+extended_asm::get_inner_extended_asm () const
+{
+ /* Manual downcast: */
+ return reinterpret_cast<gcc_jit_extended_asm *> (get_inner_object ());
+}
+
/* Overloaded operators. */
// Unary operators
inline rvalue operator- (rvalue a)
diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index a00aefc..f9c33c6 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -96,6 +96,11 @@ struct gcc_jit_timer : public timer
{
};
+struct gcc_jit_extended_asm : public gcc::jit::recording::extended_asm
+{
+};
+
+
/**********************************************************************
Error-handling.
@@ -300,13 +305,13 @@ struct gcc_jit_timer : public timer
static void
jit_error (gcc::jit::recording::context *ctxt,
- gcc_jit_location *loc,
+ gcc::jit::recording::location *loc,
const char *fmt, ...)
GNU_PRINTF(3, 4);
static void
jit_error (gcc::jit::recording::context *ctxt,
- gcc_jit_location *loc,
+ gcc::jit::recording::location *loc,
const char *fmt, ...)
{
va_list ap;
@@ -3290,3 +3295,182 @@ gcc_jit_version_patchlevel (void)
version_info vi;
return vi.patchlevel;
}
+
+/**********************************************************************
+ Asm support.
+ **********************************************************************/
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
+ gcc::jit::recording::block::add_extended_asm, in
+ jit-recording.c. */
+
+gcc_jit_extended_asm *
+gcc_jit_block_add_extended_asm (gcc_jit_block *block,
+ gcc_jit_location *loc,
+ const char *asm_template)
+{
+ RETURN_NULL_IF_NOT_VALID_BLOCK (block, loc);
+ gcc::jit::recording::context *ctxt = block->get_context ();
+ JIT_LOG_FUNC (ctxt->get_logger ());
+ /* LOC can be NULL. */
+ RETURN_NULL_IF_FAIL (asm_template, ctxt, loc, "NULL asm_template");
+
+ return (gcc_jit_extended_asm *)block->add_extended_asm (loc, asm_template);
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
+ gcc::jit::recording::block::end_with_extended_asm_goto, in
+ jit-recording.c. */
+
+gcc_jit_extended_asm *
+gcc_jit_block_end_with_extended_asm_goto (gcc_jit_block *block,
+ gcc_jit_location *loc,
+ const char *asm_template,
+ int num_goto_blocks,
+ gcc_jit_block **goto_blocks,
+ gcc_jit_block *fallthrough_block)
+{
+ RETURN_NULL_IF_NOT_VALID_BLOCK (block, loc);
+ gcc::jit::recording::context *ctxt = block->get_context ();
+ JIT_LOG_FUNC (ctxt->get_logger ());
+ /* LOC can be NULL. */
+ RETURN_NULL_IF_FAIL (asm_template, ctxt, loc, "NULL asm_template");
+ RETURN_NULL_IF_FAIL (num_goto_blocks >= 0, ctxt, loc, "num_goto_blocks < 0");
+ for (int i = 0; i < num_goto_blocks; i++)
+ RETURN_NULL_IF_FAIL_PRINTF1 (goto_blocks[i],
+ ctxt, loc,
+ "NULL goto_blocks[%i]", i);
+ /* fallthrough_block can be NULL. */
+ return (gcc_jit_extended_asm *)block->end_with_extended_asm_goto
+ (loc, asm_template,
+ num_goto_blocks, (gcc::jit::recording::block **)goto_blocks,
+ fallthrough_block);
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, this calls the trivial
+ gcc::jit::recording::memento::as_object method (an extended_asm is a
+ memento), in jit-recording.h. */
+
+gcc_jit_object *
+gcc_jit_extended_asm_as_object (gcc_jit_extended_asm *ext_asm)
+{
+ RETURN_NULL_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
+
+ return static_cast <gcc_jit_object *> (ext_asm->as_object ());
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
+ gcc::jit::recording::extended_asm::set_volatile_flag, in
+ jit-recording.c. */
+
+void
+gcc_jit_extended_asm_set_volatile_flag (gcc_jit_extended_asm *ext_asm,
+ int flag)
+{
+ RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
+ ext_asm->set_volatile_flag (flag);
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
+ gcc::jit::recording::extended_asm::set_inline_flag, in
+ jit-recording.c. */
+
+void
+gcc_jit_extended_asm_set_inline_flag (gcc_jit_extended_asm *ext_asm,
+ int flag)
+{
+ RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
+ ext_asm->set_inline_flag (flag);
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
+ gcc::jit::recording::extended_asm::add_output_operand, in
+ jit-recording.c. */
+
+void
+gcc_jit_extended_asm_add_output_operand (gcc_jit_extended_asm *ext_asm,
+ const char *asm_symbolic_name,
+ const char *constraint,
+ gcc_jit_lvalue *dest)
+{
+ RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
+ gcc::jit::recording::context *ctxt = ext_asm->get_context ();
+ JIT_LOG_FUNC (ctxt->get_logger ());
+ gcc::jit::recording::location *loc = ext_asm->get_loc ();
+ /* asm_symbolic_name can be NULL. */
+ RETURN_IF_FAIL (constraint, ctxt, loc, "NULL constraint");
+ RETURN_IF_FAIL (dest, ctxt, loc, "NULL dest");
+ RETURN_IF_FAIL (!ext_asm->is_goto (), ctxt, loc,
+ "cannot add output operand to asm goto");
+ ext_asm->add_output_operand (asm_symbolic_name, constraint, dest);
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
+ gcc::jit::recording::extended_asm::add_input_operand, in
+ jit-recording.c. */
+
+extern void
+gcc_jit_extended_asm_add_input_operand (gcc_jit_extended_asm *ext_asm,
+ const char *asm_symbolic_name,
+ const char *constraint,
+ gcc_jit_rvalue *src)
+{
+ RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
+ gcc::jit::recording::context *ctxt = ext_asm->get_context ();
+ JIT_LOG_FUNC (ctxt->get_logger ());
+ gcc::jit::recording::location *loc = ext_asm->get_loc ();
+ /* asm_symbolic_name can be NULL. */
+ RETURN_IF_FAIL (constraint, ctxt, loc, "NULL constraint");
+ RETURN_IF_FAIL (src, ctxt, loc, "NULL src");
+ ext_asm->add_input_operand (asm_symbolic_name, constraint, src);
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
+ gcc::jit::recording::extended_asm::add_clobber, in
+ jit-recording.c. */
+
+void
+gcc_jit_extended_asm_add_clobber (gcc_jit_extended_asm *ext_asm,
+ const char *victim)
+{
+ RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
+ gcc::jit::recording::context *ctxt = ext_asm->get_context ();
+ JIT_LOG_FUNC (ctxt->get_logger ());
+ gcc::jit::recording::location *loc = ext_asm->get_loc ();
+ RETURN_IF_FAIL (victim, ctxt, loc, "NULL victim");
+ ext_asm->add_clobber (victim);
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
+ gcc::jit::recording::context::add_top_level_asm, in
+ jit-recording.c. */
+
+void
+gcc_jit_context_add_top_level_asm (gcc_jit_context *ctxt,
+ gcc_jit_location *loc,
+ const char *asm_stmts)
+{
+ RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL ctxt");
+ JIT_LOG_FUNC (ctxt->get_logger ());
+ /* LOC can be NULL. */
+ RETURN_IF_FAIL (asm_stmts, ctxt, NULL, "NULL asm_stmts");
+ ctxt->add_top_level_asm (loc, asm_stmts);
+}
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index 7134841..c523f93 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -68,6 +68,7 @@ typedef struct gcc_jit_result gcc_jit_result;
+- gcc_jit_lvalue
+- gcc_jit_param
+- gcc_jit_case
+ +- gcc_jit_extended_asm
*/
typedef struct gcc_jit_object gcc_jit_object;
@@ -138,6 +139,12 @@ typedef struct gcc_jit_param gcc_jit_param;
destination block. */
typedef struct gcc_jit_case gcc_jit_case;
+/* A gcc_jit_extended_asm represents an assembly language statement,
+ analogous to an extended "asm" statement in GCC's C front-end: a series
+ of low-level instructions inside a function that convert inputs to
+ outputs. */
+typedef struct gcc_jit_extended_asm gcc_jit_extended_asm;
+
/* Acquire a JIT-compilation context. */
extern gcc_jit_context *
gcc_jit_context_acquire (void);
@@ -1504,7 +1511,7 @@ gcc_jit_context_new_rvalue_from_vector (gcc_jit_context *ctxt,
#define LIBGCCJIT_HAVE_gcc_jit_version
-/* Functions to retrive libgccjit version.
+/* Functions to retrieve libgccjit version.
Analogous to __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__ in C code.
These API entrypoints were added in LIBGCCJIT_ABI_13; you can test for their
@@ -1518,6 +1525,102 @@ gcc_jit_version_minor (void);
extern int
gcc_jit_version_patchlevel (void);
+/**********************************************************************
+ Asm support.
+ **********************************************************************/
+
+/* Functions for adding inline assembler code, analogous to GCC's
+ "extended asm" syntax.
+
+ See https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html
+
+ These API entrypoints were added in LIBGCCJIT_ABI_15; you can test for their
+ presence using
+ #ifdef LIBGCCJIT_HAVE_ASM_STATEMENTS
+*/
+
+#define LIBGCCJIT_HAVE_ASM_STATEMENTS
+
+/* Create a gcc_jit_extended_asm for an extended asm statement
+ with no control flow (i.e. without the goto qualifier).
+
+ The asm_template parameter corresponds to the AssemblerTemplate
+ within C's extended asm syntax. It must be non-NULL. */
+
+extern gcc_jit_extended_asm *
+gcc_jit_block_add_extended_asm (gcc_jit_block *block,
+ gcc_jit_location *loc,
+ const char *asm_template);
+
+/* Create a gcc_jit_extended_asm for an extended asm statement
+ that may perform jumps, and use it to terminate the given block.
+ This is equivalent to the "goto" qualifier in C's extended asm
+ syntax. */
+
+extern gcc_jit_extended_asm *
+gcc_jit_block_end_with_extended_asm_goto (gcc_jit_block *block,
+ gcc_jit_location *loc,
+ const char *asm_template,
+ int num_goto_blocks,
+ gcc_jit_block **goto_blocks,
+ gcc_jit_block *fallthrough_block);
+
+/* Upcasting from extended asm to object. */
+
+extern gcc_jit_object *
+gcc_jit_extended_asm_as_object (gcc_jit_extended_asm *ext_asm);
+
+/* Set whether the gcc_jit_extended_asm has side-effects, equivalent to
+ the "volatile" qualifier in C's extended asm syntax. */
+
+extern void
+gcc_jit_extended_asm_set_volatile_flag (gcc_jit_extended_asm *ext_asm,
+ int flag);
+
+/* Set the equivalent of the "inline" qualifier in C's extended asm
+ syntax. */
+
+extern void
+gcc_jit_extended_asm_set_inline_flag (gcc_jit_extended_asm *ext_asm,
+ int flag);
+
+/* Add an output operand to the extended asm statement.
+ "asm_symbolic_name" can be NULL.
+ "constraint" and "dest" must be non-NULL.
+ This function can't be called on an "asm goto" as such instructions
+ can't have outputs */
+
+extern void
+gcc_jit_extended_asm_add_output_operand (gcc_jit_extended_asm *ext_asm,
+ const char *asm_symbolic_name,
+ const char *constraint,
+ gcc_jit_lvalue *dest);
+
+/* Add an input operand to the extended asm statement.
+ "asm_symbolic_name" can be NULL.
+ "constraint" and "src" must be non-NULL. */
+
+extern void
+gcc_jit_extended_asm_add_input_operand (gcc_jit_extended_asm *ext_asm,
+ const char *asm_symbolic_name,
+ const char *constraint,
+ gcc_jit_rvalue *src);
+
+/* Add "victim" to the list of registers clobbered by the extended
+ asm statement. It must be non-NULL. */
+
+extern void
+gcc_jit_extended_asm_add_clobber (gcc_jit_extended_asm *ext_asm,
+ const char *victim);
+
+/* Add "asm_stmts", a set of top-level asm statements, analogous to
+ those created by GCC's "basic" asm syntax in C at file scope. */
+
+extern void
+gcc_jit_context_add_top_level_asm (gcc_jit_context *ctxt,
+ gcc_jit_location *loc,
+ const char *asm_stmts);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index a6e67e78..bcabe16 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -192,3 +192,16 @@ LIBGCCJIT_ABI_14 {
global:
gcc_jit_global_set_initializer;
} LIBGCCJIT_ABI_13;
+
+LIBGCCJIT_ABI_15 {
+ global:
+ gcc_jit_block_add_extended_asm;
+ gcc_jit_block_end_with_extended_asm_goto;
+ gcc_jit_extended_asm_as_object;
+ gcc_jit_extended_asm_set_volatile_flag;
+ gcc_jit_extended_asm_set_inline_flag;
+ gcc_jit_extended_asm_add_output_operand;
+ gcc_jit_extended_asm_add_input_operand;
+ gcc_jit_extended_asm_add_clobber;
+ gcc_jit_context_add_top_level_asm;
+} LIBGCCJIT_ABI_14;
diff --git a/gcc/json.cc b/gcc/json.cc
index 627741d..70775d1 100644
--- a/gcc/json.cc
+++ b/gcc/json.cc
@@ -70,7 +70,10 @@ object::print (pretty_printer *pp) const
pp_string (pp, ", ");
const char *key = const_cast <char *>((*it).first);
value *value = (*it).second;
- pp_printf (pp, "\"%s\": ", key); // FIXME: escaping?
+ pp_doublequote (pp);
+ pp_string (pp, key); // FIXME: escaping?
+ pp_doublequote (pp);
+ pp_string (pp, ": ");
value->print (pp);
}
pp_character (pp, '}');
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index a909915..2f66f5e 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -103,6 +103,10 @@ extern void lhd_finalize_early_debug (void);
#define LANG_HOOKS_INIT_OPTIONS_STRUCT hook_void_gcc_optionsp
#define LANG_HOOKS_INIT_OPTIONS lhd_init_options
#define LANG_HOOKS_INITIALIZE_DIAGNOSTICS lhd_initialize_diagnostics
+#define LANG_HOOKS_PREPROCESS_MAIN_FILE NULL
+#define LANG_HOOKS_PREPROCESS_OPTIONS NULL
+#define LANG_HOOKS_PREPROCESS_UNDEF NULL
+#define LANG_HOOKS_PREPROCESS_TOKEN NULL
#define LANG_HOOKS_REGISTER_DUMPS lhd_register_dumps
#define LANG_HOOKS_COMPLAIN_WRONG_LANG_P lhd_complain_wrong_lang_p
#define LANG_HOOKS_HANDLE_OPTION lhd_handle_option
@@ -317,6 +321,10 @@ extern void lhd_end_section (void);
LANG_HOOKS_INIT_OPTIONS_STRUCT, \
LANG_HOOKS_INIT_OPTIONS, \
LANG_HOOKS_INITIALIZE_DIAGNOSTICS, \
+ LANG_HOOKS_PREPROCESS_MAIN_FILE, \
+ LANG_HOOKS_PREPROCESS_OPTIONS, \
+ LANG_HOOKS_PREPROCESS_UNDEF, \
+ LANG_HOOKS_PREPROCESS_TOKEN, \
LANG_HOOKS_REGISTER_DUMPS, \
LANG_HOOKS_COMPLAIN_WRONG_LANG_P, \
LANG_HOOKS_HANDLE_OPTION, \
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index a35cf21..f12589e 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -356,6 +356,24 @@ struct lang_hooks
global diagnostic context structure. */
void (*initialize_diagnostics) (diagnostic_context *);
+ /* Beginning the main source file. */
+ void (*preprocess_main_file) (cpp_reader *, line_maps *,
+ const line_map_ordinary *);
+
+ /* Adjust libcpp options and callbacks. */
+ void (*preprocess_options) (cpp_reader *);
+
+ /* Undefining a macro. */
+ void (*preprocess_undef) (cpp_reader *, location_t, cpp_hashnode *);
+
+ /* Observer for preprocessing stream. */
+ uintptr_t (*preprocess_token) (cpp_reader *, const cpp_token *, uintptr_t);
+ /* Various flags it can return about the token. */
+ enum PT_flags
+ {
+ PT_begin_pragma = 1 << 0
+ };
+
/* Register language-specific dumps. */
void (*register_dumps) (gcc::dump_manager *);
diff --git a/gcc/loop-init.c b/gcc/loop-init.c
index 401e528..ac87daf 100644
--- a/gcc/loop-init.c
+++ b/gcc/loop-init.c
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-loop-niter.h"
#include "loop-unroll.h"
#include "tree-scalar-evolution.h"
+#include "tree-cfgcleanup.h"
/* Apply FLAGS to the loop state. */
@@ -133,13 +134,19 @@ loop_optimizer_init (unsigned flags)
/* Finalize loop structures. */
void
-loop_optimizer_finalize (struct function *fn)
+loop_optimizer_finalize (struct function *fn, bool clean_loop_closed_phi)
{
class loop *loop;
basic_block bb;
timevar_push (TV_LOOP_FINI);
+ if (clean_loop_closed_phi && loops_state_satisfies_p (fn, LOOP_CLOSED_SSA))
+ {
+ clean_up_loop_closed_phi (fn);
+ loops_state_clear (fn, LOOP_CLOSED_SSA);
+ }
+
if (loops_state_satisfies_p (fn, LOOPS_HAVE_RECORDED_EXITS))
release_recorded_exits (fn);
diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
index 37ae654..653e303 100644
--- a/gcc/loop-invariant.c
+++ b/gcc/loop-invariant.c
@@ -1099,6 +1099,10 @@ find_invariant_insn (rtx_insn *insn, bool always_reached, bool always_executed)
if (HAVE_cc0 && sets_cc0_p (insn))
return;
+ /* Jumps have control flow side-effects. */
+ if (JUMP_P (insn))
+ return;
+
set = single_set (insn);
if (!set)
return;
diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c
index d7b3d90..9f266e2 100644
--- a/gcc/loop-iv.c
+++ b/gcc/loop-iv.c
@@ -44,7 +44,7 @@ along with GCC; see the file COPYING3. If not see
iv_analyze_result (insn, def, iv): Stores to IV the description of the iv
corresponding to DEF, which is a register defined in INSN.
iv_analyze_expr (insn, mode, expr, iv): Stores to IV the description of iv
- corresponding to expression EXPR evaluated at INSN. All registers used bu
+ corresponding to expression EXPR evaluated at INSN. All registers used by
EXPR must also be used in INSN. MODE is the mode of EXPR.
*/
diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c
index 40e323c..b040f7f 100644
--- a/gcc/lra-assigns.c
+++ b/gcc/lra-assigns.c
@@ -1715,8 +1715,8 @@ find_reload_regno_insns (int regno, rtx_insn * &start, rtx_insn * &finish)
start_insn = lra_insn_recog_data[uid]->insn;
n++;
}
- /* For reload pseudo we should have at most 3 insns referring for it:
- input/output reload insns and the original insn. */
+ /* For reload pseudo we should have at most 3 insns referring for
+ it: input/output reload insns and the original insn. */
if (n > 3)
return false;
if (n > 1)
@@ -1792,7 +1792,8 @@ lra_split_hard_reg_for (void)
{
if (! find_reload_regno_insns (i, first, last))
continue;
- if (spill_hard_reg_in_range (i, rclass, first, last))
+ if (BLOCK_FOR_INSN (first) == BLOCK_FOR_INSN (last)
+ && spill_hard_reg_in_range (i, rclass, first, last))
{
bitmap_clear (&failed_reload_pseudos);
return true;
@@ -1817,16 +1818,10 @@ lra_split_hard_reg_for (void)
lra_asm_error_p = asm_p = true;
error_for_asm (insn,
"%<asm%> operand has impossible constraints");
- /* Avoid further trouble with this insn.
- For asm goto, instead of fixing up all the edges
- just clear the template and clear input operands
- (asm goto doesn't have any output operands). */
+ /* Avoid further trouble with this insn. */
if (JUMP_P (insn))
{
- rtx asm_op = extract_asm_operands (PATTERN (insn));
- ASM_OPERANDS_TEMPLATE (asm_op) = ggc_strdup ("");
- ASM_OPERANDS_INPUT_VEC (asm_op) = rtvec_alloc (0);
- ASM_OPERANDS_INPUT_CONSTRAINT_VEC (asm_op) = rtvec_alloc (0);
+ ira_nullify_asm_goto (insn);
lra_update_insn_regno_info (insn);
}
else
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index fbc47ba..80ca1e0 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -3954,10 +3954,10 @@ curr_insn_transform (bool check_only_p)
no_input_reloads_p = no_output_reloads_p = false;
goal_alt_number = -1;
change_p = sec_mem_p = false;
- /* JUMP_INSNs and CALL_INSNs are not allowed to have any output
- reloads; neither are insns that SET cc0. Insns that use CC0 are
- not allowed to have any input reloads. */
- if (JUMP_P (curr_insn) || CALL_P (curr_insn))
+ /* CALL_INSNs are not allowed to have any output reloads; neither
+ are insns that SET cc0. Insns that use CC0 are not allowed to
+ have any input reloads. */
+ if (CALL_P (curr_insn))
no_output_reloads_p = true;
if (HAVE_cc0 && reg_referenced_p (cc0_rtx, PATTERN (curr_insn)))
@@ -4104,9 +4104,18 @@ curr_insn_transform (bool check_only_p)
error_for_asm (curr_insn,
"inconsistent operand constraints in an %<asm%>");
lra_asm_error_p = true;
- /* Avoid further trouble with this insn. Don't generate use
- pattern here as we could use the insn SP offset. */
- lra_set_insn_deleted (curr_insn);
+ if (! JUMP_P (curr_insn))
+ {
+ /* Avoid further trouble with this insn. Don't generate use
+ pattern here as we could use the insn SP offset. */
+ lra_set_insn_deleted (curr_insn);
+ }
+ else
+ {
+ lra_invalidate_insn_data (curr_insn);
+ ira_nullify_asm_goto (curr_insn);
+ lra_update_insn_regno_info (curr_insn);
+ }
return true;
}
diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c
index 8082a5b..85c3664 100644
--- a/gcc/lra-spills.c
+++ b/gcc/lra-spills.c
@@ -788,6 +788,14 @@ lra_final_code_change (void)
{
rtx pat = PATTERN (insn);
+ if (GET_CODE (pat) == USE && XEXP (pat, 0) == const1_rtx)
+ {
+ /* Remove markers to eliminate critical edges for jump insn
+ output reloads (see code in ira.c::ira). */
+ lra_invalidate_insn_data (insn);
+ delete_insn (insn);
+ continue;
+ }
if (GET_CODE (pat) == CLOBBER && LRA_TEMP_CLOBBER_P (pat))
{
/* Remove clobbers temporarily created in LRA. We don't
diff --git a/gcc/lra.c b/gcc/lra.c
index 664f1b5..a79213e 100644
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -1852,8 +1852,6 @@ void
lra_process_new_insns (rtx_insn *insn, rtx_insn *before, rtx_insn *after,
const char *title)
{
- rtx_insn *last;
-
if (before == NULL_RTX && after == NULL_RTX)
return;
if (lra_dump_file != NULL)
@@ -1864,12 +1862,6 @@ lra_process_new_insns (rtx_insn *insn, rtx_insn *before, rtx_insn *after,
fprintf (lra_dump_file," %s before:\n", title);
dump_rtl_slim (lra_dump_file, before, NULL, -1, 0);
}
- if (after != NULL_RTX)
- {
- fprintf (lra_dump_file, " %s after:\n", title);
- dump_rtl_slim (lra_dump_file, after, NULL, -1, 0);
- }
- fprintf (lra_dump_file, "\n");
}
if (before != NULL_RTX)
{
@@ -1883,12 +1875,69 @@ lra_process_new_insns (rtx_insn *insn, rtx_insn *before, rtx_insn *after,
{
if (cfun->can_throw_non_call_exceptions)
copy_reg_eh_region_note_forward (insn, after, NULL);
- for (last = after; NEXT_INSN (last) != NULL_RTX; last = NEXT_INSN (last))
- ;
- emit_insn_after (after, insn);
- push_insns (last, insn);
- setup_sp_offset (after, last);
+ if (! JUMP_P (insn))
+ {
+ rtx_insn *last;
+
+ if (lra_dump_file != NULL)
+ {
+ fprintf (lra_dump_file, " %s after:\n", title);
+ dump_rtl_slim (lra_dump_file, after, NULL, -1, 0);
+ }
+ for (last = after;
+ NEXT_INSN (last) != NULL_RTX;
+ last = NEXT_INSN (last))
+ ;
+ emit_insn_after (after, insn);
+ push_insns (last, insn);
+ setup_sp_offset (after, last);
+ }
+ else
+ {
+ /* Put output reload insns on successor BBs: */
+ edge_iterator ei;
+ edge e;
+
+ FOR_EACH_EDGE (e, ei, BLOCK_FOR_INSN (insn)->succs)
+ if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
+ {
+ /* We already made the edge no-critical in ira.c::ira */
+ lra_assert (!EDGE_CRITICAL_P (e));
+ rtx_insn *curr, *tmp = BB_HEAD (e->dest);
+ if (LABEL_P (tmp))
+ tmp = NEXT_INSN (tmp);
+ if (NOTE_INSN_BASIC_BLOCK_P (tmp))
+ tmp = NEXT_INSN (tmp);
+ /* Do not put reload insns if it is the last BB
+ without actual insns. */
+ if (tmp == NULL)
+ continue;
+ start_sequence ();
+ for (curr = after; curr != NULL_RTX; curr = NEXT_INSN (curr))
+ emit_insn (copy_insn (PATTERN (curr)));
+ rtx_insn *copy = get_insns (), *last = get_last_insn ();
+ end_sequence ();
+ if (lra_dump_file != NULL)
+ {
+ fprintf (lra_dump_file, " %s after in bb%d:\n", title,
+ e->dest->index);
+ dump_rtl_slim (lra_dump_file, copy, NULL, -1, 0);
+ }
+ /* Use the right emit func for setting up BB_END/BB_HEAD: */
+ if (BB_END (e->dest) == PREV_INSN (tmp))
+ emit_insn_after_noloc (copy, PREV_INSN (tmp), e->dest);
+ else
+ emit_insn_before_noloc (copy, tmp, e->dest);
+ push_insns (last, PREV_INSN (copy));
+ setup_sp_offset (copy, last);
+ /* We can ignore BB live info here as it and reg notes
+ will be updated before the next assignment
+ sub-pass. */
+ }
+ }
}
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file, "\n");
if (cfun->can_throw_non_call_exceptions)
{
rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 64037f7..a20d64b 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -1017,7 +1017,6 @@ input_cfg (class lto_input_block *ib, class data_in *data_in,
int index;
init_empty_tree_cfg_for_function (fn);
- init_ssa_operands (fn);
profile_status_for_fn (fn) = streamer_read_enum (ib, profile_status_d,
PROFILE_LAST);
@@ -1144,7 +1143,9 @@ input_ssa_names (class lto_input_block *ib, class data_in *data_in,
unsigned int i, size;
size = streamer_read_uhwi (ib);
- init_ssanames (fn, size);
+ init_tree_ssa (fn, size);
+ cfun->gimple_df->in_ssa_p = true;
+ init_ssa_operands (fn);
i = streamer_read_uhwi (ib);
while (i)
@@ -1384,9 +1385,6 @@ input_function (tree fn_decl, class data_in *data_in,
push_struct_function (fn_decl);
fn = DECL_STRUCT_FUNCTION (fn_decl);
- init_tree_ssa (fn);
- /* We input IL in SSA form. */
- cfun->gimple_df->in_ssa_p = true;
gimple_register_cfg_hooks ();
diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
index fe10f4f..68ccb15 100644
--- a/gcc/lto-wrapper.c
+++ b/gcc/lto-wrapper.c
@@ -323,8 +323,9 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
if (cf_protection_option
&& cf_protection_option->value == CF_CHECK)
fatal_error (input_location,
- "option -fcf-protection with mismatching values"
+ "option %qs with mismatching values"
" (%s, %s)",
+ "-fcf-protection",
(*decoded_options)[j].arg, foption->arg);
else
{
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index d336074..25c9063 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,31 @@
+2020-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/97911
+ * Make-lang.in (lto1.serial, lto2.serial): Change from goals to
+ variables.
+ (.PHONY): Drop lto1.serial, lto2.serial, lto1.prev and lto2.prev.
+ ($(LTO_EXE)): Depend on $(lto1.serial) rather than lto1.serial.
+ ($(LTO_DUMP_EXE)): Depend on $(lto2.serial) rather than lto2.serial.
+
+2020-11-18 Jerry Clcanny <a837940593@gmail.com>
+
+ * lto-symtab.c (lto_symtab_merge_symbols): Fix typos in comment.
+
+2020-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ * Make-lang.in (lto, lto1.serial, lto2.serial): New goals.
+ (.PHONY): Add lto lto1.serial lto1.prev lto2.serial lto2.prev.
+ (lto.all.cross, lto.start.encap): Remove dependencies.
+ ($(LTO_EXE)): Depend on lto1.prev. Call LINK_PROGRESS.
+ ($(LTO_DUMP_EXE)): Depend on lto2.prev. Call LINK_PROGRESS.
+
+2020-11-17 Jan Hubicka <jh@suse.cz>
+
+ PR bootstrap/97857
+ * lto-common.c (gimple_register_canonical_type_1): Only
+ register types with TYPE_CXX_ODR_P flag; sanity check that no
+ conflict happens at ltrans time.
+
2020-11-06 Nathan Sidwell <nathan@acm.org>
* lto-symtab.c (lto_symtab_merge_decls_1): Rename
diff --git a/gcc/lto/Make-lang.in b/gcc/lto/Make-lang.in
index 0b73f9e..6e5fbac 100644
--- a/gcc/lto/Make-lang.in
+++ b/gcc/lto/Make-lang.in
@@ -41,10 +41,16 @@ lto_dump_OBJS = $(LTO_DUMP_OBJS)
# Rules
+lto: $(LTO_EXE) $(LTO_DUMP_EXE)
+lto1.serial = $(LTO_EXE)
+lto2.serial = $(LTO_DUMP_EXE)
+
+.PHONY: lto
+
# These hooks are used by the main GCC Makefile. Consult that
# Makefile for documentation.
-lto.all.cross: $(LTO_EXE) $(LTO_DUMP_EXE)
-lto.start.encap: $(LTO_EXE) $(LTO_DUMP_EXE)
+lto.all.cross:
+lto.start.encap:
lto.rest.encap:
lto.tags:
lto.install-common: installdirs
@@ -84,13 +90,17 @@ lto.stagefeedback:
# Use strict warnings for this front end.
lto-warn = $(STRICT_WARN)
-$(LTO_EXE): $(LTO_OBJS) $(BACKEND) $(LIBDEPS)
+$(LTO_EXE): $(LTO_OBJS) $(BACKEND) $(LIBDEPS) $(lto1.prev)
+ @$(call LINK_PROGRESS,$(INDEX.lto1),start)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(LTO_OBJS) $(BACKEND) $(BACKENDLIBS) $(LIBS)
+ @$(call LINK_PROGRESS,$(INDEX.lto1),end)
-$(LTO_DUMP_EXE): $(LTO_DUMP_OBJS) $(BACKEND) $(LIBDEPS)
+$(LTO_DUMP_EXE): $(LTO_DUMP_OBJS) $(BACKEND) $(LIBDEPS) $(lto2.prev)
+ @$(call LINK_PROGRESS,$(INDEX.lto2),start)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(LTO_DUMP_OBJS) $(BACKEND) $(BACKENDLIBS) $(LIBS)
+ @$(call LINK_PROGRESS,$(INDEX.lto2),end)
lto/lto-dump.o: $(LTO_OBJS)
diff --git a/gcc/lto/lto-common.c b/gcc/lto/lto-common.c
index 6944c46..0a3033c 100644
--- a/gcc/lto/lto-common.c
+++ b/gcc/lto/lto-common.c
@@ -415,8 +415,8 @@ gimple_register_canonical_type_1 (tree t, hashval_t hash)
that we can use to lookup structurally equivalent non-ODR type.
In case we decide to treat type as unique ODR type we recompute hash based
on name and let TBAA machinery know about our decision. */
- if (RECORD_OR_UNION_TYPE_P (t)
- && odr_type_p (t) && !odr_type_violation_reported_p (t))
+ if (RECORD_OR_UNION_TYPE_P (t) && odr_type_p (t)
+ && TYPE_CXX_ODR_P (t) && !odr_type_violation_reported_p (t))
{
/* Anonymous namespace types never conflict with non-C++ types. */
if (type_with_linkage_p (t) && type_in_anonymous_namespace_p (t))
@@ -434,6 +434,7 @@ gimple_register_canonical_type_1 (tree t, hashval_t hash)
if (slot && !TYPE_CXX_ODR_P (*(tree *)slot))
{
tree nonodr = *(tree *)slot;
+ gcc_checking_assert (!flag_ltrans);
if (symtab->dump_file)
{
fprintf (symtab->dump_file,
diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
index 0058d98..80457c3 100644
--- a/gcc/lto/lto-symtab.c
+++ b/gcc/lto/lto-symtab.c
@@ -985,7 +985,7 @@ lto_symtab_merge_symbols (void)
/* Do the actual merging.
At this point we invalidate hash translating decls into symtab nodes
because after removing one of duplicate decls the hash is not correcly
- updated to the ohter dupliate. */
+ updated to the other duplicate. */
FOR_EACH_SYMBOL (node)
if (lto_symtab_symbol_p (node)
&& node->next_sharing_asm_name
diff --git a/gcc/machmode.def b/gcc/machmode.def
index e4c9b4b..6f8c685 100644
--- a/gcc/machmode.def
+++ b/gcc/machmode.def
@@ -153,6 +153,9 @@ along with GCC; see the file COPYING3. If not see
the element at index 0 occupying the lsb of the first byte in
memory. Only the lowest bit of each element is significant.
+ OPAQUE_MODE (NAME, BYTESIZE)
+ Create an opaque mode called NAME that is BYTESIZE bytes wide.
+
COMPLEX_MODES (CLASS);
For all modes presently declared in class CLASS, construct
corresponding complex modes. Modes smaller than one byte
diff --git a/gcc/machmode.h b/gcc/machmode.h
index fbeefc2..bb3a5c6 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -225,6 +225,10 @@ extern const unsigned char mode_class[NUM_MACHINE_MODES];
(SIGNED_FIXED_POINT_MODE_P (MODE) \
|| UNSIGNED_FIXED_POINT_MODE_P (MODE))
+/* Nonzero if MODE is opaque. */
+#define OPAQUE_MODE_P(MODE) \
+ (GET_MODE_CLASS (MODE) == MODE_OPAQUE)
+
/* Nonzero if CLASS modes can be widened. */
#define CLASS_HAS_WIDER_MODES_P(CLASS) \
(CLASS == MODE_INT \
diff --git a/gcc/match.pd b/gcc/match.pd
index 349eab6..68201ff 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -650,9 +650,36 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(for div (trunc_div ceil_div floor_div round_div exact_div)
(simplify
(div (mult:c @0 @1) @1)
- (if (ANY_INTEGRAL_TYPE_P (type)
- && TYPE_OVERFLOW_UNDEFINED (type))
- @0)))
+ (if (ANY_INTEGRAL_TYPE_P (type))
+ (if (TYPE_OVERFLOW_UNDEFINED (type))
+ @0
+#if GIMPLE
+ (with
+ {
+ bool overflowed = true;
+ wide_int wmin0, wmax0, wmin1, wmax1;
+ if (INTEGRAL_TYPE_P (type)
+ && get_range_info (@0, &wmin0, &wmax0) == VR_RANGE
+ && get_range_info (@1, &wmin1, &wmax1) == VR_RANGE)
+ {
+ /* If the multiplication can't overflow/wrap around, then
+ it can be optimized too. */
+ wi::overflow_type min_ovf, max_ovf;
+ wi::mul (wmin0, wmin1, TYPE_SIGN (type), &min_ovf);
+ wi::mul (wmax0, wmax1, TYPE_SIGN (type), &max_ovf);
+ if (min_ovf == wi::OVF_NONE && max_ovf == wi::OVF_NONE)
+ {
+ wi::mul (wmin0, wmax1, TYPE_SIGN (type), &min_ovf);
+ wi::mul (wmax0, wmin1, TYPE_SIGN (type), &max_ovf);
+ if (min_ovf == wi::OVF_NONE && max_ovf == wi::OVF_NONE)
+ overflowed = false;
+ }
+ }
+ }
+ (if (!overflowed)
+ @0))
+#endif
+ ))))
(for op (negate abs)
/* Simplify cos(-x) and cos(|x|) -> cos(x). Similarly for cosh. */
@@ -901,6 +928,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(bit_not (bit_ior:cs (bit_not @0) @1))
(bit_and @0 (bit_not @1)))
+/* (a ^ b) & ((b ^ c) ^ a) --> (a ^ b) & ~c */
+(simplify
+ (bit_and:c (bit_xor:c@3 @0 @1) (bit_xor:cs (bit_xor:cs @1 @2) @0))
+ (bit_and @3 (bit_not @2)))
+
+/* (a ^ b) | ((b ^ c) ^ a) --> (a ^ b) | c */
+(simplify
+ (bit_ior:c (bit_xor:c@3 @0 @1) (bit_xor:c (bit_xor:c @1 @2) @0))
+ (bit_ior @3 @2))
+
/* Simplify (~X & Y) to X ^ Y if we know that (X & ~Y) is 0. */
#if GIMPLE
(simplify
@@ -1423,6 +1460,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(bitop:c (rbitop:c (bit_not @0) @1) @0)
(bitop @0 @1)))
+/* ((x | y) & z) | x -> (z & y) | x */
+(simplify
+ (bit_ior:c (bit_and:cs (bit_ior:cs @0 @1) @2) @0)
+ (bit_ior (bit_and @2 @1) @0))
+
/* (x | CST1) & CST2 -> (x & CST2) | (CST1 & CST2) */
(simplify
(bit_and (bit_ior @0 CONSTANT_CLASS_P@1) CONSTANT_CLASS_P@2)
@@ -2841,6 +2883,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(cmp (minmax @0 INTEGER_CST@1) INTEGER_CST@2)
(comb (cmp @0 @2) (cmp @1 @2))))
+/* X <= MAX(X, Y) -> true
+ X > MAX(X, Y) -> false
+ X >= MIN(X, Y) -> true
+ X < MIN(X, Y) -> false */
+(for minmax (min min max max )
+ cmp (ge lt le gt )
+ (simplify
+ (cmp @0 (minmax:c @0 @1))
+ { constant_boolean_node (cmp == GE_EXPR || cmp == LE_EXPR, type); } ))
+
/* Undo fancy way of writing max/min or other ?: expressions,
like a - ((a - b) & -(a < b)), in this case into (a < b) ? b : a.
People normally use ?: and that is what we actually try to optimize. */
@@ -2890,8 +2942,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* Optimize -1 >> x for arithmetic right shifts. */
(simplify
(rshift integer_all_onesp@0 @1)
- (if (!TYPE_UNSIGNED (type)
- && tree_expr_nonnegative_p (@1))
+ (if (!TYPE_UNSIGNED (type))
@0))
/* Optimize (x >> c) << c into x & (-1<<c). */
@@ -3110,7 +3161,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(shift (convert?:s (bit_op:s @0 INTEGER_CST@2)) INTEGER_CST@1)
(if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
(with { tree mask = int_const_binop (shift, fold_convert (type, @2), @1); }
- (bit_op (shift (convert @0) @1) { mask; }))))))
+ (if (mask)
+ (bit_op (shift (convert @0) @1) { mask; })))))))
/* ~(~X >> Y) -> X >> Y (for arithmetic shift). */
(simplify
@@ -4922,6 +4974,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
{ constant_boolean_node (cmp == ORDERED_EXPR || cmp == LTGT_EXPR
? false : true, type); })))
+/* Fold UNORDERED if either operand must be NaN, or neither can be. */
+(simplify
+ (unordered @0 @1)
+ (switch
+ (if (tree_expr_nan_p (@0) || tree_expr_nan_p (@1))
+ { constant_boolean_node (true, type); })
+ (if (!tree_expr_maybe_nan_p (@0) && !tree_expr_maybe_nan_p (@1))
+ { constant_boolean_node (false, type); })))
+
+/* Fold ORDERED if either operand must be NaN, or neither can be. */
+(simplify
+ (ordered @0 @1)
+ (switch
+ (if (tree_expr_nan_p (@0) || tree_expr_nan_p (@1))
+ { constant_boolean_node (false, type); })
+ (if (!tree_expr_maybe_nan_p (@0) && !tree_expr_maybe_nan_p (@1))
+ { constant_boolean_node (true, type); })))
+
/* bool_var != 0 becomes bool_var. */
(simplify
(ne @0 integer_zerop)
@@ -5053,7 +5123,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* Simplify sqrt(x) * sqrt(x) -> x. */
(simplify
(mult (SQRT_ALL@1 @0) @1)
- (if (!HONOR_SNANS (type))
+ (if (!tree_expr_maybe_signaling_nan_p (@0))
@0))
(for op (plus minus)
diff --git a/gcc/mode-classes.def b/gcc/mode-classes.def
index f181def0..b78a715 100644
--- a/gcc/mode-classes.def
+++ b/gcc/mode-classes.def
@@ -36,4 +36,5 @@ along with GCC; see the file COPYING3. If not see
DEF_MODE_CLASS (MODE_VECTOR_UFRACT), /* SIMD vectors */ \
DEF_MODE_CLASS (MODE_VECTOR_ACCUM), /* SIMD vectors */ \
DEF_MODE_CLASS (MODE_VECTOR_UACCUM), /* SIMD vectors */ \
- DEF_MODE_CLASS (MODE_VECTOR_FLOAT)
+ DEF_MODE_CLASS (MODE_VECTOR_FLOAT), \
+ DEF_MODE_CLASS (MODE_OPAQUE) /* opaque modes */
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index 5bc41c6..3e83a4f 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -1,3 +1,34 @@
+2020-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/97911
+ * Make-lang.in (objc.serial): Change from goal to a variable.
+ (.PHONY): Drop objc.serial and objc.prev.
+ (cc1obj$(exeext)): Depend on $(objc.serial) rather than objc.serial.
+
+2020-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ * Make-lang.in (objc.serial): New goal.
+ (.PHONY): Add objc.serial objc.prev.
+ (cc1obj$(exeext)): Depend on objc.prev. Call LINK_PROGRESS.
+
+2020-11-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR objc/90707
+ * objc-act.c (objc_prop_attr_kind_for_rid): Handle nullability.
+ (objc_add_property_declaration): Handle nullability attributes.
+ Check that these are applicable to the property type.
+ * objc-act.h (enum objc_property_nullability): New.
+
+2020-11-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR objc/77404
+ * objc-act.c (objc_start_class_interface): Accept the location
+ of the class name, use it in existing diagnostic.
+ (start_class): Accept obj_root_class type attributes. Warn when
+ the interface for an implementation does not contain a super
+ class (unless the diagnostic is suppressed by the the command
+ line flag or the objc_root_class type attribute).
+
2020-11-08 Iain Sandoe <iain@sandoe.co.uk>
* objc-act.c (objc_prop_attr_kind_for_rid): Handle class
diff --git a/gcc/objc/Make-lang.in b/gcc/objc/Make-lang.in
index add1355..2edf0a9 100644
--- a/gcc/objc/Make-lang.in
+++ b/gcc/objc/Make-lang.in
@@ -38,6 +38,7 @@
#
# Define the names for selecting Objective-C in LANGUAGES.
objc: cc1obj$(exeext)
+objc.serial = cc1obj$(exeext)
# Tell GNU make to ignore these if they exist.
.PHONY: objc
@@ -62,10 +63,13 @@ cc1obj-checksum.c : build/genchecksum$(build_exeext) checksum-options \
$(BACKEND) $(LIBDEPS) checksum-options > cc1obj-checksum.c.tmp && \
$(srcdir)/../move-if-change cc1obj-checksum.c.tmp cc1obj-checksum.c
-cc1obj$(exeext): $(OBJC_OBJS) $(C_AND_OBJC_OBJS) cc1obj-checksum.o $(BACKEND) $(LIBDEPS)
+cc1obj$(exeext): $(OBJC_OBJS) $(C_AND_OBJC_OBJS) cc1obj-checksum.o $(BACKEND) \
+ $(LIBDEPS) $(objc.prev)
+ @$(call LINK_PROGRESS,$(INDEX.objc),start)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(OBJC_OBJS) $(C_AND_OBJC_OBJS) cc1obj-checksum.o \
$(BACKEND) $(LIBS) $(BACKENDLIBS)
+ @$(call LINK_PROGRESS,$(INDEX.objc),end)
objc.srcextra:
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index b9ed32d..2700bbe 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -571,11 +571,11 @@ lookup_protocol_in_reflist (tree rproto_list, tree lproto)
}
void
-objc_start_class_interface (tree klass, tree super_class,
+objc_start_class_interface (tree klass, location_t name_loc, tree super_class,
tree protos, tree attributes)
{
if (flag_objc1_only && attributes)
- error_at (input_location, "class attributes are not available in Objective-C 1.0");
+ error_at (name_loc, "class attributes are not available in Objective-C 1.0");
objc_interface_context
= objc_ivar_context
@@ -825,6 +825,11 @@ objc_prop_attr_kind_for_rid (enum rid prop_rid)
case RID_PROPATOMIC: return OBJC_PROPERTY_ATTR_ATOMIC;
case RID_NONATOMIC: return OBJC_PROPERTY_ATTR_NONATOMIC;
+ case RID_NULL_UNSPECIFIED:return OBJC_PROPERTY_ATTR_NULL_UNSPECIFIED;
+ case RID_NULLABLE: return OBJC_PROPERTY_ATTR_NULLABLE;
+ case RID_NONNULL: return OBJC_PROPERTY_ATTR_NONNULL;
+ case RID_NULL_RESETTABLE: return OBJC_PROPERTY_ATTR_NULL_RESETTABLE;
+
case RID_CLASS: return OBJC_PROPERTY_ATTR_CLASS;
}
}
@@ -995,6 +1000,27 @@ objc_add_property_declaration (location_t location, tree decl,
property_nonatomic = attrs[OBJC_PROPATTR_GROUP_CLASS]->prop_kind
== OBJC_PROPERTY_ATTR_CLASS;
+ /* Nullability specifications for the property. */
+ enum objc_property_nullability property_nullability
+ = OBJC_PROPERTY_NULL_UNSET;
+ if (attrs[OBJC_PROPATTR_GROUP_NULLABLE])
+ {
+ if (attrs[OBJC_PROPATTR_GROUP_NULLABLE]->prop_kind
+ == OBJC_PROPERTY_ATTR_NULL_UNSPECIFIED)
+ property_nullability = OBJC_PROPERTY_NULL_UNSPECIFIED;
+ else if (attrs[OBJC_PROPATTR_GROUP_NULLABLE]->prop_kind
+ == OBJC_PROPERTY_ATTR_NULLABLE)
+ property_nullability = OBJC_PROPERTY_NULLABLE;
+ else if (attrs[OBJC_PROPATTR_GROUP_NULLABLE]->prop_kind
+ == OBJC_PROPERTY_ATTR_NONNULL)
+ property_nullability = OBJC_PROPERTY_NONNULL;
+ else if (attrs[OBJC_PROPATTR_GROUP_NULLABLE]->prop_kind
+ == OBJC_PROPERTY_ATTR_NULL_RESETTABLE)
+ property_nullability = OBJC_PROPERTY_NULL_RESETTABLE;
+ else
+ gcc_unreachable ();
+ }
+
/* TODO: Check that the property type is an Objective-C object or a
"POD". */
@@ -1272,7 +1298,8 @@ objc_add_property_declaration (location_t location, tree decl,
tree property_decl = make_node (PROPERTY_DECL);
/* Copy the basic information from the original decl. */
- TREE_TYPE (property_decl) = TREE_TYPE (decl);
+ tree p_type = TREE_TYPE (decl);
+ TREE_TYPE (property_decl) = p_type;
DECL_SOURCE_LOCATION (property_decl) = DECL_SOURCE_LOCATION (decl);
TREE_DEPRECATED (property_decl) = TREE_DEPRECATED (decl);
@@ -1287,6 +1314,28 @@ objc_add_property_declaration (location_t location, tree decl,
PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
PROPERTY_DYNAMIC (property_decl) = 0;
+ /* FIXME: We seem to drop any existing DECL_ATTRIBUTES on the floor. */
+ if (property_nullability != OBJC_PROPERTY_NULL_UNSET)
+ {
+ if (p_type && !POINTER_TYPE_P (p_type))
+ error_at (decl_loc, "nullability specifier %qE cannot be applied to"
+ " non-pointer type %qT",
+ attrs[OBJC_PROPATTR_GROUP_NULLABLE]->name, p_type);
+ else if (p_type && POINTER_TYPE_P (p_type) && TREE_TYPE (p_type)
+ && POINTER_TYPE_P (TREE_TYPE (p_type)))
+ error_at (decl_loc, "nullability specifier %qE cannot be applied to"
+ " multi-level pointer type %qT",
+ attrs[OBJC_PROPATTR_GROUP_NULLABLE]->name, p_type);
+ else
+ {
+ tree attr_name = get_identifier ("objc_nullability");
+ tree attr_value = build_int_cst (unsigned_type_node,
+ (unsigned)property_nullability);
+ tree nulla = build_tree_list (attr_name, attr_value);
+ DECL_ATTRIBUTES (property_decl) = nulla;
+ }
+ }
+
/* Remember the fact that the property was found in the @optional
section in a @protocol, or not. */
if (objc_method_optional_flag)
@@ -7014,6 +7063,12 @@ start_class (enum tree_code code, tree class_name, tree super_name,
CLASS_SUPER_NAME (objc_implementation_context)
= CLASS_SUPER_NAME (implementation_template);
}
+
+ if (!CLASS_SUPER_NAME (objc_implementation_context)
+ && !lookup_attribute ("objc_root_class",
+ TYPE_ATTRIBUTES (implementation_template)))
+ warning (OPT_Wobjc_root_class, "class %qE defined without"
+ " specifying a base class", class_name);
break;
case CLASS_INTERFACE_TYPE:
@@ -7044,6 +7099,8 @@ start_class (enum tree_code code, tree class_name, tree super_name,
TREE_DEPRECATED (klass) = 1;
else if (is_attribute_p ("objc_exception", name))
CLASS_HAS_EXCEPTION_ATTR (klass) = 1;
+ else if (is_attribute_p ("objc_root_class", name))
+ ;
else if (is_attribute_p ("visibility", name))
;
else
diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h
index 5b0433f..2fe409db 100644
--- a/gcc/objc/objc-act.h
+++ b/gcc/objc/objc-act.h
@@ -141,6 +141,16 @@ enum objc_property_assign_semantics {
#define PROPERTY_CLASS(DECL) \
DECL_LANG_FLAG_6 (PROPERTY_DECL_CHECK (DECL))
+/* PROPERTY_NULLABILITY attributes added to the decl attributes.
+ effectively, __attribute__((objc_nullability(kind))), */
+enum objc_property_nullability {
+ OBJC_PROPERTY_NULL_UNSPECIFIED = 0,
+ OBJC_PROPERTY_NULLABLE,
+ OBJC_PROPERTY_NONNULL,
+ OBJC_PROPERTY_NULL_RESETTABLE,
+ OBJC_PROPERTY_NULL_UNSET
+};
+
/* PROPERTY_REF. A PROPERTY_REF represents an 'object.property'
expression. It is normally used for property access, but when
the Objective-C 2.0 "dot-syntax" (object.component) is used
diff --git a/gcc/objcp/ChangeLog b/gcc/objcp/ChangeLog
index 64a0deb..0b257a9 100644
--- a/gcc/objcp/ChangeLog
+++ b/gcc/objcp/ChangeLog
@@ -1,3 +1,17 @@
+2020-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/97911
+ * Make-lang.in (obj-c++.serial): Change from goal to a variable.
+ (.PHONY): Drop obj-c++.serial and obj-c++.prev.
+ (cc1objplus$(exeext)): Depend on $(obj-c++.serial) rather than
+ obj-c++.serial.
+
+2020-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ * Make-lang.in (obj-c++.serial): New goal.
+ (.PHONY): Add obj-c++.serial obj-c++.prev.
+ (cc1objplus$(exeext)): Depend on obj-c++.prev. Call LINK_PROGRESS.
+
2020-09-25 Nathan Sidwell <nathan@acm.org>
* objcp-decl.c (objcp_start_struct): Use TAG_how not tag_scope.
diff --git a/gcc/objcp/Make-lang.in b/gcc/objcp/Make-lang.in
index 5bfef24..2e3e37e 100644
--- a/gcc/objcp/Make-lang.in
+++ b/gcc/objcp/Make-lang.in
@@ -39,6 +39,7 @@
#
# Define the names for selecting Objective-C++ in LANGUAGES.
obj-c++: cc1objplus$(exeext)
+obj-c++.serial = cc1objplus$(exeext)
# Tell GNU make to ignore these if they exist.
.PHONY: obj-c++
@@ -66,9 +67,12 @@ cc1objplus-checksum.c : build/genchecksum$(build_exeext) checksum-options \
$(srcdir)/../move-if-change cc1objplus-checksum.c.tmp \
cc1objplus-checksum.c
-cc1objplus$(exeext): $(OBJCXX_OBJS) cc1objplus-checksum.o $(BACKEND) $(LIBDEPS)
+cc1objplus$(exeext): $(OBJCXX_OBJS) cc1objplus-checksum.o $(BACKEND) \
+ $(LIBDEPS) $(obj-c++.prev)
+ @$(call LINK_PROGRESS,$(INDEX.obj-c++),start)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(OBJCXX_OBJS) cc1objplus-checksum.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
+ @$(call LINK_PROGRESS,$(INDEX.obj-c++),end)
# Objective C++ language specific files.
diff --git a/gcc/omp-builtins.def b/gcc/omp-builtins.def
index f461d60..f9b78ed 100644
--- a/gcc/omp-builtins.def
+++ b/gcc/omp-builtins.def
@@ -47,6 +47,8 @@ DEF_GOACC_BUILTIN (BUILT_IN_GOACC_UPDATE, "GOACC_update",
DEF_GOACC_BUILTIN (BUILT_IN_GOACC_WAIT, "GOACC_wait",
BT_FN_VOID_INT_INT_VAR,
ATTR_NOTHROW_LIST)
+DEF_GOACC_BUILTIN (BUILT_IN_GOACC_DECLARE, "GOACC_declare",
+ BT_FN_VOID_INT_SIZE_PTR_PTR_PTR, ATTR_NOTHROW_LIST)
DEF_GOACC_BUILTIN_COMPILER (BUILT_IN_ACC_ON_DEVICE, "acc_on_device",
BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
@@ -444,5 +446,8 @@ DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TASK_REDUCTION_REMAP,
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_WORKSHARE_TASK_REDUCTION_UNREGISTER,
"GOMP_workshare_task_reduction_unregister",
BT_FN_VOID_BOOL, ATTR_NOTHROW_LEAF_LIST)
-DEF_GOACC_BUILTIN (BUILT_IN_GOACC_DECLARE, "GOACC_declare",
- BT_FN_VOID_INT_SIZE_PTR_PTR_PTR, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ALLOC,
+ "GOMP_alloc", BT_FN_PTR_SIZE_SIZE_PTRMODE,
+ ATTR_ALLOC_WARN_UNUSED_RESULT_SIZE_2_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_FREE,
+ "GOMP_free", BT_FN_VOID_PTR_PTRMODE, ATTR_NOTHROW_LEAF_LIST)
diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c
index 6583c88..4a6c44d 100644
--- a/gcc/omp-expand.c
+++ b/gcc/omp-expand.c
@@ -1510,8 +1510,8 @@ struct oacc_collapse
static tree
expand_oacc_collapse_init (const struct omp_for_data *fd,
gimple_stmt_iterator *gsi,
- oacc_collapse *counts, tree bound_type,
- location_t loc)
+ oacc_collapse *counts, tree diff_type,
+ tree bound_type, location_t loc)
{
tree tiling = fd->tiling;
tree total = build_int_cst (bound_type, 1);
@@ -1528,17 +1528,12 @@ expand_oacc_collapse_init (const struct omp_for_data *fd,
const omp_for_data_loop *loop = &fd->loops[ix];
tree iter_type = TREE_TYPE (loop->v);
- tree diff_type = iter_type;
tree plus_type = iter_type;
gcc_assert (loop->cond_code == fd->loop.cond_code);
if (POINTER_TYPE_P (iter_type))
plus_type = sizetype;
- if (POINTER_TYPE_P (diff_type) || TYPE_UNSIGNED (diff_type))
- diff_type = signed_type_for (diff_type);
- if (TYPE_PRECISION (diff_type) < TYPE_PRECISION (integer_type_node))
- diff_type = integer_type_node;
if (tiling)
{
@@ -1626,7 +1621,8 @@ expand_oacc_collapse_init (const struct omp_for_data *fd,
static void
expand_oacc_collapse_vars (const struct omp_for_data *fd, bool inner,
gimple_stmt_iterator *gsi,
- const oacc_collapse *counts, tree ivar)
+ const oacc_collapse *counts, tree ivar,
+ tree diff_type)
{
tree ivar_type = TREE_TYPE (ivar);
@@ -1638,7 +1634,6 @@ expand_oacc_collapse_vars (const struct omp_for_data *fd, bool inner,
const oacc_collapse *collapse = &counts[ix];
tree v = inner ? loop->v : collapse->outer;
tree iter_type = TREE_TYPE (v);
- tree diff_type = TREE_TYPE (collapse->step);
tree plus_type = iter_type;
enum tree_code plus_code = PLUS_EXPR;
tree expr;
@@ -1660,7 +1655,7 @@ expand_oacc_collapse_vars (const struct omp_for_data *fd, bool inner,
}
expr = fold_build2 (MULT_EXPR, diff_type, fold_convert (diff_type, expr),
- collapse->step);
+ fold_convert (diff_type, collapse->step));
expr = fold_build2 (plus_code, iter_type,
inner ? collapse->outer : collapse->base,
fold_convert (plus_type, expr));
@@ -2514,7 +2509,8 @@ expand_omp_for_init_vars (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
&& (TREE_CODE (fd->loop.n2) == INTEGER_CST
|| fd->first_inner_iterations)
&& (optab_handler (sqrt_optab, TYPE_MODE (double_type_node))
- != CODE_FOR_nothing))
+ != CODE_FOR_nothing)
+ && !integer_zerop (fd->loop.n2))
{
tree outer_n1 = fd->adjn1 ? fd->adjn1 : fd->loops[i - 1].n1;
tree itype = TREE_TYPE (fd->loops[i].v);
@@ -4255,8 +4251,7 @@ expand_omp_for_generic (struct omp_region *region,
: POINTER_PLUS_EXPR, TREE_TYPE (t), v, a);
t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
false, GSI_CONTINUE_LINKING);
- assign_stmt = gimple_build_assign (dest, t);
- gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
+ expand_omp_build_assign (&gsi, dest, t, true);
}
if (fd->collapse > 1)
expand_omp_for_init_vars (fd, &gsi, counts, NULL, inner_stmt, startvar);
@@ -5250,8 +5245,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
: POINTER_PLUS_EXPR, TREE_TYPE (t), t, a);
t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
false, GSI_CONTINUE_LINKING);
- assign_stmt = gimple_build_assign (dest, t);
- gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
+ expand_omp_build_assign (&gsi, dest, t, true);
}
if (fd->collapse > 1)
{
@@ -5974,8 +5968,7 @@ expand_omp_for_static_chunk (struct omp_region *region,
: POINTER_PLUS_EXPR, TREE_TYPE (t), v, a);
t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
false, GSI_CONTINUE_LINKING);
- assign_stmt = gimple_build_assign (dest, t);
- gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
+ expand_omp_build_assign (&gsi, dest, t, true);
}
if (fd->collapse > 1)
expand_omp_for_init_vars (fd, &gsi, counts, NULL, inner_stmt, startvar);
@@ -7415,6 +7408,21 @@ expand_omp_taskloop_for_inner (struct omp_region *region,
static void
expand_oacc_for (struct omp_region *region, struct omp_for_data *fd)
{
+ bool is_oacc_kernels_parallelized
+ = (lookup_attribute ("oacc kernels parallelized",
+ DECL_ATTRIBUTES (current_function_decl)) != NULL);
+ {
+ bool is_oacc_kernels
+ = (lookup_attribute ("oacc kernels",
+ DECL_ATTRIBUTES (current_function_decl)) != NULL);
+ if (is_oacc_kernels_parallelized)
+ gcc_checking_assert (is_oacc_kernels);
+ }
+ gcc_assert (gimple_in_ssa_p (cfun) == is_oacc_kernels_parallelized);
+ /* In the following, some of the 'gimple_in_ssa_p (cfun)' conditionals are
+ for SSA specifics, and some are for 'parloops' OpenACC
+ 'kernels'-parallelized specifics. */
+
tree v = fd->loop.v;
enum tree_code cond_code = fd->loop.cond_code;
enum tree_code plus_code = PLUS_EXPR;
@@ -7436,6 +7444,12 @@ expand_oacc_for (struct omp_region *region, struct omp_for_data *fd)
plus_code = POINTER_PLUS_EXPR;
plus_type = sizetype;
}
+ for (int ix = fd->collapse; ix--;)
+ {
+ tree diff_type2 = TREE_TYPE (fd->loops[ix].step);
+ if (TYPE_PRECISION (diff_type) < TYPE_PRECISION (diff_type2))
+ diff_type = diff_type2;
+ }
if (POINTER_TYPE_P (diff_type) || TYPE_UNSIGNED (diff_type))
diff_type = signed_type_for (diff_type);
if (TYPE_PRECISION (diff_type) < TYPE_PRECISION (integer_type_node))
@@ -7519,7 +7533,7 @@ expand_oacc_for (struct omp_region *region, struct omp_for_data *fd)
{
gcc_assert (!gimple_in_ssa_p (cfun) && up);
counts = XALLOCAVEC (struct oacc_collapse, fd->collapse);
- tree total = expand_oacc_collapse_init (fd, &gsi, counts,
+ tree total = expand_oacc_collapse_init (fd, &gsi, counts, diff_type,
TREE_TYPE (fd->loop.n2), loc);
if (SSA_VAR_P (fd->loop.n2))
@@ -7681,7 +7695,7 @@ expand_oacc_for (struct omp_region *region, struct omp_for_data *fd)
gsi_insert_before (&gsi, ass, GSI_SAME_STMT);
if (fd->collapse > 1 || fd->tiling)
- expand_oacc_collapse_vars (fd, false, &gsi, counts, v);
+ expand_oacc_collapse_vars (fd, false, &gsi, counts, v, diff_type);
if (fd->tiling)
{
@@ -7751,7 +7765,8 @@ expand_oacc_for (struct omp_region *region, struct omp_for_data *fd)
/* Initialize the user's loop vars. */
gsi = gsi_start_bb (elem_body_bb);
- expand_oacc_collapse_vars (fd, true, &gsi, counts, e_offset);
+ expand_oacc_collapse_vars (fd, true, &gsi, counts, e_offset,
+ diff_type);
}
}
@@ -9260,11 +9275,14 @@ expand_omp_target (struct omp_region *region)
case GF_OMP_TARGET_KIND_OACC_UPDATE:
case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
case GF_OMP_TARGET_KIND_OACC_DECLARE:
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
data_region = false;
break;
case GF_OMP_TARGET_KIND_DATA:
case GF_OMP_TARGET_KIND_OACC_DATA:
case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
+ case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
data_region = true;
break;
default:
@@ -9287,27 +9305,43 @@ expand_omp_target (struct omp_region *region)
entry_bb = region->entry;
exit_bb = region->exit;
+ if (target_kind == GF_OMP_TARGET_KIND_OACC_KERNELS)
+ mark_loops_in_oacc_kernels_region (region->entry, region->exit);
+
+ /* Going on, all OpenACC compute constructs are mapped to
+ 'BUILT_IN_GOACC_PARALLEL', and get their compute regions outlined.
+ To distinguish between them, we attach attributes. */
switch (target_kind)
{
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL:
+ DECL_ATTRIBUTES (child_fn)
+ = tree_cons (get_identifier ("oacc parallel"),
+ NULL_TREE, DECL_ATTRIBUTES (child_fn));
+ break;
case GF_OMP_TARGET_KIND_OACC_KERNELS:
- mark_loops_in_oacc_kernels_region (region->entry, region->exit);
-
- /* Further down, all OpenACC compute constructs will be mapped to
- BUILT_IN_GOACC_PARALLEL, and to distinguish between them, there
- is an "oacc kernels" attribute set for OpenACC kernels. */
DECL_ATTRIBUTES (child_fn)
= tree_cons (get_identifier ("oacc kernels"),
NULL_TREE, DECL_ATTRIBUTES (child_fn));
break;
case GF_OMP_TARGET_KIND_OACC_SERIAL:
- /* Further down, all OpenACC compute constructs will be mapped to
- BUILT_IN_GOACC_PARALLEL, and to distinguish between them, there
- is an "oacc serial" attribute set for OpenACC serial. */
DECL_ATTRIBUTES (child_fn)
= tree_cons (get_identifier ("oacc serial"),
NULL_TREE, DECL_ATTRIBUTES (child_fn));
break;
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
+ DECL_ATTRIBUTES (child_fn)
+ = tree_cons (get_identifier ("oacc parallel_kernels_parallelized"),
+ NULL_TREE, DECL_ATTRIBUTES (child_fn));
+ break;
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
+ DECL_ATTRIBUTES (child_fn)
+ = tree_cons (get_identifier ("oacc parallel_kernels_gang_single"),
+ NULL_TREE, DECL_ATTRIBUTES (child_fn));
+ break;
default:
+ /* Make sure we don't miss any. */
+ gcc_checking_assert (!(is_gimple_omp_oacc (entry_stmt)
+ && is_gimple_omp_offloaded (entry_stmt)));
break;
}
@@ -9514,10 +9548,13 @@ expand_omp_target (struct omp_region *region)
case GF_OMP_TARGET_KIND_OACC_PARALLEL:
case GF_OMP_TARGET_KIND_OACC_KERNELS:
case GF_OMP_TARGET_KIND_OACC_SERIAL:
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
start_ix = BUILT_IN_GOACC_PARALLEL;
break;
case GF_OMP_TARGET_KIND_OACC_DATA:
case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
+ case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
start_ix = BUILT_IN_GOACC_DATA_START;
break;
case GF_OMP_TARGET_KIND_OACC_UPDATE:
@@ -9990,6 +10027,9 @@ build_omp_regions_1 (basic_block bb, struct omp_region *parent,
case GF_OMP_TARGET_KIND_OACC_SERIAL:
case GF_OMP_TARGET_KIND_OACC_DATA:
case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
+ case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
break;
case GF_OMP_TARGET_KIND_UPDATE:
case GF_OMP_TARGET_KIND_ENTER_DATA:
@@ -10244,6 +10284,9 @@ omp_make_gimple_edges (basic_block bb, struct omp_region **region,
case GF_OMP_TARGET_KIND_OACC_SERIAL:
case GF_OMP_TARGET_KIND_OACC_DATA:
case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
+ case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
break;
case GF_OMP_TARGET_KIND_UPDATE:
case GF_OMP_TARGET_KIND_ENTER_DATA:
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 447d7db..09a8cbd 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -126,6 +126,10 @@ struct omp_context
corresponding tracking loop iteration variables. */
hash_map<tree, tree> *lastprivate_conditional_map;
+ /* And a hash map from the allocate variables to their corresponding
+ allocators. */
+ hash_map<tree, tree> *allocate_map;
+
/* A tree_list of the reduction clauses in this context. This is
only used for checking the consistency of OpenACC reduction
clauses in scan_omp_for and is not guaranteed to contain a valid
@@ -189,8 +193,8 @@ static tree scan_omp_1_op (tree *, int *, void *);
*handled_ops_p = false; \
break;
-/* Return true if CTX corresponds to an OpenACC 'parallel' or 'serial'
- region. */
+/* Return whether CTX represents an OpenACC 'parallel' or 'serial' construct.
+ (This doesn't include OpenACC 'kernels' decomposed parts.) */
static bool
is_oacc_parallel_or_serial (omp_context *ctx)
@@ -203,7 +207,8 @@ is_oacc_parallel_or_serial (omp_context *ctx)
== GF_OMP_TARGET_KIND_OACC_SERIAL)));
}
-/* Return true if CTX corresponds to an oacc kernels region. */
+/* Return whether CTX represents an OpenACC 'kernels' construct.
+ (This doesn't include OpenACC 'kernels' decomposed parts.) */
static bool
is_oacc_kernels (omp_context *ctx)
@@ -214,6 +219,21 @@ is_oacc_kernels (omp_context *ctx)
== GF_OMP_TARGET_KIND_OACC_KERNELS));
}
+/* Return whether CTX represents an OpenACC 'kernels' decomposed part. */
+
+static bool
+is_oacc_kernels_decomposed_part (omp_context *ctx)
+{
+ enum gimple_code outer_type = gimple_code (ctx->stmt);
+ return ((outer_type == GIMPLE_OMP_TARGET)
+ && ((gimple_omp_target_kind (ctx->stmt)
+ == GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED)
+ || (gimple_omp_target_kind (ctx->stmt)
+ == GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE)
+ || (gimple_omp_target_kind (ctx->stmt)
+ == GF_OMP_TARGET_KIND_OACC_DATA_KERNELS)));
+}
+
/* Return true if STMT corresponds to an OpenMP target region. */
static bool
is_omp_target (gimple *stmt)
@@ -783,7 +803,7 @@ install_var_field (tree var, bool by_ref, int mask, omp_context *ctx)
}
else if (by_ref)
type = build_pointer_type (type);
- else if ((mask & 3) == 1 && omp_is_reference (var))
+ else if ((mask & (32 | 3)) == 1 && omp_is_reference (var))
type = TREE_TYPE (type);
field = build_decl (DECL_SOURCE_LOCATION (var),
@@ -1043,6 +1063,7 @@ delete_omp_context (splay_tree_value value)
}
delete ctx->lastprivate_conditional_map;
+ delete ctx->allocate_map;
XDELETE (ctx);
}
@@ -1115,6 +1136,20 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
bool scan_array_reductions = false;
for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE
+ && (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
+ /* omp_default_mem_alloc is 1 */
+ || !integer_onep (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))))
+ {
+ if (ctx->allocate_map == NULL)
+ ctx->allocate_map = new hash_map<tree, tree>;
+ ctx->allocate_map->put (OMP_CLAUSE_DECL (c),
+ OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
+ ? OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
+ : integer_zero_node);
+ }
+
+ for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
{
bool by_ref;
@@ -1130,6 +1165,8 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE_SHARED:
decl = OMP_CLAUSE_DECL (c);
+ if (ctx->allocate_map && ctx->allocate_map->get (decl))
+ ctx->allocate_map->remove (decl);
/* Ignore shared directives in teams construct inside of
target construct. */
if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS
@@ -1171,13 +1208,32 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
goto do_private;
case OMP_CLAUSE_REDUCTION:
- if (is_oacc_parallel_or_serial (ctx) || is_oacc_kernels (ctx))
- ctx->local_reduction_clauses
- = tree_cons (NULL, c, ctx->local_reduction_clauses);
+ /* Collect 'reduction' clauses on OpenACC compute construct. */
+ if (is_gimple_omp_oacc (ctx->stmt)
+ && is_gimple_omp_offloaded (ctx->stmt))
+ {
+ /* No 'reduction' clauses on OpenACC 'kernels'. */
+ gcc_checking_assert (!is_oacc_kernels (ctx));
+ /* Likewise, on OpenACC 'kernels' decomposed parts. */
+ gcc_checking_assert (!is_oacc_kernels_decomposed_part (ctx));
+
+ ctx->local_reduction_clauses
+ = tree_cons (NULL, c, ctx->local_reduction_clauses);
+ }
/* FALLTHRU */
case OMP_CLAUSE_IN_REDUCTION:
decl = OMP_CLAUSE_DECL (c);
+ if (ctx->allocate_map
+ && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
+ && (OMP_CLAUSE_REDUCTION_INSCAN (c)
+ || OMP_CLAUSE_REDUCTION_TASK (c)))
+ || is_task_ctx (ctx)))
+ {
+ /* For now. */
+ if (ctx->allocate_map->get (decl))
+ ctx->allocate_map->remove (decl);
+ }
if (TREE_CODE (decl) == MEM_REF)
{
tree t = TREE_OPERAND (decl, 0);
@@ -1261,7 +1317,16 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
if (is_variable_sized (decl))
{
if (is_task_ctx (ctx))
- install_var_field (decl, false, 1, ctx);
+ {
+ if (ctx->allocate_map
+ && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
+ {
+ /* For now. */
+ if (ctx->allocate_map->get (decl))
+ ctx->allocate_map->remove (decl);
+ }
+ install_var_field (decl, false, 1, ctx);
+ }
break;
}
else if (is_taskreg_ctx (ctx))
@@ -1273,7 +1338,11 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
if (is_task_ctx (ctx)
&& (global || by_ref || omp_is_reference (decl)))
{
- install_var_field (decl, false, 1, ctx);
+ if (ctx->allocate_map
+ && ctx->allocate_map->get (decl))
+ install_var_field (decl, by_ref, 32 | 1, ctx);
+ else
+ install_var_field (decl, false, 1, ctx);
if (!global)
install_var_field (decl, by_ref, 2, ctx);
}
@@ -2377,7 +2446,9 @@ enclosing_target_ctx (omp_context *ctx)
return ctx;
}
-/* Return true if ctx is part of an oacc kernels region. */
+/* Return whether CTX's parent compute construct is an OpenACC 'kernels'
+ construct.
+ (This doesn't include OpenACC 'kernels' decomposed parts.) */
static bool
ctx_in_oacc_kernels_region (omp_context *ctx)
@@ -2393,7 +2464,8 @@ ctx_in_oacc_kernels_region (omp_context *ctx)
return false;
}
-/* Check the parallelism clauses inside a kernels regions.
+/* Check the parallelism clauses inside a OpenACC 'kernels' region.
+ (This doesn't include OpenACC 'kernels' decomposed parts.)
Until kernels handling moves to use the same loop indirection
scheme as parallel, we need to do this checking early. */
@@ -2471,7 +2543,7 @@ scan_omp_for (gomp_for *stmt, omp_context *outer_ctx)
{
omp_context *tgt = enclosing_target_ctx (outer_ctx);
- if (!tgt || is_oacc_parallel_or_serial (tgt))
+ if (!(tgt && is_oacc_kernels (tgt)))
for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
{
tree c_op0;
@@ -2495,6 +2567,10 @@ scan_omp_for (gomp_for *stmt, omp_context *outer_ctx)
if (c_op0)
{
+ /* By construction, this is impossible for OpenACC 'kernels'
+ decomposed parts. */
+ gcc_assert (!(tgt && is_oacc_kernels_decomposed_part (tgt)));
+
error_at (OMP_CLAUSE_LOCATION (c),
"argument not permitted on %qs clause",
omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
@@ -2937,7 +3013,8 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
{
error_at (gimple_location (stmt),
"%<ordered simd threads%> must be closely "
- "nested inside of %<for simd%> region");
+ "nested inside of %<%s simd%> region",
+ lang_GNU_Fortran () ? "do" : "for");
return false;
}
return true;
@@ -3031,6 +3108,8 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
case GF_OMP_TARGET_KIND_OACC_PARALLEL:
case GF_OMP_TARGET_KIND_OACC_KERNELS:
case GF_OMP_TARGET_KIND_OACC_SERIAL:
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
ok = true;
break;
@@ -3487,6 +3566,11 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
case GF_OMP_TARGET_KIND_OACC_DECLARE: stmt_name = "declare"; break;
case GF_OMP_TARGET_KIND_OACC_HOST_DATA: stmt_name = "host_data";
break;
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
+ case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
+ /* OpenACC 'kernels' decomposed parts. */
+ stmt_name = "kernels"; break;
default: gcc_unreachable ();
}
switch (gimple_omp_target_kind (ctx->stmt))
@@ -3502,6 +3586,11 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
case GF_OMP_TARGET_KIND_OACC_DATA: ctx_stmt_name = "data"; break;
case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
ctx_stmt_name = "host_data"; break;
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
+ case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
+ /* OpenACC 'kernels' decomposed parts. */
+ ctx_stmt_name = "kernels"; break;
default: gcc_unreachable ();
}
@@ -4357,6 +4446,79 @@ task_reduction_read (gimple_seq *ilist, tree tskred_temp, tree type,
return v;
}
+/* Lower early initialization of privatized variable NEW_VAR
+ if it needs an allocator (has allocate clause). */
+
+static bool
+lower_private_allocate (tree var, tree new_var, tree &allocator,
+ tree &allocate_ptr, gimple_seq *ilist,
+ omp_context *ctx, bool is_ref, tree size)
+{
+ if (allocator)
+ return false;
+ gcc_assert (allocate_ptr == NULL_TREE);
+ if (ctx->allocate_map
+ && (DECL_P (new_var) || (TYPE_P (new_var) && size)))
+ if (tree *allocatorp = ctx->allocate_map->get (var))
+ allocator = *allocatorp;
+ if (allocator == NULL_TREE)
+ return false;
+ if (!is_ref && omp_is_reference (var))
+ {
+ allocator = NULL_TREE;
+ return false;
+ }
+
+ if (TREE_CODE (allocator) != INTEGER_CST)
+ allocator = build_outer_var_ref (allocator, ctx);
+ allocator = fold_convert (pointer_sized_int_node, allocator);
+ if (TREE_CODE (allocator) != INTEGER_CST)
+ {
+ tree var = create_tmp_var (TREE_TYPE (allocator));
+ gimplify_assign (var, allocator, ilist);
+ allocator = var;
+ }
+
+ tree ptr_type, align, sz = size;
+ if (TYPE_P (new_var))
+ {
+ ptr_type = build_pointer_type (new_var);
+ align = build_int_cst (size_type_node, TYPE_ALIGN_UNIT (new_var));
+ }
+ else if (is_ref)
+ {
+ ptr_type = build_pointer_type (TREE_TYPE (TREE_TYPE (new_var)));
+ align = build_int_cst (size_type_node,
+ TYPE_ALIGN_UNIT (TREE_TYPE (ptr_type)));
+ }
+ else
+ {
+ ptr_type = build_pointer_type (TREE_TYPE (new_var));
+ align = build_int_cst (size_type_node, DECL_ALIGN_UNIT (new_var));
+ if (sz == NULL_TREE)
+ sz = fold_convert (size_type_node, DECL_SIZE_UNIT (new_var));
+ }
+ if (TREE_CODE (sz) != INTEGER_CST)
+ {
+ tree szvar = create_tmp_var (size_type_node);
+ gimplify_assign (szvar, sz, ilist);
+ sz = szvar;
+ }
+ allocate_ptr = create_tmp_var (ptr_type);
+ tree a = builtin_decl_explicit (BUILT_IN_GOMP_ALLOC);
+ gimple *g = gimple_build_call (a, 3, align, sz, allocator);
+ gimple_call_set_lhs (g, allocate_ptr);
+ gimple_seq_add_stmt (ilist, g);
+ if (!is_ref)
+ {
+ tree x = build_simple_mem_ref (allocate_ptr);
+ TREE_THIS_NOTRAP (x) = 1;
+ SET_DECL_VALUE_EXPR (new_var, x);
+ DECL_HAS_VALUE_EXPR_P (new_var) = 1;
+ }
+ return true;
+}
+
/* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
from the receiver (aka child) side and initializers for REFERENCE_TYPE
private variables. Initialization statements go in ILIST, while calls
@@ -4522,6 +4684,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
bool task_reduction_p = false;
bool task_reduction_needs_orig_p = false;
tree cond = NULL_TREE;
+ tree allocator, allocate_ptr;
switch (c_kind)
{
@@ -4658,6 +4821,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
if (task_reduction_p != (pass >= 2))
continue;
+ allocator = NULL_TREE;
+ allocate_ptr = NULL_TREE;
new_var = var = OMP_CLAUSE_DECL (c);
if ((c_kind == OMP_CLAUSE_REDUCTION
|| c_kind == OMP_CLAUSE_IN_REDUCTION)
@@ -4766,7 +4931,23 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
tree type = TREE_TYPE (d);
gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
+ tree sz = v;
const char *name = get_name (orig_var);
+ if (pass != 3 && !TREE_CONSTANT (v))
+ {
+ tree t = maybe_lookup_decl (v, ctx);
+ if (t)
+ v = t;
+ else
+ v = maybe_lookup_decl_in_outer_ctx (v, ctx);
+ gimplify_expr (&v, ilist, NULL, is_gimple_val, fb_rvalue);
+ t = fold_build2_loc (clause_loc, PLUS_EXPR,
+ TREE_TYPE (v), v,
+ build_int_cst (TREE_TYPE (v), 1));
+ sz = fold_build2_loc (clause_loc, MULT_EXPR,
+ TREE_TYPE (v), t,
+ TYPE_SIZE_UNIT (TREE_TYPE (type)));
+ }
if (pass == 3)
{
tree xv = create_tmp_var (ptr_type_node);
@@ -4824,6 +5005,13 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
gimplify_assign (cond, x, ilist);
x = xv;
}
+ else if (lower_private_allocate (var, type, allocator,
+ allocate_ptr, ilist, ctx,
+ true,
+ TREE_CONSTANT (v)
+ ? TYPE_SIZE_UNIT (type)
+ : sz))
+ x = allocate_ptr;
else if (TREE_CONSTANT (v))
{
x = create_tmp_var_raw (type, name);
@@ -4835,20 +5023,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
{
tree atmp
= builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
- tree t = maybe_lookup_decl (v, ctx);
- if (t)
- v = t;
- else
- v = maybe_lookup_decl_in_outer_ctx (v, ctx);
- gimplify_expr (&v, ilist, NULL, is_gimple_val, fb_rvalue);
- t = fold_build2_loc (clause_loc, PLUS_EXPR,
- TREE_TYPE (v), v,
- build_int_cst (TREE_TYPE (v), 1));
- t = fold_build2_loc (clause_loc, MULT_EXPR,
- TREE_TYPE (v), t,
- TYPE_SIZE_UNIT (TREE_TYPE (type)));
tree al = size_int (TYPE_ALIGN (TREE_TYPE (type)));
- x = build_call_expr_loc (clause_loc, atmp, 2, t, al);
+ x = build_call_expr_loc (clause_loc, atmp, 2, sz, al);
}
tree ptype = build_pointer_type (TREE_TYPE (type));
@@ -5110,6 +5286,12 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
gimple_seq_add_stmt (dlist, g);
gimple_seq_add_stmt (dlist, gimple_build_label (end2));
}
+ if (allocator)
+ {
+ tree f = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
+ g = gimple_build_call (f, 2, allocate_ptr, allocator);
+ gimple_seq_add_stmt (dlist, g);
+ }
continue;
}
else if (pass == 2)
@@ -5194,8 +5376,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
{
- gcall *stmt;
- tree tmp, atmp;
+ tree tmp;
ptr = DECL_VALUE_EXPR (new_var);
gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
@@ -5203,16 +5384,25 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
gcc_assert (DECL_P (ptr));
x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
- /* void *tmp = __builtin_alloca */
- atmp = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
- stmt = gimple_build_call (atmp, 2, x,
- size_int (DECL_ALIGN (var)));
- cfun->calls_alloca = 1;
- tmp = create_tmp_var_raw (ptr_type_node);
- gimple_add_tmp_var (tmp);
- gimple_call_set_lhs (stmt, tmp);
-
- gimple_seq_add_stmt (ilist, stmt);
+ if (lower_private_allocate (var, new_var, allocator,
+ allocate_ptr, ilist, ctx,
+ false, x))
+ tmp = allocate_ptr;
+ else
+ {
+ /* void *tmp = __builtin_alloca */
+ tree atmp
+ = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
+ gcall *stmt
+ = gimple_build_call (atmp, 2, x,
+ size_int (DECL_ALIGN (var)));
+ cfun->calls_alloca = 1;
+ tmp = create_tmp_var_raw (ptr_type_node);
+ gimple_add_tmp_var (tmp);
+ gimple_call_set_lhs (stmt, tmp);
+
+ gimple_seq_add_stmt (ilist, stmt);
+ }
x = fold_convert_loc (clause_loc, TREE_TYPE (ptr), tmp);
gimplify_assign (ptr, x, ilist);
@@ -5234,8 +5424,23 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
if (c_kind == OMP_CLAUSE_FIRSTPRIVATE && is_task_ctx (ctx))
{
x = build_receiver_ref (var, false, ctx);
- x = build_fold_addr_expr_loc (clause_loc, x);
+ if (ctx->allocate_map)
+ if (tree *allocatep = ctx->allocate_map->get (var))
+ {
+ allocator = *allocatep;
+ if (TREE_CODE (allocator) != INTEGER_CST)
+ allocator = build_outer_var_ref (allocator, ctx);
+ allocator = fold_convert (pointer_sized_int_node,
+ allocator);
+ allocate_ptr = unshare_expr (x);
+ }
+ if (allocator == NULL_TREE)
+ x = build_fold_addr_expr_loc (clause_loc, x);
}
+ else if (lower_private_allocate (var, new_var, allocator,
+ allocate_ptr,
+ ilist, ctx, true, x))
+ x = allocate_ptr;
else if (TREE_CONSTANT (x))
{
/* For reduction in SIMD loop, defer adding the
@@ -5348,6 +5553,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
tree nx;
bool copy_ctor;
copy_ctor = false;
+ lower_private_allocate (var, new_var, allocator, allocate_ptr,
+ ilist, ctx, false, NULL_TREE);
nx = unshare_expr (new_var);
if (is_simd
&& OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
@@ -5493,6 +5700,25 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
x = lang_hooks.decls.omp_clause_dtor (c, new_var);
if (x)
gimplify_and_add (x, dlist);
+ if (allocator)
+ {
+ if (!is_gimple_val (allocator))
+ {
+ tree avar = create_tmp_var (TREE_TYPE (allocator));
+ gimplify_assign (avar, allocator, dlist);
+ allocator = avar;
+ }
+ if (!is_gimple_val (allocate_ptr))
+ {
+ tree apvar = create_tmp_var (TREE_TYPE (allocate_ptr));
+ gimplify_assign (apvar, allocate_ptr, dlist);
+ allocate_ptr = apvar;
+ }
+ tree f = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
+ gimple *g
+ = gimple_build_call (f, 2, allocate_ptr, allocator);
+ gimple_seq_add_stmt (dlist, g);
+ }
break;
case OMP_CLAUSE_LINEAR:
@@ -5516,6 +5742,18 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
|| use_pointer_for_field (var, NULL))
{
x = build_receiver_ref (var, false, ctx);
+ if (ctx->allocate_map)
+ if (tree *allocatep = ctx->allocate_map->get (var))
+ {
+ allocator = *allocatep;
+ if (TREE_CODE (allocator) != INTEGER_CST)
+ allocator = build_outer_var_ref (allocator, ctx);
+ allocator = fold_convert (pointer_sized_int_node,
+ allocator);
+ allocate_ptr = unshare_expr (x);
+ x = build_simple_mem_ref (x);
+ TREE_THIS_NOTRAP (x) = 1;
+ }
SET_DECL_VALUE_EXPR (new_var, x);
DECL_HAS_VALUE_EXPR_P (new_var) = 1;
goto do_dtor;
@@ -5534,6 +5772,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
goto do_dtor;
}
do_firstprivate:
+ lower_private_allocate (var, new_var, allocator, allocate_ptr,
+ ilist, ctx, false, NULL_TREE);
x = build_outer_var_ref (var, ctx);
if (is_simd)
{
@@ -5721,6 +5961,9 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
else
{
+ lower_private_allocate (var, new_var, allocator,
+ allocate_ptr, ilist, ctx, false,
+ NULL_TREE);
x = build_outer_var_ref (var, ctx);
if (omp_is_reference (var)
@@ -6117,6 +6360,9 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
else
{
+ lower_private_allocate (var, new_var, allocator,
+ allocate_ptr, ilist, ctx,
+ false, NULL_TREE);
if (omp_is_reference (var) && is_simd)
handle_simd_reference (clause_loc, new_vard, ilist);
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
@@ -6131,6 +6377,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
ref = build_outer_var_ref (var, ctx);
gimplify_assign (ref, x, dlist);
}
+ if (allocator)
+ goto do_dtor;
}
}
break;
@@ -6767,6 +7015,11 @@ lower_oacc_reductions (location_t loc, tree clauses, tree level, bool inner,
for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
{
+ /* No 'reduction' clauses on OpenACC 'kernels'. */
+ gcc_checking_assert (!is_oacc_kernels (ctx));
+ /* Likewise, on OpenACC 'kernels' decomposed parts. */
+ gcc_checking_assert (!is_oacc_kernels_decomposed_part (ctx));
+
tree orig = OMP_CLAUSE_DECL (c);
tree var = maybe_lookup_decl (orig, ctx);
tree ref_to_res = NULL_TREE;
@@ -6804,10 +7057,11 @@ lower_oacc_reductions (location_t loc, tree clauses, tree level, bool inner,
break;
case GIMPLE_OMP_TARGET:
- if ((gimple_omp_target_kind (probe->stmt)
- != GF_OMP_TARGET_KIND_OACC_PARALLEL)
- && (gimple_omp_target_kind (probe->stmt)
- != GF_OMP_TARGET_KIND_OACC_SERIAL))
+ /* No 'reduction' clauses inside OpenACC 'kernels'
+ regions. */
+ gcc_checking_assert (!is_oacc_kernels (probe));
+
+ if (!is_gimple_omp_offloaded (probe->stmt))
goto do_lookup;
cls = gimple_omp_target_clauses (probe->stmt);
@@ -7487,7 +7741,10 @@ lower_send_shared_vars (gimple_seq *ilist, gimple_seq *olist, omp_context *ctx)
continue;
nvar = maybe_lookup_decl (ovar, ctx);
- if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
+ if (!nvar
+ || !DECL_HAS_VALUE_EXPR_P (nvar)
+ || (ctx->allocate_map
+ && ctx->allocate_map->get (ovar)))
continue;
/* If CTX is a nested parallel directive. Find the immediately
@@ -7611,11 +7868,29 @@ lower_oacc_head_mark (location_t loc, tree ddvar, tree clauses,
tag |= OLF_GANG_STATIC;
}
- /* In a parallel region, loops are implicitly INDEPENDENT. */
omp_context *tgt = enclosing_target_ctx (ctx);
if (!tgt || is_oacc_parallel_or_serial (tgt))
+ ;
+ else if (is_oacc_kernels (tgt))
+ /* Not using this loops handling inside OpenACC 'kernels' regions. */
+ gcc_unreachable ();
+ else if (is_oacc_kernels_decomposed_part (tgt))
+ ;
+ else
+ gcc_unreachable ();
+
+ /* In a parallel region, loops are implicitly INDEPENDENT. */
+ if (!tgt || is_oacc_parallel_or_serial (tgt))
tag |= OLF_INDEPENDENT;
+ /* Loops inside OpenACC 'kernels' decomposed parts' regions are expected to
+ have an explicit 'seq' or 'independent' clause, and no 'auto' clause. */
+ if (tgt && is_oacc_kernels_decomposed_part (tgt))
+ {
+ gcc_assert (tag & (OLF_SEQ | OLF_INDEPENDENT));
+ gcc_assert (!(tag & OLF_AUTO));
+ }
+
if (tag & OLF_TILE)
/* Tiling could use all 3 levels. */
levels = 3;
@@ -11065,7 +11340,35 @@ create_task_copyfn (gomp_task *task_stmt, omp_context *ctx)
if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
else
- t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
+ {
+ if (ctx->allocate_map)
+ if (tree *allocatorp = ctx->allocate_map->get (decl))
+ {
+ tree allocator = *allocatorp;
+ if (TREE_CODE (allocator) != INTEGER_CST)
+ {
+ n = splay_tree_lookup (ctx->sfield_map,
+ (splay_tree_key) allocator);
+ allocator = (tree) n->value;
+ if (tcctx.cb.decl_map)
+ allocator = *tcctx.cb.decl_map->get (allocator);
+ tree a = build_simple_mem_ref_loc (loc, sarg);
+ allocator = omp_build_component_ref (a, allocator);
+ }
+ allocator = fold_convert (pointer_sized_int_node, allocator);
+ tree a = builtin_decl_explicit (BUILT_IN_GOMP_ALLOC);
+ tree align = build_int_cst (size_type_node,
+ DECL_ALIGN_UNIT (decl));
+ tree sz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (dst)));
+ tree ptr = build_call_expr_loc (loc, a, 3, align, sz,
+ allocator);
+ ptr = fold_convert (TREE_TYPE (dst), ptr);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, ptr);
+ append_to_statement_list (t, &list);
+ dst = build_simple_mem_ref_loc (loc, dst);
+ }
+ t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
+ }
append_to_statement_list (t, &list);
break;
case OMP_CLAUSE_PRIVATE:
@@ -11463,11 +11766,14 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
case GF_OMP_TARGET_KIND_OACC_UPDATE:
case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
case GF_OMP_TARGET_KIND_OACC_DECLARE:
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
+ case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
data_region = false;
break;
case GF_OMP_TARGET_KIND_DATA:
case GF_OMP_TARGET_KIND_OACC_DATA:
case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
+ case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
data_region = true;
break;
default:
@@ -11648,8 +11954,16 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
break;
case OMP_CLAUSE_FIRSTPRIVATE:
- if (is_oacc_parallel_or_serial (ctx))
- goto oacc_firstprivate;
+ gcc_checking_assert (offloaded);
+ if (is_gimple_omp_oacc (ctx->stmt))
+ {
+ /* No 'firstprivate' clauses on OpenACC 'kernels'. */
+ gcc_checking_assert (!is_oacc_kernels (ctx));
+ /* Likewise, on OpenACC 'kernels' decomposed parts. */
+ gcc_checking_assert (!is_oacc_kernels_decomposed_part (ctx));
+
+ goto oacc_firstprivate;
+ }
map_cnt++;
var = OMP_CLAUSE_DECL (c);
if (!omp_is_reference (var)
@@ -11674,8 +11988,16 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
break;
case OMP_CLAUSE_PRIVATE:
+ gcc_checking_assert (offloaded);
if (is_gimple_omp_oacc (ctx->stmt))
- break;
+ {
+ /* No 'private' clauses on OpenACC 'kernels'. */
+ gcc_checking_assert (!is_oacc_kernels (ctx));
+ /* Likewise, on OpenACC 'kernels' decomposed parts. */
+ gcc_checking_assert (!is_oacc_kernels_decomposed_part (ctx));
+
+ break;
+ }
var = OMP_CLAUSE_DECL (c);
if (is_variable_sized (var))
{
@@ -12038,7 +12360,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
break;
case OMP_CLAUSE_FIRSTPRIVATE:
- if (is_oacc_parallel_or_serial (ctx))
+ if (is_gimple_omp_oacc (ctx->stmt))
goto oacc_firstprivate_map;
ovar = OMP_CLAUSE_DECL (c);
if (omp_is_reference (ovar))
@@ -12642,7 +12964,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
gimple_seq fork_seq = NULL;
gimple_seq join_seq = NULL;
- if (is_oacc_parallel_or_serial (ctx))
+ if (offloaded && is_gimple_omp_oacc (ctx->stmt))
{
/* If there are reductions on the offloaded region itself, treat
them as a dummy GANG loop. */
diff --git a/gcc/omp-oacc-kernels-decompose.cc b/gcc/omp-oacc-kernels-decompose.cc
new file mode 100644
index 0000000..c46168e
--- /dev/null
+++ b/gcc/omp-oacc-kernels-decompose.cc
@@ -0,0 +1,1545 @@
+/* Decompose OpenACC 'kernels' constructs into parts, a sequence of compute
+ constructs
+
+ Copyright (C) 2020 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/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "target.h"
+#include "tree.h"
+#include "langhooks.h"
+#include "gimple.h"
+#include "tree-pass.h"
+#include "cgraph.h"
+#include "fold-const.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
+#include "gomp-constants.h"
+#include "omp-general.h"
+#include "diagnostic-core.h"
+
+
+/* This preprocessing pass is run immediately before lower_omp. It decomposes
+ OpenACC 'kernels' constructs into parts, a sequence of compute constructs.
+
+ The translation is as follows:
+ - The entire 'kernels' region is turned into a 'data' region with clauses
+ taken from the 'kernels' region. New 'create' clauses are added for all
+ variables declared at the top level in the kernels region.
+ - Any loop nests annotated with an OpenACC 'loop' directive are wrapped in
+ a new compute construct.
+ - 'loop' directives without an explicit 'independent' or 'seq' clause
+ get an 'auto' clause added; other clauses are preserved on the loop
+ or moved to the new surrounding compute construct, as applicable.
+ - Any sequences of other code (non-loops, non-OpenACC 'loop's) are wrapped
+ in new "gang-single" compute construct: 'worker'/'vector' parallelism is
+ preserved, but 'num_gangs (1)' is enforced.
+ - Both points above only apply at the topmost level in the region, that
+ is, the transformation does not introduce new compute constructs inside
+ nested statement bodies. In particular, this means that a
+ gang-parallelizable loop inside an 'if' statement is made "gang-single".
+ - In order to make the host wait only once for the whole region instead
+ of once per device kernel launch, the new compute constructs are
+ annotated 'async'. Unless the original 'kernels' construct already was
+ marked 'async', the entire region ends with a 'wait' directive. If the
+ original 'kernels' construct was marked 'async', the synthesized 'async'
+ clauses use the original 'kernels' construct's 'async' argument
+ (possibly implicit).
+*/
+
+
+/*TODO Things are conceptually wrong here: 'loop' clauses may be hidden behind
+ 'device_type', so we have to defer a lot of processing until we're in the
+ offloading compilation. "Fortunately", GCC doesn't support the OpenACC
+ 'device_type' clause yet, so we get away that. */
+
+
+/* Helper function for decompose_kernels_region_body. If STMT contains a
+ "top-level" OMP_FOR statement, returns a pointer to that statement;
+ returns NULL otherwise.
+
+ A "top-level" OMP_FOR statement is one that is possibly accompanied by
+ small snippets of setup code. Specifically, this function accepts an
+ OMP_FOR possibly wrapped in a singleton bind and a singleton try
+ statement to allow for a local loop variable, but not an OMP_FOR
+ statement nested in any other constructs. Alternatively, it accepts a
+ non-singleton bind containing only assignments and then an OMP_FOR
+ statement at the very end. The former style can be generated by the C
+ frontend, the latter by the Fortran frontend. */
+
+static gimple *
+top_level_omp_for_in_stmt (gimple *stmt)
+{
+ if (gimple_code (stmt) == GIMPLE_OMP_FOR)
+ return stmt;
+
+ if (gimple_code (stmt) == GIMPLE_BIND)
+ {
+ gimple_seq body = gimple_bind_body (as_a <gbind *> (stmt));
+ if (gimple_seq_singleton_p (body))
+ {
+ /* Accept an OMP_FOR statement, or a try statement containing only
+ a single OMP_FOR. */
+ gimple *maybe_for_or_try = gimple_seq_first_stmt (body);
+ if (gimple_code (maybe_for_or_try) == GIMPLE_OMP_FOR)
+ return maybe_for_or_try;
+ else if (gimple_code (maybe_for_or_try) == GIMPLE_TRY)
+ {
+ gimple_seq try_body = gimple_try_eval (maybe_for_or_try);
+ if (!gimple_seq_singleton_p (try_body))
+ return NULL;
+ gimple *maybe_omp_for_stmt = gimple_seq_first_stmt (try_body);
+ if (gimple_code (maybe_omp_for_stmt) == GIMPLE_OMP_FOR)
+ return maybe_omp_for_stmt;
+ }
+ }
+ else
+ {
+ gimple_stmt_iterator gsi;
+ /* Accept only a block of optional assignments followed by an
+ OMP_FOR at the end. No other kinds of statements allowed. */
+ for (gsi = gsi_start (body); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple *body_stmt = gsi_stmt (gsi);
+ if (gimple_code (body_stmt) == GIMPLE_ASSIGN)
+ continue;
+ else if (gimple_code (body_stmt) == GIMPLE_OMP_FOR
+ && gsi_one_before_end_p (gsi))
+ return body_stmt;
+ else
+ return NULL;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/* Helper for adjust_region_code: evaluate the statement at GSI_P. */
+
+static tree
+adjust_region_code_walk_stmt_fn (gimple_stmt_iterator *gsi_p,
+ bool *handled_ops_p,
+ struct walk_stmt_info *wi)
+{
+ int *region_code = (int *) wi->info;
+
+ gimple *stmt = gsi_stmt (*gsi_p);
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_OMP_FOR:
+ {
+ tree clauses = gimple_omp_for_clauses (stmt);
+ if (omp_find_clause (clauses, OMP_CLAUSE_INDEPENDENT))
+ {
+ /* Explicit 'independent' clause. */
+ /* Keep going; recurse into loop body. */
+ break;
+ }
+ else if (omp_find_clause (clauses, OMP_CLAUSE_SEQ))
+ {
+ /* Explicit 'seq' clause. */
+ /* We'll "parallelize" if at some level a loop construct has been
+ marked up by the user as unparallelizable ('seq' clause; we'll
+ respect that in the later processing). Given that the user has
+ explicitly marked it up, this loop construct cannot be
+ performance-critical, and in this case it's also fine to
+ "parallelize" instead of "gang-single", because any outer or
+ inner loops may still exploit the available parallelism. */
+ /* Keep going; recurse into loop body. */
+ break;
+ }
+ else
+ {
+ /* Explicit or implicit 'auto' clause. */
+ /* The user would like this loop analyzed ('auto' clause) and
+ typically parallelized, but we don't have available yet the
+ compiler logic to analyze this, so can't parallelize it here, so
+ we'd very likely be running into a performance problem if we
+ were to execute this unparallelized, thus forward the whole loop
+ nest to 'parloops'. */
+ *region_code = GF_OMP_TARGET_KIND_OACC_KERNELS;
+ /* Terminate: final decision for this region. */
+ *handled_ops_p = true;
+ return integer_zero_node;
+ }
+ gcc_unreachable ();
+ }
+
+ case GIMPLE_COND:
+ case GIMPLE_GOTO:
+ case GIMPLE_SWITCH:
+ case GIMPLE_ASM:
+ case GIMPLE_TRANSACTION:
+ case GIMPLE_RETURN:
+ /* Statement that might constitute some looping/control flow pattern. */
+ /* The user would like this code analyzed (implicit inside a 'kernels'
+ region) and typically parallelized, but we don't have available yet
+ the compiler logic to analyze this, so can't parallelize it here, so
+ we'd very likely be running into a performance problem if we were to
+ execute this unparallelized, thus forward the whole thing to
+ 'parloops'. */
+ *region_code = GF_OMP_TARGET_KIND_OACC_KERNELS;
+ /* Terminate: final decision for this region. */
+ *handled_ops_p = true;
+ return integer_zero_node;
+
+ default:
+ /* Keep going. */
+ break;
+ }
+
+ return NULL;
+}
+
+/* Adjust the REGION_CODE for the region in GS. */
+
+static void
+adjust_region_code (gimple_seq gs, int *region_code)
+{
+ struct walk_stmt_info wi;
+ memset (&wi, 0, sizeof (wi));
+ wi.info = region_code;
+ walk_gimple_seq (gs, adjust_region_code_walk_stmt_fn, NULL, &wi);
+}
+
+/* Helper function for make_loops_gang_single for walking the tree. If the
+ statement indicated by GSI_P is an OpenACC for loop with a gang clause,
+ issue a warning and remove the clause. */
+
+static tree
+visit_loops_in_gang_single_region (gimple_stmt_iterator *gsi_p,
+ bool *handled_ops_p,
+ struct walk_stmt_info *)
+{
+ *handled_ops_p = false;
+
+ gimple *stmt = gsi_stmt (*gsi_p);
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_OMP_FOR:
+ /*TODO Given the current 'adjust_region_code' algorithm, this is
+ actually... */
+ gcc_unreachable ();
+
+ {
+ tree clauses = gimple_omp_for_clauses (stmt);
+ tree prev_clause = NULL;
+ for (tree clause = clauses; clause; clause = OMP_CLAUSE_CHAIN (clause))
+ {
+ if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_GANG)
+ {
+ /* It makes no sense to have a 'gang' clause in a "gang-single"
+ region, so warn and remove it. */
+ warning_at (gimple_location (stmt), 0,
+ "conditionally executed loop in %<kernels%> region"
+ " will be executed by a single gang;"
+ " ignoring %<gang%> clause");
+ if (prev_clause != NULL)
+ OMP_CLAUSE_CHAIN (prev_clause) = OMP_CLAUSE_CHAIN (clause);
+ else
+ clauses = OMP_CLAUSE_CHAIN (clause);
+
+ break;
+ }
+ prev_clause = clause;
+ }
+ gimple_omp_for_set_clauses (stmt, clauses);
+ }
+ /* No need to recurse into nested statements; no loop nested inside
+ this loop can be gang-partitioned. */
+ sorry ("%<gang%> loop in %<gang-single%> region");
+ *handled_ops_p = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+/* Visit all nested OpenACC loops in the sequence indicated by GS. This
+ statement is expected to be inside a gang-single region. Issue a warning
+ for any loops inside it that have gang clauses and remove the clauses. */
+
+static void
+make_loops_gang_single (gimple_seq gs)
+{
+ struct walk_stmt_info wi;
+ memset (&wi, 0, sizeof (wi));
+ walk_gimple_seq (gs, visit_loops_in_gang_single_region, NULL, &wi);
+}
+
+/* Construct a "gang-single" compute construct at LOC containing the STMTS.
+ Annotate with CLAUSES, which must not contain a 'num_gangs' clause, and an
+ additional 'num_gangs (1)' clause to force "gang-single" execution. */
+
+static gimple *
+make_region_seq (location_t loc, gimple_seq stmts,
+ tree num_gangs_clause,
+ tree num_workers_clause,
+ tree vector_length_clause,
+ tree clauses)
+{
+ /* This correctly unshares the entire clause chain rooted here. */
+ clauses = unshare_expr (clauses);
+
+ dump_user_location_t loc_stmts_first = gimple_seq_first (stmts);
+
+ /* Figure out the region code for this region. */
+ /* Optimistic default: assume "setup code", no looping; thus not
+ performance-critical. */
+ int region_code = GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE;
+ adjust_region_code (stmts, &region_code);
+
+ if (region_code == GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE)
+ {
+ if (dump_enabled_p ())
+ /*TODO MSG_MISSED_OPTIMIZATION? */
+ dump_printf_loc (MSG_NOTE, loc_stmts_first,
+ "beginning %<gang-single%> part"
+ " in OpenACC %<kernels%> region\n");
+
+ /* Synthesize a 'num_gangs (1)' clause. */
+ tree gang_single_clause = build_omp_clause (loc, OMP_CLAUSE_NUM_GANGS);
+ OMP_CLAUSE_OPERAND (gang_single_clause, 0) = integer_one_node;
+ OMP_CLAUSE_CHAIN (gang_single_clause) = clauses;
+ clauses = gang_single_clause;
+
+ /* Remove and issue warnings about gang clauses on any OpenACC
+ loops nested inside this sequentially executed statement. */
+ make_loops_gang_single (stmts);
+ }
+ else if (region_code == GF_OMP_TARGET_KIND_OACC_KERNELS)
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, loc_stmts_first,
+ "beginning %<parloops%> part"
+ " in OpenACC %<kernels%> region\n");
+
+ /* As we're transforming a 'GF_OMP_TARGET_KIND_OACC_KERNELS' into another
+ 'GF_OMP_TARGET_KIND_OACC_KERNELS', this isn't doing any of the clauses
+ mangling that 'make_region_loop_nest' is doing. */
+ /* Re-assemble the clauses stripped off earlier. */
+ if (num_gangs_clause != NULL)
+ {
+ tree c = unshare_expr (num_gangs_clause);
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ if (num_workers_clause != NULL)
+ {
+ tree c = unshare_expr (num_workers_clause);
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ if (vector_length_clause != NULL)
+ {
+ tree c = unshare_expr (vector_length_clause);
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ }
+ else
+ gcc_unreachable ();
+
+ /* Build the gang-single region. */
+ gimple *single_region = gimple_build_omp_target (NULL, region_code, clauses);
+ gimple_set_location (single_region, loc);
+ gbind *single_body = gimple_build_bind (NULL, stmts, make_node (BLOCK));
+ gimple_omp_set_body (single_region, single_body);
+
+ return single_region;
+}
+
+/* Helper function for make_region_loop_nest. Adds a 'num_gangs'
+ ('num_workers', 'vector_length') clause to the given CLAUSES, either the one
+ from the parent compute construct (PARENT_CLAUSE) or a new one based on the
+ loop's own LOOP_CLAUSE ('gang (num: N)' or similar for 'worker' or 'vector'
+ clauses) with the given CLAUSE_CODE. Does nothing if neither PARENT_CLAUSE
+ nor LOOP_CLAUSE exist. Returns the new clauses. */
+
+static tree
+add_parent_or_loop_num_clause (tree parent_clause, tree loop_clause,
+ omp_clause_code clause_code, tree clauses)
+{
+ if (parent_clause != NULL)
+ {
+ tree num_clause = unshare_expr (parent_clause);
+ OMP_CLAUSE_CHAIN (num_clause) = clauses;
+ clauses = num_clause;
+ }
+ else if (loop_clause != NULL)
+ {
+ /* The kernels region does not have a 'num_gangs' clause, but the loop
+ itself had a 'gang (num: N)' clause. Honor it by adding a
+ 'num_gangs (N)' clause on the compute construct. */
+ tree num = OMP_CLAUSE_OPERAND (loop_clause, 0);
+ tree new_num_clause
+ = build_omp_clause (OMP_CLAUSE_LOCATION (loop_clause), clause_code);
+ OMP_CLAUSE_OPERAND (new_num_clause, 0) = num;
+ OMP_CLAUSE_CHAIN (new_num_clause) = clauses;
+ clauses = new_num_clause;
+ }
+ return clauses;
+}
+
+/* Helper for make_region_loop_nest, looking for 'worker (num: N)' or 'vector
+ (length: N)' clauses in nested loops. Removes the argument, transferring it
+ to the enclosing compute construct (via WI->INFO). If arguments within the
+ same loop nest conflict, emits a warning.
+
+ This function also decides whether to add an 'auto' clause on each of these
+ nested loops. */
+
+struct adjust_nested_loop_clauses_wi_info
+{
+ tree *loop_gang_clause_ptr;
+ tree *loop_worker_clause_ptr;
+ tree *loop_vector_clause_ptr;
+};
+
+static tree
+adjust_nested_loop_clauses (gimple_stmt_iterator *gsi_p, bool *,
+ struct walk_stmt_info *wi)
+{
+ struct adjust_nested_loop_clauses_wi_info *wi_info
+ = (struct adjust_nested_loop_clauses_wi_info *) wi->info;
+ gimple *stmt = gsi_stmt (*gsi_p);
+
+ if (gimple_code (stmt) == GIMPLE_OMP_FOR)
+ {
+ bool add_auto_clause = true;
+ tree loop_clauses = gimple_omp_for_clauses (stmt);
+ tree loop_clause = loop_clauses;
+ for (; loop_clause; loop_clause = OMP_CLAUSE_CHAIN (loop_clause))
+ {
+ tree *outer_clause_ptr = NULL;
+ switch (OMP_CLAUSE_CODE (loop_clause))
+ {
+ case OMP_CLAUSE_GANG:
+ outer_clause_ptr = wi_info->loop_gang_clause_ptr;
+ break;
+ case OMP_CLAUSE_WORKER:
+ outer_clause_ptr = wi_info->loop_worker_clause_ptr;
+ break;
+ case OMP_CLAUSE_VECTOR:
+ outer_clause_ptr = wi_info->loop_vector_clause_ptr;
+ break;
+ case OMP_CLAUSE_SEQ:
+ case OMP_CLAUSE_INDEPENDENT:
+ case OMP_CLAUSE_AUTO:
+ add_auto_clause = false;
+ default:
+ break;
+ }
+ if (outer_clause_ptr != NULL)
+ {
+ if (OMP_CLAUSE_OPERAND (loop_clause, 0) != NULL
+ && *outer_clause_ptr == NULL)
+ {
+ /* Transfer the clause to the enclosing compute construct and
+ remove the numerical argument from the 'loop'. */
+ *outer_clause_ptr = unshare_expr (loop_clause);
+ OMP_CLAUSE_OPERAND (loop_clause, 0) = NULL;
+ }
+ else if (OMP_CLAUSE_OPERAND (loop_clause, 0) != NULL &&
+ OMP_CLAUSE_OPERAND (*outer_clause_ptr, 0) != NULL)
+ {
+ /* See if both of these are the same constant. If they
+ aren't, emit a warning. */
+ tree old_op = OMP_CLAUSE_OPERAND (*outer_clause_ptr, 0);
+ tree new_op = OMP_CLAUSE_OPERAND (loop_clause, 0);
+ if (!(cst_and_fits_in_hwi (old_op) &&
+ cst_and_fits_in_hwi (new_op) &&
+ int_cst_value (old_op) == int_cst_value (new_op)))
+ {
+ const char *clause_name
+ = omp_clause_code_name[OMP_CLAUSE_CODE (loop_clause)];
+ error_at (gimple_location (stmt),
+ "cannot honor conflicting %qs clause",
+ clause_name);
+ inform (OMP_CLAUSE_LOCATION (*outer_clause_ptr),
+ "location of the previous clause"
+ " in the same loop nest");
+ }
+ OMP_CLAUSE_OPERAND (loop_clause, 0) = NULL;
+ }
+ }
+ }
+ if (add_auto_clause)
+ {
+ tree auto_clause
+ = build_omp_clause (gimple_location (stmt), OMP_CLAUSE_AUTO);
+ OMP_CLAUSE_CHAIN (auto_clause) = loop_clauses;
+ gimple_omp_for_set_clauses (stmt, auto_clause);
+ }
+ }
+
+ return NULL;
+}
+
+/* Helper for make_region_loop_nest. Transform OpenACC 'kernels'/'loop'
+ construct clauses into OpenACC 'parallel'/'loop' construct ones. */
+
+static tree
+transform_kernels_loop_clauses (gimple *omp_for,
+ tree num_gangs_clause,
+ tree num_workers_clause,
+ tree vector_length_clause,
+ tree clauses)
+{
+ /* If this loop in a kernels region does not have an explicit 'seq',
+ 'independent', or 'auto' clause, we must give it an explicit 'auto'
+ clause.
+ We also check for 'gang (num: N)' clauses. These must not appear in
+ kernels regions that have their own 'num_gangs' clause. Otherwise, they
+ must be converted and put on the region; similarly for 'worker' and
+ 'vector' clauses. */
+ bool add_auto_clause = true;
+ tree loop_gang_clause = NULL, loop_worker_clause = NULL,
+ loop_vector_clause = NULL;
+ tree loop_clauses = gimple_omp_for_clauses (omp_for);
+ for (tree loop_clause = loop_clauses;
+ loop_clause;
+ loop_clause = OMP_CLAUSE_CHAIN (loop_clause))
+ {
+ bool found_num_clause = false;
+ tree *clause_ptr, clause_to_check;
+ switch (OMP_CLAUSE_CODE (loop_clause))
+ {
+ case OMP_CLAUSE_GANG:
+ found_num_clause = true;
+ clause_ptr = &loop_gang_clause;
+ clause_to_check = num_gangs_clause;
+ break;
+ case OMP_CLAUSE_WORKER:
+ found_num_clause = true;
+ clause_ptr = &loop_worker_clause;
+ clause_to_check = num_workers_clause;
+ break;
+ case OMP_CLAUSE_VECTOR:
+ found_num_clause = true;
+ clause_ptr = &loop_vector_clause;
+ clause_to_check = vector_length_clause;
+ break;
+ case OMP_CLAUSE_INDEPENDENT:
+ case OMP_CLAUSE_SEQ:
+ case OMP_CLAUSE_AUTO:
+ add_auto_clause = false;
+ default:
+ break;
+ }
+ if (found_num_clause && OMP_CLAUSE_OPERAND (loop_clause, 0) != NULL)
+ {
+ if (clause_to_check)
+ {
+ const char *clause_name
+ = omp_clause_code_name[OMP_CLAUSE_CODE (loop_clause)];
+ const char *parent_clause_name
+ = omp_clause_code_name[OMP_CLAUSE_CODE (clause_to_check)];
+ error_at (OMP_CLAUSE_LOCATION (loop_clause),
+ "argument not permitted on %qs clause"
+ " in OpenACC %<kernels%> region with a %qs clause",
+ clause_name, parent_clause_name);
+ inform (OMP_CLAUSE_LOCATION (clause_to_check),
+ "location of OpenACC %<kernels%>");
+ }
+ /* Copy the 'gang (N)'/'worker (N)'/'vector (N)' clause to the
+ enclosing compute construct. */
+ *clause_ptr = unshare_expr (loop_clause);
+ OMP_CLAUSE_CHAIN (*clause_ptr) = NULL;
+ /* Leave a 'gang'/'worker'/'vector' clause on the 'loop', but without
+ argument. */
+ OMP_CLAUSE_OPERAND (loop_clause, 0) = NULL;
+ }
+ }
+ if (add_auto_clause)
+ {
+ tree auto_clause = build_omp_clause (gimple_location (omp_for),
+ OMP_CLAUSE_AUTO);
+ OMP_CLAUSE_CHAIN (auto_clause) = loop_clauses;
+ loop_clauses = auto_clause;
+ }
+ gimple_omp_for_set_clauses (omp_for, loop_clauses);
+ /* We must also recurse into the loop; it might contain nested loops having
+ their own 'worker (num: W)' or 'vector (length: V)' clauses. Turn these
+ into 'worker'/'vector' clauses on the compute construct. */
+ struct walk_stmt_info wi;
+ memset (&wi, 0, sizeof (wi));
+ struct adjust_nested_loop_clauses_wi_info wi_info;
+ wi_info.loop_gang_clause_ptr = &loop_gang_clause;
+ wi_info.loop_worker_clause_ptr = &loop_worker_clause;
+ wi_info.loop_vector_clause_ptr = &loop_vector_clause;
+ wi.info = &wi_info;
+ gimple *body = gimple_omp_body (omp_for);
+ walk_gimple_seq (body, adjust_nested_loop_clauses, NULL, &wi);
+ /* Check if there were conflicting numbers of workers or vector length. */
+ if (loop_gang_clause != NULL &&
+ OMP_CLAUSE_OPERAND (loop_gang_clause, 0) == NULL)
+ loop_gang_clause = NULL;
+ if (loop_worker_clause != NULL &&
+ OMP_CLAUSE_OPERAND (loop_worker_clause, 0) == NULL)
+ loop_worker_clause = NULL;
+ if (loop_vector_clause != NULL &&
+ OMP_CLAUSE_OPERAND (loop_vector_clause, 0) == NULL)
+ vector_length_clause = NULL;
+
+ /* If the kernels region had 'num_gangs', 'num_worker', 'vector_length'
+ clauses, add these to this new compute construct. */
+ clauses
+ = add_parent_or_loop_num_clause (num_gangs_clause, loop_gang_clause,
+ OMP_CLAUSE_NUM_GANGS, clauses);
+ clauses
+ = add_parent_or_loop_num_clause (num_workers_clause, loop_worker_clause,
+ OMP_CLAUSE_NUM_WORKERS, clauses);
+ clauses
+ = add_parent_or_loop_num_clause (vector_length_clause, loop_vector_clause,
+ OMP_CLAUSE_VECTOR_LENGTH, clauses);
+
+ return clauses;
+}
+
+/* Construct a possibly gang-parallel compute construct containing the STMT,
+ which must be identical to, or a bind containing, the loop OMP_FOR.
+
+ The NUM_GANGS_CLAUSE, NUM_WORKERS_CLAUSE, and VECTOR_LENGTH_CLAUSE are
+ optional clauses from the original kernels region and must not be contained
+ in the other CLAUSES. The newly created compute construct is annotated with
+ the optional NUM_GANGS_CLAUSE as well as the other CLAUSES. If there is no
+ NUM_GANGS_CLAUSE but the loop has a 'gang (num: N)' clause, that is
+ converted to a 'num_gangs (N)' clause on the new compute construct, and
+ similarly for 'worker' and 'vector' clauses.
+
+ The outermost loop gets an 'auto' clause unless there already is an
+ 'seq'/'independent'/'auto' clause. Nested loops inside OMP_FOR are treated
+ similarly by the adjust_nested_loop_clauses function. */
+
+static gimple *
+make_region_loop_nest (gimple *omp_for, gimple_seq stmts,
+ tree num_gangs_clause,
+ tree num_workers_clause,
+ tree vector_length_clause,
+ tree clauses)
+{
+ /* This correctly unshares the entire clause chain rooted here. */
+ clauses = unshare_expr (clauses);
+
+ /* Figure out the region code for this region. */
+ /* Optimistic default: assume that the loop nest is parallelizable
+ (essentially, no GIMPLE_OMP_FOR with (explicit or implicit) 'auto' clause,
+ and no un-annotated loops). */
+ int region_code = GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED;
+ adjust_region_code (stmts, &region_code);
+
+ if (region_code == GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED)
+ {
+ if (dump_enabled_p ())
+ /* This is not MSG_OPTIMIZED_LOCATIONS, as we're just doing what the
+ user asked us to. */
+ dump_printf_loc (MSG_NOTE, omp_for,
+ "parallelized loop nest"
+ " in OpenACC %<kernels%> region\n");
+
+ clauses = transform_kernels_loop_clauses (omp_for,
+ num_gangs_clause,
+ num_workers_clause,
+ vector_length_clause,
+ clauses);
+ }
+ else if (region_code == GF_OMP_TARGET_KIND_OACC_KERNELS)
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, omp_for,
+ "forwarded loop nest"
+ " in OpenACC %<kernels%> region"
+ " to %<parloops%> for analysis\n");
+
+ /* We're transforming one 'GF_OMP_TARGET_KIND_OACC_KERNELS' into another
+ 'GF_OMP_TARGET_KIND_OACC_KERNELS', so don't have to
+ 'transform_kernels_loop_clauses'. */
+ /* Re-assemble the clauses stripped off earlier. */
+ clauses
+ = add_parent_or_loop_num_clause (num_gangs_clause, NULL,
+ OMP_CLAUSE_NUM_GANGS, clauses);
+ clauses
+ = add_parent_or_loop_num_clause (num_workers_clause, NULL,
+ OMP_CLAUSE_NUM_WORKERS, clauses);
+ clauses
+ = add_parent_or_loop_num_clause (vector_length_clause, NULL,
+ OMP_CLAUSE_VECTOR_LENGTH, clauses);
+ }
+ else
+ gcc_unreachable ();
+
+ gimple *parallel_body_bind
+ = gimple_build_bind (NULL, stmts, make_node (BLOCK));
+ gimple *parallel_region
+ = gimple_build_omp_target (parallel_body_bind, region_code, clauses);
+ gimple_set_location (parallel_region, gimple_location (omp_for));
+
+ return parallel_region;
+}
+
+/* Eliminate any binds directly inside BIND by adding their statements to
+ BIND (i.e., modifying it in place), excluding binds that hold only an
+ OMP_FOR loop and associated setup/cleanup code. Recurse into binds but
+ not other statements. Return a chain of the local variables of eliminated
+ binds, i.e., the local variables found in nested binds. If
+ INCLUDE_TOPLEVEL_VARS is true, this also includes the variables belonging
+ to BIND itself. */
+
+static tree
+flatten_binds (gbind *bind, bool include_toplevel_vars = false)
+{
+ tree vars = NULL, last_var = NULL;
+
+ if (include_toplevel_vars)
+ {
+ vars = gimple_bind_vars (bind);
+ last_var = vars;
+ }
+
+ gimple_seq new_body = NULL;
+ gimple_seq body_sequence = gimple_bind_body (bind);
+ gimple_stmt_iterator gsi, gsi_n;
+ for (gsi = gsi_start (body_sequence); !gsi_end_p (gsi); gsi = gsi_n)
+ {
+ /* Advance the iterator here because otherwise it would be invalidated
+ by moving statements below. */
+ gsi_n = gsi;
+ gsi_next (&gsi_n);
+
+ gimple *stmt = gsi_stmt (gsi);
+ /* Flatten bind statements, except the ones that contain only an
+ OpenACC for loop. */
+ if (gimple_code (stmt) == GIMPLE_BIND
+ && !top_level_omp_for_in_stmt (stmt))
+ {
+ gbind *inner_bind = as_a <gbind *> (stmt);
+ /* Flatten recursively, and collect all variables. */
+ tree inner_vars = flatten_binds (inner_bind, true);
+ gimple_seq inner_sequence = gimple_bind_body (inner_bind);
+ if (flag_checking)
+ {
+ for (gimple_stmt_iterator inner_gsi = gsi_start (inner_sequence);
+ !gsi_end_p (inner_gsi);
+ gsi_next (&inner_gsi))
+ {
+ gimple *inner_stmt = gsi_stmt (inner_gsi);
+ gcc_assert (gimple_code (inner_stmt) != GIMPLE_BIND
+ || top_level_omp_for_in_stmt (inner_stmt));
+ }
+ }
+ gimple_seq_add_seq (&new_body, inner_sequence);
+ /* Find the last variable; we will append others to it. */
+ while (last_var != NULL && TREE_CHAIN (last_var) != NULL)
+ last_var = TREE_CHAIN (last_var);
+ if (last_var != NULL)
+ {
+ TREE_CHAIN (last_var) = inner_vars;
+ last_var = inner_vars;
+ }
+ else
+ {
+ vars = inner_vars;
+ last_var = vars;
+ }
+ }
+ else
+ gimple_seq_add_stmt (&new_body, stmt);
+ }
+
+ /* Put the possibly transformed body back into the bind. */
+ gimple_bind_set_body (bind, new_body);
+ return vars;
+}
+
+/* Helper function for places where we construct data regions. Wraps the BODY
+ inside a try-finally construct at LOC that calls __builtin_GOACC_data_end
+ in its cleanup block. Returns this try statement. */
+
+static gimple *
+make_data_region_try_statement (location_t loc, gimple *body)
+{
+ tree data_end_fn = builtin_decl_explicit (BUILT_IN_GOACC_DATA_END);
+ gimple *call = gimple_build_call (data_end_fn, 0);
+ gimple_seq cleanup = NULL;
+ gimple_seq_add_stmt (&cleanup, call);
+ gimple *try_stmt = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
+ gimple_set_location (body, loc);
+ return try_stmt;
+}
+
+/* If INNER_BIND_VARS holds variables, build an OpenACC data region with
+ location LOC containing BODY and having 'create (var)' clauses for each
+ variable. If INNER_CLEANUP is present, add a try-finally statement with
+ this cleanup code in the finally block. Return the new data region, or
+ the original BODY if no data region was needed. */
+
+static gimple *
+maybe_build_inner_data_region (location_t loc, gimple *body,
+ tree inner_bind_vars, gimple *inner_cleanup)
+{
+ /* Is this an instantiation of a template? (In this case, we don't care what
+ the generic decl is - just whether the function decl has one.) */
+ bool generic_inst_p
+ = (lang_hooks.decls.get_generic_function_decl (current_function_decl)
+ != NULL);
+
+ /* Build data 'create (var)' clauses for these local variables.
+ Below we will add these to a data region enclosing the entire body
+ of the decomposed kernels region. */
+ tree prev_mapped_var = NULL, next = NULL, artificial_vars = NULL,
+ inner_data_clauses = NULL;
+ for (tree v = inner_bind_vars; v; v = next)
+ {
+ next = TREE_CHAIN (v);
+ if (DECL_ARTIFICIAL (v)
+ || TREE_CODE (v) == CONST_DECL
+ || generic_inst_p)
+ {
+ /* If this is an artificial temporary, it need not be mapped. We
+ move its declaration into the bind inside the data region.
+ Also avoid mapping variables if we are inside a template
+ instantiation; the code does not contain all the copies to
+ temporaries that would make this legal. */
+ TREE_CHAIN (v) = artificial_vars;
+ artificial_vars = v;
+ if (prev_mapped_var != NULL)
+ TREE_CHAIN (prev_mapped_var) = next;
+ else
+ inner_bind_vars = next;
+ }
+ else
+ {
+ /* Otherwise, build the map clause. */
+ tree new_clause = build_omp_clause (loc, OMP_CLAUSE_MAP);
+ OMP_CLAUSE_SET_MAP_KIND (new_clause, GOMP_MAP_ALLOC);
+ OMP_CLAUSE_DECL (new_clause) = v;
+ OMP_CLAUSE_SIZE (new_clause) = DECL_SIZE_UNIT (v);
+ OMP_CLAUSE_CHAIN (new_clause) = inner_data_clauses;
+ inner_data_clauses = new_clause;
+
+ prev_mapped_var = v;
+ }
+ }
+
+ if (artificial_vars)
+ body = gimple_build_bind (artificial_vars, body, make_node (BLOCK));
+
+ /* If we determined above that there are variables that need to be created
+ on the device, construct a data region for them and wrap the body
+ inside that. */
+ if (inner_data_clauses != NULL)
+ {
+ gcc_assert (inner_bind_vars != NULL);
+ gimple *inner_data_region
+ = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DATA_KERNELS,
+ inner_data_clauses);
+ gimple_set_location (inner_data_region, loc);
+ /* Make sure __builtin_GOACC_data_end is called at the end. */
+ gimple *try_stmt = make_data_region_try_statement (loc, body);
+ gimple_omp_set_body (inner_data_region, try_stmt);
+ gimple *bind_body;
+ if (inner_cleanup != NULL)
+ /* Clobber all the inner variables that need to be clobbered. */
+ bind_body = gimple_build_try (inner_data_region, inner_cleanup,
+ GIMPLE_TRY_FINALLY);
+ else
+ bind_body = inner_data_region;
+ body = gimple_build_bind (inner_bind_vars, bind_body, make_node (BLOCK));
+ }
+
+ return body;
+}
+
+/* Helper function of decompose_kernels_region_body. The statements in
+ REGION_BODY are expected to be decomposed parts; add an 'async' clause to
+ each. Also add a 'wait' directive at the end of the sequence. */
+
+static void
+add_async_clauses_and_wait (location_t loc, gimple_seq *region_body)
+{
+ tree default_async_queue
+ = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
+ for (gimple_stmt_iterator gsi = gsi_start (*region_body);
+ !gsi_end_p (gsi);
+ gsi_next (&gsi))
+ {
+ gimple *stmt = gsi_stmt (gsi);
+ tree target_clauses = gimple_omp_target_clauses (stmt);
+ tree new_async_clause = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
+ OMP_CLAUSE_OPERAND (new_async_clause, 0) = default_async_queue;
+ OMP_CLAUSE_CHAIN (new_async_clause) = target_clauses;
+ target_clauses = new_async_clause;
+ gimple_omp_target_set_clauses (as_a <gomp_target *> (stmt),
+ target_clauses);
+ }
+ /* A '#pragma acc wait' is just a call 'GOACC_wait (acc_async_sync, 0)'. */
+ tree wait_fn = builtin_decl_explicit (BUILT_IN_GOACC_WAIT);
+ tree sync_arg = build_int_cst (integer_type_node, GOMP_ASYNC_SYNC);
+ gimple *wait_call = gimple_build_call (wait_fn, 2,
+ sync_arg, integer_zero_node);
+ gimple_set_location (wait_call, loc);
+ gimple_seq_add_stmt (region_body, wait_call);
+}
+
+/* Auxiliary analysis of the body of a kernels region, to determine for each
+ OpenACC loop whether it is control-dependent (i.e., not necessarily
+ executed every time the kernels region is entered) or not.
+ We say that a loop is control-dependent if there is some cond, switch, or
+ goto statement that jumps over it, forwards or backwards. For example,
+ if the loop is controlled by an if statement, then a jump to the true
+ block, the false block, or from one of those blocks to the control flow
+ join point will necessarily jump over the loop.
+ This analysis implements an ad-hoc union-find data structure classifying
+ statements into "control-flow regions" as follows: Most statements are in
+ the same region as their predecessor, except that each OpenACC loop is in
+ a region of its own, and each OpenACC loop's successor starts a new
+ region. We then unite the regions of any statements linked by jumps,
+ placing any cond, switch, or goto statement in the same region as its
+ target label(s).
+ In the end, control dependence of OpenACC loops can be determined by
+ comparing their immediate predecessor and successor statements' regions.
+ A jump crosses the loop if and only if the predecessor and successor are
+ in the same region. (If there is no predecessor or successor, the loop
+ is executed unconditionally.)
+ The methods in this class identify statements by their index in the
+ kernels region's body. */
+
+class control_flow_regions
+{
+ public:
+ /* Initialize an instance and pre-compute the control-flow region
+ information for the statement sequence SEQ. */
+ control_flow_regions (gimple_seq seq);
+
+ /* Return true if the statement with the given index IDX in the analyzed
+ statement sequence is an unconditionally executed OpenACC loop. */
+ bool is_unconditional_oacc_for_loop (size_t idx);
+
+ private:
+ /* Find the region representative for the statement identified by index
+ STMT_IDX. */
+ size_t find_rep (size_t stmt_idx);
+
+ /* Union the regions containing the statements represented by
+ representatives A and B. */
+ void union_reps (size_t a, size_t b);
+
+ /* Helper for the constructor. Performs the actual computation of the
+ control-flow regions in the statement sequence SEQ. */
+ void compute_regions (gimple_seq seq);
+
+ /* The mapping from statement indices to region representatives. */
+ vec <size_t> representatives;
+
+ /* A cache mapping statement indices to a flag indicating whether the
+ statement is a top level OpenACC for loop. */
+ vec <bool> omp_for_loops;
+};
+
+control_flow_regions::control_flow_regions (gimple_seq seq)
+{
+ representatives.create (1);
+ omp_for_loops.create (1);
+ compute_regions (seq);
+}
+
+bool
+control_flow_regions::is_unconditional_oacc_for_loop (size_t idx)
+{
+ if (idx == 0 || idx == representatives.length () - 1)
+ /* The first or last statement in the kernels region. This means that
+ there is no room before or after it for a jump or a label. Thus
+ there cannot be a jump across it, so it is unconditional. */
+ return true;
+ /* Otherwise, the loop is unconditional if the statements before and after
+ it are in different control flow regions. Scan forward and backward,
+ skipping over neighboring OpenACC for loops, to find these preceding
+ statements. */
+ size_t prev_index = idx - 1;
+ while (prev_index > 0 && omp_for_loops [prev_index] == true)
+ prev_index--;
+ /* If all preceding statements are also OpenACC loops, all of these are
+ unconditional. */
+ if (prev_index == 0)
+ return true;
+ size_t succ_index = idx + 1;
+ while (succ_index < omp_for_loops.length ()
+ && omp_for_loops [succ_index] == true)
+ succ_index++;
+ /* If all following statements are also OpenACC loops, all of these are
+ unconditional. */
+ if (succ_index == omp_for_loops.length ())
+ return true;
+ return (find_rep (prev_index) != find_rep (succ_index));
+}
+
+size_t
+control_flow_regions::find_rep (size_t stmt_idx)
+{
+ size_t rep = stmt_idx, aux = stmt_idx;
+ /* Find the root representative of this statement. */
+ while (representatives[rep] != rep)
+ rep = representatives[rep];
+ /* Compress the path from the original statement to the representative. */
+ while (representatives[aux] != rep)
+ {
+ size_t tmp = representatives[aux];
+ representatives[aux] = rep;
+ aux = tmp;
+ }
+ return rep;
+}
+
+void
+control_flow_regions::union_reps (size_t a, size_t b)
+{
+ a = find_rep (a);
+ b = find_rep (b);
+ representatives[b] = a;
+}
+
+void
+control_flow_regions::compute_regions (gimple_seq seq)
+{
+ hash_map <gimple *, size_t> control_flow_reps;
+ hash_map <tree, size_t> label_reps;
+ size_t current_region = 0, idx = 0;
+
+ /* In a first pass, assign an initial region to each statement. Except in
+ the case of OpenACC loops, each statement simply gets the same region
+ representative as its predecessor. */
+ for (gimple_stmt_iterator gsi = gsi_start (seq);
+ !gsi_end_p (gsi);
+ gsi_next (&gsi))
+ {
+ gimple *stmt = gsi_stmt (gsi);
+ gimple *omp_for = top_level_omp_for_in_stmt (stmt);
+ omp_for_loops.safe_push (omp_for != NULL);
+ if (omp_for != NULL)
+ {
+ /* Assign a new region to this loop and to its successor. */
+ current_region = idx;
+ representatives.safe_push (current_region);
+ current_region++;
+ }
+ else
+ {
+ representatives.safe_push (current_region);
+ /* Remember any jumps and labels for the second pass below. */
+ if (gimple_code (stmt) == GIMPLE_COND
+ || gimple_code (stmt) == GIMPLE_SWITCH
+ || gimple_code (stmt) == GIMPLE_GOTO)
+ control_flow_reps.put (stmt, current_region);
+ else if (gimple_code (stmt) == GIMPLE_LABEL)
+ label_reps.put (gimple_label_label (as_a <glabel *> (stmt)),
+ current_region);
+ }
+ idx++;
+ }
+ gcc_assert (representatives.length () == omp_for_loops.length ());
+
+ /* Revisit all the control flow statements and union the region of each
+ cond, switch, or goto statement with the target labels' regions. */
+ for (hash_map <gimple *, size_t>::iterator it = control_flow_reps.begin ();
+ it != control_flow_reps.end ();
+ ++it)
+ {
+ gimple *stmt = (*it).first;
+ size_t stmt_rep = (*it).second;
+ switch (gimple_code (stmt))
+ {
+ tree label;
+ unsigned int n;
+
+ case GIMPLE_COND:
+ label = gimple_cond_true_label (as_a <gcond *> (stmt));
+ union_reps (stmt_rep, *label_reps.get (label));
+ label = gimple_cond_false_label (as_a <gcond *> (stmt));
+ union_reps (stmt_rep, *label_reps.get (label));
+ break;
+
+ case GIMPLE_SWITCH:
+ n = gimple_switch_num_labels (as_a <gswitch *> (stmt));
+ for (unsigned int i = 0; i < n; i++)
+ {
+ tree switch_case
+ = gimple_switch_label (as_a <gswitch *> (stmt), i);
+ label = CASE_LABEL (switch_case);
+ union_reps (stmt_rep, *label_reps.get (label));
+ }
+ break;
+
+ case GIMPLE_GOTO:
+ label = gimple_goto_dest (stmt);
+ union_reps (stmt_rep, *label_reps.get (label));
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+}
+
+/* Decompose the body of the KERNELS_REGION, which was originally annotated
+ with the KERNELS_CLAUSES, into a series of compute constructs. */
+
+static gimple *
+decompose_kernels_region_body (gimple *kernels_region, tree kernels_clauses)
+{
+ location_t loc = gimple_location (kernels_region);
+
+ /* The kernels clauses will be propagated to the child clauses unmodified,
+ except that the 'num_gangs', 'num_workers', and 'vector_length' clauses
+ will only be added to loop regions. The other regions are "gang-single"
+ and get an explicit 'num_gangs (1)' clause. So separate out the
+ 'num_gangs', 'num_workers', and 'vector_length' clauses here.
+ Also check for the presence of an 'async' clause but do not remove it from
+ the 'kernels' clauses. */
+ tree num_gangs_clause = NULL, num_workers_clause = NULL,
+ vector_length_clause = NULL;
+ tree async_clause = NULL;
+ tree prev_clause = NULL, next_clause = NULL;
+ tree parallel_clauses = kernels_clauses;
+ for (tree c = parallel_clauses; c; c = next_clause)
+ {
+ /* Preserve this here, as we might NULL it later. */
+ next_clause = OMP_CLAUSE_CHAIN (c);
+
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_GANGS
+ || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_WORKERS
+ || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_VECTOR_LENGTH)
+ {
+ /* Cut this clause out of the chain. */
+ if (prev_clause != NULL)
+ OMP_CLAUSE_CHAIN (prev_clause) = OMP_CLAUSE_CHAIN (c);
+ else
+ kernels_clauses = OMP_CLAUSE_CHAIN (c);
+ OMP_CLAUSE_CHAIN (c) = NULL;
+ switch (OMP_CLAUSE_CODE (c))
+ {
+ case OMP_CLAUSE_NUM_GANGS:
+ num_gangs_clause = c;
+ break;
+ case OMP_CLAUSE_NUM_WORKERS:
+ num_workers_clause = c;
+ break;
+ case OMP_CLAUSE_VECTOR_LENGTH:
+ vector_length_clause = c;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ }
+ else
+ prev_clause = c;
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ASYNC)
+ async_clause = c;
+ }
+
+ gimple *kernels_body = gimple_omp_body (kernels_region);
+ gbind *kernels_bind = as_a <gbind *> (kernels_body);
+
+ /* The body of the region may contain other nested binds declaring inner
+ local variables. Collapse all these binds into one to ensure that we
+ have a single sequence of statements to iterate over; also, collect all
+ inner variables. */
+ tree inner_bind_vars = flatten_binds (kernels_bind);
+ gimple_seq body_sequence = gimple_bind_body (kernels_bind);
+
+ /* All these inner variables will get allocated on the device (below, by
+ calling maybe_build_inner_data_region). Here we create 'present'
+ clauses for them and add these clauses to the list of clauses to be
+ attached to each inner compute construct. */
+ tree present_clauses = kernels_clauses;
+ for (tree var = inner_bind_vars; var; var = TREE_CHAIN (var))
+ {
+ if (!DECL_ARTIFICIAL (var) && TREE_CODE (var) != CONST_DECL)
+ {
+ tree present_clause = build_omp_clause (loc, OMP_CLAUSE_MAP);
+ OMP_CLAUSE_SET_MAP_KIND (present_clause, GOMP_MAP_FORCE_PRESENT);
+ OMP_CLAUSE_DECL (present_clause) = var;
+ OMP_CLAUSE_SIZE (present_clause) = DECL_SIZE_UNIT (var);
+ OMP_CLAUSE_CHAIN (present_clause) = present_clauses;
+ present_clauses = present_clause;
+ }
+ }
+ kernels_clauses = present_clauses;
+
+ /* In addition to nested binds, the "real" body of the region may be
+ nested inside a try-finally block. Find its cleanup block, which
+ contains code to clobber the local variables that must be clobbered. */
+ gimple *inner_cleanup = NULL;
+ if (body_sequence != NULL && gimple_code (body_sequence) == GIMPLE_TRY)
+ {
+ if (gimple_seq_singleton_p (body_sequence))
+ {
+ /* The try statement is the only thing inside the bind. */
+ inner_cleanup = gimple_try_cleanup (body_sequence);
+ body_sequence = gimple_try_eval (body_sequence);
+ }
+ else
+ {
+ /* The bind's body starts with a try statement, but it is followed
+ by other things. */
+ gimple_stmt_iterator gsi = gsi_start (body_sequence);
+ gimple *try_stmt = gsi_stmt (gsi);
+ inner_cleanup = gimple_try_cleanup (try_stmt);
+ gimple *try_body = gimple_try_eval (try_stmt);
+
+ gsi_remove (&gsi, false);
+ /* Now gsi indicates the sequence of statements after the try
+ statement in the bind. Append the statement in the try body and
+ the trailing statements from gsi. */
+ gsi_insert_seq_before (&gsi, try_body, GSI_CONTINUE_LINKING);
+ body_sequence = gsi_stmt (gsi);
+ }
+ }
+
+ /* This sequence will collect all the top-level statements in the body of
+ the data region we are about to construct. */
+ gimple_seq region_body = NULL;
+ /* This sequence will collect consecutive statements to be put into a
+ gang-single region. */
+ gimple_seq gang_single_seq = NULL;
+ /* Flag recording whether the gang_single_seq only contains copies to
+ local variables. These may be loop setup code that should not be
+ separated from the loop. */
+ bool only_simple_assignments = true;
+
+ /* Precompute the control flow region information to determine whether an
+ OpenACC loop is executed conditionally or unconditionally. */
+ control_flow_regions cf_regions (body_sequence);
+
+ /* Iterate over the statements in the kernels region's body. */
+ size_t idx = 0;
+ gimple_stmt_iterator gsi, gsi_n;
+ for (gsi = gsi_start (body_sequence); !gsi_end_p (gsi); gsi = gsi_n, idx++)
+ {
+ /* Advance the iterator here because otherwise it would be invalidated
+ by moving statements below. */
+ gsi_n = gsi;
+ gsi_next (&gsi_n);
+
+ gimple *stmt = gsi_stmt (gsi);
+ gimple *omp_for = top_level_omp_for_in_stmt (stmt);
+ bool is_unconditional_oacc_for_loop = false;
+ if (omp_for != NULL)
+ is_unconditional_oacc_for_loop
+ = cf_regions.is_unconditional_oacc_for_loop (idx);
+ if (omp_for != NULL
+ && is_unconditional_oacc_for_loop)
+ {
+ /* This is an OMP for statement, put it into a separate region.
+ But first, construct a gang-single region containing any
+ complex sequential statements we may have seen. */
+ if (gang_single_seq != NULL && !only_simple_assignments)
+ {
+ gimple *single_region
+ = make_region_seq (loc, gang_single_seq,
+ num_gangs_clause,
+ num_workers_clause,
+ vector_length_clause,
+ kernels_clauses);
+ gimple_seq_add_stmt (&region_body, single_region);
+ }
+ else if (gang_single_seq != NULL && only_simple_assignments)
+ {
+ /* There is a sequence of sequential statements preceding this
+ loop, but they are all simple assignments. This is
+ probably setup code for the loop; in particular, Fortran DO
+ loops are preceded by code to copy the loop limit variable
+ to a temporary. Group this code together with the loop
+ itself. */
+ gimple_seq_add_stmt (&gang_single_seq, stmt);
+ stmt = gimple_build_bind (NULL, gang_single_seq,
+ make_node (BLOCK));
+ }
+ gang_single_seq = NULL;
+ only_simple_assignments = true;
+
+ gimple_seq parallel_seq = NULL;
+ gimple_seq_add_stmt (&parallel_seq, stmt);
+ gimple *parallel_region
+ = make_region_loop_nest (omp_for, parallel_seq,
+ num_gangs_clause,
+ num_workers_clause,
+ vector_length_clause,
+ kernels_clauses);
+ gimple_seq_add_stmt (&region_body, parallel_region);
+ }
+ else
+ {
+ if (omp_for != NULL)
+ {
+ gcc_checking_assert (!is_unconditional_oacc_for_loop);
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, omp_for,
+ "unparallelized loop nest"
+ " in OpenACC %<kernels%> region:"
+ " it's executed conditionally\n");
+ }
+
+ /* This is not an unconditional OMP for statement, so it will be
+ put into a gang-single region. */
+ gimple_seq_add_stmt (&gang_single_seq, stmt);
+ /* Is this a simple assignment? We call it simple if it is an
+ assignment to an artificial local variable. This captures
+ Fortran loop setup code computing loop bounds and offsets. */
+ bool is_simple_assignment
+ = (gimple_code (stmt) == GIMPLE_ASSIGN
+ && TREE_CODE (gimple_assign_lhs (stmt)) == VAR_DECL
+ && DECL_ARTIFICIAL (gimple_assign_lhs (stmt)));
+ if (!is_simple_assignment)
+ only_simple_assignments = false;
+ }
+ }
+
+ /* If we did not emit a new region, and are not going to emit one now
+ (that is, the original region was empty), prepare to emit a dummy so as
+ to preserve the original construct, which other processing (at least
+ test cases) depend on. */
+ if (region_body == NULL && gang_single_seq == NULL)
+ {
+ gimple *stmt = gimple_build_nop ();
+ gimple_set_location (stmt, loc);
+ gimple_seq_add_stmt (&gang_single_seq, stmt);
+ }
+
+ /* Gather up any remaining gang-single statements. */
+ if (gang_single_seq != NULL)
+ {
+ gimple *single_region
+ = make_region_seq (loc, gang_single_seq,
+ num_gangs_clause,
+ num_workers_clause,
+ vector_length_clause,
+ kernels_clauses);
+ gimple_seq_add_stmt (&region_body, single_region);
+ }
+
+ /* We want to launch these kernels asynchronously. If the original
+ kernels region had an async clause, this is done automatically because
+ that async clause was copied to the individual regions we created.
+ Otherwise, add an async clause to each newly created region, as well as
+ a wait directive at the end. */
+ if (async_clause == NULL)
+ add_async_clauses_and_wait (loc, &region_body);
+
+ tree kernels_locals = gimple_bind_vars (as_a <gbind *> (kernels_body));
+ gimple *body = gimple_build_bind (kernels_locals, region_body,
+ make_node (BLOCK));
+
+ /* If we found variables declared in nested scopes, build a data region to
+ map them to the device. */
+ body = maybe_build_inner_data_region (loc, body, inner_bind_vars,
+ inner_cleanup);
+
+ return body;
+}
+
+/* Decompose one OpenACC 'kernels' construct into an OpenACC 'data' construct
+ containing the original OpenACC 'kernels' construct's region cut up into a
+ sequence of compute constructs. */
+
+static gimple *
+omp_oacc_kernels_decompose_1 (gimple *kernels_stmt)
+{
+ gcc_checking_assert (gimple_omp_target_kind (kernels_stmt)
+ == GF_OMP_TARGET_KIND_OACC_KERNELS);
+ location_t loc = gimple_location (kernels_stmt);
+
+ /* Collect the data clauses of the OpenACC 'kernels' directive and create a
+ new OpenACC 'data' construct with those clauses. */
+ tree kernels_clauses = gimple_omp_target_clauses (kernels_stmt);
+ tree data_clauses = NULL;
+ for (tree c = kernels_clauses; c; c = OMP_CLAUSE_CHAIN (c))
+ {
+ /* Certain clauses are copied to the enclosing OpenACC 'data'. Other
+ clauses remain on the OpenACC 'kernels'. */
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
+ {
+ tree decl = OMP_CLAUSE_DECL (c);
+ HOST_WIDE_INT map_kind = OMP_CLAUSE_MAP_KIND (c);
+ switch (map_kind)
+ {
+ default:
+ if (map_kind == GOMP_MAP_ALLOC
+ && integer_zerop (OMP_CLAUSE_SIZE (c)))
+ /* ??? This is an alloc clause for mapping a pointer whose
+ target is already mapped. We leave these on the inner
+ compute constructs because moving them to the outer data
+ region causes runtime errors. */
+ break;
+
+ /* For non-artificial variables, and for non-declaration
+ expressions like A[0:n], copy the clause to the data
+ region. */
+ if ((DECL_P (decl) && !DECL_ARTIFICIAL (decl))
+ || !DECL_P (decl))
+ {
+ tree new_clause = build_omp_clause (OMP_CLAUSE_LOCATION (c),
+ OMP_CLAUSE_MAP);
+ OMP_CLAUSE_SET_MAP_KIND (new_clause, map_kind);
+ /* This must be unshared here to avoid "incorrect sharing
+ of tree nodes" errors from verify_gimple. */
+ OMP_CLAUSE_DECL (new_clause) = unshare_expr (decl);
+ OMP_CLAUSE_SIZE (new_clause) = OMP_CLAUSE_SIZE (c);
+ OMP_CLAUSE_CHAIN (new_clause) = data_clauses;
+ data_clauses = new_clause;
+
+ /* Now that this data is mapped, turn the data clause on the
+ inner OpenACC 'kernels' into a 'present' clause. */
+ OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_PRESENT);
+ }
+ break;
+
+ case GOMP_MAP_POINTER:
+ case GOMP_MAP_TO_PSET:
+ case GOMP_MAP_FORCE_TOFROM:
+ case GOMP_MAP_FIRSTPRIVATE_POINTER:
+ case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
+ /* ??? Copying these map kinds leads to internal compiler
+ errors in later passes. */
+ break;
+ }
+ }
+ else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
+ {
+ /* If there is an 'if' clause, it must be duplicated to the
+ enclosing data region. Temporarily remove the if clause's
+ chain to avoid copying it. */
+ tree saved_chain = OMP_CLAUSE_CHAIN (c);
+ OMP_CLAUSE_CHAIN (c) = NULL;
+ tree new_if_clause = unshare_expr (c);
+ OMP_CLAUSE_CHAIN (c) = saved_chain;
+ OMP_CLAUSE_CHAIN (new_if_clause) = data_clauses;
+ data_clauses = new_if_clause;
+ }
+ }
+ /* Restore the original order of the clauses. */
+ data_clauses = nreverse (data_clauses);
+
+ gimple *data_region
+ = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DATA_KERNELS,
+ data_clauses);
+ gimple_set_location (data_region, loc);
+
+ /* Transform the body of the kernels region into a sequence of compute
+ constructs. */
+ gimple *body = decompose_kernels_region_body (kernels_stmt,
+ kernels_clauses);
+
+ /* Put the transformed pieces together. The entire body of the region is
+ wrapped in a try-finally statement that calls __builtin_GOACC_data_end
+ for cleanup. */
+ gimple *try_stmt = make_data_region_try_statement (loc, body);
+ gimple_omp_set_body (data_region, try_stmt);
+
+ return data_region;
+}
+
+
+/* Decompose OpenACC 'kernels' constructs in the current function. */
+
+static tree
+omp_oacc_kernels_decompose_callback_stmt (gimple_stmt_iterator *gsi_p,
+ bool *handled_ops_p,
+ struct walk_stmt_info *)
+{
+ gimple *stmt = gsi_stmt (*gsi_p);
+
+ if ((gimple_code (stmt) == GIMPLE_OMP_TARGET)
+ && gimple_omp_target_kind (stmt) == GF_OMP_TARGET_KIND_OACC_KERNELS)
+ {
+ gimple *stmt_new = omp_oacc_kernels_decompose_1 (stmt);
+ gsi_replace (gsi_p, stmt_new, false);
+ *handled_ops_p = true;
+ }
+ else
+ *handled_ops_p = false;
+
+ return NULL;
+}
+
+static unsigned int
+omp_oacc_kernels_decompose (void)
+{
+ gimple_seq body = gimple_body (current_function_decl);
+
+ struct walk_stmt_info wi;
+ memset (&wi, 0, sizeof (wi));
+ walk_gimple_seq_mod (&body, omp_oacc_kernels_decompose_callback_stmt, NULL,
+ &wi);
+
+ gimple_set_body (current_function_decl, body);
+
+ return 0;
+}
+
+
+namespace {
+
+const pass_data pass_data_omp_oacc_kernels_decompose =
+{
+ GIMPLE_PASS, /* type */
+ "omp_oacc_kernels_decompose", /* name */
+ OPTGROUP_OMP, /* optinfo_flags */
+ TV_NONE, /* tv_id */
+ PROP_gimple_any, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+class pass_omp_oacc_kernels_decompose : public gimple_opt_pass
+{
+public:
+ pass_omp_oacc_kernels_decompose (gcc::context *ctxt)
+ : gimple_opt_pass (pass_data_omp_oacc_kernels_decompose, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ virtual bool gate (function *)
+ {
+ return (flag_openacc
+ && flag_openacc_kernels == OPENACC_KERNELS_DECOMPOSE);
+ }
+ virtual unsigned int execute (function *)
+ {
+ return omp_oacc_kernels_decompose ();
+ }
+
+}; // class pass_omp_oacc_kernels_decompose
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_omp_oacc_kernels_decompose (gcc::context *ctxt)
+{
+ return new pass_omp_oacc_kernels_decompose (ctxt);
+}
diff --git a/gcc/omp-offload.c b/gcc/omp-offload.c
index 4490701..9013961 100644
--- a/gcc/omp-offload.c
+++ b/gcc/omp-offload.c
@@ -1762,12 +1762,59 @@ execute_oacc_device_lower ()
flag_openacc_dims = (char *)&flag_openacc_dims;
}
+ bool is_oacc_parallel
+ = (lookup_attribute ("oacc parallel",
+ DECL_ATTRIBUTES (current_function_decl)) != NULL);
bool is_oacc_kernels
= (lookup_attribute ("oacc kernels",
DECL_ATTRIBUTES (current_function_decl)) != NULL);
+ bool is_oacc_serial
+ = (lookup_attribute ("oacc serial",
+ DECL_ATTRIBUTES (current_function_decl)) != NULL);
+ bool is_oacc_parallel_kernels_parallelized
+ = (lookup_attribute ("oacc parallel_kernels_parallelized",
+ DECL_ATTRIBUTES (current_function_decl)) != NULL);
+ bool is_oacc_parallel_kernels_gang_single
+ = (lookup_attribute ("oacc parallel_kernels_gang_single",
+ DECL_ATTRIBUTES (current_function_decl)) != NULL);
+ int fn_level = oacc_fn_attrib_level (attrs);
+ bool is_oacc_routine = (fn_level >= 0);
+ gcc_checking_assert (is_oacc_parallel
+ + is_oacc_kernels
+ + is_oacc_serial
+ + is_oacc_parallel_kernels_parallelized
+ + is_oacc_parallel_kernels_gang_single
+ + is_oacc_routine
+ == 1);
+
bool is_oacc_kernels_parallelized
= (lookup_attribute ("oacc kernels parallelized",
DECL_ATTRIBUTES (current_function_decl)) != NULL);
+ if (is_oacc_kernels_parallelized)
+ gcc_checking_assert (is_oacc_kernels);
+
+ if (dump_file)
+ {
+ if (is_oacc_parallel)
+ fprintf (dump_file, "Function is OpenACC parallel offload\n");
+ else if (is_oacc_kernels)
+ fprintf (dump_file, "Function is %s OpenACC kernels offload\n",
+ (is_oacc_kernels_parallelized
+ ? "parallelized" : "unparallelized"));
+ else if (is_oacc_serial)
+ fprintf (dump_file, "Function is OpenACC serial offload\n");
+ else if (is_oacc_parallel_kernels_parallelized)
+ fprintf (dump_file, "Function is %s OpenACC kernels offload\n",
+ "parallel_kernels_parallelized");
+ else if (is_oacc_parallel_kernels_gang_single)
+ fprintf (dump_file, "Function is %s OpenACC kernels offload\n",
+ "parallel_kernels_gang_single");
+ else if (is_oacc_routine)
+ fprintf (dump_file, "Function is OpenACC routine level %d\n",
+ fn_level);
+ else
+ gcc_unreachable ();
+ }
/* Unparallelized OpenACC kernels constructs must get launched as 1 x 1 x 1
kernels, so remove the parallelism dimensions function attributes
@@ -1780,22 +1827,10 @@ execute_oacc_device_lower ()
/* Discover, partition and process the loops. */
oacc_loop *loops = oacc_loop_discovery ();
- int fn_level = oacc_fn_attrib_level (attrs);
- if (dump_file)
- {
- if (fn_level >= 0)
- fprintf (dump_file, "Function is OpenACC routine level %d\n",
- fn_level);
- else if (is_oacc_kernels)
- fprintf (dump_file, "Function is %s OpenACC kernels offload\n",
- (is_oacc_kernels_parallelized
- ? "parallelized" : "unparallelized"));
- else
- fprintf (dump_file, "Function is OpenACC parallel offload\n");
- }
-
- unsigned outer_mask = fn_level >= 0 ? GOMP_DIM_MASK (fn_level) - 1 : 0;
+ unsigned outer_mask = 0;
+ if (is_oacc_routine)
+ outer_mask = GOMP_DIM_MASK (fn_level) - 1;
unsigned used_mask = oacc_loop_partition (loops, outer_mask);
/* OpenACC kernels constructs are special: they currently don't use the
generic oacc_loop infrastructure and attribute/dimension processing. */
@@ -1817,6 +1852,11 @@ execute_oacc_device_lower ()
fprintf (dump_file, "]\n");
}
+ /* Verify that for OpenACC 'kernels' decomposed "gang-single" parts we launch
+ a single gang only. */
+ if (is_oacc_parallel_kernels_gang_single)
+ gcc_checking_assert (dims[GOMP_DIM_GANG] == 1);
+
oacc_loop_process (loops);
if (dump_file)
{
diff --git a/gcc/optabs-tree.c b/gcc/optabs-tree.c
index badd30b..a8968f3 100644
--- a/gcc/optabs-tree.c
+++ b/gcc/optabs-tree.c
@@ -170,6 +170,22 @@ optab_for_tree_code (enum tree_code code, const_tree type,
return (TYPE_UNSIGNED (type)
? vec_widen_ushiftl_lo_optab : vec_widen_sshiftl_lo_optab);
+ case VEC_WIDEN_PLUS_LO_EXPR:
+ return (TYPE_UNSIGNED (type)
+ ? vec_widen_uaddl_lo_optab : vec_widen_saddl_lo_optab);
+
+ case VEC_WIDEN_PLUS_HI_EXPR:
+ return (TYPE_UNSIGNED (type)
+ ? vec_widen_uaddl_hi_optab : vec_widen_saddl_hi_optab);
+
+ case VEC_WIDEN_MINUS_LO_EXPR:
+ return (TYPE_UNSIGNED (type)
+ ? vec_widen_usubl_lo_optab : vec_widen_ssubl_lo_optab);
+
+ case VEC_WIDEN_MINUS_HI_EXPR:
+ return (TYPE_UNSIGNED (type)
+ ? vec_widen_usubl_hi_optab : vec_widen_ssubl_hi_optab);
+
case VEC_UNPACK_HI_EXPR:
return (TYPE_UNSIGNED (type)
? vec_unpacku_hi_optab : vec_unpacks_hi_optab);
@@ -321,6 +337,35 @@ supportable_convert_operation (enum tree_code code,
return false;
}
+/* Return true iff vec_cmp_optab/vec_cmpu_optab can handle a vector comparison
+ for code CODE, comparing operands of type VALUE_TYPE and producing a result
+ of type MASK_TYPE. */
+
+static bool
+vec_cmp_icode_p (tree value_type, tree mask_type, enum tree_code code)
+{
+ enum rtx_code rcode = get_rtx_code_1 (code, TYPE_UNSIGNED (value_type));
+ if (rcode == UNKNOWN)
+ return false;
+
+ return can_vec_cmp_compare_p (rcode, TYPE_MODE (value_type),
+ TYPE_MODE (mask_type));
+}
+
+/* Return true iff vec_cmpeq_optab can handle a vector comparison for code
+ CODE, comparing operands of type VALUE_TYPE and producing a result of type
+ MASK_TYPE. */
+
+static bool
+vec_cmp_eq_icode_p (tree value_type, tree mask_type, enum tree_code code)
+{
+ if (code != EQ_EXPR && code != NE_EXPR)
+ return false;
+
+ return get_vec_cmp_eq_icode (TYPE_MODE (value_type), TYPE_MODE (mask_type))
+ != CODE_FOR_nothing;
+}
+
/* Return TRUE if appropriate vector insn is available
for vector comparison expr with vector type VALUE_TYPE
and resulting mask with MASK_TYPE. */
@@ -328,14 +373,8 @@ supportable_convert_operation (enum tree_code code,
bool
expand_vec_cmp_expr_p (tree value_type, tree mask_type, enum tree_code code)
{
- if (get_vec_cmp_icode (TYPE_MODE (value_type), TYPE_MODE (mask_type),
- TYPE_UNSIGNED (value_type)) != CODE_FOR_nothing)
- return true;
- if ((code == EQ_EXPR || code == NE_EXPR)
- && (get_vec_cmp_eq_icode (TYPE_MODE (value_type), TYPE_MODE (mask_type))
- != CODE_FOR_nothing))
- return true;
- return false;
+ return vec_cmp_icode_p (value_type, mask_type, code)
+ || vec_cmp_eq_icode_p (value_type, mask_type, code);
}
/* Return true iff vcond_optab/vcondu_optab can handle a vector
@@ -345,8 +384,12 @@ expand_vec_cmp_expr_p (tree value_type, tree mask_type, enum tree_code code)
static bool
vcond_icode_p (tree value_type, tree cmp_op_type, enum tree_code code)
{
- return can_vcond_compare_p (get_rtx_code (code, TYPE_UNSIGNED (cmp_op_type)),
- TYPE_MODE (value_type), TYPE_MODE (cmp_op_type));
+ enum rtx_code rcode = get_rtx_code_1 (code, TYPE_UNSIGNED (cmp_op_type));
+ if (rcode == UNKNOWN)
+ return false;
+
+ return can_vcond_compare_p (rcode, TYPE_MODE (value_type),
+ TYPE_MODE (cmp_op_type));
}
/* Return true iff vcondeq_optab can handle a vector comparison for code CODE,
@@ -377,8 +420,7 @@ expand_vec_cond_expr_p (tree value_type, tree cmp_op_type, enum tree_code code)
TYPE_MODE (cmp_op_type)) != CODE_FOR_nothing)
return true;
- if (maybe_ne (GET_MODE_SIZE (value_mode), GET_MODE_SIZE (cmp_op_mode))
- || maybe_ne (GET_MODE_NUNITS (value_mode), GET_MODE_NUNITS (cmp_op_mode)))
+ if (maybe_ne (GET_MODE_NUNITS (value_mode), GET_MODE_NUNITS (cmp_op_mode)))
return false;
if (TREE_CODE_CLASS (code) != tcc_comparison)
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 1820b91..bdc692b 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -28,8 +28,8 @@ along with GCC; see the file COPYING3. If not see
#include "memmodel.h"
#include "predict.h"
#include "tm_p.h"
-#include "expmed.h"
#include "optabs.h"
+#include "expmed.h"
#include "emit-rtl.h"
#include "recog.h"
#include "diagnostic-core.h"
@@ -44,6 +44,8 @@ along with GCC; see the file COPYING3. If not see
#include "expr.h"
#include "optabs-tree.h"
#include "libfuncs.h"
+#include "internal-fn.h"
+#include "langhooks.h"
static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
machine_mode *);
@@ -926,6 +928,289 @@ expand_doubleword_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
emit_move_insn (product_high, adjust);
return product;
}
+
+/* Subroutine of expand_binop. Optimize unsigned double-word OP0 % OP1 for
+ constant OP1. If for some bit in [BITS_PER_WORD / 2, BITS_PER_WORD] range
+ (prefer higher bits) ((1w << bit) % OP1) == 1, then the modulo can be
+ computed in word-mode as ((OP0 & (bit - 1)) + ((OP0 >> bit) & (bit - 1))
+ + (OP0 >> (2 * bit))) % OP1. Whether we need to sum 2, 3 or 4 values
+ depends on the bit value, if 2, then carry from the addition needs to be
+ added too, i.e. like:
+ sum += __builtin_add_overflow (low, high, &sum)
+
+ Optimize signed double-word OP0 % OP1 similarly, just apply some correction
+ factor to the sum before doing unsigned remainder, in the form of
+ sum += (((signed) OP0 >> (2 * BITS_PER_WORD - 1)) & const);
+ then perform unsigned
+ remainder = sum % OP1;
+ and finally
+ remainder += ((signed) OP0 >> (2 * BITS_PER_WORD - 1)) & (1 - OP1); */
+
+static rtx
+expand_doubleword_mod (machine_mode mode, rtx op0, rtx op1, bool unsignedp)
+{
+ if (INTVAL (op1) <= 1 || (INTVAL (op1) & 1) == 0)
+ return NULL_RTX;
+
+ rtx_insn *last = get_last_insn ();
+ for (int bit = BITS_PER_WORD; bit >= BITS_PER_WORD / 2; bit--)
+ {
+ wide_int w = wi::shifted_mask (bit, 1, false, 2 * BITS_PER_WORD);
+ if (wi::ne_p (wi::umod_trunc (w, INTVAL (op1)), 1))
+ continue;
+ rtx sum = NULL_RTX, mask = NULL_RTX;
+ if (bit == BITS_PER_WORD)
+ {
+ /* For signed modulo we need to add correction to the sum
+ and that might again overflow. */
+ if (!unsignedp)
+ continue;
+ if (optab_handler (uaddv4_optab, word_mode) == CODE_FOR_nothing)
+ continue;
+ tree wtype = lang_hooks.types.type_for_mode (word_mode, 1);
+ if (wtype == NULL_TREE)
+ continue;
+ tree ctype = build_complex_type (wtype);
+ if (TYPE_MODE (ctype) != GET_MODE_COMPLEX_MODE (word_mode))
+ continue;
+ machine_mode cmode = TYPE_MODE (ctype);
+ rtx op00 = operand_subword_force (op0, 0, mode);
+ rtx op01 = operand_subword_force (op0, 1, mode);
+ rtx cres = gen_rtx_CONCAT (cmode, gen_reg_rtx (word_mode),
+ gen_reg_rtx (word_mode));
+ tree lhs = make_tree (ctype, cres);
+ tree arg0 = make_tree (wtype, op00);
+ tree arg1 = make_tree (wtype, op01);
+ expand_addsub_overflow (UNKNOWN_LOCATION, PLUS_EXPR, lhs, arg0,
+ arg1, true, true, true, false, NULL);
+ sum = expand_simple_binop (word_mode, PLUS, XEXP (cres, 0),
+ XEXP (cres, 1), NULL_RTX, 1,
+ OPTAB_DIRECT);
+ if (sum == NULL_RTX)
+ return NULL_RTX;
+ }
+ else
+ {
+ /* Code below uses GEN_INT, so we need the masks to be representable
+ in HOST_WIDE_INTs. */
+ if (bit >= HOST_BITS_PER_WIDE_INT)
+ continue;
+ /* If op0 is e.g. -1 or -2 unsigned, then the 2 additions might
+ overflow. Consider 64-bit -1ULL for word size 32, if we add
+ 0x7fffffffU + 0x7fffffffU + 3U, it wraps around to 1. */
+ if (bit == BITS_PER_WORD - 1)
+ continue;
+
+ int count = (2 * BITS_PER_WORD + bit - 1) / bit;
+ rtx sum_corr = NULL_RTX;
+
+ if (!unsignedp)
+ {
+ /* For signed modulo, compute it as unsigned modulo of
+ sum with a correction added to it if OP0 is negative,
+ such that the result can be computed as unsigned
+ remainder + ((OP1 >> (2 * BITS_PER_WORD - 1)) & (1 - OP1). */
+ w = wi::min_value (2 * BITS_PER_WORD, SIGNED);
+ wide_int wmod1 = wi::umod_trunc (w, INTVAL (op1));
+ wide_int wmod2 = wi::smod_trunc (w, INTVAL (op1));
+ /* wmod2 == -wmod1. */
+ wmod2 = wmod2 + (INTVAL (op1) - 1);
+ if (wi::ne_p (wmod1, wmod2))
+ {
+ wide_int wcorr = wmod2 - wmod1;
+ if (wi::neg_p (w))
+ wcorr = wcorr + INTVAL (op1);
+ /* Now verify if the count sums can't overflow, and punt
+ if they could. */
+ w = wi::mask (bit, false, 2 * BITS_PER_WORD);
+ w = w * (count - 1);
+ w = w + wi::mask (2 * BITS_PER_WORD - (count - 1) * bit,
+ false, 2 * BITS_PER_WORD);
+ w = w + wcorr;
+ w = wi::lrshift (w, BITS_PER_WORD);
+ if (wi::ne_p (w, 0))
+ continue;
+
+ mask = operand_subword_force (op0, WORDS_BIG_ENDIAN ? 0 : 1,
+ mode);
+ mask = expand_simple_binop (word_mode, ASHIFTRT, mask,
+ GEN_INT (BITS_PER_WORD - 1),
+ NULL_RTX, 0, OPTAB_DIRECT);
+ if (mask == NULL_RTX)
+ return NULL_RTX;
+ sum_corr = immed_wide_int_const (wcorr, word_mode);
+ sum_corr = expand_simple_binop (word_mode, AND, mask,
+ sum_corr, NULL_RTX, 1,
+ OPTAB_DIRECT);
+ if (sum_corr == NULL_RTX)
+ return NULL_RTX;
+ }
+ }
+
+ for (int i = 0; i < count; i++)
+ {
+ rtx v = op0;
+ if (i)
+ v = expand_simple_binop (mode, LSHIFTRT, v, GEN_INT (i * bit),
+ NULL_RTX, 1, OPTAB_DIRECT);
+ if (v == NULL_RTX)
+ return NULL_RTX;
+ v = lowpart_subreg (word_mode, v, mode);
+ if (v == NULL_RTX)
+ return NULL_RTX;
+ if (i != count - 1)
+ v = expand_simple_binop (word_mode, AND, v,
+ GEN_INT ((HOST_WIDE_INT_1U << bit)
+ - 1), NULL_RTX, 1,
+ OPTAB_DIRECT);
+ if (v == NULL_RTX)
+ return NULL_RTX;
+ if (sum == NULL_RTX)
+ sum = v;
+ else
+ sum = expand_simple_binop (word_mode, PLUS, sum, v, NULL_RTX,
+ 1, OPTAB_DIRECT);
+ if (sum == NULL_RTX)
+ return NULL_RTX;
+ }
+ if (sum_corr)
+ {
+ sum = expand_simple_binop (word_mode, PLUS, sum, sum_corr,
+ NULL_RTX, 1, OPTAB_DIRECT);
+ if (sum == NULL_RTX)
+ return NULL_RTX;
+ }
+ }
+ rtx remainder = expand_divmod (1, TRUNC_MOD_EXPR, word_mode, sum, op1,
+ NULL_RTX, 1, OPTAB_DIRECT);
+ if (remainder == NULL_RTX)
+ return NULL_RTX;
+
+ if (!unsignedp)
+ {
+ if (mask == NULL_RTX)
+ {
+ mask = operand_subword_force (op0, WORDS_BIG_ENDIAN ? 0 : 1,
+ mode);
+ mask = expand_simple_binop (word_mode, ASHIFTRT, mask,
+ GEN_INT (BITS_PER_WORD - 1),
+ NULL_RTX, 0, OPTAB_DIRECT);
+ if (mask == NULL_RTX)
+ return NULL_RTX;
+ }
+ mask = expand_simple_binop (word_mode, AND, mask,
+ GEN_INT (1 - INTVAL (op1)),
+ NULL_RTX, 1, OPTAB_DIRECT);
+ if (mask == NULL_RTX)
+ return NULL_RTX;
+ remainder = expand_simple_binop (word_mode, PLUS, remainder,
+ mask, NULL_RTX, 1, OPTAB_DIRECT);
+ if (remainder == NULL_RTX)
+ return NULL_RTX;
+ }
+
+ remainder = convert_modes (mode, word_mode, remainder, unsignedp);
+ /* Punt if we need any library calls. */
+ for (; last; last = NEXT_INSN (last))
+ if (CALL_P (last))
+ return NULL_RTX;
+ return remainder;
+ }
+ return NULL_RTX;
+}
+
+/* Similarly to the above function, but compute both quotient and remainder.
+ Quotient can be computed from the remainder as:
+ rem = op0 % op1; // Handled using expand_doubleword_mod
+ quot = (op0 - rem) * inv; // inv is multiplicative inverse of op1 modulo
+ // 2 * BITS_PER_WORD
+
+ We can also handle cases where op1 is a multiple of power of two constant
+ and constant handled by expand_doubleword_mod.
+ op11 = 1 << __builtin_ctz (op1);
+ op12 = op1 / op11;
+ rem1 = op0 % op12; // Handled using expand_doubleword_mod
+ quot1 = (op0 - rem1) * inv; // inv is multiplicative inverse of op12 modulo
+ // 2 * BITS_PER_WORD
+ rem = (quot1 % op11) * op12 + rem1;
+ quot = quot1 / op11; */
+
+rtx
+expand_doubleword_divmod (machine_mode mode, rtx op0, rtx op1, rtx *rem,
+ bool unsignedp)
+{
+ *rem = NULL_RTX;
+
+ /* Negative dividend should have been optimized into positive,
+ similarly modulo by 1 and modulo by power of two is optimized
+ differently too. */
+ if (INTVAL (op1) <= 1 || pow2p_hwi (INTVAL (op1)))
+ return NULL_RTX;
+
+ rtx op11 = const1_rtx;
+ rtx op12 = op1;
+ if ((INTVAL (op1) & 1) == 0)
+ {
+ int bit = ctz_hwi (INTVAL (op1));
+ op11 = GEN_INT (HOST_WIDE_INT_1 << bit);
+ op12 = GEN_INT (INTVAL (op1) >> bit);
+ }
+
+ rtx rem1 = expand_doubleword_mod (mode, op0, op12, unsignedp);
+ if (rem1 == NULL_RTX)
+ return NULL_RTX;
+
+ int prec = 2 * BITS_PER_WORD;
+ wide_int a = wide_int::from (INTVAL (op12), prec + 1, UNSIGNED);
+ wide_int b = wi::shifted_mask (prec, 1, false, prec + 1);
+ wide_int m = wide_int::from (wi::mod_inv (a, b), prec, UNSIGNED);
+ rtx inv = immed_wide_int_const (m, mode);
+
+ rtx_insn *last = get_last_insn ();
+ rtx quot1 = expand_simple_binop (mode, MINUS, op0, rem1,
+ NULL_RTX, unsignedp, OPTAB_DIRECT);
+ if (quot1 == NULL_RTX)
+ return NULL_RTX;
+
+ quot1 = expand_simple_binop (mode, MULT, quot1, inv,
+ NULL_RTX, unsignedp, OPTAB_DIRECT);
+ if (quot1 == NULL_RTX)
+ return NULL_RTX;
+
+ if (op11 != const1_rtx)
+ {
+ rtx rem2 = expand_divmod (1, TRUNC_MOD_EXPR, mode, quot1, op11,
+ NULL_RTX, unsignedp, OPTAB_DIRECT);
+ if (rem2 == NULL_RTX)
+ return NULL_RTX;
+
+ rem2 = expand_simple_binop (mode, MULT, rem2, op12, NULL_RTX,
+ unsignedp, OPTAB_DIRECT);
+ if (rem2 == NULL_RTX)
+ return NULL_RTX;
+
+ rem2 = expand_simple_binop (mode, PLUS, rem2, rem1, NULL_RTX,
+ unsignedp, OPTAB_DIRECT);
+ if (rem2 == NULL_RTX)
+ return NULL_RTX;
+
+ rtx quot2 = expand_divmod (0, TRUNC_DIV_EXPR, mode, quot1, op11,
+ NULL_RTX, unsignedp, OPTAB_DIRECT);
+ if (quot2 == NULL_RTX)
+ return NULL_RTX;
+
+ rem1 = rem2;
+ quot1 = quot2;
+ }
+
+ /* Punt if we need any library calls. */
+ for (; last; last = NEXT_INSN (last))
+ if (CALL_P (last))
+ return NULL_RTX;
+
+ *rem = rem1;
+ return quot1;
+}
/* Wrapper around expand_binop which takes an rtx code to specify
the operation to perform, not an optab pointer. All other
@@ -1806,6 +2091,54 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
}
}
+ /* Attempt to synthetize double word modulo by constant divisor. */
+ if ((binoptab == umod_optab
+ || binoptab == smod_optab
+ || binoptab == udiv_optab
+ || binoptab == sdiv_optab)
+ && optimize
+ && CONST_INT_P (op1)
+ && is_int_mode (mode, &int_mode)
+ && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
+ && optab_handler ((binoptab == umod_optab || binoptab == udiv_optab)
+ ? udivmod_optab : sdivmod_optab,
+ int_mode) == CODE_FOR_nothing
+ && optab_handler (and_optab, word_mode) != CODE_FOR_nothing
+ && optab_handler (add_optab, word_mode) != CODE_FOR_nothing
+ && optimize_insn_for_speed_p ())
+ {
+ rtx res = NULL_RTX;
+ if ((binoptab == umod_optab || binoptab == smod_optab)
+ && (INTVAL (op1) & 1) == 0)
+ res = expand_doubleword_mod (int_mode, op0, op1,
+ binoptab == umod_optab);
+ else
+ {
+ rtx quot = expand_doubleword_divmod (int_mode, op0, op1, &res,
+ binoptab == umod_optab
+ || binoptab == udiv_optab);
+ if (quot == NULL_RTX)
+ res = NULL_RTX;
+ else if (binoptab == udiv_optab || binoptab == sdiv_optab)
+ res = quot;
+ }
+ if (res != NULL_RTX)
+ {
+ if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing)
+ {
+ rtx_insn *move = emit_move_insn (target ? target : res,
+ res);
+ set_dst_reg_note (move, REG_EQUAL,
+ gen_rtx_fmt_ee (optab_to_code (binoptab),
+ int_mode, copy_rtx (op0), op1),
+ target ? target : res);
+ }
+ return res;
+ }
+ else
+ delete_insns_since (last);
+ }
+
/* It can't be open-coded in this mode.
Use a library call if one is available and caller says that's ok. */
@@ -3834,23 +4167,59 @@ can_compare_p (enum rtx_code code, machine_mode mode,
return 0;
}
-/* Return whether the backend can emit a vector comparison for code CODE,
- comparing operands of mode CMP_OP_MODE and producing a result with
- VALUE_MODE. */
+/* Return whether RTL code CODE corresponds to an unsigned optab. */
+
+static bool
+unsigned_optab_p (enum rtx_code code)
+{
+ return code == LTU || code == LEU || code == GTU || code == GEU;
+}
+
+/* Return whether the backend-emitted comparison for code CODE, comparing
+ operands of mode VALUE_MODE and producing a result with MASK_MODE, matches
+ operand OPNO of pattern ICODE. */
+
+static bool
+insn_predicate_matches_p (enum insn_code icode, unsigned int opno,
+ enum rtx_code code, machine_mode mask_mode,
+ machine_mode value_mode)
+{
+ rtx reg1 = alloca_raw_REG (value_mode, LAST_VIRTUAL_REGISTER + 1);
+ rtx reg2 = alloca_raw_REG (value_mode, LAST_VIRTUAL_REGISTER + 2);
+ rtx test = alloca_rtx_fmt_ee (code, mask_mode, reg1, reg2);
+ return insn_operand_matches (icode, opno, test);
+}
+
+/* Return whether the backend can emit a vector comparison (vec_cmp/vec_cmpu)
+ for code CODE, comparing operands of mode VALUE_MODE and producing a result
+ with MASK_MODE. */
+
+bool
+can_vec_cmp_compare_p (enum rtx_code code, machine_mode value_mode,
+ machine_mode mask_mode)
+{
+ enum insn_code icode
+ = get_vec_cmp_icode (value_mode, mask_mode, unsigned_optab_p (code));
+ if (icode == CODE_FOR_nothing)
+ return false;
+
+ return insn_predicate_matches_p (icode, 1, code, mask_mode, value_mode);
+}
+
+/* Return whether the backend can emit a vector comparison (vcond/vcondu) for
+ code CODE, comparing operands of mode CMP_OP_MODE and producing a result
+ with VALUE_MODE. */
bool
can_vcond_compare_p (enum rtx_code code, machine_mode value_mode,
machine_mode cmp_op_mode)
{
- enum insn_code icode;
- bool unsigned_p = (code == LTU || code == LEU || code == GTU || code == GEU);
- rtx reg1 = alloca_raw_REG (cmp_op_mode, LAST_VIRTUAL_REGISTER + 1);
- rtx reg2 = alloca_raw_REG (cmp_op_mode, LAST_VIRTUAL_REGISTER + 2);
- rtx test = alloca_rtx_fmt_ee (code, value_mode, reg1, reg2);
-
- return (icode = get_vcond_icode (value_mode, cmp_op_mode, unsigned_p))
- != CODE_FOR_nothing
- && insn_operand_matches (icode, 3, test);
+ enum insn_code icode
+ = get_vcond_icode (value_mode, cmp_op_mode, unsigned_optab_p (code));
+ if (icode == CODE_FOR_nothing)
+ return false;
+
+ return insn_predicate_matches_p (icode, 3, code, value_mode, cmp_op_mode);
}
/* Return whether the backend can emit vector set instructions for inserting
@@ -5403,11 +5772,11 @@ gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
return insn;
}
-/* Return rtx code for TCODE. Use UNSIGNEDP to select signed
+/* Return rtx code for TCODE or UNKNOWN. Use UNSIGNEDP to select signed
or unsigned operation code. */
enum rtx_code
-get_rtx_code (enum tree_code tcode, bool unsignedp)
+get_rtx_code_1 (enum tree_code tcode, bool unsignedp)
{
enum rtx_code code;
switch (tcode)
@@ -5465,11 +5834,23 @@ get_rtx_code (enum tree_code tcode, bool unsignedp)
break;
default:
- gcc_unreachable ();
+ code = UNKNOWN;
+ break;
}
return code;
}
+/* Return rtx code for TCODE. Use UNSIGNEDP to select signed
+ or unsigned operation code. */
+
+enum rtx_code
+get_rtx_code (enum tree_code tcode, bool unsignedp)
+{
+ enum rtx_code code = get_rtx_code_1 (tcode, unsignedp);
+ gcc_assert (code != UNKNOWN);
+ return code;
+}
+
/* Return a comparison rtx of mode CMP_MODE for COND. Use UNSIGNEDP to
select signed or unsigned operators. OPNO holds the index of the
first comparison operand for insn ICODE. Do not generate the
diff --git a/gcc/optabs.def b/gcc/optabs.def
index 78409aa..5607f51 100644
--- a/gcc/optabs.def
+++ b/gcc/optabs.def
@@ -383,6 +383,10 @@ OPTAB_D (vec_widen_smult_even_optab, "vec_widen_smult_even_$a")
OPTAB_D (vec_widen_smult_hi_optab, "vec_widen_smult_hi_$a")
OPTAB_D (vec_widen_smult_lo_optab, "vec_widen_smult_lo_$a")
OPTAB_D (vec_widen_smult_odd_optab, "vec_widen_smult_odd_$a")
+OPTAB_D (vec_widen_ssubl_hi_optab, "vec_widen_ssubl_hi_$a")
+OPTAB_D (vec_widen_ssubl_lo_optab, "vec_widen_ssubl_lo_$a")
+OPTAB_D (vec_widen_saddl_hi_optab, "vec_widen_saddl_hi_$a")
+OPTAB_D (vec_widen_saddl_lo_optab, "vec_widen_saddl_lo_$a")
OPTAB_D (vec_widen_sshiftl_hi_optab, "vec_widen_sshiftl_hi_$a")
OPTAB_D (vec_widen_sshiftl_lo_optab, "vec_widen_sshiftl_lo_$a")
OPTAB_D (vec_widen_umult_even_optab, "vec_widen_umult_even_$a")
@@ -391,6 +395,10 @@ OPTAB_D (vec_widen_umult_lo_optab, "vec_widen_umult_lo_$a")
OPTAB_D (vec_widen_umult_odd_optab, "vec_widen_umult_odd_$a")
OPTAB_D (vec_widen_ushiftl_hi_optab, "vec_widen_ushiftl_hi_$a")
OPTAB_D (vec_widen_ushiftl_lo_optab, "vec_widen_ushiftl_lo_$a")
+OPTAB_D (vec_widen_usubl_hi_optab, "vec_widen_usubl_hi_$a")
+OPTAB_D (vec_widen_usubl_lo_optab, "vec_widen_usubl_lo_$a")
+OPTAB_D (vec_widen_uaddl_hi_optab, "vec_widen_uaddl_hi_$a")
+OPTAB_D (vec_widen_uaddl_lo_optab, "vec_widen_uaddl_lo_$a")
OPTAB_D (sync_add_optab, "sync_add$I$a")
OPTAB_D (sync_and_optab, "sync_and$I$a")
diff --git a/gcc/optabs.h b/gcc/optabs.h
index bfa10c8..87fed90 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -183,6 +183,8 @@ extern bool force_expand_binop (machine_mode, optab, rtx, rtx, rtx, int,
enum optab_methods);
extern rtx expand_vector_broadcast (machine_mode, rtx);
+extern rtx expand_doubleword_divmod (machine_mode, rtx, rtx, rtx *, bool);
+
/* Generate code for a simple binary or unary operation. "Simple" in
this case means "can be unambiguously described by a (mode, code)
pair and mapped to a single optab." */
@@ -244,9 +246,14 @@ enum can_compare_purpose
extern int can_compare_p (enum rtx_code, machine_mode,
enum can_compare_purpose);
-/* Return whether the backend can emit a vector comparison for code CODE,
- comparing operands of mode CMP_OP_MODE and producing a result with
- VALUE_MODE. */
+/* Return whether the backend can emit a vector comparison (vec_cmp/vec_cmpu)
+ for code CODE, comparing operands of mode VALUE_MODE and producing a result
+ with MASK_MODE. */
+extern bool can_vec_cmp_compare_p (enum rtx_code, machine_mode, machine_mode);
+
+/* Return whether the backend can emit a vector comparison (vcond/vcondu) for
+ code CODE, comparing operands of mode CMP_OP_MODE and producing a result
+ with VALUE_MODE. */
extern bool can_vcond_compare_p (enum rtx_code, machine_mode, machine_mode);
/* Return whether the backend can emit vector set instructions for inserting
@@ -366,6 +373,7 @@ extern void expand_insn (enum insn_code icode, unsigned int nops,
extern void expand_jump_insn (enum insn_code icode, unsigned int nops,
class expand_operand *ops);
+extern enum rtx_code get_rtx_code_1 (enum tree_code tcode, bool unsignedp);
extern enum rtx_code get_rtx_code (enum tree_code tcode, bool unsignedp);
extern rtx vector_compare_rtx (machine_mode cmp_mode, enum tree_code tcode,
tree t_op0, tree t_op1, bool unsignedp,
diff --git a/gcc/optc-gen.awk b/gcc/optc-gen.awk
index 9e7e997..be5566b 100644
--- a/gcc/optc-gen.awk
+++ b/gcc/optc-gen.awk
@@ -595,5 +595,29 @@ for (i = 0; i < n_opts; i++) {
}
print "} "
+split("", var_seen, ":")
+print "\n#if !defined(GENERATOR_FILE) && defined(ENABLE_PLUGIN)"
+print "DEBUG_VARIABLE const struct cl_var cl_vars[] =\n{"
+
+for (i = 0; i < n_opts; i++) {
+ name = var_name(flags[i]);
+ if (name == "")
+ continue;
+ var_seen[name] = 1;
}
+for (i = 0; i < n_extra_vars; i++) {
+ var = extra_vars[i]
+ sub(" *=.*", "", var)
+ name = var
+ sub("^.*[ *]", "", name)
+ sub("\\[.*\\]$", "", name)
+ if (name in var_seen)
+ continue;
+ print " { " quote name quote ", offsetof (struct gcc_options, x_" name ") },"
+ var_seen[name] = 1
+}
+
+print " { NULL, (unsigned short) -1 }\n};\n#endif"
+
+}
diff --git a/gcc/optc-save-gen.awk b/gcc/optc-save-gen.awk
index a756835..0a1be8c 100644
--- a/gcc/optc-save-gen.awk
+++ b/gcc/optc-save-gen.awk
@@ -1290,6 +1290,7 @@ for (i = 0; i < n_opts; i++) {
var_opt_val_type[n_opt_val] = otype;
var_opt_val[n_opt_val] = "x_" name;
var_opt_hash[n_opt_val] = flag_set_p("Optimization", flags[i]);
+ var_opt_init[n_opt_val] = opt_args("Init", flags[i]);
n_opt_val++;
}
}
@@ -1361,10 +1362,21 @@ for (i = 0; i < n_opt_val; i++) {
otype = var_opt_val_type[i];
if (otype ~ "^const char \\**$")
print " bp_pack_string (ob, bp, ptr->" name", true);";
- else if (otype ~ "^unsigned")
- print " bp_pack_var_len_unsigned (bp, ptr->" name");";
- else
- print " bp_pack_var_len_int (bp, ptr->" name");";
+ else {
+ if (otype ~ "^unsigned") {
+ sgn = "unsigned";
+ } else {
+ sgn = "int";
+ }
+ if (name ~ "^x_param" && !(otype ~ "^enum ") && var_opt_init[i]) {
+ print " if (" var_opt_init[i] " > (" var_opt_val_type[i] ") 10)";
+ print " bp_pack_var_len_" sgn " (bp, ptr->" name" ^ " var_opt_init[i] ");";
+ print " else";
+ print " bp_pack_var_len_" sgn " (bp, ptr->" name");";
+ } else {
+ print " bp_pack_var_len_" sgn " (bp, ptr->" name");";
+ }
+ }
}
print " for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)";
print " bp_pack_value (bp, ptr->explicit_mask[i], 64);";
@@ -1385,10 +1397,18 @@ for (i = 0; i < n_opt_val; i++) {
print " if (ptr->" name")";
print " ptr->" name" = xstrdup (ptr->" name");";
}
- else if (otype ~ "^unsigned")
- print " ptr->" name" = (" var_opt_val_type[i] ") bp_unpack_var_len_unsigned (bp);";
- else
- print " ptr->" name" = (" var_opt_val_type[i] ") bp_unpack_var_len_int (bp);";
+ else {
+ if (otype ~ "^unsigned") {
+ sgn = "unsigned";
+ } else {
+ sgn = "int";
+ }
+ print " ptr->" name" = (" var_opt_val_type[i] ") bp_unpack_var_len_" sgn " (bp);";
+ if (name ~ "^x_param" && !(otype ~ "^enum ") && var_opt_init[i]) {
+ print " if (" var_opt_init[i] " > (" var_opt_val_type[i] ") 10)";
+ print " ptr->" name" ^= " var_opt_init[i] ";";
+ }
+ }
}
print " for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)";
print " ptr->explicit_mask[i] = bp_unpack_value (bp, 64);";
diff --git a/gcc/opts.c b/gcc/opts.c
index 96291e8..cc1d0cc 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -688,30 +688,26 @@ control_options_for_live_patching (struct gcc_options *opts,
{
case LIVE_PATCHING_INLINE_ONLY_STATIC:
if (opts_set->x_flag_ipa_cp_clone && opts->x_flag_ipa_cp_clone)
- error_at (loc,
- "%<-fipa-cp-clone%> is incompatible with "
- "%<-flive-patching=inline-only-static%>");
+ error_at (loc, "%qs is incompatible with %qs",
+ "-fipa-cp-clone", "-flive-patching=inline-only-static");
else
opts->x_flag_ipa_cp_clone = 0;
if (opts_set->x_flag_ipa_sra && opts->x_flag_ipa_sra)
- error_at (loc,
- "%<-fipa-sra%> is incompatible with "
- "%<-flive-patching=inline-only-static%>");
+ error_at (loc, "%qs is incompatible with %qs",
+ "-fipa-sra", "-flive-patching=inline-only-static");
else
opts->x_flag_ipa_sra = 0;
if (opts_set->x_flag_partial_inlining && opts->x_flag_partial_inlining)
- error_at (loc,
- "%<-fpartial-inlining%> is incompatible with "
- "%<-flive-patching=inline-only-static%>");
+ error_at (loc, "%qs is incompatible with %qs",
+ "-fpartial-inlining", "-flive-patching=inline-only-static");
else
opts->x_flag_partial_inlining = 0;
if (opts_set->x_flag_ipa_cp && opts->x_flag_ipa_cp)
- error_at (loc,
- "%<-fipa-cp%> is incompatible with "
- "%<-flive-patching=inline-only-static%>");
+ error_at (loc, "%qs is incompatible with %qs",
+ "-fipa-cp", "-flive-patching=inline-only-static");
else
opts->x_flag_ipa_cp = 0;
@@ -719,9 +715,9 @@ control_options_for_live_patching (struct gcc_options *opts,
case LIVE_PATCHING_INLINE_CLONE:
/* live patching should disable whole-program optimization. */
if (opts_set->x_flag_whole_program && opts->x_flag_whole_program)
- error_at (loc,
- "%<-fwhole-program%> is incompatible with "
- "%<-flive-patching=inline-only-static|inline-clone%>");
+ error_at (loc, "%qs is incompatible with %qs",
+ "-fwhole-program",
+ "-flive-patching=inline-only-static|inline-clone");
else
opts->x_flag_whole_program = 0;
@@ -730,65 +726,65 @@ control_options_for_live_patching (struct gcc_options *opts,
&& !flag_partial_inlining. */
if (opts_set->x_flag_ipa_pta && opts->x_flag_ipa_pta)
- error_at (loc,
- "%<-fipa-pta%> is incompatible with "
- "%<-flive-patching=inline-only-static|inline-clone%>");
+ error_at (loc, "%qs is incompatible with %qs",
+ "-fipa-pta",
+ "-flive-patching=inline-only-static|inline-clone");
else
opts->x_flag_ipa_pta = 0;
if (opts_set->x_flag_ipa_reference && opts->x_flag_ipa_reference)
- error_at (loc,
- "%<-fipa-reference%> is incompatible with "
- "%<-flive-patching=inline-only-static|inline-clone%>");
+ error_at (loc, "%qs is incompatible with %qs",
+ "-fipa-reference",
+ "-flive-patching=inline-only-static|inline-clone");
else
opts->x_flag_ipa_reference = 0;
if (opts_set->x_flag_ipa_ra && opts->x_flag_ipa_ra)
- error_at (loc,
- "%<-fipa-ra%> is incompatible with "
- "%<-flive-patching=inline-only-static|inline-clone%>");
+ error_at (loc, "%qs is incompatible with %qs",
+ "-fipa-ra",
+ "-flive-patching=inline-only-static|inline-clone");
else
opts->x_flag_ipa_ra = 0;
if (opts_set->x_flag_ipa_icf && opts->x_flag_ipa_icf)
- error_at (loc,
- "%<-fipa-icf%> is incompatible with "
- "%<-flive-patching=inline-only-static|inline-clone%>");
+ error_at (loc, "%qs is incompatible with %qs",
+ "-fipa-icf",
+ "-flive-patching=inline-only-static|inline-clone");
else
opts->x_flag_ipa_icf = 0;
if (opts_set->x_flag_ipa_icf_functions && opts->x_flag_ipa_icf_functions)
- error_at (loc,
- "%<-fipa-icf-functions%> is incompatible with "
- "%<-flive-patching=inline-only-static|inline-clone%>");
+ error_at (loc, "%qs is incompatible with %qs",
+ "-fipa-icf-functions",
+ "-flive-patching=inline-only-static|inline-clone");
else
opts->x_flag_ipa_icf_functions = 0;
if (opts_set->x_flag_ipa_icf_variables && opts->x_flag_ipa_icf_variables)
- error_at (loc,
- "%<-fipa-icf-variables%> is incompatible with "
- "%<-flive-patching=inline-only-static|inline-clone%>");
+ error_at (loc, "%qs is incompatible with %qs",
+ "-fipa-icf-variables",
+ "-flive-patching=inline-only-static|inline-clone");
else
opts->x_flag_ipa_icf_variables = 0;
if (opts_set->x_flag_ipa_bit_cp && opts->x_flag_ipa_bit_cp)
- error_at (loc,
- "%<-fipa-bit-cp%> is incompatible with "
- "%<-flive-patching=inline-only-static|inline-clone%>");
+ error_at (loc, "%qs is incompatible with %qs",
+ "-fipa-bit-cp",
+ "-flive-patching=inline-only-static|inline-clone");
else
opts->x_flag_ipa_bit_cp = 0;
if (opts_set->x_flag_ipa_vrp && opts->x_flag_ipa_vrp)
- error_at (loc,
- "%<-fipa-vrp%> is incompatible with "
- "%<-flive-patching=inline-only-static|inline-clone%>");
+ error_at (loc, "%qs is incompatible with %qs",
+ "-fipa-vrp",
+ "-flive-patching=inline-only-static|inline-clone");
else
opts->x_flag_ipa_vrp = 0;
if (opts_set->x_flag_ipa_pure_const && opts->x_flag_ipa_pure_const)
- error_at (loc,
- "%<-fipa-pure-const%> is incompatible with "
- "%<-flive-patching=inline-only-static|inline-clone%>");
+ error_at (loc, "%qs is incompatible with %qs",
+ "-fipa-pure-const",
+ "-flive-patching=inline-only-static|inline-clone");
else
opts->x_flag_ipa_pure_const = 0;
@@ -804,18 +800,18 @@ control_options_for_live_patching (struct gcc_options *opts,
/* discovery of functions/variables with no address taken. */
if (opts_set->x_flag_ipa_reference_addressable
&& opts->x_flag_ipa_reference_addressable)
- error_at (loc,
- "%<-fipa-reference-addressable%> is incompatible with "
- "%<-flive-patching=inline-only-static|inline-clone%>");
+ error_at (loc, "%qs is incompatible with %qs",
+ "-fipa-reference-addressable",
+ "-flive-patching=inline-only-static|inline-clone");
else
opts->x_flag_ipa_reference_addressable = 0;
/* ipa stack alignment propagation. */
if (opts_set->x_flag_ipa_stack_alignment
&& opts->x_flag_ipa_stack_alignment)
- error_at (loc,
- "%<-fipa-stack-alignment%> is incompatible with "
- "%<-flive-patching=inline-only-static|inline-clone%>");
+ error_at (loc, "%qs is incompatible with %qs",
+ "-fipa-stack-alignment",
+ "-flive-patching=inline-only-static|inline-clone");
else
opts->x_flag_ipa_stack_alignment = 0;
break;
@@ -827,6 +823,57 @@ control_options_for_live_patching (struct gcc_options *opts,
/* --help option argument if set. */
vec<const char *> help_option_arguments;
+/* Return the string name describing a sanitizer argument which has been
+ provided on the command line and has set this particular flag. */
+const char *
+find_sanitizer_argument (struct gcc_options *opts, unsigned int flags)
+{
+ for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
+ {
+ /* Need to find the sanitizer_opts element which:
+ a) Could have set the flags requested.
+ b) Has been set on the command line.
+
+ Can have (a) without (b) if the flag requested is e.g.
+ SANITIZE_ADDRESS, since both -fsanitize=address and
+ -fsanitize=kernel-address set this flag.
+
+ Can have (b) without (a) by requesting more than one sanitizer on the
+ command line. */
+ if ((sanitizer_opts[i].flag & opts->x_flag_sanitize)
+ != sanitizer_opts[i].flag)
+ continue;
+ if ((sanitizer_opts[i].flag & flags) != flags)
+ continue;
+ return sanitizer_opts[i].name;
+ }
+ return NULL;
+}
+
+
+/* Report an error to the user about sanitizer options they have requested
+ which have set conflicting flags.
+
+ LEFT and RIGHT indicate sanitizer flags which conflict with each other, this
+ function reports an error if both have been set in OPTS->x_flag_sanitize and
+ ensures the error identifies the requested command line options that have
+ set these flags. */
+static void
+report_conflicting_sanitizer_options (struct gcc_options *opts, location_t loc,
+ unsigned int left, unsigned int right)
+{
+ unsigned int left_seen = (opts->x_flag_sanitize & left);
+ unsigned int right_seen = (opts->x_flag_sanitize & right);
+ if (left_seen && right_seen)
+ {
+ const char* left_arg = find_sanitizer_argument (opts, left_seen);
+ const char* right_arg = find_sanitizer_argument (opts, right_seen);
+ gcc_assert (left_arg && right_arg);
+ error_at (loc,
+ "%<-fsanitize=%s%> is incompatible with %<-fsanitize=%s%>",
+ left_arg, right_arg);
+ }
+}
/* After all options at LOC have been read into OPTS and OPTS_SET,
finalize settings of those options and diagnose incompatible
@@ -1078,24 +1125,22 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
"%<-fsanitize=address%> or %<-fsanitize=kernel-address%>");
}
- /* Userspace and kernel ASan conflict with each other. */
- if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS)
- && (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS))
- error_at (loc,
- "%<-fsanitize=address%> is incompatible with "
- "%<-fsanitize=kernel-address%>");
+ /* Address sanitizers conflict with the thread sanitizer. */
+ report_conflicting_sanitizer_options (opts, loc, SANITIZE_THREAD,
+ SANITIZE_ADDRESS | SANITIZE_HWADDRESS);
+ /* The leak sanitizer conflicts with the thread sanitizer. */
+ report_conflicting_sanitizer_options (opts, loc, SANITIZE_LEAK,
+ SANITIZE_THREAD);
- /* And with TSan. */
- if ((opts->x_flag_sanitize & SANITIZE_ADDRESS)
- && (opts->x_flag_sanitize & SANITIZE_THREAD))
- error_at (loc,
- "%<-fsanitize=address%> and %<-fsanitize=kernel-address%> "
- "are incompatible with %<-fsanitize=thread%>");
+ /* No combination of HWASAN and ASAN work together. */
+ report_conflicting_sanitizer_options (opts, loc,
+ SANITIZE_HWADDRESS, SANITIZE_ADDRESS);
- if ((opts->x_flag_sanitize & SANITIZE_LEAK)
- && (opts->x_flag_sanitize & SANITIZE_THREAD))
- error_at (loc,
- "%<-fsanitize=leak%> is incompatible with %<-fsanitize=thread%>");
+ /* The userspace and kernel address sanitizers conflict with each other. */
+ report_conflicting_sanitizer_options (opts, loc, SANITIZE_USER_HWADDRESS,
+ SANITIZE_KERNEL_HWADDRESS);
+ report_conflicting_sanitizer_options (opts, loc, SANITIZE_USER_ADDRESS,
+ SANITIZE_KERNEL_ADDRESS);
/* Check error recovery for -fsanitize-recover option. */
for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
@@ -1114,9 +1159,10 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
if (opts->x_flag_sanitize & ~(SANITIZE_LEAK | SANITIZE_UNREACHABLE))
opts->x_flag_aggressive_loop_optimizations = 0;
- /* Enable -fsanitize-address-use-after-scope if address sanitizer is
+ /* Enable -fsanitize-address-use-after-scope if either address sanitizer is
enabled. */
- if (opts->x_flag_sanitize & SANITIZE_USER_ADDRESS)
+ if (opts->x_flag_sanitize
+ & (SANITIZE_USER_ADDRESS | SANITIZE_USER_HWADDRESS))
SET_OPTION_IF_UNSET (opts, opts_set, flag_sanitize_address_use_after_scope,
true);
@@ -1730,8 +1776,13 @@ const struct sanitizer_opts_s sanitizer_opts[] =
#define SANITIZER_OPT(name, flags, recover) \
{ #name, flags, sizeof #name - 1, recover }
SANITIZER_OPT (address, (SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS), true),
+ SANITIZER_OPT (hwaddress, (SANITIZE_HWADDRESS | SANITIZE_USER_HWADDRESS),
+ true),
SANITIZER_OPT (kernel-address, (SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS),
true),
+ SANITIZER_OPT (kernel-hwaddress,
+ (SANITIZE_HWADDRESS | SANITIZE_KERNEL_HWADDRESS),
+ true),
SANITIZER_OPT (pointer-compare, SANITIZE_POINTER_COMPARE, true),
SANITIZER_OPT (pointer-subtract, SANITIZE_POINTER_SUBTRACT, true),
SANITIZER_OPT (thread, SANITIZE_THREAD, false),
@@ -2310,6 +2361,15 @@ common_handle_option (struct gcc_options *opts,
SET_OPTION_IF_UNSET (opts, opts_set, param_asan_protect_allocas, 0);
SET_OPTION_IF_UNSET (opts, opts_set, param_asan_use_after_return, 0);
}
+ if (opts->x_flag_sanitize & SANITIZE_KERNEL_HWADDRESS)
+ {
+ SET_OPTION_IF_UNSET (opts, opts_set,
+ param_hwasan_instrument_stack, 0);
+ SET_OPTION_IF_UNSET (opts, opts_set,
+ param_hwasan_random_frame_tag, 0);
+ SET_OPTION_IF_UNSET (opts, opts_set,
+ param_hwasan_instrument_allocas, 0);
+ }
break;
case OPT_fsanitize_recover_:
@@ -2602,6 +2662,10 @@ common_handle_option (struct gcc_options *opts,
SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_bit_cp, value);
break;
+ case OPT_fprofile_info_section:
+ opts->x_profile_info_section = ".gcov_info";
+ break;
+
case OPT_fpatchable_function_entry_:
{
char *patch_area_arg = xstrdup (arg);
diff --git a/gcc/opts.h b/gcc/opts.h
index 7d1e126..d62bfcf 100644
--- a/gcc/opts.h
+++ b/gcc/opts.h
@@ -124,6 +124,14 @@ struct cl_option
int range_max;
};
+struct cl_var
+{
+ /* Name of the variable. */
+ const char *var_name;
+ /* Offset of field for this var in struct gcc_options. */
+ unsigned short var_offset;
+};
+
/* Records that the state of an option consists of SIZE bytes starting
at DATA. DATA might point to CH in some cases. */
struct cl_option_state {
@@ -134,6 +142,9 @@ struct cl_option_state {
extern const struct cl_option cl_options[];
extern const unsigned int cl_options_count;
+#ifdef ENABLE_PLUGIN
+extern const struct cl_var cl_vars[];
+#endif
extern const char *const lang_names[];
extern const unsigned int cl_lang_count;
diff --git a/gcc/output.h b/gcc/output.h
index 2f2f169..fa8ace1 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -381,7 +381,12 @@ extern void no_asm_to_stream (FILE *);
#define SECTION_COMMON 0x800000 /* contains common data */
#define SECTION_RELRO 0x1000000 /* data is readonly after relocation processing */
#define SECTION_EXCLUDE 0x2000000 /* discarded by the linker */
-#define SECTION_MACH_DEP 0x4000000 /* subsequent bits reserved for target */
+#define SECTION_RETAIN 0x4000000 /* retained by the linker. */
+#define SECTION_LINK_ORDER 0x8000000 /* section needs link-order. */
+
+/* NB: The maximum SECTION_MACH_DEP is 0x10000000 since AVR needs 4 bits
+ in SECTION_MACH_DEP. */
+#define SECTION_MACH_DEP 0x10000000 /* subsequent bits reserved for target */
/* This SECTION_STYLE is used for unnamed sections that we can switch
to using a special assembler directive. */
@@ -572,8 +577,8 @@ extern void default_ctor_section_asm_out_constructor (rtx, int);
extern section *default_select_section (tree, int, unsigned HOST_WIDE_INT);
extern section *default_elf_select_section (tree, int, unsigned HOST_WIDE_INT);
extern void default_unique_section (tree, int);
-extern section *default_function_rodata_section (tree);
-extern section *default_no_function_rodata_section (tree);
+extern section *default_function_rodata_section (tree, bool);
+extern section *default_no_function_rodata_section (tree, bool);
extern section *default_clone_table_section (void);
extern section *default_select_rtx_section (machine_mode, rtx,
unsigned HOST_WIDE_INT);
diff --git a/gcc/params.opt b/gcc/params.opt
index a33a371..54951f2 100644
--- a/gcc/params.opt
+++ b/gcc/params.opt
@@ -62,6 +62,30 @@ Enable asan stack protection.
Common Joined UInteger Var(param_asan_use_after_return) Init(1) IntegerRange(0, 1) Param Optimization
Enable asan detection of use-after-return bugs.
+-param=hwasan-instrument-stack=
+Common Joined UInteger Var(param_hwasan_instrument_stack) Init(1) IntegerRange(0, 1) Param Optimization
+Enable hwasan instrumentation of statically sized stack-allocated variables.
+
+-param=hwasan-random-frame-tag=
+Common Joined UInteger Var(param_hwasan_random_frame_tag) Init(1) IntegerRange(0, 1) Param Optimization
+Use random base tag for each frame, as opposed to base always zero.
+
+-param=hwasan-instrument-allocas=
+Common Joined UInteger Var(param_hwasan_instrument_allocas) Init(1) IntegerRange(0, 1) Param Optimization
+Enable hwasan instrumentation of allocas/VLAs.
+
+-param=hwasan-instrument-reads=
+Common Joined UInteger Var(param_hwasan_instrument_reads) Init(1) IntegerRange(0, 1) Param Optimization
+Enable hwasan instrumentation of load operations.
+
+-param=hwasan-instrument-writes=
+Common Joined UInteger Var(param_hwasan_instrument_writes) Init(1) IntegerRange(0, 1) Param Optimization
+Enable hwasan instrumentation of store operations.
+
+-param=hwasan-instrument-mem-intrinsics=
+Common Joined UInteger Var(param_hwasan_instrument_mem_intrinsics) Init(1) IntegerRange(0, 1) Param Optimization
+Enable hwasan instrumentation of builtin functions.
+
-param=avg-loop-niter=
Common Joined UInteger Var(param_avg_loop_niter) Init(10) IntegerRange(1, 65536) Param Optimization
Average number of iterations of a loop.
@@ -349,6 +373,10 @@ Maximal stack frame growth due to inlining (in percent).
Common Joined UInteger Var(param_large_unit_insns) Optimization Init(10000) Param
The size of translation unit to be considered large.
+-param=lazy-modules=
+C++ Joined UInteger Var(param_lazy_modules) Init(32768) Param
+Maximum number of concurrently open C++ module files when lazy loading.
+
-param=lim-expensive=
Common Joined UInteger Var(param_lim_expensive) Init(20) Param Optimization
The minimum cost of an expensive expression in the loop invariant motion.
@@ -597,10 +625,6 @@ Maximum depth of sqrt chains to use when synthesizing exponentiation by a real c
Common Joined UInteger Var(param_max_predicted_iterations) Init(100) IntegerRange(0, 65536) Param Optimization
The maximum number of loop iterations we predict statically.
--param=max-pre-hoist-insert-iterations=
-Common Joined UInteger Var(param_max_pre_hoist_insert_iterations) Init(3) Param Optimization
-The maximum number of insert iterations done for PRE code hoisting.
-
-param=max-reload-search-insns=
Common Joined UInteger Var(param_max_reload_search_insns) Init(100) Param Optimization
The maximum number of instructions to search backward when looking for equivalent reload.
@@ -916,21 +940,29 @@ Common Joined UInteger Var(param_switch_conversion_branch_ratio) Init(8) Integer
The maximum ratio between array size and switch branches for a switch conversion to take place.
-param=modref-max-bases=
-Common Joined UInteger Var(param_modref_max_bases) Init(32)
+Common Joined UInteger Var(param_modref_max_bases) Init(32) Param Optimization
Maximum number of bases stored in each modref tree.
-param=modref-max-refs=
-Common Joined UInteger Var(param_modref_max_refs) Init(16)
+Common Joined UInteger Var(param_modref_max_refs) Init(16) Param Optimization
Maximum number of references stored in each modref base.
-param=modref-max-accesses=
-Common Joined UInteger Var(param_modref_max_accesses) Init(16)
+Common Joined UInteger Var(param_modref_max_accesses) Init(16) Param Optimization
Maximum number of accesse stored in each modref reference.
-param=modref-max-tests=
-Common Joined UInteger Var(param_modref_max_tests) Init(64)
+Common Joined UInteger Var(param_modref_max_tests) Init(64) Param Optimization
Maximum number of tests performed by modref query.
+-param=modref-max-depth=
+Common Joined UInteger Var(param_modref_max_depth) Init(256) Param Optimization
+Maximum depth of DFS walk used by modref escape analysis.
+
+-param=modref-max-escape-points=
+Common Joined UInteger Var(param_modref_max_escape_points) Init(256) Param Optimization
+Maximum number of escape points tracked by modref per SSA-name.
+
-param=tm-max-aggregate-size=
Common Joined UInteger Var(param_tm_max_aggregate_size) Init(9) Param Optimization
Size in bytes after which thread-local aggregates should be instrumented with the logging functions instead of save/restore pairs.
diff --git a/gcc/passes.c b/gcc/passes.c
index f71f639..973c958 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -1837,6 +1837,9 @@ emergency_dump_function ()
fnotice (stderr, "dump file: %s\n", dump_file_name);
fprintf (dump_file, "\n\n\nEMERGENCY DUMP:\n\n");
execute_function_dump (cfun, current_pass);
+
+ if (symtab && current_pass->type == IPA_PASS)
+ symtab->dump (dump_file);
}
static struct profile_record *profile_record;
diff --git a/gcc/passes.def b/gcc/passes.def
index c682312..21b2e2a 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_warn_unused_result);
NEXT_PASS (pass_diagnose_omp_blocks);
NEXT_PASS (pass_diagnose_tm_blocks);
+ NEXT_PASS (pass_omp_oacc_kernels_decompose);
NEXT_PASS (pass_lower_omp);
NEXT_PASS (pass_lower_cf);
NEXT_PASS (pass_lower_tm);
@@ -93,6 +94,7 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_phiopt, true /* early_p */);
NEXT_PASS (pass_modref);
NEXT_PASS (pass_tail_recursion);
+ NEXT_PASS (pass_if_to_switch);
NEXT_PASS (pass_convert_switch);
NEXT_PASS (pass_cleanup_eh);
NEXT_PASS (pass_profile);
diff --git a/gcc/plugin.c b/gcc/plugin.c
index 69b6f5b..76069e6 100644
--- a/gcc/plugin.c
+++ b/gcc/plugin.c
@@ -497,6 +497,7 @@ register_callback (const char *plugin_name,
case PLUGIN_EARLY_GIMPLE_PASSES_END:
case PLUGIN_NEW_PASS:
case PLUGIN_INCLUDE_FILE:
+ case PLUGIN_ANALYZER_INIT:
{
struct callback_info *new_callback;
if (!callback)
@@ -577,6 +578,7 @@ invoke_plugin_callbacks_full (int event, void *gcc_data)
case PLUGIN_EARLY_GIMPLE_PASSES_END:
case PLUGIN_NEW_PASS:
case PLUGIN_INCLUDE_FILE:
+ case PLUGIN_ANALYZER_INIT:
{
/* Iterate over every callback registered with this event and
call it. */
diff --git a/gcc/plugin.def b/gcc/plugin.def
index 3482ed7..b811019 100644
--- a/gcc/plugin.def
+++ b/gcc/plugin.def
@@ -99,6 +99,10 @@ DEFEVENT (PLUGIN_NEW_PASS)
as a const char* pointer. */
DEFEVENT (PLUGIN_INCLUDE_FILE)
+/* Called when -fanalyzer starts. The event data is an
+ ana::plugin_analyzer_init_iface *. */
+DEFEVENT (PLUGIN_ANALYZER_INIT)
+
/* When adding a new hard-coded plugin event, don't forget to edit in
file plugin.c the functions register_callback and
invoke_plugin_callbacks_full accordingly! */
diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog
index 0cd3014f..e29c057 100644
--- a/gcc/po/ChangeLog
+++ b/gcc/po/ChangeLog
@@ -1,3 +1,7 @@
+2020-11-18 Joseph Myers <joseph@codesourcery.com>
+
+ * zh_TW.po: Update.
+
2020-07-29 Joseph Myers <joseph@codesourcery.com>
* ja.po, sv.po: Update.
diff --git a/gcc/po/zh_TW.po b/gcc/po/zh_TW.po
index 69cd0be..bf76882 100644
--- a/gcc/po/zh_TW.po
+++ b/gcc/po/zh_TW.po
@@ -7,10 +7,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: gcc 10.1.0\n"
+"Project-Id-Version: gcc 10.2.0\n"
"Report-Msgid-Bugs-To: https://gcc.gnu.org/bugs/\n"
"POT-Creation-Date: 2020-07-20 18:08+0000\n"
-"PO-Revision-Date: 2020-05-08 22:14+0800\n"
+"PO-Revision-Date: 2020-11-19 00:56+0800\n"
"Last-Translator: Yi-Jyun Pan <pan93412@gmail.com>\n"
"Language-Team: Chinese (traditional) <zh-l10n@lists.linux.org.tw>\n"
"Language: zh_TW\n"
@@ -19,7 +19,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.3\n"
+"X-Generator: Poedit 2.4.1\n"
#: cfgrtl.c:2748
msgid "flow control insn inside a basic block"
@@ -134,7 +134,7 @@ msgstr "請參閱 %s 取得指引。\n"
#: diagnostic.c:602
#, c-format
msgid "compilation terminated.\n"
-msgstr "編譯插斷。\n"
+msgstr "編譯終止。\n"
#: diagnostic.c:663
msgid "In file included from"
diff --git a/gcc/predict.c b/gcc/predict.c
index 361c401..3acbb86 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -2204,7 +2204,7 @@ predict_loops (void)
{
gimple *call_stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (stmt));
if (gimple_code (call_stmt) == GIMPLE_ASSIGN
- && gimple_expr_code (call_stmt) == NOP_EXPR
+ && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (call_stmt))
&& TREE_CODE (gimple_assign_rhs1 (call_stmt)) == SSA_NAME)
call_stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (call_stmt));
if (gimple_call_internal_p (call_stmt, IFN_BUILTIN_EXPECT)
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index aff9383..36f9fd6 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -80,30 +80,25 @@ empty_range_varying (irange &r, tree type,
return false;
}
-// Return TRUE if shifting by OP is undefined behavior, and set R to
-// the appropriate range.
+// Return false if shifting by OP is undefined behavior. Otherwise, return
+// true and the range it is to be shifted by. This allows trimming out of
+// undefined ranges, leaving only valid ranges if there are any.
static inline bool
-undefined_shift_range_check (irange &r, tree type, const irange &op)
+get_shift_range (irange &r, tree type, const irange &op)
{
if (op.undefined_p ())
- {
- r.set_undefined ();
- return true;
- }
+ return false;
- // Shifting by any values outside [0..prec-1], gets undefined
- // behavior from the shift operation. We cannot even trust
- // SHIFT_COUNT_TRUNCATED at this stage, because that applies to rtl
- // shifts, and the operation at the tree level may be widened.
- if (wi::lt_p (op.lower_bound (), 0, TYPE_SIGN (op.type ()))
- || wi::ge_p (op.upper_bound (),
- TYPE_PRECISION (type), TYPE_SIGN (op.type ())))
- {
- r.set_varying (type);
- return true;
- }
- return false;
+ // Build valid range and intersect it with the shift range.
+ r = value_range (build_int_cst_type (op.type (), 0),
+ build_int_cst_type (op.type (), TYPE_PRECISION (type) - 1));
+ r.intersect (op);
+
+ // If there are no valid ranges in the shift range, returned false.
+ if (r.undefined_p ())
+ return false;
+ return true;
}
// Return TRUE if 0 is within [WMIN, WMAX].
@@ -1465,13 +1460,20 @@ operator_lshift::fold_range (irange &r, tree type,
const irange &op1,
const irange &op2) const
{
- if (undefined_shift_range_check (r, type, op2))
- return true;
+ int_range_max shift_range;
+ if (!get_shift_range (shift_range, type, op2))
+ {
+ if (op2.undefined_p ())
+ r.set_undefined ();
+ else
+ r.set_varying (type);
+ return true;
+ }
// Transform left shifts by constants into multiplies.
- if (op2.singleton_p ())
+ if (shift_range.singleton_p ())
{
- unsigned shift = op2.lower_bound ().to_uhwi ();
+ unsigned shift = shift_range.lower_bound ().to_uhwi ();
wide_int tmp = wi::set_bit_in_zero (shift, TYPE_PRECISION (type));
int_range<1> mult (type, tmp, tmp);
@@ -1487,7 +1489,7 @@ operator_lshift::fold_range (irange &r, tree type,
}
else
// Otherwise, invoke the generic fold routine.
- return range_operator::fold_range (r, type, op1, op2);
+ return range_operator::fold_range (r, type, op1, shift_range);
}
void
@@ -1709,11 +1711,17 @@ operator_rshift::fold_range (irange &r, tree type,
const irange &op1,
const irange &op2) const
{
- // Invoke the generic fold routine if not undefined..
- if (undefined_shift_range_check (r, type, op2))
- return true;
+ int_range_max shift;
+ if (!get_shift_range (shift, type, op2))
+ {
+ if (op2.undefined_p ())
+ r.set_undefined ();
+ else
+ r.set_varying (type);
+ return true;
+ }
- return range_operator::fold_range (r, type, op1, op2);
+ return range_operator::fold_range (r, type, op1, shift);
}
void
@@ -2163,6 +2171,14 @@ wi_optimize_and_or (irange &r,
else
gcc_unreachable ();
value_range_with_overflow (r, type, res_lb, res_ub);
+
+ // Furthermore, if the mask is non-zero, an IOR cannot contain zero.
+ if (code == BIT_IOR_EXPR && wi::ne_p (mask, 0))
+ {
+ int_range<2> tmp;
+ tmp.set_nonzero (type);
+ r.intersect (tmp);
+ }
return true;
}
@@ -2626,6 +2642,12 @@ public:
const wide_int &lh_ub,
const wide_int &rh_lb,
const wide_int &rh_ub) const;
+ virtual bool op1_range (irange &r, tree type,
+ const irange &lhs,
+ const irange &op2) const;
+ virtual bool op2_range (irange &r, tree type,
+ const irange &lhs,
+ const irange &op1) const;
} op_trunc_mod;
void
@@ -2672,6 +2694,65 @@ operator_trunc_mod::wi_fold (irange &r, tree type,
value_range_with_overflow (r, type, new_lb, new_ub);
}
+bool
+operator_trunc_mod::op1_range (irange &r, tree type,
+ const irange &lhs,
+ const irange &) const
+{
+ // PR 91029.
+ signop sign = TYPE_SIGN (type);
+ unsigned prec = TYPE_PRECISION (type);
+ // (a % b) >= x && x > 0 , then a >= x.
+ if (wi::gt_p (lhs.lower_bound (), 0, sign))
+ {
+ r = value_range (type, lhs.lower_bound (), wi::max_value (prec, sign));
+ return true;
+ }
+ // (a % b) <= x && x < 0 , then a <= x.
+ if (wi::lt_p (lhs.upper_bound (), 0, sign))
+ {
+ r = value_range (type, wi::min_value (prec, sign), lhs.upper_bound ());
+ return true;
+ }
+ return false;
+}
+
+bool
+operator_trunc_mod::op2_range (irange &r, tree type,
+ const irange &lhs,
+ const irange &) const
+{
+ // PR 91029.
+ signop sign = TYPE_SIGN (type);
+ unsigned prec = TYPE_PRECISION (type);
+ // (a % b) >= x && x > 0 , then b is in ~[-x, x] for signed
+ // or b > x for unsigned.
+ if (wi::gt_p (lhs.lower_bound (), 0, sign))
+ {
+ if (sign == SIGNED)
+ r = value_range (type, wi::neg (lhs.lower_bound ()),
+ lhs.lower_bound (), VR_ANTI_RANGE);
+ else if (wi::lt_p (lhs.lower_bound (), wi::max_value (prec, sign),
+ sign))
+ r = value_range (type, lhs.lower_bound () + 1,
+ wi::max_value (prec, sign));
+ else
+ return false;
+ return true;
+ }
+ // (a % b) <= x && x < 0 , then b is in ~[x, -x].
+ if (wi::lt_p (lhs.upper_bound (), 0, sign))
+ {
+ if (wi::gt_p (lhs.upper_bound (), wi::min_value (prec, sign), sign))
+ r = value_range (type, lhs.upper_bound (),
+ wi::neg (lhs.upper_bound ()), VR_ANTI_RANGE);
+ else
+ return false;
+ return true;
+ }
+ return false;
+}
+
class operator_logical_not : public range_operator
{
@@ -3328,6 +3409,7 @@ pointer_table::pointer_table ()
set (GT_EXPR, op_gt);
set (GE_EXPR, op_ge);
set (SSA_NAME, op_identity);
+ set (INTEGER_CST, op_integer_cst);
set (ADDR_EXPR, op_addr);
set (NOP_EXPR, op_convert);
set (CONVERT_EXPR, op_convert);
@@ -3341,10 +3423,12 @@ pointer_table::pointer_table ()
range_operator *
range_op_handler (enum tree_code code, tree type)
{
- // First check if there is apointer specialization.
+ // First check if there is a pointer specialization.
if (POINTER_TYPE_P (type))
return pointer_tree_table[code];
- return integral_tree_table[code];
+ if (INTEGRAL_TYPE_P (type))
+ return integral_tree_table[code];
+ return NULL;
}
// Cast the range in R to TYPE.
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index 8f98bd8..3dab843 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -3426,7 +3426,8 @@ static unsigned int
rest_of_handle_stack_regs (void)
{
#ifdef STACK_REGS
- reg_to_stack ();
+ if (reg_to_stack ())
+ df_insn_rescan_all ();
regstack_completed = 1;
#endif
return 0;
diff --git a/gcc/reload.c b/gcc/reload.c
index 78b4049..a63cc02 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -2656,6 +2656,22 @@ find_reloads (rtx_insn *insn, int replace, int ind_levels, int live_known,
hard_regs_live_known = live_known;
static_reload_reg_p = reload_reg_p;
+ if (JUMP_P (insn) && INSN_CODE (insn) < 0)
+ {
+ extract_insn (insn);
+ for (i = 0; i < recog_data.n_operands; i++)
+ if (recog_data.operand_type[i] != OP_IN)
+ break;
+ if (i < recog_data.n_operands)
+ {
+ error_for_asm (insn,
+ "the target does not support %<asm goto%> "
+ "with outputs in %<asm%>");
+ ira_nullify_asm_goto (insn);
+ return 0;
+ }
+ }
+
/* JUMP_INSNs and CALL_INSNs are not allowed to have any output reloads;
neither are insns that SET cc0. Insns that use CC0 are not allowed
to have any input reloads. */
diff --git a/gcc/sanitizer.def b/gcc/sanitizer.def
index a32715d..f02731e 100644
--- a/gcc/sanitizer.def
+++ b/gcc/sanitizer.def
@@ -180,6 +180,67 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_POINTER_COMPARE, "__sanitizer_ptr_cmp",
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_POINTER_SUBTRACT, "__sanitizer_ptr_sub",
BT_FN_VOID_PTR_PTRMODE, ATTR_NOTHROW_LEAF_LIST)
+/* Hardware Address Sanitizer. */
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_INIT, "__hwasan_init",
+ BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_LOAD1, "__hwasan_load1",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_LOAD2, "__hwasan_load2",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_LOAD4, "__hwasan_load4",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_LOAD8, "__hwasan_load8",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_LOAD16, "__hwasan_load16",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_LOADN, "__hwasan_loadN",
+ BT_FN_VOID_PTR_PTRMODE, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_STORE1, "__hwasan_store1",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_STORE2, "__hwasan_store2",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_STORE4, "__hwasan_store4",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_STORE8, "__hwasan_store8",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_STORE16, "__hwasan_store16",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_STOREN, "__hwasan_storeN",
+ BT_FN_VOID_PTR_PTRMODE, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_LOAD1_NOABORT, "__hwasan_load1_noabort",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_LOAD2_NOABORT, "__hwasan_load2_noabort",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_LOAD4_NOABORT, "__hwasan_load4_noabort",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_LOAD8_NOABORT, "__hwasan_load8_noabort",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_LOAD16_NOABORT, "__hwasan_load16_noabort",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_LOADN_NOABORT, "__hwasan_loadN_noabort",
+ BT_FN_VOID_PTR_PTRMODE, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_STORE1_NOABORT, "__hwasan_store1_noabort",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_STORE2_NOABORT, "__hwasan_store2_noabort",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_STORE4_NOABORT, "__hwasan_store4_noabort",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_STORE8_NOABORT, "__hwasan_store8_noabort",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_STORE16_NOABORT,
+ "__hwasan_store16_noabort",
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_STOREN_NOABORT, "__hwasan_storeN_noabort",
+ BT_FN_VOID_PTR_PTRMODE, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_TAG_MISMATCH4, "__hwasan_tag_mismatch4",
+ BT_FN_VOID_PTR, ATTR_NOTHROW_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_HANDLE_LONGJMP, "__hwasan_handle_longjmp",
+ BT_FN_VOID_CONST_PTR, ATTR_NOTHROW_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_TAG_PTR, "__hwasan_tag_pointer",
+ BT_FN_PTR_CONST_PTR_UINT8, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_HWASAN_TAG_MEM, "__hwasan_tag_memory",
+ BT_FN_VOID_PTR_UINT8_PTRMODE, ATTR_NOTHROW_LIST)
+
/* Thread Sanitizer */
DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_INIT, "__tsan_init",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
diff --git a/gcc/sanopt.c b/gcc/sanopt.c
index 6c3bce9..965ab36 100644
--- a/gcc/sanopt.c
+++ b/gcc/sanopt.c
@@ -776,7 +776,8 @@ sanopt_optimize_walker (basic_block bb, class sanopt_ctx *ctx)
basic_block son;
gimple_stmt_iterator gsi;
sanopt_info *info = (sanopt_info *) bb->aux;
- bool asan_check_optimize = (flag_sanitize & SANITIZE_ADDRESS) != 0;
+ bool asan_check_optimize
+ = ((flag_sanitize & (SANITIZE_ADDRESS | SANITIZE_HWADDRESS)) != 0);
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
{
@@ -806,6 +807,7 @@ sanopt_optimize_walker (basic_block bb, class sanopt_ctx *ctx)
if (asan_check_optimize
&& gimple_call_builtin_p (stmt, BUILT_IN_ASAN_BEFORE_DYNAMIC_INIT))
{
+ gcc_assert (!hwasan_sanitize_p ());
use_operand_p use;
gimple *use_stmt;
if (single_imm_use (gimple_vdef (stmt), &use, &use_stmt))
@@ -834,6 +836,7 @@ sanopt_optimize_walker (basic_block bb, class sanopt_ctx *ctx)
case IFN_UBSAN_PTR:
remove = maybe_optimize_ubsan_ptr_ifn (ctx, stmt);
break;
+ case IFN_HWASAN_CHECK:
case IFN_ASAN_CHECK:
if (asan_check_optimize)
remove = maybe_optimize_asan_check_ifn (ctx, stmt);
@@ -1262,6 +1265,10 @@ sanitize_rewrite_addressable_params (function *fun)
unsigned int
pass_sanopt::execute (function *fun)
{
+ /* n.b. ASAN_MARK is used for both HWASAN and ASAN.
+ asan_num_accesses is hence used to count either HWASAN_CHECK or ASAN_CHECK
+ stuff. This is fine because you can only have one of these active at a
+ time. */
basic_block bb;
int asan_num_accesses = 0;
bool contains_asan_mark = false;
@@ -1269,10 +1276,10 @@ pass_sanopt::execute (function *fun)
/* Try to remove redundant checks. */
if (optimize
&& (flag_sanitize
- & (SANITIZE_NULL | SANITIZE_ALIGNMENT
+ & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_HWADDRESS
| SANITIZE_ADDRESS | SANITIZE_VPTR | SANITIZE_POINTER_OVERFLOW)))
asan_num_accesses = sanopt_optimize (fun, &contains_asan_mark);
- else if (flag_sanitize & SANITIZE_ADDRESS)
+ else if (flag_sanitize & (SANITIZE_ADDRESS | SANITIZE_HWADDRESS))
{
gimple_stmt_iterator gsi;
FOR_EACH_BB_FN (bb, fun)
@@ -1292,7 +1299,7 @@ pass_sanopt::execute (function *fun)
sanitize_asan_mark_poison ();
}
- if (asan_sanitize_stack_p ())
+ if (asan_sanitize_stack_p () || hwasan_sanitize_stack_p ())
sanitize_rewrite_addressable_params (fun);
bool use_calls = param_asan_instrumentation_with_call_threshold < INT_MAX
@@ -1334,6 +1341,9 @@ pass_sanopt::execute (function *fun)
case IFN_UBSAN_VPTR:
no_next = ubsan_expand_vptr_ifn (&gsi);
break;
+ case IFN_HWASAN_CHECK:
+ no_next = hwasan_expand_check_ifn (&gsi, use_calls);
+ break;
case IFN_ASAN_CHECK:
no_next = asan_expand_check_ifn (&gsi, use_calls);
break;
@@ -1345,6 +1355,9 @@ pass_sanopt::execute (function *fun)
&need_commit_edge_insert,
shadow_vars_mapping);
break;
+ case IFN_HWASAN_MARK:
+ no_next = hwasan_expand_mark_ifn (&gsi);
+ break;
default:
break;
}
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index dff81d1..ee1cf55 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -393,6 +393,9 @@ int_mode_for_mode (machine_mode mode)
case MODE_VECTOR_UACCUM:
return int_mode_for_size (GET_MODE_BITSIZE (mode), 0);
+ case MODE_OPAQUE:
+ return opt_scalar_int_mode ();
+
case MODE_RANDOM:
if (mode == BLKmode)
return opt_scalar_int_mode ();
diff --git a/gcc/symtab-thunks.h b/gcc/symtab-thunks.h
index 41a6849..0dba221 100644
--- a/gcc/symtab-thunks.h
+++ b/gcc/symtab-thunks.h
@@ -167,7 +167,7 @@ inline void
thunk_info::release ()
{
if (symtab->m_thunks)
- delete (symtab->m_thunks);
+ ggc_delete (symtab->m_thunks);
symtab->m_thunks = NULL;
}
#endif /* GCC_SYMTAB_THUNKS_H */
diff --git a/gcc/symtab.c b/gcc/symtab.c
index 58b14f3..6ceec55 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -368,6 +368,36 @@ section_name_hasher::equal (section_hash_entry *n1, const char *name)
return n1->name == name || !strcmp (n1->name, name);
}
+/* Bump the reference count on ENTRY so that it is retained. */
+
+static section_hash_entry *
+retain_section_hash_entry (section_hash_entry *entry)
+{
+ entry->ref_count++;
+ return entry;
+}
+
+/* Drop the reference count on ENTRY and remove it if the reference
+ count drops to zero. */
+
+static void
+release_section_hash_entry (section_hash_entry *entry)
+{
+ if (entry)
+ {
+ entry->ref_count--;
+ if (!entry->ref_count)
+ {
+ hashval_t hash = htab_hash_string (entry->name);
+ section_hash_entry **slot
+ = symtab->section_hash->find_slot_with_hash (entry->name,
+ hash, INSERT);
+ ggc_free (entry);
+ symtab->section_hash->clear_slot (slot);
+ }
+ }
+}
+
/* Add node into symbol table. This function is not used directly, but via
cgraph/varpool node creation routines. */
@@ -1484,8 +1514,7 @@ symtab_node::copy_visibility_from (symtab_node *n)
DECL_DLLIMPORT_P (decl) = DECL_DLLIMPORT_P (n->decl);
resolution = n->resolution;
set_comdat_group (n->get_comdat_group ());
- call_for_symbol_and_aliases (symtab_node::set_section,
- const_cast<char *>(n->get_section ()), true);
+ set_section (*n);
externally_visible = n->externally_visible;
if (!DECL_RTL_SET_P (decl))
return;
@@ -1610,57 +1639,76 @@ void
symtab_node::set_section_for_node (const char *section)
{
const char *current = get_section ();
- section_hash_entry **slot;
if (current == section
|| (current && section
&& !strcmp (current, section)))
return;
- if (current)
- {
- x_section->ref_count--;
- if (!x_section->ref_count)
- {
- hashval_t hash = htab_hash_string (x_section->name);
- slot = symtab->section_hash->find_slot_with_hash (x_section->name,
- hash, INSERT);
- ggc_free (x_section);
- symtab->section_hash->clear_slot (slot);
- }
- x_section = NULL;
- }
+ release_section_hash_entry (x_section);
if (!section)
{
+ x_section = NULL;
implicit_section = false;
return;
}
if (!symtab->section_hash)
symtab->section_hash = hash_table<section_name_hasher>::create_ggc (10);
- slot = symtab->section_hash->find_slot_with_hash (section,
- htab_hash_string (section),
- INSERT);
+ section_hash_entry **slot = symtab->section_hash->find_slot_with_hash
+ (section, htab_hash_string (section), INSERT);
if (*slot)
- x_section = (section_hash_entry *)*slot;
+ x_section = retain_section_hash_entry (*slot);
else
{
int len = strlen (section);
*slot = x_section = ggc_cleared_alloc<section_hash_entry> ();
+ x_section->ref_count = 1;
x_section->name = ggc_vec_alloc<char> (len + 1);
memcpy (x_section->name, section, len + 1);
}
- x_section->ref_count++;
}
-/* Worker for set_section. */
+/* Set the section of node THIS to be the same as the section
+ of node OTHER. Keep reference counts of the sections
+ up-to-date as needed. */
+
+void
+symtab_node::set_section_for_node (const symtab_node &other)
+{
+ if (x_section == other.x_section)
+ return;
+ if (get_section () && other.get_section ())
+ gcc_checking_assert (strcmp (get_section (), other.get_section ()) != 0);
+ release_section_hash_entry (x_section);
+ if (other.x_section)
+ x_section = retain_section_hash_entry (other.x_section);
+ else
+ {
+ x_section = NULL;
+ implicit_section = false;
+ }
+}
+
+/* Workers for set_section. */
bool
-symtab_node::set_section (symtab_node *n, void *s)
+symtab_node::set_section_from_string (symtab_node *n, void *s)
{
n->set_section_for_node ((char *)s);
return false;
}
+/* Set the section of node N to be the same as the section
+ of node O. */
+
+bool
+symtab_node::set_section_from_node (symtab_node *n, void *o)
+{
+ const symtab_node &other = *static_cast<const symtab_node *> (o);
+ n->set_section_for_node (other);
+ return false;
+}
+
/* Set section of symbol and its aliases. */
void
@@ -1668,7 +1716,14 @@ symtab_node::set_section (const char *section)
{
gcc_assert (!this->alias || !this->analyzed);
call_for_symbol_and_aliases
- (symtab_node::set_section, const_cast<char *>(section), true);
+ (symtab_node::set_section_from_string, const_cast<char *>(section), true);
+}
+
+void
+symtab_node::set_section (const symtab_node &other)
+{
+ call_for_symbol_and_aliases
+ (symtab_node::set_section_from_node, const_cast<symtab_node *>(&other), true);
}
/* Return the initialization priority. */
@@ -1814,8 +1869,7 @@ symtab_node::resolve_alias (symtab_node *target, bool transparent)
{
error ("section of alias %q+D must match section of its target", decl);
}
- call_for_symbol_and_aliases (symtab_node::set_section,
- const_cast<char *>(target->get_section ()), true);
+ set_section (*target);
if (target->implicit_section)
call_for_symbol_and_aliases (set_implicit_section, NULL, true);
diff --git a/gcc/system.h b/gcc/system.h
index b0f3f1d..6f6ab61 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -789,6 +789,12 @@ extern void fancy_abort (const char *, int, const char *)
#define ALWAYS_INLINE inline
#endif
+#if GCC_VERSION >= 3004
+#define WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__))
+#else
+#define WARN_UNUSED_RESULT
+#endif
+
/* Use gcc_unreachable() to mark unreachable locations (like an
unreachable default case of a switch. Do not use gcc_assert(0). */
#if (GCC_VERSION >= 4005) && !ENABLE_ASSERT_CHECKING
diff --git a/gcc/target.def b/gcc/target.def
index b916635..a0ea853 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -185,6 +185,16 @@ DEFHOOK
void, (rtx personality),
NULL)
+/* If necessary, modify personality and LSDA references to handle
+ indirection. This is used when the assembler supports CFI directives. */
+DEFHOOK
+(make_eh_symbol_indirect,
+ "If necessary, modify personality and LSDA references to handle indirection.\
+ The original symbol is in @code{origsymbol} and if @code{pubvis} is true\
+ the symbol is visible outside the TU.",
+ rtx, (rtx origsymbol, bool pubvis),
+ NULL)
+
/* Emit any directives required to unwind this instruction. */
DEFHOOK
(unwind_emit,
@@ -549,16 +559,18 @@ Whatever the actual target object format, this is often good enough.",
void, (tree decl, int reloc),
default_unique_section)
-/* Return the readonly data section associated with function DECL. */
+/* Return the readonly data or relocated readonly data section
+ associated with function DECL. */
DEFHOOK
(function_rodata_section,
- "Return the readonly data section associated with\n\
-@samp{DECL_SECTION_NAME (@var{decl})}.\n\
+ "Return the readonly data or reloc readonly data section associated with\n\
+@samp{DECL_SECTION_NAME (@var{decl})}. @var{relocatable} selects the latter\n\
+over the former.\n\
The default version of this function selects @code{.gnu.linkonce.r.name} if\n\
the function's section is @code{.gnu.linkonce.t.name}, @code{.rodata.name}\n\
-if function is in @code{.text.name}, and the normal readonly-data section\n\
-otherwise.",
- section *, (tree decl),
+or @code{.data.rel.ro.name} if function is in @code{.text.name}, and\n\
+the normal readonly-data or reloc readonly data section otherwise.",
+ section *, (tree decl, bool relocatable),
default_function_rodata_section)
/* Nonnull if the target wants to override the default ".rodata" prefix
@@ -4452,7 +4464,8 @@ DEFHOOK
(asan_shadow_offset,
"Return the offset bitwise ored into shifted address to get corresponding\n\
Address Sanitizer shadow memory address. NULL if Address Sanitizer is not\n\
-supported by the target.",
+supported by the target. May return 0 if Address Sanitizer is not supported\n\
+by a subtarget.",
unsigned HOST_WIDE_INT, (void),
NULL)
@@ -5153,12 +5166,28 @@ Note that the block move need only cover the constant parts of the\n\
trampoline. If the target isolates the variable parts of the trampoline\n\
to the end, not all @code{TRAMPOLINE_SIZE} bytes need be copied.\n\
\n\
-If the target requires any other actions, such as flushing caches or\n\
+If the target requires any other actions, such as flushing caches\n\
+(possibly calling function maybe_emit_call_builtin___clear_cache) or\n\
enabling stack execution, these actions should be performed after\n\
initializing the trampoline proper.",
void, (rtx m_tramp, tree fndecl, rtx static_chain),
default_trampoline_init)
+/* Emit a call to a function to clear the instruction cache. */
+DEFHOOK
+(emit_call_builtin___clear_cache,
+ "On targets that do not define a @code{clear_cache} insn expander,\n\
+but that define the @code{CLEAR_CACHE_INSN} macro,\n\
+maybe_emit_call_builtin___clear_cache relies on this target hook\n\
+to clear an address range in the instruction cache.\n\
+\n\
+The default implementation calls the @code{__clear_cache} builtin,\n\
+taking the assembler name from the builtin declaration. Overriding\n\
+definitions may call alternate functions, with alternate calling\n\
+conventions, or emit alternate RTX to perform the job.",
+ void, (rtx begin, rtx end),
+ default_emit_call_builtin___clear_cache)
+
/* Adjust the address of the trampoline in a target-specific way. */
DEFHOOK
(trampoline_adjust_address,
@@ -6850,6 +6879,86 @@ DEFHOOK
HOOK_VECTOR_END (mode_switching)
#undef HOOK_PREFIX
+#define HOOK_PREFIX "TARGET_MEMTAG_"
+HOOK_VECTOR (TARGET_MEMTAG_, memtag)
+
+DEFHOOK
+(can_tag_addresses,
+ "True if the backend architecture naturally supports ignoring some region\n\
+of pointers. This feature means that @option{-fsanitize=hwaddress} can\n\
+work.\n\
+\n\
+At preset, this feature does not support address spaces. It also requires\n\
+@code{Pmode} to be the same as @code{ptr_mode}.",
+ bool, (), default_memtag_can_tag_addresses)
+
+DEFHOOK
+(tag_size,
+ "Return the size of a tag (in bits) for this platform.\n\
+\n\
+The default returns 8.",
+ uint8_t, (), default_memtag_tag_size)
+
+DEFHOOK
+(granule_size,
+ "Return the size in real memory that each byte in shadow memory refers to.\n\
+I.e. if a variable is @var{X} bytes long in memory, then this hook should\n\
+return the value @var{Y} such that the tag in shadow memory spans\n\
+@var{X}/@var{Y} bytes.\n\
+\n\
+Most variables will need to be aligned to this amount since two variables\n\
+that are neighbors in memory and share a tag granule would need to share\n\
+the same tag.\n\
+\n\
+The default returns 16.",
+ uint8_t, (), default_memtag_granule_size)
+
+DEFHOOK
+(insert_random_tag,
+ "Return an RTX representing the value of @var{untagged} but with a\n\
+(possibly) random tag in it.\n\
+Put that value into @var{target} if it is convenient to do so.\n\
+This function is used to generate a tagged base for the current stack frame.",
+ rtx, (rtx untagged, rtx target), default_memtag_insert_random_tag)
+
+DEFHOOK
+(add_tag,
+ "Return an RTX that represents the result of adding @var{addr_offset} to\n\
+the address in pointer @var{base} and @var{tag_offset} to the tag in pointer\n\
+@var{base}.\n\
+The resulting RTX must either be a valid memory address or be able to get\n\
+put into an operand with @code{force_operand}.\n\
+\n\
+Unlike other memtag hooks, this must return an expression and not emit any\n\
+RTL.",
+ rtx, (rtx base, poly_int64 addr_offset, uint8_t tag_offset),
+ default_memtag_add_tag)
+
+DEFHOOK
+(set_tag,
+ "Return an RTX representing @var{untagged_base} but with the tag @var{tag}.\n\
+Try and store this in @var{target} if convenient.\n\
+@var{untagged_base} is required to have a zero tag when this hook is called.\n\
+The default of this hook is to set the top byte of @var{untagged_base} to\n\
+@var{tag}.",
+ rtx, (rtx untagged_base, rtx tag, rtx target), default_memtag_set_tag)
+
+DEFHOOK
+(extract_tag,
+ "Return an RTX representing the tag stored in @var{tagged_pointer}.\n\
+Store the result in @var{target} if it is convenient.\n\
+The default represents the top byte of the original pointer.",
+ rtx, (rtx tagged_pointer, rtx target), default_memtag_extract_tag)
+
+DEFHOOK
+(untagged_pointer,
+ "Return an RTX representing @var{tagged_pointer} with its tag set to zero.\n\
+Store the result in @var{target} if convenient.\n\
+The default clears the top byte of the original pointer.",
+ rtx, (rtx tagged_pointer, rtx target), default_memtag_untagged_pointer)
+
+HOOK_VECTOR_END (memtag)
+#undef HOOK_PREFIX
#define HOOK_PREFIX "TARGET_"
#define DEF_TARGET_INSN(NAME, PROTO) \
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 5b68a2a..6e12e13 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -73,6 +73,7 @@ along with GCC; see the file COPYING3. If not see
#include "varasm.h"
#include "flags.h"
#include "explow.h"
+#include "expmed.h"
#include "calls.h"
#include "expr.h"
#include "output.h"
@@ -86,6 +87,9 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "sbitmap.h"
#include "function-abi.h"
+#include "attribs.h"
+#include "asan.h"
+#include "emit-rtl.h"
bool
default_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
@@ -1860,8 +1864,11 @@ default_print_patchable_function_entry (FILE *file,
patch_area_number++;
ASM_GENERATE_INTERNAL_LABEL (buf, "LPFE", patch_area_number);
+ unsigned int flags = SECTION_WRITE | SECTION_RELRO;
+ if (HAVE_GAS_SECTION_LINK_ORDER)
+ flags |= SECTION_LINK_ORDER;
switch_to_section (get_section ("__patchable_function_entries",
- SECTION_WRITE | SECTION_RELRO, NULL));
+ flags, current_function_decl));
assemble_align (POINTER_SIZE);
fputs (asm_op, file);
assemble_name_raw (file, buf);
@@ -2415,4 +2422,115 @@ default_speculation_safe_value (machine_mode mode ATTRIBUTE_UNUSED,
return result;
}
+/* How many bits to shift in order to access the tag bits.
+ The default is to store the tag in the top 8 bits of a 64 bit pointer, hence
+ shifting 56 bits will leave just the tag. */
+#define HWASAN_SHIFT (GET_MODE_PRECISION (Pmode) - 8)
+#define HWASAN_SHIFT_RTX GEN_INT (HWASAN_SHIFT)
+
+bool
+default_memtag_can_tag_addresses ()
+{
+ return false;
+}
+
+uint8_t
+default_memtag_tag_size ()
+{
+ return 8;
+}
+
+uint8_t
+default_memtag_granule_size ()
+{
+ return 16;
+}
+
+/* The default implementation of TARGET_MEMTAG_INSERT_RANDOM_TAG. */
+rtx
+default_memtag_insert_random_tag (rtx untagged, rtx target)
+{
+ gcc_assert (param_hwasan_instrument_stack);
+ if (param_hwasan_random_frame_tag)
+ {
+ rtx fn = init_one_libfunc ("__hwasan_generate_tag");
+ rtx new_tag = emit_library_call_value (fn, NULL_RTX, LCT_NORMAL, QImode);
+ return targetm.memtag.set_tag (untagged, new_tag, target);
+ }
+ else
+ {
+ /* NOTE: The kernel API does not have __hwasan_generate_tag exposed.
+ In the future we may add the option emit random tags with inline
+ instrumentation instead of function calls. This would be the same
+ between the kernel and userland. */
+ return untagged;
+ }
+}
+
+/* The default implementation of TARGET_MEMTAG_ADD_TAG. */
+rtx
+default_memtag_add_tag (rtx base, poly_int64 offset, uint8_t tag_offset)
+{
+ /* Need to look into what the most efficient code sequence is.
+ This is a code sequence that would be emitted *many* times, so we
+ want it as small as possible.
+
+ There are two places where tag overflow is a question:
+ - Tagging the shadow stack.
+ (both tagging and untagging).
+ - Tagging addressable pointers.
+
+ We need to ensure both behaviors are the same (i.e. that the tag that
+ ends up in a pointer after "overflowing" the tag bits with a tag addition
+ is the same that ends up in the shadow space).
+
+ The aim is that the behavior of tag addition should follow modulo
+ wrapping in both instances.
+
+ The libhwasan code doesn't have any path that increments a pointer's tag,
+ which means it has no opinion on what happens when a tag increment
+ overflows (and hence we can choose our own behavior). */
+
+ offset += ((uint64_t)tag_offset << HWASAN_SHIFT);
+ return plus_constant (Pmode, base, offset);
+}
+
+/* The default implementation of TARGET_MEMTAG_SET_TAG. */
+rtx
+default_memtag_set_tag (rtx untagged, rtx tag, rtx target)
+{
+ gcc_assert (GET_MODE (untagged) == Pmode && GET_MODE (tag) == QImode);
+ tag = expand_simple_binop (Pmode, ASHIFT, tag, HWASAN_SHIFT_RTX, NULL_RTX,
+ /* unsignedp = */1, OPTAB_WIDEN);
+ rtx ret = expand_simple_binop (Pmode, IOR, untagged, tag, target,
+ /* unsignedp = */1, OPTAB_DIRECT);
+ gcc_assert (ret);
+ return ret;
+}
+
+/* The default implementation of TARGET_MEMTAG_EXTRACT_TAG. */
+rtx
+default_memtag_extract_tag (rtx tagged_pointer, rtx target)
+{
+ rtx tag = expand_simple_binop (Pmode, LSHIFTRT, tagged_pointer,
+ HWASAN_SHIFT_RTX, target,
+ /* unsignedp = */0,
+ OPTAB_DIRECT);
+ rtx ret = gen_lowpart (QImode, tag);
+ gcc_assert (ret);
+ return ret;
+}
+
+/* The default implementation of TARGET_MEMTAG_UNTAGGED_POINTER. */
+rtx
+default_memtag_untagged_pointer (rtx tagged_pointer, rtx target)
+{
+ rtx tag_mask = gen_int_mode ((HOST_WIDE_INT_1U << HWASAN_SHIFT) - 1, Pmode);
+ rtx untagged_base = expand_simple_binop (Pmode, AND, tagged_pointer,
+ tag_mask, target, true,
+ OPTAB_DIRECT);
+ gcc_assert (untagged_base);
+ return untagged_base;
+}
+
#include "gt-targhooks.h"
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index e0a925f..4542ba1 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -166,6 +166,7 @@ extern bool default_function_value_regno_p (const unsigned int);
extern rtx default_internal_arg_pointer (void);
extern rtx default_static_chain (const_tree, bool);
extern void default_trampoline_init (rtx, tree, rtx);
+extern void default_emit_call_builtin___clear_cache (rtx, rtx);
extern poly_int64 default_return_pops_args (tree, tree, poly_int64);
extern reg_class_t default_ira_change_pseudo_allocno_class (int, reg_class_t,
reg_class_t);
@@ -286,4 +287,13 @@ extern bool default_have_speculation_safe_value (bool);
extern bool speculation_safe_value_not_needed (bool);
extern rtx default_speculation_safe_value (machine_mode, rtx, rtx, rtx);
+extern bool default_memtag_can_tag_addresses ();
+extern uint8_t default_memtag_tag_size ();
+extern uint8_t default_memtag_granule_size ();
+extern rtx default_memtag_insert_random_tag (rtx, rtx);
+extern rtx default_memtag_add_tag (rtx, poly_int64, uint8_t);
+extern rtx default_memtag_set_tag (rtx, rtx, rtx);
+extern rtx default_memtag_extract_tag (rtx, rtx);
+extern rtx default_memtag_untagged_pointer (rtx, rtx);
+
#endif /* GCC_TARGHOOKS_H */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7f89efa..3339d70 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,2444 @@
+2020-12-03 Peter Bergner <bergner@linux.ibm.com>
+
+ PR c++/97947
+ * g++.target/powerpc/pr97947.C: New test.
+
+2020-12-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/80780
+ PR c++/93093
+ * g++.dg/cpp2a/srcloc15.C: New test.
+ * g++.dg/cpp2a/srcloc16.C: New test.
+ * g++.dg/cpp2a/srcloc17.C: New test.
+ * g++.dg/cpp2a/srcloc18.C: New test.
+
+2020-12-02 qing zhao <qinzhao@gcc.gnu.org>
+
+ PR rtl-optimization/97777
+ PR rtl-optimization/97777
+ * gcc.target/i386/pr97777.c: New test.
+
+2020-12-02 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/other/pr88187.C: Adjust expected error.
+ * g++.dg/cpp2a/class-deduction-abbrev1.C: New test.
+
+2020-12-02 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97975
+ * g++.dg/cpp1z/inline-var8.C: New test.
+
+2020-12-02 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97187
+ PR c++/97993
+ * g++.dg/eh/crash2.C: New test.
+ * g++.dg/template/crash132.C: New test.
+
+2020-12-02 Martin Sebor <msebor@redhat.com>
+
+ * gcc.dg/tree-ssa/builtin-sprintf-warn-1.c: Adjust expected warnings
+ to correctly reflect the maximum object size.
+ * gcc.dg/tree-ssa/builtin-sprintf-warn-11.c: Same.
+ * gcc.dg/tree-ssa/builtin-sprintf-warn-18.c: Same.
+
+2020-12-02 Ilya Leoshkevich <iii@linux.ibm.com>
+
+ * gcc.target/s390/load-imm64-1.c: New test.
+ * gcc.target/s390/load-imm64-2.c: New test.
+
+2020-12-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * ada/acats/support/acats25.lst: Delete.
+ * ada/acats/support/acats26.lst: New file.
+ * ada/acats/support/fcndecl.ada: Minor tweak.
+ * ada/acats/support/impdef.a: Add commentary.
+ * ada/acats/support/impdefg.a (Negative_Zero return): Simplify.
+ * ada/acats/support/macro.dfs (TASK_STORAGE_SIZE): Bump.
+ * ada/acats/support/repbody.ada: Upgrade to ACATS 2.6.
+ * ada/acats/support/tctouch.ada: Likewise.
+ * ada/acats/tests/c3/c352001.a: New file.
+ * ada/acats/tests/c4/c433001.a: Correct error messages.
+ * ada/acats/tests/c4/c453001.a: New file.
+ * ada/acats/tests/c4/c45622a.ada: Delete.
+ * ada/acats/tests/c4/c45624a.ada: Likewise.
+ * ada/acats/tests/c4/c45624b.ada: Likewise.
+ * ada/acats/tests/c4/c460013.a: New file.
+ * ada/acats/tests/c4/c460014.a: Likewise.
+ * ada/acats/tests/c6/c620001.a: Likewise.
+ * ada/acats/tests/c6/c620002.a: Likewise.
+ * ada/acats/tests/c7/c761006.a: Redo Unchecked_Deallocation case.
+ * ada/acats/tests/c9/c96004a.ada: Adjust for Ada 2005.
+ * ada/acats/tests/c9/c96007a.ada: Likewise.
+ * ada/acats/tests/cb/cb41004.a: Adjust for AI95-0044.
+ * ada/acats/tests/cc/cc3016f.ada: Minor tweak.
+ * ada/acats/tests/cd/cd30011.a: New file.
+ * ada/acats/tests/cd/cd30012.a: Likewise.
+ * ada/acats/tests/cd/cd90001.a: Fix comparison.
+ * ada/acats/tests/cxa/cxa3004.a: New file.
+ * ada/acats/tests/cxa/cxa5013.a: Likewise.
+ * ada/acats/tests/cxa/cxac005.a: Adjust for return-by-reference.
+ * ada/acats/tests/cxb/cxb30061.am: New file.
+ * ada/acats/tests/cxf/cxf2001.a: Fix failure message.
+
+2020-12-02 Martin Liska <mliska@suse.cz>
+
+ PR ipa/98075
+ * g++.dg/ipa/pr98075.C: New test.
+
+2020-12-02 H.J. Lu <hjl.tools@gmail.com>
+
+ PR middle-end/93195
+ * g++.dg/pr93195a.C: New test.
+ * g++.dg/pr93195b.C: Likewise.
+ * lib/target-supports.exp
+ (check_effective_target_o_flag_in_section): New proc.
+
+2020-12-02 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/98084
+ * gcc.dg/tree-ssa/pr98094.c: New test.
+
+2020-12-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/97459
+ * gcc.target/i386/pr97282.c (foo): Use 123456 divisor instead of
+ 10.
+ * gcc.dg/pr97459-1.c (TESTS): Add tests for 10, 12 and
+ 6144.
+ * gcc.dg/pr97459-2.c (TESTS): Likewise.
+ * gcc.dg/pr97459-3.c: New test.
+ * gcc.dg/pr97459-4.c: New test.
+ * gcc.dg/pr97459-5.c: New test.
+ * gcc.dg/pr97459-6.c: New test.
+
+2020-12-02 Martin Liska <mliska@suse.cz>
+
+ PR c/98087
+ * gcc.c-torture/compile/pr98087.c: New test.
+
+2020-12-02 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/98079
+ * gcc.target/i386/pr98079.c: New test.
+
+2020-12-02 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/88702
+ * gcc.dg/tree-ssa/if-to-switch-9.c: New test.
+
+2020-12-02 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/98084
+ * gcc.dg/tree-ssa/pr98084.c: New test.
+
+2020-12-02 Jeff Law <law@redhat.com>
+
+ * gcc.target/h8300/add.c: New test.
+ * gcc.target/h8300/add-2.c: New test.
+ * gcc.target/h8300/add-3.c: New test.
+ * gcc.target/h8300/sub.c: New test.
+ * gcc.target/h8300/sub-2.c: New test.
+ * gcc.target/h8300/sub-3.c: New test.
+
+2020-12-02 Ian Lance Taylor <iant@golang.org>
+
+ * go.test/go-test.exp (errchk): Permit trailing */ on ERROR line.
+
+2020-12-02 H.J. Lu <hjl.tools@gmail.com>
+ Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * c-c++-common/attr-used.c: Check the 'R' flag.
+ * c-c++-common/attr-used-2.c: Likewise.
+ * c-c++-common/attr-used-3.c: New test.
+ * c-c++-common/attr-used-4.c: Likewise.
+ * gcc.c-torture/compile/attr-used-retain-1.c: Likewise.
+ * gcc.c-torture/compile/attr-used-retain-2.c: Likewise.
+ * lib/target-supports.exp
+ (check_effective_target_R_flag_in_section): New proc.
+
+2020-12-02 H.J. Lu <hjl.tools@gmail.com>
+
+ * gcc.target/i386/x86-needed-1.c: New test.
+ * gcc.target/i386/x86-needed-2.c: Likewise.
+ * gcc.target/i386/x86-needed-3.c: Likewise.
+
+2020-12-01 Eugene Rozenfeld <Eugene.Rozenfeld@microsoft.com>
+
+ * gcc.dg/pr96708-negative.c: New test.
+ * gcc.dg/pr96708-positive.c: New test.
+
+2020-12-01 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/97595
+ * g++.dg/warn/Warray-bounds-14.C: New test.
+ * g++.dg/warn/Wstringop-overflow-6.C: New test.
+
+2020-12-01 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/pr96480.c: Disable jump table optimization
+
+2020-12-01 JeanHeyd Meneide <phdofthehouse@gmail.com>
+
+ * c-c++-common/cpp/wide-narrow-predef-macros.c: New test.
+
+2020-12-01 Jeff Law <law@redhat.com>
+
+ * gcc.dg/pr46309-2.c: Add -fno-bit-tests and -fno-jump-tables
+ to avoid compromising the test.
+
+2020-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/98072
+ * c-c++-common/gomp/depobj-2.c: New test.
+
+2020-12-01 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/97373
+ * gcc.dg/tree-ssa/builtin-sprintf-warn-25.c: New test.
+
+2020-12-01 Martin Liska <mliska@suse.cz>
+
+ * g++.dg/tree-ssa/if-to-switch-1.C: Do not allow newlines
+ in .* pattern.
+ * gcc.dg/tree-ssa/if-to-switch-1.c: Likewise.
+ * gcc.dg/tree-ssa/if-to-switch-2.c: Likewise.
+ * gcc.dg/tree-ssa/if-to-switch-3.c: Likewise.
+ * gcc.dg/tree-ssa/if-to-switch-5.c: Likewise.
+
+2020-12-01 Martin Liska <mliska@suse.cz>
+
+ PR testsuite/98085
+ * g++.dg/tree-ssa/if-to-switch-1.C: Do not expect precise number
+ of BBs.
+ * gcc.dg/tree-ssa/if-to-switch-1.c: Likewise.
+ * gcc.dg/tree-ssa/if-to-switch-2.c: Likewise. Find better name
+ for the function.
+ * gcc.dg/tree-ssa/if-to-switch-3.c: Likewise. Find better name
+ for the function.
+ * gcc.dg/tree-ssa/if-to-switch-5.c: Likewise.
+
+2020-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/97954
+ * gcc.dg/pr97954.c: New test.
+
+2020-12-01 Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * lib/hwasan-dg.exp (check_effective_target_hwaddress_exec): Fix
+ check for correct kernel version.
+
+2020-12-01 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/14799
+ PR ipa/88702
+ * gcc.dg/tree-ssa/pr96480.c: Disable if-to-switch conversion.
+ * gcc.dg/tree-ssa/reassoc-32.c: Likewise.
+ * g++.dg/tree-ssa/if-to-switch-1.C: New test.
+ * gcc.dg/tree-ssa/if-to-switch-1.c: New test.
+ * gcc.dg/tree-ssa/if-to-switch-2.c: New test.
+ * gcc.dg/tree-ssa/if-to-switch-3.c: New test.
+ * gcc.dg/tree-ssa/if-to-switch-4.c: New test.
+ * gcc.dg/tree-ssa/if-to-switch-5.c: New test.
+ * gcc.dg/tree-ssa/if-to-switch-6.c: New test.
+ * gcc.dg/tree-ssa/if-to-switch-7.c: New test.
+ * gcc.dg/tree-ssa/if-to-switch-8.c: New test.
+
+2020-12-01 Marius Hillenbrand <mhillen@linux.ibm.com>
+
+ * gcc.target/s390/float_t-1.c: New test.
+ * gcc.target/s390/float_t-2.c: New test.
+
+2020-12-01 Martin Liska <mliska@suse.cz>
+
+ * g++.dg/torture/pr93347.C: Reduce and remove LIT keywords.
+
+2020-12-01 Martin Liska <mliska@suse.cz>
+
+ PR ipa/98057
+ * g++.dg/ipa/pr98057.C: New test.
+
+2020-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/98063
+ * gcc.target/i386/pr98063.c: New test.
+
+2020-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/debug/dwarf2/lang-cpp17.C: New test.
+ * g++.dg/debug/dwarf2/lang-cpp20.C: New test.
+
+2020-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/97989
+ * gcc.dg/cpp/pr97989-1.c: New test.
+ * gcc.dg/cpp/pr97989-2.c: New test.
+
+2020-11-30 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/plugin/analyzer_gil_plugin.c: New test.
+ * gcc.dg/plugin/gil-1.c: New test.
+ * gcc.dg/plugin/gil.h: New header.
+ * gcc.dg/plugin/plugin.exp (plugin_test_list): Add the new plugin
+ and test.
+
+2020-11-30 Ilya Leoshkevich <iii@linux.ibm.com>
+
+ * lib/profopt.exp: Unset testname_with_flags if create_gcov
+ fails.
+
+2020-11-30 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR rtl-optimization/98037
+ * gcc.target/aarch64/sve/acle/general/pr98037.c: New test.
+
+2020-11-30 Jeff Law <law@redhat.com>
+
+ * g++.dg/warn/Wnonnull5.C: Fix non-unique testnames.
+ * g++.dg/warn/Wplacement-new-size-8.C: Likewise.
+
+2020-11-30 Tobias Burnus <tobias@codesourcery.com>
+
+ PR fortran/98011
+ * gfortran.dg/goacc/sentinel-free-form.f95:
+ * gfortran.dg/goacc-gomp/fixed-1.f: New test.
+ * gfortran.dg/goacc-gomp/free-1.f90: New test.
+ * gfortran.dg/goacc/fixed-5.f: New test.
+
+2020-11-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/98064
+ * g++.dg/vect/pr98064.cc: New testcase.
+
+2020-11-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/98048
+ * gcc.dg/vect/pr98048.c: New testcase.
+
+2020-11-30 Stam Markianos-Wright <stam.markianos-wright@arm.com>
+
+ * gcc.target/arm/pr91816.c: New test.
+
+2020-11-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/97459
+ * gcc.dg/pr97459-1.c: New test.
+ * gcc.dg/pr97459-2.c: New test.
+
+2020-11-29 Harald Anlauf <anlauf@gmx.de>
+
+ * gfortran.dg/pr98017.f90: New test.
+
+2020-11-29 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/92936
+ PR middle-end/92940
+ PR middle-end/89428
+ * c-c++-common/Wstringop-overflow-2.c: Adjust text of expected
+ informational notes.
+ * g++.dg/warn/Wstringop-overflow-3.C: Same.
+ * g++.dg/warn/Wplacement-new-size.C: Remove a test for a no longer
+ issued warning.
+ * gcc.dg/Warray-bounds-43.c: Removed unused declarations.
+ * gcc.dg/Wstringop-overflow-11.c: Remove xfails.
+ * gcc.dg/Wstringop-overflow-12.c: Same.
+ * gcc.dg/Wstringop-overflow-17.c: Adjust text of expected messages.
+ * gcc.dg/Wstringop-overflow-27.c: Same. Remove xfails.
+ * gcc.dg/Wstringop-overflow-28.c: Adjust text of expected messages.
+ * gcc.dg/Wstringop-overflow-29.c: Same.
+ * gcc.dg/Wstringop-overflow-37.c: Same.
+ * gcc.dg/Wstringop-overflow-46.c: Same.
+ * gcc.dg/Wstringop-overflow-47.c: Same.
+ * gcc.dg/Wstringop-overflow-54.c: Same.
+ * gcc.dg/warn-strnlen-no-nul.c: Add expected warning.
+ * gcc.dg/Wstringop-overflow-7.c: New test.
+ * gcc.dg/Wstringop-overflow-58.c: New test.
+ * gcc.dg/Wstringop-overflow-59.c: New test.
+ * gcc.dg/Wstringop-overflow-60.c: New test.
+ * gcc.dg/Wstringop-overflow-61.c: New test.
+ * gcc.dg/Wstringop-overflow-62.c: New test.
+ * gcc.dg/Wstringop-overflow-63.c: New test.
+ * gcc.dg/Wstringop-overflow-64.c: New test.
+
+2020-11-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.target/sparc/overflow-6.c: New test.
+
+2020-11-27 Joseph Myers <joseph@codesourcery.com>
+
+ PR preprocessor/97602
+ * gcc.dg/cpp/line9.c, gcc.dg/cpp/line10.c: New tests.
+
+2020-11-27 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * gdc.dg/intrinsics.d: Adjust patterns in scan-tree-dump.
+
+2020-11-27 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR testsuite/98036
+ * gcc.target/i386/fma4-256-maccXX.c (check_maccps):
+ Remove unnecessary postfix increment on a returned variable.
+ (check_maccpd): Ditto.
+ * gcc.target/i386/fma4-256-msubXX.c (check_msubps): Ditto.
+ (check_msubpd): Ditto.
+ * gcc.target/i386/fma4-256-nmaccXX.c (check_nmaccps): Ditto.
+ (check_nmaccpd): Ditto.
+ * gcc.target/i386/fma4-256-nmsubXX.c (check_nmsubps): Ditto.
+ (check_nmsubpd): Ditto.
+ * gcc.target/i386/fma4-maccXX.c (check_maccps): Ditto.
+ (check_maccpd): Ditto.
+ (check_maccss): Ditto.
+ (check_maccsd): Ditto.
+ * gcc.target/i386/fma4-msubXX.c (check_msubps): Ditto.
+ (check_msubpd): Ditto.
+ (check_msubss): Ditto.
+ (check_msubsd): Ditto.
+ * gcc.target/i386/fma4-nmaccXX.c (check_nmaccps): Ditto.
+ (check_nmaccpd): Ditto.
+ (check_nmaccss): Ditto.
+ (check_nmaccsd): Ditto.
+ * gcc.target/i386/fma4-nmsubXX.c (check_nmsubps): Ditto.
+ (check_nmsubpd): Ditto.
+ (check_nmsubss): Ditto.
+ (check_nmsubsd): Ditto.
+ * gcc.target/i386/xop-haddX.c (check_sbyte2word): Add missing return.
+ (check_sbyte2dword):
+ Remove unnecessary postfix increment on a returned value.
+ (check_sbyte2qword): Ditto.
+ (check_sword2dword): Add missing return.
+ (check_sword2qword):
+ Remove unnecessary postfix increment on a returned value.
+ (check_dword2qword): Add missing return.
+ * gcc.target/i386/xop-hadduX.c (check_byte2word): Add missing return.
+ (check_byte2dword):
+ Remove unnecessary postfix increment on a returned value.
+ (check_byte2qword): Ditto.
+ (check_word2dword): Add missing return.
+ (check_word2qword):
+ Remove unnecessary postfix increment on a returned value.
+ (check_word2qword): Add missing return.
+ * gcc.target/i386/xop-hsubX.c (check_sbyte2word): Add missing return.
+ (check_sword2dword): Ditto.
+ (check_sword2qword): Ditto.
+
+2020-11-27 Thomas Schwinge <thomas@codesourcery.com>
+
+ * c-c++-common/goacc/kernels-decompose-ice-1.c: Adjust.
+ * c-c++-common/goacc/kernels-decompose-ice-2.c: Likewise.
+
+2020-11-27 Tobias Burnus <tobias@codesourcery.com>
+
+ * gfortran.dg/gomp/requires-4.f90: Fix typo in '!$omp' clause.
+
+2020-11-27 Tobias Burnus <tobias@codesourcery.com>
+
+ * gfortran.dg/gomp/requires-4.f90: Fix '!$omp' syntax.
+
+2020-11-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR libstdc++/88101
+ * g++.dg/torture/builtin-clear-padding-3.C: New test.
+
+2020-11-27 Tobias Burnus <tobias@codesourcery.com>
+
+ PR c/97880
+ * gcc.dg/goacc/tile-1.c: New test.
+
+2020-11-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/97997
+ * gcc.dg/tree-ssa/pr97997-1.c: New test.
+ * gcc.dg/tree-ssa/pr97997-2.c: New test.
+
+2020-11-26 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97953
+ * gcc.dg/pr97953.c: New testcase.
+
+2020-11-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/97979
+ * gcc.dg/pr97979.c: New test.
+ * gcc.c-torture/compile/pr97979.c: New test.
+
+2020-11-26 Richard Biener <rguenther@suse.de>
+
+ PR testsuite/98002
+ * gcc.dg/strncmp-2.c: Call mprotect again before free.
+
+2020-11-26 Thomas Schwinge <thomas@codesourcery.com>
+
+ * c-c++-common/goacc/cache-3-1.c: New.
+ * c-c++-common/goacc/cache-3-2.c: Likewise.
+ * c-c++-common/goacc/data-clause-1.c: Likewise.
+ * c-c++-common/goacc/data-clause-2.c: Likewise.
+ * c-c++-common/gomp/map-1.c: Adjust.
+ * c-c++-common/gomp/map-2.c: Likewise.
+ * g++.dg/goacc/cache-3-1.C: New.
+ * g++.dg/goacc/cache-3-2.C: Likewise.
+ * g++.dg/goacc/data-clause-1.C: Likewise.
+ * g++.dg/goacc/data-clause-2.C: Likewise.
+ * g++.dg/gomp/map-1.C: Adjust.
+ * g++.dg/gomp/map-2.C: Likewise.
+
+2020-11-26 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/97873
+ * gcc.target/i386/pr97873-3.c: New test.
+
+2020-11-26 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/multfixed.adb: Robustify.
+
+2020-11-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/96906
+ * gcc.target/i386/pr96906-1.c: New test.
+
+2020-11-26 Martin Uecker <muecker@gwdg.de>
+
+ PR c/65455
+ PR c/92935
+ * gcc.dg/typeof-2.c: Adapt test.
+
+2020-11-26 David Edelsohn <dje.gcc@gmail.com>
+
+ * gcc.dg/nextafter-1.c: Omit prototypes if _NEXT_AFTER_2 defined.
+ * gcc.dg/nextafter-2.c: Define _NEXT_AFTER_2.
+ * gcc.dg/profile-info-section.c: Skip on AIX.
+
+2020-11-25 Martin Sebor <msebor@redhat.com>
+
+ PR bootstrap/94982
+ * c-c++-common/patchable_function_entry-error-3.c: Adjust text
+ of expected warning.
+
+2020-11-25 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/lto/modref-3_0.c: New test.
+ * gcc.dg/lto/modref-3_1.c: New test.
+ * gcc.dg/lto/modref-4_0.c: New test.
+ * gcc.dg/lto/modref-4_1.c: New test.
+ * gcc.dg/tree-ssa/modref-5.c: New test.
+
+2020-11-25 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/85796
+ * gfortran.dg/pr85796.f90: New test.
+
+2020-11-25 Thomas Schwinge <thomas@codesourcery.com>
+
+ * g++.dg/gomp/map-1.C: New.
+ * g++.dg/gomp/map-2.C: Likewise.
+ * c-c++-common/gomp/map-1.c: Adjust.
+ * c-c++-common/gomp/map-2.c: Likewise.
+
+2020-11-25 Thomas Schwinge <thomas@codesourcery.com>
+
+ * c-c++-common/goacc/cache-1.c: Update.
+ * c-c++-common/goacc/cache-2.c: Likewise.
+ * g++.dg/goacc/cache-1.C: New.
+ * g++.dg/goacc/cache-2.C: Likewise.
+
+2020-11-25 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/97956
+ * gcc.dg/memchr-3.c: New test.
+
+2020-11-25 Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * c-c++-common/ubsan/sanitize-recover-7.c: Update error message format.
+ * lib/asan-dg.exp (asan_link_flags): Implement as a helper
+ function asan_link_flags_1 which asan_link_flags and
+ hwasan_link_flags use.
+ (asan_link_flags_1): Parametrised version of asan_link_flags.
+ * c-c++-common/hwasan/aligned-alloc.c: New test.
+ * c-c++-common/hwasan/alloca-array-accessible.c: New test.
+ * c-c++-common/hwasan/alloca-base-init.c: New test.
+ * c-c++-common/hwasan/alloca-gets-different-tag.c: New test.
+ * c-c++-common/hwasan/alloca-outside-caught.c: New test.
+ * c-c++-common/hwasan/arguments-1.c: New test.
+ * c-c++-common/hwasan/arguments-2.c: New test.
+ * c-c++-common/hwasan/arguments-3.c: New test.
+ * c-c++-common/hwasan/arguments.c: New test.
+ * c-c++-common/hwasan/asan-pr63316.c: New test.
+ * c-c++-common/hwasan/asan-pr70541.c: New test.
+ * c-c++-common/hwasan/asan-pr78106.c: New test.
+ * c-c++-common/hwasan/asan-pr79944.c: New test.
+ * c-c++-common/hwasan/asan-rlimit-mmap-test-1.c: New test.
+ * c-c++-common/hwasan/bitfield-1.c: New test.
+ * c-c++-common/hwasan/bitfield-2.c: New test.
+ * c-c++-common/hwasan/builtin-special-handling.c: New test.
+ * c-c++-common/hwasan/check-interface.c: New test.
+ * c-c++-common/hwasan/halt_on_error-1.c: New test.
+ * c-c++-common/hwasan/handles-poly_int-marked-vars.c: New test.
+ * c-c++-common/hwasan/heap-overflow.c: New test.
+ * c-c++-common/hwasan/hwasan-poison-optimisation.c: New test.
+ * c-c++-common/hwasan/hwasan-thread-access-parent.c: New test.
+ * c-c++-common/hwasan/hwasan-thread-basic-failure.c: New test.
+ * c-c++-common/hwasan/hwasan-thread-clears-stack.c: New test.
+ * c-c++-common/hwasan/hwasan-thread-success.c: New test.
+ * c-c++-common/hwasan/kernel-defaults.c: New test.
+ * c-c++-common/hwasan/large-aligned-0.c: New test.
+ * c-c++-common/hwasan/large-aligned-1.c: New test.
+ * c-c++-common/hwasan/large-aligned-untagging-0.c: New test.
+ * c-c++-common/hwasan/large-aligned-untagging-1.c: New test.
+ * c-c++-common/hwasan/large-aligned-untagging-2.c: New test.
+ * c-c++-common/hwasan/large-aligned-untagging-3.c: New test.
+ * c-c++-common/hwasan/large-aligned-untagging-4.c: New test.
+ * c-c++-common/hwasan/large-aligned-untagging-5.c: New test.
+ * c-c++-common/hwasan/large-aligned-untagging-6.c: New test.
+ * c-c++-common/hwasan/large-aligned-untagging-7.c: New test.
+ * c-c++-common/hwasan/macro-definition.c: New test.
+ * c-c++-common/hwasan/no-sanitize-attribute.c: New test.
+ * c-c++-common/hwasan/param-instrument-mem-intrinsics.c: New test.
+ * c-c++-common/hwasan/param-instrument-reads-and-writes.c: New test.
+ * c-c++-common/hwasan/param-instrument-reads.c: New test.
+ * c-c++-common/hwasan/param-instrument-writes.c: New test.
+ * c-c++-common/hwasan/random-frame-tag.c: New test.
+ * c-c++-common/hwasan/sanity-check-pure-c.c: New test.
+ * c-c++-common/hwasan/setjmp-longjmp-0.c: New test.
+ * c-c++-common/hwasan/setjmp-longjmp-1.c: New test.
+ * c-c++-common/hwasan/stack-tagging-basic-0.c: New test.
+ * c-c++-common/hwasan/stack-tagging-basic-1.c: New test.
+ * c-c++-common/hwasan/stack-tagging-disable.c: New test.
+ * c-c++-common/hwasan/unprotected-allocas-0.c: New test.
+ * c-c++-common/hwasan/unprotected-allocas-1.c: New test.
+ * c-c++-common/hwasan/use-after-free.c: New test.
+ * c-c++-common/hwasan/vararray-outside-caught.c: New test.
+ * c-c++-common/hwasan/vararray-stack-restore-correct.c: New test.
+ * c-c++-common/hwasan/very-large-objects.c: New test.
+ * g++.dg/hwasan/hwasan.exp: New test.
+ * g++.dg/hwasan/rvo-handled.C: New test.
+ * gcc.dg/hwasan/hwasan.exp: New test.
+ * gcc.dg/hwasan/nested-functions-0.c: New test.
+ * gcc.dg/hwasan/nested-functions-1.c: New test.
+ * gcc.dg/hwasan/nested-functions-2.c: New test.
+ * lib/hwasan-dg.exp: New file.
+
+2020-11-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/95862
+ * gcc.dg/builtin-artih-overflow-5.c: Renamed to ...
+ * gcc.dg/builtin-arith-overflow-5.c: ... this.
+
+2020-11-25 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/acle/asm/abs_f16.c (abs_f16_x_untied): Expect
+ a MOVPRFX instruction.
+ * gcc.target/aarch64/sve/acle/asm/abs_f32.c (abs_f32_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/abs_f64.c (abs_f64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/abs_s16.c (abs_s16_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/abs_s32.c (abs_s32_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/abs_s64.c (abs_s64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/abs_s8.c (abs_s8_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cls_s16.c (cls_s16_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cls_s32.c (cls_s32_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cls_s64.c (cls_s64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cls_s8.c (cls_s8_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/clz_s16.c (clz_s16_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/clz_s32.c (clz_s32_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/clz_s64.c (clz_s64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/clz_s8.c (clz_s8_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/clz_u16.c (clz_u16_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/clz_u32.c (clz_u32_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/clz_u64.c (clz_u64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/clz_u8.c (clz_u8_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnot_s16.c (cnot_s16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnot_s32.c (cnot_s32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnot_s64.c (cnot_s64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnot_s8.c (cnot_s8_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnot_u16.c (cnot_u16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnot_u32.c (cnot_u32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnot_u64.c (cnot_u64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnot_u8.c (cnot_u8_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnt_bf16.c (cnt_bf16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnt_f16.c (cnt_f16_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnt_f32.c (cnt_f32_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnt_f64.c (cnt_f64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnt_s16.c (cnt_s16_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnt_s32.c (cnt_s32_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnt_s64.c (cnt_s64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnt_s8.c (cnt_s8_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnt_u16.c (cnt_u16_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnt_u32.c (cnt_u32_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnt_u64.c (cnt_u64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cnt_u8.c (cnt_u8_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cvt_bf16.c (cvt_bf16_f32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cvt_f16.c (cvt_f16_f32_x_untied)
+ (cvt_f16_f64_x_untied, cvt_f16_s16_x_untied, cvt_f16_s32_x_untied)
+ (cvt_f16_s64_x_untied, cvt_f16_u16_x_untied, cvt_f16_u32_x_untied)
+ (cvt_f16_u64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cvt_f32.c (cvt_f32_f16_x_untied)
+ (cvt_f32_f64_x_untied, cvt_f32_s16_x_untied, cvt_f32_s32_x_untied)
+ (cvt_f32_s64_x_untied, cvt_f32_u16_x_untied, cvt_f32_u32_x_untied)
+ (cvt_f32_u64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cvt_f64.c (cvt_f64_f16_x_untied)
+ (cvt_f64_f32_x_untied, cvt_f64_s16_x_untied, cvt_f64_s32_x_untied)
+ (cvt_f64_s64_x_untied, cvt_f64_u16_x_untied, cvt_f64_u32_x_untied)
+ (cvt_f64_u64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cvt_s16.c (cvt_s16_f16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cvt_s32.c (cvt_s32_f16_x_untied)
+ (cvt_s32_f32_x_untied, cvt_s32_s64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cvt_s64.c (cvt_s64_f16_x_untied)
+ (cvt_s64_f32_x_untied, cvt_s64_s64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cvt_u16.c (cvt_u16_f16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cvt_u32.c (cvt_u32_f16_x_untied)
+ (cvt_u32_f32_x_untied, cvt_u32_u64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/cvt_u64.c (cvt_u64_f16_x_untied)
+ (cvt_u64_f32_x_untied, cvt_u64_u64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/extb_s16.c (extb_s16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/extb_s32.c (extb_s32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/extb_s64.c (extb_s64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/exth_s32.c (exth_s32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/exth_s64.c (exth_s64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/extw_s64.c (extw_s64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/neg_f16.c (neg_f16_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/neg_f32.c (neg_f32_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/neg_f64.c (neg_f64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/neg_s16.c (neg_s16_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/neg_s32.c (neg_s32_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/neg_s64.c (neg_s64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/neg_s8.c (neg_s8_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/not_s16.c (not_s16_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/not_s32.c (not_s32_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/not_s64.c (not_s64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/not_s8.c (not_s8_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/not_u16.c (not_u16_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/not_u32.c (not_u32_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/not_u64.c (not_u64_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/not_u8.c (not_u8_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rbit_s16.c (rbit_s16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rbit_s32.c (rbit_s32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rbit_s64.c (rbit_s64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rbit_s8.c (rbit_s8_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rbit_u16.c (rbit_u16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rbit_u32.c (rbit_u32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rbit_u64.c (rbit_u64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rbit_u8.c (rbit_u8_x_untied): Ditto.
+ * gcc.target/aarch64/sve/acle/asm/recpx_f16.c (recpx_f16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/recpx_f32.c (recpx_f32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/recpx_f64.c (recpx_f64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/revb_s16.c (revb_s16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/revb_s32.c (revb_s32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/revb_s64.c (revb_s64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/revb_u16.c (revb_u16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/revb_u32.c (revb_u32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/revb_u64.c (revb_u64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/revh_s32.c (revh_s32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/revh_s64.c (revh_s64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/revh_u32.c (revh_u32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/revh_u64.c (revh_u64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/revw_s64.c (revw_s64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/revw_u64.c (revw_u64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rinta_f16.c (rinta_f16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rinta_f32.c (rinta_f32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rinta_f64.c (rinta_f64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rinti_f16.c (rinti_f16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rinti_f32.c (rinti_f32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rinti_f64.c (rinti_f64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rintm_f16.c (rintm_f16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rintm_f32.c (rintm_f32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rintm_f64.c (rintm_f64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rintn_f16.c (rintn_f16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rintn_f32.c (rintn_f32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rintn_f64.c (rintn_f64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rintp_f16.c (rintp_f16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rintp_f32.c (rintp_f32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rintp_f64.c (rintp_f64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rintx_f16.c (rintx_f16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rintx_f32.c (rintx_f32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rintx_f64.c (rintx_f64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rintz_f16.c (rintz_f16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rintz_f32.c (rintz_f32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/rintz_f64.c (rintz_f64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/sqrt_f16.c (sqrt_f16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/sqrt_f32.c (sqrt_f32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve/acle/asm/sqrt_f64.c (sqrt_f64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve2/acle/asm/cvtx_f32.c (cvtx_f32_f64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve2/acle/asm/logb_f16.c (logb_f16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve2/acle/asm/logb_f32.c (logb_f32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve2/acle/asm/logb_f64.c (logb_f64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve2/acle/asm/qabs_s16.c (qabs_s16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve2/acle/asm/qabs_s32.c (qabs_s32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve2/acle/asm/qabs_s64.c (qabs_s64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve2/acle/asm/qabs_s8.c (qabs_s8_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve2/acle/asm/qneg_s16.c (qneg_s16_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve2/acle/asm/qneg_s32.c (qneg_s32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve2/acle/asm/qneg_s64.c (qneg_s64_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve2/acle/asm/qneg_s8.c (qneg_s8_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve2/acle/asm/recpe_u32.c (recpe_u32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve2/acle/asm/rsqrte_u32.c (rsqrte_u32_x_untied):
+ Ditto.
+ * gcc.target/aarch64/sve2/acle/asm/cvtlt_f32.c
+ (cvtlt_f32_f16_x_untied): Expect a MOV instruction.
+ * gcc.target/aarch64/sve2/acle/asm/cvtlt_f64.c
+ (cvtlt_f64_f32_x_untied): Likewise.
+
+2020-11-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/95862
+ * gcc.dg/builtin-artih-overflow-5.c: New test.
+
+2020-11-25 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/97579
+ * gcc.dg/pr97579.c: New testcase.
+
+2020-11-25 Stam Markianos-Wright <stam.markianos-wright@arm.com>
+
+ PR target/91816
+ * gcc.target/arm/pr91816.c: New test.
+
+2020-11-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/97943
+ * c-c++-common/builtin-clear-padding-2.c: New test.
+ * c-c++-common/builtin-clear-padding-3.c: New test.
+ * g++.dg/ext/builtin-clear-padding-1.C: New test.
+ * gcc.dg/builtin-clear-padding-2.c: New test.
+
+2020-11-24 Martin Sebor <msebor@redhat.com>
+
+ * gcc.dg/pr97955.c: New test.
+
+2020-11-24 Martin Sebor <msebor@redhat.com>
+
+ * gcc.dg/Wstringop-overflow-47.c: Add a note.
+
+2020-11-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/97899
+ * g++.dg/cpp0x/initlist-template3.C: New test.
+
+2020-11-24 Martin Sebor <msebor@redhat.com>
+
+ * gfortran.dg/gomp/declare-target-4.f90: Adjust pattern to expect
+ an additional attribute and function return type.
+
+2020-11-24 Richard Earnshaw <rearnsha@arm.com>
+
+ * gcc.dg/pr97534.c: New test.
+
+2020-11-24 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/aapcs64/abitest.h (FUNC_VAL_CHECK): Use
+ noipa rather than noinline.
+ * gcc.target/aarch64/aapcs64/abitest-2.h (FUNC_VAL_CHECK): Likewise.
+
+2020-11-24 Ilya Leoshkevich <iii@linux.ibm.com>
+
+ * gcc.target/s390/zvector/autovec-double-quiet-uneq.c: Expect
+ that "vx" is not emitted.
+ * gcc.target/s390/zvector/autovec-float-quiet-uneq.c: Likewise.
+
+2020-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/97950
+ * gcc.target/i386/pr97950.c: New test.
+
+2020-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/97964
+ * gcc.dg/tree-ssa/pr97964.c: New test.
+
+2020-11-24 Thomas Schwinge <thomas@codesourcery.com>
+
+ * c-c++-common/goacc/kernels-decompose-1.c: Avoid Tcl 8.5-specific
+ behavior.
+ * c-c++-common/goacc/kernels-decompose-2.c: Likewise.
+ * gfortran.dg/goacc/kernels-decompose-1.f95: Likewise.
+ * gfortran.dg/goacc/kernels-decompose-2.f95: Likewise.
+
+2020-11-24 Thomas Schwinge <thomas@codesourcery.com>
+
+ * lib/gcc-dg.exp (dg-optimized, dg-missed): Use 'saved-dg-warning'
+ instead of 'saved-dg-error'.
+
+2020-11-24 Thomas Schwinge <thomas@codesourcery.com>
+
+ * lib/gcc-dg.exp (dg-optimized, dg-missed): Fix 'process-message'
+ call.
+ * gcc.dg/vect/nodump-vect-opt-info-1.c: Demonstrate.
+ * gcc.dg/vect/nodump-vect-opt-info-2.c: Likewise.
+
+2020-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/97958
+ * c-c++-common/gomp/pr97958.c: New test.
+
+2020-11-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/96929
+ * gcc.dg/tree-ssa/pr96929.c: New test.
+
+2020-11-24 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/pr23401.c: Update expected output.
+ * gcc.dg/tree-ssa/pr27810.c: Update expected output.
+ * gcc.dg/tree-ssa/slsr-8.c: Update expected output.
+
+2020-11-24 Kewen Lin <linkw@linux.ibm.com>
+
+ * gcc.dg/vect/slp-perm-1.c: Adjust for partial vectors.
+ * gcc.dg/vect/slp-perm-5.c: Likewise.
+ * gcc.dg/vect/slp-perm-6.c: Likewise.
+ * gcc.dg/vect/slp-perm-7.c: Likewise.
+
+2020-11-24 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ PR tree-optimization/97849
+ * gcc.dg/tree-ssa/pr97849.c: New test.
+
+2020-11-24 Martin Sebor <msebor@redhat.com>
+
+ * gcc.dg/attr-access-5.c: New test.
+
+2020-11-23 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/95630
+ * gcc.dg/c11-compare-incomplete-1.c,
+ gcc.dg/c11-compare-incomplete-2.c,
+ gcc.dg/c99-compare-incomplete-1.c,
+ gcc.dg/c99-compare-incomplete-2.c: New tests.
+
+2020-11-23 Martin Jambor <mjambor@suse.cz>
+
+ * gfortran.dg/ipcp-array-2.f90: New test.
+
+2020-11-23 Nathan Sidwell <nathan@acm.org>
+
+ * lib/prune.exp (prune_gcc_output): Adjust include stack pruning
+ for modules.
+ (print_ices): Relax regexp.
+
+2020-11-23 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * g++.target/msp430/data-attributes.C: Remove expected warnings for
+ "lower" attribute conflicts.
+ Adjust expected wording for "persistent" attribute misuse.
+ * gcc.target/msp430/data-attributes-2.c: Likewise.
+ * gcc.target/msp430/pr78818-auto-warn.c: Likewise.
+
+2020-11-23 Richard Biener <rguenther@suse.de>
+
+ * g++.dg/vect/simd-12.cc: New testcase.
+
+2020-11-23 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * gcc.c-torture/execute/noinit-attribute.c: Moved to...
+ * c-c++-common/torture/attr-noinit-main.inc: ...here.
+ * lib/target-supports.exp (check_effective_target_persistent): New.
+ * c-c++-common/torture/attr-noinit-1.c: New test.
+ * c-c++-common/torture/attr-noinit-2.c: New test.
+ * c-c++-common/torture/attr-noinit-3.c: New test.
+ * c-c++-common/torture/attr-noinit-invalid.c: New test.
+ * c-c++-common/torture/attr-persistent-1.c: New test.
+ * c-c++-common/torture/attr-persistent-2.c: New test.
+ * c-c++-common/torture/attr-persistent-3.c: New test.
+ * c-c++-common/torture/attr-persistent-invalid.c: New test.
+ * c-c++-common/torture/attr-persistent-main.inc: New test.
+
+2020-11-23 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * gcc.target/msp430/data-attributes-2.c: Adjust test.
+ * g++.target/msp430/data-attributes.C: New test.
+ * g++.target/msp430/msp430.exp: New test.
+
+2020-11-23 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * gcc.c-torture/execute/noinit-attribute.c: Don't override
+ optimization options set by torture test harness.
+ * lib/target-supports.exp (check_effective_target_noinit): Adjust
+ comment formatting.
+
+2020-11-23 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/arm/cortex-m55-nodsp-flag-hard.c: Add -mthumb.
+ * gcc.target/arm/cortex-m55-nodsp-flag-softfp.c: Likewise.
+ * gcc.target/arm/cortex-m55-nodsp-nofp-flag-softfp.c: Likewise.
+ * gcc.target/arm/cortex-m55-nofp-flag-hard.c: Likewise.
+ * gcc.target/arm/cortex-m55-nofp-flag-softfp.c: Likewise.
+ * gcc.target/arm/cortex-m55-nofp-nomve-flag-softfp.c: Likewise.
+ * gcc.target/arm/cortex-m55-nomve-flag-hard.c: Likewise.
+ * gcc.target/arm/cortex-m55-nomve-flag-softfp.c: Likewise.
+ * gcc.target/arm/cortex-m55-nomve.fp-flag-hard.c: Likewise.
+ * gcc.target/arm/cortex-m55-nomve.fp-flag-softfp.c: Likewise.
+ * gcc.target/arm/mve/intrinsics/pr97327.c: Likewise.
+
+2020-11-23 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR c++/97904
+ * g++.dg/ext/sve-sizeless-1.C: Add more template tests.
+ * g++.dg/ext/sve-sizeless-2.C: Likewise.
+
+2020-11-22 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/97873
+ * gcc.target/i386/pr97873-2.c: New test.
+
+2020-11-22 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/97889
+ * gdc.dg/torture/pr97889.d: New test.
+
+2020-11-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/95853
+ * gcc.dg/pr95853.c: New test.
+
+2020-11-21 Marek Polacek <polacek@redhat.com>
+
+ PR c++/94695
+ * g++.dg/warn/Wrange-loop-construct2.C: New test.
+
+2020-11-21 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97846
+ * g++.dg/cpp1y/constexpr-label.C: New test.
+
+2020-11-21 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97881
+ * g++.dg/warn/Wvexing-parse9.C: New test.
+
+2020-11-21 David Edelsohn <dje.gcc@gmail.com>
+
+ * g++.dg/debug/localclass2.C: Require LTO.
+
+2020-11-21 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97839
+ * g++.dg/cpp2a/lambda-generic8.C: New test.
+
+2020-11-21 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97427
+ * g++.dg/cpp2a/constexpr-dtor10.C: New test.
+
+2020-11-21 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/vect/vect-35-big-array.c: Excpect 2 loops to be vectorized.
+ * gcc.dg/vect/vect-35.c: Excpect 2 loops to be vectorized.
+
+2020-11-21 Aaron Sawdey <acsawdey@linux.ibm.com>
+
+ * gcc.target/powerpc/mma-double-test.c (main): Call abort for failure.
+ * gcc.target/powerpc/mma-single-test.c (main): Call abort for failure.
+ * gcc.target/powerpc/pr96506.c: Rename to pr96506-1.c.
+ * gcc.target/powerpc/pr96506-2.c: New test.
+ * gcc.target/powerpc/pr96506-1.c: New file.
+
+2020-11-20 Michael Meissner <meissner@linux.ibm.com>
+
+ * gcc.dg/nextafter-2.c: Include math.h.
+
+2020-11-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/97918
+ * g++.dg/debug/localclass2.C: New test.
+
+2020-11-20 Martin Sebor <msebor@redhat.com>
+
+ * gcc.dg/attr-access-4.c: New test.
+
+2020-11-20 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/97879
+ * gcc.dg/attr-access-3.c: New test.
+
+2020-11-20 Andrew MacLeod <amacleod@redhat.com>
+
+ * gcc.dg/pr97515.c: Check in ccp2, not evrp.
+
+2020-11-20 Andrea Corallo <andrea.corallo@arm.com>
+
+ PR target/97727
+ * gcc.target/aarch64/advsimd-intrinsics/bf16_vstN_lane_2.c: Relax
+ regexps.
+
+2020-11-20 Andrea Corallo <andrea.corallo@arm.com>
+
+ PR target/97726
+ * gcc.target/arm/simd/bf16_vldn_1.c: Relax regexps not to fail on
+ big endian.
+ * gcc.target/arm/simd/vldn_lane_bf16_1.c: Likewise
+ * gcc.target/arm/simd/vmmla_1.c: Add -mfloat-abi=hard flag.
+
+2020-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR libstdc++/88101
+ * c-c++-common/builtin-clear-padding-1.c: New test.
+ * c-c++-common/torture/builtin-clear-padding-1.c: New test.
+ * c-c++-common/torture/builtin-clear-padding-2.c: New test.
+ * c-c++-common/torture/builtin-clear-padding-3.c: New test.
+ * c-c++-common/torture/builtin-clear-padding-4.c: New test.
+ * c-c++-common/torture/builtin-clear-padding-5.c: New test.
+ * g++.dg/torture/builtin-clear-padding-1.C: New test.
+ * g++.dg/torture/builtin-clear-padding-2.C: New test.
+ * gcc.dg/builtin-clear-padding-1.c: New test.
+
+2020-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/97528
+ * gcc.target/arm/pr97528.c: New test.
+
+2020-11-20 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/opt90a.adb: New test.
+ * gnat.dg/opt90b.adb: Likewise.
+ * gnat.dg/opt90c.adb: Likewise.
+ * gnat.dg/opt90d.adb: Likewise.
+ * gnat.dg/opt90e.adb: Likewise.
+ * gnat.dg/opt90a_pkg.ads: New helper.
+ * gnat.dg/opt90b_pkg.ads: Likewise.
+ * gnat.dg/opt90c_pkg.ads: Likewise.
+ * gnat.dg/opt90d_pkg.ads: Likewise.
+ * gnat.dg/opt90e_pkg.ads: Likewise.
+
+2020-11-20 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/97873
+ * gcc.target/i386/pr97873.c: New test.
+ * gcc.target/i386/pr97873-1.c: New test.
+
+2020-11-20 Martin Uecker <muecker@gwdg.de>
+
+ * gcc.dg/cond-constqual-1.c: Adapt test.
+ * gcc.dg/lvalue-11.c: New test.
+ * gcc.dg/pr60195.c: Add warning.
+
+2020-11-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/91029
+ * gcc.dg/tree-ssa/pr91029-1.c: New test.
+ * gcc.dg/tree-ssa/pr91029-2.c: New test.
+
+2020-11-19 Andrew MacLeod <amacleod@redhat.com>
+
+ * gcc.dg/tree-ssa/pr93781-1.c: New.
+ * gcc.dg/tree-ssa/pr93781-2.c: New.
+ * gcc.dg/tree-ssa/pr93781-3.c: New.
+
+2020-11-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/97860
+ * gcc.dg/pr97860.c: New test.
+
+2020-11-19 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97523
+ * g++.dg/expr/anew5.C: New test.
+ * g++.dg/expr/anew6.C: New test.
+
+2020-11-19 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97895
+ * g++.dg/cpp0x/auto54.C: New test.
+
+2020-11-19 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/97905
+ * g++.dg/lookup/pr97905.C: New.
+
+2020-11-19 Dimitar Dimitrov <dimitar@dinux.eu>
+
+ * gcc.target/pru/halt.c: New test.
+ * gcc.target/pru/lmbd.c: New test.
+
+2020-11-19 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/vect/vect-cost-model-1.c: New test.
+ * gcc.dg/vect/vect-cost-model-2.c: Likewise.
+ * gcc.dg/vect/vect-cost-model-3.c: Likewise.
+ * gcc.dg/vect/vect-cost-model-4.c: Likewise.
+ * gcc.dg/vect/vect-cost-model-5.c: Likewise.
+ * gcc.dg/vect/vect-cost-model-6.c: Likewise.
+
+2020-11-19 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/pr97897.c: Add dg-options.
+
+2020-11-19 Joel Hutton <joel.hutton@arm.com>
+
+ * gcc.target/aarch64/vect-widen-lshift.c: New test.
+
+2020-11-19 Joel Hutton <joel.hutton@arm.com>
+
+ * gcc.target/aarch64/vect-widen-add.c: New test.
+ * gcc.target/aarch64/vect-widen-sub.c: New test.
+
+2020-11-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97901
+ * gcc.dg/torture/pr97901.c: New testcase.
+
+2020-11-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97897
+ * gcc.dg/pr97897.c: New testcase.
+
+2020-11-19 Uroš Bizjak <ubizjak@gmail.com>
+
+ * gcc.target/i386/pr97887.c: New test.
+
+2020-11-18 Roger Sayle <roger@nextmovesoftware.com>
+
+ PR middle-end/85811
+ * gcc.dg/pr85811.c: New test.
+ * gcc.dg/fold-isfinite-1.c: New test.
+ * gcc.dg/fold-isfinite-2.c: New test.
+ * gcc.dg/fold-isinf-1.c: New test.
+ * gcc.dg/fold-isinf-2.c: New test.
+ * gcc.dg/fold-isnan-1.c: New test.
+ * gcc.dg/fold-isnan-2.c: New test.
+
+2020-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/91029
+ PR tree-optimization/97888
+ * gcc.dg/pr91029.c: Add comment with PR number.
+ (f2): Use > 0 rather than >= 0.
+ * gcc.c-torture/execute/pr97888-1.c: New test.
+ * gcc.c-torture/execute/pr97888-2.c: New test.
+
+2020-11-18 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/97893
+ * gcc.dg/analyzer/malloc-1.c: Add CWE-690 and CWE-476 codes to
+ expected output.
+
+2020-11-18 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/vect/bb-slp-pr68892.c: Don't XFAIL the profitability
+ test for aarch64*-*-*. Allow the "BB vectorization with gaps"
+ message to be printed more than once.
+
+2020-11-18 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/vect/slp-21.c: Expect 4 SLP instances to be vectorized
+ on arm* and aarch64* targets.
+
+2020-11-18 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/vect/fast-math-vect-call-1.c: Only expect SLP to be used
+ on vect_perm3_int targets.
+ * gcc.dg/vect/slp-perm-6.c: Likewise. Only XFAIL the LOAD/STORE_LANES
+ tests on vect_perm3_int targets.
+
+2020-11-18 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/vect/vect-epilogues.c: XFAIL test for epilogue loop
+ vectorization if vect_partial_vectors_usage_2.
+
+2020-11-18 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/vect/vect-sdiv-pow2-1.c (main): Add an asm to the
+ set-up loop.
+
+2020-11-18 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/97843
+ * gdc.dg/torture/pr97843.d: New test.
+
+2020-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/97862
+ * c-c++-common/gomp/pr97862.c: New test.
+
+2020-11-18 Kito Cheng <kito.cheng@sifive.com>
+
+ * gcc.target/riscv/arch-9.c: New.
+ * gcc.target/riscv/arch-10.c: Ditto.
+ * gcc.target/riscv/arch-11.c: Ditto.
+ * gcc.target/riscv/attribute-6.c: Remove, we don't support G
+ with version anymore.
+ * gcc.target/riscv/attribute-8.c: Reorder arch string to fit canonical
+ ordering.
+ * gcc.target/riscv/attribute-9.c: We don't emit version for
+ unknown extensions now.
+ * gcc.target/riscv/attribute-11.c: Add -misa-spec=2.2 flags.
+ * gcc.target/riscv/attribute-12.c: Ditto.
+ * gcc.target/riscv/attribute-13.c: Ditto.
+ * gcc.target/riscv/attribute-14.c: Ditto.
+ * gcc.target/riscv/attribute-15.c: New.
+ * gcc.target/riscv/attribute-16.c: Ditto.
+ * gcc.target/riscv/attribute-17.c: Ditto.
+
+2020-11-18 Kito Cheng <kito.cheng@sifive.com>
+
+ * gcc.target/riscv/arch-8.c: New.
+ * gcc.target/riscv/attribute-14.c: Ditto.
+
+2020-11-18 Jiufu Guo <guojiufu@linux.ibm.com>
+
+ * gcc.dg/tree-ssa/loopclosedphi.c: New test.
+
+2020-11-17 Andrew MacLeod <amacleod@redhat.com>
+
+ * gcc.dg/pr91029.c: New.
+
+2020-11-17 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/97877
+ * g++.dg/lookup/pr97877.C: New.
+
+2020-11-17 Andrew MacLeod <amacleod@redhat.com>
+
+ * gcc.dg/pr83072.c: New.
+
+2020-11-17 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/cr-decimal-dig-3.c: New test.
+
+2020-11-17 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/c11-float-6.c, gcc.dg/c2x-float-10.c: New tests.
+
+2020-11-17 David Edelsohn <dje.gcc@gmail.com>
+
+ * gcc.dg/pr25376.c: Allow .opd section.
+
+2020-11-17 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/31799
+ * gcc.target/i386/pr31799.c: New test.
+
+2020-11-17 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/cond_cnot_1.c: Remove XFAIL.
+ * gcc.target/aarch64/sve/cond_unary_1.c: Likewise.
+
+2020-11-17 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR tree-optimization/97693
+ * gcc.dg/vect/pr97693.c: New test.
+
+2020-11-17 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/vect/slp-46.c: XFAIL test for SLP on vect_load_lanes targets.
+
+2020-11-17 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/vect/aligned-section-anchors-nest-1.c: XFAIL alignment
+ test if vect_element_align_preferred.
+
+2020-11-17 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/vect/bb-slp-subgroups-3.c: XFAIL for variable-length vectors.
+
+2020-11-17 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/vect/pr65947-8.c: Expect the loop to be vectorized for SVE.
+
+2020-11-17 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/vect/pr97678.c: XFAIL test for SLP vectorization
+ for variable-length vectors.
+ * gcc.dg/vect/pr97835.c: Likewise.
+ * gcc.dg/vect/slp-49.c: Likewise.
+ * gcc.dg/vect/vect-outer-slp-1.c: Likewise.
+ * gcc.dg/vect/vect-outer-slp-2.c: Likewise.
+ * gcc.dg/vect/vect-outer-slp-3.c: Likewise.
+
+2020-11-17 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/vect/slp-reduc-4.c: XFAIL test for SLP vectorization
+ for variable-length SVE.
+ * gcc.dg/vect/slp-reduc-7.c: Likewise.
+
+2020-11-17 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/vect/bb-slp-43.c: Remove XFAIL for vect_variable_length.
+
+2020-11-17 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/vect/pr91750.c: Allow "[]," inside a vector(...) lane count.
+
+2020-11-17 Liu Hao <lh_mouse@126.com>
+
+ * gcc.dg/format/ms_c99-printf-3.c: Update tests.
+
+2020-11-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/90628
+ * gcc.dg/builtin-arith-overflow-4.c: New test.
+
+2020-11-17 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.dg/guality/pr59776.c (foo): Use noipa attribute instead of
+ noinline, noclone.
+
+2020-11-17 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/avx2-vec-set-1.c: New test.
+ * gcc.target/i386/avx2-vec-set-2.c: New test.
+ * gcc.target/i386/avx512bw-vec-set-1.c: New test.
+ * gcc.target/i386/avx512bw-vec-set-2.c: New test.
+ * gcc.target/i386/avx512f-vec-set-2.c: New test.
+ * gcc.target/i386/avx512vl-vec-set-2.c: New test.
+
+2020-11-17 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/95673
+ * gcc.dg/Wstring-compare-3.c: New test.
+
+2020-11-17 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/dfp/c2x-float-dfp-7.c, gcc.dg/dfp/c2x-float-dfp-8.c: New
+ tests.
+ * gcc.dg/c2x-float-no-dfp-3.c: Also check that DEC32_SNAN,
+ DEC64_SNAN and DEC128_SNAN are not defined.
+
+2020-11-17 Joseph Myers <joseph@codesourcery.com>
+
+ * lib/target-supports.exp (check_effective_target_inff): New.
+ * gcc.dg/c11-float-4.c, gcc.dg/c11-float-5.c,
+ gcc.dg/c11-float-dfp-2.c, gcc.dg/c2x-float-2.c,
+ gcc.dg/c2x-float-3.c, gcc.dg/c2x-float-4.c, gcc.dg/c2x-float-5.c,
+ gcc.dg/c2x-float-6.c, gcc.dg/c2x-float-7.c, gcc.dg/c2x-float-8.c,
+ gcc.dg/c2x-float-9.c, gcc.dg/c2x-float-no-dfp-3.c,
+ gcc.dg/c2x-float-no-dfp-4.c, gcc.dg/dfp/c2x-float-dfp-4.c,
+ gcc.dg/dfp/c2x-float-dfp-5.c, gcc.dg/dfp/c2x-float-dfp-6.c,
+ gcc.dg/torture/float128-nan-floath.c,
+ gcc.dg/torture/float128x-nan-floath.c,
+ gcc.dg/torture/float16-nan-floath.c,
+ gcc.dg/torture/float32-nan-floath.c,
+ gcc.dg/torture/float32x-nan-floath.c,
+ gcc.dg/torture/float64-nan-floath.c,
+ gcc.dg/torture/float64x-nan-floath.c,
+ gcc.dg/torture/floatn-nan-floath.h: New tests.
+
+2020-11-16 Roger Sayle <roger@nextmovesoftware.com>
+
+ PR rtl-optimization/92180
+ * gcc.target/i386/pr92180.c: New test.
+
+2020-11-16 Harald Anlauf <anlauf@gmx.de>
+
+ * gfortran.dg/pr48958.f90: New test.
+
+2020-11-16 Jan Hubicka <jh@suse.cz>
+
+ * g++.dg/warn/uninit-1.C: New test.
+
+2020-11-16 Ilya Leoshkevich <iii@linux.ibm.com>
+
+ * gcc.target/s390/s390.exp (check_effective_target_s390_z14_hw):
+ New predicate.
+ * gcc.target/s390/vector/long-double-caller-abi-run.c: Use the
+ new predicate.
+ * gcc.target/s390/vector/long-double-copysign.c: Likewise.
+ * gcc.target/s390/vector/long-double-from-double.c: Likewise.
+ * gcc.target/s390/vector/long-double-from-float.c: Likewise.
+ * gcc.target/s390/vector/long-double-from-i16.c: Likewise.
+ * gcc.target/s390/vector/long-double-from-i32.c: Likewise.
+ * gcc.target/s390/vector/long-double-from-i64.c: Likewise.
+ * gcc.target/s390/vector/long-double-from-i8.c: Likewise.
+ * gcc.target/s390/vector/long-double-from-u16.c: Likewise.
+ * gcc.target/s390/vector/long-double-from-u32.c: Likewise.
+ * gcc.target/s390/vector/long-double-from-u64.c: Likewise.
+ * gcc.target/s390/vector/long-double-from-u8.c: Likewise.
+ * gcc.target/s390/vector/long-double-to-double.c: Likewise.
+ * gcc.target/s390/vector/long-double-to-float.c: Likewise.
+ * gcc.target/s390/vector/long-double-to-i16.c: Likewise.
+ * gcc.target/s390/vector/long-double-to-i32.c: Likewise.
+ * gcc.target/s390/vector/long-double-to-i64.c: Likewise.
+ * gcc.target/s390/vector/long-double-to-i8.c: Likewise.
+ * gcc.target/s390/vector/long-double-to-u16.c: Likewise.
+ * gcc.target/s390/vector/long-double-to-u32.c: Likewise.
+ * gcc.target/s390/vector/long-double-to-u64.c: Likewise.
+ * gcc.target/s390/vector/long-double-to-u8.c: Likewise.
+ * gcc.target/s390/vector/long-double-wfaxb.c: Likewise.
+ * gcc.target/s390/vector/long-double-wfdxb.c: Likewise.
+ * gcc.target/s390/vector/long-double-wfsxb-1.c: Likewise.
+
+2020-11-16 H.J. Lu <hjl.tools@gmail.com>
+
+ PR testsuite/97803
+ * c-c++-common/asan/pointer-compare-1.c (global1): Add
+ __attribute__((used))
+ (global2): Likewise.
+ (small_global): Likewise.
+ (large_global): Likewise.
+
+2020-11-16 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+ * gcc.dg/profile-info-section.c: New test.
+
+2020-11-16 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97838
+ * gcc.dg/vect/pr97838.c: New testcase.
+
+2020-11-16 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/97736
+ * gcc.dg/tree-ssa/switch-1.c: Prefer bit tests.
+ * g++.dg/tree-ssa/pr97736.C: New test.
+
+2020-11-16 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97835
+ * gcc.dg/vect/pr97835.c: New testcase.
+
+2020-11-16 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97830
+ * gcc.dg/pr97830.c: New testcase.
+
+2020-11-15 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * gcc.target/msp430/rtx-cost-Os-f5series.c: Adjust test to use new
+ hwmult library function name.
+
+2020-11-15 David Edelsohn <dje.gcc@gmail.com>
+
+ * gcc.dg/ipa/modref-2.c: Add ilp32 expected result.
+
+2020-11-15 David Edelsohn <dje.gcc@gmail.com>
+
+ * lib/scanasm.exp (parse_section_of_symbols): Also look for AIX
+ XCOFF CSECT notation.
+ * g++.dg/opt/const4.C: Also look for AIX XCOFF "[RO]".
+ * gcc.dg/20021029-1.c: Likewise.
+ * gcc.dg/array-quals-1.c: Likewise and "[RW]".
+ * g++.dg/gomp/tls-5.C: Also look for AIX XCOFF "[TL]".
+ * gcc.dg/pr25376.c: Accept AIX decoration around named section
+ and function descriptor.
+
+2020-11-15 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * gcc.target/vax/bswapdi-1.c (dg-options): New setting.
+
+2020-11-15 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/other/abstract1.C: Adjust.
+ * g++.dg/other/abstract2.C: Adjust.
+ * g++.dg/other/abstract4.C: Adjust.
+ * g++.dg/other/abstract5.C: Adjust.
+ * g++.dg/other/abstract8.C: New test.
+ * g++.dg/template/sfinae-dr657.C: Adjust.
+ * g++.old-deja/g++.other/decl3.C: Adjust.
+
+2020-11-15 Jan Hubicka <jh@suse.cz>
+
+ * gcc.c-torture/execute/pr97836.c: New test.
+
+2020-11-14 Iain Sandoe <iain@sandoe.co.uk>
+
+ * objc.dg/pr23214.m: Use Object as the root object before
+ Darwin12 (and NSObject after).
+
+2020-11-14 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/torture/pta-ptrarith-1.c: Escape parameters.
+
+2020-11-14 Matthew Glazar <strager.nds@gmail.com>
+
+ * lib/scanasm.exp (dg-scan): Extract file globbing code ...
+ (dg_glob_remote): ... into this new procedure.
+ (scan-assembler-symbol-section): Define.
+ (scan-symbol-section): Define.
+ * g++.dg/gomp/tls-5.C: Add symbol section test.
+ * g++.dg/opt/const4.C: Likewise.
+ * gcc.dg/20021029-1.c: Likewise.
+ * gcc.dg/array-quals-1.c: Likewise.
+ * gcc.dg/darwin-sections.c: Likewise.
+ * gcc.dg/pr25376.c: Likewise.
+ * gcc.test-framework/test-framework.exp: Load scanasm and test .S files.
+ * gcc.test-framework/dg-scan-symbol-section-1-exp-F.S: New test.
+ * gcc.test-framework/dg-scan-symbol-section-2-exp-F.S: New test.
+ * gcc.test-framework/dg-scan-symbol-section-3-exp-F.S: New test.
+ * gcc.test-framework/dg-scan-symbol-section-exp-P.S: New test.
+
+2020-11-14 Monk Chiang <monk.chiang@sifive.com>
+
+ PR target/97682
+ * g++.target/riscv/pr97682.C: New test.
+ * gcc.target/riscv/interrupt-3.c: Check register for t0.
+ * gcc.target/riscv/interrupt-4.c: Likewise.
+
+2020-11-13 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/binary-constants-2.c, gcc.dg/binary-constants-3.c,
+ gcc.dg/system-binary-constants-1.c: Update expected diagnostics.
+ * gcc.dg/c11-binary-constants-1.c,
+ gcc.dg/c11-binary-constants-2.c, gcc.dg/c2x-binary-constants-1.c,
+ gcc.dg/c2x-binary-constants-2.c, gcc.dg/c2x-binary-constants-3.c:
+ New tests.
+
+2020-11-13 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/guality/redeclaration1.C (p): New variable.
+ (S::f): Increment what p points to before storing S::i into l. Adjust
+ gdb-test line numbers.
+ (main): Initialize p to address of an automatic variable.
+
+2020-11-13 Gergö Barany <gergo@codesourcery.com>
+ Thomas Schwinge <thomas@codesourcery.com>
+
+ * c-c++-common/goacc/kernels-decompose-1.c: New.
+ * c-c++-common/goacc/kernels-decompose-2.c: New.
+ * c-c++-common/goacc/kernels-decompose-ice-1.c: New.
+ * c-c++-common/goacc/kernels-decompose-ice-2.c: New.
+ * gfortran.dg/goacc/kernels-decompose-1.f95: New.
+ * gfortran.dg/goacc/kernels-decompose-2.f95: New.
+ * c-c++-common/goacc/if-clause-2.c: Adjust.
+ * gfortran.dg/goacc/kernels-tree.f95: Likewise.
+
+2020-11-13 Thomas Schwinge <thomas@codesourcery.com>
+
+ * c-c++-common/goacc/classify-parallel.c: Adjust.
+ * gfortran.dg/goacc/classify-parallel.f95: Likewise.
+ * c-c++-common/goacc/classify-serial.c: New.
+ * gfortran.dg/goacc/classify-serial.f95: Likewise.
+
+2020-11-13 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/cpp2a/feat-cxx2a.C: Check it.
+
+2020-11-13 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/cpp0x/inh-ctor28.C: Adjust expected diagnostic.
+ * g++.dg/cpp0x/inh-ctor33.C: Likewise.
+ * g++.dg/cpp0x/using-enum-1.C: Add comment.
+ * g++.dg/cpp0x/using-enum-2.C: Allowed in C++20.
+ * g++.dg/cpp0x/using-enum-3.C: Likewise.
+ * g++.dg/cpp1z/class-deduction69.C: Adjust diagnostic.
+ * g++.dg/inherit/using5.C: Likewise.
+ * g++.dg/cpp2a/using-enum-1.C: New test.
+ * g++.dg/cpp2a/using-enum-2.C: New test.
+ * g++.dg/cpp2a/using-enum-3.C: New test.
+ * g++.dg/cpp2a/using-enum-4.C: New test.
+ * g++.dg/cpp2a/using-enum-5.C: New test.
+ * g++.dg/cpp2a/using-enum-6.C: New test.
+ * g++.dg/debug/dwarf2/using-enum.C: New test.
+
+2020-11-13 Vladimir N. Makarov <vmakarov@redhat.com>
+
+ * c-c++-common/asmgoto-2.c: Permit output in asm goto.
+ * gcc.c-torture/compile/asmgoto-2.c: New.
+ * gcc.c-torture/compile/asmgoto-3.c: New.
+ * gcc.c-torture/compile/asmgoto-4.c: New.
+ * gcc.c-torture/compile/asmgoto-5.c: New.
+
+2020-11-13 Andrew MacLeod <amacleod@redhat.com>
+
+ * gcc.dg/tree-ssa/evrp20.c
+ * gcc.dg/tree-ssa/evrp21.c
+ * gcc.dg/tree-ssa/evrp22.c
+
+2020-11-13 Martin Liska <mliska@suse.cz>
+
+ PR testsuite/97788
+ * g++.dg/ubsan/pr61272.C: Move expected error location.
+
+2020-11-13 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * gcc.c-torture/execute/index-1.c: Skip for the default MSP430 430X ISA.
+
+2020-11-13 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * gcc.target/msp430/rtx-cost-O3-default.c: New test.
+ * gcc.target/msp430/rtx-cost-O3-f5series.c: New test.
+ * gcc.target/msp430/rtx-cost-Os-default.c: New test.
+ * gcc.target/msp430/rtx-cost-Os-f5series.c: New test.
+
+2020-11-13 Jan Hubicka <jh@suse.cz>
+
+ * c-c++-common/Wstringop-overflow-2.c: Disable ICF.
+ * g++.dg/warn/Warray-bounds-8.C: Disable ICF.
+
+2020-11-13 Andrew MacLeod <amacleod@redhat.com>
+
+ * gcc.dg/tree-ssa/pr78655.c: New.
+
+2020-11-13 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * gdc.dg/pr92216.d: Update scan-assember.
+
+2020-11-13 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97812
+ * gcc.dg/torture/pr97812.c: New testcase.
+
+2020-11-13 Sudakshina Das <sudi.das@arm.com>
+
+ * g++.dg/tree-ssa/pr90883.C: Remove xfail for aarch64.
+ * gcc.dg/tree-prof/stringop-2.c: Add xfail for aarch64.
+ * gcc.target/aarch64/memset-corner-cases.c: New test.
+ * gcc.target/aarch64/memset-q-reg.c: New test.
+
+2020-11-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR objc/90707
+ * obj-c++.dg/property/at-property-4.mm: Add basic nullability
+ tests.
+ * objc.dg/property/at-property-4.m: Likewise.
+ * obj-c++.dg/attributes/nullability-00.mm: New test.
+ * obj-c++.dg/property/nullability-00.mm: New test.
+ * objc.dg/attributes/nullability-00.m: New test.
+ * objc.dg/property/nullability-00.m: New test.
+
+2020-11-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR objc/77404
+ * obj-c++.dg/attributes/class-attribute-1.mm:
+ Add Wno-objc-root-class.
+ * obj-c++.dg/attributes/class-attribute-2.mm: Likewise.
+ * obj-c++.dg/attributes/class-attribute-3.mm: Likewise.
+ * obj-c++.dg/attributes/method-deprecated-1.mm: Likewise.
+ * obj-c++.dg/attributes/method-deprecated-2.mm: Likewise.
+ * obj-c++.dg/attributes/method-deprecated-3.mm: Likewise.
+ * obj-c++.dg/attributes/method-format-1.mm: Likewise.
+ * obj-c++.dg/attributes/method-nonnull-1.mm: Likewise.
+ * obj-c++.dg/attributes/method-noreturn-1.mm: Likewise.
+ * obj-c++.dg/attributes/method-sentinel-1.mm: Likewise.
+ * obj-c++.dg/attributes/nsobject-01.mm: Likewise.
+ * obj-c++.dg/attributes/parameter-attribute-1.mm: Likewise.
+ * obj-c++.dg/attributes/parameter-attribute-2.mm: Likewise.
+ * obj-c++.dg/attributes/proto-attribute-1.mm: Likewise.
+ * obj-c++.dg/attributes/proto-attribute-3.mm: Likewise.
+ * obj-c++.dg/attributes/proto-attribute-4.mm: Likewise.
+ * obj-c++.dg/attributes/unused-parameter-1.mm: Likewise.
+ * obj-c++.dg/bad-receiver-type.mm: Likewise.
+ * obj-c++.dg/bitfield-3.mm: Likewise.
+ * obj-c++.dg/bitfield-5.mm: Likewise.
+ * obj-c++.dg/class-extension-1.mm: Likewise.
+ * obj-c++.dg/class-extension-2.mm: Likewise.
+ * obj-c++.dg/class-extension-3.mm: Likewise.
+ * obj-c++.dg/class-extension-4.mm: Likewise.
+ * obj-c++.dg/class-protocol-1.mm: Likewise.
+ * obj-c++.dg/comp-types-1.mm: Likewise.
+ * obj-c++.dg/comp-types-10.mm: Likewise.
+ * obj-c++.dg/comp-types-2.mm: Likewise.
+ * obj-c++.dg/comp-types-3.mm: Likewise.
+ * obj-c++.dg/comp-types-5.mm: Likewise.
+ * obj-c++.dg/comp-types-6.mm: Likewise.
+ * obj-c++.dg/comp-types-7.mm: Likewise.
+ * obj-c++.dg/comp-types-8.mm: Likewise.
+ * obj-c++.dg/demangle-2.mm: Likewise.
+ * obj-c++.dg/demangle-3.mm: Likewise.
+ * obj-c++.dg/duplicate-class-1.mm: Likewise.
+ * obj-c++.dg/encode-1-next.mm: Likewise.
+ * obj-c++.dg/encode-1.mm: Likewise.
+ * obj-c++.dg/enhanced-proto-2.mm: Likewise.
+ * obj-c++.dg/exceptions-1.mm: Likewise.
+ * obj-c++.dg/exceptions-3.mm: Likewise.
+ * obj-c++.dg/exceptions-4.mm: Likewise.
+ * obj-c++.dg/exceptions-5.mm: Likewise.
+ * obj-c++.dg/extern-c-1.mm: Likewise.
+ * obj-c++.dg/fobjc-std-1.mm: Likewise.
+ * obj-c++.dg/gnu-api-2-class-meta.mm: Likewise.
+ * obj-c++.dg/gnu-api-2-class.mm: Likewise.
+ * obj-c++.dg/gnu-api-2-ivar.mm: Likewise.
+ * obj-c++.dg/gnu-api-2-method.mm: Likewise.
+ * obj-c++.dg/gnu-api-2-objc.mm: Likewise.
+ * obj-c++.dg/gnu-api-2-objc_msg_lookup.mm: Likewise.
+ * obj-c++.dg/gnu-api-2-object.mm: Likewise.
+ * obj-c++.dg/gnu-api-2-property.mm: Likewise.
+ * obj-c++.dg/gnu-api-2-protocol.mm: Likewise.
+ * obj-c++.dg/gnu-api-2-resolve-method.mm: Likewise.
+ * obj-c++.dg/gnu-api-2-sel.mm: Likewise.
+ * obj-c++.dg/invalid-method-2.mm: Likewise.
+ * obj-c++.dg/ivar-invalid-type-1.mm: Likewise.
+ * obj-c++.dg/ivar-problem-1.mm: Likewise.
+ * obj-c++.dg/lto/lto.exp: Likewise.
+ * obj-c++.dg/lto/trivial-1_0.mm: Likewise.
+ * obj-c++.dg/method-1.mm: Likewise.
+ * obj-c++.dg/method-12.mm: Likewise.
+ * obj-c++.dg/method-18.mm: Likewise.
+ * obj-c++.dg/method-19.mm: Likewise.
+ * obj-c++.dg/method-20.mm: Likewise.
+ * obj-c++.dg/method-3.mm: Likewise.
+ * obj-c++.dg/method-4.mm: Likewise.
+ * obj-c++.dg/method-5.mm: Likewise.
+ * obj-c++.dg/method-8.mm: Likewise.
+ * obj-c++.dg/method-9.mm: Likewise.
+ * obj-c++.dg/method-namespace-1.mm: Likewise.
+ * obj-c++.dg/plugin/diagnostic-test-expressions-1.mm:
+ Likewise.
+ * obj-c++.dg/pr23709.mm: Likewise.
+ * obj-c++.dg/pragma-2.mm: Likewise.
+ * obj-c++.dg/private-1.mm: Likewise.
+ * obj-c++.dg/private-2.mm: Likewise.
+ * obj-c++.dg/property/property.exp: Likewise.
+ * obj-c++.dg/proto-lossage-1.mm: Likewise.
+ * obj-c++.dg/proto-lossage-5.mm: Likewise.
+ * obj-c++.dg/proto-qual-1.mm: Likewise.
+ * obj-c++.dg/protocol-inheritance-1.mm: Likewise.
+ * obj-c++.dg/protocol-inheritance-2.mm: Likewise.
+ * obj-c++.dg/protocol-optional-1.mm: Likewise.
+ * obj-c++.dg/selector-1.mm: Likewise.
+ * obj-c++.dg/selector-2.mm: Likewise.
+ * obj-c++.dg/selector-3.mm: Likewise.
+ * obj-c++.dg/selector-4.mm: Likewise.
+ * obj-c++.dg/strings/strings.exp: Likewise.
+ * obj-c++.dg/stubify-1.mm: Likewise.
+ * obj-c++.dg/stubify-2.mm: Likewise.
+ * obj-c++.dg/super-dealloc-1.mm: Likewise.
+ * obj-c++.dg/super-dealloc-2.mm: Likewise.
+ * obj-c++.dg/sync-3.mm: Likewise.
+ * obj-c++.dg/syntax-error-2.mm: Likewise.
+ * obj-c++.dg/syntax-error-4.mm: Likewise.
+ * obj-c++.dg/syntax-error-7.mm: Likewise.
+ * obj-c++.dg/syntax-error-9.mm: Likewise.
+ * obj-c++.dg/template-4.mm: Likewise.
+ * obj-c++.dg/template-7.mm: Likewise.
+ * obj-c++.dg/template-8.mm: Likewise.
+ * obj-c++.dg/threedotthree-abi-1.mm: Likewise.
+ * obj-c++.dg/torture/dg-torture.exp: Likewise.
+ * obj-c++.dg/torture/strings/strings.exp: Likewise.
+ * obj-c++.dg/try-catch-12.mm: Likewise.
+ * obj-c++.dg/try-catch-13.mm: Likewise.
+
+2020-11-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR objc/77404
+ * objc.dg/anon-1.m: Add Wno-objc-root-class.
+ * objc.dg/attributes/class-attribute-1.m: Likewise.
+ * objc.dg/attributes/class-attribute-2.m: Likewise.
+ * objc.dg/attributes/class-attribute-3.m: Likewise.
+ * objc.dg/attributes/method-deprecated-1.m: Likewise.
+ * objc.dg/attributes/method-deprecated-2.m: Likewise.
+ * objc.dg/attributes/method-deprecated-3.m: Likewise.
+ * objc.dg/attributes/method-format-1.m: Likewise.
+ * objc.dg/attributes/method-nonnull-1.m: Likewise.
+ * objc.dg/attributes/method-noreturn-1.m: Likewise.
+ * objc.dg/attributes/method-sentinel-1.m: Likewise.
+ * objc.dg/attributes/nsobject-01.m: Likewise.
+ * objc.dg/attributes/objc-exception-1.m: Likewise.
+ * objc.dg/attributes/parameter-attribute-1.m: Likewise.
+ * objc.dg/attributes/parameter-attribute-2.m: Likewise.
+ * objc.dg/attributes/proto-attribute-1.m: Likewise.
+ * objc.dg/attributes/proto-attribute-2.m: Likewise.
+ * objc.dg/attributes/proto-attribute-3.m: Likewise.
+ * objc.dg/attributes/proto-attribute-4.m: Likewise.
+ * objc.dg/bitfield-2.m: Likewise.
+ * objc.dg/break-in-ifstmt.m: Likewise.
+ * objc.dg/class-1.m: Likewise.
+ * objc.dg/class-extension-1.m: Likewise.
+ * objc.dg/class-extension-2.m: Likewise.
+ * objc.dg/class-extension-3.m: Likewise.
+ * objc.dg/class-extension-4.m: Likewise.
+ * objc.dg/class-protocol-1.m: Likewise.
+ * objc.dg/comp-types-7.m: Likewise.
+ * objc.dg/demangle-1.m: Likewise.
+ * objc.dg/duplicate-class-1.m: Likewise.
+ * objc.dg/encode-6-next.m: Likewise.
+ * objc.dg/encode-6.m: Likewise.
+ * objc.dg/enhanced-proto-2.m: Likewise.
+ * objc.dg/exceptions-1.m: Likewise.
+ * objc.dg/exceptions-3.m: Likewise.
+ * objc.dg/exceptions-4.m: Likewise.
+ * objc.dg/exceptions-5.m: Likewise.
+ * objc.dg/fobjc-std-1.m: Likewise.
+ * objc.dg/foreach-2.m: Likewise.
+ * objc.dg/foreach-4.m: Likewise.
+ * objc.dg/foreach-5.m: Likewise.
+ * objc.dg/fsyntax-only.m: Likewise.
+ * objc.dg/gnu-api-2-class-meta.m: Likewise.
+ * objc.dg/gnu-api-2-class.m: Likewise.
+ * objc.dg/gnu-api-2-ivar.m: Likewise.
+ * objc.dg/gnu-api-2-method.m: Likewise.
+ * objc.dg/gnu-api-2-objc.m: Likewise.
+ * objc.dg/gnu-api-2-objc_msg_lookup.m: Likewise.
+ * objc.dg/gnu-api-2-object.m: Likewise.
+ * objc.dg/gnu-api-2-property.m: Likewise.
+ * objc.dg/gnu-api-2-protocol.m: Likewise.
+ * objc.dg/gnu-api-2-resolve-method.m: Likewise.
+ * objc.dg/gnu-api-2-sel.m: Likewise.
+ * objc.dg/incomplete-type-1.m: Likewise.
+ * objc.dg/instancetype-0.m: Likewise.
+ * objc.dg/invalid-method-2.m: Likewise.
+ * objc.dg/ivar-invalid-type-1.m: Likewise.
+ * objc.dg/ivar-problem-1.m: Likewise.
+ * objc.dg/ivar-scope-1.m: Likewise.
+ * objc.dg/ivar-scope-2.m: Likewise.
+ * objc.dg/ivar-scope-4.m: Likewise.
+ * objc.dg/ivar-visibility-1.m: Likewise.
+ * objc.dg/ivar-visibility-2.m: Likewise.
+ * objc.dg/ivar-visibility-3.m: Likewise.
+ * objc.dg/ivar-visibility-4.m: Likewise.
+ * objc.dg/local-decl-1.m: Likewise.
+ * objc.dg/lto/lto.exp: Likewise.
+ * objc.dg/lto/trivial-1_0.m: Likewise.
+ * objc.dg/method-1.m: Likewise.
+ * objc.dg/method-12.m: Likewise.
+ * objc.dg/method-13.m: Likewise.
+ * objc.dg/method-14.m: Likewise.
+ * objc.dg/missing-proto-3.m: Likewise.
+ * objc.dg/next-runtime-1.m: Likewise.
+ * objc.dg/objc-foreach-1.m: Likewise.
+ * objc.dg/objc-foreach-2.m: Likewise.
+ * objc.dg/objc-foreach-3.m: Likewise.
+ * objc.dg/objc-nofilename-1.m: Likewise.
+ * objc.dg/param-1.m: Likewise.
+ * objc.dg/pch/pch.exp: Likewise.
+ * objc.dg/plugin/diagnostic-test-expressions-1.m: Likewise.
+ * objc.dg/pr23709.m: Likewise.
+ * objc.dg/private-1.m: Likewise.
+ * objc.dg/private-2.m: Likewise.
+ * objc.dg/property/property.exp: Likewise.
+ * objc.dg/proto-hier-1.m: Likewise.
+ * objc.dg/proto-hier-2.m: Likewise.
+ * objc.dg/proto-lossage-1.m: Likewise.
+ * objc.dg/proto-lossage-5.m: Likewise.
+ * objc.dg/proto-qual-1.m: Likewise.
+ * objc.dg/protocol-inheritance-1.m: Likewise.
+ * objc.dg/protocol-inheritance-2.m: Likewise.
+ * objc.dg/protocol-optional-1.m: Likewise.
+ * objc.dg/selector-1.m: Likewise.
+ * objc.dg/selector-2.m: Likewise.
+ * objc.dg/selector-3.m: Likewise.
+ * objc.dg/selector-4.m: Likewise.
+ * objc.dg/shadow-1.m: Likewise.
+ * objc.dg/shadow-2.m: Likewise.
+ * objc.dg/special/load-category-1.m: Likewise.
+ * objc.dg/special/load-category-2.m: Likewise.
+ * objc.dg/special/load-category-3.m: Likewise.
+ * objc.dg/special/special.exp: Likewise.
+ * objc.dg/special/unclaimed-category-1.h: Likewise.
+ * objc.dg/special/unclaimed-category-1.m: Likewise.
+ * objc.dg/stabs-1.m: Likewise.
+ * objc.dg/strings/strings.exp: Likewise.
+ * objc.dg/stubify-1.m: Likewise.
+ * objc.dg/stubify-2.m: Likewise.
+ * objc.dg/super-class-2.m: Likewise.
+ * objc.dg/super-dealloc-1.m: Likewise.
+ * objc.dg/super-dealloc-2.m: Likewise.
+ * objc.dg/sync-3.m: Likewise.
+ * objc.dg/threedotthree-abi-1.m: Likewise.
+ * objc.dg/torture/dg-torture.exp: Likewise.
+ * objc.dg/torture/strings/strings.exp: Likewise.
+ * objc.dg/try-catch-11.m: Likewise.
+ * objc.dg/try-catch-12.m: Likewise.
+ * objc.dg/type-size-2.m: Likewise.
+ * objc.dg/type-size-3.m: Likewise.
+ * objc.dg/type-size-4.m: Likewise.
+ * objc.dg/type-size-5.m: Likewise.
+ * objc.dg/undeclared-selector.m: Likewise.
+ * objc.dg/volatile-1.m: Likewise.
+
+2020-11-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR objc/77404
+ * objc.dg/attributes/root-class-01.m: New test.
+ * objc.dg/root-class-00.m: New test.
+ * obj-c++.dg/attributes/root-class-01.mm: New test.
+ * obj-c++.dg/root-class-00.mm: New test.
+
+2020-11-13 Patrick Palka <ppalka@redhat.com>
+
+ * g++.dg/cpp2a/concepts-decltype3.C: New test.
+
+2020-11-12 David Malcolm <dmalcolm@redhat.com>
+
+ PR jit/87291
+ * jit.dg/jit.exp: Load target-supports-dg.exp.
+ Set dg-do-what-default.
+ (jit-dg-test): Set dg-do-what and call dg-get-options, skipping
+ the test if it's not supported on the given target.
+ * jit.dg/test-asm.c: New test.
+ * jit.dg/test-asm.cc: New test.
+
+2020-11-12 David Malcolm <dmalcolm@redhat.com>
+
+ * jit.dg/test-debug-strings.c (create_code): Add tests of
+ string literal escaping.
+
+2020-11-12 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/c2x-has-c-attribute-1.c, gcc.dg/c2x-has-c-attribute-2.c,
+ gcc.dg/c2x-has-c-attribute-3.c, gcc.dg/c2x-has-c-attribute-4.c:
+ New tests.
+
+2020-11-12 Tobias Burnus <tobias@codesourcery.com>
+
+ PR fortran/97782
+ * gfortran.dg/goacc/classify-kernels-unparallelized.f95: Move dg-message
+ one line up.
+ * gfortran.dg/goacc/classify-kernels.f95: Likewise.
+
+2020-11-12 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ * gfortran.dg/entry_23.f: New test.
+
+2020-11-12 Alex Coplan <alex.coplan@arm.com>
+
+ PR target/97730
+ * gcc.target/aarch64/sve2/bcax_1.c (OP): Add missing bitwise not
+ to match correct bcax semantics.
+ * gcc.dg/vect/pr97730.c: New test.
+
+2020-11-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97806
+ * gcc.dg/pr97806.c: New testcase.
+
+2020-11-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/97790
+ * g++.dg/cpp2a/constexpr-dtor9.C: New test.
+
+2020-11-12 Jason Merrill <jason@redhat.com>
+
+ PR debug/97060
+ * gcc.dg/debug/dwarf2/pr97060.c: New test.
+
+2020-11-12 Kewen Lin <linkw@linux.ibm.com>
+
+ * gcc.dg/tree-ssa/pr96789.c: Adjusted by disabling loop
+ vectorization.
+
+2020-11-12 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/analyzer/setjmp-5.c: Update expected path output to show
+ an event where the pertinent stack frame is popped. Update
+ expected message from final event to reference this event.
+
+2020-11-12 David Malcolm <dmalcolm@redhat.com>
+
+ PR tree-optimization/97424
+ * gcc.dg/analyzer/invalid-shift-1.c: New test.
+
+2020-11-11 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/88115
+ * g++.dg/abi/macro0.C: Adjust.
+ * g++.dg/cpp0x/alignof7.C: New test.
+ * g++.dg/cpp0x/alignof8.C: New test.
+
+2020-11-11 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/88115
+ * g++.dg/cpp0x/alignof6.C: New test.
+
+2020-11-11 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97518
+ * g++.dg/diagnostic/static_assert3.C: New test.
+
+2020-11-11 Jakub Jelinek <jakub@redhat.com>
+
+ * gfortran.dg/gomp/workshare-reduction-3.f90: Use (?:_ull)? instead
+ of (?:_ull) in the scan-tree-dump-times directives.
+ * gfortran.dg/gomp/workshare-reduction-26.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-27.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-28.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-36.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-37.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-38.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-39.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-40.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-41.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-42.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-43.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-44.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-45.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-46.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-47.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-56.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-57.f90: Likewise.
+
+2020-11-11 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/bias2.adb: New test.
+
+2020-11-11 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/opt89.adb: New test.
+
+2020-11-11 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/shift1.adb: New test.
+
+2020-11-11 Richard Biener <rguenther@suse.de>
+
+ PR testsuite/97797
+ * gcc.dg/torture/ssa-fre-5.c: Use __SIZETYPE__ where
+ appropriate.
+ * gcc.dg/torture/ssa-fre-6.c: Likewise.
+
+2020-11-11 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97623
+ * gcc.dg/tree-ssa/ssa-hoist-3.c: Adjust.
+ * gcc.dg/tree-ssa/ssa-hoist-7.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-pre-30.c: Likewise.
+
+2020-11-11 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/cmp_1.c: New test.
+ * gcc.target/aarch64/sve/cmp_2.c: Likewise.
+ * gcc.target/aarch64/sve/cond_arith_1.c: Add --param
+ aarch64-sve-compare-costs=0
+ * gcc.target/aarch64/sve/cond_arith_1_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_arith_3.c: Likewise.
+ * gcc.target/aarch64/sve/cond_arith_3_run.c: Likewise.
+ * gcc.target/aarch64/sve/mask_gather_load_7.c: Likewise.
+ * gcc.target/aarch64/sve/mask_load_slp_1.c: Likewise.
+ * gcc.target/aarch64/sve/vcond_11.c: Likewise.
+ * gcc.target/aarch64/sve/vcond_11_run.c: Likewise.
+
+2020-11-11 Hongtao Liu <hongtao.liu@intel.com>
+ Hongyu Wang <hongyu.wang@intel.com>
+
+ * gcc.target/i386/avx512vl-vnni-1.c: Rename..
+ * gcc.target/i386/avx512vl-vnni-1a.c: To This.
+ * gcc.target/i386/avx512vl-vnni-1b.c: New test.
+ * gcc.target/i386/avx512vl-vnni-2.c: Ditto.
+ * gcc.target/i386/avx512vl-vnni-3.c: Ditto.
+ * gcc.target/i386/avx-vnni-1.c: Ditto.
+ * gcc.target/i386/avx-vnni-2.c: Ditto.
+ * gcc.target/i386/avx-vnni-3.c: Ditto.
+ * gcc.target/i386/avx-vnni-4.c: Ditto.
+ * gcc.target/i386/avx-vnni-5.c: Ditto.
+ * gcc.target/i386/avx-vnni-6.c: Ditto.
+ * gcc.target/i386/avx-vpdpbusd-2.c: Ditto.
+ * gcc.target/i386/avx-vpdpbusds-2.c: Ditto.
+ * gcc.target/i386/avx-vpdpwssd-2.c: Ditto.
+ * gcc.target/i386/avx-vpdpwssds-2.c: Ditto.
+ * gcc.target/i386/vnni_inline_error.c: Ditto.
+ * gcc.target/i386/avx512vnnivl-builtin.c: Ditto.
+ * gcc.target/i386/avxvnni-builtin.c: Ditto.
+ * gcc.target/i386/funcspec-56.inc: Add new target attribute.
+ * gcc.target/i386/sse-12.c: Add -mavxvnni.
+ * gcc.target/i386/sse-13.c: Ditto.
+ * gcc.target/i386/sse-14.c: Ditto.
+ * gcc.target/i386/sse-22.c: Ditto.
+ * gcc.target/i386/sse-23.c: Ditto.
+ * g++.dg/other/i386-2.C: Ditto.
+ * g++.dg/other/i386-3.C: Ditto.
+ * lib/target-supports.exp (check_effective_target_avxvnni):
+ New proc.
+
+2020-11-11 Tobias Burnus <tobias@codesourcery.com>
+
+ * gfortran.dg/gomp/workshare-reduction-26.f90: Add (?:_ull) to
+ scan-tree-dump-times regex for -m32.
+ * gfortran.dg/gomp/workshare-reduction-27.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-28.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-3.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-36.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-37.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-38.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-39.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-40.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-41.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-42.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-43.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-44.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-45.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-46.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-47.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-56.f90: Likewise.
+ * gfortran.dg/gomp/workshare-reduction-57.f90: Likewise.
+
+2020-11-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/97768
+ * gfortran.dg/pr97768_1.f90: New test.
+ * gfortran.dg/pr97768_2.f90: New test.
+
+2020-11-11 Nagaraju Mekala <nmekala@xilinx.com>
+
+ * gcc.target/microblaze/others/strings1.c: Update
+ to include $LC label.
+
+2020-11-11 David Edelsohn <dje.gcc@gmail.com>
+
+ * c-c++-common/zero-scratch-regs-10.c: Skip on powerpc*-*-*.
+ * c-c++-common/zero-scratch-regs-11.c: Skip on powerpc*-*-*.
+ * c-c++-common/zero-scratch-regs-5.c: Skip on powerpc*-*-aix*.
+ * c-c++-common/zero-scratch-regs-8.c: Skip on powerpc*-*-*.
+ * c-c++-common/zero-scratch-regs-9.c: Skip on powerpc*-*-*.
+
+2020-11-10 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97518
+ * g++.dg/diagnostic/pr87386.C: Adjust expected output.
+ * g++.dg/diagnostic/static_assert1.C: New test.
+ * g++.dg/diagnostic/static_assert2.C: New test.
+
+2020-11-10 Marek Polacek <polacek@redhat.com>
+
+ PR c++/52830
+ PR c++/88982
+ PR c++/90799
+ PR c++/87765
+ PR c++/89565
+ * g++.dg/cpp0x/constexpr-52830.C: New test.
+ * g++.dg/cpp0x/vt-88982.C: New test.
+ * g++.dg/cpp1z/class-deduction76.C: New test.
+ * g++.dg/cpp1z/constexpr-lambda26.C: New test.
+ * g++.dg/cpp2a/nontype-class39.C: New test.
+
+2020-11-10 Tobias Burnus <tobias@codesourcery.com>
+
+ * gfortran.dg/gomp/schedule-modifiers-2.f90: Remove some dg-error.
+ * gfortran.dg/gomp/reduction4.f90: New test.
+ * gfortran.dg/gomp/reduction5.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-1.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-2.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-3.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-4.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-5.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-6.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-7.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-8.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-9.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-10.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-11.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-12.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-13.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-14.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-15.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-16.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-17.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-18.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-19.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-20.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-21.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-22.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-23.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-24.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-25.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-26.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-27.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-28.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-29.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-30.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-31.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-32.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-33.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-34.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-35.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-36.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-37.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-38.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-39.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-40.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-41.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-42.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-43.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-44.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-45.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-46.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-47.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-48.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-49.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-50.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-51.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-52.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-53.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-54.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-55.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-56.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-57.f90: New test.
+ * gfortran.dg/gomp/workshare-reduction-58.f90: New test.
+
+2020-11-10 Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * c-c++-common/ubsan/sanitize-recover-7.c: Update testcase.
+
+2020-11-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/97748
+ * c-c++-common/Wunused-value-1.c: New test.
+
+2020-11-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97769
+ * gcc.dg/vect/pr97769.c: New testcase.
+
+2020-11-10 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * c-c++-common/gomp/clauses-2.c: Remove dg-error cases now valid.
+ * gfortran.dg/gomp/map-2.f90: Likewise.
+ * c-c++-common/gomp/map-5.c: New testcase.
+
+2020-11-10 Ilya Leoshkevich <iii@linux.ibm.com>
+
+ * gcc.target/s390/vector/long-double-callee-abi-scan.c: New test.
+ * gcc.target/s390/vector/long-double-caller-abi-run.c: New test.
+ * gcc.target/s390/vector/long-double-caller-abi-scan.c: New test.
+ * gcc.target/s390/vector/long-double-copysign.c: New test.
+ * gcc.target/s390/vector/long-double-fprx2-constant.c: New test.
+ * gcc.target/s390/vector/long-double-from-double.c: New test.
+ * gcc.target/s390/vector/long-double-from-float.c: New test.
+ * gcc.target/s390/vector/long-double-from-i16.c: New test.
+ * gcc.target/s390/vector/long-double-from-i32.c: New test.
+ * gcc.target/s390/vector/long-double-from-i64.c: New test.
+ * gcc.target/s390/vector/long-double-from-i8.c: New test.
+ * gcc.target/s390/vector/long-double-from-u16.c: New test.
+ * gcc.target/s390/vector/long-double-from-u32.c: New test.
+ * gcc.target/s390/vector/long-double-from-u64.c: New test.
+ * gcc.target/s390/vector/long-double-from-u8.c: New test.
+ * gcc.target/s390/vector/long-double-to-double.c: New test.
+ * gcc.target/s390/vector/long-double-to-float.c: New test.
+ * gcc.target/s390/vector/long-double-to-i16.c: New test.
+ * gcc.target/s390/vector/long-double-to-i32.c: New test.
+ * gcc.target/s390/vector/long-double-to-i64.c: New test.
+ * gcc.target/s390/vector/long-double-to-i8.c: New test.
+ * gcc.target/s390/vector/long-double-to-u16.c: New test.
+ * gcc.target/s390/vector/long-double-to-u32.c: New test.
+ * gcc.target/s390/vector/long-double-to-u64.c: New test.
+ * gcc.target/s390/vector/long-double-to-u8.c: New test.
+ * gcc.target/s390/vector/long-double-vec-duplicate.c: New test.
+ * gcc.target/s390/vector/long-double-wf.h: New test.
+ * gcc.target/s390/vector/long-double-wfaxb.c: New test.
+ * gcc.target/s390/vector/long-double-wfcxb-0001.c: New test.
+ * gcc.target/s390/vector/long-double-wfcxb-0111.c: New test.
+ * gcc.target/s390/vector/long-double-wfcxb-1011.c: New test.
+ * gcc.target/s390/vector/long-double-wfcxb-1101.c: New test.
+ * gcc.target/s390/vector/long-double-wfdxb.c: New test.
+ * gcc.target/s390/vector/long-double-wfixb.c: New test.
+ * gcc.target/s390/vector/long-double-wfkxb-0111.c: New test.
+ * gcc.target/s390/vector/long-double-wfkxb-1011.c: New test.
+ * gcc.target/s390/vector/long-double-wfkxb-1101.c: New test.
+ * gcc.target/s390/vector/long-double-wflcxb.c: New test.
+ * gcc.target/s390/vector/long-double-wflpxb.c: New test.
+ * gcc.target/s390/vector/long-double-wfmaxb-2.c: New test.
+ * gcc.target/s390/vector/long-double-wfmaxb-3.c: New test.
+ * gcc.target/s390/vector/long-double-wfmaxb-disabled.c: New test.
+ * gcc.target/s390/vector/long-double-wfmaxb.c: New test.
+ * gcc.target/s390/vector/long-double-wfmsxb-disabled.c: New test.
+ * gcc.target/s390/vector/long-double-wfmsxb.c: New test.
+ * gcc.target/s390/vector/long-double-wfmxb.c: New test.
+ * gcc.target/s390/vector/long-double-wfnmaxb-disabled.c: New test.
+ * gcc.target/s390/vector/long-double-wfnmaxb.c: New test.
+ * gcc.target/s390/vector/long-double-wfnmsxb-disabled.c: New test.
+ * gcc.target/s390/vector/long-double-wfnmsxb.c: New test.
+ * gcc.target/s390/vector/long-double-wfsqxb.c: New test.
+ * gcc.target/s390/vector/long-double-wfsxb-1.c: New test.
+ * gcc.target/s390/vector/long-double-wfsxb.c: New test.
+ * gcc.target/s390/vector/long-double-wftcixb-1.c: New test.
+ * gcc.target/s390/vector/long-double-wftcixb.c: New test.
+
+2020-11-10 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/opt88.adb: New test.
+
+2020-11-10 David Candler <david.candler@arm.com>
+
+ * gcc.target/aarch64/advsimd-intrinsics/vqrshrn_high_n.c: Added skip
+ directive.
+ * gcc.target/aarch64/advsimd-intrinsics/vqrshrun_high_n.c: Likewise.
+ * gcc.target/aarch64/advsimd-intrinsics/vqshrn_high_n.c: Likewise.
+ * gcc.target/aarch64/advsimd-intrinsics/vqshrun_high_n.c: Likewise.
+
+2020-11-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/97764
+ * gcc.c-torture/execute/pr97764.c: New test.
+
+2020-11-10 Tobias Burnus <tobias@codesourcery.com>
+
+ PR fortran/95847
+ * gfortran.dg/coverage.f90: New test.
+
+2020-11-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/97760
+ * gcc.dg/vect/pr97760.c: New testcase.
+
+2020-11-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * g++.dg/opt/pr97767.C: New test.
+
+2020-11-10 hongyuw1 <hongyuw1@intel.com>
+
+ * gcc.target/i386/keylocker-aesdec128kl.c: Adjust regex patterns.
+ * gcc.target/i386/keylocker-aesdec256kl.c: Likewise.
+ * gcc.target/i386/keylocker-aesdecwide128kl.c: Likewise.
+ * gcc.target/i386/keylocker-aesdecwide256kl.c: Likewise.
+ * gcc.target/i386/keylocker-aesenc128kl.c: Likewise.
+ * gcc.target/i386/keylocker-aesencwide128kl.c: Likewise.
+ * gcc.target/i386/keylocker-aesencwide256kl.c: Likewise.
+ * gcc.target/i386/keylocker-encodekey128.c: Likewise.
+ * gcc.target/i386/keylocker-encodekey256.c: Likewise.
+ * gcc.target/i386/keylocker-aesenc256kl.c: New test.
+
+2020-11-10 Andrew MacLeod <amacleod@redhat.com>
+
+ * gcc.dg/pr97567-2.c: New.
+
2020-11-09 Marek Polacek <polacek@redhat.com>
DR 1914
diff --git a/gcc/testsuite/ada/acats/support/acats25.lst b/gcc/testsuite/ada/acats/support/acats26.lst
index 0133ed3..d99145e 100644
--- a/gcc/testsuite/ada/acats/support/acats25.lst
+++ b/gcc/testsuite/ada/acats/support/acats26.lst
@@ -462,6 +462,7 @@ b460001.a
b460002.a
b460004.a
b460005.a
+b460006.a
b46002a.ada
b46003a.ada
b46004a.ada
@@ -846,6 +847,7 @@ b85015a.ada
b8510010.a
b8510011.a
b8510012.am
+b854001.a
b86001a0.ada
b86001a1.ada
b87b23b.ada
@@ -1517,6 +1519,7 @@ bd8004b.tst
bd8004c.tst
bdb0a01.a
bdd2001.a
+bdd2002.a
bde0001.a
bde0002.a
bde0003.a
@@ -1525,6 +1528,8 @@ bde0005.a
bde0006.a
bde0007.a
bde0008.a
+bde0009.a
+bde0010.a
be2101e.ada
be2101j.ada
be2114a.ada
@@ -1876,6 +1881,10 @@ c37404a.ada
c37404b.ada
c37405a.ada
c37411a.ada
+c380001.a
+c380002.a
+c380003.a
+c380004.a
c38002a.ada
c38002b.ada
c38005a.ada
@@ -2218,6 +2227,7 @@ c45532o.dep
c45532p.dep
c45534b.ada
c45536a.dep
+c456001.a
c45611a.ada
c45611b.dep
c45611c.dep
@@ -2227,9 +2237,6 @@ c45613c.dep
c45614a.ada
c45614b.dep
c45614c.dep
-c45622a.ada
-c45624a.ada
-c45624b.ada
c45631a.ada
c45631b.dep
c45631c.dep
@@ -2563,6 +2570,7 @@ c761006.a
c761007.a
c761010.a
c761011.a
+c761012.a
c83007a.ada
c83012d.ada
c83022a.ada
@@ -2639,6 +2647,7 @@ c85018b.ada
c85019a.ada
c854001.a
c854002.a
+c854003.a
c86003a.ada
c86004a.ada
c86004b0.ada
@@ -3275,6 +3284,7 @@ cc51003.a
cc51004.a
cc51006.a
cc51007.a
+cc51008.a
cc51a01.a
cc51b03.a
cc51d01.a
@@ -3293,6 +3303,7 @@ cc70b02.a
cc70c01.a
cc70c02.a
cd10001.a
+cd10002.a
cd1009a.ada
cd1009b.ada
cd1009d.ada
@@ -3466,6 +3477,9 @@ cdb0a01.a
cdb0a02.a
cdd1001.a
cdd2001.a
+cdd2a01.a
+cdd2a02.a
+cdd2a03.a
cde0001.a
ce2102a.ada
ce2102b.ada
@@ -4049,6 +4063,7 @@ fc70c00.a
fcndecl.ada
fd72a00.a
fdb0a00.a
+fdd2a00.a
fxa5a00.a
fxaca00.a
fxacb00.a
@@ -4200,6 +4215,15 @@ la5008f0.ada
la5008f1.ada
la5008g0.ada
la5008g1.ada
+lc300010.a
+lc300011.a
+lc300012.am
+lc300020.a
+lc300021.a
+lc300022.am
+lc300030.a
+lc300031.a
+lc300032.am
lencheck.ada
lxd70010.a
lxd70011.a
diff --git a/gcc/testsuite/ada/acats/support/fcndecl.ada b/gcc/testsuite/ada/acats/support/fcndecl.ada
index 53347a4..eddc137 100644
--- a/gcc/testsuite/ada/acats/support/fcndecl.ada
+++ b/gcc/testsuite/ada/acats/support/fcndecl.ada
@@ -3,22 +3,22 @@
-- Grant of Unlimited Rights
--
-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
--- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
+-- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
-- unlimited rights in the software and documentation contained herein.
--- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
--- this public release, the Government intends to confer upon all
--- recipients unlimited rights equal to those held by the Government.
--- These rights include rights to use, duplicate, release or disclose the
--- released technical data and computer software in whole or in part, in
--- any manner and for any purpose whatsoever, and to have or permit others
+-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
+-- this public release, the Government intends to confer upon all
+-- recipients unlimited rights equal to those held by the Government.
+-- These rights include rights to use, duplicate, release or disclose the
+-- released technical data and computer software in whole or in part, in
+-- any manner and for any purpose whatsoever, and to have or permit others
-- to do so.
--
-- DISCLAIMER
--
-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
--- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
+-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
--- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
+-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
-- PARTICULAR PURPOSE OF SAID MATERIAL.
--*
diff --git a/gcc/testsuite/ada/acats/support/impdef.a b/gcc/testsuite/ada/acats/support/impdef.a
index 9c23d0b..ca02a7a 100644
--- a/gcc/testsuite/ada/acats/support/impdef.a
+++ b/gcc/testsuite/ada/acats/support/impdef.a
@@ -105,6 +105,9 @@ package ImpDef is
Minimum_Task_Switch : constant Duration := 0.001;
-- ^^^ --- MODIFY HERE AS NEEDED
+ -- The above constant has been chosen for use with delay statements in the
+ -- GCC testsuite so that they do not take too long, but may be too small.
+
Long_Minimum_Task_Switch : constant Duration := 0.1;
--=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====--
@@ -119,6 +122,9 @@ package ImpDef is
Switch_To_New_Task : constant Duration := 0.001;
-- ^^^ -- MODIFY HERE AS NEEDED
+ -- The above constant has been chosen for use with delay statements in the
+ -- GCC testsuite so that they do not take too long, but may be too small.
+
Long_Switch_To_New_Task : constant Duration := 0.1;
--=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====--
@@ -208,7 +214,7 @@ package ImpDef is
-- CD30005_1_Foreign_Address : constant System.Address:=
-- System.Storage_Elements.To_Address ( 16#0000_0000# )
- -- --MODIFY HERE AS REQUIRED --- ^^^^^^^^^^^^^
+ -- MODIFY HERE AS REQUIRED --- ^^^^^^^^^^^^^
--=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====--
@@ -337,11 +343,14 @@ package ImpDef is
-- package Address_Value_IO is
-- new Ada.Text_IO.Integer_IO(System.Storage_Elements.Integer_Address);
- package Address_Value_IO is
- new Ada.Text_IO.Modular_IO(System.Storage_Elements.Integer_Address);
+ package Address_Value_IO is
+ new Ada.Text_IO.Modular_IO(System.Storage_Elements.Integer_Address);
--=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====--
+ -- The following constants have been defined for use with various delay
+ -- statements in the GCC testsuite so that they do not take too long.
+
One_Second : constant Duration := 0.001;
One_Long_Second : constant Duration := 0.1;
diff --git a/gcc/testsuite/ada/acats/support/impdefg.a b/gcc/testsuite/ada/acats/support/impdefg.a
index 459ba9c..6afc7cd 100644
--- a/gcc/testsuite/ada/acats/support/impdefg.a
+++ b/gcc/testsuite/ada/acats/support/impdefg.a
@@ -60,24 +60,31 @@ end ImpDef.Annex_G;
package body ImpDef.Annex_G is
+ -- NOTE: These are example bodies. It is expected that implementors
+ -- will write their own versions of these routines.
--=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====--
- -- This function must return a negative zero value for implementations
- -- for which Float'Signed_Zeros is True.
- -- We generate the smallest normalized negative number, and divide by a
- -- few powers of two to obtain a number whose absolute value equals zero
- -- but whose sign is negative.
+ -- This function must return a negative zero value for implementations
+ -- for which Float'Signed_Zeros is True.
+ --
+ -- The default body simply returns a negated literal 0.0. If the
+ -- default body does not return the value corresponding to a negatively
+ -- signed zero for the implementation under test, it must be replaced
+ -- by one which does. See RM A.5.3(13).
function Negative_Zero return Float is
- negz : float := -1.0 *
- float (float'Machine_Radix)
- ** ( Float'Machine_Emin - Float'Machine_Mantissa);
begin
- return negz / 8.0;
+ return -0.0; -- Note: If this value is not negative zero for the
+ -- implementation, use of this "default" value
+ -- could result in false failures in
+ -- implementations where Float'Signed_Zeros
+ -- is True.
+
+ -- ^^^^^^^^^^^^^^^^^^^^ MODIFY THIS BODY AS NEEDED ^^^^^^^^^^^^^^^^^^^^
+
end Negative_Zero;
--=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====-=====--
end ImpDef.Annex_G;
-
diff --git a/gcc/testsuite/ada/acats/support/macro.dfs b/gcc/testsuite/ada/acats/support/macro.dfs
index e3c5559..c0acaf1 100644
--- a/gcc/testsuite/ada/acats/support/macro.dfs
+++ b/gcc/testsuite/ada/acats/support/macro.dfs
@@ -244,7 +244,7 @@ MIN_INT ACATS4GNATMININT
-- IDENTIFIER SUCH AS NO_SUCH_TYPE_AVAILABLE.)
-- USED IN: C45231D CD7101G
NAME LONG_LONG_INTEGER
-
+
-- $OPTIONAL_DISC
-- A DISCRIMINANT USED AS THE DISCRIMINANT PART OF $RECORD_NAME.
-- IF MACHINE CODE INSERTIONS ARE NOT SUPPORTED THEN SUBSTITUTE
@@ -277,7 +277,7 @@ TASK_SIZE ACATS4GNATBIT
-- THE NUMBER OF STORAGE UNITS REQUIRED FOR A TASK ACTIVATION.
-- USED IN: BD2C01D BD2C02A BD2C03A C87B62D CD1009K CD1009T
-- CD1009U CD1C03E CD1C06A CD2C11A CC1225A CD2C11D
-TASK_STORAGE_SIZE 1024
+TASK_STORAGE_SIZE 32768
-- $VARIABLE_ADDRESS
-- AN EXPRESSION YIELDING A LEGAL ADDRESS FOR A VARIABLE FOR THIS
@@ -298,4 +298,3 @@ VARIABLE_ADDRESS1 VAR_ADDR1
-- THE MACROS $VARIABLE_ADDRESS AND $VARIABLE_ADDRESS1.
-- USED IN: SPPRT13SP
VARIABLE_ADDRESS2 VAR_ADDR2
-
diff --git a/gcc/testsuite/ada/acats/support/repbody.ada b/gcc/testsuite/ada/acats/support/repbody.ada
index dd5c53b..d7b9fe0 100644
--- a/gcc/testsuite/ada/acats/support/repbody.ada
+++ b/gcc/testsuite/ada/acats/support/repbody.ada
@@ -57,7 +57,8 @@
-- RLB 3/16/00 UPDATED ACATS VERSION STRING TO "2.3".
-- CHANGED VARIOUS STRINGS TO READ "ACATS".
-- RLB 3/22/01 UPDATED ACATS VERSION STRING TO "2.4".
--- RLB 3/29/01 UPDATED ACATS VERSION STRING TO "2.5".
+-- RLB 3/29/02 UPDATED ACATS VERSION STRING TO "2.5".
+-- RLB 3/06/07 UPDATED ACATS VERSION STRING TO "2.6".
WITH TEXT_IO, CALENDAR;
USE TEXT_IO, CALENDAR;
@@ -80,7 +81,7 @@ PACKAGE BODY REPORT IS
- ACATS_VERSION : CONSTANT STRING := "2.5";
+ ACATS_VERSION : CONSTANT STRING := "2.6";
-- VERSION OF ACATS BEING RUN (X.XX).
PROCEDURE PUT_MSG (MSG : STRING) IS
diff --git a/gcc/testsuite/ada/acats/support/tctouch.ada b/gcc/testsuite/ada/acats/support/tctouch.ada
index 8fd4f00..83f1254 100644
--- a/gcc/testsuite/ada/acats/support/tctouch.ada
+++ b/gcc/testsuite/ada/acats/support/tctouch.ada
@@ -93,11 +93,12 @@
-- 16 MAR 00 RLB Changed foundation id to reflect test suite version.
-- 22 MAR 01 RLB Changed foundation id to reflect test suite version.
-- 29 MAR 02 RLB Changed foundation id to reflect test suite version.
+-- 06 MAR 07 RLB Changed foundation id to reflect test suite version.
--
--!
package TCTouch is
- Foundation_ID : constant String := "TCTouch ACATS 2.5";
+ Foundation_ID : constant String := "TCTouch ACATS 2.6";
Max_Touch_Count : constant := 80;
procedure Assert ( SB_True : Boolean; Message : String );
diff --git a/gcc/testsuite/ada/acats/tests/c3/c352001.a b/gcc/testsuite/ada/acats/tests/c3/c352001.a
new file mode 100644
index 0000000..04b094f
--- /dev/null
+++ b/gcc/testsuite/ada/acats/tests/c3/c352001.a
@@ -0,0 +1,270 @@
+--
+-- C352001.A
+--
+-- Grant of Unlimited Rights
+--
+-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
+-- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
+-- unlimited rights in the software and documentation contained herein.
+-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
+-- this public release, the Government intends to confer upon all
+-- recipients unlimited rights equal to those held by the Government.
+-- These rights include rights to use, duplicate, release or disclose the
+-- released technical data and computer software in whole or in part, in
+-- any manner and for any purpose whatsoever, and to have or permit others
+-- to do so.
+--
+-- DISCLAIMER
+--
+-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
+-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
+-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
+-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
+-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
+-- PARTICULAR PURPOSE OF SAID MATERIAL.
+--*
+--
+-- OBJECTIVE:
+-- Check that the predefined Character type comprises 256 positions.
+-- Check that the names of the non-graphic characters are usable with
+-- the attributes (Wide_)Image and (Wide_)Value, and that these
+-- attributes produce the correct result.
+--
+-- TEST DESCRIPTION:
+-- Build two tables of nongraphic characters from positions of Row 00
+-- (0000-001F and 007F-009F) of the ISO 10646 Basic Multilingual Plane.
+-- Fill the first table with compiler created strings. Fill the second
+-- table with strings defined by the language. Compare the two tables.
+-- Check 256 positions of the predefined character type. Use attributes
+-- (Wide_)Image and (Wide_)Value to check the values of the non-graphic
+-- characters and the last 2 characters.
+--
+--
+-- CHANGE HISTORY:
+-- 20 Jun 95 SAIC Initial prerelease version.
+-- 27 Jan 96 SAIC Revised for 2.1. Hid values, added "del" case.
+--
+--!
+
+with Ada.Characters.Handling;
+with Report;
+procedure C352001 is
+
+ Lower_Bound : Integer := 0;
+ Middle_Bound : Integer := 31;
+ Upper_Bound : Integer := 159;
+ Half_Bound : Integer := 127;
+ Max_Bound : Integer := 255;
+
+ type Dyn_String is access String;
+ type Value_Result is array (Character) of Dyn_String;
+
+ Table_Of_Character : Value_Result;
+ TC_Table : Value_Result;
+
+ function CVII(K : Natural) return Character is
+ begin
+ return Character'Val( Report.Ident_Int(K) );
+ end CVII;
+
+ function "=" (L, R : String) return Boolean is
+ UCL : String (L'First .. L'Last);
+ UCR : String (R'First .. R'last);
+ begin
+ UCL := Ada.Characters.Handling.To_Upper (L);
+ UCR := Ada.Characters.Handling.To_Upper (R);
+ if UCL'Last /= UCR'Last then
+ return False;
+ else
+ for I in UCL'First .. UCR'Last loop
+ if UCL (I) /= UCR (I) then
+ return False;
+ end if;
+ end loop;
+ return True;
+ end if;
+ end "=";
+
+begin
+
+ Report.Test ("C352001", "Check that, the predefined Character type " &
+ "comprises 256 positions. Check that the names of the " &
+ "non-graphic characters are usable with the attributes " &
+ "(Wide_)Image and (Wide_)Value, and that these attributes " &
+ "produce the correct result");
+
+ -- Fill table with strings (positions of Row 00 (0000-001F) of the ISO
+ -- 10646 Basic Multilingual Plane created by the compiler.
+
+ for I in CVII(Lower_Bound) .. CVII(Middle_Bound) loop
+ Table_Of_Character (I) := new String'(Character'Image(I));
+ end loop;
+
+ -- Fill table with strings (positions of Row 00 (007F-009F) of the ISO
+ -- 10646 Basic Multilingual Plane created by the compiler.
+
+ for I in CVII(Half_Bound) .. CVII(Upper_Bound) loop
+ Table_Of_Character (I) := new String'(Character'Image(I));
+ end loop;
+
+ -- Fill table with strings (positions of Row 00 (0000-001F) of the ISO
+ -- 10646 Basic Multilingual Plane defined by the language.
+
+ TC_Table (CVII(0)) := new String'("nul");
+ TC_Table (CVII(1)) := new String'("soh");
+ TC_Table (CVII(2)) := new String'("stx");
+ TC_Table (CVII(3)) := new String'("etx");
+ TC_Table (CVII(4)) := new String'("eot");
+ TC_Table (CVII(5)) := new String'("enq");
+ TC_Table (CVII(6)) := new String'("ack");
+ TC_Table (CVII(7)) := new String'("bel");
+ TC_Table (CVII(8)) := new String'("bs");
+ TC_Table (CVII(9)) := new String'("ht");
+ TC_Table (CVII(10)) := new String'("lf");
+ TC_Table (CVII(11)) := new String'("vt");
+ TC_Table (CVII(12)) := new String'("ff");
+ TC_Table (CVII(13)) := new String'("cr");
+ TC_Table (CVII(14)) := new String'("so");
+ TC_Table (CVII(15)) := new String'("si");
+ TC_Table (CVII(16)) := new String'("dle");
+ TC_Table (CVII(17)) := new String'("dc1");
+ TC_Table (CVII(18)) := new String'("dc2");
+ TC_Table (CVII(19)) := new String'("dc3");
+ TC_Table (CVII(20)) := new String'("dc4");
+ TC_Table (CVII(21)) := new String'("nak");
+ TC_Table (CVII(22)) := new String'("syn");
+ TC_Table (CVII(23)) := new String'("etb");
+ TC_Table (CVII(24)) := new String'("can");
+ TC_Table (CVII(25)) := new String'("em");
+ TC_Table (CVII(26)) := new String'("sub");
+ TC_Table (CVII(27)) := new String'("esc");
+ TC_Table (CVII(28)) := new String'("fs");
+ TC_Table (CVII(29)) := new String'("gs");
+ TC_Table (CVII(30)) := new String'("rs");
+ TC_Table (CVII(31)) := new String'("us");
+ TC_Table (CVII(127)) := new String'("del");
+
+ -- Fill table with strings (positions of Row 00 (007F-009F) of the ISO
+ -- 10646 Basic Multilingual Plane defined by the language.
+
+ TC_Table (CVII(128)) := new String'("reserved_128");
+ TC_Table (CVII(129)) := new String'("reserved_129");
+ TC_Table (CVII(130)) := new String'("bph");
+ TC_Table (CVII(131)) := new String'("nbh");
+ TC_Table (CVII(132)) := new String'("reserved_132");
+ TC_Table (CVII(133)) := new String'("nel");
+ TC_Table (CVII(134)) := new String'("ssa");
+ TC_Table (CVII(135)) := new String'("esa");
+ TC_Table (CVII(136)) := new String'("hts");
+ TC_Table (CVII(137)) := new String'("htj");
+ TC_Table (CVII(138)) := new String'("vts");
+ TC_Table (CVII(139)) := new String'("pld");
+ TC_Table (CVII(140)) := new String'("plu");
+ TC_Table (CVII(141)) := new String'("ri");
+ TC_Table (CVII(142)) := new String'("ss2");
+ TC_Table (CVII(143)) := new String'("ss3");
+ TC_Table (CVII(144)) := new String'("dcs");
+ TC_Table (CVII(145)) := new String'("pu1");
+ TC_Table (CVII(146)) := new String'("pu2");
+ TC_Table (CVII(147)) := new String'("sts");
+ TC_Table (CVII(148)) := new String'("cch");
+ TC_Table (CVII(149)) := new String'("mw");
+ TC_Table (CVII(150)) := new String'("spa");
+ TC_Table (CVII(151)) := new String'("epa");
+ TC_Table (CVII(152)) := new String'("sos");
+ TC_Table (CVII(153)) := new String'("reserved_153");
+ TC_Table (CVII(154)) := new String'("sci");
+ TC_Table (CVII(155)) := new String'("csi");
+ TC_Table (CVII(156)) := new String'("st");
+ TC_Table (CVII(157)) := new String'("osc");
+ TC_Table (CVII(158)) := new String'("pm");
+ TC_Table (CVII(159)) := new String'("apc");
+
+
+ -- Compare the first half of two tables.
+ for I in CVII(Lower_Bound) .. CVII(Middle_Bound) loop
+ if TC_Table(I).all /= Table_Of_Character(I).all then
+ Report.Failed("Value of character#" & Integer'Image(Character'Pos(I)) &
+ " is not the same in the first half of the table");
+ end if;
+ end loop;
+
+
+ -- Compare the second half of two tables.
+ for I in CVII(Half_Bound) .. CVII(Upper_Bound) loop
+ if TC_Table(I).all /= Table_Of_Character(I).all then
+ Report.Failed("Value of character#" & Integer'Image(Character'Pos(I)) &
+ " is not the same in the second half of the table");
+ end if;
+ end loop;
+
+
+ -- Check the first character.
+ if Character'Image( Character'First ) /= "NUL" then
+ Report.Failed("Value of character#" &
+ Integer'Image(Character'Pos (Character'First)) &
+ " is not NUL");
+ end if;
+
+
+ -- Check that the names of the non-graphic characters are usable with
+ -- Image and Value attributes.
+ if Character'Value( Character'Image( CVII(153) )) /=
+ CVII( 153 ) then
+ Report.Failed ("Value of character#" &
+ Integer'Image( Character'Pos(CVII(153)) ) &
+ " is not reserved_153");
+ end if;
+
+
+ for I in CVII(Lower_Bound) .. CVII(Max_Bound) loop
+ if Character'Value(
+ Report.Ident_Str(
+ Character'Image(CVII(Character'Pos(I)))))
+ /= CVII( Character'Pos(I)) then
+ Report.Failed ("Value of character#" &
+ Integer'Image( Character'Pos(I) ) &
+ " is not the same as the predefined character type");
+ end if;
+ end loop;
+
+
+ -- Check Wide_Character attributes.
+ for I in Wide_Character'Val(Lower_Bound) .. Wide_Character'Val(Max_Bound)
+ loop
+ if Wide_Character'Wide_Value(
+ Report.Ident_Wide_Str(
+ Wide_Character'Wide_Image(
+ Wide_Character'Val(Wide_Character'Pos(I)))))
+ /= Wide_Character'Val(Wide_Character'Pos(I))
+ then
+ Report.Failed ("Value of the predefined Wide_Character type " &
+ "is not correct");
+ end if;
+ end loop;
+
+
+ if Wide_Character'Value( Wide_Character'Image(Wide_Character'Val(132)) )
+ /= Wide_Character'Val( Report.Ident_Int(132) ) then
+ Report.Failed ("Wide_Character at 132 is not reserved_132");
+ end if;
+
+
+ if Wide_Character'Image( Wide_Character'First ) /= "NUL" then
+ Report.Failed ("Wide_Character'First is not NUL");
+ end if;
+
+
+ if Wide_Character'Image
+ (Wide_Character'Pred (Wide_Character'Last) ) /= "FFFE" then
+ Report.Failed ("Wide_Character at 65534 is not FFFE");
+ end if;
+
+
+ if Wide_Character'Image(Wide_Character'Last) /= "FFFF" then
+ Report.Failed ("Wide_Character'Last is not FFFF");
+ end if;
+
+ Report.Result;
+
+end C352001;
diff --git a/gcc/testsuite/ada/acats/tests/c4/c433001.a b/gcc/testsuite/ada/acats/tests/c4/c433001.a
index 613b688..305e010 100644
--- a/gcc/testsuite/ada/acats/tests/c4/c433001.a
+++ b/gcc/testsuite/ada/acats/tests/c4/c433001.a
@@ -36,6 +36,7 @@
--
-- HISTORY:
-- 16 DEC 1999 RLB Initial Version.
+-- 20 JAN 2009 RLB Corrected error messages.
with Report;
procedure C433001 is
@@ -82,10 +83,10 @@ procedure C433001 is
Report.Failed ("First Component incorrect (" & Test_Case & ")");
end if;
if Obj(Low+1) /= Second_Component then
- Report.Failed ("First Component incorrect (" & Test_Case & ")");
+ Report.Failed ("Second Component incorrect (" & Test_Case & ")");
end if;
if Obj(High) /= Last_Component then
- Report.Failed ("First Component incorrect (" & Test_Case & ")");
+ Report.Failed ("Last Component incorrect (" & Test_Case & ")");
end if;
end Check_1;
@@ -104,10 +105,10 @@ procedure C433001 is
Report.Failed ("First Component incorrect (" & Test_Case & ")");
end if;
if Obj(Color_Type'Succ(Low)) /= Second_Component then
- Report.Failed ("First Component incorrect (" & Test_Case & ")");
+ Report.Failed ("Second Component incorrect (" & Test_Case & ")");
end if;
if Obj(High) /= Last_Component then
- Report.Failed ("First Component incorrect (" & Test_Case & ")");
+ Report.Failed ("Last Component incorrect (" & Test_Case & ")");
end if;
end Check_2;
diff --git a/gcc/testsuite/ada/acats/tests/c4/c453001.a b/gcc/testsuite/ada/acats/tests/c4/c453001.a
new file mode 100644
index 0000000..53f4584
--- /dev/null
+++ b/gcc/testsuite/ada/acats/tests/c4/c453001.a
@@ -0,0 +1,236 @@
+-- C453001.A
+--
+-- Grant of Unlimited Rights
+--
+-- The Ada Conformity Assessment Authority (ACAA) holds unlimited
+-- rights in the software and documentation contained herein. Unlimited
+-- rights are the same as those granted by the U.S. Government for older
+-- parts of the Ada Conformity Assessment Test Suite, and are defined
+-- in DFAR 252.227-7013(a)(19). By making this public release, the ACAA
+-- intends to confer upon all recipients unlimited rights equal to those
+-- held by the ACAA. These rights include rights to use, duplicate,
+-- release or disclose the released technical data and computer software
+-- in whole or in part, in any manner and for any purpose whatsoever, and
+-- to have or permit others to do so.
+--
+-- DISCLAIMER
+--
+-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
+-- DISCLOSED ARE AS IS. THE ACAA MAKES NO EXPRESS OR IMPLIED
+-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
+-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
+-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
+-- PARTICULAR PURPOSE OF SAID MATERIAL.
+--
+-- Notice
+--
+-- The ACAA has created and maintains the Ada Conformity Assessment Test
+-- Suite for the purpose of conformity assessments conducted in accordance
+-- with the International Standard ISO/IEC 18009 - Ada: Conformity
+-- assessment of a language processor. This test suite should not be used
+-- to make claims of conformance unless used in accordance with
+-- ISO/IEC 18009 and any applicable ACAA procedures.
+--*
+-- OBJECTIVES:
+-- Check that overflow checking is not performed for adding operators of
+-- modular types.
+--
+-- TEST DESCRIPTION:
+-- Check that Constraint_Error is not raised by + or - when the result
+-- is out of the range of the base type.
+-- Also check that assignment to values in the upper half of the range
+-- does not raise Constraint_Error.
+--
+-- We define modular types of various common sizes. We cannot
+-- assume a binary modulus greater than 2**16 is supported by 3.5.4(23),
+-- so the DWord type might be smaller on some targets. We also try
+-- a small prime number as a modulus (these are often used for hashing).
+-- We also the language-defined types
+-- System.Storage_Elements.Storage_Element, Ada.Streams.Stream_Element,
+-- and Ada.Containers.Hash_Type.
+--
+-- CHANGE HISTORY:
+-- 11 Feb 17 JAC Initial pre-release version.
+-- 30 Mar 17 RLB Renamed, removed non-modular test cases, removed
+-- types that aren't required to be supported, added
+-- other language-defined types, added key to locate
+-- failures, added additional test cases.
+-- 03 Apr 17 RLB Removed Ada.Containers from the Ada 95 version of
+-- this test.
+--
+--!
+with Report;
+with System.Storage_Elements;
+with Ada.Streams;
+
+procedure C453001 is
+ type Unsigned_Byte_Type is mod 16#100#; -- 256;
+
+ type Unsigned_Word_Type is mod 16#1_0000#; -- 65536;
+
+ type Unsigned_DWord_Type is mod
+ Natural'Min (2**32, System.Max_Binary_Modulus);
+
+ type Unsigned_NBM_Type is mod System.Max_Nonbinary_Modulus;
+
+ type Biggest_Unsigned_Type is mod System.Max_Binary_Modulus;
+
+ type Prime_Type is mod 23; -- Prime number for hashing.
+
+ generic
+ type Mod_Type is mod <>; -- Assume this is a base type.
+ Key : in String;
+ procedure Test_Operators;
+
+ procedure Test_Operators is
+
+ function Ident_Mod (Val : in Mod_Type) return Mod_Type is
+ -- Optimization breaker.
+ begin
+ if Report.Equal (4, 12) then -- Always False (but complex).
+ return 1;
+ else
+ return Val;
+ end if;
+ end Ident_Mod;
+
+ begin
+ if Mod_Type'First /= 0 then -- The First of a base type is always 0.
+ Report.Failed ("Not base type first - " & Key);
+ end if;
+ if Mod_Type'Last /= Mod_Type'Base'Last then
+ Report.Failed ("Not base type last - " & Key);
+ end if;
+
+ -- Note: Mod_Type'First always is 0.
+
+ -- Check addition
+ declare
+ M : constant Mod_Type := Mod_Type'Last;
+ V : Mod_Type;
+ begin
+ V := M + 1; -- Should wrap around
+ if Ident_Mod (V) /= 0 then
+ Report.Failed ("Addition didn't wrap round - " & Key);
+ end if;
+ V := Ident_Mod (M - 2) + 5; -- Should wrap around
+ if Ident_Mod (V) /= 2 then
+ Report.Failed ("Addition didn't wrap round again - " & Key);
+ end if;
+ exception
+ when Constraint_Error =>
+ Report.Failed ("Constraint_Error raised for addition - " & Key);
+ when others =>
+ Report.Failed
+ ("Some even more unexpected exception raised for addition - " &
+ Key);
+ end;
+
+ -- Check subtraction
+ declare
+ M : constant Mod_Type := 0;
+ V : Mod_Type;
+ begin
+ V := M - 1; -- Should wrap around
+ if Ident_Mod (V) /= Mod_Type'Last then
+ Report.Failed ("Subtraction didn't wrap round - " & Key);
+ end if;
+ V := Ident_Mod (3) - 7; -- Should wrap around
+ if Ident_Mod (V) /= Mod_Type'Last-3 then
+ Report.Failed ("Subtraction didn't wrap round again - " & Key);
+ end if;
+ exception
+ when Constraint_Error =>
+ Report.Failed ("Constraint_Error raised for subtraction - " & Key);
+ when others =>
+ Report.Failed
+ ("Some even more unexpected exception raised for subtraction - " &
+ Key);
+ end;
+
+ end Test_Operators;
+
+ procedure Test_Unsigned_Byte_Operators is new Test_Operators
+ (Unsigned_Byte_Type, "Byte");
+
+ procedure Test_Unsigned_Word_Operators is new Test_Operators
+ (Unsigned_Word_Type, "Word");
+
+ procedure Test_Unsigned_DWord_Operators is new Test_Operators
+ (Unsigned_DWord_Type, "DWord");
+
+ procedure Test_Unsigned_NBM_Operators is new Test_Operators
+ (Unsigned_NBM_Type, "NBM");
+
+ procedure Test_Biggest_Unsigned_Operators is new Test_Operators
+ (Biggest_Unsigned_Type, "Big");
+
+ procedure Test_Prime_Operators is new Test_Operators (Prime_Type, "Prime");
+
+ procedure Test_Storage_Element_Operators is new Test_Operators
+ (System.Storage_Elements.Storage_Element, "Storage");
+
+ procedure Test_Stream_Element_Operators is new Test_Operators
+ (Ada.Streams.Stream_Element, "Stream");
+
+begin
+
+ Report.Test
+ ("C453001",
+ "Check that overflow checking is not performed for adding operators " &
+ "of modular types");
+
+ -- Check assignment
+ declare
+ -- Define subtypes
+ subtype My_Unsigned_Byte_Type is Unsigned_Byte_Type;
+ subtype My_Unsigned_Word_Type is Unsigned_Word_Type;
+ subtype My_Unsigned_DWord_Type is Unsigned_DWord_Type;
+
+ -- Define constants in upper half of range
+ C1 : constant Unsigned_Byte_Type := Unsigned_Byte_Type'Last;
+ C2 : constant My_Unsigned_Byte_Type := 16#FE#;
+ C3 : constant Unsigned_Word_Type := 16#FACE#;
+ C4 : constant My_Unsigned_Word_Type := My_Unsigned_Word_Type'Last;
+ C5 : constant Unsigned_DWord_Type := My_Unsigned_DWord_Type'Last;
+
+ -- Define variables
+ V1 : Unsigned_Byte_Type;
+ V2 : My_Unsigned_Byte_Type;
+ V3 : Unsigned_Word_Type;
+ V4 : My_Unsigned_Word_Type;
+ V5 : Unsigned_DWord_Type;
+ begin
+ V1 := C1;
+ V1 := C2;
+ V2 := C1;
+ V2 := C2;
+ V3 := C3;
+ V3 := C4;
+ V4 := C3;
+ V4 := C4;
+ V5 := C5;
+ if V1 /= C2 or V2 /= C2 or V3 /= C4 or V4 /= C4 or V5 /= C5 then
+ Report.Comment ("Don't optimize assignment!"); -- Optimization breaker
+ end if;
+ exception
+ when Constraint_Error =>
+ Report.Failed ("Constraint_Error raised for assignment");
+ when others =>
+ Report.Failed ("Some even more unexpected exception raised " &
+ "for assignment");
+ end;
+
+ Test_Unsigned_Byte_Operators;
+ Test_Unsigned_Word_Operators;
+ Test_Unsigned_DWord_Operators;
+ Test_Unsigned_NBM_Operators;
+ Test_Biggest_Unsigned_Operators;
+ Test_Prime_Operators;
+ Test_Storage_Element_Operators;
+ Test_Stream_Element_Operators;
+
+ Report.Result;
+
+end C453001;
+
diff --git a/gcc/testsuite/ada/acats/tests/c4/c45622a.ada b/gcc/testsuite/ada/acats/tests/c4/c45622a.ada
deleted file mode 100644
index 42f0204..0000000
--- a/gcc/testsuite/ada/acats/tests/c4/c45622a.ada
+++ /dev/null
@@ -1,83 +0,0 @@
--- C45622A.ADA
-
--- Grant of Unlimited Rights
---
--- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
--- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
--- unlimited rights in the software and documentation contained herein.
--- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
--- this public release, the Government intends to confer upon all
--- recipients unlimited rights equal to those held by the Government.
--- These rights include rights to use, duplicate, release or disclose the
--- released technical data and computer software in whole or in part, in
--- any manner and for any purpose whatsoever, and to have or permit others
--- to do so.
---
--- DISCLAIMER
---
--- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
--- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
--- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
--- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
--- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
--- PARTICULAR PURPOSE OF SAID MATERIAL.
---*
--- OBJECTIVE:
--- FOR EXPONENTIATION OF FLOATING POINT TYPES, CHECK THAT
--- CONSTRAINT_ERROR IS RAISED IF
--- MACHINE_OVERFLOWS IS TRUE AND THE RESULT IS OUTSIDE THE RANGE OF
--- THE BASE TYPE. THIS TESTS DIGITS 5.
-
--- *** NOTE: This test has been modified since ACVC version 1.11 to -- 9X
--- *** remove incompatibilities associated with the transition -- 9X
--- *** to Ada 9X. -- 9X
--- *** -- 9X
-
--- HISTORY:
--- BCB 02/09/88 CREATED ORIGINAL TEST.
--- MRM 03/30/93 REMOVED NUMERIC_ERROR FOR 9X COMPATIBILITY
-
-WITH REPORT; USE REPORT;
-
-PROCEDURE C45622A IS
-
- TYPE FLT IS DIGITS 5;
-
- F : FLT;
-
- FUNCTION EQUAL_FLT (ONE, TWO : FLT) RETURN BOOLEAN IS
- BEGIN
- RETURN ONE = TWO * FLT (IDENT_INT(1));
- END EQUAL_FLT;
-
-BEGIN
- TEST ("C45622A", "FOR EXPONENTIATION OF FLOATING POINT TYPES, " &
- "CHECK THAT CONSTRAINT_ERROR " &
- "IS RAISED IF MACHINE_OVERFLOWS IS TRUE AND " &
- "THE RESULT IS OUTSIDE THE RANGE OF THE BASE " &
- "TYPE. THIS TESTS DIGITS 5");
-
- IF FLT'MACHINE_OVERFLOWS THEN
- BEGIN
- F := (FLT'BASE'LAST)**IDENT_INT (2);
- FAILED ("CONSTRAINT_ERROR WAS NOT RAISED FOR " &
- "EXPONENTIATION");
-
- IF NOT EQUAL_FLT(F,F) THEN
- COMMENT ("DON'T OPTIMIZE F");
- END IF;
- EXCEPTION
- WHEN CONSTRAINT_ERROR =>
- COMMENT ("CONSTRAINT_ERROR WAS RAISED FOR " &
- "EXPONENTIATION");
- WHEN OTHERS =>
- FAILED ("AN EXCEPTION OTHER THAN CONSTRAINT_ERROR " &
- "WAS RAISED FOR EXPONENTIATION");
- END;
- ELSE
- NOT_APPLICABLE ("THIS TEST IS NOT APPLICABLE DUE TO " &
- "MACHINE_OVERFLOWS BEING FALSE");
- END IF;
-
- RESULT;
-END C45622A;
diff --git a/gcc/testsuite/ada/acats/tests/c4/c45624a.ada b/gcc/testsuite/ada/acats/tests/c4/c45624a.ada
deleted file mode 100644
index 32ba4c0..0000000
--- a/gcc/testsuite/ada/acats/tests/c4/c45624a.ada
+++ /dev/null
@@ -1,86 +0,0 @@
--- C45624A.ADA
-
--- Grant of Unlimited Rights
---
--- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
--- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
--- unlimited rights in the software and documentation contained herein.
--- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
--- this public release, the Government intends to confer upon all
--- recipients unlimited rights equal to those held by the Government.
--- These rights include rights to use, duplicate, release or disclose the
--- released technical data and computer software in whole or in part, in
--- any manner and for any purpose whatsoever, and to have or permit others
--- to do so.
---
--- DISCLAIMER
---
--- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
--- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
--- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
--- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
--- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
--- PARTICULAR PURPOSE OF SAID MATERIAL.
---*
--- OBJECTIVE:
--- FOR FLOATING POINT TYPES, CHECK THAT CONSTRAINT_ERROR
--- IS RAISED IF THE RESULT OF A FLOATING POINT
--- EXPONENTIATION IS OUTSIDE THE RANGE OF THE BASE TYPE AND
--- MACHINE_OVERFLOWS IS FALSE. THIS TESTS DIGITS 5.
-
--- *** NOTE: This test has been modified since ACVC version 1.11 to -- 9X
--- *** remove incompatibilities associated with the transition -- 9X
--- *** to Ada 9X. -- 9X
--- *** -- 9X
-
--- HISTORY:
--- BCB 02/09/88 CREATED ORIGINAL TEST.
--- MRM 03/30/93 REMOVED NUMERIC_ERROR FOR 9X COMPATIBILITY
-
-WITH REPORT; USE REPORT;
-
-PROCEDURE C45624A IS
-
- TYPE FLT IS DIGITS 5;
-
- F : FLT;
-
- FUNCTION EQUAL_FLT (ONE, TWO : FLT) RETURN BOOLEAN IS
- BEGIN
- IF EQUAL(3,3) THEN
- RETURN ONE = TWO;
- ELSE
- RETURN ONE /= TWO;
- END IF;
- END EQUAL_FLT;
-
-BEGIN
- TEST ("C45624A", "FOR FLOATING POINT TYPES, CHECK THAT " &
- "CONSTRAINT_ERROR IS RAISED " &
- "IF MACHINE_OVERFLOWS IS FALSE. THIS TESTS " &
- "DIGITS 5");
-
- IF FLT'MACHINE_OVERFLOWS THEN
- NOT_APPLICABLE ("THIS TEST IS NOT APPLICABLE DUE TO " &
- "MACHINE_OVERFLOWS BEING TRUE");
- ELSE
- BEGIN
- F := FLT'BASE'FIRST**IDENT_INT (2);
- COMMENT ("CONSTRAINT_ERROR WAS NOT RAISED WHEN " &
- "MACHINE_OVERFLOWS WAS FALSE");
-
- IF EQUAL_FLT(F,F**IDENT_INT(1)) THEN
- COMMENT ("DON'T OPTIMIZE F");
- END IF;
- EXCEPTION
- WHEN CONSTRAINT_ERROR =>
- COMMENT ("CONSTRAINT_ERROR WAS RAISED WHEN " &
- "MACHINE_OVERFLOWS WAS FALSE");
- WHEN OTHERS =>
- FAILED ("AN EXCEPTION OTHER THAN CONSTRAINT_ERROR " &
- "WAS RAISED");
- END;
- END IF;
-
- RESULT;
-END C45624A;
diff --git a/gcc/testsuite/ada/acats/tests/c4/c45624b.ada b/gcc/testsuite/ada/acats/tests/c4/c45624b.ada
deleted file mode 100644
index c7bd592..0000000
--- a/gcc/testsuite/ada/acats/tests/c4/c45624b.ada
+++ /dev/null
@@ -1,81 +0,0 @@
--- C45624B.ADA
-
--- Grant of Unlimited Rights
---
--- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
--- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
--- unlimited rights in the software and documentation contained herein.
--- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
--- this public release, the Government intends to confer upon all
--- recipients unlimited rights equal to those held by the Government.
--- These rights include rights to use, duplicate, release or disclose the
--- released technical data and computer software in whole or in part, in
--- any manner and for any purpose whatsoever, and to have or permit others
--- to do so.
---
--- DISCLAIMER
---
--- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
--- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
--- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
--- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
--- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
--- PARTICULAR PURPOSE OF SAID MATERIAL.
---*
--- OBJECTIVE:
--- FOR FLOATING POINT TYPES, CHECK THAT
--- CONSTRAINT_ERROR IS RAISED IF THE RESULT OF A FLOATING POINT
--- EXPONENTIATION IS OUTSIDE THE RANGE OF THE BASE TYPE AND
--- MACHINE_OVERFLOWS IS FALSE. THIS TESTS DIGITS 6.
-
--- *** NOTE: This test has been modified since ACVC version 1.11 to -- 9X
--- *** remove incompatibilities associated with the transition -- 9X
--- *** to Ada 9X. -- 9X
--- *** -- 9X
-
--- HISTORY:
--- BCB 07/14/88 CREATED ORIGINAL TEST.
--- MRM 03/30/93 REMOVED NUMERIC_ERROR FOR 9X COMPATIBILITY
-
-WITH REPORT; USE REPORT;
-
-PROCEDURE C45624B IS
-
- TYPE FLT IS DIGITS 6;
-
- F : FLT;
-
- FUNCTION EQUAL_FLT (ONE, TWO : FLT) RETURN BOOLEAN IS
- BEGIN
- RETURN ONE = TWO * FLT (IDENT_INT(1));
- END EQUAL_FLT;
-
-BEGIN
- TEST ("C45624B", "FOR FLOATING POINT TYPES, CHECK THAT " &
- "CONSTRAINT_ERROR IS RAISED " &
- "IF MACHINE_OVERFLOWS IS FALSE. THIS TESTS " &
- "DIGITS 6");
-
- IF FLT'MACHINE_OVERFLOWS THEN
- NOT_APPLICABLE ("THIS TEST IS NOT APPLICABLE DUE TO " &
- "MACHINE_OVERFLOWS BEING TRUE");
- ELSE
- BEGIN
- F := FLT'BASE'LAST**IDENT_INT (2);
- COMMENT ("CONSTRAINT_ERROR WAS NOT RAISED WHEN " &
- "MACHINE_OVERFLOWS WAS FALSE");
- IF NOT EQUAL_FLT(F,F**IDENT_INT(1)) THEN
- COMMENT ("DON'T OPTIMIZE F");
- END IF;
- EXCEPTION
- WHEN CONSTRAINT_ERROR =>
- COMMENT ("CONSTRAINT_ERROR WAS RAISED WHEN " &
- "MACHINE_OVERFLOWS WAS FALSE");
- WHEN OTHERS =>
- FAILED ("AN EXCEPTION OTHER THAN CONSTRAINT_ERROR " &
- "WAS RAISED");
- END;
- END IF;
-
- RESULT;
-END C45624B;
diff --git a/gcc/testsuite/ada/acats/tests/c4/c460013.a b/gcc/testsuite/ada/acats/tests/c4/c460013.a
new file mode 100644
index 0000000..7644f88
--- /dev/null
+++ b/gcc/testsuite/ada/acats/tests/c4/c460013.a
@@ -0,0 +1,188 @@
+-- C460013.A
+--
+-- Grant of Unlimited Rights
+--
+-- The Ada Conformity Assessment Authority (ACAA) holds unlimited
+-- rights in the software and documentation contained herein. Unlimited
+-- rights are the same as those granted by the U.S. Government for older
+-- parts of the Ada Conformity Assessment Test Suite, and are defined
+-- in DFAR 252.227-7013(a)(19). By making this public release, the ACAA
+-- intends to confer upon all recipients unlimited rights equal to those
+-- held by the ACAA. These rights include rights to use, duplicate,
+-- release or disclose the released technical data and computer software
+-- in whole or in part, in any manner and for any purpose whatsoever, and
+-- to have or permit others to do so.
+--
+-- DISCLAIMER
+--
+-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
+-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
+-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
+-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
+-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
+-- PARTICULAR PURPOSE OF SAID MATERIAL.
+--*
+--
+-- OBJECTIVE:
+-- Check that if the target subtype excludes null, the value is not
+-- null. Check access parameters, which null-excluding if:
+-- (1) not null is given in their definition;
+-- (2) the access parameter is controlling;
+-- (3) an Ada 95 compiler is in use.
+--
+-- Note that the not null syntax is required even for Ada 95 compilers
+-- (see AI95-00447).
+--
+-- CHANGE HISTORY:
+-- 18 DEC 2006 RLB Initial version.
+-- 05 JAN 2007 RLB Corrected syntax error.
+--
+--!
+with Ada.Exceptions;
+use Ada.Exceptions;
+with Report;
+use Report;
+procedure C460013 is
+
+
+ package Nest1 is
+ type Doggie is tagged record
+ Cnt : Natural;
+ end record;
+ type Doggie_Access is access all Doggie;
+
+ procedure Controlled (P : access Doggie); -- Always null-excluding.
+ end Nest1;
+
+ package Nest2 is
+ type Kitty is record
+ Cnt : Natural;
+ end record;
+ type Kitty_Access is access all Kitty;
+
+ procedure Include (P : access Kitty); -- Null-excluding only in Ada 95.
+ procedure Exclude (P : not null access Kitty); -- Always null-excluding.
+ end Nest2;
+
+
+ package body Nest1 is
+ procedure Controlled (P : access Doggie) is
+ begin
+ if P.Cnt /= Ident_Int(4) then
+ Failed ("Bad value in null-excluding controlling parameter");
+ -- else OK
+ end if;
+ exception
+ when Constraint_Error => -- Dereference of null
+ Failed ("Null allowed in null-excluding controlling parameter");
+ end Controlled;
+ end Nest1;
+
+ package body Nest2 is
+ procedure Include (P : access Kitty) is
+ begin
+ if P.Cnt /= Ident_Int(31) then
+ Failed ("Bad value in access parameter");
+ -- else OK
+ end if;
+ exception
+ when Constraint_Error => -- Dereference of null
+ null;
+ --Comment ("Null allowed in access parameter - Ada 2005 semantics");
+ end Include;
+
+ procedure Exclude (P : not null access Kitty) is
+ begin
+ if P.Cnt /= Ident_Int(80) then
+ Failed ("Bad value in explicit null-excluding parameter");
+ -- else OK
+ end if;
+ exception
+ when Constraint_Error => -- Dereference of null
+ Failed ("Null allowed in explicit null-excluding parameter");
+ end Exclude;
+ end Nest2;
+
+ Shep : aliased Nest1.Doggie := (Cnt => 4);
+ Frisky : aliased Nest2.Kitty := (Cnt => 80);
+ Snuggles : aliased Nest2.Kitty := (Cnt => 31);
+
+begin
+ Test ("C460013",
+ "Check that if the target subtype excludes null, the value is not" &
+ " null - access parameter cases");
+
+ declare
+ Ptr : Nest1.Doggie_Access := Shep'Access;
+ begin
+ begin
+ Nest1.Controlled (Ptr); -- OK.
+ exception
+ when A: others =>
+ Failed ("Unexpected exception " & Exception_Name (A) &
+ " raised (1A) - " & Exception_Message (A));
+ end;
+ Ptr := null;
+ begin
+ Nest1.Controlled (Ptr);
+ Failed ("Null allowed for null-excluding controlling access parameter (1)");
+ exception
+ when Constraint_Error =>
+ null;
+ when B: others =>
+ Failed ("Unexpected exception " & Exception_Name (B) &
+ " raised (1B) - " & Exception_Message (B));
+ end;
+ end;
+
+ declare
+ Ptr : Nest2.Kitty_Access := Frisky'Access;
+ begin
+ begin
+ Nest2.Exclude (Ptr); -- OK.
+ exception
+ when C: others =>
+ Failed ("Unexpected exception " & Exception_Name (C) &
+ " raised (2A) - " & Exception_Message (C));
+ end;
+ Ptr := null;
+ begin
+ Nest2.Exclude (Ptr);
+ Failed ("Null allowed for null-excluding access parameter (2)");
+ exception
+ when Constraint_Error =>
+ null;
+ when D: others =>
+ Failed ("Unexpected exception " & Exception_Name (D) &
+ " raised (2B) - " & Exception_Message (D));
+ end;
+ end;
+
+ declare
+ Ptr : Nest2.Kitty_Access := Snuggles'Access;
+ begin
+ begin
+ Nest2.Include (Ptr); -- OK.
+ exception
+ when E: others =>
+ Failed ("Unexpected exception " & Exception_Name (E) &
+ " raised (3A) - " & Exception_Message (E));
+ end;
+ Ptr := null;
+ begin
+ Nest2.Include (Ptr);
+ Comment ("Null allowed for normal access parameter - " &
+ "Ada 2005 semantics");
+ exception
+ when Constraint_Error =>
+ Comment ("Null not allowed for normal access parameter - " &
+ "Ada 95 semantics");
+ when F: others =>
+ Failed ("Unexpected exception " & Exception_Name (F) &
+ " raised (3B) - " & Exception_Message (F));
+ end;
+ end;
+
+ Result;
+end C460013;
+
diff --git a/gcc/testsuite/ada/acats/tests/c4/c460014.a b/gcc/testsuite/ada/acats/tests/c4/c460014.a
new file mode 100644
index 0000000..59a95d9
--- /dev/null
+++ b/gcc/testsuite/ada/acats/tests/c4/c460014.a
@@ -0,0 +1,289 @@
+-- C460014.A
+--
+-- Grant of Unlimited Rights
+--
+-- The Ada Conformity Assessment Authority (ACAA) holds unlimited
+-- rights in the software and documentation contained herein. Unlimited
+-- rights are the same as those granted by the U.S. Government for older
+-- parts of the Ada Conformity Assessment Test Suite, and are defined
+-- in DFAR 252.227-7013(a)(19). By making this public release, the ACAA
+-- intends to confer upon all recipients unlimited rights equal to those
+-- held by the ACAA. These rights include rights to use, duplicate,
+-- release or disclose the released technical data and computer software
+-- in whole or in part, in any manner and for any purpose whatsoever, and
+-- to have or permit others to do so.
+--
+-- DISCLAIMER
+--
+-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
+-- DISCLOSED ARE AS IS. THE ACAA MAKES NO EXPRESS OR IMPLIED
+-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
+-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
+-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
+-- PARTICULAR PURPOSE OF SAID MATERIAL.
+--
+-- Notice
+--
+-- The ACAA has created and maintains the Ada Conformity Assessment Test
+-- Suite for the purpose of conformity assessments conducted in accordance
+-- with the International Standard ISO/IEC 18009 - Ada: Conformity
+-- assessment of a language processor. This test suite should not be used
+-- to make claims of conformance unless used in accordance with
+-- ISO/IEC 18009 and any applicable ACAA procedures.
+--*
+-- OBJECTIVES:
+-- Check that if the operand type of a type conversion is
+-- access-to-class-wide, Constraint_Error is raised if the tag of the
+-- object designated by the operand does not identify a specific type
+-- that is covered by or descended from the target type.
+--
+-- TEST DESCRIPTION:
+-- Attempt to convert a parameter of a type that designates a class-wide
+-- type to an object of a type that designates a specific member of that
+-- class, for both an actual with a different tag and an actual with a
+-- matching tag.
+--
+-- This test checks 4.6(42) as required by 4.6(50).
+--
+-- CHANGE HISTORY:
+-- 19 Aug 16 JAC Initial pre-release version.
+-- 19 Jan 17 RLB Readied for release: replaced objective, renamed
+-- to appropriate number, added class-wide cases,
+-- eliminated 11.6 problems, added third level of
+-- types, and checks on null.
+--
+--!
+package C460014_1 is
+ type Root_Facade_Type is tagged record
+ Error_Code : Integer;
+ end record;
+
+ type Root_Facade_Ptr_Type is access all Root_Facade_Type;
+
+ type Facade_Class_Ptr_Type is access all Root_Facade_Type'Class;
+
+ type Data_A_Type is
+ record
+ A : Boolean;
+ end record;
+
+ type Facade_A_Type is new Root_Facade_Type with
+ record
+ Data_A : Data_A_Type;
+ end record;
+
+ type Facade_A_Ptr_Type is access all Facade_A_Type;
+
+ type Facade_A_Class_Ptr_Type is access all Facade_A_Type'Class;
+
+ type Facade_B_Type is new Facade_A_Type with
+ record
+ B : Character;
+ end record;
+
+ type Facade_B_Ptr_Type is access all Facade_B_Type;
+
+ type Facade_B_Class_Ptr_Type is access all Facade_B_Type'Class;
+
+ procedure Define_Construct
+ (Facade_Class_Ptr : in Facade_Class_Ptr_Type);
+
+ procedure Define_Class_Construct
+ (Facade_Class_Ptr : in Facade_Class_Ptr_Type);
+
+ function Init_Root_Facade_Ptr return Root_Facade_Ptr_Type;
+
+ function Init_Facade_A_Ptr return Facade_A_Ptr_Type;
+
+ function Init_Facade_B_Ptr return Facade_B_Ptr_Type;
+
+ function Init_Facade_Class_Ptr_with_Root return Facade_Class_Ptr_Type;
+
+ function Init_Facade_Class_Ptr_with_A return Facade_Class_Ptr_Type;
+
+ function Init_Facade_Class_Ptr_with_B return Facade_Class_Ptr_Type;
+
+end C460014_1;
+
+with Report;
+package body C460014_1 is
+
+ procedure Define_Construct
+ (Facade_Class_Ptr : in Facade_Class_Ptr_Type) is
+
+ Facade_A_Ptr : constant Facade_A_Ptr_Type :=
+ Facade_A_Ptr_Type (Facade_Class_Ptr);
+
+ My_A : Data_A_Type renames Facade_A_Ptr.Data_A;
+ begin
+ if not My_A.A then
+ Report.Comment ("Wrong value"); -- So My_A is not dead by 11.6(5).
+ end if;
+ end Define_Construct;
+
+ procedure Define_Class_Construct
+ (Facade_Class_Ptr : in Facade_Class_Ptr_Type) is
+
+ Facade_Class_A_Ptr : constant Facade_A_Class_Ptr_Type :=
+ Facade_A_Class_Ptr_Type (Facade_Class_Ptr);
+
+ begin
+ if Facade_Class_A_Ptr /= null and then
+ (not Facade_Class_A_Ptr.Data_A.A) then
+ Report.Comment ("Wrong value"); -- So the ptr is not dead by 11.6(5).
+ end if;
+ end Define_Class_Construct;
+
+ Dummy_Root_Facade : aliased Root_Facade_Type := (Error_Code => 123);
+
+ function Init_Root_Facade_Ptr return Root_Facade_Ptr_Type is
+ begin
+ return Dummy_Root_Facade'Access;
+ end Init_Root_Facade_Ptr;
+
+ Dummy_Facade_A : aliased Facade_A_Type := (Error_Code => 123,
+ Data_A => (A => True));
+
+ function Init_Facade_A_Ptr return Facade_A_Ptr_Type is
+ begin
+ return Dummy_Facade_A'Access;
+ end Init_Facade_A_Ptr;
+
+ Dummy_Facade_B : aliased Facade_B_Type := (Error_Code => 234,
+ Data_A => (A => True),
+ B => 'P');
+
+ function Init_Facade_B_Ptr return Facade_B_Ptr_Type is
+ begin
+ return Dummy_Facade_B'Access;
+ end Init_Facade_B_Ptr;
+
+ function Init_Facade_Class_Ptr_with_Root return Facade_Class_Ptr_Type is
+ begin
+ return Dummy_Root_Facade'Access;
+ end Init_Facade_Class_Ptr_with_Root;
+
+ function Init_Facade_Class_Ptr_with_A return Facade_Class_Ptr_Type is
+ begin
+ return Dummy_Facade_A'Access;
+ end Init_Facade_Class_Ptr_with_A;
+
+ function Init_Facade_Class_Ptr_with_B return Facade_Class_Ptr_Type is
+ begin
+ return Dummy_Facade_B'Access;
+ end Init_Facade_Class_Ptr_with_B;
+
+end C460014_1;
+
+
+with C460014_1;
+with Report;
+
+procedure C460014 is
+
+ My_Root_Facade_Ptr : constant C460014_1.Facade_Class_Ptr_Type :=
+ C460014_1.Init_Facade_Class_Ptr_with_Root;
+
+ My_Facade_A_Ptr : constant C460014_1.Facade_Class_Ptr_Type :=
+ C460014_1.Init_Facade_Class_Ptr_with_A;
+
+ My_Facade_B_Ptr : constant C460014_1.Facade_Class_Ptr_Type :=
+ C460014_1.Init_Facade_Class_Ptr_with_B;
+
+ My_Null_Facade_B_Ptr : constant C460014_1.Facade_B_Ptr_Type := null;
+
+ Constraint_Error_Raised : Boolean;
+
+ procedure Test_Define_Construct
+ (Facade_Class_Ptr : in C460014_1.Facade_Class_Ptr_Type) is
+ begin
+ Constraint_Error_Raised := False;
+ -- Should fail Tag_Check and therefore raise Constraint_Error if
+ -- parameter doesn't designate an object of Facade_A_Type
+ -- or Facade_B_Type.
+ C460014_1.Define_Construct (Facade_Class_Ptr => Facade_Class_Ptr);
+ exception
+ when Constraint_Error =>
+ Constraint_Error_Raised := True;
+ end Test_Define_Construct;
+
+
+ procedure Test_Define_Class_Construct
+ (Facade_Class_Ptr : in C460014_1.Facade_Class_Ptr_Type) is
+ begin
+ Constraint_Error_Raised := False;
+ -- Should fail Tag_Check and therefore raise Constraint_Error if
+ -- parameter doesn't designate an object of Facade_A_Type
+ -- or Facade_B_Type.
+ C460014_1.Define_Class_Construct (Facade_Class_Ptr => Facade_Class_Ptr);
+ exception
+ when Constraint_Error =>
+ Constraint_Error_Raised := True;
+ end Test_Define_Class_Construct;
+
+begin
+
+ Report.Test
+ ("C460014",
+ "Check that if the operand type of a type conversion is " &
+ "access-to-class-wide, Constraint_Error is raised if the tag of the " &
+ "object designated by the operand does not identify a specific type " &
+ "that is covered by or descended from the target type");
+
+ Test_Define_Construct (Facade_Class_Ptr => My_Root_Facade_Ptr);
+
+ if not Constraint_Error_Raised then
+ Report.Failed ("Didn't get expected Constraint_Error (1)");
+ end if;
+
+ Test_Define_Construct
+ (Facade_Class_Ptr => My_Facade_A_Ptr);
+
+ if Constraint_Error_Raised then
+ Report.Failed ("Unexpected Constraint_Error (2)");
+ end if;
+
+ Test_Define_Construct
+ (Facade_Class_Ptr => My_Facade_B_Ptr);
+
+ if Constraint_Error_Raised then
+ Report.Failed ("Unexpected Constraint_Error (3)");
+ end if;
+
+ Test_Define_Class_Construct (Facade_Class_Ptr => My_Root_Facade_Ptr);
+
+ if not Constraint_Error_Raised then
+ Report.Failed ("Didn't get expected Constraint_Error (4)");
+ end if;
+
+ Test_Define_Class_Construct
+ (Facade_Class_Ptr => My_Facade_A_Ptr);
+
+ if Constraint_Error_Raised then
+ Report.Failed ("Unexpected Constraint_Error (5)");
+ end if;
+
+ Test_Define_Class_Construct
+ (Facade_Class_Ptr => My_Facade_B_Ptr);
+
+ if Constraint_Error_Raised then
+ Report.Failed ("Unexpected Constraint_Error (6)");
+ end if;
+
+ -- Check that it is OK to pass null and that does not cause some failure.
+ Test_Define_Class_Construct (Facade_Class_Ptr => null);
+
+ if Constraint_Error_Raised then
+ Report.Failed ("Unexpected Constraint_Error (7)");
+ end if;
+
+ Test_Define_Class_Construct (Facade_Class_Ptr =>
+ C460014_1.Facade_Class_Ptr_Type (My_Null_Facade_B_Ptr));
+
+ if Constraint_Error_Raised then
+ Report.Failed ("Unexpected Constraint_Error (8)");
+ end if;
+
+ Report.Result;
+
+end C460014;
diff --git a/gcc/testsuite/ada/acats/tests/c6/c620001.a b/gcc/testsuite/ada/acats/tests/c6/c620001.a
new file mode 100644
index 0000000..0f854d1
--- /dev/null
+++ b/gcc/testsuite/ada/acats/tests/c6/c620001.a
@@ -0,0 +1,340 @@
+-- C620001.A
+
+-- Grant of Unlimited Rights
+--
+-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
+-- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
+-- unlimited rights in the software and documentation contained herein.
+-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
+-- this public release, the Government intends to confer upon all
+-- recipients unlimited rights equal to those held by the Government.
+-- These rights include rights to use, duplicate, release or disclose the
+-- released technical data and computer software in whole or in part, in
+-- any manner and for any purpose whatsoever, and to have or permit others
+-- to do so.
+--
+-- DISCLAIMER
+--
+-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
+-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
+-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
+-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
+-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
+-- PARTICULAR PURPOSE OF SAID MATERIAL.
+--*
+-- OBJECTIVE:
+-- Check that elementary parameters are passed by copy.
+--
+-- Part 1: Integer, float, and access types, procedures and functions.
+--
+-- TEST DESCRIPTION:
+-- Subtests are:
+-- (A) Scalar parameters to procedures.
+-- (B) Scalar parameters to functions.
+-- (C) Access parameters to procedures.
+-- (D) Access parameters to functions.
+--
+-- For the procedure examples, we pass array elements indexed by dynamically
+-- determined indexes. Doing this side-steps the check of 6.4.1(6.15/3) and
+-- makes the test more realistic.
+--
+-- To completely test this objective, we should also try in out and out
+-- parameters for functions (Ada 2012), in/in out/out parameters for
+-- task and protected entries, and a variety of different scalar types
+-- (enumeration, modular, fixed, decimal).
+--
+-- CHANGE HISTORY:
+-- 14 Jan 1980 DAS Created test.
+-- 26 Oct 1982 SPS
+-- 25 May 1984 CPP
+-- 29 Oct 1985 EG Eliminate the use of Numeric_Error in the test.
+-- 14 Mar 2014 RLB Revised so test cases are legal for Ada 2012, modernized
+-- objective, converted to modern format, added float cases.
+
+with Report;
+procedure C620001 is
+
+ use Report;
+
+begin
+ Test ("C620001", "Check that elementary parameters are passed by copy");
+
+ --------------------------------------------------
+
+ declare -- (A)
+
+ I,J,K : Natural := Report.Ident_Int(1); -- Index values.
+ Arr : array (1 .. 4) of Integer;
+ E : exception;
+
+ procedure P (PI : in Integer;
+ PO : out Integer;
+ PIO : in out Integer) is
+
+ Tmp : Integer;
+
+ begin
+
+ Tmp := PI; -- Save value of PI at procedure entry.
+
+ PO := 10;
+ if (PI /= Tmp) then
+ Failed ("Assignement to scalar out " &
+ "parameter changes the value of " &
+ "input parameter");
+ Tmp := PI; -- Reset Tmp for next case.
+ end if;
+
+ PIO := PIO + 100;
+ if (PI /= Tmp) then
+ Failed ("Assignment to scalar in out " &
+ "parameter changes the value of " &
+ "inputparameter");
+ Tmp := PI; -- Reset Tmp for next case.
+ end if;
+
+ Arr(I) := Arr(I) + 1;
+ if (PI /= Tmp) then
+ Failed ("Assignment to scalar actual " &
+ "parameter changes the value of " &
+ "input parameter");
+ end if;
+
+ raise E; -- Check exception handling.
+ end P;
+
+ begin -- (A)
+ Arr := (others => 0);
+ P (Arr(I), Arr(J), Arr(K));
+ Failed ("Exception not raised - A");
+ exception
+ when E =>
+ if (Arr(I) /= 1) then
+ case Arr(I) is
+ when 11 =>
+ Failed ("Out actual scalar parameter " &
+ "changed global value");
+ when 101 =>
+ Failed ("In out actual scalar " &
+ "parameter changed global value");
+ when 111 =>
+ Failed ("Out and in out actual scalar " &
+ "parameters changed global " &
+ "value");
+ when others =>
+ Failed ("Uundetermined change to global " &
+ "value");
+ end case;
+ end if;
+ when others =>
+ Failed ("Wrong exception raised - A");
+ end; -- (A)
+
+ --------------------------------------------------
+
+ declare -- (B)
+
+ I,J : Integer;
+
+ function F (FI : in Integer) return Integer is
+
+ Tmp : Integer := FI;
+
+ begin
+
+ I := I + 1;
+ if (FI /= Tmp) then
+ Failed ("Assignment to scalar actual function " &
+ "parameter changes the value of " &
+ "input parameter");
+ end if;
+
+ return (100);
+ end F;
+
+ begin -- (B)
+ I := 100;
+ J := F (I);
+ end; -- (B)
+
+ --------------------------------------------------
+
+ declare -- (C)
+
+ type Acctype is access Integer;
+
+ I,J,K : Natural := Report.Ident_Int(2); -- Index values.
+ Arr : array (1 .. 5) of Acctype;
+ E : exception;
+
+ procedure P (PI : in Acctype;
+ PO : out Acctype;
+ PIO : in out Acctype) is
+
+ Tmp : Acctype;
+
+ begin
+
+ Tmp := PI; -- Save value of PI at procedure entry.
+
+ Arr(I) := new Integer'(101);
+ if (PI /= Tmp) then
+ Failed ("Assignment to access actual " &
+ "parameter changes the value of " &
+ "input parameter");
+ Tmp := PI; -- Reset Tmp for next case.
+ end if;
+
+ PO := new Integer'(1);
+ if (PI /= Tmp) then
+ Failed ("Assignment to access out " &
+ "parameter changes the value of " &
+ "input parameter");
+ Tmp := PI; -- Reset Tmp for next case.
+ end if;
+
+ PIO := new Integer'(10);
+ if (PI /= Tmp) then
+ Failed ("Assignment to access in out " &
+ "parameter changes the value of " &
+ "input parameter");
+ end if;
+
+ raise E; -- Check exception handling.
+ end P;
+
+ begin -- (C)
+ Arr(I) := new Integer'(100);
+ P (Arr(I), Arr(J), Arr(K));
+ Failed ("Exception not raised - C");
+ exception
+ when E =>
+ if (Arr(I).all /= 101) then
+ Failed ("Out or in out actual procedure " &
+ "parameter value changed despite " &
+ "raised exception");
+ end if;
+ when others =>
+ Failed ("Wrong exception raised - C");
+ end; -- (C)
+
+ --------------------------------------------------
+
+ declare -- (D)
+
+ Type Acctype is access Integer;
+
+ I,J : Acctype;
+
+ function F (FI : in Acctype) return Acctype is
+
+ Tmp : Acctype := FI;
+
+ begin
+
+ I := new Integer;
+ if (FI /= Tmp) then
+ Failed ("Assignment to access actual function " &
+ "parameter changes the value of " &
+ "Input parameter");
+ end if;
+
+ return null;
+ end F;
+
+ begin -- (D)
+ I := null;
+ J := F(I);
+ end; -- (D)
+
+ --------------------------------------------------
+
+ declare -- (E)
+
+ I,J,K : Natural := Report.Ident_Int(3); -- Index values.
+ Arr : array (1 .. 3) of Float;
+ E : exception;
+
+ procedure P (PI : in Float;
+ PO : out Float;
+ PIO : in out Float) is
+
+ Tmp : Float;
+
+ begin
+
+ Tmp := PI; -- Save value of PI at procedure entry.
+
+ PO := 0.5;
+ if (PI /= Tmp) then
+ Failed ("Assignement to float out " &
+ "parameter changes the value of " &
+ "input parameter");
+ Tmp := PI; -- Reset Tmp for next case.
+ end if;
+
+ PIO := PIO + 0.25;
+ if (PI /= Tmp) then
+ Failed ("Assignment to float in out " &
+ "parameter changes the value of " &
+ "inputparameter");
+ Tmp := PI; -- Reset Tmp for next case.
+ end if;
+
+ Arr(I) := Arr(I) + 1.0;
+ if (PI /= Tmp) then
+ Failed ("Assignment to float actual " &
+ "parameter changes the value of " &
+ "input parameter");
+ end if;
+
+ raise E; -- Check exception handling.
+ end P;
+
+ begin -- (E)
+ Arr := (others => 0.0);
+ P (Arr(I), Arr(J), Arr(K));
+ Failed ("Exception not raised - E");
+ exception
+ when E =>
+ if (Arr(I) /= 1.0) then
+ Failed ("Out or in out actual procedure " &
+ "parameter value changed despite " &
+ "raised exception");
+ end if;
+ when others =>
+ Failed ("Wrong exception raised - E");
+ end; -- (E)
+
+ --------------------------------------------------
+
+ declare -- (F)
+
+ I,J : Float;
+
+ function F (FI : in Float) return Float is
+
+ Tmp : Float := FI;
+
+ begin
+
+ I := I + 1.0;
+ if (FI /= Tmp) then
+ Failed ("Assignment to float actual function " &
+ "parameter changes the value of " &
+ "input parameter");
+ end if;
+
+ return 100.0;
+ end F;
+
+ begin -- (F)
+ I := 100.0;
+ J := F (I);
+ end; -- (F)
+
+ --------------------------------------------------
+
+ Result;
+
+end C620001;
diff --git a/gcc/testsuite/ada/acats/tests/c6/c620002.a b/gcc/testsuite/ada/acats/tests/c6/c620002.a
new file mode 100644
index 0000000..b46a04e
--- /dev/null
+++ b/gcc/testsuite/ada/acats/tests/c6/c620002.a
@@ -0,0 +1,509 @@
+-- C620001.A
+
+-- Grant of Unlimited Rights
+--
+-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
+-- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
+-- unlimited rights in the software and documentation contained herein.
+-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
+-- this public release, the Government intends to confer upon all
+-- recipients unlimited rights equal to those held by the Government.
+-- These rights include rights to use, duplicate, release or disclose the
+-- released technical data and computer software in whole or in part, in
+-- any manner and for any purpose whatsoever, and to have or permit others
+-- to do so.
+--
+-- DISCLAIMER
+--
+-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
+-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
+-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
+-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
+-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
+-- PARTICULAR PURPOSE OF SAID MATERIAL.
+--*
+-- OBJECTIVE:
+-- Check that elementary parameters are passed by copy.
+--
+-- Part 2: Integer, float, and access types, task and protected entries.
+--
+-- TEST DESCRIPTION:
+-- Subtests are:
+-- (A) Scalar parameters to task entries.
+-- (B) Scalar parameters to protected entries.
+-- (C) Access parameters to task entries.
+-- (D) Access parameters to protected entries.
+--
+-- For all of these examples, we pass array elements indexed by dynamically
+-- determined indexes. Doing this side-steps the check of 6.4.1(6.15/3) and
+-- makes the test more realistic.
+--
+-- Note: This is based on legacy test C95072A.ADA (which was withdrawn).
+--
+-- CHANGE HISTORY:
+-- 22 Jul 1985 DAS Created test.
+-- 12 May 2020 RLB Revised so test cases are legal for Ada 2012, modernized
+-- objective, converted to modern format, added float
+-- and protected cases.
+
+with Report;
+procedure C620002 is
+
+ use Report;
+
+begin
+ Test ("C620002", "Check that elementary parameters are passed by copy," &
+ " part 2 - task and protected entries");
+
+ --------------------------------------------------
+
+ declare -- (A)
+
+ I,J,K : Natural := Report.Ident_Int (1); -- Index values.
+ Arr : array (1 .. 4) of Integer;
+ E : exception;
+
+ task TA is
+ entry EA (EI : in Integer;
+ EO : out Integer;
+ EIO : in out Integer);
+ end TA;
+
+ task body TA is
+
+ Tmp : Integer;
+
+ begin
+
+ accept EA (EI : in Integer;
+ EO : out Integer;
+ EIO : in out Integer) do
+
+ Tmp := EI; -- Save value of EI at accept.
+
+ EO := 10;
+ if EI /= Tmp then
+ Failed ("Assignement to scalar out " &
+ "parameter changes the value of " &
+ "input parameter - A");
+ Tmp := EI; -- Reset Tmp for next case.
+ end if;
+
+ EIO := EIO + 100;
+ if EI /= Tmp then
+ Failed ("Assignment to scalar in out " &
+ "parameter changes the value of " &
+ "input parameter - A");
+ Tmp := EI; -- Reset Tmp for next case.
+ end if;
+
+ Arr(I) := Arr(I) + 1;
+ if EI /= Tmp then
+ Failed ("Assignment to scalar actual " &
+ "parameter changes the value of " &
+ "input parameter - A");
+ end if;
+
+ raise E; -- Check exception handling.
+ end EA;
+
+ exception
+ when others => null;
+ end TA;
+
+ begin -- (A)
+ Arr := (others => 0);
+ TA.EA (Arr(I), Arr(J), Arr(K));
+ Failed ("Exception not raised - A");
+ exception
+ when E =>
+ if Arr(I) /= 1 then
+ case Arr(I) is
+ when 11 =>
+ Failed ("Out actual scalar parameter " &
+ "changed global value - A");
+ when 101 =>
+ Failed ("In out actual scalar " &
+ "parameter changed global value - A");
+ when 111 =>
+ Failed ("Out and in out actual scalar " &
+ "parameters changed global " &
+ "value - A");
+ when others =>
+ Failed ("Undetermined change to global " &
+ "value - A");
+ end case;
+ end if;
+ when others =>
+ Failed ("Wrong exception raised - A");
+ end; -- (A)
+
+ --------------------------------------------------
+
+ declare -- (B)
+
+ I,J,K : Natural := Report.Ident_Int (3); -- Index values.
+ Arr : array (1 .. 5) of Integer;
+ E : exception;
+
+ protected PA is
+ entry EA (EI : in Integer;
+ EO : out Integer;
+ EIO : in out Integer);
+ end PA;
+
+ protected body PA is
+
+ entry EA (EI : in Integer;
+ EO : out Integer;
+ EIO : in out Integer) when True is
+
+ Tmp : Integer;
+
+ begin
+
+ Tmp := EI; -- Save value of EI at entry.
+
+ EO := 10;
+ if EI /= Tmp then
+ Failed ("Assignement to scalar out " &
+ "parameter changes the value of " &
+ "input parameter - B");
+ Tmp := EI; -- Reset Tmp for next case.
+ end if;
+
+ EIO := EIO + 100;
+ if EI /= Tmp then
+ Failed ("Assignment to scalar in out " &
+ "parameter changes the value of " &
+ "input parameter - B");
+ Tmp := EI; -- Reset Tmp for next case.
+ end if;
+
+ Arr(I) := Arr(I) + 1;
+ if EI /= Tmp then
+ Failed ("Assignment to scalar actual " &
+ "parameter changes the value of " &
+ "input parameter - B");
+ end if;
+
+ raise E; -- Check exception handling.
+ end EA;
+
+ end PA;
+
+ begin -- (B)
+ Arr := (others => 0);
+ PA.EA (Arr(I), Arr(J), Arr(K));
+ Failed ("Exception not raised - B");
+ exception
+ when E =>
+ if Arr(I) /= 1 then
+ case Arr(I) is
+ when 11 =>
+ Failed ("Out actual scalar parameter " &
+ "changed global value - B");
+ when 101 =>
+ Failed ("In out actual scalar " &
+ "parameter changed global value - B");
+ when 111 =>
+ Failed ("Out and in out actual scalar " &
+ "parameters changed global " &
+ "value - B");
+ when others =>
+ Failed ("Undetermined change to global " &
+ "value - B");
+ end case;
+ end if;
+ when others =>
+ Failed ("Wrong exception raised - B");
+ end; -- (B)
+
+ --------------------------------------------------
+
+ declare -- (C)
+
+ type Acctype is access Integer;
+
+ I,J,K : Natural := Report.Ident_Int (2); -- Index values.
+ Arr : array (1 .. 5) of Acctype;
+ E : exception;
+
+ task TB is
+ entry EB (EI : in Acctype;
+ EO : out Acctype;
+ EIO : in out Acctype);
+ end TB;
+
+ task body TB is
+
+ Tmp : Acctype;
+
+ begin
+
+ accept EB (EI : in Acctype;
+ EO : out Acctype;
+ EIO : in out Acctype) do
+
+ Tmp := EI; -- Save value of EI at accept.
+
+ Arr(I) := new Integer'(101);
+ if EI /= Tmp then
+ Failed ("Assignment to access actual " &
+ "parameter changes the value of " &
+ "input parameter - C");
+ Tmp := EI; -- Reset Tmp for next case.
+ end if;
+
+ EO := new Integer'(1);
+ if EI /= Tmp then
+ Failed ("Assignment to access out " &
+ "parameter changes the value of " &
+ "input parameter - C");
+ Tmp := EI; -- Reset Tmp for next case.
+ end if;
+
+ EIO := new Integer'(10);
+ if EI /= Tmp then
+ Failed ("Assignment to access in out " &
+ "parameter changes the value of " &
+ "input parameter - C");
+ end if;
+
+ raise E; -- Check exception handling.
+ end EB;
+
+ exception
+ when others => null;
+ end TB;
+
+ begin -- (C)
+ Arr(I) := new Integer'(100);
+ TB.EB (Arr(I), Arr(J), Arr(K));
+ Failed ("Exception not raised - C");
+ exception
+ when E =>
+ if (Arr(I).all /= 101) then
+ Failed ("Out or in out actual " &
+ "parameter value changed despite " &
+ "raised exception - C");
+ end if;
+ when others =>
+ Failed ("Wrong exception raised - C");
+ end; -- (C)
+
+ --------------------------------------------------
+
+ declare -- (D)
+
+ type Acctype is access Integer;
+
+ I,J,K : Natural := Report.Ident_Int (4); -- Index values.
+ Arr : array (1 .. 6) of Acctype;
+ E : exception;
+
+ protected PB is
+ entry EB (EI : in Acctype;
+ EO : out Acctype;
+ EIO : in out Acctype);
+ end PB;
+
+ protected body PB is
+
+ entry EB (EI : in Acctype;
+ EO : out Acctype;
+ EIO : in out Acctype) when True is
+
+ Tmp : Acctype;
+
+ begin
+ Tmp := EI; -- Save value of EI at entry.
+
+ Arr(I) := new Integer'(101);
+ if EI /= Tmp then
+ Failed ("Assignment to access actual " &
+ "parameter changes the value of " &
+ "input parameter - D");
+ Tmp := EI; -- Reset Tmp for next case.
+ end if;
+
+ EO := new Integer'(1);
+ if EI /= Tmp then
+ Failed ("Assignment to access out " &
+ "parameter changes the value of " &
+ "input parameter - D");
+ Tmp := EI; -- Reset Tmp for next case.
+ end if;
+
+ EIO := new Integer'(10);
+ if EI /= Tmp then
+ Failed ("Assignment to access in out " &
+ "parameter changes the value of " &
+ "input parameter - D");
+ end if;
+
+ raise E; -- Check exception handling.
+ end EB;
+
+ end PB;
+
+ begin -- (D)
+ Arr(I) := new Integer'(100);
+ PB.EB (Arr(I), Arr(J), Arr(K));
+ Failed ("Exception not raised - D");
+ exception
+ when E =>
+ if (Arr(I).all /= 101) then
+ Failed ("Out or in out actual " &
+ "parameter value changed despite " &
+ "raised exception - D");
+ end if;
+ when others =>
+ Failed ("Wrong exception raised - D");
+ end; -- (D)
+
+ --------------------------------------------------
+
+ declare -- (E)
+
+ I,J,K : Natural := Report.Ident_Int (3); -- Index values.
+ Arr : array (1 .. 3) of Float;
+ E : exception;
+
+ task TC is
+ entry EC (EI : in Float;
+ EO : out Float;
+ EIO : in out Float);
+ end TC;
+
+ task body TC is
+
+ Tmp : Float;
+
+ begin
+
+ accept EC (EI : in Float;
+ EO : out Float;
+ EIO : in out Float) do
+
+ Tmp := EI; -- Save value of EI at accept.
+
+ EO := 0.5;
+ if EI /= Tmp then
+ Failed ("Assignement to float out " &
+ "parameter changes the value of " &
+ "input parameter - E");
+ Tmp := EI; -- Reset Tmp for next case.
+ end if;
+
+ EIO := EIO + 0.25;
+ if EI /= Tmp then
+ Failed ("Assignment to float in out " &
+ "parameter changes the value of " &
+ "input parameter - E");
+ Tmp := EI; -- Reset Tmp for next case.
+ end if;
+
+ Arr(I) := Arr(I) + 1.0;
+ if EI /= Tmp then
+ Failed ("Assignment to float actual " &
+ "parameter changes the value of " &
+ "input parameter - E");
+ end if;
+
+ raise E; -- Check exception handling.
+ end EC;
+
+ exception
+ when others => null;
+ end TC;
+
+ begin -- (E)
+ Arr := (others => 0.0);
+ TC.EC (Arr(I), Arr(J), Arr(K));
+ Failed ("Exception not raised - E");
+ exception
+ when E =>
+ if (Arr(I) /= 1.0) then
+ Failed ("Out or in out actual procedure " &
+ "parameter value changed despite " &
+ "raised exception - E");
+ end if;
+ when others =>
+ Failed ("Wrong exception raised - E");
+ end; -- (E)
+
+ --------------------------------------------------
+
+ declare -- (F)
+
+ I,J,K : Natural := Report.Ident_Int (6); -- Index values.
+ Arr : array (1 .. 7) of Float;
+ E : exception;
+
+ protected PC is
+ entry EC (EI : in Float;
+ EO : out Float;
+ EIO : in out Float);
+ end PC;
+
+ protected body PC is
+
+ entry EC (EI : in Float;
+ EO : out Float;
+ EIO : in out Float) when True is
+
+ Tmp : Float;
+
+ begin
+
+ Tmp := EI; -- Save value of EI at entry.
+
+ EO := 0.5;
+ if EI /= Tmp then
+ Failed ("Assignement to float out " &
+ "parameter changes the value of " &
+ "input parameter - F");
+ Tmp := EI; -- Reset Tmp for next case.
+ end if;
+
+ EIO := EIO + 0.25;
+ if EI /= Tmp then
+ Failed ("Assignment to float in out " &
+ "parameter changes the value of " &
+ "input parameter - F");
+ Tmp := EI; -- Reset Tmp for next case.
+ end if;
+
+ Arr(I) := Arr(I) + 1.0;
+ if EI /= Tmp then
+ Failed ("Assignment to float actual " &
+ "parameter changes the value of " &
+ "input parameter - F");
+ end if;
+
+ raise E; -- Check exception handling.
+ end EC;
+
+ end PC;
+
+ begin -- (F)
+ Arr := (others => 0.0);
+ PC.EC (Arr(I), Arr(J), Arr(K));
+ Failed ("Exception not raised - F");
+ exception
+ when E =>
+ if (Arr(I) /= 1.0) then
+ Failed ("Out or in out actual procedure " &
+ "parameter value changed despite " &
+ "raised exception - F");
+ end if;
+ when others =>
+ Failed ("Wrong exception raised - F");
+ end; -- (F)
+
+ --------------------------------------------------
+
+ Result;
+
+end C620002;
diff --git a/gcc/testsuite/ada/acats/tests/c7/c761006.a b/gcc/testsuite/ada/acats/tests/c7/c761006.a
index 771e625..5cf4d89 100644
--- a/gcc/testsuite/ada/acats/tests/c7/c761006.a
+++ b/gcc/testsuite/ada/acats/tests/c7/c761006.a
@@ -55,6 +55,9 @@
-- 01 DEC 97 EDS Made correction wrt RM 7.6(21)
-- 16 MAR 01 RLB Corrected Adjust cases to avoid problems with
-- RM 7.6.1(16/1) from Technical Corrigendum 1.
+-- 05 JUL 12 RLB Redid Unchecked_Deallocation case to handle
+-- the fact that the behavior is unspecified (see
+-- AI95-0179-1). Also fixed indentation.
--
--!
@@ -346,23 +349,39 @@ procedure C761006 is
-- finalization of Item/Target should cause PE
end Finalize_15;
- -- check failure in finalize due to Unchecked_Deallocation
+ -- check failure in finalize due to Unchecked_Deallocation
- type Shark is access C761006_2.Fin_Check;
+ procedure Finalize_17_Outer is
+ -- This procedure exists to make Shark local, so everything allocated
+ -- on it will be finalized when this routine exits.
- procedure Catch is
- new Unchecked_Deallocation( C761006_2.Fin_Check, Shark );
+ type Shark is access C761006_2.Fin_Check;
- procedure Finalize_17 is
- White : Shark := new C761006_2.Fin_Check;
- begin
- Catch( White );
- exception
- when Program_Error =>
+ procedure Catch is
+ new Unchecked_Deallocation( C761006_2.Fin_Check, Shark );
+
+ procedure Finalize_17_Inner is
+ White : Shark := new C761006_2.Fin_Check;
+ begin
+ Catch (White);
+ -- Note: It is unspecified if Catch deallocates the memory
+ -- of the allocated object, and if it ceases to exist.
+ -- As such, it is possible that it will be finalized when
+ -- the scope of the access type is exited. We check for this
+ -- case below.
+ exception
+ when Program_Error =>
if not Sup.Events_Occurring(Sup.Good_Finalize) then
Report.Failed("Unchecked_Deallocation: " & Fin_Not_Perf);
end if;
- end Finalize_17;
+ end Finalize_17_Inner;
+
+ begin
+ Finalize_17_Inner;
+ exception
+ when others =>
+ Report.Failed("Unchecked_Deallocation check, unwanted exception in Outer");
+ end Finalize_17_Outer;
begin
@@ -373,10 +392,12 @@ procedure C761006 is
end Exception_In_Finalization;
Use_Of_Unchecked_Deallocation: begin
- Finalize_17;
+ Finalize_17_Outer;
exception
+ when Program_Error =>
+ Report.Comment("Unchecked_Deallocation check, double finalization occurred");
when others =>
- Report.Failed("Unchecked_Deallocation check, unwanted exception");
+ Report.Failed("Unchecked_Deallocation check, unwanted exception in caller");
end Use_Of_Unchecked_Deallocation;
end Finalize_Test;
diff --git a/gcc/testsuite/ada/acats/tests/c9/c96004a.ada b/gcc/testsuite/ada/acats/tests/c9/c96004a.ada
index f5357fc..b1f769b 100644
--- a/gcc/testsuite/ada/acats/tests/c9/c96004a.ada
+++ b/gcc/testsuite/ada/acats/tests/c9/c96004a.ada
@@ -3,22 +3,22 @@
-- Grant of Unlimited Rights
--
-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
--- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
+-- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
-- unlimited rights in the software and documentation contained herein.
--- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
--- this public release, the Government intends to confer upon all
--- recipients unlimited rights equal to those held by the Government.
--- These rights include rights to use, duplicate, release or disclose the
--- released technical data and computer software in whole or in part, in
--- any manner and for any purpose whatsoever, and to have or permit others
+-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
+-- this public release, the Government intends to confer upon all
+-- recipients unlimited rights equal to those held by the Government.
+-- These rights include rights to use, duplicate, release or disclose the
+-- released technical data and computer software in whole or in part, in
+-- any manner and for any purpose whatsoever, and to have or permit others
-- to do so.
--
-- DISCLAIMER
--
-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
--- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
+-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
--- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
+-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
-- PARTICULAR PURPOSE OF SAID MATERIAL.
--*
@@ -35,6 +35,8 @@
-- CPP 08/15/84 CREATED ORIGINAL TEST.
-- JET 01/06/88 UPDATED HEADER FORMAT AND ADDED CODE TO PREVENT
-- OPTIMIZATION.
+-- RLB 12/18/06 Changed so that the test will work for Ada 2005
+-- implementations.
WITH CALENDAR; USE CALENDAR;
WITH REPORT; USE REPORT;
@@ -92,15 +94,35 @@ BEGIN
END;
BEGIN
- YR := IDENT_INT(YEAR_NUMBER'LAST + 1);
- FAILED ("EXCEPTION NOT RAISED - (A)3");
+ YR := IDENT_INT(2100);
IF NOT EQUAL (YR, YR) THEN
COMMENT ("NO EXCEPTION RAISED");
END IF;
-
+ BEGIN
+ YR := 2399;
+ IF NOT EQUAL (YR, YR) THEN
+ COMMENT ("NO EXCEPTION RAISED");
+ END IF;
+
+ EXCEPTION
+ WHEN OTHERS =>
+ FAILED ("ADA 2005 CASE RAISED EXCEPTION ON 2399 - (A)");
+ END;
+ BEGIN
+ YR := IDENT_INT(2400);
+ IF NOT EQUAL (YR, YR) THEN
+ COMMENT ("NO EXCEPTION RAISED");
+ END IF;
+ FAILED ("EXCEPTION NOT RAISED - (A)3");
+ EXCEPTION
+ WHEN CONSTRAINT_ERROR =>
+ Comment ("Upper bound of Year_Number is appropriate" &
+ " for Ada 2005");
+ END;
EXCEPTION
WHEN CONSTRAINT_ERROR =>
- NULL;
+ Comment ("Upper bound of Year_Number is appropriate" &
+ " for Ada 95");
WHEN OTHERS =>
FAILED ("WRONG EXCEPTION RAISED - (A)3");
END;
diff --git a/gcc/testsuite/ada/acats/tests/c9/c96007a.ada b/gcc/testsuite/ada/acats/tests/c9/c96007a.ada
index beda25f..15ac5e9 100644
--- a/gcc/testsuite/ada/acats/tests/c9/c96007a.ada
+++ b/gcc/testsuite/ada/acats/tests/c9/c96007a.ada
@@ -3,22 +3,22 @@
-- Grant of Unlimited Rights
--
-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
--- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
+-- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
-- unlimited rights in the software and documentation contained herein.
--- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
--- this public release, the Government intends to confer upon all
--- recipients unlimited rights equal to those held by the Government.
--- These rights include rights to use, duplicate, release or disclose the
--- released technical data and computer software in whole or in part, in
--- any manner and for any purpose whatsoever, and to have or permit others
+-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
+-- this public release, the Government intends to confer upon all
+-- recipients unlimited rights equal to those held by the Government.
+-- These rights include rights to use, duplicate, release or disclose the
+-- released technical data and computer software in whole or in part, in
+-- any manner and for any purpose whatsoever, and to have or permit others
-- to do so.
--
-- DISCLAIMER
--
-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
--- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
+-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
--- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
+-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
-- PARTICULAR PURPOSE OF SAID MATERIAL.
--*
@@ -27,7 +27,9 @@
-- (A) TIME_ERROR IS RAISED ON INVALID DATES.
-- (B) CONSTRAINT_ERROR IS RAISED FOR OUT-OF-RANGE PARAMETERS.
--- CPP 8/16/84
+-- CPP 8/16/84
+-- RLB 12/18/06 - Changed so that the test will work for Ada 2005
+-- implementations.
WITH CALENDAR; USE CALENDAR;
WITH REPORT; USE REPORT;
@@ -136,13 +138,13 @@ BEGIN
END;
BEGIN
- BAD_TIME := TIME_OF (YEAR_NUMBER'LAST + 1, 8, 13);
- FAILED ("EXCEPTION NOT RAISED - 2100 (B)");
+ BAD_TIME := TIME_OF (YEAR_NUMBER'LAST+1, 8, 13);
+ FAILED ("EXCEPTION NOT RAISED - YEAR_NUM'LAST+1 (B)");
EXCEPTION
WHEN CONSTRAINT_ERROR =>
NULL;
WHEN OTHERS =>
- FAILED ("WRONG EXCEPTION RAISED - 2100 (B)");
+ FAILED ("WRONG EXCEPTION RAISED - YEAR_NUM'LAST+1 (B)");
END;
BEGIN
diff --git a/gcc/testsuite/ada/acats/tests/cb/cb41004.a b/gcc/testsuite/ada/acats/tests/cb/cb41004.a
index 5a7b704..b73ed8f 100644
--- a/gcc/testsuite/ada/acats/tests/cb/cb41004.a
+++ b/gcc/testsuite/ada/acats/tests/cb/cb41004.a
@@ -56,10 +56,8 @@
-- 06 Dec 94 SAIC ACVC 2.0
-- 08 Dec 00 RLB Removed Exception_Identity subtest, pending
-- resolution of AI95-00241.
--- Notes for future: Replace Exception_Identity
--- subtest with whatever the resolution is.
--- Add a subtest for Exception_Name(Null_Id), which
--- is missing from this test.
+-- 29 Mar 07 RLB Replaced Exception_Identity subtest, repaired
+-- Raise_Exception subtest for AI95-00446.
--!
with Report;
@@ -96,6 +94,29 @@ begin
end if;
+ -- Verify that Raise_Exception has no effect in the case of Null_Id.
+ -- Modified by AI-446.
+ begin
+ Ada.Exceptions.Raise_Exception(A_Null_Exception_Id);
+ Report.Comment(
+ "No exception raised by procedure Raise_Exception " &
+ "when called with a Null_Id input parameter - compatible with " &
+ "original Ada95");
+ exception
+ when Constraint_Error => null; -- OK, expected exception.
+ Report.Comment(
+ "Constraint_Error exception raised by procedure Raise_Exception " &
+ "when called with a Null_Id input parameter - compatible with " &
+ "AI95-00446");
+ when others =>
+ Report.Failed(
+ "Unexpected exception raised by procedure Raise_Exception " &
+ "when called with a Null_Id input parameter");
+ end;
+
+ TC_Flag := False;
+
+
-- Verify that Reraise_Occurrence has no effect in the case of
-- Null_Occurrence.
begin
@@ -135,26 +156,30 @@ begin
end;
--- -- Verify that function Exception_Identity raises Constraint_Error for
--- -- a Null_Occurrence input parameter.
--- -- Note: (RLB, 2000/12/08) This behavior may be modified by AI-00241.
--- -- As such, this test case has been removed pending a resolution.
--- begin
--- declare
--- Id : Ada.Exceptions.Exception_Id :=
--- Ada.Exceptions.Exception_Identity(A_Null_Exception_Occurrence);
--- begin
--- Report.Failed
--- ("Constraint_Error not raised by Function Exception_Identity " &
--- "when called with a Null_Occurrence input parameter");
--- end;
--- exception
--- when Constraint_Error => null; -- OK, expected exception.
--- when others =>
--- Report.Failed
--- ("Unexpected exception raised by Function Exception_Identity " &
--- "when called with a Null_Occurrence input parameter");
--- end;
+ -- Verify that function Exception_Identity raises Constraint_Error for
+ -- a Null_Occurrence input parameter.
+ -- Modified by AI-241.
+ begin
+ declare
+ Id : Ada.Exceptions.Exception_Id :=
+ Ada.Exceptions.Exception_Identity(A_Null_Exception_Occurrence);
+ begin
+ Report.Comment
+ ("No exception raised by Function Exception_Identity " &
+ "when called with a Null_Occurrence input parameter - " &
+ "compatible with AI95-00241.");
+ end;
+ exception
+ when Constraint_Error =>
+ Report.Comment
+ ("Constraint_Error raised by Function Exception_Identity " &
+ "when called with a Null_Occurrence input parameter - " &
+ "compatible with original Ada95.");
+ when others =>
+ Report.Failed
+ ("Unexpected exception raised by Function Exception_Identity " &
+ "when called with a Null_Occurrence input parameter");
+ end;
-- Verify that function Exception_Name raises Constraint_Error for
diff --git a/gcc/testsuite/ada/acats/tests/cc/cc3016f.ada b/gcc/testsuite/ada/acats/tests/cc/cc3016f.ada
index 9a1f099..ef94672 100644
--- a/gcc/testsuite/ada/acats/tests/cc/cc3016f.ada
+++ b/gcc/testsuite/ada/acats/tests/cc/cc3016f.ada
@@ -3,26 +3,25 @@
-- Grant of Unlimited Rights
--
-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
--- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
+-- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
-- unlimited rights in the software and documentation contained herein.
--- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
--- this public release, the Government intends to confer upon all
--- recipients unlimited rights equal to those held by the Government.
--- These rights include rights to use, duplicate, release or disclose the
--- released technical data and computer software in whole or in part, in
--- any manner and for any purpose whatsoever, and to have or permit others
+-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
+-- this public release, the Government intends to confer upon all
+-- recipients unlimited rights equal to those held by the Government.
+-- These rights include rights to use, duplicate, release or disclose the
+-- released technical data and computer software in whole or in part, in
+-- any manner and for any purpose whatsoever, and to have or permit others
-- to do so.
--
-- DISCLAIMER
--
-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
--- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
+-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
--- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
+-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
-- PARTICULAR PURPOSE OF SAID MATERIAL.
--*
--- OFFICE, 3E 114, THE PENTAGON, WASHINGTON DC 20301-3081.
-- OBJECTIVE:
-- CHECK THAT AN INSTANTIATED PACKAGE HAS THE PROPERTIES REQUIRED
diff --git a/gcc/testsuite/ada/acats/tests/cd/cd30011.a b/gcc/testsuite/ada/acats/tests/cd/cd30011.a
new file mode 100644
index 0000000..2cd96a4
--- /dev/null
+++ b/gcc/testsuite/ada/acats/tests/cd/cd30011.a
@@ -0,0 +1,155 @@
+-- CD30011.A
+
+-- Grant of Unlimited Rights
+--
+-- The Ada Conformity Assessment Authority (ACAA) holds unlimited
+-- rights in the software and documentation contained herein. Unlimited
+-- rights are the same as those granted by the U.S. Government for older
+-- parts of the Ada Conformity Assessment Test Suite, and are defined
+-- in DFAR 252.227-7013(a)(19). By making this public release, the ACAA
+-- intends to confer upon all recipients unlimited rights equal to those
+-- held by the ACAA. These rights include rights to use, duplicate,
+-- release or disclose the released technical data and computer software
+-- in whole or in part, in any manner and for any purpose whatsoever, and
+-- to have or permit others to do so.
+--
+-- DISCLAIMER
+--
+-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
+-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
+-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
+-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
+-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
+-- PARTICULAR PURPOSE OF SAID MATERIAL.
+--
+-- Notice
+--
+-- The ACAA has created and maintains the Ada Conformity Assessment Test
+-- Suite for the purpose of conformity assessments conducted in accordance
+-- with the International Standard ISO/IEC 18009 - Ada: Conformity
+-- assessment of a language processor. This test suite should not be used
+-- to make claims of conformance unless used in accordance with
+-- ISO/IEC 18009 and any applicable ACAA procedures.
+--
+--*
+-- OBJECTIVE:
+-- Check that a size specification can be given by an attribute definition
+-- clause for an enumeration type:
+-- * in the visible or private part of a package for a type declared
+-- in the visible part;
+-- * for a derived enumeration type;
+-- * for a derived private type whose full declaration is an
+-- enumeration type.
+--
+-- TEST DESCRIPTION:
+-- This test was created from legacy tests CD1009B and CD2A31C. The
+-- objective of CD1009B was also an objective of CD2A31C; the tests
+-- were merged to eliminate duplication and add appropriate applicability
+-- criteria.
+--
+-- APPLICABILITY CRITERIA:
+-- All implementations must attempt to compile this test.
+--
+-- For implementations validating against Systems Programming Annex (C):
+-- this test must execute and report PASSED.
+--
+-- or implementations not validating against Annex C:
+-- this test may report compile time errors at one or more points
+-- indicated by "-- ANX-C RQMT", in which case it may be graded as
+-- inapplicable. Otherwise, the test must execute and report PASSED.
+--
+-- CHANGE HISTORY:
+-- 17 Jun 87 PWB Created original test CD2A21C.
+-- 07 Oct 87 VCL Created original test CD1009B.
+-- 17 Apr 89 DHH Changed extension from '.DEP' TO '.ADA', changed
+-- operators on 'Size tests, and added check on
+-- representation clause.
+-- 26 Mar 92 JRL Removed testing of nonobjective types.
+-- 29 Mar 17 RLB Created test from CD2A21C and CD1009B; reformatted
+-- to "modern" standards, added applicability criteria.
+
+with Report; use Report;
+with Length_Check; -- CONTAINS A CALL TO 'Failed'.
+procedure CD30011 is
+
+ type Basic_Enum is (A, B, C, D, E);
+ Specified_Size : constant := Basic_Enum'Size;
+
+ Minimum_Size : Integer := Report.Ident_Int (Specified_Size);
+
+ type Derived_Enum is new Basic_Enum;
+ for Derived_Enum'Size use Specified_Size; -- ANX-C RQMT.
+
+ package P is
+ type Enum_in_P is (A1, B1, C1, D1, E1, F1, G1);
+ for Enum_in_P'Size use Specified_Size; -- ANX-C RQMT.
+ type private_Enum is private;
+ type Alt_Enum_in_P is (A2, B2, C2, D2, E2, F2, G2);
+ private
+ type private_Enum is (A3, B3, C3, D3, E3, F3, G3);
+ for Alt_Enum_in_P'Size use Specified_Size; -- ANX-C RQMT.
+ end P;
+
+ type Derived_Private_Enum is new P.Private_Enum;
+ for Derived_Private_Enum'Size use Specified_Size; -- ANX-C RQMT.
+
+ use P;
+
+ procedure Check_1 is new Length_Check (Derived_Enum);
+ procedure Check_2 is new Length_Check (Enum_in_P);
+ procedure Check_3 is new Length_Check (Alt_Enum_in_P);
+
+ X : Enum_in_P := A1;
+ Y : Alt_Enum_in_P := A2;
+
+begin
+
+ Report.Test ("CD30011", "Check that 'Size attribute definition clauses " &
+ "can be given in the visible or private part " &
+ "of a package for enumeration types declared " &
+ "declared in the visible part, and for derived " &
+ "enumeration types and derived private types " &
+ "whose full declarations are as enumeration types");
+
+ Check_1 (C, Specified_Size, "Derived_Enum");
+ Check_2 (C1, Specified_Size, "Enum_in_P");
+ Check_3 (C2, Specified_Size, "Alt_Enum_in_P");
+
+ if Derived_Enum'Size /= Minimum_Size then
+ Failed ("Derived_Enum'Size should not be greater than" &
+ Integer'Image (Minimum_Size) & ". Actual Size is" &
+ Integer'Image (Derived_Enum'Size));
+ end if;
+
+ if Enum_in_P'Size /= Minimum_Size then
+ Failed ("Enum_in_P'Size should not be greater than" &
+ Integer'Image (Minimum_Size) & ". Actual Size is" &
+ Integer'Image (Enum_in_P'Size));
+ end if;
+
+ if Alt_Enum_in_P'Size /= Minimum_Size then
+ Failed ("Alt_Enum_in_P'Size should not be greater than" &
+ Integer'Image (Minimum_Size) & ". Actual Size is" &
+ Integer'Image (Alt_Enum_in_P'Size));
+ end if;
+
+ if Derived_Private_Enum'Size /= Minimum_Size then
+
+ Failed ("Derived_Private_Enum'Size should not be greater " &
+ "than " & Integer'Image (Minimum_Size) & ". Actual Size is" &
+ Integer'Image (Derived_Private_Enum'Size));
+ end if;
+
+ if X'Size < Specified_Size then
+ Failed ("Object'Size is too small --" &
+ Enum_in_P'Image (X));
+ end if;
+
+ if Y'Size < Specified_Size then
+ Failed ("Object'Size is too small --" &
+ Alt_Enum_in_P'Image (Y));
+ end if;
+
+ Report.Result;
+
+end CD30011;
diff --git a/gcc/testsuite/ada/acats/tests/cd/cd30012.a b/gcc/testsuite/ada/acats/tests/cd/cd30012.a
new file mode 100644
index 0000000..a55dfbd
--- /dev/null
+++ b/gcc/testsuite/ada/acats/tests/cd/cd30012.a
@@ -0,0 +1,173 @@
+-- CD30012.A
+
+-- Grant of Unlimited Rights
+--
+-- The Ada Conformity Assessment Authority (ACAA) holds unlimited
+-- rights in the software and documentation contained herein. Unlimited
+-- rights are the same as those granted by the U.S. Government for older
+-- parts of the Ada Conformity Assessment Test Suite, and are defined
+-- in DFAR 252.227-7013(a)(19). By making this public release, the ACAA
+-- intends to confer upon all recipients unlimited rights equal to those
+-- held by the ACAA. These rights include rights to use, duplicate,
+-- release or disclose the released technical data and computer software
+-- in whole or in part, in any manner and for any purpose whatsoever, and
+-- to have or permit others to do so.
+--
+-- DISCLAIMER
+--
+-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
+-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
+-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
+-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
+-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
+-- PARTICULAR PURPOSE OF SAID MATERIAL.
+--
+-- Notice
+--
+-- The ACAA has created and maintains the Ada Conformity Assessment Test
+-- Suite for the purpose of conformity assessments conducted in accordance
+-- with the International Standard ISO/IEC 18009 - Ada: Conformity
+-- assessment of a language processor. This test suite should not be used
+-- to make claims of conformance unless used in accordance with
+-- ISO/IEC 18009 and any applicable ACAA procedures.
+--
+--*
+-- OBJECTIVE:
+-- Check that a size specification can be given by an attribute definition
+-- clause for an integer type:
+-- * in the visible or private part of a package for a type declared
+-- in the visible part;
+-- * for a derived integer type;
+-- * for a derived private type whose full declaration is an
+-- integer type.
+--
+-- TEST DESCRIPTION:
+-- This test was created from legacy tests CD1009B and CD2A31C. The
+-- objective of CD1009B was also an objective of CD30012; the tests
+-- were merged to eliminate duplication and add appropriate applicability
+-- criteria.
+--
+-- APPLICABILITY CRITERIA:
+-- All implementations must attempt to compile this test.
+--
+-- For implementations validating against Systems Programming Annex (C):
+-- this test must execute and report PASSED.
+--
+-- or implementations not validating against Annex C:
+-- this test may report compile time errors at one or more points
+-- indicated by "-- ANX-C RQMT", in which case it may be graded as
+-- inapplicable. Otherwise, the test must execute and report PASSED.
+--
+-- CHANGE HISTORY:
+-- 17 Jun 87 PWB Created original test CD2A31C.
+-- 09 Sep 87 VCL Created original test CD1009A.
+-- 06 Apr 89 DHH Changed extension from '.DEP' TO '.ADA', changed
+-- size clause value to 9, and added representation
+-- clause check and included test for for integer in a
+-- generic unit.
+-- 27 Mar 92 JRL Removed testing of nonobjective types.
+-- 17 Jun 92 DTN Removed the length clause for type Private_Int.
+-- 29 Mar 17 RLB Created test from CD2A31C and CD1009A; reformatted
+-- to "modern" standards, added applicability criteria,
+-- removed nonobjective packed array.
+
+with Report; use Report;
+with Length_Check; -- Contains a call to 'Failed'.
+procedure CD30012 is
+
+ type Basic_Int is range -60 .. 80;
+ Specified_Size : constant := 9;
+
+ type Derived_Int is new Basic_Int;
+ for Derived_Int'Size use Specified_Size; -- ANX-C RQMT.
+
+ package P is
+ type Int_in_P is range -125 .. 125;
+ for Int_in_P'Size use Specified_Size; -- ANX-C RQMT.
+ type Private_Int is private;
+ type Alt_Int_in_P is range -125 .. 125;
+ private
+ type Private_Int is range -125 .. 125;
+ for Alt_Int_in_P'Size use Specified_Size; -- ANX-C RQMT.
+ end P;
+
+ use P;
+ type Derived_Private_Int is new Private_Int;
+ for Derived_Private_Int'Size use Specified_Size; -- ANX-C RQMT.
+ Minimum_Size : Integer := Report.Ident_Int (Specified_Size);
+
+ -- Size specification given in a generic procedure:
+
+ generic
+ procedure Genproc;
+
+ procedure Genproc is
+ type Check_Int is range -125 .. 125;
+ for Check_Int'Size use Specified_Size; -- ANX-C RQMT.
+
+ procedure Check_4 is new Length_Check (Check_Int);
+
+ begin
+
+ if Check_Int'Size /= Minimum_Size then
+ Failed ("Generic Check_Int'Size is incorrect");
+ end if;
+ Check_4 (-60, 9, "generic Check_Int");
+
+ end Genproc;
+
+ procedure Newproc is new Genproc;
+
+ procedure Check_1 is new Length_Check (Derived_Int);
+ procedure Check_2 is new Length_Check (Int_in_P);
+ procedure Check_3 is new Length_Check (Alt_Int_in_P);
+
+ Obj1 : Int_in_P := 92;
+ Obj2 : Alt_Int_in_P := 52;
+
+begin
+
+ Report.Test ("CD30012", "Check that 'Size attribute definition clauses " &
+ "can be given in the visible or private part " &
+ "of a package for integer types declared " &
+ "declared in the visible part, and for derived " &
+ "integer types and derived private types " &
+ "whose full declarations are as integer types");
+
+ Check_1 (-60, 9, "Derived_Int");
+ Check_2 (-60, 9, "Int_in_P");
+ Check_3 (-60, 9, "Alt_Int_in_P");
+ Check_2 (Obj1, 9, "Int_in_P");
+ Check_3 (Obj2, 9, "Alt_Int_in_P");
+
+ Newproc;
+
+ if Derived_Int'Size /= Minimum_Size then
+ Failed ("Derived_Int'Size incorrect");
+ end if;
+
+ if Int_in_P'Size /= Minimum_Size then
+ Failed ("Int_in_P'Size incorrect");
+ end if;
+
+ if Alt_Int_in_P'Size /= Minimum_Size then
+ Failed ("Alt_Int_in_P'Size incorrect");
+ end if;
+
+ if Derived_Private_Int'Size /= Minimum_Size then
+ Failed ("Derived_Private_Int'Size incorrect");
+ end if;
+
+ if Obj1'Size < Specified_Size then
+ Failed ("Object'Size is too small --" &
+ Int_in_P'Image (Obj1));
+ end if;
+
+ if Obj2'Size < Specified_Size then
+ Failed ("Object'Size is too small --" &
+ Alt_Int_in_P'Image (Obj2));
+ end if;
+
+ Report.Result;
+
+end CD30012;
diff --git a/gcc/testsuite/ada/acats/tests/cd/cd90001.a b/gcc/testsuite/ada/acats/tests/cd/cd90001.a
index bd5c070..3f3bd89 100644
--- a/gcc/testsuite/ada/acats/tests/cd/cd90001.a
+++ b/gcc/testsuite/ada/acats/tests/cd/cd90001.a
@@ -3,22 +3,22 @@
-- Grant of Unlimited Rights
--
-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
--- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
+-- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
-- unlimited rights in the software and documentation contained herein.
--- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
--- this public release, the Government intends to confer upon all
--- recipients unlimited rights equal to those held by the Government.
--- These rights include rights to use, duplicate, release or disclose the
--- released technical data and computer software in whole or in part, in
--- any manner and for any purpose whatsoever, and to have or permit others
+-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
+-- this public release, the Government intends to confer upon all
+-- recipients unlimited rights equal to those held by the Government.
+-- These rights include rights to use, duplicate, release or disclose the
+-- released technical data and computer software in whole or in part, in
+-- any manner and for any purpose whatsoever, and to have or permit others
-- to do so.
--
-- DISCLAIMER
--
-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
--- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
+-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
--- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
+-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
-- PARTICULAR PURPOSE OF SAID MATERIAL.
--*
@@ -26,11 +26,11 @@
-- OBJECTIVE:
-- Check that Unchecked_Conversion is supported and is reversible in
-- the cases where:
--- Source'Size = Target'Size
--- Source'Alignment = Target'Alignment
--- Source and Target are both represented contiguously
+-- Source'Size = Target'Size
+-- Source'Alignment = Target'Alignment
+-- Source and Target are both represented contiguously
-- Bit pattern in Source is a meaningful value of Target type
---
+--
-- TEST DESCRIPTION:
-- This test declares an enumeration type with a representation
-- specification that should fit neatly into an 8 bit object; and a
@@ -61,6 +61,7 @@
-- 27 JUL 96 SAIC Allowed for partial N/A to be PASS
-- 14 FEB 97 PWB.CTA Corrected "=" to "/=" in alignment check.
-- 16 FEB 98 EDS Modified documentation.
+-- 21 DEC 05 RLB Corrected "=" to "/=" in other alignment check.
--!
----------------------------------------------------------------- CD90001_0
@@ -136,7 +137,7 @@ package body CD90001_0 is
Report.Failed ("EU => EB conversion failed");
end if;
- end loop;
+ end loop;
end TC_Check_Case_1;
procedure TC_Check_Case_2 is
@@ -209,7 +210,7 @@ begin -- Main test procedure.
Report.Comment("The sizes of the 16 bit types used in this test "
& "do not match" );
Sixteen_NA := True;
- elsif CD90001_0.Signed_16'Alignment = CD90001_0.Bits_16'Alignment then
+ elsif CD90001_0.Signed_16'Alignment /= CD90001_0.Bits_16'Alignment then
Report.Comment("The alignments of the 16 bit types used in this "
& "test do not match" );
Sixteen_NA := True;
diff --git a/gcc/testsuite/ada/acats/tests/cxa/cxa3004.a b/gcc/testsuite/ada/acats/tests/cxa/cxa3004.a
new file mode 100644
index 0000000..ed2023e
--- /dev/null
+++ b/gcc/testsuite/ada/acats/tests/cxa/cxa3004.a
@@ -0,0 +1,235 @@
+-- CXA3004.A
+--
+-- Grant of Unlimited Rights
+--
+-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
+-- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
+-- unlimited rights in the software and documentation contained herein.
+-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
+-- this public release, the Government intends to confer upon all
+-- recipients unlimited rights equal to those held by the Government.
+-- These rights include rights to use, duplicate, release or disclose the
+-- released technical data and computer software in whole or in part, in
+-- any manner and for any purpose whatsoever, and to have or permit others
+-- to do so.
+--
+-- DISCLAIMER
+--
+-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
+-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
+-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
+-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
+-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
+-- PARTICULAR PURPOSE OF SAID MATERIAL.
+--*
+--
+-- OBJECTIVE:
+-- Check that the functions defined in package Ada.Characters.Handling
+-- for classification of and conversion between Wide_Character and
+-- Character values produce correct results when given the appropriate
+-- Character and String inputs.
+--
+-- TEST DESCRIPTION:
+-- This test demonstrates the functions defined in package
+-- Ada.Characters.Handling which provide for the classification of and
+-- conversion between Wide_Characters and Characters, in character
+-- variables and strings.
+-- Each of the functions is provided with input values that are of the
+-- appropriate range. The results of the function processing are
+-- subsequently evaluated.
+--
+-- APPLICABILITY CRITERIA:
+-- Applicable to all implementations using the Latin_1 set as the
+-- definition of Character.
+--
+--
+-- CHANGE HISTORY:
+-- 06 Dec 94 SAIC ACVC 2.0
+-- 27 Dec 94 SAIC Corrected variable names.
+--
+--!
+
+with Report;
+with Ada.Characters.Handling;
+
+procedure CXA3004 is
+begin
+
+ Report.Test ("CXA3004", "Check that the functions defined in package " &
+ "Ada.Characters.Handling for classification " &
+ "of and conversion between Wide_Character and " &
+ "Character values produce correct results " &
+ "when given the appropriate Character " &
+ "and String inputs");
+
+ Test_Block:
+ declare
+
+ package ACH renames Ada.Characters.Handling;
+
+ Char_End : Integer := 255;
+ WC_Start : Integer := 256;
+ Sub_Char : Character := '*';
+
+ Blank : Character := ' ';
+ First_Char : Character := Character'First;
+ Last_Char : Character := Character'Last;
+ F_Char : Character := 'F';
+
+
+ First_Wide_Char : Wide_Character := Wide_Character'First;
+ Last_Non_Wide_Char : Wide_Character := Wide_Character'Val(Char_End);
+ First_Unique_Wide_Char : Wide_Character := Wide_Character'Val(WC_Start);
+ Last_Wide_Char : Wide_Character := Wide_Character'Last;
+
+ A_String : String (1..3) := First_Char & 'X' & Last_Char;
+ A_Wide_String : Wide_String (1..3) := First_Wide_Char &
+ ACH.To_Wide_Character('X') &
+ ACH.To_Wide_Character(Last_Char);
+
+ Unique_Wide_String : Wide_String (1..2) := First_Unique_Wide_Char &
+ Last_Wide_Char;
+
+ Mixed_Wide_String : Wide_String (1..6) := ACH.To_Wide_Character('A') &
+ First_Wide_Char &
+ Last_Non_Wide_Char &
+ First_Unique_Wide_Char &
+ Last_Wide_Char &
+ ACH.To_Wide_Character('Z');
+
+
+ Basic_Char : Character := 'A';
+ Basic_Wide_Char : Wide_Character := 'A';
+ Basic_String : String (1..6) := "ABCXYZ";
+ Basic_Wide_String : Wide_String (1..6) := "ABCXYZ";
+
+ begin
+
+
+ -- Function Is_Character
+
+
+ if not ACH.Is_Character(First_Wide_Char) then
+ Report.Failed ("Incorrect result from Is_Character - 1");
+ end if;
+
+
+ if ACH.Is_Character(First_Unique_Wide_Char) or
+ ACH.Is_Character(Last_Wide_Char)
+ then
+ Report.Failed ("Incorrect result from Is_Character - 2");
+ end if;
+
+
+ -- Function Is_String
+
+
+ if not ACH.Is_String(A_Wide_String) then
+ Report.Failed ("Incorrect result from Is_String - 1");
+ end if;
+
+
+ if ACH.Is_String(Unique_Wide_String) or
+ ACH.Is_String(Mixed_Wide_String)
+ then
+ Report.Failed ("Incorrect result from Is_String - 2");
+ end if;
+
+
+ -- Function To_Character
+
+
+ -- Use default substitution character in call of To_Character.
+
+ if ACH.To_Character(First_Wide_Char) /= First_Char or
+ ACH.To_Character(Last_Non_Wide_Char) /= Last_Char
+ then
+ Report.Failed ("Incorrect result from To_Character - 1");
+ end if;
+
+
+ -- Provide a substitution character for use with To_Character.
+
+ if ACH.To_Character(First_Unique_Wide_Char, Blank) /= Blank or
+ ACH.To_Character(First_Unique_Wide_Char, Sub_Char) /= Sub_Char or
+ ACH.To_Character(Last_Wide_Char) /= ' ' -- default
+ then
+ Report.Failed ("Incorrect result from To_Character - 2");
+ end if;
+
+
+ -- Function To_String
+
+
+ if ACH.To_String(A_Wide_String) /= A_String then
+ Report.Failed ("Incorrect result from To_String - 1");
+ end if;
+
+
+ if ACH.To_String(Unique_Wide_String, Sub_Char) /= "**" then
+ Report.Failed ("Incorrect result from To_String - 2");
+ end if;
+
+
+
+ if ACH.To_String(Mixed_Wide_String, Sub_Char) /=
+ ('A' & First_Char & Last_Char & "**" & 'Z') or
+ ACH.To_String(Mixed_Wide_String, Sub_Char) /=
+ (ACH.To_Character(Mixed_Wide_String(1), Sub_Char) &
+ ACH.To_Character(Mixed_Wide_String(2), Sub_Char) &
+ ACH.To_Character(Mixed_Wide_String(3), Sub_Char) &
+ ACH.To_Character(Mixed_Wide_String(4), Sub_Char) &
+ ACH.To_Character(Mixed_Wide_String(5), Sub_Char) &
+ ACH.To_Character(Mixed_Wide_String(6), Sub_Char))
+ then
+ Report.Failed ("Incorrect result from To_String - 3");
+ end if;
+
+
+ -- Function To_Wide_Character
+
+
+ if ACH.To_Wide_Character(Basic_Char) /= Basic_Wide_Char then
+ Report.Failed ("Incorrect result from To_Wide_Character");
+ end if;
+
+
+ -- Function To_Wide_String
+
+
+ if not (ACH.To_Wide_String(Basic_String) = Basic_Wide_String) then
+ Report.Failed ("Incorrect result from To_Wide_String");
+ end if;
+
+
+ -- Functions Used In Combination
+
+ if not ACH.Is_Character (ACH.To_Wide_Character (
+ ACH.To_Character(First_Wide_Char)))
+ then
+ Report.Failed ("Incorrect result from functions in combination - 1");
+ end if;
+
+
+ if not ACH.Is_String(ACH.To_Wide_String(ACH.To_String(A_Wide_String)))
+ then
+ Report.Failed ("Incorrect result from functions in combination - 2");
+ end if;
+
+
+ if ACH.To_String(ACH.To_Wide_Character('A') &
+ ACH.To_Wide_Character(F_Char) &
+ ACH.To_Wide_Character('Z')) /= "AFZ"
+ then
+ Report.Failed ("Incorrect result from functions in combination - 3");
+ end if;
+
+
+ exception
+ when others => Report.Failed ("Exception raised in Test_Block");
+ end Test_Block;
+
+
+ Report.Result;
+
+end CXA3004;
diff --git a/gcc/testsuite/ada/acats/tests/cxa/cxa5013.a b/gcc/testsuite/ada/acats/tests/cxa/cxa5013.a
new file mode 100644
index 0000000..fe5b6e2
--- /dev/null
+++ b/gcc/testsuite/ada/acats/tests/cxa/cxa5013.a
@@ -0,0 +1,326 @@
+-- CXA5013.A
+--
+-- Grant of Unlimited Rights
+--
+-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
+-- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
+-- unlimited rights in the software and documentation contained herein.
+-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
+-- this public release, the Government intends to confer upon all
+-- recipients unlimited rights equal to those held by the Government.
+-- These rights include rights to use, duplicate, release or disclose the
+-- released technical data and computer software in whole or in part, in
+-- any manner and for any purpose whatsoever, and to have or permit others
+-- to do so.
+--
+-- DISCLAIMER
+--
+-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
+-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
+-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
+-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
+-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
+-- PARTICULAR PURPOSE OF SAID MATERIAL.
+--*
+--
+-- OBJECTIVE:
+-- Check that a discrete random number generator will yield each value
+-- in its result subtype in a finite number of calls, provided that
+-- the number of such values does not exceed 2**15.
+--
+-- TEST DESCRIPTION:
+-- This test demonstrates certain capabilities of the random number
+-- generator packages in Ada.Numerics. A generic subprogram is
+-- defined that will be instantiated to produce a total of two test
+-- subprograms.
+-- The area examined by this test is the production of random values
+-- over a discrete range. A generic procedure is instantiated with
+-- an instance of the Discrete_Random package, once for an integer type,
+-- and once for an enumeration type. The test procedure performs a
+-- test run, generating a specific number of random numbers over the
+-- range of the type. If this run did not generate each of the values
+-- in the type range, an asynchronous select statement is invoked. This
+-- select statement has a trigger statement delay for a specific
+-- (implementation defined) amount of time during which additional test
+-- runs will be performed.
+-- At the end of each run in this test, an evaluation is made to
+-- determine if each value in the range of possible values have been
+-- generated. At the conclusion of the runs, or if the specified test
+-- delay time expires, the test is concluded with a status value
+-- returned from the test procedure. An implementation is given three
+-- completely separate opportunities to run the test successfully, and
+-- if at the conclusion of all of these tests no successful result has
+-- been returned, the test is considered failed.
+--
+--
+-- CHANGE HISTORY:
+-- 27 Apr 95 SAIC Initial prerelease version.
+--
+--!
+
+with Ada.Numerics.Discrete_Random;
+with ImpDef;
+with Report;
+
+procedure CXA5013 is
+
+begin
+
+ Report.Test ("CXA5013", "Check that a discrete random number generator " &
+ "will yield each value in its result subtype " &
+ "in a finite number of calls");
+
+ Test_Block:
+ declare
+
+ use Ada.Numerics;
+
+ -- The following constant designed into the test creates a high
+ -- probability that a random series of numbers will satisfy the
+ -- requirements. Occasionally, even a random series of numbers
+ -- will fail. In such a case, the test will reset the random
+ -- number generator and rerun the test conditions. This constant
+ -- determines how many times the random number generator will be
+ -- reset before any individual test run is failed.
+
+ TC_Max_Random_Test_Runs : constant := 3;
+
+ -- The following constant will ensure that multiple attempts of the
+ -- complete set of tests are performed in the event of a failure of
+ -- a set of test runs.
+
+ TC_Finite_Number_Of_Tests : constant := 3;
+
+
+ TC_Test_Run : Integer := 0;
+ TC_Success : Boolean := False;
+ TC_Trials_Per_Test : Integer := 1500;
+
+ type Enum_Type is (One, Two, Three, Four, Five, Six, Seven);
+ type Discrete_Type is range 1..100;
+
+
+ package Enum_Pack is new Discrete_Random(Enum_Type);
+ package Discrete_Pack is
+ new Discrete_Random(Result_Subtype => Discrete_Type);
+
+
+
+ --
+ -- Definition of generic Random_Test procedure, which will be
+ -- instantiated for both an integer type and an enumeration type.
+ --
+
+ generic
+ with package Gen_Pack is new Ada.Numerics.Discrete_Random (<>);
+ procedure Random_Test (Trials_Per_Test : in Integer;
+ Success : out Boolean);
+
+
+ procedure Random_Test (Trials_Per_Test : in Integer;
+ Success : out Boolean) is
+ Total_Runs : Integer := 0;
+ Total_Trials : Integer := 0;
+ Total_Attempts_This_Test : Integer := 0;
+ Random_Array : array (Gen_Pack.Result_Subtype)
+ of Boolean := (others => False);
+ Gen : Gen_Pack.Generator;
+
+ function All_Values_Present return Boolean is
+ Result : Boolean := True;
+ begin
+ for i in Gen_Pack.Result_Subtype'Range loop
+ if not Random_Array(i) then
+ Result := False;
+ exit;
+ end if;
+ end loop;
+ return Result;
+ end All_Values_Present;
+
+ begin
+
+ Success := False; -- Initialized to failure prior to test.
+ Gen_Pack.Reset(Gen); -- Perform a time-dependent reset.
+
+ -- Guarantee that a specific minimum number of trials are performed
+ -- prior to the timer being set.
+
+ for i in 1..Trials_Per_Test loop
+ -- Set array element to True when a particular array
+ -- index is generated by the random number generator.
+ Random_Array(Gen_Pack.Random(Gen)) := True;
+ end loop;
+
+ if All_Values_Present then
+
+ Success := True; -- Test was successful, exit procedure with no
+ -- further testing performed.
+ else
+
+ -- Initial test above was unsuccessful, so set a timer and perform
+ -- additional trials to determine if all values in the discrete
+ -- range will be produced.
+
+ select
+
+ -- This asynchronous select has a triggering statement which
+ -- is a delay statement, set to an implementation defined
+ -- number of seconds for any particular test to execute.
+ -- The point here is to allow the implementation to decide
+ -- how long to run this test in order to generate an
+ -- appropriate (i.e., correct) sample from the Random Number
+ -- Generator.
+
+ delay ImpDef.Delay_Per_Random_Test; -- Delay per test.
+
+ -- If, after expiration of delay, the random number generator
+ -- has generated all values within the range at least once,
+ -- then the result is success; otherwise, a comment is output
+ -- to indicate that the random number generator was
+ -- unsuccessful in this series of test runs.
+
+ if All_Values_Present then
+ Success := True;
+ else
+ Total_Attempts_This_Test :=
+ Total_Runs * Trials_Per_Test + Total_Trials;
+ Report.Comment
+ ("Not all numbers within the Range were produced in " &
+ Integer'Image(
+ Integer(ImpDef.Delay_Per_Random_Test*1000.0)) &
+ " milliseconds or in " &
+ Integer'Image(Total_Attempts_This_Test) &
+ " trials during this test");
+ end if;
+
+ then abort
+
+ -- After setting the triggering statement above, the execution
+ -- of this abortable part is begun.
+ -- This loop continues until either a) every value has been
+ -- produced or b) the triggering statement times out.
+
+ Total_Runs := 1;
+
+ Test_Loop: -- This loop continues until a test run is
+ loop -- successful, the test run limit has been reached,
+ -- or the triggering statement times-out above.
+
+ Total_Trials := 0;
+
+ for i in 1..Trials_Per_Test loop
+ Total_Trials := i; -- Used above if triggering statement
+ -- completes prior to test completion.
+
+ -- Set array element to True when a particular array
+ -- index is generated by the random number generator.
+
+ Random_Array(Gen_Pack.Random(Gen)) := True;
+
+ end loop;
+
+ -- At the conclusion of a complete series of trials, the
+ -- following evaluation is performed to determine whether
+ -- the test run was successful, or whether an additional
+ -- test run should be re-attempted.
+
+ if All_Values_Present then
+ Success := True;
+ exit Test_Loop;
+ elsif Total_Runs = TC_Max_Random_Test_Runs then
+ Report.Comment
+ ("Not all numbers in the Range were produced in " &
+ Integer'Image(Total_Runs*Trials_Per_Test) &
+ " individual trials during this test");
+ exit Test_Loop;
+ else
+ Total_Runs := Total_Runs + 1;
+ end if;
+
+ end loop Test_Loop;
+ end select;
+ end if;
+ end Random_Test;
+
+
+
+ -- Instantiation of test procedures.
+
+ procedure Discrete_Random_Test is new Random_Test(Discrete_Pack);
+ procedure Enumeration_Random_Test is new Random_Test(Enum_Pack);
+
+
+ begin
+
+ -- Make a series of test runs, checking to ensure that discrete
+ -- random number generators produce each value in their result subtype
+ -- within a finite number of calls. In each case, if the first test
+ -- is not successful, another attempt is made, after a time-dependent
+ -- reset, up to a total of 3 runs. This allows an implementation
+ -- multiple opportunities to pass the test successfully.
+ -- Note: The odds of getting all 100 integer values in 1500 trials are
+ -- greater than 99.997 percent, confirmed by Monte Carlo
+ -- simulation.
+
+
+
+ -- Run the Random_Test for an integer discrete random number generator.
+
+ TC_Test_Run := 0;
+ TC_Success := False;
+ while TC_Test_Run < TC_Finite_Number_Of_Tests and
+ not TC_Success
+ loop
+ TC_Test_Run := TC_Test_Run + 1; -- Increment test counter.
+ Discrete_Random_Test (TC_Trials_Per_Test, -- Perform test.
+ TC_Success);
+ -- Increment the number of trials that will be performed
+ -- in the next test by 50%.
+ TC_Trials_Per_Test := TC_Trials_Per_Test + TC_Trials_Per_Test/2 ;
+ end loop;
+
+ if not TC_Success then
+ Report.Failed("Random_Test was run " & Integer'Image(TC_Test_Run) &
+ " times, but a successful result was not recorded " &
+ "from any run using the integer discrete random " &
+ "number generator");
+ end if;
+
+
+
+ -- Run the Random_Test for an enumeration type random number generator.
+
+ -- Note: The odds of getting all seven enumeration values in 100
+ -- trials are greater than 99.997 percent, confirmed by Monte
+ -- Carlo simulation.
+
+ TC_Test_Run := 0;
+ TC_Trials_Per_Test := 100;
+ TC_Success := False;
+ while TC_Test_Run < TC_Finite_Number_Of_Tests and
+ not TC_Success
+ loop
+ TC_Test_Run := TC_Test_Run + 1;
+ Enumeration_Random_Test (TC_Trials_Per_Test,
+ TC_Success);
+ -- Increment the number of trials that will be performed
+ -- in the next test by 50%.
+ TC_Trials_Per_Test := TC_Trials_Per_Test + TC_Trials_Per_Test/2 ;
+ end loop;
+
+ if not TC_Success then
+ Report.Failed("Random_Test was run " & Integer'Image(TC_Test_Run) &
+ " times, but a successful result was not recorded " &
+ "from any run using the enumeration random number " &
+ "generator");
+ end if;
+
+
+ exception
+ when others => Report.Failed ("Exception raised in Test_Block");
+ end Test_Block;
+
+ Report.Result;
+
+end CXA5013;
diff --git a/gcc/testsuite/ada/acats/tests/cxa/cxac005.a b/gcc/testsuite/ada/acats/tests/cxa/cxac005.a
index 34a971f..5032357 100644
--- a/gcc/testsuite/ada/acats/tests/cxa/cxac005.a
+++ b/gcc/testsuite/ada/acats/tests/cxa/cxac005.a
@@ -31,6 +31,7 @@
-- 12 FEB 2001 PHL Initial version.
-- 14 MAR 2001 RLB Readied for release; fixed Not_Applicable check
-- to terminate test gracefully.
+-- 05 MAR 2007 RLB Updated to avoid problems with return-by-reference.
--
--!
with Ada.Streams.Stream_Io;
@@ -53,7 +54,6 @@ procedure CXAC005 is
package Checked_Stream_Io is
type File_Type (Max_Size : Stream_Element_Count) is limited private;
- function Stream_Io_File (File : File_Type) return Stream_Io.File_Type;
procedure Create (File : in out File_Type;
Mode : in Stream_Io.File_Mode := Stream_Io.Out_File;
@@ -93,6 +93,8 @@ procedure CXAC005 is
function Index (File : in File_Type) return Stream_Io.Positive_Count;
+ function Size (File : in File_Type) return Stream_Io.Count;
+
procedure Set_Mode (File : in out File_Type;
Mode : in Stream_Io.File_Mode);
@@ -111,11 +113,6 @@ procedure CXAC005 is
use Stream_Io;
- function Stream_Io_File (File : File_Type) return Stream_Io.File_Type is
- begin
- return File.File;
- end Stream_Io_File;
-
procedure Create (File : in out File_Type;
Mode : in Stream_Io.File_Mode := Stream_Io.Out_File;
Name : in String := "";
@@ -244,6 +241,13 @@ procedure CXAC005 is
return New_Index;
end Index;
+ function Size (File : in File_Type) return Stream_Io.Count is
+ New_Size : constant Count := Stream_Io.Size (File.File);
+ begin
+ TC_Assert (New_Size <= Count(File.Max_Size), "File too large");
+ return New_Size;
+ end Size;
+
procedure Set_Mode (File : in out File_Type;
Mode : in Stream_Io.File_Mode) is
Old_Index : constant Count := File.Index;
@@ -268,7 +272,8 @@ procedure CXAC005 is
begin
- Test ("CXAC005", "Check that stream file positioning work as specified");
+ Report.Test ("CXAC005",
+ "Check that stream file positioning work as specified");
declare
Name : constant String := Legal_File_Name;
@@ -320,8 +325,7 @@ begin
-- Check the contents of the entire file.
declare
S : Stream_Element_Array
- (1 .. Stream_Element_Offset
- (Stream_Io.Size (Csio.Stream_Io_File (F))));
+ (1 .. Stream_Element_Offset (Csio.Size (F)));
begin
Csio.Reset (F, Stream_Io.In_File);
Csio.Read (F, S, Last);
@@ -330,7 +334,7 @@ begin
Csio.Delete (F);
end;
- Result;
+ Report.Result;
exception
when Incomplete =>
Report.Result;
diff --git a/gcc/testsuite/ada/acats/tests/cxb/cxb30061.am b/gcc/testsuite/ada/acats/tests/cxb/cxb30061.am
new file mode 100644
index 0000000..d31345a
--- /dev/null
+++ b/gcc/testsuite/ada/acats/tests/cxb/cxb30061.am
@@ -0,0 +1,404 @@
+-- CXB30061.AM
+--
+-- Grant of Unlimited Rights
+--
+-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
+-- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
+-- unlimited rights in the software and documentation contained herein.
+-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
+-- this public release, the Government intends to confer upon all
+-- recipients unlimited rights equal to those held by the Government.
+-- These rights include rights to use, duplicate, release or disclose the
+-- released technical data and computer software in whole or in part, in
+-- any manner and for any purpose whatsoever, and to have or permit others
+-- to do so.
+--
+-- DISCLAIMER
+--
+-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
+-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
+-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
+-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
+-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
+-- PARTICULAR PURPOSE OF SAID MATERIAL.
+--*
+--
+-- OBJECTIVE:
+-- Check that the function To_C maps between the Ada type Wide_Character
+-- and the C type wchar_t.
+--
+-- Check that the function To_Ada maps between the C type wchar_t and
+-- the Ada type Wide_Character.
+--
+-- Check that the function Is_Nul_Terminated returns True if the
+-- wchar_array parameter contains wide_nul, and otherwise False.
+--
+-- Check that the function To_C produces a correct wchar_array result,
+-- with lower bound of 0, and length dependent upon the Item and
+-- Append_Nul parameters.
+--
+-- Check that the function To_Ada produces a correct wide_string result,
+-- with lower bound of 1, and length dependent upon the Item and
+-- Trim_Nul parameters.
+--
+-- Check that the function To_Ada raises Terminator_Error if the
+-- parameter Trim_Nul is set to True, but the actual Item parameter
+-- does not contain the wide_nul wchar_t.
+--
+-- TEST DESCRIPTION:
+-- This test uses a variety of Wide_Character, wchar_t, Wide_String, and
+-- wchar_array objects to test versions of the To_C, To_Ada, and
+-- Is_Nul_Terminated functions.
+--
+-- This test assumes that the following characters are all included
+-- in the implementation defined type Interfaces.C.wchar_t:
+-- ' ', ',', '.', '0'..'9', 'a'..'z' and 'A'..'Z'.
+--
+-- APPLICABILITY CRITERIA:
+-- This test is applicable to all implementations that provide
+-- package Interfaces.C. If an implementation provides
+-- package Interfaces.C, this test must compile, execute, and
+-- report "PASSED".
+--
+-- SPECIAL REQUIREMENTS:
+-- The file CXB30060.C must be compiled with a C compiler.
+-- Implementation dialects of C may require alteration of
+-- the C program syntax (see individual C files).
+--
+-- Note that the compiled C code must be bound with the compiled Ada
+-- code to create an executable image. An implementation must provide
+-- the necessary commands to accomplish this.
+--
+-- Note that the C code included in CXB30060.C conforms
+-- to ANSI-C. Modifications to these files may be required for other
+-- C compilers. An implementation must provide the necessary
+-- modifications to satisfy the function requirements.
+--
+-- TEST FILES:
+-- The following files comprise this test:
+--
+-- CXB30060.C
+-- CXB30061.AM
+--
+-- CHANGE HISTORY:
+-- 07 Sep 95 SAIC Initial prerelease version.
+-- 09 May 96 SAIC Incorporated reviewer comments for ACVC 2.1.
+-- 13 Sep 99 RLB Replaced (bogus) Unchecked_Conversions with a
+-- C function character generator.
+--
+--!
+
+with Report;
+with Interfaces.C; -- N/A => ERROR
+with Ada.Characters.Latin_1;
+with Ada.Characters.Handling;
+with Ada.Exceptions;
+with Ada.Strings.Wide_Fixed;
+with Impdef;
+
+procedure CXB30061 is
+begin
+
+ Report.Test ("CXB3006", "Check that the functions To_C and To_Ada " &
+ "produce correct results");
+
+ Test_Block:
+ declare
+
+ use Interfaces, Interfaces.C;
+ use Ada.Characters, Ada.Characters.Latin_1, Ada.Characters.Handling;
+ use Ada.Strings.Wide_Fixed;
+
+ First_Character,
+ Last_Character : Character;
+ TC_wchar_t,
+ TC_Low_wchar_t,
+ TC_High_wchar_t : wchar_t := wchar_t'First;
+ TC_Wide_String : Wide_String(1..8) := (others => Wide_Character'First);
+ TC_wchar_array : wchar_array(0..7) := (others => C.wide_nul);
+
+ -- The function Char_Gen returns a character corresponding to its
+ -- argument.
+ -- Value 0 .. 9 ==> '0' .. '9'
+ -- Value 10 .. 19 ==> 'A' .. 'J'
+ -- Value 20 .. 29 ==> 'k' .. 't'
+ -- Value 30 ==> ' '
+ -- Value 31 ==> '.'
+ -- Value 32 ==> ','
+
+ function Char_Gen (Value : in int) return wchar_t;
+
+ -- Use the user-defined C function char_gen as a completion to the
+ -- function specification above.
+
+ pragma Import (Convention => C,
+ Entity => Char_Gen,
+ External_Name => Impdef.CXB30060_External_Name);
+
+ begin
+
+ -- Check that the functions To_C and To_Ada map between the Ada type
+ -- Wide_Character and the C type wchar_t.
+
+ if To_C(To_Wide_Character(Ada.Characters.Latin_1.NUL)) /=
+ Interfaces.C.wide_nul
+ then
+ Report.Failed("Incorrect result from To_C with NUL character input");
+ end if;
+
+ First_Character := Report.Ident_Char('k');
+ Last_Character := Report.Ident_Char('t');
+ for i in First_Character..Last_Character loop
+ if To_C(Item => To_Wide_Character(i)) /=
+ Char_Gen(Character'Pos(i) - Character'Pos('k') + 20)
+ then
+ Report.Failed("Incorrect result from To_C with lower case " &
+ "alphabetic wide character input");
+ end if;
+ end loop;
+
+ First_Character := Report.Ident_Char('A');
+ Last_Character := Report.Ident_Char('J');
+ for i in First_Character..Last_Character loop
+ if To_C(Item => To_Wide_Character(i)) /=
+ Char_Gen(Character'Pos(i) - Character'Pos('A') + 10)
+ then
+ Report.Failed("Incorrect result from To_C with upper case " &
+ "alphabetic wide character input");
+ end if;
+ end loop;
+
+ First_Character := Report.Ident_Char('0');
+ Last_Character := Report.Ident_Char('9');
+ for i in First_Character..Last_Character loop
+ if To_C(Item => To_Wide_Character(i)) /=
+ Char_Gen(Character'Pos(i) - Character'Pos('0'))
+ then
+ Report.Failed("Incorrect result from To_C with digit " &
+ "wide character input");
+ end if;
+ end loop;
+
+ if To_C(Item => To_Wide_Character(' ')) /= Char_Gen(30)
+ then
+ Report.Failed("Incorrect result from To_C with space " &
+ "wide character input");
+ end if;
+
+ if To_C(Item => To_Wide_Character('.')) /= Char_Gen(31)
+ then
+ Report.Failed("Incorrect result from To_C with dot " &
+ "wide character input");
+ end if;
+
+ if To_C(Item => To_Wide_Character(',')) /= Char_Gen(32)
+ then
+ Report.Failed("Incorrect result from To_C with comma " &
+ "wide character input");
+ end if;
+
+ if To_Ada(Interfaces.C.wide_nul) /=
+ To_Wide_Character(Ada.Characters.Latin_1.NUL)
+ then
+ Report.Failed("Incorrect result from To_Ada with wide_nul " &
+ "wchar_t input");
+ end if;
+
+ for Code in int range
+ int(Report.Ident_Int(20)) .. int(Report.Ident_Int(29)) loop
+ -- 'k' .. 't'
+ if To_Ada(Item => Char_Gen(Code)) /=
+ To_Wide_Character(Character'Val (Character'Pos('k') + (Code - 20)))
+ then
+ Report.Failed("Incorrect result from To_Ada with lower case " &
+ "alphabetic wchar_t input");
+ end if;
+ end loop;
+
+ for Code in int range
+ int(Report.Ident_Int(10)) .. int(Report.Ident_Int(19)) loop
+ -- 'A' .. 'J'
+ if To_Ada(Item => Char_Gen(Code)) /=
+ To_Wide_Character(Character'Val (Character'Pos('A') + (Code - 10)))
+ then
+ Report.Failed("Incorrect result from To_Ada with upper case " &
+ "alphabetic wchar_t input");
+ end if;
+ end loop;
+
+ for Code in int range
+ int(Report.Ident_Int(0)) .. int(Report.Ident_Int(9)) loop
+ -- '0' .. '9'
+ if To_Ada(Item => Char_Gen(Code)) /=
+ To_Wide_Character(Character'Val (Character'Pos('0') + (Code)))
+ then
+ Report.Failed("Incorrect result from To_Ada with digit " &
+ "wchar_t input");
+ end if;
+ end loop;
+
+ if To_Ada(Item => Char_Gen(30)) /= ' ' then
+ Report.Failed("Incorrect result from To_Ada with space " &
+ "char input");
+ end if;
+ if To_Ada(Item => Char_Gen(31)) /= '.' then
+ Report.Failed("Incorrect result from To_Ada with dot " &
+ "char input");
+ end if;
+ if To_Ada(Item => Char_Gen(32)) /= ',' then
+ Report.Failed("Incorrect result from To_Ada with comma " &
+ "char input");
+ end if;
+
+ -- Check that the function Is_Nul_Terminated produces correct results
+ -- whether or not the wchar_array argument contains the
+ -- Ada.Interfaces.C.wide_nul character.
+
+ TC_Wide_String := "abcdefgh";
+ if Is_Nul_Terminated(Item => To_C(TC_Wide_String, Append_Nul => False))
+ then
+ Report.Failed("Incorrect result from Is_Nul_Terminated when no " &
+ "wide_nul wchar_t is present");
+ end if;
+
+ if not Is_Nul_Terminated(To_C(TC_Wide_String, Append_Nul => True)) then
+ Report.Failed("Incorrect result from Is_Nul_Terminated when the " &
+ "wide_nul wchar_t is present");
+ end if;
+
+
+
+ -- Now that we've tested the character/char versions of To_Ada and To_C,
+ -- use them to test the string versions.
+
+ declare
+ i : size_t := 0;
+ j : integer := 1;
+ Incorrect_Conversion : Boolean := False;
+
+ TC_No_wide_nul : constant wchar_array := To_C(TC_Wide_String,
+ False);
+ TC_wide_nul_Appended : constant wchar_array := To_C(TC_Wide_String,
+ True);
+ begin
+
+ -- Check that the function To_C produces a wchar_array result with
+ -- lower bound of 0, and length dependent upon the Item and
+ -- Append_Nul parameters (if Append_Nul is True, length is
+ -- Item'Length + 1; if False, length is Item'Length).
+
+ if TC_No_wide_nul'First /= 0 or TC_wide_nul_Appended'First /= 0 then
+ Report.Failed("Incorrect lower bound from Function To_C");
+ end if;
+
+ if TC_No_wide_nul'Length /= TC_Wide_String'Length then
+ Report.Failed("Incorrect length returned from Function To_C " &
+ "when Append_Nul => False");
+ end if;
+
+ if TC_wide_nul_Appended'Length /= TC_Wide_String'Length + 1 then
+ Report.Failed("Incorrect length returned from Function To_C " &
+ "when Append_Nul => True");
+ end if;
+
+ if not Is_Nul_Terminated(TC_wide_nul_Appended) then
+ Report.Failed("No wide_nul appended to the wide_string " &
+ "parameter during conversion to wchar_array " &
+ "by function To_C");
+ end if;
+
+ for TC_char in Report.Ident_Char('a')..Report.Ident_Char('h') loop
+ if TC_No_wide_nul(i) /= To_C(To_Wide_Character(TC_char)) or
+ TC_wide_nul_Appended(i) /= To_C(To_Wide_Character(TC_char)) then
+ -- Use single character To_C.
+ Incorrect_Conversion := True;
+ end if;
+ i := i + 1;
+ end loop;
+
+ if Incorrect_Conversion then
+ Report.Failed("Incorrect result from To_C with wide_string input " &
+ "and wchar_array result");
+ end if;
+
+
+ -- Check that the function To_Ada produces a wide_string result with
+ -- lower bound of 1, and length dependent upon the Item and
+ -- Trim_Nul parameters (if Trim_Nul is False, length is Item'Length;
+ -- if False, length will be the length of the slice of Item prior to
+ -- the first wide_nul).
+
+ declare
+ TC_No_NUL_Wide_String : constant Wide_String :=
+ To_Ada(Item => TC_wide_nul_Appended, Trim_Nul => True);
+
+ TC_NUL_Appended_Wide_String : constant Wide_String :=
+ To_Ada(TC_wide_nul_Appended, False);
+
+ begin
+
+ if TC_No_NUL_Wide_String'First /= 1 or
+ TC_NUL_Appended_Wide_String'First /= 1
+ then
+ Report.Failed("Incorrect lower bound from Function To_Ada");
+ end if;
+
+ if TC_No_NUL_Wide_String'Length /= TC_Wide_String'Length then
+ Report.Failed("Incorrect length returned from Function " &
+ "To_Ada when Trim_Nul => True");
+ end if;
+
+ if TC_NUL_Appended_Wide_String'Length /=
+ TC_Wide_String'Length + 1
+ then
+ Report.Failed("Incorrect length returned from Function " &
+ "To_Ada when Trim_Nul => False");
+ end if;
+
+ for TC_Character in Wide_Character'('a') .. Wide_Character'('h') loop
+ if TC_No_NUL_Wide_String(j) /= TC_Character or
+ TC_NUL_Appended_Wide_String(j) /= TC_Character
+ then
+ Report.Failed("Incorrect result from To_Ada with " &
+ "char_array input, index = " &
+ Integer'Image(j));
+ end if;
+ j := j + 1;
+ end loop;
+
+ end;
+
+
+ -- Check that the function To_Ada raises Terminator_Error if the
+ -- parameter Trim_Nul is set to True, but the actual Item parameter
+ -- does not contain the wide_nul wchar_t.
+
+ begin
+ TC_Wide_String := To_Ada(TC_No_wide_nul, Trim_Nul => True);
+ Report.Failed("Terminator_Error not raised when Item " &
+ "parameter of To_Ada does not contain the " &
+ "wide_nul wchar_t, but parameter Trim_Nul " &
+ "=> True");
+ Report.Comment
+ (To_String(TC_Wide_String) & " printed to defeat optimization");
+ exception
+ when Terminator_Error => null; -- OK, expected exception.
+ when others =>
+ Report.Failed("Incorrect exception raised by function " &
+ "To_Ada when the Item parameter does not " &
+ "contain the wide_nul wchar_t, but " &
+ "parameter Trim_Nul => True");
+ end;
+
+ end;
+
+ exception
+ when The_Error : others =>
+ Report.Failed
+ ("The following exception was raised in the Test_Block: " &
+ Ada.Exceptions.Exception_Name(The_Error));
+ end Test_Block;
+
+ Report.Result;
+
+end CXB30061;
diff --git a/gcc/testsuite/ada/acats/tests/cxf/cxf2001.a b/gcc/testsuite/ada/acats/tests/cxf/cxf2001.a
index 96d0a0a..a9f4bb2 100644
--- a/gcc/testsuite/ada/acats/tests/cxf/cxf2001.a
+++ b/gcc/testsuite/ada/acats/tests/cxf/cxf2001.a
@@ -3,22 +3,22 @@
-- Grant of Unlimited Rights
--
-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
--- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
+-- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
-- unlimited rights in the software and documentation contained herein.
--- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
--- this public release, the Government intends to confer upon all
--- recipients unlimited rights equal to those held by the Government.
--- These rights include rights to use, duplicate, release or disclose the
--- released technical data and computer software in whole or in part, in
--- any manner and for any purpose whatsoever, and to have or permit others
+-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
+-- this public release, the Government intends to confer upon all
+-- recipients unlimited rights equal to those held by the Government.
+-- These rights include rights to use, duplicate, release or disclose the
+-- released technical data and computer software in whole or in part, in
+-- any manner and for any purpose whatsoever, and to have or permit others
-- to do so.
--
-- DISCLAIMER
--
-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
--- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
+-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
--- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
+-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
-- PARTICULAR PURPOSE OF SAID MATERIAL.
--*
@@ -31,33 +31,33 @@
--
-- TEST DESCRIPTION:
-- This test is designed to test the generic procedure Divide found in
--- package Ada.Decimal.
+-- package Ada.Decimal.
--
--- The table below attempts to portray the design approach used in this
+-- The table below attempts to portray the design approach used in this
-- test. There are three "dimensions" of concern:
-- 1) the delta value of the Quotient and Remainder types, shown as
-- column headers,
-- 2) specific choices for the Dividend and Divisor numerical values
-- (i.e., whether they yielded a repeating/non-terminating result,
--- or a terminating result ["exact"]), displayed on the left side
+-- or a terminating result ["exact"]), displayed on the left side
-- of the tables, and
-- 3) the delta for the Dividend and Divisor.
---
+--
-- Each row in the tables indicates a specific test case, showing the
-- specific quotient and remainder (under the appropriate Delta column)
-- for each combination of dividend and divisor values. Test cases
-- follow the top-to-bottom sequence shown in the tables.
---
+--
-- Most of the test case sets (same dividend/divisor combinations -
--- indicated by dashed horizontal lines in the tables) vary the
--- delta of the quotient and remainder types between test cases. This
+-- indicated by dashed horizontal lines in the tables) vary the
+-- delta of the quotient and remainder types between test cases. This
-- allows for an examination of how different deltas for a quotient
-- and/or remainder type can influence the results of a division with
-- identical dividend and divisor.
---
+--
-- Note: Test cases are performed for both Radix 10 and Radix 2 types.
---
---
+--
+--
-- Divid Divis Delta Delta Delta Delta Delta
-- (Delta)(Delta)| .1 | .01 | .001 | .0001 | .00001 |Test
-- |---|---|-----|-----|-----|-----|-----|-----|-----|-----|Case
@@ -88,14 +88,14 @@
-- ---------------------------------------------------------------------------
-- Divide by Zero| Raise Constraint_Error 41
-- ---------------------------------------------------------------------------
---
---
+--
+--
-- CHANGE HISTORY:
-- 06 Dec 94 SAIC ACVC 2.0
-- 29 Dec 94 SAIC Modified Radix 2 cases to match Radix 10 cases.
--- 03 Oct 95 RBKD Modified to fix incorrect remainder results
+-- 03 Oct 95 RBKD Modified to fix incorrect remainder results.
-- 15 Nov 95 SAIC Incorporated reviewer fixes for ACVC 2.0.1.
---
+-- 18 Dec 06 RLB Fixed failure message to have correct block name.
--!
with Report;
@@ -117,12 +117,12 @@ begin
-- Declare all types and variables used in the various blocks below
-- for all Radix 10 evaluations.
- type DT_1 is delta 1.0 digits 5;
- type DT_0_1 is delta 0.1 digits 10;
- type DT_0_01 is delta 0.01 digits 10;
- type DT_0_001 is delta 0.001 digits 10;
- type DT_0_0001 is delta 0.0001 digits 10;
- type DT_0_00001 is delta 0.00001 digits 10;
+ type DT_1 is delta 1.0 digits 5;
+ type DT_0_1 is delta 0.1 digits 10;
+ type DT_0_01 is delta 0.01 digits 10;
+ type DT_0_001 is delta 0.001 digits 10;
+ type DT_0_0001 is delta 0.0001 digits 10;
+ type DT_0_00001 is delta 0.00001 digits 10;
for DT_1'Machine_Radix use 10;
for DT_0_1'Machine_Radix use 10;
@@ -138,11 +138,11 @@ begin
Dd_0_0001, Dv_0_0001, Quot_0_0001, Rem_0_0001 : DT_0_0001 := 0.0;
Dd_0_00001, Dv_0_00001, Quot_0_00001, Rem_0_00001 : DT_0_00001 := 0.0;
- begin
+ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(Dividend_Type => DT_0_01,
Divisor_Type => DT_0_1,
Quotient_Type => DT_0_1,
@@ -158,7 +158,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_0_1, DT_0_1, DT_0_1);
begin
if TC_Verbose then Report.Comment("Case 2"); end if;
@@ -171,7 +171,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_0_1, DT_0_01, DT_0_001);
begin
if TC_Verbose then Report.Comment("Case 3"); end if;
@@ -184,7 +184,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_0_1, DT_0_01, DT_0_01);
begin
if TC_Verbose then Report.Comment("Case 4"); end if;
@@ -197,14 +197,14 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_0_1, DT_0_001, DT_0_0001);
begin
if TC_Verbose then Report.Comment("Case 5"); end if;
Dd_0_01 := DT_0_01(0.05); Dv_0_1 := DT_0_1(0.3);
Div(Dd_0_01, Dv_0_1, Quot_0_001, Rem_0_0001);
- if Quot_0_001 /= DT_0_001(0.166) or
- Rem_0_0001 /= DT_0_0001(0.0002)
+ if Quot_0_001 /= DT_0_001(0.166) or
+ Rem_0_0001 /= DT_0_0001(0.0002)
then
Report.Failed("Incorrect values returned, Case 5");
end if;
@@ -212,7 +212,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_1, DT_0_01, DT_0_0001);
begin
if TC_Verbose then Report.Comment("Case 6"); end if;
@@ -225,7 +225,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_1, DT_0_01, DT_0_001);
begin
if TC_Verbose then Report.Comment("Case 7"); end if;
@@ -238,7 +238,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_1, DT_0_01, DT_0_01);
begin
if TC_Verbose then Report.Comment("Case 8"); end if;
@@ -251,7 +251,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_1, DT_0_001, DT_0_001);
begin
if TC_Verbose then Report.Comment("Case 9"); end if;
@@ -264,7 +264,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_1, DT_0_001, DT_0_01);
begin
if TC_Verbose then Report.Comment("Case 10"); end if;
@@ -277,14 +277,14 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_1, DT_0_0001, DT_0_0001);
begin
if TC_Verbose then Report.Comment("Case 11"); end if;
Dd_0_01 := DT_0_01(0.15); Dv_1 := DT_1(20);
Div(Dd_0_01, Dv_1, Quot_0_0001, Rem_0_0001);
- if Quot_0_0001 /= DT_0_0001(0.0075) or
- Rem_0_0001 /= DT_0_0001(0.0)
+ if Quot_0_0001 /= DT_0_0001(0.0075) or
+ Rem_0_0001 /= DT_0_0001(0.0)
then
Report.Failed("Incorrect values returned, Case 11");
end if;
@@ -292,14 +292,14 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_00001, DT_0_1, DT_0_0001, DT_0_0001);
begin
if TC_Verbose then Report.Comment("Case 12"); end if;
Dd_0_00001 := DT_0_00001(0.03125); Dv_0_1 := DT_0_1(0.5);
Div(Dd_0_00001, Dv_0_1, Quot_0_0001, Rem_0_0001);
- if Quot_0_0001 /= DT_0_0001(0.0625) or
- Rem_0_0001 /= DT_0_0001(0.0)
+ if Quot_0_0001 /= DT_0_0001(0.0625) or
+ Rem_0_0001 /= DT_0_0001(0.0)
then
Report.Failed("Incorrect values returned, Case 12");
end if;
@@ -307,13 +307,13 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_00001, DT_0_1, DT_0_001, DT_0_00001);
begin
if TC_Verbose then Report.Comment("Case 13"); end if;
Dd_0_00001 := DT_0_00001(0.03125); Dv_0_1 := DT_0_1(0.5);
Div(Dd_0_00001, Dv_0_1, Quot_0_001, Rem_0_00001);
- if Quot_0_001 /= DT_0_001(0.062) or
+ if Quot_0_001 /= DT_0_001(0.062) or
Rem_0_00001 /= DT_0_00001(0.00025)
then
Report.Failed("Incorrect values returned, Case 13");
@@ -322,13 +322,13 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_00001, DT_0_1, DT_0_001, DT_0_0001);
begin
if TC_Verbose then Report.Comment("Case 14"); end if;
Dd_0_00001 := DT_0_00001(0.03125); Dv_0_1 := DT_0_1(0.5);
Div(Dd_0_00001, Dv_0_1, Quot_0_001, Rem_0_0001);
- if Quot_0_001 /= DT_0_001(0.062) or
+ if Quot_0_001 /= DT_0_001(0.062) or
Rem_0_0001 /= DT_0_0001(0.0002)
then
Report.Failed("Incorrect values returned, Case 14");
@@ -337,7 +337,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_00001, DT_0_1, DT_0_001, DT_0_001);
begin
if TC_Verbose then Report.Comment("Case 15"); end if;
@@ -351,7 +351,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_00001, DT_0_1, DT_0_001, DT_0_01);
begin
if TC_Verbose then Report.Comment("Case 16"); end if;
@@ -364,13 +364,13 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_00001, DT_0_1, DT_0_01, DT_0_00001);
begin
if TC_Verbose then Report.Comment("Case 17"); end if;
Dd_0_00001 := DT_0_00001(0.03125); Dv_0_1 := DT_0_1(0.5);
Div(Dd_0_00001, Dv_0_1, Quot_0_01, Rem_0_00001);
- if Quot_0_01 /= DT_0_01(0.06) or Rem_0_00001 /= DT_0_00001(0.00125)
+ if Quot_0_01 /= DT_0_01(0.06) or Rem_0_00001 /= DT_0_00001(0.00125)
then
Report.Failed("Incorrect values returned, Case 17");
end if;
@@ -378,13 +378,13 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_00001, DT_0_1, DT_0_01, DT_0_0001);
begin
if TC_Verbose then Report.Comment("Case 18"); end if;
Dd_0_00001 := DT_0_00001(0.03125); Dv_0_1 := DT_0_1(0.5);
Div(Dd_0_00001, Dv_0_1, Quot_0_01, Rem_0_0001);
- if Quot_0_01 /= DT_0_01(0.06) or Rem_0_0001 /= DT_0_0001(0.0012)
+ if Quot_0_01 /= DT_0_01(0.06) or Rem_0_0001 /= DT_0_0001(0.0012)
then
Report.Failed("Incorrect values returned, Case 18");
end if;
@@ -392,7 +392,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_00001, DT_0_1, DT_0_01, DT_0_001);
begin
if TC_Verbose then Report.Comment("Case 19"); end if;
@@ -405,7 +405,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_00001, DT_0_1, DT_0_01, DT_0_01);
begin
if TC_Verbose then Report.Comment("Case 20"); end if;
@@ -429,12 +429,12 @@ begin
-- Declare all types and variables used in the various blocks below
-- for all Radix 2 evaluations.
- type DT_1 is delta 1.0 digits 5;
- type DT_0_1 is delta 0.1 digits 10;
- type DT_0_01 is delta 0.01 digits 10;
- type DT_0_001 is delta 0.001 digits 10;
- type DT_0_0001 is delta 0.0001 digits 10;
- type DT_0_00001 is delta 0.00001 digits 10;
+ type DT_1 is delta 1.0 digits 5;
+ type DT_0_1 is delta 0.1 digits 10;
+ type DT_0_01 is delta 0.01 digits 10;
+ type DT_0_001 is delta 0.001 digits 10;
+ type DT_0_0001 is delta 0.0001 digits 10;
+ type DT_0_00001 is delta 0.00001 digits 10;
for DT_1'Machine_Radix use 2;
for DT_0_1'Machine_Radix use 2;
@@ -450,11 +450,11 @@ begin
Dd_0_0001, Dv_0_0001, Quot_0_0001, Rem_0_0001 : DT_0_0001 := 0.0;
Dd_0_00001, Dv_0_00001, Quot_0_00001, Rem_0_00001 : DT_0_00001 := 0.0;
- begin
+ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(Dividend_Type => DT_0_01,
Divisor_Type => DT_0_1,
Quotient_Type => DT_0_1,
@@ -470,7 +470,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_0_1, DT_0_1, DT_0_1);
begin
if TC_Verbose then Report.Comment("Case 22"); end if;
@@ -483,7 +483,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_0_1, DT_0_01, DT_0_001);
begin
if TC_Verbose then Report.Comment("Case 23"); end if;
@@ -496,7 +496,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_0_1, DT_0_01, DT_0_01);
begin
if TC_Verbose then Report.Comment("Case 24"); end if;
@@ -509,14 +509,14 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_0_1, DT_0_001, DT_0_0001);
begin
if TC_Verbose then Report.Comment("Case 25"); end if;
Dd_0_01 := DT_0_01(0.05); Dv_0_1 := DT_0_1(0.3);
Div(Dd_0_01, Dv_0_1, Quot_0_001, Rem_0_0001);
- if Quot_0_001 /= DT_0_001(0.166) or
- Rem_0_0001 /= DT_0_0001(0.0002)
+ if Quot_0_001 /= DT_0_001(0.166) or
+ Rem_0_0001 /= DT_0_0001(0.0002)
then
Report.Failed("Incorrect values returned, Case 25");
end if;
@@ -524,7 +524,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_1, DT_0_01, DT_0_0001);
begin
if TC_Verbose then Report.Comment("Case 26"); end if;
@@ -537,7 +537,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_1, DT_0_01, DT_0_001);
begin
if TC_Verbose then Report.Comment("Case 27"); end if;
@@ -550,7 +550,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_1, DT_0_01, DT_0_01);
begin
if TC_Verbose then Report.Comment("Case 28"); end if;
@@ -563,7 +563,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_1, DT_0_001, DT_0_001);
begin
if TC_Verbose then Report.Comment("Case 29"); end if;
@@ -576,7 +576,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_1, DT_0_001, DT_0_01);
begin
if TC_Verbose then Report.Comment("Case 30"); end if;
@@ -589,14 +589,14 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_01, DT_1, DT_0_0001, DT_0_0001);
begin
if TC_Verbose then Report.Comment("Case 31"); end if;
Dd_0_01 := DT_0_01(0.15); Dv_1 := DT_1(20);
Div(Dd_0_01, Dv_1, Quot_0_0001, Rem_0_0001);
- if Quot_0_0001 /= DT_0_0001(0.0075) or
- Rem_0_0001 /= DT_0_0001(0.0)
+ if Quot_0_0001 /= DT_0_0001(0.0075) or
+ Rem_0_0001 /= DT_0_0001(0.0)
then
Report.Failed("Incorrect values returned, Case 31");
end if;
@@ -604,14 +604,14 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_00001, DT_0_1, DT_0_0001, DT_0_0001);
begin
if TC_Verbose then Report.Comment("Case 32"); end if;
Dd_0_00001 := DT_0_00001(0.03125); Dv_0_1 := DT_0_1(0.5);
Div(Dd_0_00001, Dv_0_1, Quot_0_0001, Rem_0_0001);
- if Quot_0_0001 /= DT_0_0001(0.0625) or
- Rem_0_0001 /= DT_0_0001(0.0)
+ if Quot_0_0001 /= DT_0_0001(0.0625) or
+ Rem_0_0001 /= DT_0_0001(0.0)
then
Report.Failed("Incorrect values returned, Case 32");
end if;
@@ -619,13 +619,13 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_00001, DT_0_1, DT_0_001, DT_0_00001);
begin
if TC_Verbose then Report.Comment("Case 33"); end if;
Dd_0_00001 := DT_0_00001(0.03125); Dv_0_1 := DT_0_1(0.5);
Div(Dd_0_00001, Dv_0_1, Quot_0_001, Rem_0_00001);
- if Quot_0_001 /= DT_0_001(0.062) or
+ if Quot_0_001 /= DT_0_001(0.062) or
Rem_0_00001 /= DT_0_00001(0.00025)
then
Report.Failed("Incorrect values returned, Case 33");
@@ -634,13 +634,13 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_00001, DT_0_1, DT_0_001, DT_0_0001);
begin
if TC_Verbose then Report.Comment("Case 34"); end if;
Dd_0_00001 := DT_0_00001(0.03125); Dv_0_1 := DT_0_1(0.5);
Div(Dd_0_00001, Dv_0_1, Quot_0_001, Rem_0_0001);
- if Quot_0_001 /= DT_0_001(0.062) or
+ if Quot_0_001 /= DT_0_001(0.062) or
Rem_0_0001 /= DT_0_0001(0.0002)
then
Report.Failed("Incorrect values returned, Case 34");
@@ -649,7 +649,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_00001, DT_0_1, DT_0_001, DT_0_001);
begin
if TC_Verbose then Report.Comment("Case 35"); end if;
@@ -663,7 +663,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_00001, DT_0_1, DT_0_001, DT_0_01);
begin
if TC_Verbose then Report.Comment("Case 36"); end if;
@@ -676,13 +676,13 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_00001, DT_0_1, DT_0_01, DT_0_00001);
begin
if TC_Verbose then Report.Comment("Case 37"); end if;
Dd_0_00001 := DT_0_00001(0.03125); Dv_0_1 := DT_0_1(0.5);
Div(Dd_0_00001, Dv_0_1, Quot_0_01, Rem_0_00001);
- if Quot_0_01 /= DT_0_01(0.06) or Rem_0_00001 /= DT_0_00001(0.00125)
+ if Quot_0_01 /= DT_0_01(0.06) or Rem_0_00001 /= DT_0_00001(0.00125)
then
Report.Failed("Incorrect values returned, Case 37");
end if;
@@ -690,13 +690,13 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_00001, DT_0_1, DT_0_01, DT_0_0001);
begin
if TC_Verbose then Report.Comment("Case 38"); end if;
Dd_0_00001 := DT_0_00001(0.03125); Dv_0_1 := DT_0_1(0.5);
Div(Dd_0_00001, Dv_0_1, Quot_0_01, Rem_0_0001);
- if Quot_0_01 /= DT_0_01(0.06) or Rem_0_0001 /= DT_0_0001(0.0012)
+ if Quot_0_01 /= DT_0_01(0.06) or Rem_0_0001 /= DT_0_0001(0.0012)
then
Report.Failed("Incorrect values returned, Case 38");
end if;
@@ -704,7 +704,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_00001, DT_0_1, DT_0_01, DT_0_001);
begin
if TC_Verbose then Report.Comment("Case 39"); end if;
@@ -717,7 +717,7 @@ begin
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_00001, DT_0_1, DT_0_01, DT_0_01);
begin
if TC_Verbose then Report.Comment("Case 40"); end if;
@@ -729,24 +729,24 @@ begin
end;
declare
- procedure Div is
+ procedure Div is
new Ada.Decimal.Divide(DT_0_0001, DT_1, DT_0_0001, DT_0_0001);
begin
if TC_Verbose then Report.Comment("Case 41"); end if;
- Dd_0_0001 := (DT_0_0001(6062.0) / DT_0_0001(16384.0));
+ Dd_0_0001 := (DT_0_0001(6062.0) / DT_0_0001(16384.0));
Dv_1 := DT_1(0.0);
Div(Dd_0_0001, Dv_1, Quot_0_0001, Rem_0_0001);
Report.Failed("Divide by Zero didn't raise Constraint_Error, " &
"Case 41");
exception
when Constraint_Error => null; -- OK, expected exception.
- when others =>
+ when others =>
Report.Failed("Unexpected exception raised by Divide by Zero," &
"Case 41");
end;
exception
- when others => Report.Failed("Exception raised in Radix_10_Block");
+ when others => Report.Failed("Exception raised in Radix_2_Block");
end Radix_2_Block;
diff --git a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
index 7c7932e..1d79930 100644
--- a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
+++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
@@ -1,7 +1,7 @@
/* PR middle-end/91458 - inconsistent warning for writing past the end
of an array member
{ dg-do compile }
- { dg-options "-O2 -Wall -Wno-array-bounds" } */
+ { dg-options "-O2 -Wall -Wno-array-bounds -fno-ipa-icf" } */
void sink (void*);
@@ -10,7 +10,7 @@ void sink (void*);
struct Ax
{
char n;
- char a[]; // { dg-message "declared here" }
+ char a[]; // { dg-message "destination object" "note" }
};
// Verify warning for a definition with no initializer.
@@ -91,7 +91,7 @@ void gaxx (void)
struct A0
{
char n;
- char a[0]; // { dg-message "declared here" }
+ char a[0]; // { dg-message "destination object" "note" }
};
// Verify warning for a definition with no initializer.
@@ -158,7 +158,7 @@ void ga0x (void)
struct A1
{
char n;
- char a[1]; // { dg-message "declared here" }
+ char a[1]; // { dg-message "destination object" "note" }
};
// Verify warning for a definition with no initializer.
@@ -256,7 +256,7 @@ void ga1x (void)
struct A1i
{
char n;
- char a[1]; // { dg-message "declared here" }
+ char a[1]; // { dg-message "destination object" }
char x;
};
diff --git a/gcc/testsuite/c-c++-common/asan/pointer-compare-1.c b/gcc/testsuite/c-c++-common/asan/pointer-compare-1.c
index 1ce349e..4b558bf 100644
--- a/gcc/testsuite/c-c++-common/asan/pointer-compare-1.c
+++ b/gcc/testsuite/c-c++-common/asan/pointer-compare-1.c
@@ -14,12 +14,13 @@ foo (char *p, char *q)
v = p > q;
}
-char global1[100] = {}, global2[100] = {};
+char __attribute__((used)) global1[100] = {};
+char __attribute__((used)) global2[100] = {};
char __attribute__((used)) smallest_global[5] = {};
-char small_global[7] = {};
+char __attribute__((used)) small_global[7] = {};
char __attribute__((used)) little_global[10] = {};
char __attribute__((used)) medium_global[4000] = {};
-char large_global[5000] = {};
+char __attribute__((used)) large_global[5000] = {};
char __attribute__((used)) largest_global[6000] = {};
int
diff --git a/gcc/testsuite/c-c++-common/asmgoto-2.c b/gcc/testsuite/c-c++-common/asmgoto-2.c
index 5bf4572..fb81cde 100644
--- a/gcc/testsuite/c-c++-common/asmgoto-2.c
+++ b/gcc/testsuite/c-c++-common/asmgoto-2.c
@@ -7,7 +7,7 @@ foo (void)
__label__ lab;
int i = 0;
asm goto ("" : : : : lab);
- asm goto ("" : "=r" (i) : : : lab); /* { dg-error "expected" } */
+ asm goto ("" : "=r" (i) : : : lab);
asm goto ("" : : : : ); /* { dg-error "expected" } */
asm goto ("" : : : "memory"); /* { dg-error "expected" } */
asm goto ("" : : : ); /* { dg-error "expected" } */
diff --git a/gcc/testsuite/c-c++-common/attr-used-2.c b/gcc/testsuite/c-c++-common/attr-used-2.c
index f78b94b..eef2519 100644
--- a/gcc/testsuite/c-c++-common/attr-used-2.c
+++ b/gcc/testsuite/c-c++-common/attr-used-2.c
@@ -9,3 +9,4 @@ void foo()
}
/* { dg-final { scan-assembler "xyzzy" } } */
+/* { dg-final { scan-assembler "\.data.*,\"awR\"" { target R_flag_in_section } } } */
diff --git a/gcc/testsuite/c-c++-common/attr-used-3.c b/gcc/testsuite/c-c++-common/attr-used-3.c
new file mode 100644
index 0000000..ca64197
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/attr-used-3.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall -O2 -fcommon" } */
+
+static int xyzzy __attribute__((__used__));
+
+/* { dg-final { scan-assembler "xyzzy" } } */
+/* { dg-final { scan-assembler ",\"awR\"" { target R_flag_in_section } } } */
diff --git a/gcc/testsuite/c-c++-common/attr-used-4.c b/gcc/testsuite/c-c++-common/attr-used-4.c
new file mode 100644
index 0000000..1cbc4c7
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/attr-used-4.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall -O2 -fcommon" } */
+
+int xyzzy __attribute__((__used__));
+
+/* { dg-final { scan-assembler "xyzzy" } } */
+/* { dg-final { scan-assembler ",\"awR\"" { target R_flag_in_section } } } */
diff --git a/gcc/testsuite/c-c++-common/attr-used.c b/gcc/testsuite/c-c++-common/attr-used.c
index ba7705a..2036533 100644
--- a/gcc/testsuite/c-c++-common/attr-used.c
+++ b/gcc/testsuite/c-c++-common/attr-used.c
@@ -11,3 +11,4 @@ static void function_declaration_after(void) __attribute__((__used__));
/* { dg-final { scan-assembler "function_declaration_before" } } */
/* { dg-final { scan-assembler "function_declaration_after" } } */
+/* { dg-final { scan-assembler "\.text.*,\"axR\"" { target R_flag_in_section } } } */
diff --git a/gcc/testsuite/c-c++-common/builtin-clear-padding-1.c b/gcc/testsuite/c-c++-common/builtin-clear-padding-1.c
new file mode 100644
index 0000000..8b036bf
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/builtin-clear-padding-1.c
@@ -0,0 +1,19 @@
+/* PR libstdc++/88101 */
+/* { dg-do compile } */
+
+struct S;
+struct T { char a; long long b; };
+
+void
+foo (struct S *p, void *q, char *r, const struct T *s)
+{
+ __builtin_clear_padding (); /* { dg-error "too few arguments to function '__builtin_clear_padding'" } */
+ __builtin_clear_padding (1); /* { dg-error "argument 1 in call to function '__builtin_clear_padding' does not have pointer type" } */
+ __builtin_clear_padding (&p);
+ __builtin_clear_padding (&p, 1); /* { dg-error "too many arguments to function '__builtin_clear_padding'" } */
+ __builtin_clear_padding (&p, &p); /* { dg-error "too many arguments to function '__builtin_clear_padding'" } */
+ __builtin_clear_padding (p); /* { dg-error "argument 1 in call to function '__builtin_clear_padding' points to incomplete type" } */
+ __builtin_clear_padding (q); /* { dg-error "argument 1 in call to function '__builtin_clear_padding' points to incomplete type" } */
+ __builtin_clear_padding (r);
+ __builtin_clear_padding (s); /* { dg-error "argument 1 in call to function '__builtin_clear_padding' has pointer to 'const' type" } */
+}
diff --git a/gcc/testsuite/c-c++-common/builtin-clear-padding-2.c b/gcc/testsuite/c-c++-common/builtin-clear-padding-2.c
new file mode 100644
index 0000000..67c03c8
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/builtin-clear-padding-2.c
@@ -0,0 +1,17 @@
+/* PR middle-end/97943 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+struct S { int a; char b[] __attribute__((aligned (2 * sizeof (int)))); };
+struct T { int a; struct S b; };
+union U { int a; struct S b; };
+struct V { int a; union U b; };
+
+void
+foo (struct S *s, struct T *t, union U *u, struct V *v)
+{
+ __builtin_clear_padding (s); /* { dg-error "flexible array member '(S::)?b' does not have well defined padding bits for '__builtin_clear_padding'" } */
+ __builtin_clear_padding (t); /* { dg-error "flexible array member '(S::)?b' does not have well defined padding bits for '__builtin_clear_padding'" } */
+ __builtin_clear_padding (u); /* { dg-error "flexible array member '(S::)?b' does not have well defined padding bits for '__builtin_clear_padding'" } */
+ __builtin_clear_padding (v); /* { dg-error "flexible array member '(S::)?b' does not have well defined padding bits for '__builtin_clear_padding'" } */
+}
diff --git a/gcc/testsuite/c-c++-common/builtin-clear-padding-3.c b/gcc/testsuite/c-c++-common/builtin-clear-padding-3.c
new file mode 100644
index 0000000..d16cc6a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/builtin-clear-padding-3.c
@@ -0,0 +1,15 @@
+/* PR middle-end/97943 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+union U { int a; char b[] __attribute__((aligned (2 * sizeof (int)))); }; /* { dg-error "flexible array member in union" } */
+struct V { int a; union U b; };
+struct W { int a; union U b; int c; };
+
+void
+foo (union U *u, struct V *v, struct W *w)
+{
+ __builtin_clear_padding (u);
+ __builtin_clear_padding (v);
+ __builtin_clear_padding (w);
+}
diff --git a/gcc/testsuite/c-c++-common/cpp/wide-narrow-predef-macros.c b/gcc/testsuite/c-c++-common/cpp/wide-narrow-predef-macros.c
new file mode 100644
index 0000000..d5440f8a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cpp/wide-narrow-predef-macros.c
@@ -0,0 +1,13 @@
+/*
+ { dg-do compile }
+ */
+
+#if !defined(__GNUC_EXECUTION_CHARSET_NAME)
+#error "Required implementation macro for comple-time charset name is not present"
+#endif
+#if !defined(__GNUC_WIDE_EXECUTION_CHARSET_NAME)
+#error "Required implementation macro for wide comple-time charset name is not present"
+#endif
+
+const char narrow_name[] = __GNUC_EXECUTION_CHARSET_NAME;
+const char wide_name[] = __GNUC_WIDE_EXECUTION_CHARSET_NAME;
diff --git a/gcc/testsuite/c-c++-common/goacc/cache-1.c b/gcc/testsuite/c-c++-common/goacc/cache-1.c
index 1d4759e..242f3c6 100644
--- a/gcc/testsuite/c-c++-common/goacc/cache-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/cache-1.c
@@ -1,9 +1,15 @@
-/* OpenACC cache directive: valid usage. */
-/* For execution testing, this file is "#include"d from
- libgomp/testsuite/libgomp.oacc-c-c++-common/cache-1.c. */
+/* OpenACC 'cache' directive: valid usage. */
-int
-main (int argc, char **argv)
+/* See also corresponding C++ variant: '../../g++.dg/goacc/cache-1.C'. */
+
+/* For execution testing, this file is '#include'd from
+ '../../../../libgomp/testsuite/libgomp.oacc-c-c++-common/cache-1.c'. */
+
+#ifdef TEMPLATIZE
+template <int N>
+#endif
+static void
+test ()
{
#define N 2
int a[N], b[N];
@@ -61,6 +67,4 @@ main (int argc, char **argv)
if (a[i] != b[i])
__builtin_abort ();
}
-
- return 0;
}
diff --git a/gcc/testsuite/c-c++-common/goacc/cache-2.c b/gcc/testsuite/c-c++-common/goacc/cache-2.c
index d1181d1..80b925e 100644
--- a/gcc/testsuite/c-c++-common/goacc/cache-2.c
+++ b/gcc/testsuite/c-c++-common/goacc/cache-2.c
@@ -1,7 +1,9 @@
-/* OpenACC cache directive: invalid usage. */
+/* OpenACC 'cache' directive: invalid usage. */
-int
-main (int argc, char **argv)
+/* See also corresponding C++ variant: '../../g++.dg/goacc/cache-2.C'. */
+
+static void
+test ()
{
#define N 2
int a[N], b[N];
@@ -52,6 +54,4 @@ main (int argc, char **argv)
if (a[i] != b[i])
__builtin_abort ();
}
-
- return 0;
}
diff --git a/gcc/testsuite/c-c++-common/goacc/cache-3-1.c b/gcc/testsuite/c-c++-common/goacc/cache-3-1.c
new file mode 100644
index 0000000..5318a57
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/cache-3-1.c
@@ -0,0 +1,116 @@
+/* Test 'cache' directive diagnostics. */
+
+/* See also corresponding C++ variant: '../../g++.dg/goacc/cache-3-1.C'. */
+
+/* See also corresponding C/C++ data clause variant: 'data-clause-1.c'. */
+
+/* { dg-additional-options "-fopenmp" } for '#pragma omp threadprivate'. */
+
+/* The current implementation doesn't restrict where a 'cache' directive may
+ appear, so we don't make any special arrangements. */
+
+extern int a[][10], a2[][10];
+int b[10], c[10][2], d[10], e[10], f[10];
+int b2[10], c2[10][2], d2[10], e2[10], f2[10];
+int k[10], l[10], m[10], n[10], o;
+int *p;
+int **q;
+int r[4][4][4][4][4];
+extern struct s s1;
+extern struct s s2[1]; /* { dg-error "array type has incomplete element type" "" { target c } } */
+int t[10];
+#pragma omp threadprivate (t)
+#pragma acc routine
+void bar (int *);
+
+void
+foo (int g[3][10], int h[4][8], int i[2][10], int j[][9],
+ int g2[3][10], int h2[4][8], int i2[2][10], int j2[][9])
+{
+ #pragma acc cache(bar[2:5]) /* { dg-error "is not a variable" } */
+ ;
+ #pragma acc cache(t[2:5]) /* { dg-error "is threadprivate variable" } */
+ ;
+ #pragma acc cache(k[0.5:]) /* { dg-error "low bound \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma acc cache(l[:7.5f]) /* { dg-error "length \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma acc cache(m[p:]) /* { dg-error "low bound \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma acc cache(n[:p]) /* { dg-error "length \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma acc cache(o[2:5]) /* { dg-error "does not have pointer or array type" } */
+ ;
+ #pragma acc cache(s1) /* { dg-error "expected '\\\['" } */
+ ;
+ #pragma acc cache(s2) /* { dg-error "expected '\\\['" } */
+ ;
+ #pragma acc cache(a[:][:]) /* { dg-error "array type length expression must be specified" } */
+ bar (&a[0][0]); /* { dg-bogus "referenced in target region does not have a mappable type" } */
+ #pragma acc cache(b[-1:]) /* { dg-error "negative low bound in array section" } */
+ bar (b);
+ #pragma acc cache(c[:-3][:]) /* { dg-error "negative length in array section" } */
+ bar (&c[0][0]);
+ #pragma acc cache(d[11:]) /* { dg-error "low bound \[^\n\r]* above array section size" } */
+ bar (d);
+ #pragma acc cache(e[:11]) /* { dg-error "length \[^\n\r]* above array section size" } */
+ bar (e);
+ #pragma acc cache(f[1:10]) /* { dg-error "high bound \[^\n\r]* above array section size" } */
+ bar (f);
+ #pragma acc cache(g[:][0:10]) /* { dg-error "for array function parameter length expression must be specified" } */
+ bar (&g[0][0]);
+ #pragma acc cache(h[2:1][-1:]) /* { dg-error "negative low bound in array section" } */
+ bar (&h[0][0]);
+ #pragma acc cache(h[:1][:-3]) /* { dg-error "negative length in array section" } */
+ bar (&h[0][0]);
+ #pragma acc cache(i[:1][11:]) /* { dg-error "low bound \[^\n\r]* above array section size" } */
+ bar (&i[0][0]);
+ #pragma acc cache(j[3:1][:10]) /* { dg-error "length \[^\n\r]* above array section size" } */
+ bar (&j[0][0]);
+ #pragma acc cache(j[30:1][5:5]) /* { dg-error "high bound \[^\n\r]* above array section size" } */
+ bar (&j[0][0]);
+ #pragma acc cache(a2[:1][2:4])
+ bar (&a2[0][0]);
+ #pragma acc cache(a2[3:5][:])
+ bar (&a2[0][0]);
+ #pragma acc cache(a2[3:5][:10])
+ bar (&a2[0][0]);
+ #pragma acc cache(b2[0:])
+ bar (b2);
+ #pragma acc cache(c2[:3][:])
+ bar (&c2[0][0]);
+ #pragma acc cache(d2[9:])
+ bar (d2);
+ #pragma acc cache(e2[:10])
+ bar (e2);
+ #pragma acc cache(f2[1:9])
+ bar (f2);
+ #pragma acc cache(g2[:1][2:4])
+ bar (&g2[0][0]);
+ #pragma acc cache(h2[2:2][0:])
+ bar (&h2[0][0]);
+ #pragma acc cache(h2[:1][:3])
+ bar (&h2[0][0]);
+ #pragma acc cache(i2[:1][9:])
+ bar (&i2[0][0]);
+ #pragma acc cache(j2[3:4][:9])
+ bar (&j2[0][0]);
+ #pragma acc cache(j2[30:1][5:4])
+ bar (&j2[0][0]);
+ #pragma acc cache(q[1:2])
+ ;
+ #pragma acc cache(q[3:5][:10]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma acc cache(r[3:][2:1][1:2])
+ ;
+ #pragma acc cache(r[3:][2:1][1:2][:][0:4])
+ ;
+ #pragma acc cache(r[3:][2:1][1:2][1:][0:4]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma acc cache(r[3:][2:1][1:2][:3][0:4]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma acc cache(r[3:][2:1][1:2][:][1:]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma acc cache(r[3:][2:1][1:2][:][:3]) /* { dg-error "array section is not contiguous" } */
+ ;
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/cache-3-2.c b/gcc/testsuite/c-c++-common/goacc/cache-3-2.c
new file mode 100644
index 0000000..ea5222e7
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/cache-3-2.c
@@ -0,0 +1,50 @@
+/* Test 'cache' directive diagnostics. */
+
+/* See also corresponding C++ variant: '../../g++.dg/goacc/cache-3-2.C'. */
+
+/* See also corresponding C/C++ data clause variant: 'data-clause-2.c'. */
+
+/* The current implementation doesn't restrict where a 'cache' directive may
+ appear, so we don't make any special arrangements. */
+
+void
+foo (int *p, int (*q)[10], int r[10], int s[10][10])
+{
+ int a[10], b[10][10];
+ #pragma acc cache (p[-1:2])
+ ;
+ #pragma acc cache (q[-1:2][0:10])
+ ;
+ #pragma acc cache (q[-1:2][-2:10]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc cache (r[-1:2])
+ ;
+ #pragma acc cache (s[-1:2][:])
+ ;
+ #pragma acc cache (s[-1:2][-2:10]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc cache (a[-1:2]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc cache (b[-1:2][0:]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc cache (b[1:2][-2:10]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc cache (p[2:-3]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc cache (q[2:-3][:]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc cache (q[2:3][0:-1]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc cache (r[2:-5]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc cache (s[2:-5][:]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc cache (s[2:5][0:-4]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc cache (a[2:-5]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc cache (b[2:-5][0:10]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc cache (b[2:5][0:-4]) /* { dg-error "negative length in array section in" } */
+ ;
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/classify-parallel.c b/gcc/testsuite/c-c++-common/goacc/classify-parallel.c
index 66a6d13..933d766 100644
--- a/gcc/testsuite/c-c++-common/goacc/classify-parallel.c
+++ b/gcc/testsuite/c-c++-common/goacc/classify-parallel.c
@@ -20,10 +20,10 @@ void PARALLEL ()
}
/* Check the offloaded function's attributes.
- { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(omp target entrypoint\\)\\)" 1 "ompexp" } } */
+ { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc parallel, omp target entrypoint\\)\\)" 1 "ompexp" } } */
/* Check the offloaded function's classification and compute dimensions (will
always be 1 x 1 x 1 for non-offloading compilation).
{ dg-final { scan-tree-dump-times "(?n)Function is OpenACC parallel offload" 1 "oaccdevlow" } }
{ dg-final { scan-tree-dump-times "(?n)Compute dimensions \\\[1, 1, 1\\\]" 1 "oaccdevlow" } }
- { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(1, 1, 1\\), omp target entrypoint\\)\\)" 1 "oaccdevlow" } } */
+ { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(1, 1, 1\\), oacc parallel, omp target entrypoint\\)\\)" 1 "oaccdevlow" } } */
diff --git a/gcc/testsuite/c-c++-common/goacc/classify-serial.c b/gcc/testsuite/c-c++-common/goacc/classify-serial.c
new file mode 100644
index 0000000..94ace1b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/classify-serial.c
@@ -0,0 +1,29 @@
+/* Check offloaded function's attributes and classification for OpenACC
+ serial. */
+
+/* { dg-additional-options "-O2" }
+ { dg-additional-options "-fopt-info-optimized-omp" }
+ { dg-additional-options "-fdump-tree-ompexp" }
+ { dg-additional-options "-fdump-tree-oaccdevlow" } */
+
+#define N 1024
+
+extern unsigned int *__restrict a;
+extern unsigned int *__restrict b;
+extern unsigned int *__restrict c;
+
+void SERIAL ()
+{
+#pragma acc serial loop copyin (a[0:N], b[0:N]) copyout (c[0:N]) /* { dg-message "optimized: assigned OpenACC gang vector loop parallelism" } */
+ for (unsigned int i = 0; i < N; i++)
+ c[i] = a[i] + b[i];
+}
+
+/* Check the offloaded function's attributes.
+ { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc serial, omp target entrypoint\\)\\)" 1 "ompexp" } } */
+
+/* Check the offloaded function's classification and compute dimensions (will
+ always be 1 x 1 x 1 for non-offloading compilation).
+ { dg-final { scan-tree-dump-times "(?n)Function is OpenACC serial offload" 1 "oaccdevlow" } }
+ { dg-final { scan-tree-dump-times "(?n)Compute dimensions \\\[1, 1, 1\\\]" 1 "oaccdevlow" } }
+ { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(1, 1, 1\\), oacc serial, omp target entrypoint\\)\\)" 1 "oaccdevlow" } } */
diff --git a/gcc/testsuite/c-c++-common/goacc/data-clause-1.c b/gcc/testsuite/c-c++-common/goacc/data-clause-1.c
new file mode 100644
index 0000000..9952ac4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/data-clause-1.c
@@ -0,0 +1,115 @@
+/* Test data clause diagnostics. */
+
+/* See also corresponding OpenACC C++ variant: '../../g++.dg/goacc/data-clause-1.C'. */
+
+/* See also corresponding OpenACC 'cache' directive variant: 'cache-3-1.c'. */
+
+/* See also corresponding OpenMP variant: '../gomp/map-1.c'. */
+
+/* { dg-additional-options "-fopenmp" } for '#pragma omp threadprivate'. */
+
+extern int a[][10], a2[][10];
+int b[10], c[10][2], d[10], e[10], f[10];
+int b2[10], c2[10][2], d2[10], e2[10], f2[10];
+int k[10], l[10], m[10], n[10], o;
+int *p;
+int **q;
+int r[4][4][4][4][4];
+extern struct s s1;
+extern struct s s2[1]; /* { dg-error "array type has incomplete element type" "" { target c } } */
+int t[10];
+#pragma omp threadprivate (t)
+#pragma acc routine
+void bar (int *);
+
+void
+foo (int g[3][10], int h[4][8], int i[2][10], int j[][9],
+ int g2[3][10], int h2[4][8], int i2[2][10], int j2[][9])
+{
+ #pragma acc parallel copyin(bar[2:5]) /* { dg-error "is not a variable" } */
+ ;
+ #pragma acc parallel copyout(t[2:5]) /* { dg-error "is threadprivate variable" } */
+ ;
+ #pragma acc parallel copy(k[0.5:]) /* { dg-error "low bound \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma acc parallel copyout(l[:7.5f]) /* { dg-error "length \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma acc parallel copyin(m[p:]) /* { dg-error "low bound \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma acc parallel copy(n[:p]) /* { dg-error "length \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma acc parallel copyin(o[2:5]) /* { dg-error "does not have pointer or array type" } */
+ ;
+ #pragma acc parallel create(s1) /* { dg-error "'s1' does not have a mappable type in 'map' clause" } */
+ ;
+ #pragma acc parallel create(s2) /* { dg-error "'s2' does not have a mappable type in 'map' clause" } */
+ ;
+ #pragma acc parallel copyin(a[:][:]) /* { dg-error "array type length expression must be specified" } */
+ bar (&a[0][0]); /* { dg-error "referenced in target region does not have a mappable type" } */
+ #pragma acc parallel copy(b[-1:]) /* { dg-error "negative low bound in array section" } */
+ bar (b);
+ #pragma acc parallel copy(c[:-3][:]) /* { dg-error "negative length in array section" } */
+ bar (&c[0][0]);
+ #pragma acc parallel copyout(d[11:]) /* { dg-error "low bound \[^\n\r]* above array section size" } */
+ bar (d);
+ #pragma acc parallel copyin(e[:11]) /* { dg-error "length \[^\n\r]* above array section size" } */
+ bar (e);
+ #pragma acc parallel copyin(f[1:10]) /* { dg-error "high bound \[^\n\r]* above array section size" } */
+ bar (f);
+ #pragma acc parallel copyout(g[:][0:10]) /* { dg-error "for array function parameter length expression must be specified" } */
+ bar (&g[0][0]);
+ #pragma acc parallel copyout(h[2:1][-1:]) /* { dg-error "negative low bound in array section" } */
+ bar (&h[0][0]);
+ #pragma acc parallel copy(h[:1][:-3]) /* { dg-error "negative length in array section" } */
+ bar (&h[0][0]);
+ #pragma acc parallel copy(i[:1][11:]) /* { dg-error "low bound \[^\n\r]* above array section size" } */
+ bar (&i[0][0]);
+ #pragma acc parallel copyout(j[3:1][:10]) /* { dg-error "length \[^\n\r]* above array section size" } */
+ bar (&j[0][0]);
+ #pragma acc parallel copyin(j[30:1][5:5]) /* { dg-error "high bound \[^\n\r]* above array section size" } */
+ bar (&j[0][0]);
+ #pragma acc parallel copyin(a2[:1][2:4])
+ bar (&a2[0][0]);
+ #pragma acc parallel copy(a2[3:5][:])
+ bar (&a2[0][0]);
+ #pragma acc parallel copyin(a2[3:5][:10])
+ bar (&a2[0][0]);
+ #pragma acc parallel copy(b2[0:])
+ bar (b2);
+ #pragma acc parallel copy(c2[:3][:])
+ bar (&c2[0][0]);
+ #pragma acc parallel copyout(d2[9:])
+ bar (d2);
+ #pragma acc parallel copyin(e2[:10])
+ bar (e2);
+ #pragma acc parallel copyin(f2[1:9])
+ bar (f2);
+ #pragma acc parallel copy(g2[:1][2:4])
+ bar (&g2[0][0]);
+ #pragma acc parallel copyout(h2[2:2][0:])
+ bar (&h2[0][0]);
+ #pragma acc parallel copy(h2[:1][:3])
+ bar (&h2[0][0]);
+ #pragma acc parallel copyin(i2[:1][9:])
+ bar (&i2[0][0]);
+ #pragma acc parallel copyout(j2[3:4][:9])
+ bar (&j2[0][0]);
+ #pragma acc parallel copyin(j2[30:1][5:4])
+ bar (&j2[0][0]);
+ #pragma acc parallel copy(q[1:2])
+ ;
+ #pragma acc parallel copy(q[3:5][:10]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma acc parallel copy(r[3:][2:1][1:2])
+ ;
+ #pragma acc parallel copy(r[3:][2:1][1:2][:][0:4])
+ ;
+ #pragma acc parallel copy(r[3:][2:1][1:2][1:][0:4]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma acc parallel copy(r[3:][2:1][1:2][:3][0:4]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma acc parallel copy(r[3:][2:1][1:2][:][1:]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma acc parallel copy(r[3:][2:1][1:2][:][:3]) /* { dg-error "array section is not contiguous" } */
+ ;
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/data-clause-2.c b/gcc/testsuite/c-c++-common/goacc/data-clause-2.c
new file mode 100644
index 0000000..d4603b0
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/data-clause-2.c
@@ -0,0 +1,49 @@
+/* Test data clause diagnostics. */
+
+/* See also corresponding OpenACC C++ variant: '../../g++.dg/goacc/data-clause-2.C'. */
+
+/* See also corresponding OpenACC 'cache' directive variant: 'cache-3-2.c'. */
+
+/* See also corresponding OpenMP variant: '../gomp/map-2.c'. */
+
+void
+foo (int *p, int (*q)[10], int r[10], int s[10][10])
+{
+ int a[10], b[10][10];
+ #pragma acc parallel copy (p[-1:2])
+ ;
+ #pragma acc parallel copy (q[-1:2][0:10])
+ ;
+ #pragma acc parallel copy (q[-1:2][-2:10]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc parallel copy (r[-1:2])
+ ;
+ #pragma acc parallel copy (s[-1:2][:])
+ ;
+ #pragma acc parallel copy (s[-1:2][-2:10]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc parallel copy (a[-1:2]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc parallel copy (b[-1:2][0:]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc parallel copy (b[1:2][-2:10]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc parallel copy (p[2:-3]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc parallel copy (q[2:-3][:]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc parallel copy (q[2:3][0:-1]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc parallel copy (r[2:-5]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc parallel copy (s[2:-5][:]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc parallel copy (s[2:5][0:-4]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc parallel copy (a[2:-5]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc parallel copy (b[2:-5][0:10]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc parallel copy (b[2:5][0:-4]) /* { dg-error "negative length in array section in" } */
+ ;
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/if-clause-2.c b/gcc/testsuite/c-c++-common/goacc/if-clause-2.c
index 5ab8459..7bb1153 100644
--- a/gcc/testsuite/c-c++-common/goacc/if-clause-2.c
+++ b/gcc/testsuite/c-c++-common/goacc/if-clause-2.c
@@ -1,11 +1,21 @@
+/* { dg-additional-options "-fdump-tree-gimple" } */
+/* { dg-additional-options "-fopenacc-kernels=decompose" }
+ { dg-additional-options "-fdump-tree-omp_oacc_kernels_decompose" } */
+
void
f (short c)
{
-#pragma acc parallel if(c)
- ;
-#pragma acc kernels if(c)
- ;
-#pragma acc data if(c)
- ;
-#pragma acc update device(c) if(c)
+#pragma acc parallel if(c) copy(c)
+ ++c;
+
+#pragma acc kernels if(c) copy(c)
+ /* { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_kernels map\(tofrom:c \[len: [0-9]+\]\) if\(_[0-9]+\)$} 1 "gimple" } } */
+ /* { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_data_kernels map\(tofrom:c \[len: [0-9]+\]\) if\(_[0-9]+\)$} 1 "omp_oacc_kernels_decompose" } }
+ { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_parallel_kernels_gang_single async\(-1\) num_gangs\(1\) map\(force_present:c \[len: [0-9]+\]\) if\(_[0-9]+\)$} 1 "omp_oacc_kernels_decompose" } } */
+ ++c;
+
+#pragma acc data if(c) copy(c)
+ ++c;
+
+#pragma acc update if(c) device(c)
}
diff --git a/gcc/testsuite/c-c++-common/goacc/kernels-decompose-1.c b/gcc/testsuite/c-c++-common/goacc/kernels-decompose-1.c
new file mode 100644
index 0000000..e906443
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/kernels-decompose-1.c
@@ -0,0 +1,91 @@
+/* Test OpenACC 'kernels' construct decomposition. */
+
+/* { dg-additional-options "-fopt-info-omp-all" } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+/* { dg-additional-options "-fopenacc-kernels=decompose" }
+ { dg-additional-options "-fdump-tree-omp_oacc_kernels_decompose" } */
+
+/* See also '../../gfortran.dg/goacc/kernels-decompose-1.f95'. */
+
+/* It's only with Tcl 8.5 (released in 2007) that "the variable 'varName'
+ passed to 'incr' may be unset, and in that case, it will be set to [...]",
+ so to maintain compatibility with earlier Tcl releases, we manually
+ initialize counter variables:
+ { dg-line l_dummy[variable c_loop_i 0] }
+ { dg-message "dummy" "" { target iN-VAl-Id } l_dummy } to avoid
+ "WARNING: dg-line var l_dummy defined, but not used". */
+
+#define N 1024
+
+unsigned int a[N];
+
+int
+main (void)
+{
+ int i;
+ unsigned int sum = 1;
+
+#pragma acc kernels copyin(a[0:N]) copy(sum)
+ /* { dg-bogus "optimized: assigned OpenACC seq loop parallelism" "TODO" { xfail *-*-* } .-1 }
+ TODO Is this maybe the report that belongs to the XFAILed report further down? */
+ {
+ #pragma acc loop /* { dg-line l_loop_i[incr c_loop_i] } */
+ /* { dg-message "note: forwarded loop nest in OpenACC 'kernels' region to 'parloops' for analysis" "" { target *-*-* } l_loop_i$c_loop_i } */
+ /* { dg-optimized "assigned OpenACC seq loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i } */
+ for (i = 0; i < N; ++i)
+ sum += a[i];
+
+ sum++; /* { dg-message "note: beginning 'gang-single' part in OpenACC 'kernels' region" } */
+ a[0]++;
+
+ #pragma acc loop independent /* { dg-line l_loop_i[incr c_loop_i] } */
+ /* { dg-message "note: parallelized loop nest in OpenACC 'kernels' region" "" { target *-*-* } l_loop_i$c_loop_i } */
+ /* { dg-optimized "assigned OpenACC gang vector loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i } */
+ for (i = 0; i < N; ++i)
+ sum += a[i];
+
+ if (sum > 10) /* { dg-message "note: beginning 'parloops' part in OpenACC 'kernels' region" } */
+ {
+ #pragma acc loop /* { dg-line l_loop_i[incr c_loop_i] } */
+ /* { dg-missed "unparallelized loop nest in OpenACC 'kernels' region: it's executed conditionally" "" { target *-*-* } l_loop_i$c_loop_i } */
+ /*TODO { dg-optimized "assigned OpenACC seq loop parallelism" "TODO" { xfail *-*-* } l_loop_i$c_loop_i } */
+ for (i = 0; i < N; ++i)
+ sum += a[i];
+ }
+
+ #pragma acc loop auto /* { dg-line l_loop_i[incr c_loop_i] } */
+ /* { dg-message "note: forwarded loop nest in OpenACC 'kernels' region to 'parloops' for analysis" "" { target *-*-* } l_loop_i$c_loop_i } */
+ /* { dg-optimized "assigned OpenACC seq loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i } */
+ for (i = 0; i < N; ++i)
+ sum += a[i];
+ }
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_kernels map\(tofrom:sum \[len: [0-9]+\]\) map\(to:a\[0\] \[len: [0-9]+\]\) map\(firstprivate:a \[pointer assign, bias: 0\]\)$} 1 "gimple" } }
+
+ { dg-final { scan-tree-dump-times {(?n)#pragma acc loop private\(i\)$} 2 "gimple" } }
+ { dg-final { scan-tree-dump-times {(?n)#pragma acc loop independent private\(i\)$} 1 "gimple" } }
+ { dg-final { scan-tree-dump-times {(?n)#pragma acc loop auto private\(i\)$} 1 "gimple" } }
+ { dg-final { scan-tree-dump-times {(?n)#pragma acc loop} 4 "gimple" } } */
+
+/* Check that the OpenACC 'kernels' got decomposed into 'data' and an enclosed
+ sequence of compute constructs.
+ { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_data_kernels map\(tofrom:sum \[len: [0-9]+\]\) map\(to:a\[0\] \[len: [0-9]+\]\)$} 1 "omp_oacc_kernels_decompose" } }
+ As noted above, we get three "old-style" kernel regions, one gang-single region, and one parallelized loop region.
+ { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_kernels async\(-1\) map\(force_present:sum \[len: [0-9]+\]\) map\(force_present:a\[0\] \[len: [0-9]+\]\) map\(firstprivate:a \[pointer assign, bias: 0\]\)$} 3 "omp_oacc_kernels_decompose" } }
+ { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_parallel_kernels_parallelized async\(-1\) map\(force_present:sum \[len: [0-9]+\]\) map\(force_present:a\[0\] \[len: [0-9]+\]\) map\(firstprivate:a \[pointer assign, bias: 0\]\)$} 1 "omp_oacc_kernels_decompose" } }
+ { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_parallel_kernels_gang_single async\(-1\) num_gangs\(1\) map\(force_present:sum \[len: [0-9]+\]\) map\(force_present:a\[0\] \[len: [0-9]+\]\) map\(firstprivate:a \[pointer assign, bias: 0\]\)$} 1 "omp_oacc_kernels_decompose" } }
+
+ 'data' plus five CCs.
+ { dg-final { scan-tree-dump-times {(?n)#pragma omp target } 6 "omp_oacc_kernels_decompose" } }
+
+ { dg-final { scan-tree-dump-times {(?n)#pragma acc loop private\(i\)$} 2 "omp_oacc_kernels_decompose" } }
+ { dg-final { scan-tree-dump-times {(?n)#pragma acc loop independent private\(i\)$} 1 "omp_oacc_kernels_decompose" } }
+ { dg-final { scan-tree-dump-times {(?n)#pragma acc loop auto private\(i\)$} 1 "omp_oacc_kernels_decompose" } }
+ { dg-final { scan-tree-dump-times {(?n)#pragma acc loop} 4 "omp_oacc_kernels_decompose" } }
+
+ Each of the parallel regions is async, and there is a final call to
+ __builtin_GOACC_wait.
+ { dg-final { scan-tree-dump-times "__builtin_GOACC_wait" 1 "omp_oacc_kernels_decompose" } } */
diff --git a/gcc/testsuite/c-c++-common/goacc/kernels-decompose-2.c b/gcc/testsuite/c-c++-common/goacc/kernels-decompose-2.c
new file mode 100644
index 0000000..ec0f75c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/kernels-decompose-2.c
@@ -0,0 +1,149 @@
+/* Test OpenACC 'kernels' construct decomposition. */
+
+/* { dg-additional-options "-fopt-info-omp-all" } */
+/* { dg-additional-options "-fopenacc-kernels=decompose" }
+/* { dg-additional-options "-O2" } for 'parloops'. */
+
+/* See also '../../gfortran.dg/goacc/kernels-decompose-2.f95'. */
+
+/* It's only with Tcl 8.5 (released in 2007) that "the variable 'varName'
+ passed to 'incr' may be unset, and in that case, it will be set to [...]",
+ so to maintain compatibility with earlier Tcl releases, we manually
+ initialize counter variables:
+ { dg-line l_dummy[variable c_loop_i 0 c_loop_j 0 c_loop_k 0 c_part 0] }
+ { dg-message "dummy" "" { target iN-VAl-Id } l_dummy } to avoid
+ "WARNING: dg-line var l_dummy defined, but not used". */
+
+#pragma acc routine gang
+extern int
+f_g (int);
+
+#pragma acc routine worker
+extern int
+f_w (int);
+
+#pragma acc routine vector
+extern int
+f_v (int);
+
+#pragma acc routine seq
+extern int
+f_s (int);
+
+int
+main ()
+{
+ int x, y, z;
+#define N 10
+ int a[N], b[N], c[N];
+
+#pragma acc kernels
+ {
+ x = 0; /* { dg-message "note: beginning 'gang-single' part in OpenACC 'kernels' region" } */
+ y = x < 10;
+ z = x++;
+ ;
+ }
+
+ { /*TODO Instead of using 'for (int i = 0; [...])', move 'int i' outside, to work around for ICE detailed in 'kernels-decompose-ice-1.c'. */
+ int i;
+#pragma acc kernels /* { dg-optimized "assigned OpenACC gang loop parallelism" } */
+ for (i = 0; i < N; i++) /* { dg-message "note: beginning 'parloops' part in OpenACC 'kernels' region" } */
+ a[i] = 0;
+ }
+
+#pragma acc kernels loop /* { dg-line l_loop_i[incr c_loop_i] } */
+ /* { dg-message "note: forwarded loop nest in OpenACC 'kernels' region to 'parloops' for analysis" "" { target *-*-* } l_loop_i$c_loop_i } */
+ /* { dg-optimized "assigned OpenACC seq loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i } */
+ for (int i = 0; i < N; i++)
+ b[i] = a[N - i - 1];
+
+#pragma acc kernels
+ {
+#pragma acc loop /* { dg-line l_loop_i[incr c_loop_i] } */
+ /* { dg-message "note: forwarded loop nest in OpenACC 'kernels' region to 'parloops' for analysis" "" { target *-*-* } l_loop_i$c_loop_i } */
+ /* { dg-optimized "assigned OpenACC seq loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i } */
+ for (int i = 0; i < N; i++)
+ b[i] = a[N - i - 1];
+
+#pragma acc loop /* { dg-line l_loop_i[incr c_loop_i] } */
+ /* { dg-message "note: forwarded loop nest in OpenACC 'kernels' region to 'parloops' for analysis" "" { target *-*-* } l_loop_i$c_loop_i } */
+ /* { dg-optimized "assigned OpenACC seq loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i } */
+ for (int i = 0; i < N; i++)
+ c[i] = a[i] * b[i];
+
+ a[z] = 0; /* { dg-message "note: beginning 'gang-single' part in OpenACC 'kernels' region" } */
+
+#pragma acc loop /* { dg-line l_loop_i[incr c_loop_i] } */
+ /* { dg-message "note: forwarded loop nest in OpenACC 'kernels' region to 'parloops' for analysis" "" { target *-*-* } l_loop_i$c_loop_i } */
+ /* { dg-optimized "assigned OpenACC seq loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i } */
+ for (int i = 0; i < N; i++)
+ c[i] += a[i];
+
+#pragma acc loop seq /* { dg-line l_loop_i[incr c_loop_i] } */
+ /* { dg-message "note: parallelized loop nest in OpenACC 'kernels' region" "" { target *-*-* } l_loop_i$c_loop_i } */
+ /* { dg-optimized "assigned OpenACC seq loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i } */
+ for (int i = 0 + 1; i < N; i++)
+ c[i] += c[i - 1];
+ }
+
+#pragma acc kernels
+ /*TODO What does this mean?
+ TODO { dg-optimized "assigned OpenACC worker vector loop parallelism" "" { target *-*-* } .-2 } */
+ {
+#pragma acc loop independent /* { dg-line l_loop_i[incr c_loop_i] } */
+ /* { dg-optimized "assigned OpenACC gang loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i } */
+ /* { dg-message "note: parallelized loop nest in OpenACC 'kernels' region" "" { target *-*-* } l_loop_i$c_loop_i } */
+ for (int i = 0; i < N; ++i)
+#pragma acc loop independent /* { dg-line l_loop_j[incr c_loop_j] } */
+ /* { dg-optimized "assigned OpenACC worker loop parallelism" "" { target *-*-* } l_loop_j$c_loop_j } */
+ for (int j = 0; j < N; ++j)
+#pragma acc loop independent /* { dg-line l_loop_k[incr c_loop_k] } */
+ /* { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } l_loop_k$c_loop_k } */
+ /* { dg-optimized "assigned OpenACC seq loop parallelism" "" { target *-*-* } l_loop_k$c_loop_k } */
+ for (int k = 0; k < N; ++k)
+ a[(i + j + k) % N]
+ = b[j]
+ + f_v (c[k]); /* { dg-optimized "assigned OpenACC vector loop parallelism" } */
+
+ /*TODO Should the following turn into "gang-single" instead of "parloops"?
+ TODO The problem is that the first STMT is 'if (y <= 4) goto <D.2547>; else goto <D.2548>;', thus "parloops". */
+ if (y < 5) /* { dg-message "note: beginning 'parloops' part in OpenACC 'kernels' region" } */
+#pragma acc loop independent /* { dg-line l_loop_j[incr c_loop_j] } */
+ /* { dg-missed "unparallelized loop nest in OpenACC 'kernels' region: it's executed conditionally" "" { target *-*-* } l_loop_j$c_loop_j } */
+ for (int j = 0; j < N; ++j)
+ b[j] = f_w (c[j]);
+ }
+
+#pragma acc kernels
+ {
+ y = f_g (a[5]); /* { dg-line l_part[incr c_part] } */
+ /*TODO If such a construct is placed in its own part (like it is, here), can't this actually use gang paralelism, instead of "gang-single"?
+ { dg-message "note: beginning 'gang-single' part in OpenACC 'kernels' region" "" { target *-*-* } l_part$c_part } */
+ /* { dg-optimized "assigned OpenACC gang worker vector loop parallelism" "" { target *-*-* } l_part$c_part } */
+
+#pragma acc loop independent /* { dg-line l_loop_j[incr c_loop_j] } */
+ /* { dg-message "note: parallelized loop nest in OpenACC 'kernels' region" "" { target *-*-* } l_loop_j$c_loop_j } */
+ /* { dg-optimized "assigned OpenACC gang loop parallelism" "" { target *-*-* } l_loop_j$c_loop_j } */
+ for (int j = 0; j < N; ++j)
+ b[j] = y + f_w (c[j]); /* { dg-optimized "assigned OpenACC worker vector loop parallelism" } */
+ }
+
+#pragma acc kernels
+ {
+ y = 3; /* { dg-message "note: beginning 'gang-single' part in OpenACC 'kernels' region" } */
+
+#pragma acc loop independent /* { dg-line l_loop_j[incr c_loop_j] } */
+ /* { dg-message "note: parallelized loop nest in OpenACC 'kernels' region" "" { target *-*-* } l_loop_j$c_loop_j } */
+ /* { dg-optimized "assigned OpenACC gang worker loop parallelism" "" { target *-*-* } l_loop_j$c_loop_j } */
+ for (int j = 0; j < N; ++j)
+ b[j] = y + f_v (c[j]); /* { dg-optimized "assigned OpenACC vector loop parallelism" } */
+
+ z = 2; /* { dg-message "note: beginning 'gang-single' part in OpenACC 'kernels' region" } */
+ }
+
+#pragma acc kernels /* { dg-message "note: beginning 'gang-single' part in OpenACC 'kernels' region" } */
+ ;
+
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-1.c b/gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-1.c
new file mode 100644
index 0000000..82e7bd1
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-1.c
@@ -0,0 +1,109 @@
+/* Test OpenACC 'kernels' construct decomposition. */
+
+/* { dg-additional-options "-fopt-info-omp-all" } */
+/* { dg-additional-options "-fopenacc-kernels=decompose" } */
+/* { dg-ice "TODO" }
+ { dg-prune-output "during GIMPLE pass: omplower" } */
+
+/* Reduced from 'kernels-decompose-2.c'.
+ (Hopefully) similar instances:
+ - 'kernels-decompose-ice-2.c'
+ - 'libgomp.oacc-c-c++-common/declare-vla-kernels-decompose-ice-1.c'
+ - 'libgomp.oacc-c-c++-common/kernels-decompose-1.c'
+*/
+
+int
+main ()
+{
+#define N 10
+
+#pragma acc kernels
+ for (int i = 0; i < N; i++) /* { dg-message "note: beginning 'parloops' part in OpenACC 'kernels' region" } */
+ ;
+
+ return 0;
+}
+
+/*
+ In 'gimple' we've got:
+
+ main ()
+ {
+ int D.2087;
+
+ {
+ int a[10];
+
+ try
+ {
+ #pragma omp target oacc_kernels map(tofrom:a [len: 40])
+ {
+ {
+ int i;
+
+ i = 0;
+ goto <D.2085>;
+ [...]
+
+ ..., which in 'omp_oacc_kernels_decompose' we turn into:
+
+ main ()
+ {
+ int D.2087;
+
+ {
+ int a[10];
+
+ try
+ {
+ #pragma omp target oacc_data_kernels map(tofrom:a [len: 40])
+ {
+ try
+ {
+ {
+ int i;
+
+ #pragma omp target oacc_data_kernels map(alloc:i [len: 4])
+ {
+ try
+ {
+ {
+ #pragma omp target oacc_kernels async(-1) map(force_present:i [len: 4]) map(force_present:a [len: 40])
+ {
+ i = 0;
+ goto <D.2085>;
+ [...]
+
+ ..., which results in ICE in:
+
+ #1 0x0000000000d2247b in lower_omp_target (gsi_p=gsi_p@entry=0x7fffffffbc90, ctx=ctx@entry=0x2c994c0) at [...]/gcc/omp-low.c:11981
+ 11981 gcc_assert (offloaded);
+ (gdb) list
+ 11976 talign = TYPE_ALIGN_UNIT (TREE_TYPE (TREE_TYPE (ovar)));
+ 11977 gimplify_assign (x, var, &ilist);
+ 11978 }
+ 11979 else if (is_gimple_reg (var))
+ 11980 {
+ 11981 gcc_assert (offloaded);
+ 11982 tree avar = create_tmp_var (TREE_TYPE (var));
+ 11983 mark_addressable (avar);
+ 11984 enum gomp_map_kind map_kind = OMP_CLAUSE_MAP_KIND (c);
+ 11985 if (GOMP_MAP_COPY_TO_P (map_kind)
+ (gdb) call debug_tree(var)
+ <var_decl 0x7ffff7feebd0 i
+ type <integer_type 0x7ffff67be5e8 int sizes-gimplified public SI
+ size <integer_cst 0x7ffff67a5f18 constant 32>
+ unit-size <integer_cst 0x7ffff67a5f30 constant 4>
+ align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff67be5e8 precision:32 min <integer_cst 0x7ffff67a5ed0 -2147483648> max <integer_cst 0x7ffff67a5ee8 2147483647>
+ pointer_to_this <pointer_type 0x7ffff67c69d8>>
+ used read SI [...]:15:12 size <integer_cst 0x7ffff67a5f18 32> unit-size <integer_cst 0x7ffff67a5f30 4>
+ align:32 warn_if_not_align:0 context <function_decl 0x7ffff68eea00 main>>
+
+ Just defusing the 'assert' is not sufficient:
+
+ libgomp: present clause: !acc_is_present (0x7ffe29cba3ec, 4 (0x4))
+
+ TODO Can't the 'omp_oacc_kernels_decompose' transformation be much simpler, such that we avoid the intermediate 'data' if we've got just one compute construct inside it?
+ TODO But it's not clear if that'd just resolve one simple instance of the general problem?
+
+*/
diff --git a/gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-2.c b/gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-2.c
new file mode 100644
index 0000000..569f87a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-2.c
@@ -0,0 +1,16 @@
+/* Test OpenACC 'kernels' construct decomposition. */
+
+/* { dg-additional-options "-fopenacc-kernels=decompose" } */
+/* { dg-ice "TODO" }
+ { dg-prune-output "during GIMPLE pass: omplower" } */
+
+/* Reduced from 'kernels-decompose-ice-1.c'. */
+
+int
+main ()
+{
+#pragma acc kernels
+ {
+ int i;
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/depobj-2.c b/gcc/testsuite/c-c++-common/gomp/depobj-2.c
new file mode 100644
index 0000000..d06910c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/depobj-2.c
@@ -0,0 +1,11 @@
+/* PR c++/98072 */
+
+typedef struct __attribute__((__aligned__ (sizeof (void *)))) omp_depend_t {
+ char __omp_depend_t__[2 * sizeof (void *)];
+} omp_depend_t;
+
+void
+foo (int *x, omp_depend_t *y, int z)
+{
+ #pragma omp depobj (*y) depend (in: x[z])
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/map-1.c b/gcc/testsuite/c-c++-common/gomp/map-1.c
index 508dc8d..ed88944 100644
--- a/gcc/testsuite/c-c++-common/gomp/map-1.c
+++ b/gcc/testsuite/c-c++-common/gomp/map-1.c
@@ -1,5 +1,8 @@
-/* { dg-do compile } */
-/* { dg-options "-fopenmp" } */
+/* Test 'map' clause diagnostics. */
+
+/* See also corresponding OpenMP C++ variant: '../../g++.dg/gomp/map-1.C'. */
+
+/* See also corresponding OpenACC variant: '../goacc/data-clause-1.c'. */
extern int a[][10], a2[][10];
int b[10], c[10][2], d[10], e[10], f[10];
diff --git a/gcc/testsuite/c-c++-common/gomp/map-2.c b/gcc/testsuite/c-c++-common/gomp/map-2.c
index 101f404..01fb4be 100644
--- a/gcc/testsuite/c-c++-common/gomp/map-2.c
+++ b/gcc/testsuite/c-c++-common/gomp/map-2.c
@@ -1,5 +1,8 @@
-/* { dg-do compile } */
-/* { dg-options "-fopenmp" } */
+/* Test 'map' clause diagnostics. */
+
+/* See also corresponding OpenMP C++ variant: '../../g++.dg/gomp/map-2.C'. */
+
+/* See also corresponding OpenACC variant: '../goacc/data-clause-2.c'. */
void
foo (int *p, int (*q)[10], int r[10], int s[10][10])
diff --git a/gcc/testsuite/c-c++-common/gomp/pr97862.c b/gcc/testsuite/c-c++-common/gomp/pr97862.c
new file mode 100644
index 0000000..21aad3f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pr97862.c
@@ -0,0 +1,15 @@
+/* PR middle-end/97862 */
+
+void
+foo (void)
+{
+ int i, j;
+#pragma omp for collapse(2)
+ for (i = 0; i < 1; ++i)
+ for (j = 0; j < i; ++j)
+ ;
+#pragma omp for collapse(2)
+ for (i = 0; i < 20; i++)
+ for (j = 0; j < i - 19; j += 1)
+ ;
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/pr97958.c b/gcc/testsuite/c-c++-common/gomp/pr97958.c
new file mode 100644
index 0000000..5a6de02
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pr97958.c
@@ -0,0 +1,17 @@
+/* PR c/97958 */
+
+int *p;
+
+void
+foo (void)
+{
+ #pragma omp atomic
+ p = p + 1;
+}
+
+void
+bar (void)
+{
+ #pragma omp atomic /* { dg-error "invalid expression type for '#pragma omp atomic'" } */
+ bar = bar + 1;
+}
diff --git a/gcc/testsuite/c-c++-common/hwasan/aligned-alloc.c b/gcc/testsuite/c-c++-common/hwasan/aligned-alloc.c
new file mode 100644
index 0000000..d38b1f3
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/aligned-alloc.c
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+/* This program fails at runtime in the libhwasan library.
+ The allocator can't handle the requested invalid alignment. */
+
+int
+main ()
+{
+ void *p = __builtin_aligned_alloc (17, 100);
+ if (((unsigned long long)p & 0x10) == 0)
+ return 0;
+ return 1;
+}
+
+/* { dg-output "HWAddressSanitizer: invalid alignment requested in aligned_alloc: 17" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/alloca-array-accessible.c b/gcc/testsuite/c-c++-common/hwasan/alloca-array-accessible.c
new file mode 100644
index 0000000..5e4c168
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/alloca-array-accessible.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+
+#define alloca __builtin_alloca
+
+int __attribute__ ((noinline))
+using_alloca (int num)
+{
+ int retval = 0;
+ int *big_array = (int*)alloca (num * sizeof (int));
+ for (int i = 0; i < num; ++i) {
+ retval += big_array[i];
+ }
+ return retval;
+}
+
+int __attribute__ ((noinline))
+using_vararray (int num)
+{
+ int retval = 0;
+ int big_array[num];
+ for (int i = 0; i < num; ++i) {
+ retval += big_array[i];
+ }
+ return retval;
+}
+
+int main()
+{
+ using_alloca (16);
+ using_vararray (12);
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/hwasan/alloca-base-init.c b/gcc/testsuite/c-c++-common/hwasan/alloca-base-init.c
new file mode 100644
index 0000000..3ebeaa0
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/alloca-base-init.c
@@ -0,0 +1,66 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-additional-options "--param hwasan-random-frame-tag=1" } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+#include <alloca.h>
+
+/* This testcase checks that `alloca` calls ensure the `__hwasan_generate_tag`
+ function is called to initialize the base tag. `alloca` calls are treated
+ differently to standard variables. The prologue/epilogue sequence is
+ generated mainly based on normal stack-allocated objects.
+
+ We want to ensure that though the `alloca` call is not poisoned/unpoisoned
+ by the prologue and epilogue, the use of them in a given function still
+ triggers the prologue sequence to emit a call to __hwasan_generate_tag (and
+ hence that any call to __hwasan_generate_tag is emitted in the unconditional
+ part of the function code). */
+
+int choice = 0;
+int record = 1;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+__attribute__ ((noinline))
+unsigned char
+__hwasan_generate_tag ()
+{
+ record = 0;
+ return 3;
+}
+#ifdef __cplusplus
+}
+#endif
+
+__attribute__ ((noinline))
+int
+generate_tag_was_missed (void)
+{
+ return record;
+}
+
+__attribute__((noinline, noclone)) int
+foo (char *a)
+{
+ int i, j = 0;
+ asm volatile ("" : "+r" (a) : : "memory");
+ for (i = 0; i < 12; i++)
+ j += a[i];
+ return j;
+}
+
+int
+main ()
+{
+ if (choice)
+ {
+ char *x = (char *)alloca(100);
+ foo(x);
+ }
+ else
+ {
+ char *y = (char *)alloca(20);
+ foo(y);
+ }
+ return generate_tag_was_missed ();
+}
diff --git a/gcc/testsuite/c-c++-common/hwasan/alloca-gets-different-tag.c b/gcc/testsuite/c-c++-common/hwasan/alloca-gets-different-tag.c
new file mode 100644
index 0000000..e83734f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/alloca-gets-different-tag.c
@@ -0,0 +1,65 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+
+/* Alloca is given a different tag to other variables.
+ vararray should behave in the same way. */
+
+#define alloca __builtin_alloca
+#define assert(x) if (!(x)) __builtin_abort ()
+
+struct two_values {
+ int left;
+ int right;
+};
+
+/* Require default hwasan tag ABI.
+ Know we're using AArch64 since that's the only architecture we run hwasan
+ tests on. */
+char tag_of (void * x) { return ((unsigned long long)x) >> 56; }
+
+int __attribute__ ((noinline))
+alloca_different_tag (int num)
+{
+ struct two_values tmp_object = {
+ .left = 100,
+ .right = num,
+ };
+ int *big_array = (int *)alloca (num * sizeof (int));
+ int other_array[100];
+
+ char first_tag = tag_of (&tmp_object);
+ char second_tag = tag_of (big_array);
+ char other_tag = tag_of (other_array);
+ assert (first_tag != second_tag);
+ assert (second_tag != other_tag);
+ assert (first_tag != other_tag);
+ return 0;
+}
+
+int __attribute__ ((noinline))
+vararray_different_tag (int num)
+{
+ struct two_values tmp_object = {
+ .left = 100,
+ .right = num,
+ };
+ int big_array[num];
+ int other_array[100];
+
+ char first_tag = tag_of (&tmp_object);
+ char second_tag = tag_of (big_array);
+ char other_tag = tag_of (other_array);
+ assert (first_tag != second_tag);
+ assert (second_tag != other_tag);
+ assert (first_tag != other_tag);
+ return 0;
+}
+
+int __attribute__ ((noinline))
+main ()
+{
+ alloca_different_tag (10);
+ vararray_different_tag (8);
+ return 0;
+}
+
diff --git a/gcc/testsuite/c-c++-common/hwasan/alloca-outside-caught.c b/gcc/testsuite/c-c++-common/hwasan/alloca-outside-caught.c
new file mode 100644
index 0000000..60d7a9a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/alloca-outside-caught.c
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+
+#define alloca __builtin_alloca
+
+int __attribute__ ((noinline))
+check_alloca (int num)
+{
+ volatile int *allocd_array = (int*)alloca (num * sizeof(int));
+ int other_array[10];
+ return allocd_array[12];
+}
+
+int __attribute__ ((noinline))
+main ()
+{
+ check_alloca (3);
+ return 1;
+}
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/arguments-1.c b/gcc/testsuite/c-c++-common/hwasan/arguments-1.c
new file mode 100644
index 0000000..435dad3
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/arguments-1.c
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fsanitize=kernel-hwaddress" } */
+/* { dg-error ".*'-fsanitize=hwaddress' is incompatible with '-fsanitize=kernel-hwaddress'.*" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/arguments-2.c b/gcc/testsuite/c-c++-common/hwasan/arguments-2.c
new file mode 100644
index 0000000..fafde99
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/arguments-2.c
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fsanitize=kernel-address" } */
+/* { dg-error ".*'-fsanitize=hwaddress' is incompatible with '-fsanitize=kernel-address'.*" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/arguments-3.c b/gcc/testsuite/c-c++-common/hwasan/arguments-3.c
new file mode 100644
index 0000000..6e907b4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/arguments-3.c
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fsanitize=thread" } */
+/* { dg-error ".*'-fsanitize=thread' is incompatible with '-fsanitize=hwaddress'.*" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/arguments.c b/gcc/testsuite/c-c++-common/hwasan/arguments.c
new file mode 100644
index 0000000..7c11314
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/arguments.c
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fsanitize=address" } */
+/* { dg-error ".*'-fsanitize=hwaddress' is incompatible with '-fsanitize=address'.*" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/asan-pr63316.c b/gcc/testsuite/c-c++-common/hwasan/asan-pr63316.c
new file mode 100644
index 0000000..dd3b3db
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/asan-pr63316.c
@@ -0,0 +1,24 @@
+/* PR sanitizer/63316 */
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern void *malloc (__SIZE_TYPE__);
+extern void free (void *);
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+ int *p = (int *) malloc (sizeof (int));
+ *p = 3;
+ asm volatile ("" : : "r" (p) : "memory");
+ free (p);
+ return 0;
+}
+
diff --git a/gcc/testsuite/c-c++-common/hwasan/asan-pr70541.c b/gcc/testsuite/c-c++-common/hwasan/asan-pr70541.c
new file mode 100644
index 0000000..ba2ed49
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/asan-pr70541.c
@@ -0,0 +1,36 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-options "-fno-builtin-malloc -fno-builtin-free" } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
+/* { dg-shouldfail "hwasan" } */
+
+#include <stdio.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern void *malloc (__SIZE_TYPE__);
+extern void free (void *);
+#ifdef __cplusplus
+}
+#endif
+
+struct Simple {
+ int value;
+};
+
+int f(struct Simple simple) {
+ return simple.value;
+}
+
+int main() {
+ struct Simple *psimple = (struct Simple *) malloc(sizeof(struct Simple));
+ psimple->value = 42;
+ free(psimple);
+ printf("%d\n", f(*psimple));
+ return 0;
+}
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "freed by thread T0 here:.*" } */
+/* { dg-output "previously allocated here:" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/asan-pr78106.c b/gcc/testsuite/c-c++-common/hwasan/asan-pr78106.c
new file mode 100644
index 0000000..3f53ad1
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/asan-pr78106.c
@@ -0,0 +1,31 @@
+/* PR sanitizer/78106 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=hwaddress -fdump-tree-sanopt-details -ffat-lto-objects" } */
+
+int *variable;
+
+void __attribute__((used)) release()
+{
+ __builtin_free (variable);
+}
+
+int main2(int argc)
+{
+ *variable = 2;
+
+ if (argc <= 5)
+ asm volatile ("call release");
+
+ *variable = 2;
+ __builtin_abort ();
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ variable = (int *)__builtin_malloc (sizeof(int));
+ return main2(argc);
+}
+
+/* { dg-final { scan-tree-dump-not "Optimizing out(\n|\r\n|\r) HWASAN_CHECK \\(7, variable.*" "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/asan-pr79944.c b/gcc/testsuite/c-c++-common/hwasan/asan-pr79944.c
new file mode 100644
index 0000000..7d54f54
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/asan-pr79944.c
@@ -0,0 +1,19 @@
+/* PR sanitizer/79944 */
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+
+struct S { int i; char p[1024]; };
+
+int
+main ()
+{
+ struct S *p = (struct S *) __builtin_malloc (__builtin_offsetof (struct S, p) + 64);
+ p->i = 5;
+ asm volatile ("" : "+r" (p) : : "memory");
+ __atomic_fetch_add ((int *) p, 5, __ATOMIC_RELAXED);
+ asm volatile ("" : "+r" (p) : : "memory");
+ if (p->i != 10)
+ __builtin_abort ();
+ __builtin_free (p);
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/hwasan/asan-rlimit-mmap-test-1.c b/gcc/testsuite/c-c++-common/hwasan/asan-rlimit-mmap-test-1.c
new file mode 100644
index 0000000..5426b8a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/asan-rlimit-mmap-test-1.c
@@ -0,0 +1,24 @@
+/* Check that we properly report mmap failure. */
+
+/* { dg-do run { target setrlimit } } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
+/* { dg-require-effective-target hw } */
+/* { dg-shouldfail "hwasan" } */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+static volatile void *x;
+
+int main(int argc, char **argv) {
+ struct rlimit mmap_resource_limit = { 0, 0 };
+ if (setrlimit(RLIMIT_AS, &mmap_resource_limit)) return 1;
+ x = malloc(10000000);
+ return 0;
+}
+
+/* { dg-output "ERROR: Failed to mmap" } */
+
diff --git a/gcc/testsuite/c-c++-common/hwasan/bitfield-1.c b/gcc/testsuite/c-c++-common/hwasan/bitfield-1.c
new file mode 100644
index 0000000..0c3479e
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/bitfield-1.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+
+struct bitmapped_struct {
+ unsigned one : 1;
+ unsigned two : 1;
+ unsigned three : 1;
+ unsigned four : 1;
+ unsigned five : 1;
+ unsigned six : 1;
+ unsigned seven : 1;
+ unsigned eight : 1;
+};
+
+/* Check that hwasan allows valid bitfield accesses. */
+int __attribute__ ((noinline))
+handle_unaligned_access (struct bitmapped_struct *foo)
+{
+ if (foo->three)
+ return foo->four;
+
+ foo->five = 1;
+ return 1;
+}
+
+int main()
+{
+ struct bitmapped_struct myvar = {0};
+ handle_unaligned_access (&myvar);
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/hwasan/bitfield-2.c b/gcc/testsuite/c-c++-common/hwasan/bitfield-2.c
new file mode 100644
index 0000000..0b3f3aaa
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/bitfield-2.c
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+
+/* Ensure that hwasan instruments bitfield accesses. */
+struct A
+{
+ /* Ensure the offset from the start of this struct to the bitfield we access
+ is large enough to be in a different tag. */
+ char base[16];
+ int : 4;
+ long x : 7;
+};
+
+int __attribute__ ((noinline, noclone))
+f (void *p) {
+ return ((struct A *)p)->x;
+}
+
+int
+main ()
+{
+ char a = 0;
+ return f (&a);
+}
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* { dg-output "READ of size 2 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/builtin-special-handling.c b/gcc/testsuite/c-c++-common/hwasan/builtin-special-handling.c
new file mode 100644
index 0000000..a7a6d91
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/builtin-special-handling.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-asan" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+/* Only skip the -flto tests without the -flto-partition=none.
+ With -flto-partition=none we still get a asan1 dump file, without that
+ parameter we only get the lto dump files (which means scan-tree-dump-times
+ doesn't work. */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "-flto-partition=none" } } */
+
+typedef __SIZE_TYPE__ size_t;
+/* Functions to observe that HWASAN instruments memory builtins in the expected
+ manner. */
+void * __attribute__((noinline))
+memset_builtin (void *dest, int value, size_t len)
+{
+ return __builtin_memset (dest, value, len);
+}
+
+/* HWASAN avoids strlen because it doesn't know the size of the memory access
+ until *after* the function call. */
+size_t __attribute__ ((noinline))
+strlen_builtin (char *element)
+{
+ return __builtin_strlen (element);
+}
+
+/* First test ensures that the HWASAN_CHECK was emitted before the
+ memset. Second test ensures there was only HWASAN_CHECK (which demonstrates
+ that strlen was not instrumented). */
+/* { dg-final { scan-tree-dump-times "HWASAN_CHECK.*memset" 1 "asan1" } } */
+/* { dg-final { scan-tree-dump-times "HWASAN_CHECK" 1 "asan1" } } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/check-interface.c b/gcc/testsuite/c-c++-common/hwasan/check-interface.c
new file mode 100644
index 0000000..90f52ca
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/check-interface.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/*
+ Test taken from LLVM
+ compiler-rt/test/hwasan/TestCases/check-interface.cpp
+ */
+// Utilizes all flavors of __hwasan_load/store interface functions to verify
+// that the instrumentation and the interface provided by HWASan do match.
+// In case of a discrepancy, this test fails to link.
+
+typedef __UINT8_TYPE__ uint8_t;
+typedef __UINT16_TYPE__ uint16_t;
+typedef __UINT32_TYPE__ uint32_t;
+typedef __UINT64_TYPE__ uint64_t;
+
+#define F(T) void f_##T(T *a, T *b) { *a = *b; }
+
+F(uint8_t)
+F(uint16_t)
+F(uint32_t)
+F(uint64_t)
+
+typedef unsigned V32 __attribute__((__vector_size__(32)));
+F(V32)
+
+int main() {}
diff --git a/gcc/testsuite/c-c++-common/hwasan/halt_on_error-1.c b/gcc/testsuite/c-c++-common/hwasan/halt_on_error-1.c
new file mode 100644
index 0000000..90ca856
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/halt_on_error-1.c
@@ -0,0 +1,24 @@
+/* Test recovery mode. */
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-options "-fsanitize-recover=hwaddress" } */
+/* { dg-set-target-env-var HWASAN_OPTIONS "halt_on_error=false" } */
+/* { dg-shouldfail "hwasan" } */
+
+volatile int sixteen = 16;
+
+int main() {
+ char x[16];
+ __builtin_memset(x, 0, sixteen + 1);
+ asm volatile ("" : : : "memory");
+ volatile int res = x[sixteen];
+ x[sixteen] = res + 3;
+ res = x[sixteen];
+ return 0;
+}
+
+/* { dg-output "WRITE of size 17 at 0x\[0-9a-f\]+.*" } */
+/* { dg-output "READ of size 1 at 0x\[0-9a-f\]+.*" } */
+/* { dg-output "WRITE of size 1 at 0x\[0-9a-f\]+.*" } */
+/* { dg-output "READ of size 1 at 0x\[0-9a-f\]+.*" } */
+
diff --git a/gcc/testsuite/c-c++-common/hwasan/handles-poly_int-marked-vars.c b/gcc/testsuite/c-c++-common/hwasan/handles-poly_int-marked-vars.c
new file mode 100644
index 0000000..685b780
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/handles-poly_int-marked-vars.c
@@ -0,0 +1,37 @@
+/* { dg-do compile { target aarch64-*-* } } */
+/* { dg-additional-options "-march=armv8.6-a+sve -fsanitize-address-use-after-scope" } */
+
+#include <arm_sve.h>
+
+__attribute__((noinline, noclone)) int
+foo (char *a)
+{
+ int i, j = 0;
+ asm volatile ("" : "+r" (a) : : "memory");
+ for (i = 0; i < 12; i++)
+ j += a[i];
+ return j;
+}
+
+int
+main ()
+{
+ int i, j = 0;
+ for (i = 0; i < 4; i++)
+ {
+ char a[12];
+ __SVInt8_t freq;
+ /* Just do something with that `freq` variable so that the compiler
+ doesn't optimise its use away. */
+ if (__builtin_bcmp (&freq, a, 10))
+ j += 1;
+ __builtin_memset (a, 0, sizeof (a));
+ j += foo (a);
+ }
+ return j;
+}
+
+/* Just ensure this compiles without giving an ICE.
+ This is the equivalent of PR 97696 but for HWASAN. HWASAN can handle
+ poly_int sized variables, and this testcase ensures that we don't ICE when
+ given them. */
diff --git a/gcc/testsuite/c-c++-common/hwasan/heap-overflow.c b/gcc/testsuite/c-c++-common/hwasan/heap-overflow.c
new file mode 100644
index 0000000..1374668
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/heap-overflow.c
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-options "-fno-builtin-malloc -fno-builtin-free -fno-builtin-memset" } */
+/* { dg-shouldfail "hwasan" } */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void *memset (void *, int, __SIZE_TYPE__);
+void *malloc (__SIZE_TYPE__);
+void free (void *);
+#ifdef __cplusplus
+}
+#endif
+
+volatile int ten = 10;
+int main(int argc, char **argv) {
+ char *x = (char*)malloc(10);
+ memset(x, 0, 10);
+ int res = x[ten]; /* BOOOM */
+ free(x);
+ return res;
+}
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* { dg-output "READ of size 1 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "located 0 bytes to the right of 10-byte region.*" } */
+/* { dg-output "allocated here:.*" } */
+/* { dg-output "#1 0x\[0-9a-f\]+ +in _*main \[^\n\r]*heap-overflow.c:18" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/hwasan-poison-optimisation.c b/gcc/testsuite/c-c++-common/hwasan/hwasan-poison-optimisation.c
new file mode 100644
index 0000000..2d6bab4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/hwasan-poison-optimisation.c
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+/* { dg-additional-options "-fdump-tree-asan1 -save-temps" } */
+
+/* Here to check that the ASAN_POISON stuff works just fine.
+ This mechanism isn't very often used, but I should at least go through the
+ code-path once in my testfile. */
+int
+main ()
+{
+ int *ptr = 0;
+
+ {
+ int a;
+ ptr = &a;
+ *ptr = 12345;
+ }
+
+ return *ptr;
+}
+
+/* { dg-final { scan-tree-dump-times "ASAN_POISON" 1 "asan1" } } */
+/* { dg-final { scan-assembler-times "bl\\s*__hwasan_tag_mismatch4" 1 } } */
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/hwasan-thread-access-parent.c b/gcc/testsuite/c-c++-common/hwasan/hwasan-thread-access-parent.c
new file mode 100644
index 0000000..828909d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/hwasan-thread-access-parent.c
@@ -0,0 +1,51 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+/* { dg-additional-options "-lpthread" } */
+
+#include <pthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int printf (char const *, ...);
+#ifdef __cplusplus
+}
+#endif
+typedef __UINTPTR_TYPE__ uintptr_t;
+typedef __UINT64_TYPE__ uint64_t;
+
+/* Test that tags are checked across different threads.
+ i.e. if this thread tries to access a different threads memory with the
+ incorrect tag, then this thread fails. */
+void *
+failing_thread_function (void *argument)
+{
+ void * other = (void *)((uint64_t)argument & 0xffffffffffffffULL);
+ int *num = (int*)argument;
+ printf ("(should succeed): first number = %d\n", num[0]);
+ printf ("(now should fail):\n");
+
+ int *othernum = (int*)other;
+ printf (" second number = %d\n", othernum[0]);
+ return (void *)1;
+}
+
+int
+main (int argc, char **argv)
+{
+ int argument[100] = {0};
+ argument[1] = 10;
+ pthread_t thread_index;
+ pthread_create (&thread_index, NULL, failing_thread_function, (void*)argument);
+
+ void *retval;
+ pthread_join (thread_index, &retval);
+
+ return (uintptr_t)retval;
+}
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: 00/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T1.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/hwasan-thread-basic-failure.c b/gcc/testsuite/c-c++-common/hwasan/hwasan-thread-basic-failure.c
new file mode 100644
index 0000000..6a07521
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/hwasan-thread-basic-failure.c
@@ -0,0 +1,48 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+/* { dg-additional-options "-lpthread" } */
+
+/* Ensure the failure mode for hwasan under pthreads looks sane.
+ (Looks sane means that the same error message is printed out rather than an
+ opaque message due to mishandling). */
+
+#include <pthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int printf (char const *, ...);
+#ifdef __cplusplus
+}
+#endif
+typedef __UINTPTR_TYPE__ uintptr_t;
+typedef __UINT64_TYPE__ uint64_t;
+
+void *
+failing_from_stack (void * argument)
+{
+ int internal_array[16] = {0};
+ printf ("(now should fail):");
+ printf (" problem number is %d\n", internal_array[17]);
+ return (void *)1;
+}
+
+int
+main (int argc, char **argv)
+{
+ int argument[100] = {0};
+ argument[1] = 10;
+ pthread_t thread_index;
+ pthread_create (&thread_index, NULL, failing_from_stack, (void*)argument);
+
+ void *retval;
+ pthread_join (thread_index, &retval);
+
+ return (uintptr_t)retval;
+}
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T1.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T1.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/hwasan-thread-clears-stack.c b/gcc/testsuite/c-c++-common/hwasan/hwasan-thread-clears-stack.c
new file mode 100644
index 0000000..09c72a5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/hwasan-thread-clears-stack.c
@@ -0,0 +1,56 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+/* { dg-additional-options "-lpthread" } */
+
+/* This checks the interceptor ABI pthread hooks.
+ The stack of the thread that is finishing must be cleared of shadow tags
+ when that thread exits. */
+
+#include <pthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int printf (char const *, ...);
+#ifdef __cplusplus
+}
+#endif
+typedef __UINTPTR_TYPE__ uintptr_t;
+typedef __UINT64_TYPE__ uint64_t;
+
+__attribute__ ((noinline))
+void * Ident (void * argument)
+{
+ return argument;
+}
+
+void *
+pthread_stack_is_cleared (void *argument)
+{
+ (void)argument;
+ int internal_array[16] = {0};
+ return Ident((void*)internal_array);
+}
+
+int
+main (int argc, char **argv)
+{
+ int argument[100] = {0};
+ argument[1] = 10;
+ pthread_t thread_index;
+ pthread_create (&thread_index, NULL, pthread_stack_is_cleared, (void*)argument);
+
+ void *retval;
+ pthread_join (thread_index, &retval);
+
+ printf ("(should fail): ");
+ printf ("value left in stack is: %d\n", ((int *)retval)[0]);
+
+ return (uintptr_t)retval;
+}
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "HWAddressSanitizer can not describe address in more detail\..*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/hwasan-thread-success.c b/gcc/testsuite/c-c++-common/hwasan/hwasan-thread-success.c
new file mode 100644
index 0000000..b0281f7
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/hwasan-thread-success.c
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-additional-options "-lpthread" } */
+
+/* Just ensure that a basic threaded program works while running with hwasan.
+ */
+
+#include <pthread.h>
+
+extern int printf (const char *, ...);
+typedef __UINTPTR_TYPE__ uintptr_t;
+typedef __UINT64_TYPE__ uint64_t;
+
+void *
+successful_thread_function (void * argument)
+{
+ int *deref = (int *)argument;
+ if (deref[0] == 100)
+ deref[1] = 10;
+ return (void *)0;
+}
+
+int
+main (int argc, char **argv)
+{
+ int argument[100] = {0};
+ argument[1] = 10;
+ pthread_t thread_index;
+ pthread_create (&thread_index, NULL, successful_thread_function, (void*)argument);
+
+ void *retval;
+ pthread_join (thread_index, &retval);
+
+ return (uintptr_t)retval;
+}
diff --git a/gcc/testsuite/c-c++-common/hwasan/kernel-defaults.c b/gcc/testsuite/c-c++-common/hwasan/kernel-defaults.c
new file mode 100644
index 0000000..abfe735
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/kernel-defaults.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fno-sanitize=hwaddress -fsanitize=kernel-hwaddress" } */
+
+
+/* Defaults to check for kernel-hwaddress.
+ 1) No stack tagging => no calls to __hwasan_tag_memory.
+ 2) No block scope tagging (same again).
+ 3) Use sanitize-recover by default (everything ends in noabort). */
+int __attribute__ ((noinline))
+accessing_pointers (int *left, int *right)
+{
+ int x = right[2];
+ left[3] = right[1];
+ return right[1] + left[2];
+}
+
+int __attribute__ ((noinline))
+using_stack (int num)
+{
+ int big_array[10];
+ int other_array[20];
+ accessing_pointers(other_array, big_array);
+ return big_array[num];
+}
+
+#ifndef ARG
+#define ARG 0
+#endif
+int __attribute__ ((noinline))
+main ()
+{
+ using_stack (ARG);
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "__hwasan_tag_memory" } } */
+/* { dg-final { scan-assembler-not "__hwasan_(load|store)\\d(?!_noabort)" } } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/large-aligned-0.c b/gcc/testsuite/c-c++-common/hwasan/large-aligned-0.c
new file mode 100644
index 0000000..5b0071a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/large-aligned-0.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+
+/* Handling large aligned variables.
+ Large aligned variables take a different code-path through expand_stack_vars
+ in cfgexpand.c. This testcase is just to exercise that code-path.
+
+ The alternate code-path produces a second base-pointer through some
+ instructions emitted in the prologue.
+
+ Test cases are:
+ 0) Valid access works without complaint.
+ 1) Invalid access is caught. */
+int __attribute__ ((noinline))
+handle_large_alignment (int num)
+{
+ int other_array[10];
+ int big_array[100] __attribute__ ((aligned (32)));
+ return big_array[num] + other_array[num];
+}
+
+#ifndef ARG
+#define ARG 1
+#endif
+
+int global;
+
+int __attribute__ ((noinline))
+main ()
+{
+ global += handle_large_alignment (ARG);
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/hwasan/large-aligned-1.c b/gcc/testsuite/c-c++-common/hwasan/large-aligned-1.c
new file mode 100644
index 0000000..1aa1303
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/large-aligned-1.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+
+#define ARG 12
+#include "large-aligned-0.c"
+#undef ARG
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* NOTE: This assumes the current tagging mechanism (one at a time from the
+ base and large aligned variables being handled first). */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-0.c b/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-0.c
new file mode 100644
index 0000000..11f422f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-0.c
@@ -0,0 +1,75 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+/* Don't really need this option since there are no vararray/alloca objects in
+ the interesting function, however it never hurts to make doubly sure and
+ make it explicit that we're checking the alternate approach to deallocation.
+ */
+/* { dg-additional-options "--param hwasan-instrument-allocas=0" } */
+
+/* Handling large aligned variables.
+ Large aligned variables take a different code-path through expand_stack_vars
+ in cfgexpand.c. This testcase is just to exercise that code-path.
+
+ The alternate code-path produces a second base-pointer through some
+ instructions emitted in the prologue.
+
+ This eventually follows a different code path for untagging when not tagging
+ allocas. The untagging needs to work at the top of the frame, and this
+ should account for this different base when large aligned variables are
+ around. */
+__attribute__ ((noinline))
+void * Ident (void * argument)
+{
+ return argument;
+}
+
+#ifndef ALIGNMENT
+#define ALIGNMENT
+#endif
+void __attribute__ ((noinline))
+large_alignment_untagging (int num, int *retval, int **big, int **other)
+{
+ int other_array[100] ALIGNMENT;
+ int big_array[100] __attribute__ ((aligned (32)));
+ *retval = big_array[num] + other_array[num];
+ *big = (int*)Ident(big_array);
+ *other = (int*)Ident(other_array);
+}
+
+#ifndef ARG
+#define ARG 0
+#endif
+
+int global;
+
+int __attribute__ ((noinline))
+main ()
+{
+ int retval;
+ int *big, *other;
+ large_alignment_untagging (0, &retval, &big, &other);
+ /* Want to test that both ends of both variables are untagged. */
+ switch (ARG) {
+ case 0:
+ global += big[0];
+ break;
+ case 1:
+ global += big[99];
+ break;
+ case 2:
+ global += other[0];
+ break;
+ case 3:
+ global += other[99];
+ break;
+ }
+ return 0;
+}
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* NOTE: This assumes the current tagging mechanism (one at a time from the
+ base and large aligned variables being handled first). */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-1.c b/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-1.c
new file mode 100644
index 0000000..b2fc522
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-1.c
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+/* { dg-additional-options "--param hwasan-instrument-allocas=0" } */
+
+#define ARG 1
+#include "large-aligned-untagging-0.c"
+#undef ARG
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* NOTE: This assumes the current tagging mechanism (one at a time from the
+ base and large aligned variables being handled first). */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-2.c b/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-2.c
new file mode 100644
index 0000000..ebc4648
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-2.c
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+/* { dg-additional-options "--param hwasan-instrument-allocas=0" } */
+
+#define ARG 2
+#include "large-aligned-untagging-0.c"
+#undef ARG
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* NOTE: This assumes the current tagging mechanism (one at a time from the
+ base and large aligned variables being handled first). */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-3.c b/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-3.c
new file mode 100644
index 0000000..d3a226a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-3.c
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+/* { dg-additional-options "--param hwasan-instrument-allocas=0" } */
+
+#define ARG 3
+#include "large-aligned-untagging-0.c"
+#undef ARG
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* NOTE: This assumes the current tagging mechanism (one at a time from the
+ base and large aligned variables being handled first). */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-4.c b/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-4.c
new file mode 100644
index 0000000..cdd122b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-4.c
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+/* { dg-additional-options "--param hwasan-instrument-allocas=0" } */
+
+#define ARG 0
+#define ALIGNMENT __attribute__ ((aligned (32)))
+#include "large-aligned-untagging-0.c"
+#undef ARG
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* NOTE: This assumes the current tagging mechanism (one at a time from the
+ base and large aligned variables being handled first). */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-5.c b/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-5.c
new file mode 100644
index 0000000..7c4cb5c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-5.c
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+/* { dg-additional-options "--param hwasan-instrument-allocas=0" } */
+
+#define ARG 1
+#define ALIGNMENT __attribute__ ((aligned (32)))
+#include "large-aligned-untagging-0.c"
+#undef ARG
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* NOTE: This assumes the current tagging mechanism (one at a time from the
+ base and large aligned variables being handled first). */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-6.c b/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-6.c
new file mode 100644
index 0000000..f429ed2
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-6.c
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+/* { dg-additional-options "--param hwasan-instrument-allocas=0" } */
+
+#define ARG 2
+#define ALIGNMENT __attribute__ ((aligned (32)))
+#include "large-aligned-untagging-0.c"
+#undef ARG
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* NOTE: This assumes the current tagging mechanism (one at a time from the
+ base and large aligned variables being handled first). */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-7.c b/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-7.c
new file mode 100644
index 0000000..56f16eb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/large-aligned-untagging-7.c
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+/* { dg-additional-options "--param hwasan-instrument-allocas=0" } */
+
+#define ARG 3
+#define ALIGNMENT __attribute__ ((aligned (32)))
+#include "large-aligned-untagging-0.c"
+#undef ARG
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* NOTE: This assumes the current tagging mechanism (one at a time from the
+ base and large aligned variables being handled first). */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/macro-definition.c b/gcc/testsuite/c-c++-common/hwasan/macro-definition.c
new file mode 100644
index 0000000..5f654f5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/macro-definition.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+extern void testfunc(int);
+int foo()
+{
+#ifndef __SANITIZE_HWADDRESS__
+ testfunc(1);
+#endif
+ return 1;
+}
+
+/* { dg-final { scan-assembler-not "testfunc" } } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/no-sanitize-attribute.c b/gcc/testsuite/c-c++-common/hwasan/no-sanitize-attribute.c
new file mode 100644
index 0000000..c0a254d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/no-sanitize-attribute.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+__attribute__((no_sanitize("hwaddress"))) int
+f (int *p, int *q)
+{
+ *p = 42;
+ return *q;
+}
+
+/* Only have one instance of __hwasan, it is __hwasan_init (the module
+ * constructor) there is no instrumentation in the function. */
+/* { dg-final { scan-assembler-times "__hwasan" 1 } } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/param-instrument-mem-intrinsics.c b/gcc/testsuite/c-c++-common/hwasan/param-instrument-mem-intrinsics.c
new file mode 100644
index 0000000..f1e6dc8
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/param-instrument-mem-intrinsics.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+/* { dg-additional-options "--param hwasan-instrument-mem-intrinsics=0" } */
+
+#include "builtin-special-handling.c"
+
+/* With this flag there should be no checking of builtins.
+ The above file only has builtins, and hence there should be no checking
+ after compilation. */
+/* { dg-final { scan-assembler-not "__hwasan_(load|store)" } } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/param-instrument-reads-and-writes.c b/gcc/testsuite/c-c++-common/hwasan/param-instrument-reads-and-writes.c
new file mode 100644
index 0000000..1d565a2
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/param-instrument-reads-and-writes.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "--param hwasan-instrument-writes=0" } */
+
+#include "param-instrument-reads.c"
+
+/* { dg-final { scan-assembler "__hwasan_load" } } */
+/* { dg-final { scan-assembler-not "__hwasan_store" } } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/param-instrument-reads.c b/gcc/testsuite/c-c++-common/hwasan/param-instrument-reads.c
new file mode 100644
index 0000000..9b8049a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/param-instrument-reads.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-additional-options "--param hwasan-instrument-reads=0" } */
+
+typedef __SIZE_TYPE__ size_t;
+/* Particular code doesn't really matter, the requirement is that it has both
+ loads and stores in it. */
+__attribute__ ((noinline))
+int reader (int *array, size_t num)
+{
+ return array[num];
+}
+
+int __attribute__ ((noinline))
+writer (int *array, size_t num, int value)
+{
+ array[num] = value;
+ return num + value;
+}
+
+/* { dg-final { scan-assembler-not "__hwasan_load" } } */
+/* { dg-final { scan-assembler "__hwasan_store" } } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/param-instrument-writes.c b/gcc/testsuite/c-c++-common/hwasan/param-instrument-writes.c
new file mode 100644
index 0000000..0f04fad
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/param-instrument-writes.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "--param hwasan-instrument-reads=0 --param hwasan-instrument-writes=0" } */
+
+#include "param-instrument-reads.c"
+
+/* { dg-final { scan-assembler-not "__hwasan_load" } } */
+/* { dg-final { scan-assembler-not "__hwasan_store" } } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/random-frame-tag.c b/gcc/testsuite/c-c++-common/hwasan/random-frame-tag.c
new file mode 100644
index 0000000..8e55b29
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/random-frame-tag.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "--param hwasan-random-frame-tag=1" } */
+
+#include "stack-tagging-basic-0.c"
+
+/* Random frame tag => call to __hwasan_generate_tag. */
+/* { dg-final { scan-assembler "__hwasan_generate_tag" } } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/sanity-check-pure-c.c b/gcc/testsuite/c-c++-common/hwasan/sanity-check-pure-c.c
new file mode 100644
index 0000000..a42921bb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/sanity-check-pure-c.c
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-options "-fno-builtin-malloc -fno-builtin-free" } */
+/* { dg-shouldfail "asan" } */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void *malloc (__SIZE_TYPE__);
+void free (void *);
+#ifdef __cplusplus
+}
+#endif
+
+int main() {
+ char *x = (char*)malloc(10);
+ free(x);
+ return x[5];
+}
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* { dg-output "READ of size 1 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "located 5 bytes inside of 10-byte region.*" } */
+/* { dg-output "freed by thread T0 here:.*" } */
+/* { dg-output "previously allocated here:" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/setjmp-longjmp-0.c b/gcc/testsuite/c-c++-common/hwasan/setjmp-longjmp-0.c
new file mode 100644
index 0000000..019c4ea
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/setjmp-longjmp-0.c
@@ -0,0 +1,54 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+
+#include <setjmp.h>
+#include <stdio.h>
+
+/*
+ Testing longjmp/setjmp should test.
+
+ 0) Nothing special happens with the jmp_buf.
+ 1) Accesses to scopes jmp'd over are caught.
+ */
+int __attribute__ ((noinline))
+uses_longjmp (int **other_array, int num, jmp_buf env)
+{
+ int internal_array[100] = {0};
+ *other_array = &internal_array[0];
+ if (num % 2)
+ longjmp (env, num);
+ else
+ return num % 8;
+}
+
+int __attribute__ ((noinline))
+uses_setjmp (int num)
+{
+ int big_array[100];
+ int *other_array = NULL;
+ sigjmp_buf cur_env;
+ int temp = 0;
+ if ((temp = sigsetjmp (cur_env, 1)) != 0)
+ {
+ if (other_array != NULL)
+ printf ("Value pointed to in other_array[0]: %d\n",
+ other_array[0]);
+
+ printf ("Longjmp returned %d.\n", temp);
+ return 10;
+ }
+ else
+ {
+ return uses_longjmp (&other_array, num, cur_env);
+ }
+}
+
+#ifndef ARG
+#define ARG 0
+#endif
+int __attribute__ ((noinline))
+main ()
+{
+ uses_setjmp (ARG);
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/hwasan/setjmp-longjmp-1.c b/gcc/testsuite/c-c++-common/hwasan/setjmp-longjmp-1.c
new file mode 100644
index 0000000..6a4fcee
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/setjmp-longjmp-1.c
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+
+/*
+ Testing longjmp/setjmp should test.
+
+ 0) Nothing special happens with the jmp_buf.
+ 1) Accesses to scopes jmp'd over are caught.
+ */
+
+#define ARG 1
+#include "setjmp-longjmp-0.c"
+#undef ARG
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/stack-tagging-basic-0.c b/gcc/testsuite/c-c++-common/hwasan/stack-tagging-basic-0.c
new file mode 100644
index 0000000..1141141
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/stack-tagging-basic-0.c
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+
+/* Basic tests for stack tagging.
+
+ 0) Valid accesses work.
+ 1) Accesses outside of a variable crash.
+*/
+int __attribute__ ((noinline))
+accessing_pointers (int *left, int *right)
+{
+ int x = right[2];
+ left[3] = right[1];
+ return right[1] + left[2];
+}
+
+int __attribute__ ((noinline))
+using_stack (int num)
+{
+ int big_array[10];
+ int other_array[20];
+ accessing_pointers(other_array, big_array);
+ return big_array[num];
+}
+
+#ifndef ARG
+#define ARG 0
+#endif
+
+int global;
+
+int __attribute__ ((noinline))
+main ()
+{
+ global += using_stack (ARG);
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/hwasan/stack-tagging-basic-1.c b/gcc/testsuite/c-c++-common/hwasan/stack-tagging-basic-1.c
new file mode 100644
index 0000000..90d5837
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/stack-tagging-basic-1.c
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+
+/* Basic tests for stack tagging.
+
+ 0) Accesses outside of a variable crash.
+ 1) Valid accesses work.
+*/
+
+#define ARG 17
+#include "stack-tagging-basic-0.c"
+#undef ARG
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/stack-tagging-disable.c b/gcc/testsuite/c-c++-common/hwasan/stack-tagging-disable.c
new file mode 100644
index 0000000..9bcae16
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/stack-tagging-disable.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "--param hwasan-instrument-stack=0" } */
+
+
+/* No stack tagging => no calls to __hwasan_tag_memory. */
+int __attribute__ ((noinline))
+accessing_pointers (int *left, int *right)
+{
+ int x = right[2];
+ left[3] = right[1];
+ return right[1] + left[2];
+}
+
+int __attribute__ ((noinline))
+using_stack (int num)
+{
+ int big_array[10];
+ int other_array[20];
+ accessing_pointers(other_array, big_array);
+ return big_array[num];
+}
+
+#ifndef ARG
+#define ARG 0
+#endif
+int __attribute__ ((noinline))
+main ()
+{
+ using_stack (ARG);
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "__hwasan_tag_memory" } } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/unprotected-allocas-0.c b/gcc/testsuite/c-c++-common/hwasan/unprotected-allocas-0.c
new file mode 100644
index 0000000..8846515
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/unprotected-allocas-0.c
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-additional-options "--param hwasan-instrument-allocas=0 -save-temps" } */
+/* Only run this test without optimisation. When running with optimisation we
+ use the unprotected-allocas-1.c file that also checks there are no memory
+ tagging calls (since when optimised the only variable on the stack should be
+ the vararray/alloca). */
+/* { dg-skip-if "" { *-*-* } { "-O1" "-O2" "-O3" } { "" } } */
+
+#define alloca __builtin_alloca
+#define assert(x) if (!(x)) __builtin_abort ()
+
+char tag_of (void * x) { return ((unsigned long long)x) >> 56; }
+
+int __attribute__ ((noinline))
+using_alloca (int num)
+{
+ int retval = 0;
+ int *big_array = (int*)alloca (num * sizeof (int));
+ char alloca_tag = tag_of (big_array);
+ assert (alloca_tag == 0);
+ for (int i = 0; i < num; ++i) {
+ retval += big_array[i];
+ }
+ return retval;
+}
+
+int __attribute__ ((noinline))
+using_vararray (int num)
+{
+ int retval = 0;
+ int big_array[num];
+ char vararray_tag = tag_of (big_array);
+ assert (vararray_tag == 0);
+ for (int i = 0; i < num; ++i) {
+ retval += big_array[i];
+ }
+ return retval;
+}
+
+int main()
+{
+ using_alloca (16);
+ using_vararray (12);
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/hwasan/unprotected-allocas-1.c b/gcc/testsuite/c-c++-common/hwasan/unprotected-allocas-1.c
new file mode 100644
index 0000000..752edc1
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/unprotected-allocas-1.c
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-additional-options "--param hwasan-instrument-allocas=0 -save-temps" } */
+/* Only test there's no tagging done when not at -O0. Without optimisation
+ the compiler creates a bunch of other variables on the stack other than the
+ vararray/alloca object.
+ We also avoid checking when using -flto, since with LTO the compiler can
+ recognise the vararray is only used with one size and that size is known at
+ compile time -- when the compiler recognises that it instead creates a
+ static array, which gets tagged as is expected but not as the test expects.
+ */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-flto" } { "" } } */
+
+#include "unprotected-allocas-0.c"
+
+/* { dg-final { scan-assembler-not "__hwasan_tag_memory" } } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/use-after-free.c b/gcc/testsuite/c-c++-common/hwasan/use-after-free.c
new file mode 100644
index 0000000..41a3569
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/use-after-free.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-options "-fno-builtin-malloc -fno-builtin-free" } */
+/* { dg-shouldfail "hwasan" } */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void *malloc (__SIZE_TYPE__);
+void free (void *);
+#ifdef __cplusplus
+}
+#endif
+
+int main() {
+ char *x = (char*)malloc(10);
+ free(x);
+ return x[5];
+}
+
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* { dg-output "READ of size 1 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\] \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "is located 5 bytes inside of 10-byte region.*" } */
+/* { dg-output "freed by thread T0 here:.*" } */
+/* { dg-output "#1\[^\n\r]*main\[^\n\r]*use-after-free.c:17.*" } */
+/* { dg-output "previously allocated here:.*" } */
+/* { dg-output "#1\[^\n\r]*main\[^\n\r]*use-after-free.c:16" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/vararray-outside-caught.c b/gcc/testsuite/c-c++-common/hwasan/vararray-outside-caught.c
new file mode 100644
index 0000000..35a344d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/vararray-outside-caught.c
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+
+int __attribute__ ((noinline))
+check_vararray (int num)
+{
+ int var_array[num];
+ int other_array[10];
+ return var_array[12];
+}
+
+int __attribute__ ((noinline))
+main ()
+{
+ return check_vararray (3);
+}
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* { dg-output "READ of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/c-c++-common/hwasan/vararray-stack-restore-correct.c b/gcc/testsuite/c-c++-common/hwasan/vararray-stack-restore-correct.c
new file mode 100644
index 0000000..f4e1f57
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/vararray-stack-restore-correct.c
@@ -0,0 +1,43 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+
+#include <stdio.h>
+
+/* Testing that a function with outgoing arguments correctly decrements the
+ stack pointer when a vararray goes out of scope. */
+
+const char *
+other (int argc, int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l)
+{
+ const char ** other;
+ {
+ const char * test_array[argc];
+ test_array[0] = "test string";
+ test_array[argc - 1] = "hello";
+ /* To prevent optimisation. */
+ printf("While the value stored in our test_array is: %s\n",
+ test_array[argc - 1]);
+ other = test_array;
+ }
+ /* With the below function call (the one with many arguments), some of the
+ arguments have to be put on the stack, which means we have to reserve some
+ space on the stack for these arguments and that the VLA is stored at a
+ position that is not the stack pointer. */
+ printf("Hello there!\nOur numbers today are: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
+ a, b, c, d, e, f, g, h, i, j, k, l);
+ /* This should fail due to a bad read access. */
+ return other[0];
+}
+
+int
+main ()
+{
+ int a, b, c, d, e, f, g, h, i, j, k, l;
+ const char * retval = other (1, a, b, c, d, e, f, g, h, i, j, k, l);
+ /* Numbers don't matter here, just want to ensure the program is reading them
+ so we know they won't be optimised out. */
+ if (retval)
+ return 1;
+ return 10;
+}
diff --git a/gcc/testsuite/c-c++-common/hwasan/very-large-objects.c b/gcc/testsuite/c-c++-common/hwasan/very-large-objects.c
new file mode 100644
index 0000000..5526535
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/hwasan/very-large-objects.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+
+/* Ensure the sanitizer can handle very large offsets (i.e. that the hooks
+ handle offsets too large for the relevant instructions).
+ Just want to make sure this compiles without an ICE. */
+#ifndef ASIZE
+# define ASIZE 0x10000000000UL
+#endif
+
+typedef __UINT64_TYPE__ uint64_t;
+
+#if __LONG_MAX__ < 8 * ASIZE
+# undef ASIZE
+# define ASIZE 4096
+#endif
+
+extern void abort (void);
+
+int __attribute__((noinline))
+foo (const char *s)
+{
+ if (!s)
+ return 1;
+ if (s[0] != 'a')
+ abort ();
+ s += ASIZE - 1;
+ if (s[0] != 'b')
+ abort ();
+ return 0;
+}
+
+int (*fn) (const char *) = foo;
+
+int __attribute__((noinline))
+bar (void)
+{
+ char s[ASIZE];
+ s[0] = 'a';
+ s[ASIZE - 1] = 'b';
+ foo (s);
+ foo (s);
+ return 0;
+}
+
+int __attribute__((noinline))
+baz (long i)
+{
+ if (i)
+ return fn (0);
+ else
+ {
+ char s[ASIZE];
+ s[0] = 'a';
+ s[ASIZE - 1] = 'b';
+ foo (s);
+ foo (s);
+ return fn (0);
+ }
+}
+
+int __attribute__((noinline))
+very_large_offset (int *p)
+{
+ char init_array[(uint64_t)0xfefefef];
+ char other_array[(uint64_t)0xfefefef];
+ return (int)init_array[p[1]] + (int)other_array[p[0]];
+}
+
diff --git a/gcc/testsuite/c-c++-common/patchable_function_entry-error-3.c b/gcc/testsuite/c-c++-common/patchable_function_entry-error-3.c
index 4490e5c..c3ef54d 100644
--- a/gcc/testsuite/c-c++-common/patchable_function_entry-error-3.c
+++ b/gcc/testsuite/c-c++-common/patchable_function_entry-error-3.c
@@ -3,15 +3,15 @@
void
__attribute__((patchable_function_entry(65536)))
-foo1 (void) { /* { dg-warning "'patchable_function_entry' attribute argument '65536' is out of range" } */
+foo1 (void) { /* { dg-warning "'patchable_function_entry' attribute argument '65536' exceeds 65535" } */
}
void
__attribute__((patchable_function_entry(65536,1)))
-foo2 (void) { /* { dg-warning "'patchable_function_entry' attribute argument '65536' is out of range" } */
+foo2 (void) { /* { dg-warning "'patchable_function_entry' attribute argument '65536' exceeds 65535" } */
}
void
__attribute__((patchable_function_entry(65536,65536)))
-foo3 (void) { /* { dg-warning "'patchable_function_entry' attribute argument '65536' is out of range" } */
+foo3 (void) { /* { dg-warning "'patchable_function_entry' attribute argument '65536' exceeds 65535" } */
}
diff --git a/gcc/testsuite/c-c++-common/torture/attr-noinit-1.c b/gcc/testsuite/c-c++-common/torture/attr-noinit-1.c
new file mode 100644
index 0000000..877e764
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/attr-noinit-1.c
@@ -0,0 +1,7 @@
+/* { dg-do run } */
+/* { dg-require-effective-target noinit } */
+/* { dg-skip-if "data LMA != VMA" { msp430-*-* } { "-mlarge" } } */
+/* { dg-options "-save-temps" } */
+/* { dg-final { scan-assembler ".section\t.noinit,\"aw\"\n" } } */
+
+#include "attr-noinit-main.inc"
diff --git a/gcc/testsuite/c-c++-common/torture/attr-noinit-2.c b/gcc/testsuite/c-c++-common/torture/attr-noinit-2.c
new file mode 100644
index 0000000..befa2a0
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/attr-noinit-2.c
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+/* { dg-require-effective-target noinit } */
+/* { dg-options "-fdata-sections -save-temps" } */
+/* { dg-skip-if "data LMA != VMA" { msp430-*-* } { "-mlarge" } } */
+/* { dg-final { scan-assembler ".section\t.noinit.var_noinit,\"aw\"\n" } } */
+
+/* Test the "noinit" attribute with -fdata-sections. */
+#include "attr-noinit-main.inc"
diff --git a/gcc/testsuite/c-c++-common/torture/attr-noinit-3.c b/gcc/testsuite/c-c++-common/torture/attr-noinit-3.c
new file mode 100644
index 0000000..519e88a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/attr-noinit-3.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-require-effective-target noinit } */
+/* { dg-options "-flto -save-temps" } */
+/* { dg-skip-if "data LMA != VMA" { msp430-*-* } { "-mlarge" } } */
+/* { dg-final { scan-file attr-noinit-3.ltrans0.ltrans.s ".section\t\.noinit,\"aw\"\n" } } */
+
+/* Test the "noinit" attribute with -flto. Specifically examine the
+ final LTO assembly file, to ensure the "noinit" setting on the variable
+ hasn't been lost. */
+#include "attr-noinit-main.inc"
+
diff --git a/gcc/testsuite/c-c++-common/torture/attr-noinit-invalid.c b/gcc/testsuite/c-c++-common/torture/attr-noinit-invalid.c
new file mode 100644
index 0000000..c3b5fff
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/attr-noinit-invalid.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target noinit } */
+/* { dg-options "-Wattributes" } */
+
+/* Check warning/error messages for "noinit" attribute misuse. */
+int __attribute__((noinit)) noinit_fn (void); /* { dg-warning "ignoring 'noinit' attribute not set on a variable" } */
+int __attribute__((section ("mysection"), noinit)) noinit_section1; /* { dg-warning "because it conflicts with attribute" } */
+int __attribute__((noinit, section ("mysection"))) noinit_section2; /* { dg-warning "because it conflicts with attribute" } */
+const int __attribute__((noinit)) noinit_const; /* { dg-warning "ignoring 'noinit' attribute set on const variable" } */
+/* { dg-error "uninitialized 'const noinit_const'" "" { target c++ } .-1 } */
+int __attribute__((noinit)) noinit_init = 42; /* { dg-warning "ignoring 'noinit' attribute set on initialized variable" } */
+void foo (void) { int __attribute__((noinit)) local_noinit; } /* { dg-error "'noinit' attribute cannot be specified for local variables" } */
diff --git a/gcc/testsuite/gcc.c-torture/execute/noinit-attribute.c b/gcc/testsuite/c-c++-common/torture/attr-noinit-main.inc
index 20a2a45..92cdb9b 100644
--- a/gcc/testsuite/gcc.c-torture/execute/noinit-attribute.c
+++ b/gcc/testsuite/c-c++-common/torture/attr-noinit-main.inc
@@ -1,16 +1,16 @@
-/* { dg-do run } */
-/* { dg-require-effective-target noinit } */
-/* { dg-options "-O2" } */
-/* { dg-skip-if "data LMA != VMA" { msp430-*-* } { "-mlarge" } } */
-
-/* This test checks that noinit data is handled correctly.
+/* This test checks that data marked with the "noinit" attribute is handled
+ correctly.
If data LMA != VMA (e.g. for simulating the copy of data from ROM to RAM),
then var_init will always be re-initialized to 2 and this test will loop
- forever. */
+ forever, so it must be skipped for those targets. */
+#ifdef __cplusplus
+extern "C" {
+#endif
extern void _start (void) __attribute__ ((noreturn));
-extern void abort (void) __attribute__ ((noreturn));
-extern void exit (int) __attribute__ ((noreturn));
+#ifdef __cplusplus
+}
+#endif
int var_common;
int var_zero = 0;
@@ -18,24 +18,19 @@ 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 ();
+ __builtin_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 ();
+ __builtin_abort ();
switch (var_init)
{
@@ -45,19 +40,19 @@ main (void)
break;
case 3:
- /* Second time through - make sure that d has not been reset. */
+ /* Second time through - make sure that var_noinit has not been reset. */
if (var_noinit != 3)
- abort ();
- exit (0);
+ __builtin_abort ();
+ __builtin_exit (0);
default:
/* Any other value for var_init is an error. */
- abort ();
+ __builtin_abort ();
}
/* Simulate a processor reset by calling the C startup code. */
_start ();
/* Should never reach here. */
- abort ();
+ __builtin_abort ();
}
diff --git a/gcc/testsuite/c-c++-common/torture/attr-persistent-1.c b/gcc/testsuite/c-c++-common/torture/attr-persistent-1.c
new file mode 100644
index 0000000..72dc3c2
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/attr-persistent-1.c
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+/* { dg-require-effective-target persistent } */
+/* { dg-skip-if "data LMA != VMA" { msp430-*-* } { "-mlarge" } } */
+/* { dg-options "-save-temps" } */
+/* { dg-final { scan-assembler ".section\t.persistent,\"aw\"\n" } } */
+
+/* Test the "persistent" attribute. */
+#include "attr-persistent-main.inc"
diff --git a/gcc/testsuite/c-c++-common/torture/attr-persistent-2.c b/gcc/testsuite/c-c++-common/torture/attr-persistent-2.c
new file mode 100644
index 0000000..a7de0d5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/attr-persistent-2.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target persistent } */
+/* { dg-skip-if "data LMA != VMA" { msp430-*-* } { "-mlarge" } } */
+/* { dg-options "-fdata-sections -save-temps" } */
+/* { dg-final { scan-assembler ".section\t.persistent.var_persistent,\"aw\"\n" } } */
+
+/* Test the "persistent" attribute with -fdata-sections. */
+#include "attr-persistent-main.inc"
diff --git a/gcc/testsuite/c-c++-common/torture/attr-persistent-3.c b/gcc/testsuite/c-c++-common/torture/attr-persistent-3.c
new file mode 100644
index 0000000..3e4fd28
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/attr-persistent-3.c
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-require-effective-target persistent } */
+/* { dg-options "-flto -save-temps" } */
+/* { dg-skip-if "data LMA != VMA" { msp430-*-* } { "-mlarge" } } */
+/* { dg-final { scan-file attr-persistent-3.ltrans0.ltrans.s ".section\t\.persistent,\"aw\"\n" } } */
+
+/* Test the "persistent" attribute with -flto. Specifically examine the
+ final LTO assembly file, to ensure the "persistent" setting on the variable
+ hasn't been lost. */
+#include "attr-persistent-main.inc"
diff --git a/gcc/testsuite/c-c++-common/torture/attr-persistent-invalid.c b/gcc/testsuite/c-c++-common/torture/attr-persistent-invalid.c
new file mode 100644
index 0000000..06d9f35
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/attr-persistent-invalid.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target persistent } */
+/* { dg-options "-Wattributes" } */
+
+/* Check warning/error messages for "persistent" attribute misuse. */
+int __attribute__((persistent)) persistent_fn (void); /* { dg-warning "ignoring 'persistent' attribute not set on a variable" } */
+int __attribute__((section ("mysection"), persistent)) persistent_section1 = 1; /* { dg-warning "because it conflicts with attribute" } */
+int __attribute__((persistent, section ("mysection"))) persistent_section2 = 2; /* { dg-warning "because it conflicts with attribute" } */
+const int __attribute__((persistent)) persistent_const = 3; /* { dg-warning "ignoring 'persistent' attribute set on const variable" } */
+int __attribute__((persistent)) persistent_init; /* { dg-warning "ignoring 'persistent' attribute set on uninitialized variable" } */
+void foo (void) { int __attribute__((persistent)) local_persistent = 4; } /* { dg-error "'persistent' attribute cannot be specified for local variables" } */
diff --git a/gcc/testsuite/c-c++-common/torture/attr-persistent-main.inc b/gcc/testsuite/c-c++-common/torture/attr-persistent-main.inc
new file mode 100644
index 0000000..a442141
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/attr-persistent-main.inc
@@ -0,0 +1,58 @@
+/* This test checks that data marked with the "persistent" attribute is handled
+ correctly.
+ If data LMA != VMA (e.g. for simulating the copy of data from ROM to RAM),
+ then var_init will always be re-initialized to 2 and this test will loop
+ forever, so it must be skipped for those targets. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern void _start (void) __attribute__ ((noreturn));
+#ifdef __cplusplus
+}
+#endif
+
+int var_common;
+int var_zero = 0;
+int var_one = 1;
+int __attribute__((persistent)) var_persistent = 2;
+int var_init = 2;
+
+int
+main (void)
+{
+ /* Make sure that the C startup code has correctly initialized the ordinary variables. */
+ if (var_common != 0)
+ __builtin_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 || var_persistent != 2)
+ __builtin_abort ();
+
+ switch (var_init)
+ {
+ case 2:
+ /* First time through - change all the values. */
+ var_common = var_zero = var_one = var_persistent = var_init = 3;
+ break;
+
+ case 3:
+ /* Second time through - make sure that var_persistent has not been reset. */
+ if (var_persistent != 3)
+ __builtin_abort ();
+ __builtin_exit (0);
+
+ default:
+ /* Any other value for var_init is an error. */
+ __builtin_abort ();
+ }
+
+ /* Simulate a processor reset by calling the C startup code. */
+ _start ();
+
+ /* Should never reach here. */
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-1.c b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-1.c
new file mode 100644
index 0000000..6b01a56
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-1.c
@@ -0,0 +1,47 @@
+/* PR libstdc++/88101 */
+
+int i1, i2;
+long double l1, l2;
+struct S { char a; short b; char c; int d; char e; long long f; char g; long double h; } s1, s2;
+struct T { int a; struct S b[3]; int c; } t1, t2;
+struct U { int a : 3; int : 2; int b : 15; int : 14; int c : 1; int : 0; int : 3; int d : 2; int : 3; int e : 13; int : 3; signed char f; } u1, u2;
+
+__attribute__((noipa)) void
+foo (int *i, long double *l, struct S *s, struct T *t, struct U *u)
+{
+ *i = 123;
+ *l = -123.456L;
+ s->a = 1; s->b = 2; s->c = 3; s->d = 4; s->e = 5; s->f = 6; s->g = 7; s->h = 18.52L;
+ t->a = 8; t->c = 9;
+ t->b[0].a = 11; t->b[0].b = 12; t->b[0].c = 13; t->b[0].d = 14;
+ t->b[0].e = 15; t->b[0].f = 16; t->b[0].g = 17; t->b[0].h = 18.26L;
+ t->b[1].a = 21; t->b[1].b = 22; t->b[1].c = 23; t->b[1].d = 24;
+ t->b[1].e = 25; t->b[1].f = 26; t->b[1].g = 27; t->b[1].h = 28.26L;
+ t->b[2].a = 31; t->b[2].b = 32; t->b[2].c = 33; t->b[2].d = 34;
+ t->b[2].e = 35; t->b[2].f = 36; t->b[2].g = 37; t->b[2].h = 38.26L;
+ u->a = -1; u->b = -1; u->c = -1; u->d = -1; u->e = -1; u->f = -1;
+}
+
+int
+main ()
+{
+ __builtin_memset (&i2, -1, sizeof (i2));
+ __builtin_memset (&l2, -1, sizeof (i2));
+ __builtin_memset (&s2, -1, sizeof (s2));
+ __builtin_memset (&t2, -1, sizeof (t2));
+ __builtin_memset (&u2, -1, sizeof (u2));
+ foo (&i1, &l1, &s1, &t1, &u1);
+ foo (&i2, &l2, &s2, &t2, &u2);
+ __builtin_clear_padding (&i2);
+ __builtin_clear_padding (&l2);
+ __builtin_clear_padding (&s2);
+ __builtin_clear_padding (&t2);
+ __builtin_clear_padding (&u2);
+ if (__builtin_memcmp (&i1, &i2, sizeof (i1))
+ || __builtin_memcmp (&l1, &l2, sizeof (l1))
+ || __builtin_memcmp (&s1, &s2, sizeof (s1))
+ || __builtin_memcmp (&t1, &t2, sizeof (t1))
+ || __builtin_memcmp (&u1, &u2, sizeof (u1)))
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-2.c b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-2.c
new file mode 100644
index 0000000..1188bc0
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-2.c
@@ -0,0 +1,24 @@
+/* PR libstdc++/88101 */
+
+typedef int T __attribute__((aligned (16384)));
+struct S { char a; short b; long double c; T d; T e; long long f; };
+
+__attribute__((noipa)) void
+foo (struct S *s)
+{
+ s->a = -1; s->b = -1; s->c = -18.52L; s->d = -1; s->e = -1; s->f = -1;
+}
+
+int
+main ()
+{
+ struct S s1, s2;
+ __builtin_memset (&s1, 0, sizeof (s1));
+ __builtin_memset (&s2, -1, sizeof (s2));
+ foo (&s1);
+ foo (&s2);
+ __builtin_clear_padding (&s2);
+ if (__builtin_memcmp (&s1, &s2, sizeof (s1)))
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-3.c b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-3.c
new file mode 100644
index 0000000..edb7c8e
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-3.c
@@ -0,0 +1,65 @@
+/* PR libstdc++/88101 */
+
+union V { char a; signed char b; unsigned char c; };
+struct T { char a; int b; union V c; };
+union U { int a; long double b; struct T c; };
+struct S { char a; union U b; long long c; char d; } s1, s2;
+
+__attribute__((noipa)) void
+foo (struct S *s, int x)
+{
+ s->a = -1; s->c = -1; s->d = -1;
+ switch (x)
+ {
+ case 0:
+ s->b.a = -1;
+ break;
+ case 1:
+ s->b.b = -12345.25L;
+ break;
+ case 2:
+ s->b.c.a = -1;
+ s->b.c.b = -1;
+ s->b.c.c.b = -1;
+ break;
+ }
+}
+
+int
+main ()
+{
+ __builtin_memset (&s1, 0, sizeof (s1));
+ __builtin_memset (&s2, -1, sizeof (s2));
+ foo (&s1, 0);
+ foo (&s2, 0);
+ __builtin_clear_padding (&s2);
+ if (s2.b.a != (char) -1)
+ __builtin_abort ();
+ __builtin_clear_padding (&s2.b.a);
+ __builtin_memset (&s2.b.a + 1, 0, sizeof (union U) - sizeof (s2.b.a));
+ if (__builtin_memcmp (&s1, &s2, sizeof (s1)))
+ __builtin_abort ();
+ __builtin_memset (&s1, 0, sizeof (s1));
+ __builtin_memset (&s2, -1, sizeof (s2));
+ foo (&s1, 1);
+ foo (&s2, 1);
+ __builtin_clear_padding (&s2);
+ if (s2.b.b != -12345.25L)
+ __builtin_abort ();
+ __builtin_clear_padding (&s2.b.b);
+ __builtin_memset (&s2.b.b + 1, 0, sizeof (union U) - sizeof (s2.b.b));
+ if (__builtin_memcmp (&s1, &s2, sizeof (s1)))
+ __builtin_abort ();
+ __builtin_memset (&s1, 0, sizeof (s1));
+ __builtin_memset (&s2, -1, sizeof (s2));
+ foo (&s1, 2);
+ foo (&s2, 2);
+ __builtin_clear_padding (&s2);
+ if (s2.b.c.a != (char) -1 || s2.b.c.b != -1 || s2.b.c.c.b != -1)
+ __builtin_abort ();
+ __builtin_clear_padding (&s2.b.c);
+ __builtin_memset (&s2.b.c + 1, 0, sizeof (union U) - sizeof (s2.b.c));
+ if (__builtin_memcmp (&s1, &s2, sizeof (s1)))
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-4.c b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-4.c
new file mode 100644
index 0000000..d24f3b5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-4.c
@@ -0,0 +1,59 @@
+/* PR libstdc++/88101 */
+
+struct S { char a; short b; char c; };
+
+__attribute__((noipa)) void
+foo (int m, int n, int o)
+{
+ long double a1[m];
+ long double a2[m];
+ struct S b1[m][n];
+ struct S b2[m][n];
+ struct S c1[m][n][o];
+ struct S c2[m][n][o];
+ int i, j, k;
+ __builtin_memset (&a1, 0, sizeof (a1));
+ __builtin_memset (&a2, ~0, sizeof (a2));
+ __builtin_memset (&b1, 0, sizeof (b1));
+ __builtin_memset (&b2, ~0, sizeof (b2));
+ __builtin_memset (&c1, 0, sizeof (c1));
+ __builtin_memset (&c2, ~0, sizeof (c2));
+ for (i = 0; i < m; i++)
+ {
+ a1[i] = 13.132L;
+ a2[i] = 13.132L;
+ for (j = 0; j < n; j++)
+ {
+ b1[i][j].a = -1;
+ b1[i][j].b = -1;
+ b1[i][j].c = -1;
+ b2[i][j].a = -1;
+ b2[i][j].b = -1;
+ b2[i][j].c = -1;
+ for (k = 0; k < o; k++)
+ {
+ c1[i][j][k].a = -1;
+ c1[i][j][k].b = -1;
+ c1[i][j][k].c = -1;
+ c2[i][j][k].a = -1;
+ c2[i][j][k].b = -1;
+ c2[i][j][k].c = -1;
+ }
+ }
+ }
+ __builtin_clear_padding (&a2);
+ __builtin_clear_padding (&b2);
+ __builtin_clear_padding (&c2);
+ if (__builtin_memcmp (&a1, &a2, sizeof (a1))
+ || __builtin_memcmp (&b1, &b2, sizeof (b1))
+ || __builtin_memcmp (&c1, &c2, sizeof (c1)))
+ __builtin_abort ();
+}
+
+int
+main ()
+{
+ foo (5, 3, 4);
+ foo (17, 2, 1);
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-5.c b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-5.c
new file mode 100644
index 0000000..d5dbafe
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-5.c
@@ -0,0 +1,49 @@
+/* PR libstdc++/88101 */
+
+struct S { char a; short b; char c; } s1[24], s2[24];
+struct T { char a; long long b; char c; struct S d[3]; long long e; char f; } t1, t2;
+struct U { char a; long long b; char c; struct S d[25]; long long e; char f; } u1, u2;
+
+__attribute__((noipa)) void
+foo (struct S *s, struct T *t, struct U *u)
+{
+ int i;
+ t->a = -1; t->b = -1; t->c = -1; t->e = -1; t->f = -1;
+ u->a = -1; u->b = -1; u->c = -1; u->e = -1; u->f = -1;
+ for (i = 0; i < 24; i++)
+ {
+ s[i].a = -1;
+ s[i].b = -1;
+ s[i].c = -1;
+ }
+ for (i = 0; i < 3; i++)
+ {
+ t->d[i].a = -1;
+ t->d[i].b = -1;
+ t->d[i].c = -1;
+ }
+ for (i = 0; i < 25; i++)
+ {
+ u->d[i].a = -1;
+ u->d[i].b = -1;
+ u->d[i].c = -1;
+ }
+}
+
+int
+main ()
+{
+ __builtin_memset (&s2, -1, sizeof (s2));
+ __builtin_memset (&t2, -1, sizeof (t2));
+ __builtin_memset (&u2, -1, sizeof (u2));
+ foo (&s1[0], &t1, &u1);
+ foo (&s2[0], &t2, &u2);
+ __builtin_clear_padding (&s2);
+ __builtin_clear_padding (&t2);
+ __builtin_clear_padding (&u2);
+ if (__builtin_memcmp (&s1, &s2, sizeof (s1))
+ || __builtin_memcmp (&t1, &t2, sizeof (t1))
+ || __builtin_memcmp (&u1, &u2, sizeof (u1)))
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/ubsan/sanitize-recover-7.c b/gcc/testsuite/c-c++-common/ubsan/sanitize-recover-7.c
index a571f2b..55db0c0 100644
--- a/gcc/testsuite/c-c++-common/ubsan/sanitize-recover-7.c
+++ b/gcc/testsuite/c-c++-common/ubsan/sanitize-recover-7.c
@@ -3,4 +3,4 @@
int i;
-/* { dg-error ".-fsanitize=address. and .-fsanitize=kernel-address. are incompatible with .-fsanitize=thread." "" { target *-*-* } 0 } */
+/* { dg-error ".-fsanitize=thread. is incompatible with .-fsanitize=address." "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-10.c b/gcc/testsuite/c-c++-common/zero-scratch-regs-10.c
index d63a57d..193db8c 100644
--- a/gcc/testsuite/c-c++-common/zero-scratch-regs-10.c
+++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-10.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-skip-if "not implemented" { powerpc*-*-darwin* } } */
+/* { dg-skip-if "not implemented" { powerpc*-*-* } } */
/* { dg-options "-O2" } */
#include <assert.h>
diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-11.c b/gcc/testsuite/c-c++-common/zero-scratch-regs-11.c
index 1d8cabb..b04b6a2 100644
--- a/gcc/testsuite/c-c++-common/zero-scratch-regs-11.c
+++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-11.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-skip-if "not implemented" { powerpc*-*-darwin* } } */
+/* { dg-skip-if "not implemented" { powerpc*-*-* } } */
/* { dg-options "-O2 -fzero-call-used-regs=all" } */
#include "zero-scratch-regs-10.c"
diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-5.c b/gcc/testsuite/c-c++-common/zero-scratch-regs-5.c
index 26679a4..fde74d8 100644
--- a/gcc/testsuite/c-c++-common/zero-scratch-regs-5.c
+++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-5.c
@@ -1,4 +1,5 @@
/* { dg-do run } */
+/* { dg-skip-if "not implemented" { powerpc*-*-aix* } } */
/* { dg-options "-O2 -fzero-call-used-regs=used" } */
#include "zero-scratch-regs-1.c"
diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-8.c b/gcc/testsuite/c-c++-common/zero-scratch-regs-8.c
index 7fef0d2..f612a04 100644
--- a/gcc/testsuite/c-c++-common/zero-scratch-regs-8.c
+++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-8.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-skip-if "not implemented" { powerpc*-*-darwin* } } */
+/* { dg-skip-if "not implemented" { powerpc*-*-* } } */
/* { dg-options "-O2 -fzero-call-used-regs=all-arg" } */
#include "zero-scratch-regs-1.c"
diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-9.c b/gcc/testsuite/c-c++-common/zero-scratch-regs-9.c
index 1561656..2c63a69 100644
--- a/gcc/testsuite/c-c++-common/zero-scratch-regs-9.c
+++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-9.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-skip-if "not implemented" { powerpc*-*-darwin* } } */
+/* { dg-skip-if "not implemented" { powerpc*-*-* } } */
/* { dg-options "-O2 -fzero-call-used-regs=all" } */
#include "zero-scratch-regs-1.c"
diff --git a/gcc/testsuite/g++.dg/abi/macro0.C b/gcc/testsuite/g++.dg/abi/macro0.C
index 0810600..7c3c170 100644
--- a/gcc/testsuite/g++.dg/abi/macro0.C
+++ b/gcc/testsuite/g++.dg/abi/macro0.C
@@ -1,6 +1,6 @@
// This testcase will need to be kept in sync with c_common_post_options.
// { dg-options "-fabi-version=0" }
-#if __GXX_ABI_VERSION != 1014
+#if __GXX_ABI_VERSION != 1015
#error "Incorrect value of __GXX_ABI_VERSION"
#endif
diff --git a/gcc/testsuite/g++.dg/cpp0x/alignof6.C b/gcc/testsuite/g++.dg/cpp0x/alignof6.C
new file mode 100644
index 0000000..b1a463d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alignof6.C
@@ -0,0 +1,19 @@
+// PR c++/88115
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-Wno-pedantic" }
+
+// Verify the non-standard extension alignof(expr) behaves like
+// alignof(type) to yield the ABI alignment of the type, and that
+// __alignof__(expr) behaves like __alignof__(type) to yield the
+// preferred alignment of the type.
+
+static_assert(alignof(double{}) == alignof(double), "");
+static_assert(__alignof__(double{}) == __alignof__(double), "");
+
+template <class T>
+void f() {
+ static_assert(alignof(T{}) == alignof(T), "");
+ static_assert(__alignof__(T{}) == __alignof__(T), "");
+}
+
+template void f<double>();
diff --git a/gcc/testsuite/g++.dg/cpp0x/alignof7.C b/gcc/testsuite/g++.dg/cpp0x/alignof7.C
new file mode 100644
index 0000000..a4d7f24
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alignof7.C
@@ -0,0 +1,22 @@
+// PR c++/88115
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-Wno-pedantic" }
+
+// Verify we mangle __alignof__ differently from alignof.
+
+#include <cstddef>
+
+template <class T> void f1(decltype(alignof(T))) { }
+template <class T> void f2(decltype(alignof(T{}))) { }
+template <class T> void f3(decltype(__alignof__(T))) { }
+template <class T> void f4(decltype(__alignof__(T{}))) { }
+
+template void f1<int>(std::size_t);
+template void f2<int>(std::size_t);
+template void f3<int>(std::size_t);
+template void f4<int>(std::size_t);
+
+// { dg-final { scan-assembler "_Z2f1IiEvDTatT_E" } }
+// { dg-final { scan-assembler "_Z2f2IiEvDTaztlT_EE" } }
+// { dg-final { scan-assembler "_Z2f3IiEvDTv111__alignof__T_E" } }
+// { dg-final { scan-assembler "_Z2f4IiEvDTv111__alignof__tlT_EE" } }
diff --git a/gcc/testsuite/g++.dg/cpp0x/alignof8.C b/gcc/testsuite/g++.dg/cpp0x/alignof8.C
new file mode 100644
index 0000000..a9368e2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alignof8.C
@@ -0,0 +1,13 @@
+// PR c++/88115
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-Wno-pedantic -fabi-version=14 -Wabi" }
+
+#include "alignof7.C"
+
+// { dg-warning "changes between" "" { target *-*-* } 11 }
+// { dg-warning "changes between" "" { target *-*-* } 12 }
+
+// { dg-final { scan-assembler "_Z2f1IiEvDTatT_E" } }
+// { dg-final { scan-assembler "_Z2f2IiEvDTaztlT_EE" } }
+// { dg-final { scan-assembler "_Z2f3IiEvDTatT_E" } }
+// { dg-final { scan-assembler "_Z2f4IiEvDTaztlT_EE" } }
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto54.C b/gcc/testsuite/g++.dg/cpp0x/auto54.C
new file mode 100644
index 0000000..0c1815a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/auto54.C
@@ -0,0 +1,10 @@
+// PR c++/97895
+// { dg-do compile { target c++11 } }
+
+namespace std {
+ template<typename T> struct initializer_list {
+ const T *ptr;
+ decltype(sizeof 0) n;
+ };
+ auto a = {}; // { dg-error "unable to deduce" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C
new file mode 100644
index 0000000..2c9d2f9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C
@@ -0,0 +1,37 @@
+// PR c++/52830
+// { dg-do compile { target c++11 } }
+// { dg-ice "comptypes" }
+
+template<bool b> struct eif { typedef void type; };
+template<> struct eif<false> {};
+
+template<class A, class B> struct same
+{
+ static constexpr bool value = false;
+};
+template<class A>
+struct same<A, A>
+{
+ static constexpr bool value = true;
+};
+
+
+struct foo {
+ template<class T>
+ void func(T && a,
+ typename eif<same<decltype(a), int&&>::value>::type * = 0);
+};
+
+template<class T>
+void
+foo::
+func(T && a,
+ typename eif<same<decltype(a), int&&>::value>::type * )
+{
+}
+
+void do_stuff()
+{
+ foo f;
+ f.func(12);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor28.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor28.C
index 90a06c6..59801a1 100644
--- a/gcc/testsuite/g++.dg/cpp0x/inh-ctor28.C
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor28.C
@@ -4,4 +4,4 @@
struct A {};
struct B : virtual A {};
struct C : virtual A {};
-struct D : B,C { using A::A; }; // { dg-error "indirect" }
+struct D : B,C { using A::A; }; // { dg-error "not a direct base" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor33.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor33.C
index 95b7812..4e61290 100644
--- a/gcc/testsuite/g++.dg/cpp0x/inh-ctor33.C
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor33.C
@@ -10,7 +10,7 @@ public:
class Y : public X { };
class Z : public Y {
- using X::X; // { dg-error "cannot inherit constructors from indirect base .X." }
+ using X::X; // { dg-error ".X. is not a direct base of .Z." }
};
int main()
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-template3.C b/gcc/testsuite/g++.dg/cpp0x/initlist-template3.C
new file mode 100644
index 0000000..b65a847
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist-template3.C
@@ -0,0 +1,13 @@
+// PR c++/97899
+// { dg-do compile { target c++11 } }
+
+template <typename T = int>
+int fn()
+{
+ return 1;
+}
+
+template <typename T>
+void bar() {
+ const int i = int{fn()};
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/using-enum-1.C b/gcc/testsuite/g++.dg/cpp0x/using-enum-1.C
index 9904d59..bf251ba 100644
--- a/gcc/testsuite/g++.dg/cpp0x/using-enum-1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/using-enum-1.C
@@ -1,6 +1,9 @@
// PR c++/60265
// { dg-do compile { target c++11 } }
+// [namespace.udecl]/7 shall not name a scoped enumerator.
+// (so unscoped enumerator is ok)
+
namespace A
{
enum E { V };
diff --git a/gcc/testsuite/g++.dg/cpp0x/using-enum-2.C b/gcc/testsuite/g++.dg/cpp0x/using-enum-2.C
index faa3817..8ea70d7 100644
--- a/gcc/testsuite/g++.dg/cpp0x/using-enum-2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/using-enum-2.C
@@ -1,20 +1,23 @@
// PR c++/60265
// { dg-do compile { target c++11 } }
+// [namespace.udecl]/7 shall not name a scoped enumerator.
+// (this changes in C++2a)
+
namespace A
{
enum class E { V };
- using E::V; // { dg-error "name enumerator" }
+ using E::V; // { dg-error "enum" "" { target { ! c++2a } } }
}
void foo()
{
- using A::E::V; // { dg-error "name enumerator" }
+ using A::E::V; // { dg-error "enum" "" { target { ! c++2a } } }
}
-using A::E::V; // { dg-error "name enumerator" }
+using A::E::V; // { dg-error "enum" "" { target { ! c++2a } } }
enum class F { U };
-using F::U; // { dg-error "name enumerator" }
+using F::U; // { dg-error "enum" "" { target { ! c++2a } } }
diff --git a/gcc/testsuite/g++.dg/cpp0x/using-enum-3.C b/gcc/testsuite/g++.dg/cpp0x/using-enum-3.C
index ecc4ddc..34f8bf4 100644
--- a/gcc/testsuite/g++.dg/cpp0x/using-enum-3.C
+++ b/gcc/testsuite/g++.dg/cpp0x/using-enum-3.C
@@ -1,15 +1,24 @@
// PR c++/89511
// { dg-do compile { target c++11 } }
+// [namespace.udecl] In a using-declaration used as a
+// member-declaration, the nested-name-specifier shall name a base
+// class of the class being defined
+// (this changes in C++2a)
+
void f ()
{
enum e { a };
- using e::a; // { dg-error "name enumerator" }
+ using e::a; // { dg-error "redeclaration" }
+ // { dg-error "enum" "" { target { ! c++2a } } .-1 }
}
+enum E { A };
+
struct S {
enum E { A };
- using E::A; // { dg-error "type .S. is not a base type for type .S." }
+ using E::A; // { dg-error "not a base" "" { target { ! c++2a } } }
+ // { dg-error "conflicts" "" { target c++2a } .-1 }
};
namespace N {
@@ -17,5 +26,5 @@ namespace N {
}
struct T {
- using N::E::B; // { dg-error "using-declaration for non-member at class scope" }
+ using N::E::B; // { dg-error "enum" "" { target { ! c++2a } } }
};
diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-88982.C b/gcc/testsuite/g++.dg/cpp0x/vt-88982.C
new file mode 100644
index 0000000..cb9530d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/vt-88982.C
@@ -0,0 +1,14 @@
+// PR c++/88982
+// { dg-do compile { target c++11 } }
+// { dg-ice "tsubst_pack_expansion" }
+
+template<typename...Ts> struct A {
+ template<template<typename, Ts = 0> class ...Cs, Cs<Ts> ...Vs> struct B {
+ B() {
+ }
+ };
+};
+
+template<typename, int> using Int = int;
+template<typename, short> using Char = char;
+A<int, short>::B<Int, Char> b;
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-label.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-label.C
new file mode 100644
index 0000000..a2d113c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-label.C
@@ -0,0 +1,9 @@
+// PR c++/97846
+// { dg-do compile { target c++14 } }
+
+constexpr int
+f ()
+{
+x: // { dg-error "label definition is not a constant expression" }
+ return 42;
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction69.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction69.C
index 8291f4a..d336366 100644
--- a/gcc/testsuite/g++.dg/cpp1z/class-deduction69.C
+++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction69.C
@@ -6,7 +6,7 @@ namespace a {
template <typename...> using c = b;
}
template <typename... d> struct e : a::c<d...> { // { dg-error "incomplete" }
- using a::c<>::c; // { dg-prune-output "not a base" }
+ using a::c<>::c; // { dg-prune-output "not a direct base" }
};
template <template <typename> typename f> void g() { f(); }
void h() { g<e>(); }
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction76.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction76.C
new file mode 100644
index 0000000..23bb6e8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction76.C
@@ -0,0 +1,25 @@
+// PR c++/90799
+// { dg-do compile { target c++17 } }
+// { dg-ice "unify" }
+
+template<class T>
+void foo() noexcept(T::value);
+
+struct S {
+ static constexpr const bool value = true;
+
+ template<class T>
+ void bar() noexcept(T::value);
+};
+
+template<class... Args, bool is_noexcept>
+constexpr bool is_noexcept_function(void(Args...) noexcept(is_noexcept)) noexcept {
+ return is_noexcept;
+}
+
+template<class... Args, bool is_noexcept>
+constexpr bool is_noexcept_member_function(void(S::*)(Args...) noexcept(is_noexcept)) noexcept {
+ return is_noexcept;
+}
+
+static_assert(is_noexcept_function(foo<S>));
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda26.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda26.C
new file mode 100644
index 0000000..d6c8bae
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda26.C
@@ -0,0 +1,13 @@
+// PR c++/87765
+// { dg-do compile { target c++17 } }
+// { dg-ice "cxx_eval_constant_expression" }
+
+template <int N>
+using foo = int;
+
+struct A {
+ constexpr int bar() const { return 42; }
+};
+
+void baz(A a) {
+ [=](auto c) { return foo<a.bar()> { }; }; }
diff --git a/gcc/testsuite/g++.dg/cpp1z/inline-var8.C b/gcc/testsuite/g++.dg/cpp1z/inline-var8.C
new file mode 100644
index 0000000..8db3c19
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/inline-var8.C
@@ -0,0 +1,17 @@
+// PR c++/97975
+// { dg-do compile { target c++17 } }
+
+template <class>
+class A
+{
+ static const float b;
+ static inline const int c = b;
+};
+
+A<int> a;
+
+struct B
+{
+ static const float b;
+ static inline const int c = b;
+};
diff --git a/gcc/testsuite/g++.dg/cpp2a/bit-cast1.C b/gcc/testsuite/g++.dg/cpp2a/bit-cast1.C
new file mode 100644
index 0000000..34cd1b9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/bit-cast1.C
@@ -0,0 +1,47 @@
+// { dg-do compile }
+
+struct S { short a, b; };
+struct T { float a[16]; };
+struct U { int b[16]; };
+
+#if __SIZEOF_FLOAT__ == __SIZEOF_INT__
+int
+f1 (float x)
+{
+ return __builtin_bit_cast (int, x);
+}
+#endif
+
+#if 2 * __SIZEOF_SHORT__ == __SIZEOF_INT__
+S
+f2 (int x)
+{
+ return __builtin_bit_cast (S, x);
+}
+
+int
+f3 (S x)
+{
+ return __builtin_bit_cast (int, x);
+}
+#endif
+
+#if __SIZEOF_FLOAT__ == __SIZEOF_INT__
+U
+f4 (T &x)
+{
+ return __builtin_bit_cast (U, x);
+}
+
+T
+f5 (int (&x)[16])
+{
+ return __builtin_bit_cast (T, x);
+}
+#endif
+
+int
+f6 ()
+{
+ return __builtin_bit_cast (unsigned char, (signed char) 0);
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/bit-cast2.C b/gcc/testsuite/g++.dg/cpp2a/bit-cast2.C
new file mode 100644
index 0000000..6bb1760
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/bit-cast2.C
@@ -0,0 +1,57 @@
+// { dg-do compile }
+
+struct S { ~S (); int s; };
+S s;
+struct V; // { dg-message "forward declaration of 'struct V'" }
+extern V v; // { dg-error "'v' has incomplete type" }
+extern V *p;
+struct U { int a, b; };
+U u;
+
+void
+foo (int *q)
+{
+ __builtin_bit_cast (int, s); // { dg-error "'__builtin_bit_cast' source type 'S' is not trivially copyable" }
+ __builtin_bit_cast (S, 0); // { dg-error "'__builtin_bit_cast' destination type 'S' is not trivially copyable" }
+ __builtin_bit_cast (int &, q); // { dg-error "'__builtin_bit_cast' destination type 'int&' is not trivially copyable" }
+ __builtin_bit_cast (int [1], 0); // { dg-error "'__builtin_bit_cast' destination type \[^\n\r]* is an array type" }
+ __builtin_bit_cast (V, 0); // { dg-error "invalid use of incomplete type 'struct V'" }
+ __builtin_bit_cast (int, v);
+ __builtin_bit_cast (int, *p); // { dg-error "invalid use of incomplete type 'struct V'" }
+ __builtin_bit_cast (U, 0); // { dg-error "'__builtin_bit_cast' source size '\[0-9]*' not equal to destination type size '\[0-9]*'" }
+ __builtin_bit_cast (int, u); // { dg-error "'__builtin_bit_cast' source size '\[0-9]*' not equal to destination type size '\[0-9]*'" }
+}
+
+template <int N>
+void
+bar (int *q)
+{
+ __builtin_bit_cast (int, s); // { dg-error "'__builtin_bit_cast' source type 'S' is not trivially copyable" }
+ __builtin_bit_cast (S, 0); // { dg-error "'__builtin_bit_cast' destination type 'S' is not trivially copyable" }
+ __builtin_bit_cast (int &, q); // { dg-error "'__builtin_bit_cast' destination type 'int&' is not trivially copyable" }
+ __builtin_bit_cast (int [1], 0); // { dg-error "'__builtin_bit_cast' destination type \[^\n\r]* is an array type" }
+ __builtin_bit_cast (V, 0); // { dg-error "invalid use of incomplete type 'struct V'" }
+ __builtin_bit_cast (int, *p); // { dg-error "invalid use of incomplete type 'struct V'" }
+ __builtin_bit_cast (U, 0); // { dg-error "'__builtin_bit_cast' source size '\[0-9]*' not equal to destination type size '\[0-9]*'" }
+ __builtin_bit_cast (int, u); // { dg-error "'__builtin_bit_cast' source size '\[0-9]*' not equal to destination type size '\[0-9]*'" }
+}
+
+template <typename T1, typename T2, typename T3, typename T4>
+void
+baz (T3 s, T4 *p, T1 *q)
+{
+ __builtin_bit_cast (int, s); // { dg-error "'__builtin_bit_cast' source type 'S' is not trivially copyable" }
+ __builtin_bit_cast (T3, 0); // { dg-error "'__builtin_bit_cast' destination type 'S' is not trivially copyable" }
+ __builtin_bit_cast (T1 &, q); // { dg-error "'__builtin_bit_cast' destination type 'int&' is not trivially copyable" }
+ __builtin_bit_cast (T2, 0); // { dg-error "'__builtin_bit_cast' destination type \[^\n\r]* is an array type" }
+ __builtin_bit_cast (T4, 0); // { dg-error "invalid use of incomplete type 'struct V'" }
+ __builtin_bit_cast (int, *p); // { dg-error "invalid use of incomplete type 'struct V'" }
+ __builtin_bit_cast (U, (T1) 0); // { dg-error "'__builtin_bit_cast' source size '\[0-9]*' not equal to destination type size '\[0-9]*'" }
+ __builtin_bit_cast (T1, u); // { dg-error "'__builtin_bit_cast' source size '\[0-9]*' not equal to destination type size '\[0-9]*'" }
+}
+
+void
+qux (int *q)
+{
+ baz <int, int [1], S, V> (s, p, q);
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/bit-cast3.C b/gcc/testsuite/g++.dg/cpp2a/bit-cast3.C
new file mode 100644
index 0000000..a3ff211
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/bit-cast3.C
@@ -0,0 +1,229 @@
+// { dg-do compile { target c++11 } }
+
+template <typename To, typename From>
+constexpr To
+bit_cast (const From &from)
+{
+ return __builtin_bit_cast (To, from);
+}
+
+template <typename To, typename From>
+constexpr bool
+check (const From &from)
+{
+ return bit_cast <From> (bit_cast <To> (from)) == from;
+}
+
+struct A
+{
+ int a, b, c;
+ constexpr bool operator == (const A &x) const
+ {
+ return x.a == a && x.b == b && x.c == c;
+ }
+};
+
+struct B
+{
+ unsigned a[3];
+ constexpr bool operator == (const B &x) const
+ {
+ return x.a[0] == a[0] && x.a[1] == a[1] && x.a[2] == a[2];
+ }
+};
+
+struct C
+{
+ char a[2][3][2];
+ constexpr bool operator == (const C &x) const
+ {
+ return x.a[0][0][0] == a[0][0][0]
+ && x.a[0][0][1] == a[0][0][1]
+ && x.a[0][1][0] == a[0][1][0]
+ && x.a[0][1][1] == a[0][1][1]
+ && x.a[0][2][0] == a[0][2][0]
+ && x.a[0][2][1] == a[0][2][1]
+ && x.a[1][0][0] == a[1][0][0]
+ && x.a[1][0][1] == a[1][0][1]
+ && x.a[1][1][0] == a[1][1][0]
+ && x.a[1][1][1] == a[1][1][1]
+ && x.a[1][2][0] == a[1][2][0]
+ && x.a[1][2][1] == a[1][2][1];
+ }
+};
+
+struct D
+{
+ int a, b;
+ constexpr bool operator == (const D &x) const
+ {
+ return x.a == a && x.b == b;
+ }
+};
+
+struct E {};
+struct F { char c, d, e, f; };
+struct G : public D, E, F
+{
+ int g;
+ constexpr bool operator == (const G &x) const
+ {
+ return x.a == a && x.b == b && x.c == c && x.d == d
+ && x.e == e && x.f == f && x.g == g;
+ }
+};
+
+struct H
+{
+ int a, b[2], c;
+ constexpr bool operator == (const H &x) const
+ {
+ return x.a == a && x.b[0] == b[0] && x.b[1] == b[1] && x.c == c;
+ }
+};
+
+#if __SIZEOF_INT__ == 4
+struct I
+{
+ int a;
+ int b : 3;
+ int c : 24;
+ int d : 5;
+ int e;
+ constexpr bool operator == (const I &x) const
+ {
+ return x.a == a && x.b == b && x.c == c && x.d == d && x.e == e;
+ }
+};
+#endif
+
+#if __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8
+struct J
+{
+ long long int a, b : 11, c : 3, d : 37, e : 1, f : 10, g : 2, h;
+ constexpr bool operator == (const J &x) const
+ {
+ return x.a == a && x.b == b && x.c == c && x.d == d && x.e == e
+ && x.f == f && x.g == g && x.h == h;
+ }
+};
+
+struct K
+{
+ long long int a, b, c;
+ constexpr bool operator == (const K &x) const
+ {
+ return x.a == a && x.b == b && x.c == c;
+ }
+};
+
+struct M
+{
+ signed a : 6, b : 7, c : 6, d : 5;
+ unsigned char e;
+ unsigned int f;
+ long long int g;
+ constexpr bool operator == (const M &x) const
+ {
+ return x.a == a && x.b == b && x.c == c && x.d == d && x.e == e
+ && x.f == f && x.g == g;
+ }
+};
+
+struct N
+{
+ unsigned long long int a, b;
+ constexpr bool operator == (const N &x) const
+ {
+ return x.a == a && x.b == b;
+ }
+};
+#endif
+
+static_assert (check <unsigned int> (0), "");
+static_assert (check <long long int> (0xdeadbeeffeedbac1ULL), "");
+static_assert (check <signed char> ((unsigned char) 42), "");
+static_assert (check <char> ((unsigned char) 42), "");
+static_assert (check <unsigned char> ((unsigned char) 42), "");
+static_assert (check <signed char> ((signed char) 42), "");
+static_assert (check <char> ((signed char) 42), "");
+static_assert (check <unsigned char> ((signed char) 42), "");
+static_assert (check <signed char> ((char) 42), "");
+static_assert (check <char> ((char) 42), "");
+static_assert (check <unsigned char> ((char) 42), "");
+#if __SIZEOF_INT__ == __SIZEOF_FLOAT__
+static_assert (check <int> (2.5f), "");
+static_assert (check <unsigned int> (136.5f), "");
+#endif
+#if __SIZEOF_LONG_LONG__ == __SIZEOF_DOUBLE__
+static_assert (check <long long> (2.5), "");
+static_assert (check <long long unsigned> (123456.75), "");
+#endif
+
+static_assert (check <B> (A{ 1, 2, 3 }), "");
+static_assert (check <A> (B{ 4, 5, 6 }), "");
+
+#if __SIZEOF_INT__ == 4
+static_assert (check <C> (A{ 7, 8, 9 }), "");
+static_assert (check <C> (B{ 10, 11, 12 }), "");
+static_assert (check <A> (C{ { { { 13, 14 }, { 15, 16 }, { 17, 18 } },
+ { { 19, 20 }, { 21, 22 }, { 23, 24 } } } }), "");
+constexpr unsigned char c[] = { 1, 2, 3, 4 };
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+static_assert (bit_cast <unsigned int> (c) == 0x04030201U, "");
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+static_assert (bit_cast <unsigned int> (c) == 0x01020304U, "");
+#endif
+
+#if __cplusplus >= 201703L
+static_assert (check <G> (H { 0x12345678, { 0x23456789, 0x5a876543 }, 0x3ba78654 }), "");
+#endif
+constexpr int d[] = { 0x12345678, 0x23456789, 0x5a876543, 0x3ba78654 };
+static_assert (bit_cast <G> (d) == bit_cast <G> (H { 0x12345678, { 0x23456789, 0x5a876543 }, 0x3ba78654 }), "");
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+static_assert (bit_cast <I> (A { 0x7efa3412, 0x5a876543, 0x1eeffeed })
+ == I { 0x7efa3412, 3, 0x50eca8, 0xb, 0x1eeffeed }, "");
+static_assert (bit_cast <A> (I { 0x7efa3412, 3, 0x50eca8, 0xb, 0x1eeffeed })
+ == A { 0x7efa3412, 0x5a876543, 0x1eeffeed }, "");
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+static_assert (bit_cast <I> (A { 0x7efa3412, 0x5a876543, 0x1eeffeed })
+ == I { 0x7efa3412, 2, -0x2bc4d6, 0x3, 0x1eeffeed }, "");
+static_assert (bit_cast <A> (I { 0x7efa3412, 2, -0x2bc4d6, 0x3, 0x1eeffeed })
+ == A { 0x7efa3412, 0x5a876543, 0x1eeffeed }, "");
+#endif
+#endif
+
+#if 2 * __SIZEOF_INT__ == __SIZEOF_LONG_LONG__ && __SIZEOF_INT__ >= 4
+constexpr unsigned long long a = 0xdeadbeeffee1deadULL;
+constexpr unsigned b[] = { 0xfeedbacU, 0xbeeffeedU };
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+static_assert (bit_cast <D> (a) == D { int (0xfee1deadU), int (0xdeadbeefU) }, "");
+static_assert (bit_cast <unsigned long long> (b) == 0xbeeffeed0feedbacULL, "");
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+static_assert (bit_cast <D> (a) == D { int (0xdeadbeefU), int (0xfee1deadU) }, "");
+static_assert (bit_cast <unsigned long long> (b) == 0x0feedbacbeeffeedULL, "");
+#endif
+#endif
+
+#if __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+static_assert (bit_cast <J> (K { 0x0feedbacdeadbeefLL, 7862463375103529997LL, 0x0feedbacdeadbeefLL })
+ == J { 0x0feedbacdeadbeefLL, -1011, 2, -0xbacdeadbeLL, -1, -303, 1, 0x0feedbacdeadbeefLL }, "");
+static_assert (bit_cast <K> (J { 0x0feedbacdeadbeefLL, -1011, 2, -0xbacdeadbeLL, -1, -303, 1, 0x0feedbacdeadbeefLL })
+ == K { 0x0feedbacdeadbeefLL, 7862463375103529997LL, 0x0feedbacdeadbeefLL }, "");
+static_assert (bit_cast <M> (N { 0xfeedbacdeadbeef8ULL, 0x123456789abcde42ULL })
+ == M { -8, 59, 31, -5, 234, 0xfeedbacdU, 0x123456789abcde42ULL }, "");
+static_assert (bit_cast <N> (M { -8, 59, 31, -5, 234, 0xfeedbacdU, 0x123456789abcde42ULL })
+ == N { 0xfeedbacdeadbeef8ULL, 0x123456789abcde42ULL }, "");
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+static_assert (bit_cast <J> (K { 0x0feedbacdeadbeefLL, -9103311533965288635LL, 0x0feedbacdeadbeefLL })
+ == J { 0x0feedbacdeadbeefLL, -1011, 2, -0xbacdeadbeLL, -1, -303, 1, 0x0feedbacdeadbeefLL }, "");
+static_assert (bit_cast <K> (J { 0x0feedbacdeadbeefLL, -1011, 2, -0xbacdeadbeLL, -1, -303, 1, 0x0feedbacdeadbeefLL })
+ == K { 0x0feedbacdeadbeefLL, -9103311533965288635LL, 0x0feedbacdeadbeefLL }, "");
+static_assert (bit_cast <M> (N { 0xfeedbacdeadbeef8ULL, 0x123456789abcde42ULL })
+ == M { -1, -35, -19, -6, 205, 0xeadbeef8U, 0x123456789abcde42ULL }, "");
+static_assert (bit_cast <N> (M { -1, -35, -19, -6, 205, 0xeadbeef8U, 0x123456789abcde42ULL })
+ == N { 0xfeedbacdeadbeef8ULL, 0x123456789abcde42ULL }, "");
+#endif
+#endif
diff --git a/gcc/testsuite/g++.dg/cpp2a/bit-cast4.C b/gcc/testsuite/g++.dg/cpp2a/bit-cast4.C
new file mode 100644
index 0000000..9ffa2ff
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/bit-cast4.C
@@ -0,0 +1,44 @@
+// { dg-do compile { target c++11 } }
+
+template <typename To, typename From>
+constexpr To
+bit_cast (const From &from)
+{
+ return __builtin_bit_cast (To, from);
+}
+// { dg-error "'__builtin_bit_cast' is not a constant expression because 'U' is a union type" "U" { target *-*-* } 7 }
+// { dg-error "'__builtin_bit_cast' is not a constant expression because 'const U' is a union type" "const U" { target *-*-* } 7 }
+// { dg-error "'__builtin_bit_cast' is not a constant expression because 'B' contains a union type" "B" { target *-*-* } 7 }
+// { dg-error "'__builtin_bit_cast' is not a constant expression because 'char\\\*' is a pointer type" "char ptr" { target *-*-* } 7 }
+// { dg-error "'__builtin_bit_cast' is not a constant expression because 'const int\\\*' is a pointer type" "const int ptr" { target *-*-* } 7 }
+// { dg-error "'__builtin_bit_cast' is not a constant expression because 'C' contains a pointer type" "C" { target *-*-* } 7 }
+// { dg-error "'__builtin_bit_cast' is not a constant expression because 'const C' contains a pointer type" "const C" { target *-*-* } 7 }
+// { dg-error "'__builtin_bit_cast' is not a constant expression because 'int D::\\\*' is a pointer to member type" "ptrmem 1" { target *-*-* } 7 }
+// { dg-error "'__builtin_bit_cast' is not a constant expression because 'int \\\(D::\\\*\\\)\\\(\\\) const' is a pointer to member type" "ptrmem 2" { target *-*-* } 7 }
+// { dg-error "'__builtin_bit_cast' is not a constant expression because 'int \\\(D::\\\*\\\)\\\(\\\)' is a pointer to member type" "ptrmem 3" { target *-*-* } 7 }
+
+union U { int u; };
+struct A { int a; U b; };
+struct B : public A { int c; };
+struct C { const int *p; };
+constexpr int a[] = { 1, 2, 3 };
+constexpr const int *b = &a[0];
+constexpr C c = { b };
+struct D { int d; constexpr int foo () const { return 1; } };
+constexpr int D::*d = &D::d;
+constexpr int (D::*e) () const = &D::foo;
+struct E { __INTPTR_TYPE__ e, f; };
+constexpr E f = { 1, 2 };
+constexpr U g { 0 };
+
+constexpr auto z = bit_cast <U> (0);
+constexpr auto y = bit_cast <int> (g);
+constexpr auto x = bit_cast <B> (a);
+constexpr auto w = bit_cast <char *> ((__INTPTR_TYPE__) 0);
+constexpr auto v = bit_cast <__UINTPTR_TYPE__> (b);
+constexpr auto u = bit_cast <C> ((__INTPTR_TYPE__) 0);
+constexpr auto t = bit_cast <__INTPTR_TYPE__> (c);
+constexpr auto s = bit_cast <__INTPTR_TYPE__> (d);
+constexpr auto r = bit_cast <E> (e);
+constexpr auto q = bit_cast <int D::*> ((__INTPTR_TYPE__) 0);
+constexpr auto p = bit_cast <int (D::*) ()> (f);
diff --git a/gcc/testsuite/g++.dg/cpp2a/bit-cast5.C b/gcc/testsuite/g++.dg/cpp2a/bit-cast5.C
new file mode 100644
index 0000000..9d536d1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/bit-cast5.C
@@ -0,0 +1,69 @@
+// { dg-do compile { target { c++20 && { ilp32 || lp64 } } } }
+
+struct A { signed char a, b, c, d, e, f; };
+struct B {};
+struct C { B a, b; short c; B d; };
+struct D { int a : 4, b : 24, c : 4; };
+struct E { B a, b; short c; };
+struct F { B a; signed char b, c; B d; };
+
+constexpr bool
+f1 ()
+{
+ A a;
+ a.c = 23; a.d = 42;
+ C b = __builtin_bit_cast (C, a); // OK
+ return false;
+}
+
+constexpr bool
+f2 ()
+{
+ A a;
+ a.a = 1; a.b = 2; a.c = 3; a.e = 4; a.f = 5;
+ C b = __builtin_bit_cast (C, a); // { dg-error "'__builtin_bit_cast' accessing uninitialized byte at offset 3" }
+ return false;
+}
+
+constexpr bool
+f3 ()
+{
+ D a;
+ a.b = 1;
+ F b = __builtin_bit_cast (F, a); // OK
+ return false;
+}
+
+constexpr bool
+f4 ()
+{
+ D a;
+ a.b = 1; a.c = 2;
+ E b = __builtin_bit_cast (E, a); // OK
+ return false;
+}
+
+constexpr bool
+f5 ()
+{
+ D a;
+ a.b = 1;
+ E b = __builtin_bit_cast (E, a); // { dg-error "'__builtin_bit_cast' accessing uninitialized byte at offset 3" }
+ return false;
+}
+
+constexpr bool
+f6 ()
+{
+ D a;
+ a.c = 1;
+ E b = __builtin_bit_cast (E, a); // { dg-error "'__builtin_bit_cast' accessing uninitialized byte at offset 2" }
+ return false;
+}
+
+constexpr bool a = f1 ();
+constexpr bool b = f2 ();
+constexpr bool c = f3 ();
+constexpr bool d = f4 ();
+constexpr bool e = f5 ();
+constexpr bool f = f6 ();
diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-abbrev1.C b/gcc/testsuite/g++.dg/cpp2a/class-deduction-abbrev1.C
new file mode 100644
index 0000000..f931009
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-abbrev1.C
@@ -0,0 +1,13 @@
+ // { dg-do compile { target c++20 } }
+
+template <class T> struct A { };
+template <class T> concept is_A = requires { A(T()); };
+
+void f(auto); // OK
+void f(is_A auto); // OK
+void f(A); // { dg-error "placeholder" }
+
+int main()
+{
+ f(A<int>());
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-decltype3.C b/gcc/testsuite/g++.dg/cpp2a/concepts-decltype3.C
new file mode 100644
index 0000000..837855c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-decltype3.C
@@ -0,0 +1,15 @@
+// { dg-do compile { target c++20 } }
+
+template <class T> concept C = requires(T t) { t; };
+
+template <class T> using A = decltype((T{}, int{}));
+
+template <class T> concept D = C<A<T>>;
+
+template <class T, class U> void f() requires D<T>;
+template <class T> void g() requires D<T>;
+
+void h() {
+ f<int, int>();
+ g<int>();
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-nodiscard1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-nodiscard1.C
new file mode 100644
index 0000000..28ce29b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-nodiscard1.C
@@ -0,0 +1,10 @@
+// PR c++/98019
+// { dg-do compile { target c++20 } }
+
+template <class T, class U> concept same_as = __is_same_as (T, U);
+
+[[nodiscard]] int foo() { return 0; }
+[[maybe_unused]] constexpr bool b = requires {
+ { foo() } -> same_as<int>;
+};
+[[maybe_unused]] constexpr auto x = sizeof(foo());
diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval-defarg1.C b/gcc/testsuite/g++.dg/cpp2a/consteval-defarg1.C
new file mode 100644
index 0000000..826ee25
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/consteval-defarg1.C
@@ -0,0 +1,11 @@
+// Test that late-parsed default args have the same consteval semantics.
+// { dg-do compile { target c++20 } }
+
+consteval bool foo (bool x) { if (x) throw 1; return false; }
+consteval bool bar (bool x = foo (true)) { return true; }
+struct S
+{
+ consteval static bool baz (bool x = foo (true)) { return true; }
+};
+constexpr bool a = bar (true);
+constexpr bool b = S::baz (true);
diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval-defarg2.C b/gcc/testsuite/g++.dg/cpp2a/consteval-defarg2.C
new file mode 100644
index 0000000..e8462c8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/consteval-defarg2.C
@@ -0,0 +1,29 @@
+// Test that late-parsed default args have the same consteval semantics.
+// { dg-do compile { target c++20 } }
+
+template <int N>
+consteval bool foo (bool x) { if (x) throw N; return false; }
+consteval bool qux (bool x) { if (x) throw 1; return false; }
+template <int N>
+consteval bool bar (bool x = foo<N> (true)) { return true; }
+template <int N>
+consteval bool corge (bool x = qux (true)) { return true; }
+template <int N>
+struct S
+{
+ consteval static bool baz (bool x = foo<N> (true)) { return true; }
+ consteval static bool garply (bool x = qux (true)) { return true; }
+};
+struct T
+{
+ template <int N>
+ consteval static bool baz (bool x = foo<N> (true)) { return true; }
+ template <int N>
+ consteval static bool garply (bool x = qux (true)) { return true; }
+};
+constexpr bool a = bar<0> (true);
+constexpr bool b = corge<0> (true);
+constexpr bool c = S<0>::baz (true);
+constexpr bool d = S<0>::garply (true);
+constexpr bool e = T::baz<0> (true);
+constexpr bool f = T::garply<0> (true);
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor10.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor10.C
new file mode 100644
index 0000000..1551746
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor10.C
@@ -0,0 +1,16 @@
+// PR c++/97427
+// { dg-do compile { target c++20 } }
+
+struct Foo {
+ int n = 1;
+ constexpr ~Foo() {
+ n = 0;
+ }
+};
+
+constexpr bool foo() {
+ const Foo b;
+ return true;
+}
+
+static_assert(foo());
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor9.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor9.C
new file mode 100644
index 0000000..975e5fc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor9.C
@@ -0,0 +1,31 @@
+// PR c++/97790
+// { dg-do compile { target c++20 } }
+
+struct S
+{
+ int *d;
+ int n;
+ constexpr S () : d(new int[1]{}), n(1) {}
+ constexpr ~S () { delete [] d; }
+};
+
+constexpr S
+foo ()
+{
+ return S ();
+}
+
+constexpr int
+bar ()
+{
+ return foo ().n;
+}
+
+constexpr int
+baz ()
+{
+ return S ().n;
+}
+
+constexpr int a = baz ();
+constexpr int b = bar ();
diff --git a/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C b/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C
index 7f1fe34..dc46e48 100644
--- a/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C
+++ b/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C
@@ -533,3 +533,9 @@
#elif __cpp_concepts != 201907
# error "__cpp_concepts != 201907"
#endif
+
+#ifndef __cpp_using_enum
+# error "__cpp_using_enum"
+#elif __cpp_using_enum != 201907
+# error "__cpp_using_enum != 201907"
+#endif
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-generic8.C b/gcc/testsuite/g++.dg/cpp2a/lambda-generic8.C
new file mode 100644
index 0000000..f3c3809
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/lambda-generic8.C
@@ -0,0 +1,9 @@
+// PR c++/97839
+// { dg-do compile { target c++20 } }
+// Test that a lambda with <template-param-list> doesn't require
+// a lambda-declarator.
+
+int main()
+{
+ []<typename T>{}.operator()<int>();
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class39.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class39.C
new file mode 100644
index 0000000..f5f79a7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class39.C
@@ -0,0 +1,12 @@
+// PR c++/89565
+// { dg-do compile { target c++20 } }
+// { dg-ice "resolve_args" }
+
+template <auto>
+struct N{};
+
+template <N>
+struct S {};
+
+template <typename T>
+using NS = S<T::value>;
diff --git a/gcc/testsuite/g++.dg/cpp2a/pr98082.C b/gcc/testsuite/g++.dg/cpp2a/pr98082.C
new file mode 100644
index 0000000..b2caacb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/pr98082.C
@@ -0,0 +1,14 @@
+/* PR middle-end/98082 */
+/* Reported by Martin Liska <marxin@gcc.gnu.org> */
+
+/* { dg-do compile { target c++20 } } */
+/* { dg-options "-fipa-icf" } */
+
+class GoodIter {
+public:
+ GoodIter();
+ GoodIter(GoodIter &);
+};
+
+GoodIter operator-(int, GoodIter) { return GoodIter(); }
+GoodIter operator+(int, GoodIter) { return GoodIter(); }
diff --git a/gcc/testsuite/g++.dg/cpp2a/srcloc15.C b/gcc/testsuite/g++.dg/cpp2a/srcloc15.C
new file mode 100644
index 0000000..30e5845
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/srcloc15.C
@@ -0,0 +1,119 @@
+// { dg-do run { target c++20 } }
+
+namespace std {
+ struct source_location {
+ struct __impl {
+ const char *_M_file_name;
+ const char *_M_function_name;
+ unsigned int _M_line, _M_column;
+ };
+ const __impl *__ptr;
+ constexpr source_location () : __ptr (nullptr) {}
+ static consteval source_location
+ current (const void *__p = __builtin_source_location ()) {
+ source_location __ret;
+ __ret.__ptr = static_cast <const __impl *> (__p);
+ return __ret;
+ }
+ constexpr const char *file_name () const {
+ return __ptr ? __ptr->_M_file_name : "";
+ }
+ constexpr const char *function_name () const {
+ return __ptr ? __ptr->_M_function_name : "";
+ }
+ constexpr unsigned line () const {
+ return __ptr ? __ptr->_M_line : 0;
+ }
+ constexpr unsigned column () const {
+ return __ptr ? __ptr->_M_column : 0;
+ }
+ };
+}
+
+using namespace std;
+
+constexpr source_location
+foo (const source_location x = source_location::current ())
+{
+ return x;
+}
+
+struct S {
+ const char *func;
+ unsigned line = 0;
+ source_location loc = source_location::current ();
+
+ constexpr S (int l, source_location loc = source_location::current ())
+ : func(__FUNCTION__), line(l), loc(loc)
+ {}
+
+ constexpr S (double)
+ : func(__FUNCTION__), line(__LINE__)
+ // ^ column 38
+ {}
+};
+
+constexpr bool
+cmp (const char *p, const char *q)
+{
+ for (; *p && *q; p++, q++)
+ if (*p != *q)
+ return true;
+ return *p || *q;
+}
+
+constexpr bool
+bar ()
+{
+ int line = __LINE__;
+ source_location a = foo ();
+ source_location b = source_location::current ();
+ source_location c = foo ();
+ // ^ column 28
+ // ^ column 49
+ const source_location *d[3] = { &a, &b, &c };
+ const char *file1 = __FILE__;
+ const char *function1 = __FUNCTION__;
+ for (int j = 0; j < 3; j++)
+ {
+ int i= 0;
+ if (cmp (d[j]->file_name (), file1))
+ return false;
+ if (cmp (d[j]->function_name (), function1))
+ return false;
+ if (d[j]->line () != line + j + 1)
+ return false;
+ if (d[j]->column () != (j == 1 ? 49 : 28))
+ return false;
+ }
+
+ S e = __LINE__;
+ // ^ column 9
+ S f = 1.0;
+ if (cmp (e.loc.file_name (), file1))
+ return false;
+ if (cmp (f.loc.file_name (), file1))
+ return false;
+ if (cmp (e.loc.function_name (), function1))
+ return false;
+ if (cmp (f.loc.function_name (), f.func))
+ return false;
+ if (e.loc.line () != e.line)
+ return false;
+ if (f.loc.line () != f.line)
+ return false;
+ if (e.loc.column () != 9)
+ return false;
+ if (f.loc.column () != 38)
+ return false;
+ return true;
+}
+
+static_assert (bar ());
+
+int
+main ()
+{
+ if (!bar ())
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/srcloc16.C b/gcc/testsuite/g++.dg/cpp2a/srcloc16.C
new file mode 100644
index 0000000..c8bd281
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/srcloc16.C
@@ -0,0 +1,97 @@
+// { dg-do run { target c++20 } }
+
+namespace std {
+ struct source_location {
+ struct __impl {
+ const char *_M_file_name;
+ const char *_M_function_name;
+ unsigned int _M_line, _M_column;
+ };
+ const __impl *__ptr;
+ constexpr source_location () : __ptr (nullptr) {}
+ static consteval source_location
+ current (const void *__p = __builtin_source_location ()) {
+ source_location __ret;
+ __ret.__ptr = static_cast <const __impl *> (__p);
+ return __ret;
+ }
+ constexpr const char *file_name () const {
+ return __ptr ? __ptr->_M_file_name : "";
+ }
+ constexpr const char *function_name () const {
+ return __ptr ? __ptr->_M_function_name : "";
+ }
+ constexpr unsigned line () const {
+ return __ptr ? __ptr->_M_line : 0;
+ }
+ constexpr unsigned column () const {
+ return __ptr ? __ptr->_M_column : 0;
+ }
+ };
+}
+
+using namespace std;
+
+struct S
+{
+ source_location a = source_location::current ();
+ source_location b = source_location::current ();
+ source_location c = source_location ();
+ constexpr S () { c = source_location::current (); }
+};
+
+struct T
+{
+ int t;
+ source_location u = source_location::current ();
+ int v = __builtin_LINE ();
+};
+
+constexpr S s;
+constexpr T t = { 1 };
+
+constexpr bool
+cmp (const char *p, const char *q)
+{
+ for (; *p && *q; p++, q++)
+ if (*p != *q)
+ return true;
+ return *p || *q;
+}
+
+constexpr bool
+foo ()
+{
+ T u = { 2 };
+ source_location v = source_location::current ();
+ if (cmp (s.a.file_name (), s.c.file_name ())
+ || cmp (s.b.file_name (), s.c.file_name ())
+ || cmp (t.u.file_name (), s.c.file_name ())
+ || cmp (u.u.file_name (), s.c.file_name ())
+ || cmp (v.file_name (), s.c.file_name ())
+ || cmp (s.a.function_name (), s.c.function_name ())
+ || cmp (s.b.function_name (), s.c.function_name ())
+ || cmp (t.u.function_name (), "")
+ || cmp (u.u.function_name (), v.function_name ())
+ || s.a.line () != s.c.line ()
+ || s.b.line () != s.c.line ()
+ || t.u.line () != t.v
+ || u.u.line () + 1 != v.line ()
+ || s.a.column () != 18
+ || s.b.column () != 18
+ || s.c.column () != 50
+ || t.u.column () != 21
+ || u.u.column () != 13
+ || v.column () != 49)
+ return false;
+ return true;
+}
+
+static_assert (foo ());
+
+int
+main ()
+{
+ if (!foo ())
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/srcloc17.C b/gcc/testsuite/g++.dg/cpp2a/srcloc17.C
new file mode 100644
index 0000000..16704d0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/srcloc17.C
@@ -0,0 +1,122 @@
+// { dg-do run { target c++20 } }
+
+namespace std {
+ struct source_location {
+ struct __impl {
+ const char *_M_file_name;
+ const char *_M_function_name;
+ unsigned int _M_line, _M_column;
+ };
+ const __impl *__ptr;
+ constexpr source_location () : __ptr (nullptr) {}
+ static consteval source_location
+ current (const void *__p = __builtin_source_location ()) {
+ source_location __ret;
+ __ret.__ptr = static_cast <const __impl *> (__p);
+ return __ret;
+ }
+ constexpr const char *file_name () const {
+ return __ptr ? __ptr->_M_file_name : "";
+ }
+ constexpr const char *function_name () const {
+ return __ptr ? __ptr->_M_function_name : "";
+ }
+ constexpr unsigned line () const {
+ return __ptr ? __ptr->_M_line : 0;
+ }
+ constexpr unsigned column () const {
+ return __ptr ? __ptr->_M_column : 0;
+ }
+ };
+}
+
+using namespace std;
+
+template <int N>
+constexpr source_location
+foo (const source_location x = source_location::current ())
+{
+ return x;
+}
+
+template <int N>
+struct S {
+ const char *func;
+ unsigned line = 0;
+ source_location loc = source_location::current ();
+
+ constexpr S (int l, source_location loc = source_location::current ())
+ : func(__FUNCTION__), line(l), loc(loc)
+ {}
+
+ constexpr S (double)
+ : func(__FUNCTION__), line(__LINE__)
+ // ^ column 38
+ {}
+};
+
+constexpr bool
+cmp (const char *p, const char *q)
+{
+ for (; *p && *q; p++, q++)
+ if (*p != *q)
+ return true;
+ return *p || *q;
+}
+
+template <int N>
+constexpr bool
+bar ()
+{
+ int line = __LINE__;
+ source_location a = foo<N> ();
+ source_location b = source_location::current ();
+ source_location c = foo<N> ();
+ // ^ column 30
+ // ^ column 48
+ const source_location *d[3] = { &a, &b, &c };
+ const char *file1 = __FILE__;
+ const char *function1 = b.function_name ();
+ for (int j = 0; j < 3; j++)
+ {
+ int i= 0;
+ if (cmp (d[j]->file_name (), file1))
+ return false;
+ if (cmp (d[j]->function_name (), function1))
+ return false;
+ if (d[j]->line () != line + j + 1)
+ return false;
+ if (d[j]->column () != (j == 1 ? 48 : 30))
+ return false;
+ }
+
+ S<N> e = __LINE__;
+ // ^ column 8
+ S<N> f = 1.0;
+ if (cmp (e.loc.file_name (), file1))
+ return false;
+ if (cmp (f.loc.file_name (), file1))
+ return false;
+ if (cmp (e.loc.function_name (), function1))
+ return false;
+ if (cmp (f.loc.function_name (), f.func))
+ return false;
+ if (e.loc.line () != e.line)
+ return false;
+ if (f.loc.line () != f.line)
+ return false;
+ if (e.loc.column () != 8)
+ return false;
+ if (f.loc.column () != 38)
+ return false;
+ return true;
+}
+
+static_assert (bar<0> ());
+
+int
+main ()
+{
+ if (!bar<0> ())
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/srcloc18.C b/gcc/testsuite/g++.dg/cpp2a/srcloc18.C
new file mode 100644
index 0000000..7e685ba
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/srcloc18.C
@@ -0,0 +1,100 @@
+// { dg-do run { target c++20 } }
+
+namespace std {
+ struct source_location {
+ struct __impl {
+ const char *_M_file_name;
+ const char *_M_function_name;
+ unsigned int _M_line, _M_column;
+ };
+ const __impl *__ptr;
+ constexpr source_location () : __ptr (nullptr) {}
+ static consteval source_location
+ current (const void *__p = __builtin_source_location ()) {
+ source_location __ret;
+ __ret.__ptr = static_cast <const __impl *> (__p);
+ return __ret;
+ }
+ constexpr const char *file_name () const {
+ return __ptr ? __ptr->_M_file_name : "";
+ }
+ constexpr const char *function_name () const {
+ return __ptr ? __ptr->_M_function_name : "";
+ }
+ constexpr unsigned line () const {
+ return __ptr ? __ptr->_M_line : 0;
+ }
+ constexpr unsigned column () const {
+ return __ptr ? __ptr->_M_column : 0;
+ }
+ };
+}
+
+using namespace std;
+
+template <int N>
+struct S
+{
+ source_location a = source_location::current ();
+ source_location b = source_location::current ();
+ source_location c = source_location ();
+ constexpr S () { c = source_location::current (); }
+};
+
+template <int N>
+struct T
+{
+ int t;
+ source_location u = source_location::current ();
+ int v = __builtin_LINE ();
+};
+
+constexpr S<0> s;
+constexpr T<0> t = { 1 };
+
+constexpr bool
+cmp (const char *p, const char *q)
+{
+ for (; *p && *q; p++, q++)
+ if (*p != *q)
+ return true;
+ return *p || *q;
+}
+
+template <int N>
+constexpr bool
+foo ()
+{
+ T<N> u = { 2 };
+ source_location v = source_location::current ();
+ if (cmp (s.a.file_name (), s.c.file_name ())
+ || cmp (s.b.file_name (), s.c.file_name ())
+ || cmp (t.u.file_name (), s.c.file_name ())
+ || cmp (u.u.file_name (), s.c.file_name ())
+ || cmp (v.file_name (), s.c.file_name ())
+ || cmp (s.a.function_name (), s.c.function_name ())
+ || cmp (s.b.function_name (), s.c.function_name ())
+ || cmp (t.u.function_name (), "")
+ || cmp (u.u.function_name (), v.function_name ())
+ || s.a.line () != s.c.line ()
+ || s.b.line () != s.c.line ()
+ || t.u.line () != t.v
+ || u.u.line () + 1 != v.line ()
+ || s.a.column () != 18
+ || s.b.column () != 18
+ || s.c.column () != 49
+ || t.u.column () != 24
+ || u.u.column () != 8
+ || v.column () != 48)
+ return false;
+ return true;
+}
+
+static_assert (foo<1> ());
+
+int
+main ()
+{
+ if (!foo<1> ())
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/using-enum-1.C b/gcc/testsuite/g++.dg/cpp2a/using-enum-1.C
new file mode 100644
index 0000000..fd34ca8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/using-enum-1.C
@@ -0,0 +1,62 @@
+// Test of using an enumerator.
+// { dg-do compile { target c++2a } }
+
+// using ENUM::V;
+enum class E {v};
+
+using E::v;
+using E::v; // OK
+
+E a = v;
+
+class C
+{
+ using E::v; // { dg-message "declared private here" }
+
+ static inline const E m = v;
+};
+
+E b = C::v; // { dg-error "private" }
+
+struct B
+{
+ enum E {e};
+ enum class EC {f};
+ using EC::f;
+};
+
+struct D
+{
+private:
+ using B::e; // { dg-message "declared private here" }
+ using B::f; // { dg-message "declared private here" }
+};
+
+struct F : D
+{
+ static inline const auto bad1 = e; // { dg-error "private" }
+ static inline const auto bad2 = f; // { dg-error "private" }
+
+ static inline const auto ok1 = B::e;
+ static inline const auto ok2 = B::f;
+ static inline const auto also_ok1 = B::E::e;
+ static inline const auto also_ok2 = B::EC::f;
+};
+
+using B::e;
+auto bob = e;
+
+struct Q
+{
+ using B::e;
+};
+using Q::e; // OK
+
+using D::e; // { dg-error "private" }
+
+template <class T>
+struct X : T
+{
+ using T::e;
+};
+auto fob = X<Q>::e;
diff --git a/gcc/testsuite/g++.dg/cpp2a/using-enum-2.C b/gcc/testsuite/g++.dg/cpp2a/using-enum-2.C
new file mode 100644
index 0000000..66b37f9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/using-enum-2.C
@@ -0,0 +1,48 @@
+// Test of 'using enum' in different scopes.
+// { dg-do compile { target c++20 } }
+
+namespace N
+{
+ enum class E { e, f };
+}
+
+int main()
+{
+ using enum N::E;
+ static_assert (e < f);
+}
+
+struct A
+{
+ using enum N::E;
+ static_assert (e < f);
+};
+
+namespace M
+{
+ using enum N::E;
+ static_assert (e < f);
+
+ enum class X: int; // { dg-message "opaque" }
+ using enum X; // { dg-error "enum-specifier" }
+}
+
+template <class T>
+void f()
+{
+ using enum N::E;
+ static_assert (e < f);
+}
+
+template <class T>
+struct AT
+{
+ using enum N::E;
+ static_assert (e < f);
+};
+
+template <class T>
+struct BT
+{
+ using enum T::E; // { dg-error "dependent" }
+};
diff --git a/gcc/testsuite/g++.dg/cpp2a/using-enum-3.C b/gcc/testsuite/g++.dg/cpp2a/using-enum-3.C
new file mode 100644
index 0000000..d09bd6a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/using-enum-3.C
@@ -0,0 +1,6 @@
+// Test of 'using enum' syntax error recovery.
+// { dg-do compile { target c++20 } }
+
+using enum 2 + garbage3'850%^&; // { dg-error "" }
+
+void f() {}
diff --git a/gcc/testsuite/g++.dg/cpp2a/using-enum-4.C b/gcc/testsuite/g++.dg/cpp2a/using-enum-4.C
new file mode 100644
index 0000000..03432cf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/using-enum-4.C
@@ -0,0 +1,13 @@
+// Test for suggestion to try 'using enum'.
+// { dg-do compile { target c++20 } }
+
+struct A
+{
+ enum E { e };
+};
+
+struct B
+{
+ using A::E; // { dg-error "" }
+ // { dg-message "using enum" "" { target *-*-* } .-1 }
+};
diff --git a/gcc/testsuite/g++.dg/cpp2a/using-enum-5.C b/gcc/testsuite/g++.dg/cpp2a/using-enum-5.C
new file mode 100644
index 0000000..e5fe820
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/using-enum-5.C
@@ -0,0 +1,132 @@
+// Examples from P1099R5
+// { dg-do compile { target c++20 } }
+
+namespace my_lib {
+
+ enum class errcode
+ {
+ SUCCESS = 0,
+ ENOMEM = 1,
+ EAGAIN = 2,
+ ETOOSLOW = 3
+ };
+ using enum errcode; // import enumerators into namespace
+}
+
+namespace NS {
+ my_lib::errcode get_widget() {
+ using namespace my_lib;
+ return ETOOSLOW; // works, and conversions to int don't.
+ int i = ETOOSLOW; // { dg-error "" }
+ }
+}
+
+enum class rgba_color_channel { red, green, blue, alpha};
+
+const char * to_string(rgba_color_channel channel) {
+ switch (channel) {
+ using enum rgba_color_channel;
+ case red: return "red";
+ case green: return "green";
+ case blue: return "blue";
+ case alpha: return "alpha";
+ }
+ return nullptr;
+}
+
+namespace ns {
+ struct E_detail {
+ enum E { e1, e2 };
+ friend void swap(E&, E&); // adl-only swap in the only associated scope of the enum
+ };
+ using E = E_detail::E; // import E into ns
+ using enum E; // expose the enumerators of E in ns. Also note the direct reference to E.
+}
+
+int main() {
+ auto x = ns::e1;
+ auto y = ns::e2;
+ swap(x, y); // finds the swap in the associated struct
+}
+
+namespace N0 {
+ enum E { x };
+ struct S {
+ enum H { y };
+ enum class K { z };
+ using E::x; // OK, introduces x into S
+ using E::x; // { dg-error "" } redeclaration in class scope
+ using H::y; // { dg-error "" } redeclaration in class scope
+ using K::z; // OK, introduces z into S
+ };
+ namespace NS {
+ enum H { y };
+ enum class K { z };
+ using E::x; // OK, introduces x into NS
+ using E::x; // OK, just a redeclaration of the same entity
+ using H::y; // OK, redeclaration of the same entity
+ using K::z; // OK, introduces z into NS
+ };
+}
+namespace N1 {
+ struct S {
+ enum E { x };
+ enum class EC { y };
+ using EC::y;
+ };
+
+ void f() {
+ using S::x; // OK
+ x; // resolves to S::E::x;
+ using S::y; // OK
+ y; // resolves to S::EC::y;
+ }
+}
+
+namespace N2 {
+ enum class E { a, b, c };
+ using E::a, E::b, E::c; // OK, imports all three
+ auto x = (a,b,c);
+}
+
+namespace N3 {
+ struct B {
+ enum class E { x };
+ };
+ enum class H { y };
+ struct C : B {
+ using enum B::E; // OK, introduces E::x into C
+ using enum H; // OK, introduces y into C. Does not introduce H
+ };
+ auto i = C::y; // OK
+ C::H h; // { dg-error "" }
+}
+
+namespace N4 {
+ enum class button { up, down };
+ struct S {
+ using button::up;
+ button b = up; // OK
+ };
+}
+
+namespace N5 {
+ enum class fruit { orange, apple };
+ struct S {
+ using enum fruit; // OK, introduces orange and apple into S
+ };
+ void f() {
+ S s;
+ s.orange; // OK, names fruit::orange
+ S::orange; // OK, names fruit::orange
+ }
+}
+
+namespace N6 {
+ enum class fruit { orange, apple };
+ enum class color { red, orange };
+ void f() {
+ using enum fruit; // OK
+ using enum color; // { dg-error "" } color::orange and fruit::orange conflict
+ }
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/using-enum-6.C b/gcc/testsuite/g++.dg/cpp2a/using-enum-6.C
new file mode 100644
index 0000000..732cdfd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/using-enum-6.C
@@ -0,0 +1,5 @@
+// { dg-do compile { target c++2a } }
+
+using enum void; // { dg-error "non-enum" }
+struct A {}; // { dg-message "declared here" }
+using enum A; // { dg-error "non-enum" }
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp17.C b/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp17.C
new file mode 100644
index 0000000..460294c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp17.C
@@ -0,0 +1,7 @@
+// { dg-do compile }
+// { dg-options "-O -std=c++17 -gdwarf-5 -dA" }
+// For -gdwarf-6 hopefully DW_LANG_C_plus_plus_17
+// DW_LANG_C_plus_plus_14 = 0x0021
+// { dg-final { scan-assembler "0x21\[^\n\r]* DW_AT_language" } } */
+
+int version;
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp20.C b/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp20.C
new file mode 100644
index 0000000..abd7351
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/lang-cpp20.C
@@ -0,0 +1,7 @@
+// { dg-do compile }
+// { dg-options "-O -std=c++20 -gdwarf-5 -dA" }
+// For -gdwarf-6 hopefully DW_LANG_C_plus_plus_20
+// DW_LANG_C_plus_plus_14 = 0x0021
+// { dg-final { scan-assembler "0x21\[^\n\r]* DW_AT_language" } } */
+
+int version;
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/using-enum.C b/gcc/testsuite/g++.dg/debug/dwarf2/using-enum.C
new file mode 100644
index 0000000..7663a13
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/using-enum.C
@@ -0,0 +1,21 @@
+// Test of 'using enum' debug info.
+// { dg-do compile { target c++20 } }
+// { dg-options "-g -dA" }
+
+struct A
+{
+ // All the counts are +1 for the abbreviation table.
+ // { dg-final { scan-assembler-times "DW_TAG_enumeration_type" 2 } }
+ // { dg-final { scan-assembler-times "DW_TAG_enumerator" 3 } }
+ enum E { e, f };
+};
+
+struct B
+{
+ // The using-enum-declaration is represented by two
+ // DW_TAG_imported_declaration, one for each enumerator.
+ // { dg-final { scan-assembler-times "DW_TAG_imported_declaration" 3 } }
+ using enum A::E;
+};
+
+B b;
diff --git a/gcc/testsuite/g++.dg/debug/localclass2.C b/gcc/testsuite/g++.dg/debug/localclass2.C
new file mode 100644
index 0000000..9897eec
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/localclass2.C
@@ -0,0 +1,24 @@
+// PR c++/97918
+// { dg-do compile { target c++11 } }
+// { dg-require-effective-target lto }
+// { dg-additional-options "-g -O -flto" }
+
+namespace { class A {}; }
+class B {};
+template <typename T> struct H {
+ constexpr static unsigned h = 0;
+};
+
+template <typename T> A bar ()
+{
+ struct J {
+ static void foo();
+ };
+ H<J>();
+ return A ();
+}
+
+void fn ()
+{
+ bar<B>; // only mentions the function
+}
diff --git a/gcc/testsuite/g++.dg/diagnostic/pr87386.C b/gcc/testsuite/g++.dg/diagnostic/pr87386.C
index 85726af..679a517 100644
--- a/gcc/testsuite/g++.dg/diagnostic/pr87386.C
+++ b/gcc/testsuite/g++.dg/diagnostic/pr87386.C
@@ -14,5 +14,5 @@ static_assert (foo::test<int>::value, "foo"); // { dg-error "static assertion f
static_assert (foo::test<int>::value && true, "bar"); // { dg-error "static assertion failed: bar" }
/* { dg-begin-multiline-output "" }
static_assert (foo::test<int>::value && true, "bar");
- ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
+ ~~~~~~~~~~~~~~~~^~~~~
{ dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/g++.dg/diagnostic/static_assert1.C b/gcc/testsuite/g++.dg/diagnostic/static_assert1.C
new file mode 100644
index 0000000..fecf3cc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/static_assert1.C
@@ -0,0 +1,30 @@
+// PR c++/97518
+// { dg-do compile { target c++17 } }
+
+template <typename T, typename U> struct is_same { static constexpr bool value = false; };
+template <typename T> struct is_same<T, T> { static constexpr bool value = true; };
+
+template <typename T> using some_metafunction_t = T;
+
+template <typename T>
+void foo(T ) {
+ using X = T*;
+ using Y = some_metafunction_t<T>;
+
+ static_assert(is_same<X, Y>::value); // { dg-error "static assertion failed" }
+ // { dg-message {.is_same<int\*, int>::value. evaluates to false} "" { target *-*-* } .-1 }
+ static_assert(is_same<X, Y>::value, "foo"); // { dg-error "static assertion failed: foo" }
+ // { dg-message {.is_same<int\*, int>::value. evaluates to false} "" { target *-*-* } .-1 }
+ static_assert(is_same<X, X>::value && is_same<X, Y>::value); // { dg-error "static assertion failed" }
+ // { dg-message {.is_same<int\*, int>::value. evaluates to false} "" { target *-*-* } .-1 }
+ static_assert(is_same<X, Y>::value && is_same<X, X>::value); // { dg-error "static assertion failed" }
+ // { dg-message {.is_same<int\*, int>::value. evaluates to false} "" { target *-*-* } .-1 }
+ static_assert(is_same<X, X>::value
+ && is_same<Y, Y>::value
+ && is_same<X, Y>::value); // { dg-error "static assertion failed" }
+ // { dg-message {.is_same<int\*, int>::value. evaluates to false} "" { target *-*-* } .-1 }
+}
+
+void bar() {
+ foo(0);
+}
diff --git a/gcc/testsuite/g++.dg/diagnostic/static_assert2.C b/gcc/testsuite/g++.dg/diagnostic/static_assert2.C
new file mode 100644
index 0000000..542697f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/static_assert2.C
@@ -0,0 +1,68 @@
+// PR c++/97518
+// { dg-do compile { target c++11 } }
+// { dg-options "-fdiagnostics-show-caret" }
+
+constexpr bool yes () { return true; }
+constexpr bool no () { return false; }
+constexpr bool yay = true;
+constexpr bool nay = false;
+
+void
+bar ()
+{
+ static_assert (true && true && no(), ""); // { dg-error "static assertion failed" }
+/* { dg-begin-multiline-output "" }
+ static_assert (true && true && no(), "");
+ ~~^~
+ { dg-end-multiline-output "" } */
+ static_assert (yay && nay, ""); // { dg-error "static assertion failed" }
+/* { dg-begin-multiline-output "" }
+ static_assert (yay && nay, "");
+ ^~~
+ { dg-end-multiline-output "" } */
+ static_assert (yes() && no(), ""); // { dg-error "static assertion failed" }
+/* { dg-begin-multiline-output "" }
+ static_assert (yes() && no(), "");
+ ~~^~
+ { dg-end-multiline-output "" } */
+ static_assert (no() && yes(), ""); // { dg-error "static assertion failed" }
+/* { dg-begin-multiline-output "" }
+ static_assert (no() && yes(), "");
+ ~~^~
+ { dg-end-multiline-output "" } */
+ static_assert (no() && no() && yes(), ""); // { dg-error "static assertion failed" }
+/* { dg-begin-multiline-output "" }
+ static_assert (no() && no() && yes(), "");
+ ~~^~
+ { dg-end-multiline-output "" } */
+ static_assert (yes() && yes() && yes () && no() && yes(), ""); // { dg-error "static assertion failed" }
+/* { dg-begin-multiline-output "" }
+ static_assert (yes() && yes() && yes () && no() && yes(), "");
+ ~~^~
+ { dg-end-multiline-output "" } */
+ static_assert (yes() && yes() && yes () && (no() && yes()), ""); // { dg-error "static assertion failed" }
+/* { dg-begin-multiline-output "" }
+ static_assert (yes() && yes() && yes () && (no() && yes()), "");
+ ~~^~
+ { dg-end-multiline-output "" } */
+ static_assert ((yes() && no()) && no(), ""); // { dg-error "static assertion failed" }
+/* { dg-begin-multiline-output "" }
+ static_assert ((yes() && no()) && no(), "");
+ ~~^~
+ { dg-end-multiline-output "" } */
+ static_assert ((yes() && no()) && no(), ""); // { dg-error "static assertion failed" }
+/* { dg-begin-multiline-output "" }
+ static_assert ((yes() && no()) && no(), "");
+ ~~^~
+ { dg-end-multiline-output "" } */
+ static_assert ((no() || no()) && yes(), ""); // { dg-error "static assertion failed" }
+/* { dg-begin-multiline-output "" }
+ static_assert ((no() || no()) && yes(), "");
+ ~~~~~~^~~~~~~~
+ { dg-end-multiline-output "" } */
+ static_assert ((yes() || no()) && no(), ""); // { dg-error "static assertion failed" }
+/* { dg-begin-multiline-output "" }
+ static_assert ((yes() || no()) && no(), "");
+ ~~^~
+ { dg-end-multiline-output "" } */
+}
diff --git a/gcc/testsuite/g++.dg/diagnostic/static_assert3.C b/gcc/testsuite/g++.dg/diagnostic/static_assert3.C
new file mode 100644
index 0000000..5d36388
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/static_assert3.C
@@ -0,0 +1,36 @@
+// PR c++/97518
+// { dg-do compile { target c++17 } }
+// { dg-options "-fdiagnostics-show-caret" }
+
+template <typename T, typename U> struct is_same { static constexpr bool value = false; };
+template <typename T> struct is_same<T, T> { static constexpr bool value = true; };
+
+template <typename T, typename U>
+void f(T, U)
+{
+ static_assert(is_same<T, T>::value && is_same<T, U>::value); // { dg-error "56:static assertion failed" }
+/* { dg-begin-multiline-output "" }
+ static_assert(is_same<T, T>::value && is_same<T, U>::value);
+ ^~~~~
+ { dg-end-multiline-output "" } */
+// { dg-message ".is_same<int, double>::value. evaluates to false" "" { target *-*-* } .-5 }
+ static_assert(is_same<U, T>::value && is_same<U, U>::value); // { dg-error "32:static assertion failed" }
+/* { dg-begin-multiline-output "" }
+ static_assert(is_same<U, T>::value && is_same<U, U>::value);
+ ^~~~~
+ { dg-end-multiline-output "" } */
+// { dg-message ".is_same<double, int>::value. evaluates to false" "" { target *-*-* } .-5 }
+ static_assert(is_same<U, U>::value
+ && is_same<U, T>::value // { dg-error "35:static assertion failed" }
+ && is_same<T, T>::value);
+/* { dg-begin-multiline-output "" }
+ && is_same<U, T>::value
+ ^~~~~
+ { dg-end-multiline-output "" } */
+// { dg-message ".is_same<double, int>::value. evaluates to false" "" { target *-*-* } .-6 }
+}
+
+void g()
+{
+ f(0, 1.3);
+}
diff --git a/gcc/testsuite/g++.dg/eh/crash2.C b/gcc/testsuite/g++.dg/eh/crash2.C
new file mode 100644
index 0000000..fff8e14
--- /dev/null
+++ b/gcc/testsuite/g++.dg/eh/crash2.C
@@ -0,0 +1,20 @@
+// PR c++/97187
+// { dg-do compile { target c++14 } }
+// { dg-options "-fno-exceptions" }
+
+auto yp = [] { return 0; };
+
+template <class DI>
+DI
+zl ()
+{
+ auto au = [] () -> DI { return *new auto (true ? yp : throw); }; // { dg-error "exception handling disabled" }
+
+ return au ();
+}
+
+auto
+vd ()
+{
+ return zl <decltype (yp)> ();
+}
diff --git a/gcc/testsuite/g++.dg/expr/anew5.C b/gcc/testsuite/g++.dg/expr/anew5.C
new file mode 100644
index 0000000..d597caf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/anew5.C
@@ -0,0 +1,26 @@
+// PR c++/97523
+// { dg-do compile }
+// We were turning the () into {} which made it seem like
+// aggregate-initialization (we are dealing with arrays here), which
+// performs copy-initialization, which only accepts converting constructors.
+
+struct T {
+ explicit T();
+ T(int);
+};
+
+void
+fn (int n)
+{
+ new T[1]();
+ new T[2]();
+ new T[3]();
+ new T[n]();
+#if __cpp_aggregate_paren_init
+ new T[]();
+ new T[2](1, 2);
+ // T[2] is initialized via copy-initialization, so we can't call
+ // explicit T().
+ new T[3](1, 2); // { dg-error "explicit constructor" "" { target c++20 } }
+#endif
+}
diff --git a/gcc/testsuite/g++.dg/expr/anew6.C b/gcc/testsuite/g++.dg/expr/anew6.C
new file mode 100644
index 0000000..0542daa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/anew6.C
@@ -0,0 +1,33 @@
+// PR c++/97523
+// { dg-do compile { target c++11 } }
+
+// [expr.new]/24: If the new-expression creates an object or an array of
+// objects of class type, access and ambiguity control are done for the
+// [...] constructor selected for the initialization (if any).
+// NB: We only check for a default constructor if the array has a non-constant
+// bound, or there are insufficient initializers. Since an array is an
+// aggregate, we perform aggregate-initialization, which performs
+// copy-initialization, so we only accept converting constructors.
+
+struct T {
+ explicit T();
+ T(int);
+};
+
+struct S {
+ S(int);
+};
+
+void
+fn (int n)
+{
+ new T[1]{}; // { dg-error "explicit constructor" }
+ new T[2]{1, 2};
+ new T[3]{1, 2}; // { dg-error "explicit constructor" }
+ new T[n]{}; // { dg-error "explicit constructor" }
+
+ new S[1]{}; // { dg-error "could not convert" }
+ new S[2]{1, 2};
+ new S[3]{1, 2}; // { dg-error "could not convert" }
+ new S[n]{}; // { dg-error "could not convert" }
+}
diff --git a/gcc/testsuite/g++.dg/ext/builtin-clear-padding-1.C b/gcc/testsuite/g++.dg/ext/builtin-clear-padding-1.C
new file mode 100644
index 0000000..d188186
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/builtin-clear-padding-1.C
@@ -0,0 +1,15 @@
+// PR middle-end/97943
+// { dg-do compile }
+// { dg-options "" }
+
+struct S { int a; char b[] __attribute__((aligned (2 * sizeof (int)))); }; // { dg-error "flexible array member 'S::b' not at end of 'struct \[TV]'" }
+struct T { int a; struct S b; int c; }; // { dg-message "next member 'int T::c' declared here|in the definition of 'struct T'" }
+union U { int a; struct S b; };
+struct V { int a; union U b; int : 15; int c; }; // { dg-message "next member 'int V::c' declared here|in the definition of 'struct V'" }
+
+void
+foo (struct T *t, struct V *v)
+{
+ __builtin_clear_padding (t); // { dg-error "flexible array member 'S::b' does not have well defined padding bits for '__builtin_clear_padding'" }
+ __builtin_clear_padding (v); // { dg-error "flexible array member 'S::b' does not have well defined padding bits for '__builtin_clear_padding'" }
+}
diff --git a/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C b/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C
index 7f82922..9f05ca5 100644
--- a/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C
+++ b/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C
@@ -72,10 +72,37 @@ template class templated_struct4<svint8_t>;
template<typename T> struct templated_struct5 : T {}; // { dg-error {base type '[^']*' fails to be a struct or class type} }
template class templated_struct5<svint8_t>;
+template<typename T, unsigned N> struct templated_struct6 { T x[N]; }; // { dg-error {array elements cannot have SVE type '(__SVInt8_t|svint8_t)'} }
+template class templated_struct6<svint8_t, 2>;
+
+template<typename T>
+struct templated_struct7 {
+ static const int size = sizeof (T); // { dg-error {SVE type '(__SVInt8_t|svint8_t)' does not have a fixed size} }
+#if __cplusplus >= 201103L
+ static const int align = alignof (T); // { dg-error {SVE type '(__SVInt8_t|svint8_t)' does not have a defined alignment} "" { target c++11 } }
+#endif
+
+ void f1 (T (&)[2]); // { dg-error {array elements cannot have SVE type '(__SVInt8_t|svint8_t)'} }
+#if __cplusplus >= 201103L
+ auto f2 () -> decltype (new T); // { dg-error {cannot allocate objects with SVE type '(__SVInt8_t|svint8_t)'} "" { target c++11 } }
+ auto f3 (T *a) -> decltype (delete a); // { dg-error {cannot delete objects with SVE type '(__SVInt8_t|svint8_t)'} "" { target c++11 } }
+#else
+ void f2 () throw (T); // { dg-error {cannot throw or catch SVE type '(__SVInt8_t|svint8_t)'} "" { target c++98_only } }
+#endif
+};
+template class templated_struct7<svint8_t>;
+
+template<typename T> struct templated_struct8 { typedef int type; };
+
+template<typename T>
+void sfinae_f1 (typename templated_struct8<T[2]>::type);
+template<typename T>
+void sfinae_f1 (T &);
+
#if __cplusplus >= 201103L
template<int N> using typedef_sizeless1 = svint8_t;
template<int N> using typedef_sizeless1 = svint8_t;
-template<typename T> using array = T[2];
+template<typename T> using array = T[2]; // { dg-error {array elements cannot have SVE type '(svint8_t|__SVInt8_t)'} "" { target c++11 } }
#endif
// Pointers to sizeless types.
@@ -119,7 +146,7 @@ statements (int n)
__alignof (ext_produce_sve_sc ()); // { dg-error {SVE type 'svint8_t' does not have a defined alignment} }
#if __cplusplus >= 201103L
- array<svint8_t> foo = {}; // { dg-error {array elements cannot have SVE type '(svint8_t|__SVInt8_t)'} "" { target c++11 } }
+ array<svint8_t> foo = {}; // { dg-message {required from here} "" { target c++11 } }
#endif
// Initialization.
@@ -298,6 +325,8 @@ statements (int n)
thrower2 ();
#endif
+ sfinae_f1<svint8_t> (sve_sc1);
+
// Use in traits. Doesn't use static_assert so that tests work with
// earlier -std=s.
diff --git a/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C b/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C
index 40b65d3..0b86d9e 100644
--- a/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C
+++ b/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C
@@ -72,10 +72,37 @@ template class templated_struct4<svint8_t>;
template<typename T> struct templated_struct5 : T {}; // { dg-error {base type '[^']*' fails to be a struct or class type} }
template class templated_struct5<svint8_t>;
+template<typename T, unsigned N> struct templated_struct6 { T x[N]; }; // { dg-error {array elements cannot have SVE type '(__SVInt8_t|svint8_t)'} }
+template class templated_struct6<svint8_t, 2>;
+
+template<typename T>
+struct templated_struct7 {
+ static const int size = sizeof (T); // { dg-error {SVE type '(__SVInt8_t|svint8_t)' does not have a fixed size} }
+#if __cplusplus >= 201103L
+ static const int align = alignof (T); // { dg-error {SVE type '(__SVInt8_t|svint8_t)' does not have a defined alignment} "" { target c++11 } }
+#endif
+
+ void f1 (T (&)[2]); // { dg-error {array elements cannot have SVE type '(__SVInt8_t|svint8_t)'} }
+#if __cplusplus >= 201103L
+ auto f2 () -> decltype (new T); // { dg-error {cannot allocate objects with SVE type '(__SVInt8_t|svint8_t)'} "" { target c++11 } }
+ auto f3 (T *a) -> decltype (delete a); // { dg-error {cannot delete objects with SVE type '(__SVInt8_t|svint8_t)'} "" { target c++11 } }
+#else
+ void f2 () throw (T); // { dg-error {cannot throw or catch SVE type '(__SVInt8_t|svint8_t)'} "" { target c++98_only } }
+#endif
+};
+template class templated_struct7<svint8_t>;
+
+template<typename T> struct templated_struct8 { typedef int type; };
+
+template<typename T>
+void sfinae_f1 (typename templated_struct8<T[2]>::type);
+template<typename T>
+void sfinae_f1 (T &);
+
#if __cplusplus >= 201103L
template<int N> using typedef_sizeless1 = svint8_t;
template<int N> using typedef_sizeless1 = svint8_t;
-template<typename T> using array = T[2];
+template<typename T> using array = T[2]; // { dg-error {array elements cannot have SVE type '(svint8_t|__SVInt8_t)'} "" { target c++11 } }
#endif
// Pointers to sizeless types.
@@ -119,7 +146,7 @@ statements (int n)
__alignof (ext_produce_sve_sc ()); // { dg-error {SVE type 'svint8_t' does not have a defined alignment} }
#if __cplusplus >= 201103L
- array<svint8_t> foo = {}; // { dg-error {array elements cannot have SVE type '(svint8_t|__SVInt8_t)'} "" { target c++11 } }
+ array<svint8_t> foo = {}; // { dg-message {required from here} "" { target c++11 } }
#endif
// Initialization.
@@ -298,6 +325,8 @@ statements (int n)
thrower2 ();
#endif
+ sfinae_f1<svint8_t> (sve_sc1);
+
// Use in traits. Doesn't use static_assert so that tests work with
// earlier -std=s.
diff --git a/gcc/testsuite/g++.dg/goacc/cache-1.C b/gcc/testsuite/g++.dg/goacc/cache-1.C
new file mode 100644
index 0000000..a8d5ab3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/goacc/cache-1.C
@@ -0,0 +1,15 @@
+/* OpenACC 'cache' directive: valid usage. */
+
+/* See also corresponding C/C++ variant '../../c-c++-common/goacc/cache-1.c'. */
+
+/* For execution testing, this file is '#include'd from
+ '../../../../libgomp/testsuite/libgomp.oacc-c++/cache-1.C'. */
+
+#define TEMPLATIZE
+#include "../../c-c++-common/goacc/cache-1.c"
+
+static void
+instantiate ()
+{
+ &test<0>;
+}
diff --git a/gcc/testsuite/g++.dg/goacc/cache-2.C b/gcc/testsuite/g++.dg/goacc/cache-2.C
new file mode 100644
index 0000000..ef0b8a9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/goacc/cache-2.C
@@ -0,0 +1,64 @@
+/* OpenACC 'cache' directive: invalid usage. */
+
+/* See also corresponding C/C++ variant '../../c-c++-common/goacc/cache-2.c'. */
+
+template <int N>
+static void
+test ()
+{
+#define N 2
+ int a[N], b[N];
+ int i;
+
+ for (i = 0; i < N; i++)
+ {
+ a[i] = 3;
+ b[i] = 0;
+ }
+
+#pragma acc parallel copyin (a[0:N]) copyout (b[0:N])
+{
+ int ii;
+
+ for (ii = 0; ii < N; ii++)
+ {
+ const int idx = ii;
+ int n = 1;
+ const int len = n;
+
+#pragma acc cache /* { dg-error "expected '\\\(' before end of line" } */
+#pragma acc cache a[0:N] /* { dg-error "expected '\\\(' before 'a'" } */
+ /* { dg-bogus "expected end of line before 'a'" "" { xfail c++ } .-1 } */
+#pragma acc cache (a) /* { dg-error "expected '\\\['" } */
+#pragma acc cache ( /* { dg-error "expected (identifier|unqualified-id) before end of line" } */
+#pragma acc cache () /* { dg-error "expected (identifier|unqualified-id) before '\\\)' token" } */
+#pragma acc cache (,) /* { dg-error "expected (identifier|unqualified-id) before '(,|\\\))' token" } */
+#pragma acc cache (a[0:N] /* { dg-error "expected '\\\)' before end of line" } */
+#pragma acc cache (a[0:N],) /* { dg-error "expected (identifier|unqualified-id) before '(,|\\\))' token" "" { xfail c } } */
+#pragma acc cache (a[0:N]) copyin (a[0:N]) /* { dg-error "expected end of line before 'copyin'" } */
+#pragma acc cache () /* { dg-error "expected (identifier|unqualified-id) before '\\\)' token" } */
+#pragma acc cache (a[0:N] b[0:N]) /* { dg-error "expected '\\\)' before 'b'" } */
+#pragma acc cache (a[0:N] b[0:N}) /* { dg-error "expected '\\\)' before 'b'" } */
+ /* { dg-bogus "expected end of line before '\\\}' token" "" { xfail c++ } .-1 } */
+#pragma acc cache (a[0:N] /* { dg-error "expected '\\\)' before end of line" } */
+#pragma acc cache (a[0:N]) ( /* { dg-error "expected end of line before '\\(' token" } */
+#pragma acc cache (a[0:N]) ii /* { dg-error "expected end of line before 'ii'" } */
+#pragma acc cache (a[0:N] ii) /* { dg-error "expected '\\)' before 'ii'" } */
+
+ b[ii] = a[ii];
+ }
+}
+
+
+ for (i = 0; i < N; i++)
+ {
+ if (a[i] != b[i])
+ __builtin_abort ();
+ }
+}
+
+static void
+instantiate ()
+{
+ &test<0>;
+}
diff --git a/gcc/testsuite/g++.dg/goacc/cache-3-1.C b/gcc/testsuite/g++.dg/goacc/cache-3-1.C
new file mode 100644
index 0000000..ceafb38
--- /dev/null
+++ b/gcc/testsuite/g++.dg/goacc/cache-3-1.C
@@ -0,0 +1,123 @@
+/* Test 'cache' directive diagnostics. */
+
+/* See also corresponding C/C++ variant: '../../c-c++-common/goacc/cache-3-1.c'. */
+
+/* See also corresponding C++ data clause variant: 'data-clause-1.C'. */
+
+/* { dg-additional-options "-fopenmp" } for '#pragma omp threadprivate'. */
+
+/* The current implementation doesn't restrict where a 'cache' directive may
+ appear, so we don't make any special arrangements. */
+
+extern int a[][10], a2[][10];
+int b[10], c[10][2], d[10], e[10], f[10];
+int b2[10], c2[10][2], d2[10], e2[10], f2[10];
+int k[10], l[10], m[10], n[10], o;
+int *p;
+int **q;
+int r[4][4][4][4][4];
+extern struct s s1;
+extern struct s s2[1]; /* { dg-error "array type has incomplete element type" "" { target c } } */
+int t[10];
+#pragma omp threadprivate (t)
+#pragma acc routine
+void bar (int *);
+
+template <int N>
+void
+foo (int g[3][10], int h[4][8], int i[2][10], int j[][9],
+ int g2[3][10], int h2[4][8], int i2[2][10], int j2[][9])
+{
+ #pragma acc cache(bar[2:5]) /* { dg-error "is not a variable" } */
+ ;
+ #pragma acc cache(t[2:5]) /* { dg-error "is threadprivate variable" } */
+ ;
+ #pragma acc cache(k[0.5:]) /* { dg-error "low bound \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma acc cache(l[:7.5f]) /* { dg-error "length \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma acc cache(m[p:]) /* { dg-error "low bound \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma acc cache(n[:p]) /* { dg-error "length \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma acc cache(o[2:5]) /* { dg-error "does not have pointer or array type" } */
+ ;
+ #pragma acc cache(s1) /* { dg-error "expected '\\\['" } */
+ ;
+ #pragma acc cache(s2) /* { dg-error "expected '\\\['" } */
+ ;
+ #pragma acc cache(a[:][:]) /* { dg-error "array type length expression must be specified" } */
+ bar (&a[0][0]);
+ #pragma acc cache(b[-1:]) /* { dg-error "negative low bound in array section" } */
+ bar (b);
+ #pragma acc cache(c[:-3][:]) /* { dg-error "negative length in array section" } */
+ bar (&c[0][0]);
+ #pragma acc cache(d[11:]) /* { dg-error "low bound \[^\n\r]* above array section size" } */
+ bar (d);
+ #pragma acc cache(e[:11]) /* { dg-error "length \[^\n\r]* above array section size" } */
+ bar (e);
+ #pragma acc cache(f[1:10]) /* { dg-error "high bound \[^\n\r]* above array section size" } */
+ bar (f);
+ #pragma acc cache(g[:][0:10]) /* { dg-error "for array function parameter length expression must be specified" } */
+ bar (&g[0][0]);
+ #pragma acc cache(h[2:1][-1:]) /* { dg-error "negative low bound in array section" } */
+ bar (&h[0][0]);
+ #pragma acc cache(h[:1][:-3]) /* { dg-error "negative length in array section" } */
+ bar (&h[0][0]);
+ #pragma acc cache(i[:1][11:]) /* { dg-error "low bound \[^\n\r]* above array section size" } */
+ bar (&i[0][0]);
+ #pragma acc cache(j[3:1][:10]) /* { dg-error "length \[^\n\r]* above array section size" } */
+ bar (&j[0][0]);
+ #pragma acc cache(j[30:1][5:5]) /* { dg-error "high bound \[^\n\r]* above array section size" } */
+ bar (&j[0][0]);
+ #pragma acc cache(a2[:1][2:4])
+ bar (&a2[0][0]);
+ #pragma acc cache(a2[3:5][:])
+ bar (&a2[0][0]);
+ #pragma acc cache(a2[3:5][:10])
+ bar (&a2[0][0]);
+ #pragma acc cache(b2[0:])
+ bar (b2);
+ #pragma acc cache(c2[:3][:])
+ bar (&c2[0][0]);
+ #pragma acc cache(d2[9:])
+ bar (d2);
+ #pragma acc cache(e2[:10])
+ bar (e2);
+ #pragma acc cache(f2[1:9])
+ bar (f2);
+ #pragma acc cache(g2[:1][2:4])
+ bar (&g2[0][0]);
+ #pragma acc cache(h2[2:2][0:])
+ bar (&h2[0][0]);
+ #pragma acc cache(h2[:1][:3])
+ bar (&h2[0][0]);
+ #pragma acc cache(i2[:1][9:])
+ bar (&i2[0][0]);
+ #pragma acc cache(j2[3:4][:9])
+ bar (&j2[0][0]);
+ #pragma acc cache(j2[30:1][5:4])
+ bar (&j2[0][0]);
+ #pragma acc cache(q[1:2])
+ ;
+ #pragma acc cache(q[3:5][:10]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma acc cache(r[3:][2:1][1:2])
+ ;
+ #pragma acc cache(r[3:][2:1][1:2][:][0:4])
+ ;
+ #pragma acc cache(r[3:][2:1][1:2][1:][0:4]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma acc cache(r[3:][2:1][1:2][:3][0:4]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma acc cache(r[3:][2:1][1:2][:][1:]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma acc cache(r[3:][2:1][1:2][:][:3]) /* { dg-error "array section is not contiguous" } */
+ ;
+}
+
+static void
+instantiate ()
+{
+ &foo<0>;
+}
diff --git a/gcc/testsuite/g++.dg/goacc/cache-3-2.C b/gcc/testsuite/g++.dg/goacc/cache-3-2.C
new file mode 100644
index 0000000..5561e17
--- /dev/null
+++ b/gcc/testsuite/g++.dg/goacc/cache-3-2.C
@@ -0,0 +1,57 @@
+/* Test 'cache' directive diagnostics. */
+
+/* See also corresponding C/C++ variant: '../../c-c++-common/goacc/cache-3-2.c'. */
+
+/* See also corresponding C++ data clause variant: 'data-clause-2.C'. */
+
+/* The current implementation doesn't restrict where a 'cache' directive may
+ appear, so we don't make any special arrangements. */
+
+template <int N>
+void
+foo (int *p, int (*q)[10], int r[10], int s[10][10])
+{
+ int a[10], b[10][10];
+ #pragma acc cache (p[-1:2])
+ ;
+ #pragma acc cache (q[-1:2][0:10])
+ ;
+ #pragma acc cache (q[-1:2][-2:10]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc cache (r[-1:2])
+ ;
+ #pragma acc cache (s[-1:2][:])
+ ;
+ #pragma acc cache (s[-1:2][-2:10]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc cache (a[-1:2]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc cache (b[-1:2][0:]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc cache (b[1:2][-2:10]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc cache (p[2:-3]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc cache (q[2:-3][:]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc cache (q[2:3][0:-1]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc cache (r[2:-5]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc cache (s[2:-5][:]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc cache (s[2:5][0:-4]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc cache (a[2:-5]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc cache (b[2:-5][0:10]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc cache (b[2:5][0:-4]) /* { dg-error "negative length in array section in" } */
+ ;
+}
+
+static void
+instantiate ()
+{
+ &foo<0>;
+}
diff --git a/gcc/testsuite/g++.dg/goacc/data-clause-1.C b/gcc/testsuite/g++.dg/goacc/data-clause-1.C
new file mode 100644
index 0000000..07ef6ae
--- /dev/null
+++ b/gcc/testsuite/g++.dg/goacc/data-clause-1.C
@@ -0,0 +1,122 @@
+/* Test data clause diagnostics. */
+
+/* See also corresponding OpenACC C/C++ variant: '../../c-c++-common/goacc/data-clause-1.c'. */
+
+/* See also corresponding OpenACC 'cache' directive variant: 'cache-3-1.C'. */
+
+/* See also corresponding OpenMP variant: '../gomp/map-1.C'. */
+
+/* { dg-additional-options "-fopenmp" } for '#pragma omp threadprivate'. */
+
+extern int a[][10], a2[][10];
+int b[10], c[10][2], d[10], e[10], f[10];
+int b2[10], c2[10][2], d2[10], e2[10], f2[10];
+int k[10], l[10], m[10], n[10], o;
+int *p;
+int **q;
+int r[4][4][4][4][4];
+extern struct s s1;
+extern struct s s2[1]; /* { dg-error "array type has incomplete element type" "" { target c } } */
+int t[10];
+#pragma omp threadprivate (t)
+#pragma acc routine
+void bar (int *);
+
+template <int N>
+void
+foo (int g[3][10], int h[4][8], int i[2][10], int j[][9],
+ int g2[3][10], int h2[4][8], int i2[2][10], int j2[][9])
+{
+ #pragma acc parallel copyin(bar[2:5]) /* { dg-error "is not a variable" } */
+ ;
+ #pragma acc parallel copyout(t[2:5]) /* { dg-error "is threadprivate variable" } */
+ ;
+ #pragma acc parallel copy(k[0.5:]) /* { dg-error "low bound \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma acc parallel copyout(l[:7.5f]) /* { dg-error "length \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma acc parallel copyin(m[p:]) /* { dg-error "low bound \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma acc parallel copy(n[:p]) /* { dg-error "length \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma acc parallel copyin(o[2:5]) /* { dg-error "does not have pointer or array type" } */
+ ;
+ #pragma acc parallel create(s1) /* { dg-error "'s1' does not have a mappable type in 'map' clause" } */
+ ;
+ #pragma acc parallel create(s2) /* { dg-error "'s2' does not have a mappable type in 'map' clause" } */
+ ;
+ #pragma acc parallel copyin(a[:][:]) /* { dg-error "array type length expression must be specified" } */
+ bar (&a[0][0]); /* { dg-error "referenced in target region does not have a mappable type" "PR97996" { xfail *-*-* } } */
+ #pragma acc parallel copy(b[-1:]) /* { dg-error "negative low bound in array section" } */
+ bar (b);
+ #pragma acc parallel copy(c[:-3][:]) /* { dg-error "negative length in array section" } */
+ bar (&c[0][0]);
+ #pragma acc parallel copyout(d[11:]) /* { dg-error "low bound \[^\n\r]* above array section size" } */
+ bar (d);
+ #pragma acc parallel copyin(e[:11]) /* { dg-error "length \[^\n\r]* above array section size" } */
+ bar (e);
+ #pragma acc parallel copyin(f[1:10]) /* { dg-error "high bound \[^\n\r]* above array section size" } */
+ bar (f);
+ #pragma acc parallel copyout(g[:][0:10]) /* { dg-error "for array function parameter length expression must be specified" } */
+ bar (&g[0][0]);
+ #pragma acc parallel copyout(h[2:1][-1:]) /* { dg-error "negative low bound in array section" } */
+ bar (&h[0][0]);
+ #pragma acc parallel copy(h[:1][:-3]) /* { dg-error "negative length in array section" } */
+ bar (&h[0][0]);
+ #pragma acc parallel copy(i[:1][11:]) /* { dg-error "low bound \[^\n\r]* above array section size" } */
+ bar (&i[0][0]);
+ #pragma acc parallel copyout(j[3:1][:10]) /* { dg-error "length \[^\n\r]* above array section size" } */
+ bar (&j[0][0]);
+ #pragma acc parallel copyin(j[30:1][5:5]) /* { dg-error "high bound \[^\n\r]* above array section size" } */
+ bar (&j[0][0]);
+ #pragma acc parallel copyin(a2[:1][2:4])
+ bar (&a2[0][0]);
+ #pragma acc parallel copy(a2[3:5][:])
+ bar (&a2[0][0]);
+ #pragma acc parallel copyin(a2[3:5][:10])
+ bar (&a2[0][0]);
+ #pragma acc parallel copy(b2[0:])
+ bar (b2);
+ #pragma acc parallel copy(c2[:3][:])
+ bar (&c2[0][0]);
+ #pragma acc parallel copyout(d2[9:])
+ bar (d2);
+ #pragma acc parallel copyin(e2[:10])
+ bar (e2);
+ #pragma acc parallel copyin(f2[1:9])
+ bar (f2);
+ #pragma acc parallel copy(g2[:1][2:4])
+ bar (&g2[0][0]);
+ #pragma acc parallel copyout(h2[2:2][0:])
+ bar (&h2[0][0]);
+ #pragma acc parallel copy(h2[:1][:3])
+ bar (&h2[0][0]);
+ #pragma acc parallel copyin(i2[:1][9:])
+ bar (&i2[0][0]);
+ #pragma acc parallel copyout(j2[3:4][:9])
+ bar (&j2[0][0]);
+ #pragma acc parallel copyin(j2[30:1][5:4])
+ bar (&j2[0][0]);
+ #pragma acc parallel copy(q[1:2])
+ ;
+ #pragma acc parallel copy(q[3:5][:10]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma acc parallel copy(r[3:][2:1][1:2])
+ ;
+ #pragma acc parallel copy(r[3:][2:1][1:2][:][0:4])
+ ;
+ #pragma acc parallel copy(r[3:][2:1][1:2][1:][0:4]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma acc parallel copy(r[3:][2:1][1:2][:3][0:4]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma acc parallel copy(r[3:][2:1][1:2][:][1:]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma acc parallel copy(r[3:][2:1][1:2][:][:3]) /* { dg-error "array section is not contiguous" } */
+ ;
+}
+
+static void
+instantiate ()
+{
+ &foo<0>;
+}
diff --git a/gcc/testsuite/g++.dg/goacc/data-clause-2.C b/gcc/testsuite/g++.dg/goacc/data-clause-2.C
new file mode 100644
index 0000000..57d1823
--- /dev/null
+++ b/gcc/testsuite/g++.dg/goacc/data-clause-2.C
@@ -0,0 +1,56 @@
+/* Test data clause diagnostics. */
+
+/* See also corresponding OpenACC C/C++ variant: '../../c-c++-common/goacc/data-clause-2.c'. */
+
+/* See also corresponding OpenACC 'cache' directive variant: 'cache-3-2.C'. */
+
+/* See also corresponding OpenMP variant: '../gomp/map-2.C'. */
+
+template <int N>
+void
+foo (int *p, int (*q)[10], int r[10], int s[10][10])
+{
+ int a[10], b[10][10];
+ #pragma acc parallel copy (p[-1:2])
+ ;
+ #pragma acc parallel copy (q[-1:2][0:10])
+ ;
+ #pragma acc parallel copy (q[-1:2][-2:10]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc parallel copy (r[-1:2])
+ ;
+ #pragma acc parallel copy (s[-1:2][:])
+ ;
+ #pragma acc parallel copy (s[-1:2][-2:10]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc parallel copy (a[-1:2]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc parallel copy (b[-1:2][0:]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc parallel copy (b[1:2][-2:10]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma acc parallel copy (p[2:-3]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc parallel copy (q[2:-3][:]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc parallel copy (q[2:3][0:-1]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc parallel copy (r[2:-5]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc parallel copy (s[2:-5][:]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc parallel copy (s[2:5][0:-4]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc parallel copy (a[2:-5]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc parallel copy (b[2:-5][0:10]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma acc parallel copy (b[2:5][0:-4]) /* { dg-error "negative length in array section in" } */
+ ;
+}
+
+static void
+instantiate ()
+{
+ &foo<0>;
+}
diff --git a/gcc/testsuite/g++.dg/gomp/map-1.C b/gcc/testsuite/g++.dg/gomp/map-1.C
new file mode 100644
index 0000000..27dc7a5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/map-1.C
@@ -0,0 +1,119 @@
+/* Test 'map' clause diagnostics. */
+
+/* See also corresponding OpenMP C/C++ variant: '../../c-c++-common/gomp/map-1.c'. */
+
+/* See also corresponding OpenACC variant: '../goacc/data-clause-1.C'. */
+
+extern int a[][10], a2[][10];
+int b[10], c[10][2], d[10], e[10], f[10];
+int b2[10], c2[10][2], d2[10], e2[10], f2[10];
+int k[10], l[10], m[10], n[10], o;
+int *p;
+int **q;
+int r[4][4][4][4][4];
+extern struct s s1;
+extern struct s s2[1]; /* { dg-error "array type has incomplete element type" "" { target c } } */
+int t[10];
+#pragma omp threadprivate (t)
+#pragma omp declare target
+void bar (int *);
+#pragma omp end declare target
+
+template <int N>
+void
+foo (int g[3][10], int h[4][8], int i[2][10], int j[][9],
+ int g2[3][10], int h2[4][8], int i2[2][10], int j2[][9])
+{
+ #pragma omp target map(to: bar[2:5]) /* { dg-error "is not a variable" } */
+ ;
+ #pragma omp target map(from: t[2:5]) /* { dg-error "is threadprivate variable" } */
+ ;
+ #pragma omp target map(tofrom: k[0.5:]) /* { dg-error "low bound \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma omp target map(from: l[:7.5f]) /* { dg-error "length \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma omp target map(to: m[p:]) /* { dg-error "low bound \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma omp target map(tofrom: n[:p]) /* { dg-error "length \[^\n\r]* of array section does not have integral type" } */
+ ;
+ #pragma omp target map(to: o[2:5]) /* { dg-error "does not have pointer or array type" } */
+ ;
+ #pragma omp target map(alloc: s1) /* { dg-error "'s1' does not have a mappable type in 'map' clause" } */
+ ;
+ #pragma omp target map(alloc: s2) /* { dg-error "'s2' does not have a mappable type in 'map' clause" } */
+ ;
+ #pragma omp target map(to: a[:][:]) /* { dg-error "array type length expression must be specified" } */
+ bar (&a[0][0]); /* { dg-error "referenced in target region does not have a mappable type" "PR97996" { xfail *-*-* } } */
+ #pragma omp target map(tofrom: b[-1:]) /* { dg-error "negative low bound in array section" } */
+ bar (b);
+ #pragma omp target map(tofrom: c[:-3][:]) /* { dg-error "negative length in array section" } */
+ bar (&c[0][0]);
+ #pragma omp target map(from: d[11:]) /* { dg-error "low bound \[^\n\r]* above array section size" } */
+ bar (d);
+ #pragma omp target map(to: e[:11]) /* { dg-error "length \[^\n\r]* above array section size" } */
+ bar (e);
+ #pragma omp target map(to: f[1:10]) /* { dg-error "high bound \[^\n\r]* above array section size" } */
+ bar (f);
+ #pragma omp target map(from: g[:][0:10]) /* { dg-error "for array function parameter length expression must be specified" } */
+ bar (&g[0][0]);
+ #pragma omp target map(from: h[2:1][-1:]) /* { dg-error "negative low bound in array section" } */
+ bar (&h[0][0]);
+ #pragma omp target map(tofrom: h[:1][:-3]) /* { dg-error "negative length in array section" } */
+ bar (&h[0][0]);
+ #pragma omp target map(i[:1][11:]) /* { dg-error "low bound \[^\n\r]* above array section size" } */
+ bar (&i[0][0]);
+ #pragma omp target map(from: j[3:1][:10]) /* { dg-error "length \[^\n\r]* above array section size" } */
+ bar (&j[0][0]);
+ #pragma omp target map(to: j[30:1][5:5]) /* { dg-error "high bound \[^\n\r]* above array section size" } */
+ bar (&j[0][0]);
+ #pragma omp target map(to: a2[:1][2:4])
+ bar (&a2[0][0]);
+ #pragma omp target map(a2[3:5][:])
+ bar (&a2[0][0]);
+ #pragma omp target map(to: a2[3:5][:10])
+ bar (&a2[0][0]);
+ #pragma omp target map(tofrom: b2[0:])
+ bar (b2);
+ #pragma omp target map(tofrom: c2[:3][:])
+ bar (&c2[0][0]);
+ #pragma omp target map(from: d2[9:])
+ bar (d2);
+ #pragma omp target map(to: e2[:10])
+ bar (e2);
+ #pragma omp target map(to: f2[1:9])
+ bar (f2);
+ #pragma omp target map(g2[:1][2:4])
+ bar (&g2[0][0]);
+ #pragma omp target map(from: h2[2:2][0:])
+ bar (&h2[0][0]);
+ #pragma omp target map(tofrom: h2[:1][:3])
+ bar (&h2[0][0]);
+ #pragma omp target map(to: i2[:1][9:])
+ bar (&i2[0][0]);
+ #pragma omp target map(from: j2[3:4][:9])
+ bar (&j2[0][0]);
+ #pragma omp target map(to: j2[30:1][5:4])
+ bar (&j2[0][0]);
+ #pragma omp target map(q[1:2])
+ ;
+ #pragma omp target map(tofrom: q[3:5][:10]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma omp target map(r[3:][2:1][1:2])
+ ;
+ #pragma omp target map(r[3:][2:1][1:2][:][0:4])
+ ;
+ #pragma omp target map(r[3:][2:1][1:2][1:][0:4]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma omp target map(r[3:][2:1][1:2][:3][0:4]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma omp target map(r[3:][2:1][1:2][:][1:]) /* { dg-error "array section is not contiguous" } */
+ ;
+ #pragma omp target map(r[3:][2:1][1:2][:][:3]) /* { dg-error "array section is not contiguous" } */
+ ;
+}
+
+static void
+instantiate ()
+{
+ &foo<0>;
+}
diff --git a/gcc/testsuite/g++.dg/gomp/map-2.C b/gcc/testsuite/g++.dg/gomp/map-2.C
new file mode 100644
index 0000000..bbe2606
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/map-2.C
@@ -0,0 +1,54 @@
+/* Test 'map' clause diagnostics. */
+
+/* See also corresponding OpenMP C/C++ variant: '../../c-c++-common/gomp/map-2.c'. */
+
+/* See also corresponding OpenACC variant: '../goacc/data-clause-2.C'. */
+
+template <int N>
+void
+foo (int *p, int (*q)[10], int r[10], int s[10][10])
+{
+ int a[10], b[10][10];
+ #pragma omp target map (tofrom: p[-1:2])
+ ;
+ #pragma omp target map (tofrom: q[-1:2][0:10])
+ ;
+ #pragma omp target map (tofrom: q[-1:2][-2:10]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma omp target map (tofrom: r[-1:2])
+ ;
+ #pragma omp target map (tofrom: s[-1:2][:])
+ ;
+ #pragma omp target map (tofrom: s[-1:2][-2:10]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma omp target map (tofrom: a[-1:2]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma omp target map (tofrom: b[-1:2][0:]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma omp target map (tofrom: b[1:2][-2:10]) /* { dg-error "negative low bound in array section in" } */
+ ;
+ #pragma omp target map (tofrom: p[2:-3]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma omp target map (tofrom: q[2:-3][:]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma omp target map (tofrom: q[2:3][0:-1]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma omp target map (tofrom: r[2:-5]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma omp target map (tofrom: s[2:-5][:]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma omp target map (tofrom: s[2:5][0:-4]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma omp target map (tofrom: a[2:-5]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma omp target map (tofrom: b[2:-5][0:10]) /* { dg-error "negative length in array section in" } */
+ ;
+ #pragma omp target map (tofrom: b[2:5][0:-4]) /* { dg-error "negative length in array section in" } */
+ ;
+}
+
+static void
+instantiate ()
+{
+ &foo<0>;
+}
diff --git a/gcc/testsuite/g++.dg/gomp/tls-5.C b/gcc/testsuite/g++.dg/gomp/tls-5.C
index e83ff11..b18a127 100644
--- a/gcc/testsuite/g++.dg/gomp/tls-5.C
+++ b/gcc/testsuite/g++.dg/gomp/tls-5.C
@@ -1,6 +1,8 @@
// The reference temp should be TLS, not normal data.
// { dg-require-effective-target c++11 }
// { dg-final { scan-assembler-not "\\.data" { target tls_native xfail powerpc-*-aix* } } }
+// { dg-final { scan-assembler-symbol-section {^_?ir$} {^\.tbss|\[TL\]} } }
+// { dg-final { scan-assembler-symbol-section {^_?_ZGR2ir_$} {^\.tdata|\[TL\]} } }
extern int&& ir;
#pragma omp threadprivate (ir)
diff --git a/gcc/testsuite/g++.dg/guality/redeclaration1.C b/gcc/testsuite/g++.dg/guality/redeclaration1.C
index 93b0750..bd0209f 100644
--- a/gcc/testsuite/g++.dg/guality/redeclaration1.C
+++ b/gcc/testsuite/g++.dg/guality/redeclaration1.C
@@ -3,6 +3,7 @@
// { dg-skip-if "" { *-*-* } { "-flto" } { "" } }
volatile int l;
+int *volatile p;
namespace S
{
@@ -11,10 +12,11 @@ namespace S
f()
{
int i = 42;
- l = i; // { dg-final { gdb-test 14 "i" "42" } }
+ l = i; // { dg-final { gdb-test 15 "i" "42" } }
{
extern int i;
- l = i; // { dg-final { gdb-test 17 "i" "24" } }
+ p[0]++;
+ l = i; // { dg-final { gdb-test 19 "i" "24" } }
}
}
}
@@ -22,6 +24,8 @@ namespace S
int
main (void)
{
+ int x = 0;
+ p = &x;
S::f ();
return 0;
}
diff --git a/gcc/testsuite/g++.dg/hwasan/hwasan.exp b/gcc/testsuite/g++.dg/hwasan/hwasan.exp
new file mode 100644
index 0000000..559cf06
--- /dev/null
+++ b/gcc/testsuite/g++.dg/hwasan/hwasan.exp
@@ -0,0 +1,34 @@
+# Copyright (C) 2012-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/>.
+
+# Load support procs.
+load_lib g++-dg.exp
+load_lib hwasan-dg.exp
+
+# Initialize `dg'.
+dg-init
+hwasan_init
+
+# Main loop.
+if [check_effective_target_fsanitize_hwaddress] {
+ gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C $srcdir/c-c++-common/hwasan/*.c]] "" ""
+}
+
+# All done.
+hwasan_finish
+dg-finish
diff --git a/gcc/testsuite/g++.dg/hwasan/rvo-handled.C b/gcc/testsuite/g++.dg/hwasan/rvo-handled.C
new file mode 100644
index 0000000..0e30ff0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/hwasan/rvo-handled.C
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+
+#define assert(x) if (!(x)) __builtin_abort ()
+typedef __UINTPTR_TYPE__ uintptr_t;
+void *untagged (void *ptr)
+{
+ /* Untag by removing the top byte. */
+ return (void*)((uintptr_t)ptr & 0xffffffffffffff);
+}
+
+struct big_struct {
+ int left;
+ int right;
+ void *ptr;
+ int big_array[100];
+};
+
+/*
+ Tests for RVO (basically, checking -fsanitize=hwaddress has not broken RVO
+ in any way).
+
+ 0) The value is accessible in both functions without a hwasan complaint.
+ 1) RVO does happen.
+ */
+
+struct big_struct __attribute__ ((noinline))
+return_on_stack()
+{
+ struct big_struct x;
+ x.left = 100;
+ x.right = 20;
+ x.big_array[10] = 30;
+ x.ptr = untagged(&x);
+ return x;
+}
+
+int main()
+{
+ struct big_struct x;
+ x = return_on_stack();
+ /* Check that RVO happens by checking the address that the callee saw. */
+ assert (x.ptr == untagged(&x));
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/inherit/using5.C b/gcc/testsuite/g++.dg/inherit/using5.C
index b8e5107..514cd8d 100644
--- a/gcc/testsuite/g++.dg/inherit/using5.C
+++ b/gcc/testsuite/g++.dg/inherit/using5.C
@@ -6,7 +6,7 @@
template<int> struct A
{
- A::A; // { dg-error "constructor|not a base" }
+ A::A; // { dg-error "constructor|not a direct base" }
};
struct B
diff --git a/gcc/testsuite/g++.dg/ipa/pr98057.C b/gcc/testsuite/g++.dg/ipa/pr98057.C
new file mode 100644
index 0000000..9de9254
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr98057.C
@@ -0,0 +1,18 @@
+/* PR ipa/98057 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -ffunction-sections" } */
+
+class JITSymbolResolver {
+ virtual void anchor();
+};
+class MemoryManager {
+ virtual void anchor();
+};
+class MCJITMemoryManager : MemoryManager {
+ void anchor();
+};
+class RTDyldMemoryManager : MCJITMemoryManager, JITSymbolResolver {
+ void anchor();
+};
+void RTDyldMemoryManager::anchor() {}
+void MCJITMemoryManager::anchor() {}
diff --git a/gcc/testsuite/g++.dg/ipa/pr98075.C b/gcc/testsuite/g++.dg/ipa/pr98075.C
new file mode 100644
index 0000000..0c4219d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr98075.C
@@ -0,0 +1,30 @@
+/* PR ipa/98075 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-inline" } */
+
+template <typename BS>
+class xg {
+public:
+ BS *
+ fw ()
+ {
+ return static_cast<BS *> (operator new (sizeof (BS)));
+ }
+};
+
+class zp : xg<int> {
+public:
+ __attribute__ ((always_inline)) zp ()
+ {
+ hy = xg<int>::fw ();
+ }
+
+private:
+ int *hy;
+};
+
+void
+e5 ()
+{
+ zp ix;
+}
diff --git a/gcc/testsuite/g++.dg/lookup/pr97877.C b/gcc/testsuite/g++.dg/lookup/pr97877.C
new file mode 100644
index 0000000..294edd2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/pr97877.C
@@ -0,0 +1,8 @@
+// PR 97877, duplicate decls smashed decl_lang_specific
+
+void f ()
+{
+ extern int a;
+ extern int a;
+ a = 2;
+}
diff --git a/gcc/testsuite/g++.dg/lookup/pr97905.C b/gcc/testsuite/g++.dg/lookup/pr97905.C
new file mode 100644
index 0000000..22a7e5c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/pr97905.C
@@ -0,0 +1,7 @@
+// PR 97905
+
+
+template <typename> void a() {
+ extern int *b; // This decl gets an (unneeded) decl-lang-specific
+}
+int *b; // this does not
diff --git a/gcc/testsuite/g++.dg/opt/const4.C b/gcc/testsuite/g++.dg/opt/const4.C
index 883c24b..75ee0e6 100644
--- a/gcc/testsuite/g++.dg/opt/const4.C
+++ b/gcc/testsuite/g++.dg/opt/const4.C
@@ -3,7 +3,8 @@
// that have it.
// { dg-do compile }
-const int a[] __attribute__ ((__used__)) = { 0, 1, 2, 3 };
+// { dg-final { scan-assembler-symbol-section {constant_variable} {^\.(const|rodata)|\[RO\]} } }
+const int constant_variable[] __attribute__ ((__used__)) = { 0, 1, 2, 3 };
// The MMIX port always switches to the .data section at the end of a file.
// { dg-final { scan-assembler-not "\\.data(?!\\.rel\\.ro)" { xfail powerpc*-*-aix* mmix-*-* } } }
diff --git a/gcc/testsuite/g++.dg/other/abstract1.C b/gcc/testsuite/g++.dg/other/abstract1.C
index 53d767a..6ded7ec 100644
--- a/gcc/testsuite/g++.dg/other/abstract1.C
+++ b/gcc/testsuite/g++.dg/other/abstract1.C
@@ -5,34 +5,38 @@
// c++/9256: Make sure that a pointer to an array of abstract elements
// cannot be created, not even during template substitution (DR337).
+// Changed massively by P0929R2: now only creating an object of the array type
+// is ill-formed, not merely forming the array type.
+
struct Abstract { virtual void f() = 0; }; // { dg-message "note" }
struct Complete { void f(); };
/*
* TEST 1
- * Arrays of abstract elements cannot be declared.
+ * Arrays of abstract elements cannot be defined.
*/
Abstract a0[2]; // { dg-error "" }
-Abstract (*a1)[2]; // { dg-error "" }
-Abstract (**a2)[2]; // { dg-error "" }
-Abstract (***a3)[2]; // { dg-error "" }
+Abstract (*a1)[2];
+Abstract (**a2)[2];
+Abstract (***a3)[2];
Abstract *a4;
Abstract *a5[2];
-Abstract (*a6[2])[2]; // { dg-error "" }
+Abstract (*a6[2])[2];
Abstract **a7[2];
-Abstract *(*a8[2])[2];
-Abstract (**a9[2])[2]; // { dg-error "" }
+Abstract *(*a8[2])[2];
+Abstract (**a9[2])[2];
/*
* TEST 2
- * If a pointer to an array of abstract elements is created during template
+ * If an array of abstract elements is created during template
* instantiation, an error should occur.
*/
template <class T> struct K {
- T (*a)[2]; // { dg-error "abstract class type" }
+ T (*a1)[2];
+ T (a2)[2]; // { dg-error "abstract" }
};
template struct K<Abstract>; // { dg-message "required" }
@@ -41,8 +45,9 @@ template struct K<Abstract>; // { dg-message "required" }
/*
* TEST 3
- * Deducing an array of abstract elements during type deduction is a silent
- * failure (rejects overload).
+
+ * Deducing an array of abstract elements during type deduction is no longer a
+ * silent failure.
*/
template <bool> struct StaticAssert;
@@ -54,6 +59,6 @@ typedef struct { char x[2]; } No;
template<typename U> No is_abstract(U (*k)[1]);
template<typename U> Yes is_abstract(...);
-StaticAssert<sizeof(is_abstract<Abstract>(0)) == sizeof(Yes)> b1;
+StaticAssert<sizeof(is_abstract<Abstract>(0)) == sizeof(No)> b1;
StaticAssert<sizeof(is_abstract<Complete>(0)) == sizeof(No)> b2;
StaticAssert<sizeof(is_abstract<int>(0)) == sizeof(No)> b3;
diff --git a/gcc/testsuite/g++.dg/other/abstract2.C b/gcc/testsuite/g++.dg/other/abstract2.C
index 60a4e41..0a8009e 100644
--- a/gcc/testsuite/g++.dg/other/abstract2.C
+++ b/gcc/testsuite/g++.dg/other/abstract2.C
@@ -5,54 +5,59 @@
namespace N1 {
struct X;
- struct Y1 {
- void g(X parm1); // { dg-error "abstract" }
- void g(X parm2[2]); // { dg-error "abstract" }
- void g(X (*parm3)[2]); // { dg-error "abstract" }
+ struct X { // { dg-message "note" }
+ virtual void xfunc(void) = 0; // { dg-message "note" }
};
+ struct Y1 {
+ void g(X parm1) {} // { dg-error "abstract" }
+ void g(X parm2[2]) {}
+ void g(X (*parm3)[2]) {}
+ };
template <int N>
struct Y2 {
- void g(X parm4); // { dg-error "abstract" }
- void g(X parm5[2]); // { dg-error "abstract" }
- void g(X (*parm6)[2]); // { dg-error "abstract" }
+ void g(X parm4) {} // { dg-error "abstract" }
+ void g(X parm5[2]) {}
+ void g(X (*parm6)[2]) {}
};
- struct X { // { dg-message "note" }
- virtual void xfunc(void) = 0; // { dg-message "note" }
- };
+ template struct Y2<42>;
}
namespace N2 {
struct X1 { // { dg-message "note" }
virtual void xfunc(void) = 0; // { dg-message "note" }
- void g(X1 parm7); // { dg-error "abstract" }
- void g(X1 parm8[2]); // { dg-error "abstract" }
- void g(X1 (*parm9)[2]); // { dg-error "abstract" }
+ void g(X1 parm7) {} // { dg-error "abstract" }
+ void g(X1 parm8[2]) {}
+ void g(X1 (*parm9)[2]) {}
};
template <int N>
struct X2 { // { dg-message "note" }
virtual void xfunc(void) = 0; // { dg-message "note" }
- void g(X2 parm10); // { dg-error "abstract" }
- void g(X2 parm11[2]); // { dg-error "abstract" }
- void g(X2 (*parm12)[2]); // { dg-error "abstract" }
+ void g(X2 parm10) {} // { dg-error "abstract" }
+ void g(X2 parm11[2]) {}
+ void g(X2 (*parm12)[2]) {}
};
+
+ template struct X2<42>;
}
namespace N3 {
struct X { // { dg-message "note" }
virtual void xfunc(void) = 0; // { dg-message "note" }
};
- void g(X parm13); // { dg-error "abstract" }
- void g(X parm14[2]); // { dg-error "abstract" }
- void g(X (*parm15)[2]); // { dg-error "abstract" }
-
- template <int N>
- void g(X parm16); // { dg-error "abstract" }
- template <int N>
- void g(X parm17[2]); // { dg-error "abstract" }
- template <int N>
- void g(X (*parm18)[2]); // { dg-error "abstract" }
+ void g(X parm13) {} // { dg-error "abstract" }
+ void g(X parm14[2]) {}
+ void g(X (*parm15)[2]) {}
+
+ template <int N>
+ void g(X parm16) {} // { dg-error "abstract" }
+ template <int N>
+ void g(X parm17[2]) {}
+ template <int N>
+ void g(X (*parm18)[2]) {}
+
+ template void g<42>(X);
}
diff --git a/gcc/testsuite/g++.dg/other/abstract4.C b/gcc/testsuite/g++.dg/other/abstract4.C
index 68b2eb2..6a8c8c7 100644
--- a/gcc/testsuite/g++.dg/other/abstract4.C
+++ b/gcc/testsuite/g++.dg/other/abstract4.C
@@ -13,6 +13,6 @@ struct Abs
int main()
{
- S<Abs(int)> s; // { dg-error "abstract" }
- foo<Abs(int)>(); // { dg-error "abstract" }
+ S<Abs(int)> s;
+ foo<Abs(int)>();
}
diff --git a/gcc/testsuite/g++.dg/other/abstract5.C b/gcc/testsuite/g++.dg/other/abstract5.C
index d13dd9e..c17d60d 100644
--- a/gcc/testsuite/g++.dg/other/abstract5.C
+++ b/gcc/testsuite/g++.dg/other/abstract5.C
@@ -3,4 +3,4 @@ struct A
virtual void f() = 0;
};
-typedef A (*fp)(); // { dg-error "abstract" }
+typedef A (*fp)();
diff --git a/gcc/testsuite/g++.dg/other/abstract8.C b/gcc/testsuite/g++.dg/other/abstract8.C
new file mode 100644
index 0000000..bc5afbb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/abstract8.C
@@ -0,0 +1,40 @@
+// P0929R2: Checking for abstract class types.
+// { dg-do compile { target c++11 } }
+// { dg-additional-options -Wno-return-type }
+
+struct A
+{
+ virtual void f() = 0;
+};
+
+struct B
+{
+ A a; // { dg-error "abstract" }
+ A ar[4]; // { dg-error "abstract" }
+};
+
+using Aa = A[4]; // OK
+Aa* aap; // OK
+
+extern A a; // OK
+extern Aa aa; // OK
+A f(); // OK
+void g(A); // OK
+
+A a; // { dg-error "abstract" }
+Aa aa; // { dg-error "abstract" }
+A f() { } // { dg-error "abstract" }
+void g(A) { } // { dg-error "abstract" }
+
+int main()
+{
+ (A(a)); // { dg-error "abstract" }
+ A{}; // { dg-error "abstract" }
+ static_cast<A>(a); // { dg-error "abstract" }
+ Aa{}; // { dg-error "abstract" }
+ f(); // { dg-error "abstract" }
+ decltype(f())* p; // OK
+ g(a); // { dg-error "abstract" }
+
+ throw a; // { dg-error "abstract" }
+}
diff --git a/gcc/testsuite/g++.dg/other/i386-2.C b/gcc/testsuite/g++.dg/other/i386-2.C
index b964248..62b2132 100644
--- a/gcc/testsuite/g++.dg/other/i386-2.C
+++ b/gcc/testsuite/g++.dg/other/i386-2.C
@@ -1,5 +1,5 @@
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
-/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl" } */
+/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni" } */
/* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h,
xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h,
diff --git a/gcc/testsuite/g++.dg/other/i386-3.C b/gcc/testsuite/g++.dg/other/i386-3.C
index 2f73de2..843aa2b 100644
--- a/gcc/testsuite/g++.dg/other/i386-3.C
+++ b/gcc/testsuite/g++.dg/other/i386-3.C
@@ -1,5 +1,5 @@
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
-/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl" } */
+/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni" } */
/* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h,
xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h,
diff --git a/gcc/testsuite/g++.dg/other/pr88187.C b/gcc/testsuite/g++.dg/other/pr88187.C
index ebdafdd..13466d3 100644
--- a/gcc/testsuite/g++.dg/other/pr88187.C
+++ b/gcc/testsuite/g++.dg/other/pr88187.C
@@ -4,4 +4,4 @@
template <int> struct A;
void f (A ()); // { dg-error "6:variable or field 'f' declared void" "" { target c++14_down } }
// { dg-error "missing template arguments before '\\(' token" "" { target c++14_down } .-1 }
- // { dg-error "'auto' parameter not permitted in this context" "" { target c++17 } .-2 }
+ // { dg-error "placeholder .A. not permitted in this context" "" { target c++17 } .-2 }
diff --git a/gcc/testsuite/g++.dg/parse/defarg17.C b/gcc/testsuite/g++.dg/parse/defarg17.C
new file mode 100644
index 0000000..c39a819
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/defarg17.C
@@ -0,0 +1,11 @@
+typedef int I;
+
+int f(float I = 0.0, int b = I(2)); // { dg-error "parameter" }
+int g(int b = I(2), float I = 0.0);
+
+struct A
+{
+ int f(float I = 0.0, int b = I(2)); // { dg-error "parameter" }
+ int g(int b = I(2), float I = 0.0);
+};
+
diff --git a/gcc/testsuite/g++.dg/pr93195a.C b/gcc/testsuite/g++.dg/pr93195a.C
new file mode 100644
index 0000000..26d265d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr93195a.C
@@ -0,0 +1,27 @@
+/* { dg-do link { target { ! { nvptx*-*-* visium-*-* } } } } */
+// { dg-require-effective-target o_flag_in_section }
+/* { dg-options "-O0 -fpatchable-function-entry=1" } */
+/* { dg-additional-options "-fno-pie" { target sparc*-*-* } } */
+/* { dg-additional-sources pr93195b.C } */
+
+extern void bar1 (void);
+
+inline void
+foo (void)
+{
+}
+
+void
+bar (void)
+{
+ foo ();
+ bar1 ();
+}
+
+int
+main ()
+{
+ bar ();
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/pr93195b.C b/gcc/testsuite/g++.dg/pr93195b.C
new file mode 100644
index 0000000..303d858
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr93195b.C
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { ! { nvptx*-*-* visium-*-* } } } } */
+/* { dg-options "-O0 -fpatchable-function-entry=1" } */
+/* { dg-additional-options "-fno-pie" { target sparc*-*-* } } */
+
+inline void
+foo (void)
+{
+}
+
+void
+bar1 (void)
+{
+ foo ();
+}
diff --git a/gcc/testsuite/g++.dg/template/crash132.C b/gcc/testsuite/g++.dg/template/crash132.C
new file mode 100644
index 0000000..f6f4863
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/crash132.C
@@ -0,0 +1,6 @@
+// PR c++/97993
+// { dg-do compile { target c++14 } }
+
+template <class T> T a;
+template <class T, class A, class=decltype(::new T (A()))> auto foo ();
+struct S decltype (foo <int, S>); // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/template/pr98115.C b/gcc/testsuite/g++.dg/template/pr98115.C
new file mode 100644
index 0000000..0bfc57a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/pr98115.C
@@ -0,0 +1,4 @@
+// PR 98115, dependent array types lead to specialization issues
+
+template <class> class Stringify;
+template <long N> class Stringify<const char[N]>;
diff --git a/gcc/testsuite/g++.dg/template/pr98116.C b/gcc/testsuite/g++.dg/template/pr98116.C
new file mode 100644
index 0000000..d3398d2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/pr98116.C
@@ -0,0 +1,29 @@
+// PR 98116, ICE with stripping typedef array type
+// { dg-do compile { target c++11 } }
+namespace std {
+struct is_convertible;
+template <typename _Tp> using remove_pointer_t = typename _Tp ::type;
+template <bool> struct enable_if;
+template <typename> void declval();
+template <bool _Cond> using enable_if_t = typename enable_if<_Cond>::type;
+template <typename, typename> class Trans_NS___cxx11_basic_string {
+ long _M_string_length;
+};
+} // namespace std
+struct string16_char_traits;
+template class std::Trans_NS___cxx11_basic_string<unsigned short,
+ string16_char_traits>;
+template <typename, typename> using IsLegalDataConversion = std::is_convertible;
+template <typename Container, typename T>
+using ContainerHasConvertibleData = IsLegalDataConversion<
+ std::remove_pointer_t<decltype(std::declval<Container>)>, T>;
+template <typename Array, typename T, long>
+using EnableIfSpanCompatibleArray =
+ std::enable_if_t<ContainerHasConvertibleData<Array, T>::value>;
+template <int Extent> class span {
+ template <long N, EnableIfSpanCompatibleArray<
+ const std::Trans_NS___cxx11_basic_string<
+ unsigned short, string16_char_traits>[N],
+ std::Trans_NS___cxx11_basic_string<short, int>, Extent>>
+ span();
+};
diff --git a/gcc/testsuite/g++.dg/template/sfinae-dr657.C b/gcc/testsuite/g++.dg/template/sfinae-dr657.C
index b78b5a9..36c11e6 100644
--- a/gcc/testsuite/g++.dg/template/sfinae-dr657.C
+++ b/gcc/testsuite/g++.dg/template/sfinae-dr657.C
@@ -1,6 +1,7 @@
-// DR 657
-// Test that a return or parameter type with abstract class type causes a
-// deduction failure.
+// DR 657 SUPERSEDED BY DR 1646
+// Test that a return or parameter type with abstract class type DOES NOT cause
+// a deduction failure, but there is no implicit conversion sequence for
+// a parameter of abstract class type.
struct A
{
@@ -17,6 +18,6 @@ template<class T> int arg(...);
int main()
{
- int i = declval<A>();
+ int i = declval<A>(); // { dg-error "ambiguous" }
i = arg<A>(1);
}
diff --git a/gcc/testsuite/g++.dg/torture/builtin-clear-padding-1.C b/gcc/testsuite/g++.dg/torture/builtin-clear-padding-1.C
new file mode 100644
index 0000000..625a047
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/builtin-clear-padding-1.C
@@ -0,0 +1,31 @@
+/* PR libstdc++/88101 */
+
+struct S {} s1, s2;
+struct T : public S { char a; short b; char c; } t1, t2;
+struct U : public T { char d; long long e; char f; } u1, u2;
+
+__attribute__((noipa)) void
+foo (T *t, U *u)
+{
+ int i;
+ t->a = -1; t->b = -1; t->c = -1;
+ u->a = -1; u->b = -1; u->c = -1; u->d = -1; u->e = -1; u->f = -1;
+}
+
+int
+main ()
+{
+ __builtin_memset (&s2, -1, sizeof (s2));
+ __builtin_memset (&t2, -1, sizeof (t2));
+ __builtin_memset (&u2, -1, sizeof (u2));
+ foo (&t1, &u1);
+ foo (&t2, &u2);
+ __builtin_clear_padding (&s2);
+ __builtin_clear_padding (&t2);
+ __builtin_clear_padding (&u2);
+ if (__builtin_memcmp (&s1, &s2, sizeof (s1))
+ || __builtin_memcmp (&t1, &t2, sizeof (t1))
+ || __builtin_memcmp (&u1, &u2, sizeof (u1)))
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/builtin-clear-padding-2.C b/gcc/testsuite/g++.dg/torture/builtin-clear-padding-2.C
new file mode 100644
index 0000000..19cc78f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/builtin-clear-padding-2.C
@@ -0,0 +1,34 @@
+/* PR libstdc++/88101 */
+
+#include <new>
+
+struct S { char a; short b; char c; long long d; char e; decltype (nullptr) f; char g; };
+alignas (S) unsigned char buf1[sizeof (S)];
+alignas (S) unsigned char buf2[sizeof (S)];
+
+template <int N>
+void
+foo ()
+{
+ __builtin_clear_padding ((S *) buf2);
+}
+
+void
+bar (S *s)
+{
+ s->a = -1; s->b = -1; s->c = -1; s->d = -1; s->e = -1; s->g = -1;
+}
+
+int
+main ()
+{
+ S *s1 = new (buf1) S;
+ S *s2 = new (buf2) S;
+ __builtin_memset (s1, 0, sizeof (S));
+ __builtin_memset (s2, ~0, sizeof (S));
+ bar (s1);
+ bar (s2);
+ foo <0> ();
+ if (__builtin_memcmp (s1, s2, sizeof (S)) != 0)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/torture/builtin-clear-padding-3.C b/gcc/testsuite/g++.dg/torture/builtin-clear-padding-3.C
new file mode 100644
index 0000000..d528196
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/builtin-clear-padding-3.C
@@ -0,0 +1,24 @@
+/* PR libstdc++/88101 */
+
+struct D { int a; int : 24; int b : 8; };
+struct E {};
+struct F { char c, d, e; };
+struct G : public D, E, F { int f; } g1, g2;
+
+__attribute__((noipa)) void
+foo (G *g)
+{
+ g->a = -1; g->b = -1; g->c = -1; g->d = -1; g->e = -1; g->f = -1;
+}
+
+int
+main ()
+{
+ __builtin_memset (&g2, -1, sizeof (g2));
+ foo (&g1);
+ foo (&g2);
+ __builtin_clear_padding (&g2);
+ if (__builtin_memcmp (&g1, &g2, sizeof (g1)))
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr93347.C b/gcc/testsuite/g++.dg/torture/pr93347.C
index 3b5cc26..6e3b1af 100644
--- a/gcc/testsuite/g++.dg/torture/pr93347.C
+++ b/gcc/testsuite/g++.dg/torture/pr93347.C
@@ -1,306 +1,20 @@
// { dg-additional-options "--param early-inlining-insns=3 --param ipa-cp-eval-threshold=100" }
-namespace Test1 {
- struct A {
- virtual int f() final;
- };
- // CHECK-LABEL: define i32 @_ZN5Test11fEPNS_1AE
- int f(A *a) {
- // CHECK: call i32 @_ZN5Test11A1fEv
- return a->f();
- }
-}
-
-namespace Test2 {
- struct A final {
- virtual int f();
- };
-
- // CHECK-LABEL: define i32 @_ZN5Test21fEPNS_1AE
- int f(A *a) {
- // CHECK: call i32 @_ZN5Test21A1fEv
- return a->f();
- }
-}
-
-namespace Test2a {
- struct A {
- virtual ~A() final {}
- virtual int f();
- };
-
- // CHECK-LABEL: define i32 @_ZN6Test2a1fEPNS_1AE
- int f(A *a) {
- // CHECK: call i32 @_ZN6Test2a1A1fEv
- return a->f();
- }
-}
-
-
-namespace Test3 {
- struct A {
- virtual int f(); };
-
- struct B final : A { };
-
- // CHECK-LABEL: define i32 @_ZN5Test31fEPNS_1BE
- int f(B *b) {
- // CHECK: call i32 @_ZN5Test31A1fEv
- return b->f();
- }
-
- // CHECK-LABEL: define i32 @_ZN5Test31fERNS_1BE
- int f(B &b) {
- // CHECK: call i32 @_ZN5Test31A1fEv
- return b.f();
- }
-
- // CHECK-LABEL: define i32 @_ZN5Test31fEPv
- int f(void *v) {
- // CHECK: call i32 @_ZN5Test31A1fEv
- return static_cast<B*>(v)->f();
- }
-}
-
-namespace Test4 {
- struct A {
- virtual void f();
- virtual int operator-();
- };
-
- struct B final : A {
- virtual void f();
- virtual int operator-();
- };
-
- // CHECK-LABEL: define void @_ZN5Test41fEPNS_1BE
- void f(B* d) {
- // CHECK: call void @_ZN5Test41B1fEv
- static_cast<A*>(d)->f();
- // CHECK: call i32 @_ZN5Test41BngEv
- -static_cast<A&>(*d);
- }
-}
-
-namespace Test5 {
- struct A {
- virtual void f();
- virtual int operator-();
- };
-
- struct B : A {
- virtual void f();
- virtual int operator-();
- };
-
- struct C final : B {
- };
-
- // CHECK-LABEL: define void @_ZN5Test51fEPNS_1CE
- void f(C* d) {
- // FIXME: It should be possible to devirtualize this case, but that is
- // not implemented yet.
- // CHECK: getelementptr
- // CHECK-NEXT: %[[FUNC:.*]] = load
- // CHECK-NEXT: call void %[[FUNC]]
- static_cast<A*>(d)->f();
- }
- // CHECK-LABEL: define void @_ZN5Test53fopEPNS_1CE
- void fop(C* d) {
- // FIXME: It should be possible to devirtualize this case, but that is
- // not implemented yet.
- // CHECK: getelementptr
- // CHECK-NEXT: %[[FUNC:.*]] = load
- // CHECK-NEXT: call i32 %[[FUNC]]
- -static_cast<A&>(*d);
- }
-}
-
-namespace Test6 {
- struct A {
- virtual ~A();
- };
-
- struct B : public A {
- virtual ~B();
- };
-
- struct C {
- virtual ~C();
- };
-
- struct D final : public C, public B {
- };
-
- // CHECK-LABEL: define void @_ZN5Test61fEPNS_1DE
- void f(D* d) {
- // CHECK: call void @_ZN5Test61DD1Ev
- static_cast<A*>(d)->~A();
- }
-}
-
-namespace Test7 {
- struct foo {
- virtual void g() {}
- };
-
- struct bar {
- virtual int f() { return 0; }
- };
-
- struct zed final : public foo, public bar {
- int z;
- virtual int f() {return z;}
- };
-
- // CHECK-LABEL: define i32 @_ZN5Test71fEPNS_3zedE
- int f(zed *z) {
- // CHECK: alloca
- // CHECK-NEXT: store
- // CHECK-NEXT: load
- // CHECK-NEXT: call i32 @_ZN5Test73zed1fEv
- // CHECK-NEXT: ret
- return static_cast<bar*>(z)->f();
- }
-}
-
-namespace Test8 {
- struct A { virtual ~A() {} };
- struct B {
- int b;
- virtual int foo() { return b; }
- };
- struct C final : A, B { };
- // CHECK-LABEL: define i32 @_ZN5Test84testEPNS_1CE
- int test(C *c) {
- // CHECK: %[[THIS:.*]] = phi
- // CHECK-NEXT: call i32 @_ZN5Test81B3fooEv(%"struct.Test8::B"* %[[THIS]])
- return static_cast<B*>(c)->foo();
- }
-}
-
-namespace Test9 {
- struct A {
- int a;
- };
- struct B {
- int b;
- };
- struct C : public B, public A {
- };
- struct RA {
- virtual A *f() {
- return 0;
- }
- virtual A *operator-() {
- return 0;
- }
- };
- struct RC final : public RA {
- virtual C *f() {
- C *x = new C();
- x->a = 1;
- x->b = 2;
- return x;
- }
- virtual C *operator-() {
- C *x = new C();
- x->a = 1;
- x->b = 2;
- return x;
- }
- };
- // CHECK: define {{.*}} @_ZN5Test91fEPNS_2RCE
- A *f(RC *x) {
- // FIXME: It should be possible to devirtualize this case, but that is
- // not implemented yet.
- // CHECK: load
- // CHECK: bitcast
- // CHECK: [[F_PTR_RA:%.+]] = bitcast
- // CHECK: [[VTABLE:%.+]] = load {{.+}} [[F_PTR_RA]]
- // CHECK: [[VFN:%.+]] = getelementptr inbounds {{.+}} [[VTABLE]], i{{[0-9]+}} 0
- // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]]
- // CHECK-NEXT: = call {{.*}} %[[FUNC]]
- return static_cast<RA*>(x)->f();
- }
- // CHECK: define {{.*}} @_ZN5Test93fopEPNS_2RCE
- A *fop(RC *x) {
- // FIXME: It should be possible to devirtualize this case, but that is
- // not implemented yet.
- // CHECK: load
- // CHECK: bitcast
- // CHECK: [[F_PTR_RA:%.+]] = bitcast
- // CHECK: [[VTABLE:%.+]] = load {{.+}} [[F_PTR_RA]]
- // CHECK: [[VFN:%.+]] = getelementptr inbounds {{.+}} [[VTABLE]], i{{[0-9]+}} 1
- // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]]
- // CHECK-NEXT: = call {{.*}} %[[FUNC]]
- return -static_cast<RA&>(*x);
- }
-}
-
-namespace Test10 {
- struct A {
- virtual int f();
- };
-
- struct B : A {
- int f() final;
- };
-
- // CHECK-LABEL: define i32 @_ZN6Test101fEPNS_1BE
- int f(B *b) {
- // CHECK: call i32 @_ZN6Test101B1fEv
- return static_cast<A *>(b)->f();
- }
-}
-
-namespace Test11 {
- // Check that the definitions of Derived's operators are emitted.
-
- // CHECK-LABEL: define linkonce_odr void @_ZN6Test111SIiE4foo1Ev(
- // CHECK: call void @_ZN6Test111SIiE7DerivedclEv(
- // CHECK: call zeroext i1 @_ZN6Test111SIiE7DerivedeqERKNS_4BaseE(
- // CHECK: call zeroext i1 @_ZN6Test111SIiE7DerivedntEv(
- // CHECK: call dereferenceable(4) %"class.Test11::Base"* @_ZN6Test111SIiE7DerivedixEi(
- // CHECK: define linkonce_odr void @_ZN6Test111SIiE7DerivedclEv(
- // CHECK: define linkonce_odr zeroext i1 @_ZN6Test111SIiE7DerivedeqERKNS_4BaseE(
- // CHECK: define linkonce_odr zeroext i1 @_ZN6Test111SIiE7DerivedntEv(
- // CHECK: define linkonce_odr dereferenceable(4) %"class.Test11::Base"* @_ZN6Test111SIiE7DerivedixEi(
- class Base {
- public:
- virtual void operator()() {}
- virtual bool operator==(const Base &other) { return false; }
- virtual bool operator!() { return false; }
- virtual Base &operator[](int i) { return *this; }
- };
-
- template<class T>
- struct S {
- class Derived final : public Base {
- public:
- void operator()() override {}
- bool operator==(const Base &other) override { return true; }
- bool operator!() override { return true; }
- Base &operator[](int i) override { return *this; }
- };
-
- Derived *ptr = nullptr, *ptr2 = nullptr;
-
- void foo1() {
- if (ptr && ptr2) {
- // These calls get devirtualized. Linkage fails if the definitions of
- // the called functions are not emitted.
- (*ptr)();
- (void)(*ptr == *ptr2);
- (void)(!(*ptr));
- (void)((*ptr)[1]);
- }
- }
- };
-
- void foo2() {
- S<int> *s = new S<int>;
- s->foo1();
- }
-}
+struct A {
+ int a;
+};
+struct B {
+ int b;
+};
+struct C : B, A {};
+struct RA {
+ virtual A *operator-();
+};
+struct RC : RA {
+ C *operator-() {
+ C *x = new C();
+ return x;
+ }
+};
+void fop(RC *x) { -static_cast<RA &>(*x); }
diff --git a/gcc/testsuite/g++.dg/tree-ssa/if-to-switch-1.C b/gcc/testsuite/g++.dg/tree-ssa/if-to-switch-1.C
new file mode 100644
index 0000000..5cb3a7e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/if-to-switch-1.C
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+void fancy_abort(const char *, int, const char *);
+
+enum machine_mode
+{
+ MODE_FLOAT,
+ MODE_DECIMAL_FLOAT,
+ MODE_COMPLEX_INT,
+ MODE_COMPLEX_FLOAT,
+ MODE_VECTOR_BOOL,
+ MODE_VECTOR_FLOAT
+} extern const mode_class;
+
+void tree_node() {
+ if (mode_class)
+ mode_class == MODE_FLOAT || mode_class == MODE_DECIMAL_FLOAT ||
+ mode_class == MODE_COMPLEX_FLOAT || mode_class == MODE_VECTOR_FLOAT
+ ? fancy_abort("aaa", 2, __FUNCTION__),
+ 0 : 0;
+ int g = 0;
+}
+
+/* { dg-final { scan-tree-dump "Condition chain with \[^\n\r]\* BBs transformed into a switch statement." "iftoswitch" } } */
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr90883.C b/gcc/testsuite/g++.dg/tree-ssa/pr90883.C
index 0e622f2..37df17d 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/pr90883.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr90883.C
@@ -15,6 +15,6 @@
// We want to match enough here to capture that we deleted an empty
// constructor store
-// aarch64 and mips will expand to loop to clear because CLEAR_RATIO.
-// { dg-final { scan-tree-dump "Deleted redundant store: .*\.a = {}" "dse1" { xfail { aarch64-*-* mips*-*-* } } } }
+// mips will expand to loop to clear because CLEAR_RATIO.
+// { dg-final { scan-tree-dump "Deleted redundant store: .*\.a = {}" "dse1" { xfail { mips*-*-* } } } }
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr97736.C b/gcc/testsuite/g++.dg/tree-ssa/pr97736.C
new file mode 100644
index 0000000..bda77e7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr97736.C
@@ -0,0 +1,12 @@
+/* PR tree-optimization/97736 */
+/* { dg-do compile { target { { x86_64-*-* aarch64-*-* ia64-*-* powerpc64-*-* } && lp64 } } } */
+/* { dg-options "-O2 -fdump-tree-switchlower1" } */
+
+bool is_vowel(char c) {
+ switch (c)
+ case'a':case'e':case'i':case'o':case'u':
+ return true;
+ return false;
+}
+
+/* { dg-final { scan-tree-dump ";; GIMPLE switch case clusters: BT:97-117" "switchlower1" } } */
diff --git a/gcc/testsuite/g++.dg/ubsan/pr61272.C b/gcc/testsuite/g++.dg/ubsan/pr61272.C
index 11dd1ec..cb4751e 100644
--- a/gcc/testsuite/g++.dg/ubsan/pr61272.C
+++ b/gcc/testsuite/g++.dg/ubsan/pr61272.C
@@ -12,10 +12,10 @@ namespace std
};
namespace __gnu_cxx
{
- template < typename _Alloc > struct __alloc_traits:std::allocator_traits < _Alloc > // { dg-error "within this context" }
+ template < typename _Alloc > struct __alloc_traits:std::allocator_traits < _Alloc >
{
typedef std::allocator_traits < _Alloc > _Base_type;
- using _Base_type::construct;
+ using _Base_type::construct; // { dg-error "within this context" }
};
template < typename _Tp, typename _Alloc > struct _Vector_base { typedef typename __gnu_cxx::__alloc_traits < _Alloc >::template rebind < _Tp >::other _Tp_alloc_type; }; // { dg-error "no class template" }
template < typename _Tp, typename _Alloc = std::allocator < _Tp > >class vector : protected _Vector_base < _Tp, _Alloc > { };
diff --git a/gcc/testsuite/g++.dg/vect/pr98064.cc b/gcc/testsuite/g++.dg/vect/pr98064.cc
new file mode 100644
index 0000000..74043ce
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/pr98064.cc
@@ -0,0 +1,25 @@
+// { dg-do compile }
+// { dg-additional-options "-O3" }
+
+const long long &min(const long long &__a, long long &__b) {
+ if (__b < __a)
+ return __b;
+ return __a;
+}
+extern long var_2;
+extern int var_3, var_8;
+extern long long var_5;
+extern unsigned short arr_353[];
+extern short arr_362[];
+extern int arr_518[];
+void test() {
+ for (char d = 0; d < 013; d += 4) {
+ for (char e = 0; e < 11; e++)
+ arr_353[e] = var_2 | min((long long)7, var_5);
+ for (int f = var_5; f; f += 4)
+ for (short g = var_8; g; g++)
+ arr_362[g] = 0;
+ }
+ for (short h = 5; (short)var_2; h += 5)
+ arr_518[h] = 0;
+}
diff --git a/gcc/testsuite/g++.dg/vect/simd-12.cc b/gcc/testsuite/g++.dg/vect/simd-12.cc
new file mode 100644
index 0000000..a3f18d3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/simd-12.cc
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-ffast-math -g" } */
+
+template <typename> class complex;
+template <typename _Tp> complex<_Tp> operator+(complex<_Tp>, complex<_Tp> __y) {
+ complex<_Tp> __r;
+ __r += __y;
+ return __r;
+}
+template <typename _Tp> complex<_Tp> operator*(complex<_Tp>, complex<_Tp> __y) {
+ complex<_Tp> __r;
+ __r *= __y;
+ return __r;
+}
+template <> class complex<double> {
+public:
+ void operator+=(complex __z) { _M_value += __z.__rep(); }
+ void operator*=(complex __z) {
+ _Complex __t = __z.__rep();
+ _M_value *= __t;
+ }
+ _Complex __rep() { return _M_value; }
+ _Complex _M_value;
+};
+template <typename> class Vector {
+ void equ();
+ complex<double> *val;
+};
+template <typename Number> void Vector<Number>::equ() {
+ Number c;
+ for (int i; i; ++i) {
+ complex<double> __trans_tmp_2 = c * val[i];
+ val[i] = val[i] + __trans_tmp_2;
+ }
+}
+template class Vector<complex<double> >;
diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-14.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-14.C
new file mode 100644
index 0000000..0812f83
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-14.C
@@ -0,0 +1,25 @@
+/* PR middle-end/97595 - bogus -Wstringop-overflow due to DECL_SIZE_UNIT
+ underreporting field size
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+struct A { char a[32]; };
+struct B: virtual A { };
+struct C: B { };
+
+struct D
+{
+ B &b;
+ D (B&);
+};
+
+D::D (B &b): b (b) { } // { dg-bogus "-Warray-bounds" }
+
+void f (void*);
+
+void g ()
+{
+ C c;
+ D d (c);
+ f (&d);
+}
diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-8.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-8.C
index 6db2013..6e0d7f3 100644
--- a/gcc/testsuite/g++.dg/warn/Warray-bounds-8.C
+++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-8.C
@@ -3,7 +3,7 @@
See Wstringop-overflow-3.C for the same test that exercises the other
warning.
{ dg-do compile }
- { dg-options "-O2 -Wall -Wno-stringop-overflow" }
+ { dg-options "-O2 -Wall -Wno-stringop-overflow -fno-ipa-icf" }
{ dg-skip-if "" { *-*-aix* } } */
void sink (void*);
diff --git a/gcc/testsuite/g++.dg/warn/Wnonnull5.C b/gcc/testsuite/g++.dg/warn/Wnonnull5.C
index 8b25d2d..78862d4 100644
--- a/gcc/testsuite/g++.dg/warn/Wnonnull5.C
+++ b/gcc/testsuite/g++.dg/warn/Wnonnull5.C
@@ -36,7 +36,7 @@ struct S
void warn_nullptr_this ()
{
((S*)nullptr)->f0 (""); // { dg-warning "3:'this' pointer null" "pr86568" { xfail *-*-* } }
- // { dg-warning "this' pointer null" "pr86568" { target *-*-* } .-1 }
+ // { dg-warning "this' pointer null" "pr86568 second variant" { target *-*-* } .-1 }
}
void warn_null_this_cst ()
@@ -49,15 +49,15 @@ void warn_null_this_var ()
{
S* null = 0;
null->f2 (&null); // { dg-warning "3:'this' pointer null" "pr86568" { xfail *-*-* } }
- // { dg-warning "'this' pointer null" "pr86568" { target *-*-* } .-1 }
+ // { dg-warning "'this' pointer null" "pr86568 second variant" { target *-*-* } .-1 }
}
void warn_nullptr (S s)
{
s.f3 (nullptr, &s); // { dg-warning "9:argument 1 null where non-null expected" "pr86568" { xfail *-*-* } }
- // { dg-warning "argument 1 null where non-null expected" "pr86568" { target *-*-* } .-1 }
+ // { dg-warning "argument 1 null where non-null expected" "pr86568 second variant" { target *-*-* } .-1 }
s.f3 (&s, nullptr); // { dg-warning "13:argument 2 null where non-null expected" "pr86568" { xfail *-*-* } }
- // { dg-warning "argument 2 null where non-null expected" "pr86568" { target *-*-* } .-1 }
+ // { dg-warning "argument 2 null where non-null expected" "pr86568 second variant" { target *-*-* } .-1 }
}
@@ -72,9 +72,9 @@ void warn_null_var (S s)
{
void* null = 0;
s.f5 (null, &s); // { dg-warning "9:argument 1 null where non-null expected" "pr86568" { xfail *-*-* } }
- // { dg-warning "argument 1 null where non-null expected" "pr86568" { target *-*-* } .-1 }
+ // { dg-warning "argument 1 null where non-null expected" "pr86568 second variant" { target *-*-* } .-1 }
s.f5 (&s, null); // { dg-warning "16:argument 2 null where non-null expected" "pr86568" { xfail *-*-* } }
- // { dg-warning "argument 2 null where non-null expected" "pr86568" { target *-*-* } .-1 }
+ // { dg-warning "argument 2 null where non-null expected" "pr86568 second variant" { target *-*-* } .-1 }
}
void warn_null_cond (S s, void *null)
@@ -83,9 +83,9 @@ void warn_null_cond (S s, void *null)
return;
s.f6 (null, &s); // { dg-warning "9:argument 1 null where non-null expected" "pr86568" { xfail *-*-* } }
- // { dg-warning "argument 1 null where non-null expected" "pr86568" { target *-*-* } .-1 }
+ // { dg-warning "argument 1 null where non-null expected" "pr86568 second variant" { target *-*-* } .-1 }
s.f6 (&s, null); // { dg-warning "13:argument 2 null where non-null expected" "pr86568" { xfail *-*-* } }
- // { dg-warning "argument 2 null where non-null expected" "pr86568" { target *-*-* } .-1 }
+ // { dg-warning "argument 2 null where non-null expected" "pr86568 second variant" { target *-*-* } .-1 }
}
diff --git a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-8.C b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-8.C
index 77bd331..12cd4cd 100644
--- a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-8.C
+++ b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-8.C
@@ -43,7 +43,7 @@ void test_cst_off ()
/* Offsets are treated as signed so SIZE_MAX is indistinguishable
from -1. */
char ca1[1]; // { dg-message "at offset \\d+ from 'ca1' declared here" "note" { xfail *-*-* } }
- // { dg-message "at offset -1 from 'ca1' declared here" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset -1 from 'ca1' declared here" "note second variant" { target *-*-* } .-1 }
new (ca1 + SIZE_MAX) S<1>; // { dg-warning "constructing an object of type 'S<1>' and size '1' in a region of type 'char \\\[1]' and size '0'" }
}
}
diff --git a/gcc/testsuite/g++.dg/warn/Wplacement-new-size.C b/gcc/testsuite/g++.dg/warn/Wplacement-new-size.C
index 48d6b15..25325b3 100644
--- a/gcc/testsuite/g++.dg/warn/Wplacement-new-size.C
+++ b/gcc/testsuite/g++.dg/warn/Wplacement-new-size.C
@@ -332,11 +332,11 @@ void test (void *p, int32_t n)
new (&uac2.c) int32_t; // { dg-warning "placement" }
new (&uac3.c) int32_t; // { dg-warning "placement" }
- // Diagnose the following even though the size of uac4.c could be
- // expected to extend to the end of the union (as it is by Built-in
- // Object Size and so isn't diagnosed in calls to functions like
- // memset(&uac4.c, 0, sizeof(int32_t)) when _FORTIFY_SOURCE is non-zero. */
- new (&uac4.c) int32_t; // { dg-warning "placement" }
+ /* The following isn't diagnosed (anymore) for consistency with
+ the middle end where members of unions are considered to extend
+ to the end of the enclosing object.
+ See gcc.dg/Wstringop-overflow-60.c for the middle end test. */
+ new (&uac4.c) int32_t;
new (&uac4.c + 1) int32_t; // { dg-warning "placement" }
}
diff --git a/gcc/testsuite/g++.dg/warn/Wrange-loop-construct2.C b/gcc/testsuite/g++.dg/warn/Wrange-loop-construct2.C
new file mode 100644
index 0000000..5bb08cc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wrange-loop-construct2.C
@@ -0,0 +1,212 @@
+// PR c++/94695
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wrange-loop-construct" }
+
+struct Foo { };
+struct Bar {
+ char arr[100];
+ Bar(Foo);
+ Bar(int);
+ operator int();
+};
+
+template<typename T>
+struct It {
+ T operator*();
+ It operator++();
+ bool operator!=(const It);
+};
+
+template<typename T>
+struct Cont {
+ using I = It<T>;
+ I begin();
+ I end();
+};
+
+void
+fn1 ()
+{
+ int arr[10];
+ Cont<int> cont_int;
+
+ for (const double &x : arr) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (const double x : arr) { (void) x; }
+ for (const int &x : arr) { (void) x; }
+ for (double &&x : arr) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (double x : arr) { (void) x; }
+
+ for (const int &&x : cont_int) { (void) x; }
+ for (const int &x : cont_int) { (void) x; }
+ for (const int x : cont_int) { (void) x; }
+ for (int&& x : cont_int) { (void) x; }
+ for (int x : cont_int) { (void) x; }
+
+ for (const double &&x : cont_int) { (void) x; }
+ for (const double &x : cont_int) { (void) x; }
+ for (const double x : cont_int) { (void) x; }
+
+ for (double &&x : cont_int) { (void) x; }
+ for (double x : cont_int) { (void) x; }
+
+ for (const Bar &&x : cont_int) { (void) x; }
+ for (const Bar x : cont_int) { (void) x; }
+}
+
+void
+fn2 ()
+{
+ Cont<int &> cont_int_ref;
+
+ for (const int &x : cont_int_ref) { (void) x; }
+ for (const int x : cont_int_ref) { (void) x; }
+ for (int &x : cont_int_ref) { (void) x; }
+ for (int x : cont_int_ref) { (void) x; }
+
+ for (const double &&x : cont_int_ref) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (const double &x : cont_int_ref) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (const double x : cont_int_ref) { (void) x; }
+ for (double &&x : cont_int_ref) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (double x : cont_int_ref) { (void) x; }
+
+ for (const Bar &&x : cont_int_ref) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (const Bar &x : cont_int_ref) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (const Bar x : cont_int_ref) { (void) x; }
+ for (Bar &&x : cont_int_ref) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (Bar x : cont_int_ref) { (void) x; }
+}
+
+void
+fn3 ()
+{
+ Cont<Bar> cont_bar;
+
+ for (const Bar &&x : cont_bar) { (void) x; }
+ for (const Bar &x : cont_bar) { (void) x; }
+ for (const Bar x : cont_bar) { (void) x; }
+ for (Bar &&x : cont_bar) { (void) x; }
+ for (Bar x : cont_bar) { (void) x; }
+
+ for (const int &&x : cont_bar) { (void) x; }
+ for (const int &x : cont_bar) { (void) x; }
+ for (const int x : cont_bar) { (void) x; }
+ for (int &&x : cont_bar) { (void) x; }
+ for (int x : cont_bar) { (void) x; }
+}
+
+void
+fn4 ()
+{
+ Cont<Bar &> cont_bar_ref;
+
+ for (const Bar &x : cont_bar_ref) { (void) x; }
+ for (Bar &x : cont_bar_ref) { (void) x; }
+ for (Bar x : cont_bar_ref) { (void) x; }
+
+ for (const int &&x : cont_bar_ref) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (const int &x : cont_bar_ref) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (const int x : cont_bar_ref) { (void) x; }
+ for (int &&x : cont_bar_ref) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (int x : cont_bar_ref) { (void) x; }
+}
+
+void
+fn5 ()
+{
+ Cont<Foo> cont_foo;
+
+ for (const Bar &&x : cont_foo) { (void) x; }
+ for (const Bar &x : cont_foo) { (void) x; }
+ for (const Bar x : cont_foo) { (void) x; }
+ for (Bar &&x : cont_foo) { (void) x; }
+ for (Bar x : cont_foo) { (void) x; }
+}
+
+void
+fn6 ()
+{
+ Cont<Foo &> cont_foo_ref;
+
+ for (const Bar &&x : cont_foo_ref) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (const Bar &x : cont_foo_ref) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (const Bar x : cont_foo_ref) { (void) x; }
+ for (Bar &&x : cont_foo_ref) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (Bar x : cont_foo_ref) { (void) x; }
+}
+
+void
+fn7 ()
+{
+ double arr[2];
+
+ for (const double &x : arr) { (void) x; }
+ for (const double x : arr) { (void) x; }
+ for (double &x : arr) { (void) x; }
+ for (double x : arr) { (void) x; }
+
+ for (const int &&x : arr) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (const int &x : arr) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (const int x : arr) { (void) x; }
+ for (int &&x : arr) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (int x : arr) { (void) x; }
+
+ for (const Bar &&x : arr) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (const Bar &x : arr) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (const Bar x : arr) { (void) x; }
+ for (Bar &&x : arr) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (Bar x : arr) { (void) x; }
+}
+
+void
+fn8 ()
+{
+ Foo arr[2];
+
+ for (const Foo &x : arr) { (void) x; }
+ for (const Foo x : arr) { (void) x; }
+ for (Foo &x : arr) { (void) x; }
+ for (Foo x : arr) { (void) x; }
+
+ for (const Bar &&x : arr) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (const Bar &x : arr) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (const Bar x : arr) { (void) x; }
+ for (Bar &&x : arr) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (Bar x : arr) { (void) x; }
+}
+
+void
+fn9 ()
+{
+ Bar arr[2] = { 1, 2 };
+
+ for (const Bar &x : arr) { (void) x; }
+ for (Bar &x : arr) { (void) x; }
+ for (Bar x : arr) { (void) x; }
+
+ for (const int &&x : arr) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (const int &x : arr) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (const int x : arr) { (void) x; }
+ for (int &&x : arr) { (void) x; } // { dg-warning "binds to a temporary constructed from type" }
+ for (int x : arr) { (void) x; }
+}
+
+template<typename T>
+void
+fn10 ()
+{
+ Cont<Bar> cont_bar;
+
+ for (const Bar &x : cont_bar) { (void) x; }
+
+ Cont<T> cont_dep;
+ for (const T &x : cont_dep) { (void) x; }
+}
+template void fn10<Bar>();
+
+struct S {
+ void fn()
+ {
+ Cont<Bar> cont_bar;
+ for (const Bar &x : cont_bar) { (void) x; }
+ }
+};
diff --git a/gcc/testsuite/g++.dg/warn/Wstringop-overflow-3.C b/gcc/testsuite/g++.dg/warn/Wstringop-overflow-3.C
index da9ad6f..c68e82a 100644
--- a/gcc/testsuite/g++.dg/warn/Wstringop-overflow-3.C
+++ b/gcc/testsuite/g++.dg/warn/Wstringop-overflow-3.C
@@ -12,7 +12,7 @@ void sink (void*);
struct Ax
{
char n;
- char a[]; // { dg-message "at offset \[0-2\] to object 'Ax::a' declared here" "note: flexarray" }
+ char a[]; // { dg-message "destination object 'Ax::a' of size 0" "note: flexarray" }
};
// Verify warning for a definition with no initializer.
@@ -93,7 +93,7 @@ NOIPA void gaxx ()
struct A0
{
char n;
- char a[0]; // { dg-message "at offset \[0-2\] to object 'A0::a' with size 0 declared here" "note: trailing zero-length array" }
+ char a[0]; // { dg-message "destination object 'A0::a' of size 0" "note: trailing zero-length array" }
};
// Verify warning for a definition with no initializer.
@@ -160,7 +160,7 @@ NOIPA void ga0x ()
struct A1
{
char n;
- char a[1]; // { dg-message "at offset \[1-9\] to object 'A1::a' with size 1 declared here" "note: trailing one-element array" }
+ char a[1]; // { dg-message "at offset \[1-2\] into destination object 'A1::a' of size 1" "note: trailing one-element array" }
};
// Verify warning for a definition with no initializer.
@@ -234,7 +234,7 @@ NOIPA void ga1x ()
struct A1i
{
char n;
- char a[1]; // { dg-message "at offset \[1-9\] to object 'A1i::a' with size 1 declared here" "note: interior one-element array" }
+ char a[1]; // { dg-message "at offset \[1-2\] into destination object 'A1i::a' of size 1" "note: interior one-element array" }
char x;
};
@@ -307,7 +307,7 @@ NOIPA void ga1ix ()
struct Bx
{
char n;
- char a[]; // { dg-message "at offset 0 to object 'Bx::a' declared here" "note: flexarray class member" }
+ char a[]; // { dg-message "destination object 'Bx::a' of size 0" "note: flexarray class member" }
// Verify the warning for a constant.
Bx () { a[0] = 0; } // { dg-warning "\\\[-Wstringop-overflow" }
@@ -332,7 +332,7 @@ NOIPA void gbxi (int i)
struct B0
{
char n;
- char a[0]; // { dg-message "at offset 0 to object 'B0::a' with size 0 declared here" "note: zero-length trailing array class member" }
+ char a[0]; // { dg-message "destination object 'B0::a' of size 0" "note: zero-length trailing array class member" }
B0 () { a[0] = 0; } // { dg-warning "\\\[-Wstringop-overflow" }
};
@@ -348,7 +348,7 @@ NOIPA void gb0 (void)
struct B1
{
char n;
- char a[1]; // { dg-message "at offset 1 to object 'B1::a' with size 1 declared here" "note: one-element trailing array class member" }
+ char a[1]; // { dg-message "at offset 1 into destination object 'B1::a' of size 1" "note: one-element trailing array class member" }
B1 () { a[1] = 0; } // { dg-warning "\\\[-Wstringop-overflow" }
};
@@ -362,7 +362,7 @@ NOIPA void gb1 (void)
struct B123
{
- char a[123]; // { dg-message "at offset 123 to object 'B123::a' with size 123 declared here" "note: large trailing array class member" }
+ char a[123]; // { dg-message "at offset 123 into destination object 'B123::a' of size 123" "note: large trailing array class member" }
B123 () { a[123] = 0; } // { dg-warning "\\\[-Wstringop-overflow" }
};
@@ -376,7 +376,7 @@ NOIPA void gb123 (void)
struct B234
{
- char a[234]; // { dg-message "at offset 234 to object 'B234::a' with size 234 declared here" "note: large trailing array class member" }
+ char a[234]; // { dg-message "at offset 234 into destination object 'B234::a' of size 234" "note: large trailing array class member" }
B234 (int i) { a[i] = 0; } // { dg-warning "\\\[-Wstringop-overflow" }
};
diff --git a/gcc/testsuite/g++.dg/warn/Wstringop-overflow-6.C b/gcc/testsuite/g++.dg/warn/Wstringop-overflow-6.C
new file mode 100644
index 0000000..8173e60
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wstringop-overflow-6.C
@@ -0,0 +1,8 @@
+/* PR middle-end/97595 - bogus -Wstringop-overflow due to DECL_SIZE_UNIT
+ underreporting field size
+ { dg-do compile { target c++11 } }
+ { dg-options "-O2 -Wall -Wsystem-headers" } */
+
+#include <iostream>
+
+template void std::basic_iostream<char>::swap (basic_iostream&);
diff --git a/gcc/testsuite/g++.dg/warn/Wvexing-parse9.C b/gcc/testsuite/g++.dg/warn/Wvexing-parse9.C
new file mode 100644
index 0000000..92724bc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wvexing-parse9.C
@@ -0,0 +1,8 @@
+// PR c++/97881
+// { dg-do compile }
+
+void
+cb ()
+{
+ volatile _Atomic (int) a1; // { dg-error "" }
+}
diff --git a/gcc/testsuite/g++.dg/warn/pr98104.C b/gcc/testsuite/g++.dg/warn/pr98104.C
new file mode 100644
index 0000000..6ca617b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/pr98104.C
@@ -0,0 +1,20 @@
+// PR c++/98104
+
+#include <new>
+
+struct B
+{
+ B ();
+ int *a;
+ char b;
+};
+
+struct D : public B {};
+void bar (B *);
+
+void
+foo ()
+{
+ D d;
+ bar (::new (static_cast<B*>(&d)) B); // { dg-bogus "placement new constructing an object of type 'B' and size '\[0-9]*' in a region of type 'B' and size '\[0-9]*'" }
+}
diff --git a/gcc/testsuite/g++.dg/warn/uninit-1.C b/gcc/testsuite/g++.dg/warn/uninit-1.C
new file mode 100644
index 0000000..30f3cea
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/uninit-1.C
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wmaybe-uninitialized" } */
+struct a {int a;};
+__attribute__ ((noinline))
+void
+nowarn (const struct a *ptr)
+{
+ if (ptr)
+ asm volatile ("");
+}
+void
+test()
+{
+ struct a ptr;
+ nowarn (&ptr);
+}
+__attribute__ ((noinline))
+int
+nowarn2 (const struct a *ptr, const struct a ptr2)
+{
+ return ptr != 0 || ptr2.a;
+}
+int mem;
+int
+test2()
+{
+ struct a ptr,ptr2={0};
+ return nowarn2 (&ptr, ptr2);
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/decl3.C b/gcc/testsuite/g++.old-deja/g++.other/decl3.C
index bdcfcb0..4534bd1 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/decl3.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/decl3.C
@@ -13,7 +13,7 @@ struct cow_t { // { dg-message "pure" }
int main()
{
- cow_t cow[2]; // { dg-error "invalid abstract type" }
+ cow_t cow[2]; // { dg-error "abstract" }
cow[0].f();
return 0;
}
diff --git a/gcc/testsuite/g++.target/msp430/data-attributes.C b/gcc/testsuite/g++.target/msp430/data-attributes.C
new file mode 100644
index 0000000..b7faf2c
--- /dev/null
+++ b/gcc/testsuite/g++.target/msp430/data-attributes.C
@@ -0,0 +1,55 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-mcpu=msp430" } } */
+/* { dg-options "-mlarge" } */
+
+/* The msp430-specific variable attributes "upper", either", "noinit"
+ and "persistent", all conflict with one another.
+ "lower" can be used to indicate that a variable with a section set by the
+ "section", "noinit", or "persistent" attributes is in lower memory, so it
+ does not conflict with these.
+ These attributes also conflict with the "section" attribute, since they
+ specify sections to put the variables into. */
+int __attribute__((persistent)) p = 10;
+int __attribute__((persistent,lower)) pl = 20;
+int __attribute__((persistent,upper)) pu = 20; /* { dg-warning "ignoring attribute 'upper' because it conflicts with attribute 'persistent'" } */
+int __attribute__((persistent,either)) pe = 20; /* { dg-warning "ignoring attribute 'either' because it conflicts with attribute 'persistent'" } */
+/* This one results in an error because the handler for persistent sets the
+ section to .persistent there and then. */
+int __attribute__((persistent,section(".data.foo"))) ps = 20; /* { dg-warning "ignoring attribute 'section' because it conflicts with attribute 'persistent'" } */
+int __attribute__((persistent,noinit)) pn = 2; /* { dg-warning "ignoring attribute 'noinit' because it conflicts with attribute 'persistent'" } */
+int __attribute__((persistent)) zz; /* { dg-warning "ignoring 'persistent' attribute set on uninitialized variable" } */
+
+int __attribute__((noinit)) n;
+int __attribute__((noinit,lower)) nl;
+int __attribute__((noinit,upper)) nu; /* { dg-warning "ignoring attribute 'upper' because it conflicts with attribute 'noinit'" } */
+int __attribute__((noinit,either)) ne; /* { dg-warning "ignoring attribute 'either' because it conflicts with attribute 'noinit'" } */
+int __attribute__((noinit,persistent)) np; /* { dg-warning "ignoring attribute 'persistent' because it conflicts with attribute 'noinit'" } */
+int __attribute__((noinit,section(".data.foo"))) ns; /* { dg-warning "ignoring attribute 'section' because it conflicts with attribute 'noinit'" } */
+
+int __attribute__((lower)) l = 20;
+int __attribute__((lower,upper)) lu = 20; /* { dg-warning "ignoring attribute 'upper' because it conflicts with attribute 'lower'" } */
+int __attribute__((lower,either)) le = 20; /* { dg-warning "ignoring attribute 'either' because it conflicts with attribute 'lower'" } */
+int __attribute__((lower,persistent)) lp = 20;
+int __attribute__((lower,noinit)) ln;
+int __attribute__((lower,section(".data.foo"))) ls = 30;
+
+int __attribute__((upper)) u = 20;
+int __attribute__((upper,lower)) ul = 20; /* { dg-warning "ignoring attribute 'lower' because it conflicts with attribute 'upper'" } */
+int __attribute__((upper,either)) ue = 20; /* { dg-warning "ignoring attribute 'either' because it conflicts with attribute 'upper'" } */
+int __attribute__((upper,persistent)) up = 20; /* { dg-warning "ignoring attribute 'persistent' because it conflicts with attribute 'upper'" } */
+int __attribute__((upper,noinit)) un; /* { dg-warning "ignoring attribute 'noinit' because it conflicts with attribute 'upper'" } */
+int __attribute__((upper,section(".data.foo"))) us = 30; /* { dg-warning "ignoring attribute 'section' because it conflicts with attribute 'upper'" } */
+
+int __attribute__((either)) e = 20;
+int __attribute__((either,lower)) el = 20; /* { dg-warning "ignoring attribute 'lower' because it conflicts with attribute 'either'" } */
+int __attribute__((either,upper)) ee = 20; /* { dg-warning "ignoring attribute 'upper' because it conflicts with attribute 'either'" } */
+int __attribute__((either,persistent)) ep = 20; /* { dg-warning "ignoring attribute 'persistent' because it conflicts with attribute 'either'" } */
+int __attribute__((either,noinit)) en; /* { dg-warning "ignoring attribute 'noinit' because it conflicts with attribute 'either'" } */
+int __attribute__((either,section(".data.foo"))) es = 30; /* { dg-warning "ignoring attribute 'section' because it conflicts with attribute 'either'" } */
+
+int __attribute__((section(".data.foo"))) s = 20;
+int __attribute__((section(".data.foo"),noinit)) sn; /* { dg-warning "ignoring attribute 'noinit' because it conflicts with attribute 'section'" } */
+int __attribute__((section(".data.foo"),persistent)) sp = 20; /* { dg-warning "ignoring attribute 'persistent' because it conflicts with attribute 'section'" } */
+int __attribute__((section(".data.foo"),lower)) sl = 2;
+int __attribute__((section(".data.foo"),upper)) su = 20; /* { dg-warning "ignoring attribute 'upper' because it conflicts with attribute 'section'" } */
+int __attribute__((section(".data.foo"),either)) se = 2; /* { dg-warning "ignoring attribute 'either' because it conflicts with attribute 'section'" } */
diff --git a/gcc/testsuite/g++.target/msp430/msp430.exp b/gcc/testsuite/g++.target/msp430/msp430.exp
new file mode 100644
index 0000000..3574c0f
--- /dev/null
+++ b/gcc/testsuite/g++.target/msp430/msp430.exp
@@ -0,0 +1,44 @@
+# Specific regression driver for MSP430.
+# Copyright (C) 2020 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/>. */
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Exit immediately if this isn't an MSP430 target.
+if {![istarget msp430*-*-*] } then {
+ return
+}
+
+# Load support procs.
+load_lib g++-dg.exp
+
+global DEFAULT_CXXFLAGS
+if ![info exists DEFAULT_CXXFLAGS] then {
+ set DEFAULT_CXXFLAGS " -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] \
+ "" $DEFAULT_CXXFLAGS
+
+# All done.
+dg-finish
+
diff --git a/gcc/testsuite/g++.target/powerpc/pr97947.C b/gcc/testsuite/g++.target/powerpc/pr97947.C
new file mode 100644
index 0000000..94e5ed6
--- /dev/null
+++ b/gcc/testsuite/g++.target/powerpc/pr97947.C
@@ -0,0 +1,12 @@
+/* PR c++/97947 */
+/* { dg-do compile } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10" } */
+
+/* Verify we do not ICE on the test below. */
+
+void
+bug (__vector_pair *src)
+{
+ volatile __vector_pair dd = *src;
+}
diff --git a/gcc/testsuite/g++.target/riscv/pr97682.C b/gcc/testsuite/g++.target/riscv/pr97682.C
new file mode 100644
index 0000000..03c7a44
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/pr97682.C
@@ -0,0 +1,160 @@
+/* PR target/97682 */
+/* { dg-do compile } */
+/* { dg-options "-fPIC -O2 -march=rv64g -mabi=lp64" } */
+
+template <typename ab, int ac> struct g { ab b[ac]; };
+long i, m;
+
+namespace std
+{
+ template <typename c> struct t
+ {
+ int a;
+ c h;
+ };
+
+ struct ad
+ {
+ enum { j };
+ };
+
+ template <typename k> k l(k);
+ struct al {};
+ template <typename k> k aa(k);
+
+ struct v
+ {
+ template <typename n, typename q> static q o(n, n, q);
+ };
+
+ template <int, typename n, typename q> void p(n z, n ao, q ap)
+ {
+ v::o(z, ao, ap);
+ }
+
+ template <int ae, typename n, typename q> void r(n z, n ao, q ap)
+ {
+ p<ae>(z, ao, ap);
+ }
+
+ template <int ae, typename n, typename q> void af(n z, n ao, q)
+ {
+ r<ae>(aa(z), aa(ao), 0);
+ }
+
+ template <typename n, typename q> void ag(n z, n ao, q ap)
+ {
+ af<ad::j>(l(z), l(ao), ap);
+ }
+
+ template <typename> class allocator;
+ template <typename ah, typename ai, typename aj> void ak(ah, ai, aj);
+
+ template <typename s> class aq
+ {
+ template <typename am> struct ar { using f = am *; };
+ public:
+ using an = typename ar<s>::f;
+ };
+
+ template <typename s> class as
+ {
+ public:
+ using an = typename aq<s>::an;
+ an operator->();
+ };
+
+ struct ay
+ {
+ int at();
+ };
+
+ template <typename s, typename = allocator<s>> class vector : ay
+ {
+ public:
+ long au();
+ long x;
+ void av() { _M_default_append(x); }
+ void _M_default_append(unsigned long);
+ void aw();
+ long ax(int);
+ };
+
+ template <typename s, typename y>
+ void vector<s, y>::_M_default_append(unsigned long z)
+ {
+ long az = au();
+ int w = at(), bc = at();
+ i = ax(w);
+ m = ax(w);
+ if (i || m)
+ aw();
+ ak(az, z, bc);
+ }
+}
+
+namespace llvm
+{
+ template <int bd> class bh
+ {
+ enum { bf = bd } * bg[bf];
+ };
+
+ template <class> class bi;
+
+ class bm
+ {
+ using bj = bi<int>;
+ std::as<bj> bk;
+ void bl();
+ };
+
+ template <class> struct bn;
+
+ class br
+ {
+ bh<8> bo;
+ };
+
+ class ca
+ {
+ int *d;
+ int e;
+ };
+
+ template <class bp> class bv : std::al, br
+ {
+ g<std::t<ca>, 8> b;
+ };
+
+ template <class ab> bv<ab> bt(ab);
+
+ class BlockFrequencyInfoImplBase
+ {
+ public:
+ struct FrequencyData;
+ std::vector<FrequencyData> bu;
+ };
+
+ template <class> struct cb { using bw = int; };
+ template <class bx> class bi : BlockFrequencyInfoImplBase
+ {
+ using bw = typename cb<bx>::bw;
+ public:
+ void bl();
+ };
+
+ template <class bx> void bi<bx>::bl()
+ {
+ const bw *by;
+ bv<const int *> bz;
+ ag(bz, bt(by), 0);
+ bu.av();
+ }
+
+ template <> struct bn<const int *> { using u = ca; };
+ void bm::bl() { bk->bl(); }
+}
+
+/* The t1 register is to initial symbol reference for call instruction. */
+/* { dg-final { scan-assembler "la\tt1,.*FrequencyData.*_M_default_append.*" } } */
diff --git a/gcc/testsuite/gcc.c-torture/compile/asmgoto-2.c b/gcc/testsuite/gcc.c-torture/compile/asmgoto-2.c
new file mode 100644
index 0000000..f1b30c0
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/asmgoto-2.c
@@ -0,0 +1,65 @@
+/* This test should be switched off for a new target with less than 4 allocatable registers */
+/* { dg-do compile } */
+int
+foo (void)
+{
+ int x, y, z, v;
+
+ asm goto ("": "=r" (x), "=r" (y), "=r" (z), "=r" (v) : : : lab, lab2, lab3, lab4);
+ lab:
+ return x;
+ lab2:
+ return y;
+ lab3:
+ return z;
+ lab4:
+ return v;
+}
+
+int
+foo2 (void)
+{
+ int x = 0, y = 1, z = 2, v = 3;
+
+ asm goto ("": "+r" (x), "+r" (y), "+r" (z), "+r" (v) : : : lab, lab2, lab3, lab4);
+ lab:
+ return x;
+ lab2:
+ return y;
+ lab3:
+ return z;
+ lab4:
+ return v;
+}
+
+int
+foo3 (void)
+{
+ int x, y, z, v;
+
+ asm goto ("": "=rm" (x), "=mr" (y), "=rm" (z), "=mr" (v) : : : lab, lab2, lab3, lab4);
+ lab:
+ return x;
+ lab2:
+ return y;
+ lab3:
+ return z;
+ lab4:
+ return v;
+}
+
+int
+foo4 (void)
+{
+ int x, y, z, v;
+
+ asm goto ("": "=r,m" (x), "=m,r" (y), "=r,m" (z), "=m,r" (v) : : : lab, lab2, lab3, lab4);
+ lab:
+ return x;
+ lab2:
+ return y;
+ lab3:
+ return z;
+ lab4:
+ return v;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/asmgoto-3.c b/gcc/testsuite/gcc.c-torture/compile/asmgoto-3.c
new file mode 100644
index 0000000..842b73e
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/asmgoto-3.c
@@ -0,0 +1,89 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+
+int
+foo (void)
+{
+ int x;
+
+ asm goto ("": "=a" (x) : : : lab);
+ lab:
+ return x;
+}
+
+int
+foo2 (void)
+{
+ int x, y;
+
+ asm goto ("": "=a" (x), "=d" (y) : : : lab, lab2);
+ lab:
+ return x;
+ lab2:
+ return y;
+}
+
+int
+foo3 (void)
+{
+ int x, y, z;
+
+ asm goto ("": "=a" (x), "=d" (y), "=c" (z) : : : lab, lab2, lab3);
+ lab:
+ return x;
+ lab2:
+ return y;
+ lab3:
+ return z;
+}
+
+int
+foo4 (void)
+{
+ int x, y, z, v;
+
+ asm goto ("": "=a" (x), "=d" (y), "=c" (z) , "=b" (v) : : : lab, lab2, lab3, lab4);
+ lab:
+ return x;
+ lab2:
+ return y;
+ lab3:
+ return z;
+ lab4:
+ return v;
+}
+
+int
+foo5 (void)
+{
+ int x, y, z, v, w;
+
+ asm goto ("": "=a" (x), "=d" (y), "=c" (z), "=b" (v), "=S" (w) : : : lab, lab2, lab3, lab4, lab5);
+ lab:
+ return x;
+ lab2:
+ return y;
+ lab3:
+ return z;
+ lab4:
+ return v;
+ lab5:
+ return w;
+}
+
+int
+foo6 (void)
+{
+ int x = 0, y = 1, z = 2, v = 3, w = 4;
+
+ asm goto ("": "+a" (x), "+d" (y), "+c" (z), "+b" (v), "+S" (w) : : : lab, lab2, lab3, lab4, lab5);
+ lab:
+ return x;
+ lab2:
+ return y;
+ lab3:
+ return z;
+ lab4:
+ return v;
+ lab5:
+ return w;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/asmgoto-4.c b/gcc/testsuite/gcc.c-torture/compile/asmgoto-4.c
new file mode 100644
index 0000000..844157e
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/asmgoto-4.c
@@ -0,0 +1,14 @@
+/* Check that LRA really puts output reloads for p4 in two successors blocks */
+/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && { ! ia32 } } } } */
+/* { dg-options "-O0 -fdump-rtl-reload" } */
+
+int f (int *p1, int *p2, int *p3, int *p4) {
+ asm volatile goto (
+ ""
+ : "=r" (*p2), "=a" (p4)
+ : "r" (*p2), "r" (p2)
+ : "r8", "r9" : lab, lab2);
+ lab: return p2 - p4;
+ lab2: return p3 - p4;
+}
+/* { dg-final { scan-rtl-dump-times "Inserting insn reload after in bb" 2 "reload" } } */
diff --git a/gcc/testsuite/gcc.c-torture/compile/asmgoto-5.c b/gcc/testsuite/gcc.c-torture/compile/asmgoto-5.c
new file mode 100644
index 0000000..94c14dd
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/asmgoto-5.c
@@ -0,0 +1,56 @@
+/* Test to generate output reload in asm goto on x86_64. */
+/* { dg-do compile } */
+/* { dg-skip-if "no O0" { { i?86-*-* x86_64-*-* } && { ! ia32 } } { "-O0" } { "" } } */
+
+#if defined __x86_64__
+#define ASM(s) asm (s)
+#else
+#define ASM(s)
+#endif
+
+int
+foo (int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8,
+ int a9, int a10, int a11, int a12, int a13, int a14, int a15, int a16)
+{
+ register int v0 ASM ("rax") = a3;
+ register int v1 ASM ("rbx") = a4;
+ register int v2 ASM ("rcx") = a5;
+ register int v3 ASM ("rdx") = a6;
+ register int v4 ASM ("rsi") = a7;
+ register int v5 ASM ("rdi") = a8;
+ register int v6 ASM ("r8") = a9;
+ register int v7 ASM ("r9") = a10;
+ register int v8 ASM ("r10") = a11;
+ register int v9 ASM ("r11") = a12;
+ register int v10 ASM ("r12") = a13;
+ register int v11 ASM ("r13") = a14;
+ register int v12 ASM ("r14") = a15;
+ register int v13 ASM ("r15") = a16;
+ int x;
+
+ v0 += a0;
+ v1 += a1;
+ v2 += a2;
+ v0 |= a0;
+ v1 |= a1;
+ v2 |= a2;
+ v0 ^= a0;
+ v1 ^= a1;
+ v2 ^= a2;
+ v0 &= a0;
+ v1 &= a1;
+ v2 &= a2;
+ asm goto ("": "=r" (x) : : : lab);
+ a1 ^= a0;
+ a2 = a1;
+ a0 |= a2;
+ a0 |= x;
+ lab:
+ v0 += x + a0 + a1 + a2;
+ v1 -= a0 - a1 - a2;
+ v2 |= a0 | a1 | a2;
+ v3 |= a0 & a1 & a2;
+ v4 ^= a0 ^ a1 ^ a2;
+ return v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10 + v11 + v12 + v13 + a0 + a1 + a2;
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-1.c b/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-1.c
new file mode 100644
index 0000000..5f6cbca
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-1.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target R_flag_in_section } */
+/* { dg-final { scan-assembler ".text.*,\"axR\"" } } */
+/* { dg-final { scan-assembler ".bss.*,\"awR\"" } } */
+/* { dg-final { scan-assembler ".data.*,\"awR\"" } } */
+/* { dg-final { scan-assembler ".rodata.*,\"aR\"" } } */
+/* { dg-final { scan-assembler ".data.used_foo_sec,\"awR\"" } } */
+
+void __attribute__((used)) used_fn (void) { }
+void unused_fn (void) { }
+void __attribute__((hot,used)) used_hot_fn (void) { }
+void __attribute__((hot)) unused_hot_fn (void) { }
+void __attribute__((cold,used)) used_cold_fn (void) { }
+void __attribute__((cold)) unused_cold_fn (void) { }
+int __attribute__((used)) used_bss = 0;
+int __attribute__((used)) used_data = 1;
+const int __attribute__((used)) used_rodata = 2;
+int __attribute__((used)) used_comm;
+static int __attribute__((used)) used_lcomm;
+
+int unused_bss = 0;
+int unused_data = 1;
+const int unused_rodata = 2;
+int unused_comm;
+static int unused_lcomm;
+
+/* Test switching back to the retained sections. */
+void __attribute__((used)) used_fn2 (void) { }
+int __attribute__((used)) used_bss2 = 0;
+int __attribute__((used)) used_data2 = 1;
+const int __attribute__((used)) used_rodata2 = 2;
+int __attribute__((used)) used_comm2;
+static int __attribute__((used)) used_lcomm2;
+
+int __attribute__((used,section(".data.used_foo_sec"))) used_foo = 2;
diff --git a/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-2.c b/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-2.c
new file mode 100644
index 0000000..be5f391
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target R_flag_in_section } */
+/* { dg-final { scan-assembler ".text.used_fn,\"axR\"" } } */
+/* { dg-final { scan-assembler ".text.used_fn2,\"axR\"" } } */
+/* { dg-final { scan-assembler ".bss.used_bss,\"awR\"" } } */
+/* { dg-final { scan-assembler ".bss.used_bss2,\"awR\"" } } */
+/* { dg-final { scan-assembler ".data.used_data,\"awR\"" } } */
+/* { dg-final { scan-assembler ".data.used_data2,\"awR\"" } } */
+/* { dg-final { scan-assembler ".rodata.used_rodata,\"aR\"" } } */
+/* { dg-final { scan-assembler ".rodata.used_rodata2,\"aR\"" } } */
+/* { dg-final { scan-assembler ".bss.used_lcomm,\"awR\"" { target arm-*-* } } } */
+/* { dg-final { scan-assembler ".bss.used_lcomm2,\"awR\"" { target arm-*-* } } } */
+/* { dg-final { scan-assembler ".data.used_foo_sec,\"awR\"" } } */
+/* { dg-options "-ffunction-sections -fdata-sections" } */
+
+#include "attr-used-retain-1.c"
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr97979.c b/gcc/testsuite/gcc.c-torture/compile/pr97979.c
new file mode 100644
index 0000000..f4f88a4
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr97979.c
@@ -0,0 +1,7 @@
+/* PR tree-optimization/97979 */
+
+int
+foo (int x)
+{
+ return (x & 0x123) << -3;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr98087.c b/gcc/testsuite/gcc.c-torture/compile/pr98087.c
new file mode 100644
index 0000000..8cac770
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr98087.c
@@ -0,0 +1,14 @@
+/* PR c/98087 */
+
+struct S { char a; long long b; };
+struct T { struct S c[0]; char d; };
+void foo (int n)
+{
+ struct S a[n][0];
+ __builtin_clear_padding (a);
+ __builtin_clear_padding (&a);
+ struct S b[7][0];
+ __builtin_clear_padding (&b);
+ struct T c;
+ __builtin_clear_padding (&c);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/index-1.c b/gcc/testsuite/gcc.c-torture/execute/index-1.c
index b00090d..d96be4c 100644
--- a/gcc/testsuite/gcc.c-torture/execute/index-1.c
+++ b/gcc/testsuite/gcc.c-torture/execute/index-1.c
@@ -1,3 +1,5 @@
+/* { dg-skip-if "strict reloc overflow checking" { msp430-*-* } { "*" } { "-mcpu=msp430" "-mlarge"} } */
+
int a[] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr97836.c b/gcc/testsuite/gcc.c-torture/execute/pr97836.c
new file mode 100644
index 0000000..4585e1f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr97836.c
@@ -0,0 +1,17 @@
+int a;
+
+int b(int c) { return 0; }
+
+static int *d(int *e) {
+ if (a) {
+ a = a && b(*e);
+ }
+ return e;
+}
+
+int main() {
+ int f;
+ if (d(&f) != &f)
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr97888-1.c b/gcc/testsuite/gcc.c-torture/execute/pr97888-1.c
new file mode 100644
index 0000000..21fb6fc
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr97888-1.c
@@ -0,0 +1,24 @@
+/* PR tree-optimization/97888 */
+
+int a = 1, c = 4, d, e;
+
+int
+main ()
+{
+ int f = -173;
+ int b;
+ for (b = 0; b < 10; b++)
+ {
+ int g = f % (~0 && a), h = 0, i = 0;
+ if (g)
+ __builtin_unreachable ();
+ if (c)
+ h = f;
+ if (h > -173)
+ e = d / i;
+ f = h;
+ }
+ if (f != -173)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr97888-2.c b/gcc/testsuite/gcc.c-torture/execute/pr97888-2.c
new file mode 100644
index 0000000..4f06ce6
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr97888-2.c
@@ -0,0 +1,19 @@
+/* PR tree-optimization/97888 */
+
+__attribute__((noipa)) void
+foo (int i)
+{
+ if ((i % 7) >= 0)
+ {
+ if (i >= 0)
+ __builtin_abort ();
+ }
+}
+
+int
+main ()
+{
+ foo (-7);
+ foo (-21);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/20021029-1.c b/gcc/testsuite/gcc.dg/20021029-1.c
index f11a6e4..57c2b48 100644
--- a/gcc/testsuite/gcc.dg/20021029-1.c
+++ b/gcc/testsuite/gcc.dg/20021029-1.c
@@ -3,6 +3,7 @@
/* { dg-do compile { target fpic } } */
/* { dg-options "-O2 -fpic" } */
/* { dg-final { scan-assembler-not ".data.rel.ro.local" } } */
+/* { dg-final { scan-assembler-symbol-section {ar} {^\.(const|rodata)|\[RO\]} } } */
/* { dg-require-effective-target label_values } */
/* { dg-require-effective-target indirect_jumps } */
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-43.c b/gcc/testsuite/gcc.dg/Warray-bounds-43.c
index 8892921..0f521a7 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-43.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-43.c
@@ -5,20 +5,9 @@
#define NOIPA __attribute__ ((noipa))
-const char a0[] = "";
-const char a1[] = "1";
-const char a2[] = "12";
-const char a3[] = "123";
-const char a4[] = "1234";
-const char a5[] = "12345";
-const char a6[] = "123456";
-const char a7[] = "1234567";
-const char a8[] = "12345678";
const char a9[] = "123456789";
-void f (const char*, ...);
-
-int i0, i1, i2, i3, i4, i5, i6, i7, i8;
+void sink (const char*, ...);
NOIPA int g2 (int i)
{
@@ -28,7 +17,7 @@ NOIPA int g2 (int i)
const char *p1 = p0 + i;
const char *p2 = p1 + i;
- f (p0, p1, p2);
+ sink (p0, p1, p2);
return p2[8]; // { dg-warning "\\\[-Warray-bounds]" }
}
@@ -42,7 +31,7 @@ NOIPA int g3 (int i)
const char *p2 = p1 + i;
const char *p3 = p2 + i;
- f (p0, p1, p2, p3);
+ sink (p0, p1, p2, p3);
return p3[7]; // { dg-warning "\\\[-Warray-bounds]" }
}
@@ -57,7 +46,7 @@ NOIPA int g4 (int i)
const char *p3 = p2 + i;
const char *p4 = p3 + i;
- f (p0, p1, p2, p3, p4);
+ sink (p0, p1, p2, p3, p4);
return p4[6]; // { dg-warning "\\\[-Warray-bounds]" }
}
@@ -73,7 +62,7 @@ NOIPA int g5 (int i)
const char *p4 = p3 + i;
const char *p5 = p4 + i;
- f (p0, p1, p2, p3, p4, p5);
+ sink (p0, p1, p2, p3, p4, p5);
return p5[5];
}
@@ -90,7 +79,7 @@ NOIPA int g6 (int i)
const char *p5 = p4 + i;
const char *p6 = p5 + i;
- f (p0, p1, p2, p3, p4, p5, p6);
+ sink (p0, p1, p2, p3, p4, p5, p6);
return p6[4];
}
@@ -108,7 +97,7 @@ NOIPA int g7 (int i)
const char *p6 = p5 + i;
const char *p7 = p6 + i;
- f (p0, p1, p2, p3, p4, p5, p6, p7);
+ sink (p0, p1, p2, p3, p4, p5, p6, p7);
return p7[3];
}
@@ -127,7 +116,7 @@ NOIPA int g8 (int i)
const char *p7 = p6 + i;
const char *p8 = p7 + i;
- f (p0, p1, p2, p3, p4, p5, p6, p7, p8);
+ sink (p0, p1, p2, p3, p4, p5, p6, p7, p8);
return p8[2];
}
diff --git a/gcc/testsuite/gcc.dg/Wstring-compare-3.c b/gcc/testsuite/gcc.dg/Wstring-compare-3.c
new file mode 100644
index 0000000..d4d7121
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstring-compare-3.c
@@ -0,0 +1,106 @@
+/* PR middle-end/95673 - missing -Wstring-compare for an impossible strncmp test
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wstring-compare -ftrack-macro-expansion=0" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+extern int strcmp (const char*, const char*);
+extern int strncmp (const char*, const char*, size_t);
+
+void sink (int, ...);
+
+extern char a3[3];
+
+int nowarn_strcmp_one_use_ltz (int c)
+{
+ const char *s = c ? "1234" : a3;
+ int n = strcmp (s, "123");
+ return n < 0;
+}
+
+
+int nowarn_strcmp_one_use_eqnz (int c)
+{
+ const char *s = c ? "12345" : a3;
+ int n = strcmp (s, "123");
+ return n == 1;
+}
+
+
+int warn_strcmp_one_use_eqz (int c)
+{
+ const char *s = c ? "123456" : a3;
+ int n = strcmp (s, "123"); // { dg-warning "'strcmp' of a string of length 3 and an array of size 3 evaluates to nonzero" }
+ return n == 0; // { dg-message "in this expression" }
+}
+
+
+int warn_strcmp_one_use_bang (int c)
+{
+ const char *s = c ? "1234567" : a3;
+ int n = strcmp (s, "123"); // { dg-warning "'strcmp' of a string of length 3 and an array of size 3 evaluates to nonzero" }
+ return !n; // { dg-message "in this expression" }
+}
+
+
+int warn_strcmp_one_use_bang_bang (int c)
+{
+ const char *s = c ? "12345678" : a3;
+ int n = strcmp (s, "123"); // { dg-warning "'strcmp' of a string of length 3 and an array of size 3 evaluates to nonzero" }
+ return !!n; // { dg-message "in this expression" }
+}
+
+
+_Bool warn_one_use_bool (int c)
+{
+ const char *s = c ? "123456789" : a3;
+ int n = strcmp (s, "123"); // { dg-warning "'strcmp' of a string of length 3 and an array of size 3 evaluates to nonzero" }
+ return (_Bool)n; // { dg-message "in this expression" }
+}
+
+
+int warn_strcmp_one_use_cond (int c)
+{
+ const char *s = c ? "1234567890" : a3;
+ int n = strcmp (s, "123"); // { dg-warning "'strcmp' of a string of length 3 and an array of size 3 evaluates to nonzero" }
+ return n ? 3 : 5; // { dg-message "in this expression" }
+}
+
+
+int nowarn_strcmp_multiple_uses (int c)
+{
+ const char *s = c ? "1234" : a3;
+ int n = strcmp (s, "123");
+ sink (n < 0);
+ sink (n > 0);
+ sink (n <= 0);
+ sink (n >= 0);
+ sink (n + 1);
+ return n;
+}
+
+
+int warn_strcmp_multiple_uses (int c)
+{
+ const char *s = c ? "12345" : a3;
+ int n = strcmp (s, "123"); // { dg-warning "'strcmp' of a string of length 3 and an array of size 3 evaluates to nonzero" }
+ sink (n < 0);
+ sink (n > 0);
+ sink (n <= 0);
+ sink (n >= 0);
+ sink (n == 0); // { dg-message "in this expression" }
+ return n;
+}
+
+
+int warn_strncmp_multiple_uses (int c)
+{
+ const char *s = a3;
+ int n = strncmp (s, "1234", 4); // { dg-warning "'strncmp' of a string of length 4, an array of size 3 and bound of 4 evaluates to nonzero" }
+ sink (n < 0);
+ sink (n > 0);
+ sink (n <= 0);
+ sink (n >= 0);
+ sink (n == 0); // { dg-message "in this expression" }
+ return n;
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-11.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-11.c
index f5dac45..ec3c97e 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-11.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-11.c
@@ -72,7 +72,7 @@ void test_memset_array_range_cst_off (void)
{
T (SR (-7, 7), 1, 7);
T (SR (-1, 1), 1, 7);
- T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-*} } */
+ T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
T (SR ( 1, 2), 1, 1);
T (SR ( 1, 2), 1, 5);
@@ -147,7 +147,7 @@ void test_memcpy_array_range_cst_off (const void *s)
{
T (SR (-7, 7), 1, 7);
T (SR (-1, 1), 1, 7);
- T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-*} } */
+ T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
T (SR ( 1, 2), 1, 1);
T (SR ( 1, 2), 1, 5);
@@ -224,7 +224,7 @@ void test_strcpy_array_range_cst_off (const char *s)
{
T (SR (-7, 7), 1, 6);
T (SR (-1, 1), 1, 6);
- T (SR (-1, 1), 1, 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-*} } */
+ T (SR (-1, 1), 1, 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
T (SR ( 1, 2), 1, 0);
T (SR ( 1, 2), 1, 1);
T (SR ( 1, 2), 1, 4);
@@ -290,7 +290,7 @@ void test_strncpy_array_range_cst_off (const char *s)
{
T (SR (-7, 7), 1, 7);
T (SR (-1, 1), 1, 7);
- T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-*} } */
+ T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
T (SR ( 1, 2), 1, 1);
T (SR ( 1, 2), 1, 5);
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-12.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-12.c
index 1e67b5f..7c3dc8c 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-12.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-12.c
@@ -25,7 +25,9 @@ void test_memcpy_array_cst_range_off (const void *s)
T (d + UR (1, 2), 5);
T (d + UR (0, 1), 6);
- T (d + UR (0, 1), 7); /* { dg-warning ".memcpy. writing 6 bytes into a region of size 5 overflows the destination" "pr89428" { xfail *-*-* } } */
+ /* The warning below should be "writing" but the [0, 1] range
+ is somehow lost and get_range_info() returns VR_VARYING. */
+ T (d + UR (0, 1), 7); /* { dg-warning ".memcpy. writing 7 bytes into a region of size 6 overflows the destination" "pr89428" { xfail *-*-* } } */
T (d + UR (1, 2), 6); /* { dg-warning ".memcpy. writing 6 bytes into a region of size 5 overflows the destination" } */
T (d + UR (1, 2), 7); /* { dg-warning "writing 7 bytes into a region of size 5 " } */
@@ -48,7 +50,8 @@ void test_memcpy_array_range_range_off (const void *s)
char *d = ga7 + UR (0, 1);
T (d + SR (-1, 0), 1);
T (d + SR (-1, 0), 7);
- T (d + SR (-1, 0), 9); /* { dg-warning "writing 1 byte into a region of size 0 " "pr89350" { xfail *-*-* } } */
+ T (d + SR (-1, 0), 8); /* { dg-warning "writing 8 bytes into a region of size 7 " } */
+ T (d + SR (-1, 0), 9); /* { dg-warning "writing 9 bytes into a region of size 7 " "pr89350" } */
}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-17.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-17.c
index fb81420..9c05d04 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-17.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-17.c
@@ -13,7 +13,7 @@ void sink (void*);
void call_copy_n (const char *s)
{
- char a[7]; // { dg-message "declared here" }
+ char a[7]; // { dg-message "at offset 7 into destination object 'a'" }
copy_n (a, "1234567", 7);
sink (a);
}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-27.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-27.c
index 37c1ca2..607c279 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-27.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-27.c
@@ -261,8 +261,7 @@ void test_strcpy_warn (const char *s)
that the conversion from signed int to size_t doesn't prevent
the detection. */
int n = strlen (a);
- char *t = (char*)calloc (n, 1); // { dg-message "at offset 0 to an object with size 3 allocated by 'calloc' here" "calloc note 1" { xfail *-*-* } }
- // { dg-message "at offset 0 to an object with size at most 3 allocated by 'calloc' here" "calloc note 2" { target *-*-* } .-1 }
+ char *t = (char*)calloc (n, 1); // { dg-message "destination object of size 3 allocated by 'calloc'" "note" }
strcpy (t, a); // { dg-warning "writing 4 bytes into a region of size (between 0 and )?3 " }
sink (t);
@@ -271,8 +270,7 @@ void test_strcpy_warn (const char *s)
{
const char a[] = "1234";
size_t n = strlen (a);
- char *t = (char*)malloc (n); // { dg-message "at offset 0 to an object with size 4 allocated by 'malloc' here" "malloc note 1" { xfail *-*-* } }
- // { dg-message "at offset 0 to an object with size at most 4 allocated by 'malloc' here" "malloc note 2" { target *-*-* } .-1 }
+ char *t = (char*)malloc (n); // { dg-message "destination object of size 4 allocated by 'malloc'" "note" }
strcpy (t, a); // { dg-warning "writing 5 bytes into a region of size (between 0 and )?4 " }
sink (t);
}
@@ -280,14 +278,14 @@ void test_strcpy_warn (const char *s)
// Exercise PR middle-end/85484.
{
size_t len = strlen (s);
- char vla[len]; // { dg-message "at offset 0 to an object declared here" "vla note" }
+ char vla[len]; // { dg-message "destination object 'vla'" "vla note" }
strcpy (vla, s); // { dg-warning "writing one too many bytes into a region of a size that depends on 'strlen'" }
sink (vla);
}
{
size_t n = strlen (s);
- char *t = (char*)malloc (n); // { dg-message "at offset 0 to an object allocated by 'malloc' here" "malloc note" }
+ char *t = (char*)malloc (n); // { dg-message "allocated by 'malloc'" "malloc note" }
strcpy (t, s); // { dg-warning "writing one too many bytes into a region of a size that depends on 'strlen'" }
sink (t);
}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-28.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-28.c
index be7f51a..5009fb5 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-28.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-28.c
@@ -40,27 +40,27 @@ void same_size_and_offset_idx_cst (void)
const size_t n = UR (2, 3);
T (n, n, -4); // { dg-warning "writing 1 byte into a region of size 0" }
- // { dg-message "at offset \\\[-2, -1] to an object with size between 2 and 3 allocated by 'alloc1'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[-2, -1] into destination object of size \\\[2, 3] allocated by 'alloc1'" "note" { target *-*-* } .-1 }
T (n, n, -3);
T (n, n, -2);
T (n, n, -1);
T (n, n, 0);
T (n, n, 1); // { dg-warning "writing 1 byte into a region of size 0" }
- // { dg-message "at offset \\\[3, 4] to an object with size between 2 and 3 allocated by 'alloc1'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset 3 into destination object of size \\\[2, 3] allocated by 'alloc1'" "note" { target *-*-* } .-1 }
}
{
const size_t n = UR (3, 4);
T (n, n, -5); // { dg-warning "writing 1 byte into a region of size 0" }
- // { dg-message "at offset \\\[-2, -1] to an object with size between 3 and 4 allocated by 'alloc1'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[-2, -1] into destination object of size \\\[3, 4] allocated by 'alloc1'" "note" { target *-*-* } .-1 }
T (n, n, -4);
T (n, n, -3);
T (n, n, -2);
T (n, n, -1);
T (n, n, 0);
T (n, n, 1); // { dg-warning "writing 1 byte into a region of size 0" }
- // { dg-message "at offset \\\[4, 5] to an object with size between 3 and 4 allocated by 'alloc1'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset 4 into destination object of size \\\[3, 4] allocated by 'alloc1'" "note" { target *-*-* } .-1 }
}
{
@@ -84,15 +84,15 @@ void different_size_and_offset_idx_cst (void)
const size_t i = UR (1, 2);
T (n, i, -4); // { dg-warning "writing 1 byte into a region of size 0" }
- // { dg-message "at offset \\\[-3, -2] to an object with size between 2 and 3 allocated by 'alloc1'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[-3, -2] into destination object of size \\\[2, 3] allocated by 'alloc1'" "note" { target *-*-* } .-1 }
T (n, i, -3); // { dg-warning "writing 1 byte into a region of size 0" }
- // { dg-message "at offset \\\[-2, -1] to an object with size between 2 and 3 allocated by 'alloc1'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[-2, -1] into destination object of size \\\[2, 3] allocated by 'alloc1'" "note" { target *-*-* } .-1 }
T (n, i, -2);
T (n, i, -1);
T (n, i, 0);
T (n, i, 1);
T (n, i, 2); // { dg-warning "writing 1 byte into a region of size 0" }
- // { dg-message "at offset \\\[3, 4] to an object with size between 2 and 3 allocated by 'alloc1'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset 3 into destination object of size \\\[2, 3] allocated by 'alloc1'" "note" { target *-*-* } .-1 }
}
{
@@ -100,20 +100,20 @@ void different_size_and_offset_idx_cst (void)
const size_t i = UR (2, 5);
T (n, i, -6); // { dg-warning "writing 1 byte into a region of size 0" }
- // { dg-message "at offset \\\[-4, -1] to an object with size between 3 and 4 allocated by 'alloc1'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[-4, -2] into destination object of size \\\[3, 4] allocated by 'alloc1'" "note" { target *-*-* } .-1 }
- /* The offsets -5 and -4 are both necessarily invalid even if the sum
- (i - 5) and (i - 4) are (or could be) in bounds because they imply
- that the intermediate offset (p + i) is out of bounds. */
- T (n, i, -5); // { dg-warning "" "intermediate offset" { xfail *-*-* } }
- T (n, i, -4); // { dg-warning "" "intermediate offset" { xfail *-*-* } }
+ /* The offset -5 is necessarily invalid even if the sum (i - 5) is (or
+ could be) in bounds because it implies that the intermediate offset
+ (p + i) is out of bounds. */
+ T (n, i, -5); // { dg-warning "writing 1 byte into a region of size 0 " }
+ T (n, i, -4);
T (n, i, -3);
T (n, i, -2);
T (n, i, -1);
T (n, i, 0);
T (n, i, 1);
T (n, i, 2); // { dg-warning "writing 1 byte into a region of size 0" }
- // { dg-message "at offset \\\[4, 7] to an object with size between 3 and 4 allocated by 'alloc1'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset 4 into destination object of size \\\[3, 4] allocated by 'alloc1'" "note" { target *-*-* } .-1 }
}
}
@@ -133,11 +133,8 @@ void different_size_and_offset_idx_var (void)
T (n, i, SR ( 0, 1));
T (n, i, SR ( 1, 2));
T (n, i, SR ( 2, 3));
- /* The warning is issued below but the offset and the size in
- the note are wrong. See the FIXME in compute_objsize(). */
T (n, i, SR ( 3, 4)); // { dg-warning "\\\[-Wstringop-overflow" }
- // { dg-message "at offset 4 to an object with size between 3 and 4 allocated by 'alloc1'" "pr92940 note: offset addition" { xfail *-*-* } .-1 }
- // { dg-message "at offset . to an object with size . allocated by 'alloc1'" "note: offset addition" { target *-*-* } .-2 }
+ // { dg-message "at offset 4 into destination object of size \\\[3, 4] allocated by 'alloc1'" "pr92940 note: offset addition" { target *-*-* } .-1 }
}
}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-29.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-29.c
index c011d05..f13abbd 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-29.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-29.c
@@ -11,7 +11,7 @@ void sink (void*);
void direct_call (void)
{
- char *q = allocfn (0); // { dg-message "at offset 0 to an object with size 0 allocated by 'allocfn'" }
+ char *q = allocfn (0); // { dg-message "object of size 0 allocated by 'allocfn'" "note" }
q[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
sink (q);
}
@@ -20,7 +20,7 @@ void direct_call (void)
void local_ptr_call (void)
{
allocfn_t *ptr = allocfn;
- char *q = ptr (1); // { dg-message "at offset -1 to an object with size 1 allocated by 'allocfn'" }
+ char *q = ptr (1); // { dg-message "at offset -1 into destination object of size 1 allocated by 'allocfn'" "note" }
q[0] = 0;
q[-1] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
sink (q);
@@ -32,7 +32,7 @@ void global_ptr_call (void)
extern allocfn_t *ptralloc;
allocfn_t *ptr = ptralloc;
- char *q = ptr (2); // { dg-message "at offset 3 to an object with size 2 allocated by 'ptralloc'" }
+ char *q = ptr (2); // { dg-message "at offset 3 into destination object of size 2 allocated by 'ptralloc'" "note" }
q[0] = 0;
q[1] = 1;
q[3] = 3; // { dg-warning "\\\[-Wstringop-overflow" }
@@ -44,7 +44,7 @@ void global_ptr_array_call (void)
extern allocfn_t * (arralloc[]);
allocfn_t *ptr = arralloc[0];
- char *q = ptr (2); // { dg-message "at offset 3 to an object with size 2 allocated by 'ptr'" }
+ char *q = ptr (2); // { dg-message "at offset 3 into destination object of size 2 allocated by 'ptr'" "note" }
q[0] = 1;
q[1] = 2;
q[3] = 3; // { dg-warning "\\\[-Wstringop-overflow" }
@@ -56,7 +56,7 @@ struct S { allocfn_t *ptralloc; };
void member_ptr_call (struct S *p)
{
- char *q = p->ptralloc (3); // { dg-message "at offset 5 to an object with size 3 allocated by 'ptralloc' here" }
+ char *q = p->ptralloc (3); // { dg-message "at offset 5 into destination object of size 3 allocated by 'ptralloc'" "note" }
q[0] = 0;
q[1] = 1;
q[2] = 2;
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-37.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-37.c
index 46f8fed..d9cf32d 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-37.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-37.c
@@ -67,7 +67,7 @@ void* warn_malloc_3_5 (const char *s, unsigned n)
{
if (n < 3 || 5 < n)
n = 3;
- char *p = (char*)malloc (n); // { dg-message "at offset 1 into destination object of size \\\[3, 5] allocated by 'malloc'" }
+ char *p = (char*)malloc (n); // { dg-message "at offset 1 into destination object of size \\\[3, 5] allocated by 'malloc'" "note" }
// The size below should be a range like the one above.
strncpy (p + 1, s, 5); // { dg-warning "writing 5 bytes into a region of size 4 " }
return p;
@@ -89,7 +89,7 @@ void* warn_usr_alloc_3_5 (UsrAlloc *usr_alloc, const char *s, unsigned n)
{
if (n < 3 || 5 < n)
n = 3;
- char *p = (char*)usr_alloc (n, 3); // { dg-message "at offset 1 into destination object of size \\\[9, 15] allocated by 'usr_alloc'" }
+ char *p = (char*)usr_alloc (n, 3); // { dg-message "at offset 1 into destination object of size \\\[9, 15] allocated by 'usr_alloc'" "note" }
// The size below should be a range like the one above.
strncpy (p + 1, s, 15); // { dg-warning "writing 15 bytes into a region of size 14 " }
return p;
@@ -179,67 +179,67 @@ void test_note (const char *s)
extern void sink (void*);
{
- char a[1][1][2]; // { dg-message "destination object" }
+ char a[1][1][2]; // { dg-message "destination object" "note" }
strncpy (a[0][0], s, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
sink (a);
}
{
- char a[1][1][2]; // { dg-message "at offset 2 into " }
+ char a[1][1][2]; // { dg-message "at offset 2 into " "note" }
strncpy (a[0][1], s, 3); // { dg-warning "writing 3 bytes into a region of size 0 " }
sink (a);
}
{
- char a[1][2][2]; // { dg-message "destination object" }
+ char a[1][2][2]; // { dg-message "destination object" "note" }
strncpy (a[0][0], s, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
sink (a);
}
{
- char a[1][2][2]; // { dg-message "at offset 2 into " }
+ char a[1][2][2]; // { dg-message "at offset 2 into " "note" }
strncpy (a[0][1], s, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
sink (a);
}
{
- char a[1][2][2]; // { dg-message "at offset 4 into " }
+ char a[1][2][2]; // { dg-message "at offset 4 into " "note" }
strncpy (a[1][0], s, 3); // { dg-warning "writing 3 bytes into a region of size 0 " }
sink (a);
}
{
- char a[2][1][2]; // { dg-message "at offset 2 into " }
+ char a[2][1][2]; // { dg-message "at offset 2 into " "note" }
strncpy (a[0][1], s, 3); // { dg-warning "writing 3 bytes into a region of size 0 " }
sink (a);
}
{
- char a[2][1][2]; // { dg-message "at offset 2 into " }
+ char a[2][1][2]; // { dg-message "at offset 2 into " "note" }
strncpy (a[1][0], s, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
sink (a);
}
{
- char a[2][2][3]; // { dg-message "at offset 9 into " }
+ char a[2][2][3]; // { dg-message "at offset 9 into " "note" }
strncpy (a[1][1], s, 4); // { dg-warning "writing 4 bytes into a region of size 3 " }
sink (a);
}
{
- char a[2][3][3]; // { dg-message "at offset 12 into " }
+ char a[2][3][3]; // { dg-message "at offset 12 into " "note" }
strncpy (a[1][1], s, 5); // { dg-warning "writing 5 bytes into a region of size 3 " }
sink (a);
}
{
- char a[2][3][3]; // { dg-message "at offset 12 into " }
+ char a[2][3][3]; // { dg-message "at offset 12 into " "note" }
strncpy (a[1][1], s, 6); // { dg-warning "writing 6 bytes into a region of size 3 " }
sink (a);
}
{
- char a[2][3][3]; // { dg-message "at offset 15 into " }
+ char a[2][3][3]; // { dg-message "at offset 15 into " "note" }
strncpy (a[1][2], s, 7); // { dg-warning "writing 7 bytes into a region of size 3 " }
sink (a);
}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-46.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-46.c
index a4d78b2..b126fcb 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-46.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-46.c
@@ -53,7 +53,7 @@ void nowarn_memchr_anti_range_memset_cst (const void *s, size_t n)
void warn_memchr_cst_memset_cst (const void *s)
{
- char *p = malloc (4); // { dg-message "at offset \\\[0, 4] into destination object of size 4 " "note" }
+ char *p = malloc (4); // { dg-message "destination object of size 4 " "note" }
sink (p);
p = memchr (p, '1', 4);
@@ -62,7 +62,7 @@ void warn_memchr_cst_memset_cst (const void *s)
void warn_memchr_var_memset_cst (const void *s, unsigned n)
{
- char *p = malloc (4); // { dg-message "at offset \\\[0, 4] into destination object of size 4 " "note" }
+ char *p = malloc (4); // { dg-message "destination object of size 4 " "note" }
sink (p);
p = memchr (p, '1', n);
@@ -79,9 +79,9 @@ void warn_memchr_var_memset_range (const void *s, unsigned n)
as in the first two notes. The exact value probably isn't too
important. */
char *p0 = malloc (UR (5, 7));
- // { dg-message "at offset \\\[0, 7] into destination object of size \\\[5, 7]" "note" { target *-*-* } .-1 }
- // { dg-message "at offset \\\[1, 7] into destination object of size \\\[5, 7]" "note" { target *-*-* } .-2 }
- // { dg-message "at offset \\\[2, 7] into destination object of size \\\[5, 7]" "note" { target *-*-* } .-3 }
+ // { dg-message ": destination object of size \\\[5, 7]" "note 1" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[1, 7] into destination object of size \\\[5, 7]" "note 2" { target *-*-* } .-2 }
+ // { dg-message "at offset \\\[2, 7] into destination object of size \\\[5, 7]" "note 3" { target *-*-* } .-3 }
sink (p0);
char *p1 = memchr (p0, '1', n);
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c
index 02b14ee..cb2c329 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c
@@ -26,7 +26,7 @@ void nowarn_c32 (char c)
void warn_c32 (char c)
{
- extern char warn_a32[32]; // { dg-message "at offset 32 to object 'warn_a32' with size 32" }
+ extern char warn_a32[32]; // { dg-message "at offset 32 into destination object 'warn_a32' of size 32" "note" }
void *p = warn_a32 + 1;
*(C32*)p = (C32){ c }; // { dg-warning "writing 1 byte into a region of size 0" }
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-54.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-54.c
index 26568f8..f5929c9 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-54.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-54.c
@@ -15,7 +15,7 @@ void sink (void*);
void char_flexarray_cst_off_cst_size (void)
{
extern struct { char n, a[]; }
- caxcc; // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'caxcc'" }
+ caxcc; // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'caxcc'" "note" }
char *p = caxcc.a;
size_t idx = DIFF_MAX - 4;
@@ -38,7 +38,7 @@ void char_flexarray_cst_off_cst_size (void)
void char_flexarray_var_off_cst_size (ptrdiff_t idx)
{
extern struct { char n, a[]; }
- caxvc; // { dg-message "destination object 'caxvc'" }
+ caxvc; // { dg-message "destination object 'caxvc'" "note" }
char *p = caxvc.a;
@@ -55,7 +55,7 @@ void char_flexarray_var_off_cst_size (ptrdiff_t idx)
void char_flexarray_var_off_var_size (size_t n, ptrdiff_t idx)
{
extern struct { char n, a[]; }
- caxvv; // { dg-message "destination object 'caxvv'" }
+ caxvv; // { dg-message "destination object 'caxvv'" "note" }
char *p = caxvv.a;
@@ -76,7 +76,7 @@ void char_flexarray_var_off_var_size (size_t n, ptrdiff_t idx)
void alloc_array_var_off_cst_size (size_t n, ptrdiff_t idx)
{
struct { char n, a[]; }
- *p = __builtin_malloc (n); // { dg-message "at offset \\d+ into destination object" }
+ *p = __builtin_malloc (n); // { dg-message "at offset \\d+ into destination object" "note" }
if (idx < DIFF_MAX - 4)
idx = DIFF_MAX - 4;
@@ -91,7 +91,7 @@ void alloc_array_var_off_cst_size (size_t n, ptrdiff_t idx)
void int_array_cst_off_cst_size (void)
{
extern struct { int n, a[]; }
- iaxc; // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'iaxc'" }
+ iaxc; // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'iaxc'" "note" }
int *p = iaxc.a;
size_t idx = DIFF_MAX / sizeof *p - 1;
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-58.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-58.c
new file mode 100644
index 0000000..b81186c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-58.c
@@ -0,0 +1,260 @@
+/* PR middle-end/92936 - missing warning on a past-the-end store to a PHI
+ Exercise warnings for writing into one of two or more declared objects.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wno-array-bounds -ftrack-macro-expansion=0" } */
+
+#include "range.h"
+
+#define INT_MAX __INT_MAX__
+
+extern void* memset (void*, int, size_t);
+#define memset(d, c, n) sink (memset (d, c, n))
+
+void sink (int, ...);
+#define sink(...) sink (0, __VA_ARGS__)
+
+volatile int cond1, cond2;
+
+extern char ca0[0], ca1[1], ca2[2], ca3[3], ca4[4],
+ ca5[5], ca6[6], ca7[7], ca8[8], ca9[9], cax[];
+
+#define CHOOSE_DECL_2(n1, n2) \
+ (cond1 ? ca ## n1 : ca ## n2)
+#define CHOOSE_DECL_3(n1, n2, n3) \
+ (cond1 < 0 ? ca ## n1 : 0 < cond1 ? ca ## n2 : ca ## n3)
+
+
+void memset_decl_2 (void)
+{
+ {
+ char *p0_1 = CHOOSE_DECL_2 (0, 1);
+
+ memset (p0_1, 0, 0);
+ /* Writing more than the smallest destination should trigger a "may
+ write" warning if the access is unconditionally reachable from
+ the block where the pointer to either object is assigned. */
+ memset (p0_1, 0, 1);
+ memset (p0_1, 0, 2); // { dg-warning "memset' writing 2 bytes into a region of size 1 " }
+ memset (p0_1, 0, 9); // { dg-warning "memset' writing 9 bytes into a region of size 1 " }
+ }
+
+ {
+ char *p0_x = CHOOSE_DECL_2 (0, x);
+
+ memset (p0_x, 0, 0);
+ memset (p0_x, 0, 1);
+ memset (p0_x, 0, 2);
+ memset (p0_x, 0, 9);
+ }
+
+ {
+ char *p3_5 = CHOOSE_DECL_2 (3, 5);
+
+ memset (p3_5, 0, 1);
+ memset (p3_5, 0, 3);
+ memset (p3_5, 0, 4);
+ memset (p3_5, 0, 5);
+ memset (p3_5, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ char *p5_3 = CHOOSE_DECL_2 (5, 3);
+
+ memset (p5_3, 0, 3);
+ memset (p5_3, 0, 4);
+ memset (p5_3, 0, 5);
+ memset (p5_3, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ char *px_3 = CHOOSE_DECL_2 (x, 3);
+
+ memset (px_3, 0, 1);
+ memset (px_3, 0, 3);
+ memset (px_3, 0, 4);
+ memset (px_3, 0, 1234);
+ }
+
+ {
+ char *p5_x = CHOOSE_DECL_2 (5, x);
+
+ memset (p5_x, 0, 1);
+ memset (p5_x, 0, 5);
+ memset (p5_x, 0, 6);
+ memset (p5_x, 0, 1234);
+ }
+
+}
+
+
+void memset_decl_3 (void)
+{
+ {
+ char *p0_1_2 = CHOOSE_DECL_3 (0, 1, 2);
+ memset (p0_1_2, 0, 0);
+ memset (p0_1_2, 0, 1);
+ memset (p0_1_2, 0, 2);
+ memset (p0_1_2, 0, 3); // { dg-warning "memset' writing 3 bytes into a region of size 2 " }
+ memset (p0_1_2, 0, 9); // { dg-warning "memset' writing 9 bytes into a region of size 2 " }
+ }
+
+ {
+ char *p0_2_x = CHOOSE_DECL_3 (0, 2, x);
+
+ memset (p0_2_x, 0, 0);
+ memset (p0_2_x, 0, 1);
+ memset (p0_2_x, 0, 3);
+ memset (p0_2_x, 0, 9);
+ }
+
+ {
+ char *p3_4_5 = CHOOSE_DECL_3 (3, 4, 5);
+
+ memset (p3_4_5, 0, 3);
+ memset (p3_4_5, 0, 4);
+ memset (p3_4_5, 0, 5);
+ memset (p3_4_5, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ char *p5_3_4 = CHOOSE_DECL_3 (5, 3, 4);
+
+ memset (p5_3_4, 0, 3);
+ memset (p5_3_4, 0, 4);
+ memset (p5_3_4, 0, 5);
+ memset (p5_3_4, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ char *p9_8_7 = CHOOSE_DECL_3 (9, 8, 7);
+
+ memset (p9_8_7, 0, 7);
+ memset (p9_8_7, 0, 8);
+ memset (p9_8_7, 0, 9);
+ memset (p9_8_7, 0, 10); // { dg-warning "memset' writing 10 bytes into a region of size 9 " }
+ }
+}
+
+
+/* Verify conditionally writing into one of two objects with the same
+ size. */
+
+void memset_decl_2_same_size (int i)
+{
+ {
+ char a4_1[4], a4_2[4];
+ char *p4 = cond1 ? a4_1 : a4_2;
+
+ memset (p4, 0, 1);
+ memset (p4, 0, 2);
+ memset (p4, 0, 3);
+ memset (p4, 0, 4);
+ memset (p4, 0, 5); // { dg-warning "memset' writing 5 bytes into a region of size 4" }
+ }
+
+ {
+ char a4_1[4]; // { dg-message "destination object 'a4_1" "note" }
+ char a4_2[4]; // { dg-message "destination object 'a4_2" "note" }
+ char *p4 = cond1 ? a4_1 : a4_2;
+ char *p4_i = p4 + i;
+
+ memset (p4_i, 0, 5); // { dg-warning "memset' writing 5 bytes into a region of size 4" }
+ }
+
+ {
+ if (i < 1)
+ i = 1;
+
+ char a4_1[4]; // { dg-message "at offset \\\[1, 4] into destination object 'a4_1" "note" }
+ char a4_2[4]; // { dg-message "at offset \\\[1, 4] into destination object 'a4_2" "note" }
+ char *p4 = cond1 ? a4_1 : a4_2;
+ char *p4_i = p4 + i;
+
+ memset (p4_i, 0, 3);
+ memset (p4_i, 0, 4); // { dg-warning "memset' writing 4 bytes into a region of size 3 " }
+ }
+}
+
+
+void memset_decl_2_off (void)
+{
+ int i1 = SR (1, INT_MAX);
+ int i2 = SR (2, INT_MAX);
+
+ {
+ char a5[5]; // { dg-warning "at offset [1, 5] into destination object 'a5'
+ char a7[7]; // { dg-warning "at offset [2, 7] into destination object 'a7'
+ char *p5_p1 = a5 + i1;
+ char *p7_p2 = a7 + i2;
+ char *p5_7 = cond1 ? p5_p1 : p7_p2;
+
+ memset (p5_7, 0, 1);
+ memset (p5_7, 0, 2);
+ memset (p5_7, 0, 3);
+ memset (p5_7, 0, 4);
+ memset (p5_7, 0, 5);
+ memset (p5_7, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ int i3 = SR (3, INT_MAX);
+
+ {
+ char a5[5];
+ // { dg-message "at offset \\\[3, 5] into destination object 'a5'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[2, 5] into destination object 'a5'" "note" { target *-*-* } .-2 }
+ // { dg-message "at offset \\\[1, 5] into destination object 'a5'" "note" { target *-*-* } .-3 }
+ // { dg-message ": destination object 'a5'" "note" { target *-*-* } .-4 }
+ char a9[9];
+ // { dg-message "at offset \\\[4, 9] into destination object 'a9'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[3, 9] into destination object 'a9'" "note" { target *-*-* } .-2 }
+ // { dg-message "at offset \\\[2, 9] into destination object 'a9'" "note" { target *-*-* } .-3 }
+ // { dg-message ": destination object 'a9'" "note" { target *-*-* } .-4 }
+ char *p5_p2 = a5 + i2; // 3 bytes left
+ char *p9_p3 = a9 + i3; // 6 bytes left
+ char *p =
+ cond1 ? p5_p2 : p9_p3; // [3 - 6] bytes left
+ char *q = p + i1; // [2 - 5] bytes left
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5);
+ memset (q, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5" }
+
+ --q; // [3 - 6] bytes left
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5);
+ memset (q, 0, 6);
+ memset (q, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6" }
+
+ --q; // [4 - 7] bytes left
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5);
+ memset (q, 0, 6);
+ memset (q, 0, 7);
+ memset (q, 0, 8); // { dg-warning "memset' writing 8 bytes into a region of size 7" }
+
+ int m1_x = SR (-1, INT_MAX);
+ int m2_x = SR (-2, INT_MAX);
+
+ q += cond2 ? m1_x : m2_x; // [5 - 9] bytes left
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5);
+ memset (q, 0, 6);
+ memset (q, 0, 7);
+ memset (q, 0, 8);
+ memset (q, 0, 9);
+ memset (q, 0, 10); // { dg-warning "memset' writing 10 bytes into a region of size 9" }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-59.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-59.c
new file mode 100644
index 0000000..c45a92d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-59.c
@@ -0,0 +1,267 @@
+/* PR middle-end/92936 - missing warning on a past-the-end store to a PHI
+ Exercise warnings for writing into one of two or more allocated objects.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wno-array-bounds -ftrack-macro-expansion=0" } */
+
+#include "range.h"
+
+#define INT_MAX __INT_MAX__
+
+extern void* malloc (size_t);
+extern void* memset (void*, int, size_t);
+#define memset(d, c, n) sink (memset (d, c, n))
+
+void sink (int, ...);
+#define sink(...) sink (0, __VA_ARGS__)
+
+volatile int cond1, cond2, x;
+
+#define CHOOSE_MALLOC_2(n1, n2) \
+ (cond1 ? malloc (n1) : malloc (n2))
+#define CHOOSE_MALLOC_3(n1, n2, n3) \
+ (cond1 < 0 ? malloc (n1) : 0 < cond1 ? malloc (n2) : malloc (n3))
+
+
+void memset_malloc_2 (void)
+{
+ {
+ char *p0_1 = CHOOSE_MALLOC_2 (0, 1);
+
+ memset (p0_1, 0, 0);
+ /* Writing more than the smallest destination should trigger a "may
+ write" warning if the access is unconditionally reachable from
+ the block where the pointer to either object is assigned. */
+ memset (p0_1, 0, 1);
+ memset (p0_1, 0, 2); // { dg-warning "memset' writing 2 bytes into a region of size 1 " }
+ memset (p0_1, 0, 9); // { dg-warning "memset' writing 9 bytes into a region of size 1 " }
+ }
+
+ {
+ char *p0_x = CHOOSE_MALLOC_2 (0, x);
+
+ memset (p0_x, 0, 0);
+ memset (p0_x, 0, 1);
+ memset (p0_x, 0, 2);
+ memset (p0_x, 0, 12345);
+ }
+
+ {
+ char *px_x = CHOOSE_MALLOC_2 (x, x);
+
+ memset (px_x, 0, 0);
+ memset (px_x, 0, 1);
+ memset (px_x, 0, 2);
+ memset (px_x, 0, 12345);
+ }
+
+ {
+ char *p3_5 = CHOOSE_MALLOC_2 (3, 5);
+
+ memset (p3_5, 0, 1);
+ memset (p3_5, 0, 3);
+ memset (p3_5, 0, 4);
+ memset (p3_5, 0, 5);
+ memset (p3_5, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ char *p5_3 = CHOOSE_MALLOC_2 (5, 3);
+
+ memset (p5_3, 0, 3);
+ memset (p5_3, 0, 4);
+ memset (p5_3, 0, 5);
+ memset (p5_3, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ char *px_3 = CHOOSE_MALLOC_2 (x, 3);
+
+ memset (px_3, 0, 1);
+ memset (px_3, 0, 3);
+ memset (px_3, 0, 4);
+ memset (px_3, 0, 1234);
+ }
+
+ {
+ char *p5_x = CHOOSE_MALLOC_2 (5, x);
+
+ memset (p5_x, 0, 1);
+ memset (p5_x, 0, 5);
+ memset (p5_x, 0, 6);
+ memset (p5_x, 0, 1234);
+ }
+
+}
+
+
+void memset_malloc_3 (void)
+{
+ {
+ char *p0_1_2 = CHOOSE_MALLOC_3 (0, 1, 2);
+ memset (p0_1_2, 0, 0);
+ memset (p0_1_2, 0, 1);
+ memset (p0_1_2, 0, 2);
+ memset (p0_1_2, 0, 3); // { dg-warning "memset' writing 3 bytes into a region of size 2 " }
+ memset (p0_1_2, 0, 9); // { dg-warning "memset' writing 9 bytes into a region of size 2 " }
+ }
+
+ {
+ char *p0_2_x = CHOOSE_MALLOC_3 (0, 2, x);
+
+ memset (p0_2_x, 0, 0);
+ memset (p0_2_x, 0, 1);
+ memset (p0_2_x, 0, 3);
+ memset (p0_2_x, 0, 9);
+ }
+
+ {
+ char *p3_4_5 = CHOOSE_MALLOC_3 (3, 4, 5);
+
+ memset (p3_4_5, 0, 3);
+ memset (p3_4_5, 0, 4);
+ memset (p3_4_5, 0, 5);
+ memset (p3_4_5, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ char *p5_3_4 = CHOOSE_MALLOC_3 (5, 3, 4);
+
+ memset (p5_3_4, 0, 3);
+ memset (p5_3_4, 0, 4);
+ memset (p5_3_4, 0, 5);
+ memset (p5_3_4, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ char *p9_8_7 = CHOOSE_MALLOC_3 (9, 8, 7);
+
+ memset (p9_8_7, 0, 7);
+ memset (p9_8_7, 0, 8);
+ memset (p9_8_7, 0, 9);
+ memset (p9_8_7, 0, 10); // { dg-warning "memset' writing 10 bytes into a region of size 9 " }
+ }
+}
+
+
+/* Verify conditionally writing into one of two objects with the same
+ size. */
+
+void memset_malloc_2_same_size (int i)
+{
+ {
+ char a4_1[4], a4_2[4];
+ char *p4 = cond1 ? a4_1 : a4_2;
+
+ memset (p4, 0, 1);
+ memset (p4, 0, 2);
+ memset (p4, 0, 3);
+ memset (p4, 0, 4);
+ memset (p4, 0, 5); // { dg-warning "memset' writing 5 bytes into a region of size 4" }
+ }
+
+ {
+ char a4_1[4]; // { dg-message "destination object 'a4_1" "note" }
+ char a4_2[4]; // { dg-message "destination object 'a4_2" "note" }
+ char *p4 = cond1 ? a4_1 : a4_2;
+ char *p4_i = p4 + i;
+
+ memset (p4_i, 0, 5); // { dg-warning "memset' writing 5 bytes into a region of size 4" }
+ }
+
+ {
+ if (i < 1)
+ i = 1;
+
+ char a4_1[4]; // { dg-message "at offset \\\[1, 4] into destination object 'a4_1" "note" }
+ char a4_2[4]; // { dg-message "at offset \\\[1, 4] into destination object 'a4_2" "note" }
+ char *p4 = cond1 ? a4_1 : a4_2;
+ char *p4_i = p4 + i;
+
+ memset (p4_i, 0, 3);
+ memset (p4_i, 0, 4); // { dg-warning "memset' writing 4 bytes into a region of size 3 " }
+ }
+}
+
+
+void memset_malloc_2_off (void)
+{
+ int i1 = SR (1, INT_MAX);
+ int i2 = SR (2, INT_MAX);
+
+ {
+ char a5[5]; // { dg-warning "at offset [1, 5] into destination object 'a5'
+ char a7[7]; // { dg-warning "at offset [2, 7] into destination object 'a7'
+ char *p5_p1 = a5 + i1;
+ char *p7_p2 = a7 + i2;
+ char *p5_7 = cond1 ? p5_p1 : p7_p2;
+
+ memset (p5_7, 0, 1);
+ memset (p5_7, 0, 2);
+ memset (p5_7, 0, 3);
+ memset (p5_7, 0, 4);
+ memset (p5_7, 0, 5);
+ memset (p5_7, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ int i3 = SR (3, INT_MAX);
+
+ {
+ char a5[5];
+ // { dg-message "at offset \\\[3, 5] into destination object 'a5'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[2, 5] into destination object 'a5'" "note" { target *-*-* } .-2 }
+ // { dg-message "at offset \\\[1, 5] into destination object 'a5'" "note" { target *-*-* } .-3 }
+ // { dg-message ": destination object 'a5'" "note" { target *-*-* } .-4 }
+ char a9[9];
+ // { dg-message "at offset \\\[4, 9] into destination object 'a9'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[3, 9] into destination object 'a9'" "note" { target *-*-* } .-2 }
+ // { dg-message "at offset \\\[2, 9] into destination object 'a9'" "note" { target *-*-* } .-3 }
+ // { dg-message ": destination object 'a9'" "note" { target *-*-* } .-4 }
+ char *p5_p2 = a5 + i2; // 3 bytes left
+ char *p9_p3 = a9 + i3; // 6 bytes left
+ char *p =
+ cond1 ? p5_p2 : p9_p3; // [3 - 6] bytes left
+ char *q = p + i1; // [2 - 5] bytes left
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5);
+ memset (q, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5" }
+
+ --q; // [3 - 6] bytes left
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5);
+ memset (q, 0, 6);
+ memset (q, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6" }
+
+ --q; // [4 - 7] bytes left
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5);
+ memset (q, 0, 6);
+ memset (q, 0, 7);
+ memset (q, 0, 8); // { dg-warning "memset' writing 8 bytes into a region of size 7" }
+
+ int m1_x = SR (-1, INT_MAX);
+ int m2_x = SR (-2, INT_MAX);
+
+ q += cond2 ? m1_x : m2_x; // [5 - 9] bytes left
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5);
+ memset (q, 0, 6);
+ memset (q, 0, 7);
+ memset (q, 0, 8);
+ memset (q, 0, 9);
+ memset (q, 0, 10); // { dg-warning "memset' writing 10 bytes into a region of size 9" }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-60.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-60.c
new file mode 100644
index 0000000..8c9de20
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-60.c
@@ -0,0 +1,72 @@
+/* Test derived from Glibc's getifaddrs_internal. The code could be
+ rewritten to avoid the warning for the memcpy call but since unions
+ are designed to have their members treated as interchangeable there
+ isn't a whole lot to be gained from issuing one.
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+extern void* memcpy (void*, const void*, size_t);
+
+struct sockaddr
+{
+ short sa_family;
+ char sa_data[14];
+};
+
+struct in_addr
+{
+ int s_addr;
+};
+
+struct in6_addr
+{
+ union
+ {
+ char __u6_addr8[16];
+ short __u6_addr16[8];
+ int __u6_addr32[4];
+ } __in6_u;
+};
+
+struct sockaddr_in
+{
+ short sin_family;
+ short sin_port;
+ struct in_addr sin_addr;
+ unsigned char sin_zero[sizeof (struct sockaddr) -
+ (sizeof (short)) -
+ sizeof (short) -
+ sizeof (struct in_addr)];
+};
+
+struct sockaddr_in6
+{
+ short sin6_family;
+ short sin6_port;
+ int sin6_flowinfo;
+ struct in6_addr sin6_addr;
+ int sin6_scope_id;
+};
+
+union
+{
+ struct sockaddr sa;
+ struct sockaddr_in s4;
+ struct sockaddr_in6 s6;
+} u1, u2;
+
+struct sockaddr *sa;
+
+void test_unconditional (void *p)
+{
+ sa = &u1.sa;
+ memcpy (&((struct sockaddr_in6 *) sa)->sin6_addr, p, 16);
+}
+
+void test_conditional (void *p, int i)
+{
+ sa = i ? &u1.sa : &u2.sa;
+ memcpy (&((struct sockaddr_in6 *) sa)->sin6_addr, p, 16);
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-61.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-61.c
new file mode 100644
index 0000000..7601679
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-61.c
@@ -0,0 +1,88 @@
+/* { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+void* malloc (size_t);
+void* memcpy (void*, const void*, size_t);
+size_t strlen (const char *);
+
+// Test case reduced from gcc/attribs.c.
+
+char* sorted_attr_string (char *argv[])
+{
+ size_t n = 0;
+ unsigned int i;
+
+ for (i = 0; argv[i]; ++i)
+ n += strlen (argv[i]);
+
+ char *s = (char*)malloc (n);
+ n = 0;
+ for (i = 0; argv[i]; ++i)
+ {
+ const char *str = argv[i];
+ size_t len = strlen (str);
+ memcpy (s + n, str, len);
+ n += len + 1;
+ }
+
+ /* Replace "=,-" with "_". */
+ for (i = 0; i < strlen (s); i++)
+ if (s[i] == '=')
+ s[i] = '_'; // { dg-bogus "\\\[-Wstringop-overflow" }
+
+ return s;
+}
+
+
+void f (void*);
+
+void nowarn_cond_escape (int c, int *x)
+{
+ extern char a3[3], a5[5];
+
+ char *p;
+ if (c)
+ {
+ p = a3;
+ *x = 2;
+ }
+ else
+ {
+ p = a5;
+ *x = 4;
+ }
+
+ f (p); // may modify *x
+
+ if (*x == 2)
+ p[2] = 0;
+ else if (*x == 4)
+ p[4] = 0; // { dg-bogus "\\\[-Wstringop-overflow" }
+}
+
+void warn_cond_escape (int c, int *x)
+{
+ extern char a3_2[3];
+ extern char a5_2[5]; // { dg-message "at offset 5 into destination object 'a5_2'" }
+
+ char *p;
+ if (c)
+ {
+ p = a3_2;
+ *x = 2;
+ }
+ else
+ {
+ p = a5_2;
+ *x = 5;
+ }
+
+ f (p); // may modify *x
+
+ if (*x == 2)
+ p[2] = 0;
+ else if (*x == 5)
+ p[5] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-62.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-62.c
new file mode 100644
index 0000000..318d9bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-62.c
@@ -0,0 +1,363 @@
+/* Test for MIN and MAX expressions involving pointers.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wno-array-bounds -ftrack-macro-expansion=0" } */
+
+#include "range.h"
+
+#define INT_MAX __INT_MAX__
+
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+#define MAX(x, y) ((x) < (y) ? (y) : (x))
+
+typedef __SIZE_TYPE__ size_t;
+
+void* memset (void*, int, size_t);
+#define memset(...) sink (memset (__VA_ARGS__))
+
+void sink (void*, ...);
+
+volatile int cond, vi;
+char* volatile ptr;
+
+void test_min (void)
+{
+ const int i1 = SR (1, INT_MAX);
+ const int i2 = SR (2, INT_MAX);
+
+ {
+ /* Exercise both pointers pointing to a different unknown object plus
+ positive constant offset. Since PTR is volatile P1 and P2 cannot
+ normally be considered to point to the same object. It can only
+ be inferred from the MIN expression. */
+ char *p1 = ptr + 1;
+ char *p2 = ptr + 2;
+
+ char *q = MIN (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, INT_MAX);
+ // { dg-warning "writing 2147483647 bytes into a region of size 2147483646" "ilp32" { target ilp32 } .-1 }
+ memset (q, 0, DIFF_MAX - 2);
+ memset (q, 0, DIFF_MAX);
+ // { dg-warning "writing 2147483647 bytes into a region of size 2147483646" "ilp32" { target ilp32 } .-1 }
+ // { dg-warning "writing 9223372036854775807 bytes into a region of size 9223372036854775806" "lp64" { target lp64 } .-2 }
+ }
+
+ {
+ /* Exercise both pointers pointing to a different unknown object plus
+ variable offset. */
+ char *p1 = ptr + vi;
+ char *p2 = ptr + vi;
+
+ char *q = MIN (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, INT_MAX);
+ }
+
+ {
+ /* Exercise both pointers pointing to the same object plus constant
+ offset. */
+ char a2[2]; // { dg-message "at offset 1 into destination object 'a2' of size 2" "note" }
+ char *p1 = a2 + 1;
+ char *p2 = a2 + 2;
+
+ char *q = MIN (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2); // { dg-warning "writing 2 bytes into a region of size 1 " }
+ }
+
+ {
+ /* Exercise both pointers pointing to the same object plus offset
+ in a known range. */
+ char a3[3]; // { dg-message "at offset \\\[1, 3] into destination object 'a3'" "note" }
+ char *pi = a3 + i1;
+ char *pj = a3 + i2;
+
+ char *q = MIN (pi, pj);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
+ }
+
+ {
+ /* Exercise both pointers pointing to the same object plus variable
+ offset. Verify that no offset is mentioned in the note (since
+ its unknown, printing its full range is unnecessary). */
+ char a4[4]; // { dg-message ": destination object 'a4'" "note" }
+ char *pi = a4 + vi;
+ char *pj = a4 + vi;
+
+ char *q = MIN (pi, pj);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5); // { dg-warning "writing 5 bytes into a region of size 4 " }
+ }
+
+ {
+ /* Exercise a pointer pointing to a known object with one pointing
+ to an unknown object. */
+ char a5[5]; // { dg-message ": destination object 'a5'" "note" }
+ char *p = ptr;
+ char *q = MIN (p, a5);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 5);
+ memset (q, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ /* Exercise a pointer pointing to a known object plus constant offset
+ with one pointing to an unknown object. */
+ char a6[6]; // { dg-message ": destination object 'a6'" "note" }
+ char *p1 = ptr;
+ char *p2 = a6 + 1;
+ char *q = MIN (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 6);
+ memset (q, 0, 7); // { dg-warning "writing 7 bytes into a region of size 6 " }
+ }
+
+ {
+ /* Exercise a pointer pointing to a known object with one pointing
+ to an unknown object plus constant offset. */
+ char a7[7]; // { dg-message ": destination object 'a7'" "note" }
+ char *p1 = a7;
+ char *p2 = ptr + 1;
+ /* Since p1 points to a7[0] it must be less than any pointer to a7
+ plus positive offset, and so Q == P1. */
+ char *q = MIN (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 7);
+ memset (q, 0, 8); // { dg-warning "writing 8 bytes into a region of size 7 " }
+ }
+
+ {
+ /* Exercise a pointer pointing to a known object plus constant offset
+ with one pointing to an unknown object plus a different constant
+ offset. */
+ char a8[8]; // { dg-message "at offset 1 into destination object 'a8'" "note" }
+ char *p1 = a8 + 1;
+ char *p2 = ptr + 2;
+ /* Since P1 points to A8[1] it must be less than or equal to any
+ pointer to A8 plus positive offset. Either way, Q must point
+ to A8[1]. */
+ char *q = MIN (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 7);
+ memset (q, 0, 8); // { dg-warning "writing 8 bytes into a region of size 7 " }
+ }
+
+ {
+ /* Same as above but with larger offsets. */
+ char a9[9]; // { dg-message "at offset 3 into destination object 'a9'" "note" }
+ char *p1 = a9 + 3;
+ char *p2 = ptr + 4;
+ /* Since P1 points to A9[3] it must be less than or equal to any
+ pointer anywhere into A9 plus 4, so Q must point to A9[3]. */
+ char *q = MIN (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 6);
+ memset (q, 0, 7); // { dg-warning "writing 7 bytes into a region of size 6 " }
+ }
+
+ {
+ /* Same as above but with the offsets reversed. */
+ char a10[10]; // { dg-message "at offset 5 into destination object 'a10'" "note" }
+ char *p1 = a10 + 10;
+ char *p2 = ptr + 5;
+ /* Since P1 points just past the end of A10 it could be either less
+ or equal to another pointer anywhere into A10 plus 3 because
+ the other pointer itself could start at a non-zero offset that's
+ not reflected in the determined offset). */
+ char *q = MIN (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 5);
+ memset (q, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ char a3[3]; // { dg-message ": destination object 'a3'" "note" }
+ char *p1 = ptr;
+ char *p2 = a3 + i1;
+ char *q = MIN (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4); // { dg-warning "writing 4 bytes into a region of size 3 " }
+ }
+}
+
+
+void test_max (void)
+{
+ const int i1 = SR (1, INT_MAX);
+ const int i2 = SR (2, INT_MAX);
+
+ {
+ /* Exercise both pointers pointing to the same object plus constant
+ offset. */
+ char a2[2]; // { dg-message "at offset 1 into destination object 'a2' of size 2" "note" }
+ char *pi = a2 + 1;
+ char *pj = a2 + 2;
+
+ char *q = MAX (pi, pj);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2); // { dg-warning "writing 2 bytes into a region of size 1 " }
+ }
+
+ {
+ /* Exercise both pointers pointing to the same object plus offset
+ in a known range. */
+ char a3[3]; // { dg-message "at offset \\\[1, 3] into destination object 'a3'" "note" }
+ char *pi = a3 + i1;
+ char *pj = a3 + i2;
+
+ char *q = MAX (pi, pj);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
+ }
+
+ {
+ /* Exercise both pointers pointing to the same object plus variable
+ offset. Verify that no offset is mentioned in the note (since
+ its unknown, printing its full range is unnecessary). */
+ char a4[4]; // { dg-message ": destination object 'a4'" "note" }
+ char *pi = a4 + vi;
+ char *pj = a4 + vi;
+
+ char *q = MAX (pi, pj);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5); // { dg-warning "writing 5 bytes into a region of size 4 " }
+ }
+
+ {
+ /* Exercise a pointer pointing to a known object with one pointing
+ to an unknown object. */
+ char a5[5]; // { dg-message ": destination object 'a5'" "note" }
+ char *p = ptr;
+ char *q = MAX (p, a5);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 5);
+ memset (q, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ /* Exercise a pointer pointing to a known object plus constant offset
+ with one pointing to an unknown object. */
+ char a6[6]; // { dg-message "at offset 1 into destination object 'a6'" "note" }
+ char *p1 = ptr;
+ char *p2 = a6 + 1;
+ char *q = MAX (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 5);
+ memset (q, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5 " }
+ memset (q, 0, 7); // { dg-warning "writing 7 bytes into a region of size 5 " }
+ }
+
+ {
+ /* Exercise a pointer pointing to a known object with one pointing
+ to an unknown object plus constant offset. */
+ char a7[7]; // { dg-message "at offset 1 into destination object 'a7'" "note" }
+ char *p1 = a7;
+ char *p2 = ptr + 1;
+ /* Since p1 points to a7[0] it must be less than any pointer to a7
+ plus positive offset, and so Q == P2. */
+ char *q = MAX (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 6);
+ memset (q, 0, 7); // { dg-warning "writing 7 bytes into a region of size 6 " }
+ memset (q, 0, 8); // { dg-warning "writing 8 bytes into a region of size 6 " }
+ }
+
+ {
+ /* Exercise a pointer pointing to a known object plus constant offset
+ with one pointing to an unknown object plus a different constant
+ offset. */
+ char a8[8]; // { dg-message "at offset 2 into destination object 'a8'" "note" }
+ char *p1 = a8 + 1;
+ char *p2 = ptr + 2;
+ /* Since P1 points to A8[1] it must be less than or equal to any
+ pointer to A8 plus positive offset. Either way, Q must point
+ to A8[2]. */
+ char *q = MAX (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 6);
+ memset (q, 0, 7); // { dg-warning "writing 7 bytes into a region of size 6 " }
+ memset (q, 0, 8); // { dg-warning "writing 8 bytes into a region of size 6 " }
+ }
+
+ {
+ /* Same as above but with larger offsets. */
+ char a9[9]; // { dg-message "at offset 4 into destination object 'a9'" "note" }
+ char *p1 = a9 + 3;
+ char *p2 = ptr + 4;
+ /* Since P1 points to A9[3] it must be less than or equal to any
+ pointer anywhere into A9 plus 4, so Q must point to A9[4]. */
+ char *q = MAX (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 5);
+ memset (q, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ /* Same as above but with the offsets reversed. */
+ char a10[10]; // { dg-message "at offset 10 into destination object 'a10'" "note" }
+ char *p1 = a10 + 10;
+ char *p2 = ptr + 5;
+ /* Since P1 points just past the end of A10 it could be either less
+ or equal to another pointer anywhere into A10 plus 3 because
+ the other pointer itself could start at a non-zero offset that's
+ not reflected in the determaxed offset). */
+ char *q = MAX (p1, p2);
+
+ memset (q, 0, 1); // { dg-warning "writing 1 byte into a region of size 0 " }
+ }
+
+ {
+ char a11[11]; // { dg-message "at offset \\\[1, 11] into destination object 'a11'" "note" }
+ char *p1 = ptr;
+ char *p2 = a11 + i1;
+ char *q = MAX (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 10);
+ memset (q, 0, 11); // { dg-warning "writing 11 bytes into a region of size 10 " }
+ }
+}
+
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-63.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-63.c
new file mode 100644
index 0000000..c98721d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-63.c
@@ -0,0 +1,33 @@
+/* PR middle-end/92936 - missing warning on a past-the-end store to a PHI
+ Test case derived from gcc/opts-common.c.
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+char* f (const void*, ...);
+
+const char *
+candidates_list_and_hint (const char *arg, char **str, const char *a[])
+{
+ size_t len = 0;
+ int i;
+
+ for (i = 0; a[i]; ++i)
+ len += __builtin_strlen (a[i]) + 1;
+
+ char *p = (char*)__builtin_malloc (len);
+ *str = p;
+
+ for (i = 0; a[i]; ++i)
+ {
+ len = __builtin_strlen (a[i]);
+ __builtin_memcpy (p, a[i], len);
+ p[len] = ' ';
+ p += len + 1;
+ }
+
+ p[-1] = '\0'; // { dg-bogus "\\\[-Wstringop-overflow" }
+
+ return f (arg, &a);
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-64.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-64.c
new file mode 100644
index 0000000..88b9d29
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-64.c
@@ -0,0 +1,74 @@
+/* PR middle-end/92936 - missing warning on a past-the-end store to a PHI
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wno-array-bounds" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+void* malloc (size_t);
+void* memset (void*, int, size_t);
+
+extern char a3[3], a5[5], a9[9];
+
+extern int cnd[];
+
+void* f2 (void)
+{
+ char *p0 = cnd[0] ? a3 : 0;
+ char *p1 = cnd[1] ? a5 : p0;
+
+ return memset (p1, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5" }
+}
+
+void* f3 (void)
+{
+ char *p0 = cnd[0] ? a3 : 0;
+ char *p1 = cnd[1] ? a5 : 0;
+ char *p2 = cnd[2] ? p0 : p1;
+
+ return memset (p2, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5" }
+}
+
+void* f3_2 (void)
+{
+ char *p0 = cnd[0] ? a3 : 0;
+ char *p1 = cnd[1] ? a5 : 0;
+ char *p2 = cnd[2] ? p1 : p0;
+
+ return memset (p2, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5" }
+}
+
+void* f3_3 (void)
+{
+ char *p0 = cnd[0] ? a5 : 0;
+ char *p1 = cnd[1] ? p0 : a5;
+ char *p2 = cnd[2] ? p1 : p0;
+
+ return memset (p2, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5" }
+}
+
+void* f4 (void)
+{
+ char *p0 = cnd[0] ? a3 : 0;
+ char *p1 = cnd[1] ? a5 : 0;
+ char *p2 = cnd[2] ? p0 : 0;
+ char *p3 = cnd[3] ? p1 : p2;
+
+ return memset (p3, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5" }
+}
+
+void* f9 (void)
+{
+ char *p0 = cnd[0] ? a5 : 0;
+ char *p1 = cnd[1] ? a5 + 1 : 0;
+ char *p2 = cnd[2] ? a5 + 2 : 0;
+ char *p3 = cnd[3] ? a5 + 3 : 0;
+ char *p4 = cnd[4] ? a5 + 4 : 0;
+
+ char *p5 = cnd[5] ? p0 : p1;
+ char *p6 = cnd[6] ? p5 : p2;
+ char *p7 = cnd[7] ? p6 : p3;
+ char *p8 = cnd[8] ? p7 : p4;
+ char *p9 = cnd[9] ? p8 : p5;
+
+ return memset (p9, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-7.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-7.c
new file mode 100644
index 0000000..cb2addf3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-7.c
@@ -0,0 +1,124 @@
+/* Test to verify that --param ssa_name_def_chain_limit can be used to
+ limit the maximum number of SSA_NAME assignments the warning follows.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wno-array-bounds --param ssa-name-def-chain-limit=5" } */
+
+#define NOIPA __attribute__ ((noipa))
+
+void* memset (void*, int, __SIZE_TYPE__);
+
+char a9[9];
+
+void sink (const char*, ...);
+
+NOIPA void g2 (int i)
+{
+ if (i < 1) i = 1;
+
+ char *p0 = a9;
+ char *p1 = p0 + i;
+ char *p2 = p1 + i;
+
+ sink (p0, p1, p2);
+
+ memset (p2, 0, 8); // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+NOIPA void g3 (int i)
+{
+ if (i < 1) i = 1;
+
+ char *p0 = a9;
+ char *p1 = p0 + i;
+ char *p2 = p1 + i;
+ char *p3 = p2 + i;
+
+ sink (p0, p1, p2, p3);
+
+ memset (p3, 0, 7); // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+NOIPA void g4 (int i)
+{
+ if (i < 1) i = 1;
+
+ char *p0 = a9;
+ char *p1 = p0 + i;
+ char *p2 = p1 + i;
+ char *p3 = p2 + i;
+ char *p4 = p3 + i;
+
+ sink (p0, p1, p2, p3, p4);
+
+ memset (p4, 0, 6); // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+NOIPA void g5 (int i)
+{
+ if (i < 1) i = 1;
+
+ char *p0 = a9;
+ char *p1 = p0 + i;
+ char *p2 = p1 + i;
+ char *p3 = p2 + i;
+ char *p4 = p3 + i;
+ char *p5 = p4 + i;
+
+ sink (p0, p1, p2, p3, p4, p5);
+
+ memset (p5, 0, 5); // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+NOIPA void g6 (int i)
+{
+ if (i < 1) i = 1;
+
+ char *p0 = a9;
+ char *p1 = p0 + i;
+ char *p2 = p1 + i;
+ char *p3 = p2 + i;
+ char *p4 = p3 + i;
+ char *p5 = p4 + i;
+ char *p6 = p5 + i;
+
+ sink (p0, p1, p2, p3, p4, p5, p6);
+
+ memset (p6, 0, 4);
+}
+
+NOIPA void g7 (int i)
+{
+ if (i < 1) i = 1;
+
+ char *p0 = a9;
+ char *p1 = p0 + i;
+ char *p2 = p1 + i;
+ char *p3 = p2 + i;
+ char *p4 = p3 + i;
+ char *p5 = p4 + i;
+ char *p6 = p5 + i;
+ char *p7 = p6 + i;
+
+ sink (p0, p1, p2, p3, p4, p5, p6, p7);
+
+ memset (p7, 0, 4);
+}
+
+NOIPA void g8 (int i)
+{
+ if (i < 1) i = 1;
+
+ char *p0 = a9;
+ char *p1 = p0 + i;
+ char *p2 = p1 + i;
+ char *p3 = p2 + i;
+ char *p4 = p3 + i;
+ char *p5 = p4 + i;
+ char *p6 = p5 + i;
+ char *p7 = p6 + i;
+ char *p8 = p7 + i;
+
+ sink (p0, p1, p2, p3, p4, p5, p6, p7, p8);
+
+ memset (p8, 0, 2);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/invalid-shift-1.c b/gcc/testsuite/gcc.dg/analyzer/invalid-shift-1.c
new file mode 100644
index 0000000..08e5272
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/invalid-shift-1.c
@@ -0,0 +1,34 @@
+/* PR tree-optimization/97424. */
+
+#include <stdint.h>
+
+static inline uint32_t
+_dl_hwcaps_subdirs_build_bitmask (int subdirs, int active)
+{
+ /* Leading subdirectories that are not active. */
+ int inactive = subdirs - active;
+ if (inactive == 32)
+ return 0;
+
+ uint32_t mask;
+ if (subdirs != 32)
+ mask = (1 << subdirs) - 1; /* { dg-message "shift by count \\('33'\\) >= precision of type \\('\[0-9\]+'\\)" } */
+ else
+ mask = -1;
+ return mask ^ ((1U << inactive) - 1); /* { dg-message "shift by negative count \\('-1'\\)" } */
+}
+
+void f1 (int);
+
+void
+f2 (void)
+{
+ f1 (_dl_hwcaps_subdirs_build_bitmask (1, 2));
+ f1 (_dl_hwcaps_subdirs_build_bitmask (33, 31));
+}
+
+static int __attribute__((noinline)) op3 (int op, int c) { return op << c; } /* { dg-message "shift by negative count \\('-1'\\)" } */
+int test_3 (void) { return op3 (1, -1); }
+
+static int __attribute__((noinline)) op4 (int op, int c) { return op << c; }
+int test_4 (void) { return op4 (1, 0); }
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
index 38ce1a5..c5bf1227c 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
@@ -30,14 +30,14 @@ void test_2a (void *ptr)
int *test_3 (void)
{
int *ptr = (int *)malloc (sizeof (int));
- *ptr = 42; /* { dg-warning "dereference of possibly-NULL 'ptr'" } */
+ *ptr = 42; /* { dg-warning "dereference of possibly-NULL 'ptr' \\\[CWE-690\\\]" } */
return ptr;
}
int *test_3a (void)
{
int *ptr = (int *)__builtin_malloc (sizeof (int));
- *ptr = 42; /* { dg-warning "dereference of possibly-NULL 'ptr'" } */
+ *ptr = 42; /* { dg-warning "dereference of possibly-NULL 'ptr' \\\[CWE-690\\\]" } */
return ptr;
}
@@ -47,7 +47,7 @@ int *test_4 (void)
if (ptr)
*ptr = 42;
else
- *ptr = 43; /* { dg-warning "dereference of NULL 'ptr'" } */
+ *ptr = 43; /* { dg-warning "dereference of NULL 'ptr' \\\[CWE-476\\\]" } */
return ptr;
}
@@ -260,14 +260,14 @@ void test_22 (void)
int *test_23 (int n)
{
int *ptr = (int *)calloc (n, sizeof (int));
- ptr[0] = 42; /* { dg-warning "dereference of possibly-NULL 'ptr'" } */
+ ptr[0] = 42; /* { dg-warning "dereference of possibly-NULL 'ptr' \\\[CWE-690\\\]" } */
return ptr;
}
int *test_23a (int n)
{
int *ptr = (int *)__builtin_calloc (n, sizeof (int));
- ptr[0] = 42; /* { dg-warning "dereference of possibly-NULL 'ptr'" } */
+ ptr[0] = 42; /* { dg-warning "dereference of possibly-NULL 'ptr' \\\[CWE-690\\\]" } */
return ptr;
}
@@ -302,7 +302,7 @@ struct coord {
struct coord *test_27 (void)
{
struct coord *p = (struct coord *) malloc (sizeof (struct coord)); /* { dg-message "this call could return NULL" } */
- p->x = 0.f; /* { dg-warning "dereference of possibly-NULL 'p'" } */
+ p->x = 0.f; /* { dg-warning "dereference of possibly-NULL 'p' \\\[CWE-690\\\]" } */
/* Only the first such usage should be reported: */
p->y = 0.f;
@@ -313,7 +313,7 @@ struct coord *test_27 (void)
struct coord *test_28 (void)
{
struct coord *p = NULL;
- p->x = 0.f; /* { dg-warning "dereference of NULL 'p'" } */
+ p->x = 0.f; /* { dg-warning "dereference of NULL 'p' \\\[CWE-476\\\]" } */
/* Only the first such usage should be reported: */
p->y = 0.f;
@@ -416,7 +416,7 @@ void test_36 (void)
void *test_37a (void)
{
void *ptr = malloc(4096); /* { dg-message "this call could return NULL" } */
- __builtin_memset(ptr, 0, 4096); /* { dg-warning "use of possibly-NULL 'ptr' where non-null expected" } */
+ __builtin_memset(ptr, 0, 4096); /* { dg-warning "use of possibly-NULL 'ptr' where non-null expected \\\[CWE-690\\\]" } */
return ptr;
}
@@ -427,7 +427,7 @@ int test_37b (void)
if (p) {
__builtin_memset(p, 0, 4096); /* Not a bug: checked */
} else {
- __builtin_memset(q, 0, 4096); /* { dg-warning "use of possibly-NULL 'q' where non-null expected" } */
+ __builtin_memset(q, 0, 4096); /* { dg-warning "use of possibly-NULL 'q' where non-null expected \\\[CWE-690\\\]" } */
}
free(p);
free(q);
@@ -452,7 +452,7 @@ int *
test_39 (int i)
{
int *p = (int*)malloc(sizeof(int*)); /* { dg-message "this call could return NULL" } */
- *p = i; /* { dg-warning "dereference of possibly-NULL 'p'" } */
+ *p = i; /* { dg-warning "dereference of possibly-NULL 'p' \\\[CWE-690\\\]" } */
return p;
}
@@ -460,7 +460,7 @@ int *
test_40 (int i)
{
int *p = (int*)malloc(sizeof(int*));
- i = *p; /* { dg-warning "dereference of possibly-NULL 'p'" } */
+ i = *p; /* { dg-warning "dereference of possibly-NULL 'p' \\\[CWE-690\\\]" } */
/* TODO: (it's also uninitialized) */
return p;
}
@@ -476,8 +476,8 @@ test_41 (int flag)
buffer = NULL;
}
- buffer[0] = 'a'; /* { dg-warning "dereference of possibly-NULL 'buffer'" "possibly-NULL" } */
- /* { dg-warning "dereference of NULL 'buffer'" "NULL" { target *-*-* } .-1 } */
+ buffer[0] = 'a'; /* { dg-warning "dereference of possibly-NULL 'buffer' \\\[CWE-690\\\]" "possibly-NULL" } */
+ /* { dg-warning "dereference of NULL 'buffer' \\\[CWE-476\\\]" "NULL" { target *-*-* } .-1 } */
return buffer;
}
@@ -594,7 +594,7 @@ int test_47 (void)
void test_48 (void)
{
int *p = NULL; /* { dg-message "'p' is NULL" } */
- *p = 1; /* { dg-warning "dereference of NULL 'p'" } */
+ *p = 1; /* { dg-warning "dereference of NULL 'p' \\\[CWE-476\\\]" } */
}
/* As test_48, but where the assignment of NULL is not at the start of a BB. */
@@ -606,6 +606,6 @@ int test_49 (int i)
x = i * 2;
p = NULL; /* { dg-message "'p' is NULL" } */
- *p = 1; /* { dg-warning "dereference of NULL 'p'" } */
+ *p = 1; /* { dg-warning "dereference of NULL 'p' \\\[CWE-476\\\]" } */
return x;
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/setjmp-5.c b/gcc/testsuite/gcc.dg/analyzer/setjmp-5.c
index bf5b9bf..4787fa3 100644
--- a/gcc/testsuite/gcc.dg/analyzer/setjmp-5.c
+++ b/gcc/testsuite/gcc.dg/analyzer/setjmp-5.c
@@ -51,18 +51,25 @@ void outer (void)
| | |
| | (4) 'setjmp' called here
|
+ 'inner': event 5
+ |
+ | NN | }
+ | | ^
+ | | |
+ | | (5) stack frame is popped here, invalidating saved environment
+ |
<------+
|
- 'outer': events 5-6
+ 'outer': events 6-7
|
| NN | inner ();
| | ^~~~~~~~
| | |
- | | (5) returning to 'outer' from 'inner'
+ | | (6) returning to 'outer' from 'inner'
| NN |
| NN | longjmp (env, 42);
| | ~~~~~~~~~~~~~~~~~
| | |
- | | (6) here
+ | | (7) 'longjmp' called after enclosing function of 'setjmp' returned at (5)
|
{ dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/array-quals-1.c b/gcc/testsuite/gcc.dg/array-quals-1.c
index 3981c91..31aa1d3 100644
--- a/gcc/testsuite/gcc.dg/array-quals-1.c
+++ b/gcc/testsuite/gcc.dg/array-quals-1.c
@@ -6,26 +6,46 @@
/* { dg-options "-Wno-discarded-array-qualifiers" } */
/* The MMIX port always switches to the .data section at the end of a file. */
/* { dg-final { scan-assembler-not "\\.data(?!\\.rel\\.ro)" { xfail powerpc*-*-aix* mmix-*-* x86_64-*-mingw* } } } */
+/* { dg-final { scan-assembler-symbol-section {^_?a$} {^\.(const|rodata)|\[RO\]} } } */
static const int a[2] = { 1, 2 };
+/* { dg-final { scan-assembler-symbol-section {^_?a1$} {^\.(const|rodata)|\[RO\]} } } */
const int a1[2] = { 1, 2 };
typedef const int ci;
+/* { dg-final { scan-assembler-symbol-section {^_?b$} {^\.(const|rodata)|\[RO\]} } } */
static ci b[2] = { 3, 4 };
+/* { dg-final { scan-assembler-symbol-section {^_?b1$} {^\.(const|rodata)|\[RO\]} } } */
ci b1[2] = { 3, 4 };
typedef int ia[2];
+/* { dg-final { scan-assembler-symbol-section {^_?c$} {^\.(const|rodata)|\[RO\]} } } */
static const ia c = { 5, 6 };
+/* { dg-final { scan-assembler-symbol-section {^_?c1$} {^\.(const|rodata)|\[RO\]} } } */
const ia c1 = { 5, 6 };
typedef const int cia[2];
+/* { dg-final { scan-assembler-symbol-section {^_?d$} {^\.(const|rodata)|\[RO\]} } } */
static cia d = { 7, 8 };
+/* { dg-final { scan-assembler-symbol-section {^_?d1$} {^\.(const|rodata)|\[RO\]} } } */
cia d1 = { 7, 8 };
+/* { dg-final { scan-assembler-symbol-section {^_?e$} {^\.(const|rodata)|\[RO\]} } } */
static cia e[2] = { { 1, 2 }, { 3, 4 } };
+/* { dg-final { scan-assembler-symbol-section {^_?e1$} {^\.(const|rodata)|\[RO\]} } } */
cia e1[2] = { { 1, 2 }, { 3, 4 } };
+/* { dg-final { scan-assembler-symbol-section {^_?p$} {^\.(const|rodata)|\[RW\]} } } */
void *const p = &a;
+/* { dg-final { scan-assembler-symbol-section {^_?q$} {^\.(const|rodata)|\[RW\]} } } */
void *const q = &b;
+/* { dg-final { scan-assembler-symbol-section {^_?r$} {^\.(const|rodata)|\[RW\]} } } */
void *const r = &c;
+/* { dg-final { scan-assembler-symbol-section {^_?s$} {^\.(const|rodata)|\[RW\]} } } */
void *const s = &d;
+/* { dg-final { scan-assembler-symbol-section {^_?t$} {^\.(const|rodata)|\[RW\]} } } */
void *const t = &e;
+/* { dg-final { scan-assembler-symbol-section {^_?p1$} {^\.(const|rodata)|\[RW\]} } } */
void *const p1 = &a1;
+/* { dg-final { scan-assembler-symbol-section {^_?q1$} {^\.(const|rodata)|\[RW\]} } } */
void *const q1 = &b1;
+/* { dg-final { scan-assembler-symbol-section {^_?r1$} {^\.(const|rodata)|\[RW\]} } } */
void *const r1 = &c1;
+/* { dg-final { scan-assembler-symbol-section {^_?s1$} {^\.(const|rodata)|\[RW\]} } } */
void *const s1 = &d1;
+/* { dg-final { scan-assembler-symbol-section {^_?t1$} {^\.(const|rodata)|\[RW\]} } } */
void *const t1 = &e1;
diff --git a/gcc/testsuite/gcc.dg/attr-access-3.c b/gcc/testsuite/gcc.dg/attr-access-3.c
new file mode 100644
index 0000000..45dd1aa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/attr-access-3.c
@@ -0,0 +1,21 @@
+/* PR middle-end/97879 - ICE on invalid mode in attribute access
+ { dg-do compile }
+ { dg-options "-Wall" } */
+
+#define A(...) __attribute__ ((access (__VA_ARGS__)))
+
+A (" ", 1) void f1 (int *); // { dg-error "attribute 'access' mode '\" \"' is not an identifier; expected one of 'read_only', 'read_write', 'write_only', or 'none'" }
+ void f1 (int *);
+
+
+A ("none", 1) void f2 (char *); // { dg-error "not an identifier" }
+ void f2 (char *);
+
+A (1) void f3 (); // { dg-error "not an identifier" }
+
+A (1, 2) void f4 (); // { dg-error "not an identifier" }
+A (2., 3.) void f5 (); // { dg-error "not an identifier" }
+
+// Verify that copying a valid access attribute doesn't cause errors.
+A (read_only, 1, 2) void f6 (void*, int);
+__attribute__ ((copy (f6))) void f7 (void*, int);
diff --git a/gcc/testsuite/gcc.dg/attr-access-4.c b/gcc/testsuite/gcc.dg/attr-access-4.c
new file mode 100644
index 0000000..7a2870a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/attr-access-4.c
@@ -0,0 +1,8 @@
+/* PR middle-end/97861 - ICE on an invalid redeclaration of a function
+ with attribute access
+ { dg-do compile }
+ { dg-options "-Wall" } */
+
+__attribute__ ((access (read_only, 2)))
+void f (int, int*);
+void f (int a) { } // { dg-error "conflicting types for 'f'" }
diff --git a/gcc/testsuite/gcc.dg/attr-access-5.c b/gcc/testsuite/gcc.dg/attr-access-5.c
new file mode 100644
index 0000000..e78b360
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/attr-access-5.c
@@ -0,0 +1,16 @@
+/* { dg-do compile }
+ { dg-options "-fdump-tree-gimple" } */
+
+__attribute__ ((aligned (32)))
+__attribute__ ((access (write_only, 2, 1)))
+void f (int n, void *p)
+{
+ __builtin_memset (p, 0, n);
+}
+
+/* Verify the DECL_ATTRIBUTE "aligned" is mentioned:
+ { dg-final { scan-tree-dump "__attribute__\\(\\(aligned" "gimple" } }
+ and the TYPE_ATTRIBUTE "access" is also mentioned:
+ { dg-final { scan-tree-dump "__attribute__\\(\\(access" "gimple" } }
+ and the function signature including its return type is mentioned:
+ { dg-final { scan-tree-dump "void f *\\(int n, void *\\* *p\\)" "gimple" } } */
diff --git a/gcc/testsuite/gcc.dg/binary-constants-2.c b/gcc/testsuite/gcc.dg/binary-constants-2.c
index 6c3928a..5339d57 100644
--- a/gcc/testsuite/gcc.dg/binary-constants-2.c
+++ b/gcc/testsuite/gcc.dg/binary-constants-2.c
@@ -9,8 +9,8 @@
int
foo (void)
{
-#if FOO /* { dg-warning "binary constants are a GCC extension" } */
+#if FOO /* { dg-warning "binary constants are a C2X feature or GCC extension" } */
return 23;
#endif
- return 0b1101; /* { dg-warning "binary constants are a GCC extension" } */
+ return 0b1101; /* { dg-warning "binary constants are a C2X feature or GCC extension" } */
}
diff --git a/gcc/testsuite/gcc.dg/binary-constants-3.c b/gcc/testsuite/gcc.dg/binary-constants-3.c
index 410fc4c..5b49cb4 100644
--- a/gcc/testsuite/gcc.dg/binary-constants-3.c
+++ b/gcc/testsuite/gcc.dg/binary-constants-3.c
@@ -9,8 +9,8 @@
int
foo (void)
{
-#if FOO /* { dg-error "binary constants are a GCC extension" } */
+#if FOO /* { dg-error "binary constants are a C2X feature or GCC extension" } */
return 23;
#endif
- return 0b1101; /* { dg-error "binary constants are a GCC extension" } */
+ return 0b1101; /* { dg-error "binary constants are a C2X feature or GCC extension" } */
}
diff --git a/gcc/testsuite/gcc.dg/builtin-arith-overflow-4.c b/gcc/testsuite/gcc.dg/builtin-arith-overflow-4.c
new file mode 100644
index 0000000..ab7d82a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-arith-overflow-4.c
@@ -0,0 +1,43 @@
+/* PR c/90628 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+_Atomic int a = 1, b = 2, c = 3;
+_Atomic long d = 4, e = 5, f = 6;
+_Atomic long long g = 7, h = 8, i = 9;
+
+void
+f1 ()
+{
+ __builtin_add_overflow (a, b, &c); /* { dg-error "argument 3 in call to function '__builtin_add_overflow' has pointer to '_Atomic' type" } */
+}
+
+void
+f2 ()
+{
+ __builtin_sub_overflow (d, e, &f); /* { dg-error "argument 3 in call to function '__builtin_sub_overflow' has pointer to '_Atomic' type" } */
+}
+
+void
+f3 ()
+{
+ __builtin_mul_overflow (g, h, &i); /* { dg-error "argument 3 in call to function '__builtin_mul_overflow' has pointer to '_Atomic' type" } */
+}
+
+void
+f4 ()
+{
+ __builtin_sadd_overflow (a, b, &c); /* { dg-warning "passing argument 3 of '__builtin_sadd_overflow' from incompatible pointer type" } */
+}
+
+void
+f5 ()
+{
+ __builtin_ssubl_overflow (d, e, &f); /* { dg-warning "passing argument 3 of '__builtin_ssubl_overflow' from incompatible pointer type" } */
+}
+
+void
+f6 ()
+{
+ __builtin_smulll_overflow (g, h, &i); /* { dg-warning "passing argument 3 of '__builtin_smulll_overflow' from incompatible pointer type" } */
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-arith-overflow-5.c b/gcc/testsuite/gcc.dg/builtin-arith-overflow-5.c
new file mode 100644
index 0000000..b43fd18
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-arith-overflow-5.c
@@ -0,0 +1,87 @@
+/* PR rtl-optimization/95862 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+f1 (int a, int b)
+{
+ unsigned long long c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+int
+f2 (int a, unsigned b)
+{
+ unsigned long long c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+int
+f3 (unsigned a, unsigned b)
+{
+ long long c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+int
+f4 (int a, unsigned b)
+{
+ long long c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+short
+f5 (short a, short b)
+{
+ unsigned c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+short
+f6 (short a, unsigned short b)
+{
+ unsigned c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+short
+f7 (unsigned short a, unsigned short b)
+{
+ int c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+short
+f8 (short a, unsigned short b)
+{
+ int c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+signed char
+f9 (signed char a, signed char b)
+{
+ unsigned short c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+signed char
+f10 (signed char a, unsigned char b)
+{
+ unsigned short c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+signed char
+f11 (unsigned char a, unsigned char b)
+{
+ short c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+signed char
+f12 (signed char a, unsigned char b)
+{
+ short c;
+ return __builtin_mul_overflow (a, b, &c);
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-clear-padding-1.c b/gcc/testsuite/gcc.dg/builtin-clear-padding-1.c
new file mode 100644
index 0000000..27ffc0a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-clear-padding-1.c
@@ -0,0 +1,10 @@
+/* PR libstdc++/88101 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+foo (int n)
+{
+ struct S { char a; int b[n]; long long c; } s;
+ __builtin_clear_padding (&s); /* { dg-message "unimplemented: __builtin_clear_padding not supported for variable length aggregates" } */
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-clear-padding-2.c b/gcc/testsuite/gcc.dg/builtin-clear-padding-2.c
new file mode 100644
index 0000000..641d47d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-clear-padding-2.c
@@ -0,0 +1,15 @@
+/* PR middle-end/97943 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+struct S { int a; char b[] __attribute__((aligned (2 * sizeof (int)))); };
+struct T { int a; struct S b; int c; };
+union U { int a; struct S b; };
+struct V { int a; union U b; int : 15; int c; };
+
+void
+foo (struct T *t, struct V *v)
+{
+ __builtin_clear_padding (t); /* { dg-error "flexible array member 'b' does not have well defined padding bits for '__builtin_clear_padding'" } */
+ __builtin_clear_padding (v); /* { dg-error "flexible array member 'b' does not have well defined padding bits for '__builtin_clear_padding'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/c11-binary-constants-1.c b/gcc/testsuite/gcc.dg/c11-binary-constants-1.c
new file mode 100644
index 0000000..fdc7df4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-binary-constants-1.c
@@ -0,0 +1,11 @@
+/* Test that binary constants are diagnosed in C11 mode: -pedantic. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic" } */
+
+int a = 0b1; /* { dg-warning "binary constants" } */
+#if 0b101 /* { dg-warning "binary constants" } */
+#endif
+
+int b = 0B1; /* { dg-warning "binary constants" } */
+#if 0B101 /* { dg-warning "binary constants" } */
+#endif
diff --git a/gcc/testsuite/gcc.dg/c11-binary-constants-2.c b/gcc/testsuite/gcc.dg/c11-binary-constants-2.c
new file mode 100644
index 0000000..6b48a5d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-binary-constants-2.c
@@ -0,0 +1,11 @@
+/* Test that binary constants are diagnosed in C11 mode: -pedantic-errors. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+int a = 0b1; /* { dg-error "binary constants" } */
+#if 0b101 /* { dg-error "binary constants" } */
+#endif
+
+int b = 0B1; /* { dg-error "binary constants" } */
+#if 0B101 /* { dg-error "binary constants" } */
+#endif
diff --git a/gcc/testsuite/gcc.dg/c11-compare-incomplete-1.c b/gcc/testsuite/gcc.dg/c11-compare-incomplete-1.c
new file mode 100644
index 0000000..b1c05cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-compare-incomplete-1.c
@@ -0,0 +1,52 @@
+/* Test comparisons of pointers to complete and incomplete types are
+ accepted in C11 mode. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+int
+f (int (*p)[], int (*q)[3])
+{
+ return p < q;
+}
+
+int
+f2 (int (*p)[], int (*q)[3])
+{
+ return p <= q;
+}
+
+int
+f3 (int (*p)[], int (*q)[3])
+{
+ return p > q;
+}
+
+int
+f4 (int (*p)[], int (*q)[3])
+{
+ return p >= q;
+}
+
+int
+g (int (*p)[], int (*q)[3])
+{
+ return q < p;
+}
+
+int
+g2 (int (*p)[], int (*q)[3])
+{
+ return q <= p;
+}
+
+int
+g3 (int (*p)[], int (*q)[3])
+{
+ return q > p;
+}
+
+int
+g4 (int (*p)[], int (*q)[3])
+{
+ return q >= p;
+}
diff --git a/gcc/testsuite/gcc.dg/c11-compare-incomplete-2.c b/gcc/testsuite/gcc.dg/c11-compare-incomplete-2.c
new file mode 100644
index 0000000..8e809e8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-compare-incomplete-2.c
@@ -0,0 +1,52 @@
+/* Test comparisons of pointers to complete and incomplete types are
+ diagnosed in C11 mode with -Wc99-c11-compat. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors -Wc99-c11-compat" } */
+
+int
+f (int (*p)[], int (*q)[3])
+{
+ return p < q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+f2 (int (*p)[], int (*q)[3])
+{
+ return p <= q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+f3 (int (*p)[], int (*q)[3])
+{
+ return p > q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+f4 (int (*p)[], int (*q)[3])
+{
+ return p >= q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g (int (*p)[], int (*q)[3])
+{
+ return q < p; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g2 (int (*p)[], int (*q)[3])
+{
+ return q <= p; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g3 (int (*p)[], int (*q)[3])
+{
+ return q > p; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g4 (int (*p)[], int (*q)[3])
+{
+ return q >= p; /* { dg-warning "complete and incomplete" } */
+}
diff --git a/gcc/testsuite/gcc.dg/c11-float-4.c b/gcc/testsuite/gcc.dg/c11-float-4.c
new file mode 100644
index 0000000..ceac6ef
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-float-4.c
@@ -0,0 +1,25 @@
+/* Test infinity and NaN macros not defined for C11. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <float.h>
+
+#ifdef INFINITY
+#error "INFINITY defined"
+#endif
+
+#ifdef NAN
+#error "NAN defined"
+#endif
+
+#ifdef FLT_SNAN
+#error "FLT_SNAN defined"
+#endif
+
+#ifdef DBL_SNAN
+#error "DBL_SNAN defined"
+#endif
+
+#ifdef LDBL_SNAN
+#error "LDBL_SNAN defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c11-float-5.c b/gcc/testsuite/gcc.dg/c11-float-5.c
new file mode 100644
index 0000000..bb48695
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-float-5.c
@@ -0,0 +1,35 @@
+/* Test sNaN macros for _FloatN and _FloatNx not defined for C11 with
+ __STDC_WANT_IEC_60559_TYPES_EXT__. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+
+#ifdef FLT16_SNAN
+#error "FLT16_SNAN defined"
+#endif
+
+#ifdef FLT32_SNAN
+#error "FLT32_SNAN defined"
+#endif
+
+#ifdef FLT64_SNAN
+#error "FLT64_SNAN defined"
+#endif
+
+#ifdef FLT128_SNAN
+#error "FLT128_SNAN defined"
+#endif
+
+#ifdef FLT32X_SNAN
+#error "FLT32X_SNAN defined"
+#endif
+
+#ifdef FLT64X_SNAN
+#error "FLT64X_SNAN defined"
+#endif
+
+#ifdef FLT128X_SNAN
+#error "FLT128X_SNAN defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c11-float-6.c b/gcc/testsuite/gcc.dg/c11-float-6.c
new file mode 100644
index 0000000..b0381e5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-float-6.c
@@ -0,0 +1,17 @@
+/* Test *_IS_IEC_60559 not defined for C11. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <float.h>
+
+#ifdef FLT_IS_IEC_60559
+#error "FLT_IS_IEC_60559 defined"
+#endif
+
+#ifdef DBL_IS_IEC_60559
+#error "DBL_IS_IEC_60559 defined"
+#endif
+
+#ifdef LDBL_IS_IEC_60559
+#error "LDBL_IS_IEC_60559 defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c11-float-dfp-2.c b/gcc/testsuite/gcc.dg/c11-float-dfp-2.c
new file mode 100644
index 0000000..e63ebbc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-float-dfp-2.c
@@ -0,0 +1,6 @@
+/* Test DFP macros not defined in <float.h> for C11. Infinity and NaN
+ macros. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11" } */
+
+#include "c2x-float-no-dfp-3.c"
diff --git a/gcc/testsuite/gcc.dg/c2x-binary-constants-1.c b/gcc/testsuite/gcc.dg/c2x-binary-constants-1.c
new file mode 100644
index 0000000..bbb2bc8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-binary-constants-1.c
@@ -0,0 +1,5 @@
+/* Test C2x binary constants. Valid syntax and types. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include "binary-constants-1.c"
diff --git a/gcc/testsuite/gcc.dg/c2x-binary-constants-2.c b/gcc/testsuite/gcc.dg/c2x-binary-constants-2.c
new file mode 100644
index 0000000..4379427
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-binary-constants-2.c
@@ -0,0 +1,11 @@
+/* Test that binary constants are accepted in C2X mode: compat warnings. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -Wc11-c2x-compat" } */
+
+int a = 0b1; /* { dg-warning "C2X feature" } */
+#if 0b101 /* { dg-warning "C2X feature" } */
+#endif
+
+int b = 0B1; /* { dg-warning "C2X feature" } */
+#if 0B101 /* { dg-warning "C2X feature" } */
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-binary-constants-3.c b/gcc/testsuite/gcc.dg/c2x-binary-constants-3.c
new file mode 100644
index 0000000..7604791f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-binary-constants-3.c
@@ -0,0 +1,9 @@
+/* Test C2x binary constants. Invalid constants. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+int a = 0b; /* { dg-error "invalid suffix" } */
+int b = 0B2; /* { dg-error "invalid suffix" } */
+int c = 0B02; /* { dg-error "invalid digit" } */
+int d = 0b1.1; /* { dg-error "invalid prefix" } */
+int e = 0B0p0; /* { dg-error "invalid suffix" } */
diff --git a/gcc/testsuite/gcc.dg/c2x-float-10.c b/gcc/testsuite/gcc.dg/c2x-float-10.c
new file mode 100644
index 0000000..7b53a6a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-10.c
@@ -0,0 +1,33 @@
+/* Test *_IS_IEC_60559 macros. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include <float.h>
+
+#ifndef FLT_IS_IEC_60559
+#error "FLT_IS_IEC_60559 undefined"
+#endif
+
+#ifndef DBL_IS_IEC_60559
+#error "DBL_IS_IEC_60559 undefined"
+#endif
+
+#ifndef LDBL_IS_IEC_60559
+#error "LDBL_IS_IEC_60559 undefined"
+#endif
+
+#if defined __pdp11__ || defined __vax__
+_Static_assert (FLT_IS_IEC_60559 == 0);
+_Static_assert (DBL_IS_IEC_60559 == 0);
+_Static_assert (LDBL_IS_IEC_60559 == 0);
+#else
+_Static_assert (FLT_IS_IEC_60559 == 2);
+_Static_assert (DBL_IS_IEC_60559 == 2);
+#if LDBL_MANT_DIG == 106 || LDBL_MIN_EXP == -16382
+/* IBM long double and m68k extended format do not meet the definition
+ of an IEC 60559 interchange or extended format. */
+_Static_assert (LDBL_IS_IEC_60559 == 0);
+#else
+_Static_assert (LDBL_IS_IEC_60559 == 2);
+#endif
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-float-2.c b/gcc/testsuite/gcc.dg/c2x-float-2.c
new file mode 100644
index 0000000..4f669fd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-2.c
@@ -0,0 +1,23 @@
+/* Test INFINITY macro. Generic test even if infinities not
+ supported. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -w" } */
+/* { dg-add-options ieee } */
+
+#include <float.h>
+
+#ifndef INFINITY
+#error "INFINITY undefined"
+#endif
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ (void) _Generic (INFINITY, float : 0);
+ if (!(INFINITY >= FLT_MAX))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-float-3.c b/gcc/testsuite/gcc.dg/c2x-float-3.c
new file mode 100644
index 0000000..7c6298b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-3.c
@@ -0,0 +1,27 @@
+/* Test INFINITY macro. Test when infinities supported. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target inff } */
+
+#include <float.h>
+
+#ifndef INFINITY
+#error "INFINITY undefined"
+#endif
+
+volatile float f = INFINITY;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ (void) _Generic (INFINITY, float : 0);
+ if (!(INFINITY > FLT_MAX))
+ abort ();
+ if (!(f > FLT_MAX))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-float-4.c b/gcc/testsuite/gcc.dg/c2x-float-4.c
new file mode 100644
index 0000000..bca8435
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-4.c
@@ -0,0 +1,33 @@
+/* Test NAN macro. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+/* { dg-add-options ieee } */
+
+#include <float.h>
+
+/* This should be defined if and only if quiet NaNs are supported for
+ type float. If the testsuite gains effective-target support for
+ targets not supporting NaNs, or not supporting them for all types,
+ this test should be split into versions for targets with and
+ without NaNs for float. */
+#ifndef NAN
+#error "NAN undefined"
+#endif
+
+volatile float f = NAN;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ (void) _Generic (NAN, float : 0);
+ if (!__builtin_isnan (NAN))
+ abort ();
+ if (!__builtin_isnan (f))
+ abort ();
+ if (!__builtin_isnan (f + f))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-float-5.c b/gcc/testsuite/gcc.dg/c2x-float-5.c
new file mode 100644
index 0000000..477f9cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-5.c
@@ -0,0 +1,32 @@
+/* Test NAN macro. Runtime exceptions test, to verify NaN is quiet
+ not signaling. */
+/* { dg-do run } */
+/* { dg-require-effective-target fenv_exceptions } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+/* { dg-add-options ieee } */
+
+#include <fenv.h>
+#include <float.h>
+
+/* This should be defined if and only if quiet NaNs are supported for
+ type float. If the testsuite gains effective-target support for
+ targets not supporting NaNs, or not supporting them for all types,
+ this test should only be run for targets supporting quiet NaNs for
+ float. */
+#ifndef NAN
+#error "NAN undefined"
+#endif
+
+volatile float f = NAN;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ f += f;
+ if (fetestexcept (FE_INVALID))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-float-6.c b/gcc/testsuite/gcc.dg/c2x-float-6.c
new file mode 100644
index 0000000..573540b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-6.c
@@ -0,0 +1,49 @@
+/* Test SNAN macros. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -pedantic-errors -fsignaling-nans" } */
+/* { dg-add-options ieee } */
+
+#include <float.h>
+
+/* These should be defined if and only if signaling NaNs are supported
+ for the given types. If the testsuite gains effective-target
+ support for targets not supporting signaling NaNs, or not
+ supporting them for all types, this test should be made
+ appropriately conditional. */
+#ifndef FLT_SNAN
+#error "FLT_SNAN undefined"
+#endif
+#ifndef DBL_SNAN
+#error "DBL_SNAN undefined"
+#endif
+#ifndef LDBL_SNAN
+#error "LDBL_SNAN undefined"
+#endif
+
+volatile float f = FLT_SNAN;
+volatile double d = DBL_SNAN;
+volatile long double ld = LDBL_SNAN;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ (void) _Generic (FLT_SNAN, float : 0);
+ (void) _Generic (DBL_SNAN, double : 0);
+ (void) _Generic (LDBL_SNAN, long double : 0);
+ if (!__builtin_isnan (FLT_SNAN))
+ abort ();
+ if (!__builtin_isnan (f))
+ abort ();
+ if (!__builtin_isnan (DBL_SNAN))
+ abort ();
+ if (!__builtin_isnan (d))
+ abort ();
+ if (!__builtin_isnan (LDBL_SNAN))
+ abort ();
+ if (!__builtin_isnan (ld))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-float-7.c b/gcc/testsuite/gcc.dg/c2x-float-7.c
new file mode 100644
index 0000000..0c90ff2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-7.c
@@ -0,0 +1,49 @@
+/* Test SNAN macros. Runtime exceptions test, to verify NaN is
+ signaling. */
+/* { dg-do run } */
+/* { dg-require-effective-target fenv_exceptions } */
+/* { dg-options "-std=c2x -pedantic-errors -fsignaling-nans" } */
+/* { dg-add-options ieee } */
+
+#include <fenv.h>
+#include <float.h>
+
+/* These should be defined if and only if signaling NaNs are supported
+ for the given types. If the testsuite gains effective-target
+ support for targets not supporting signaling NaNs, or not
+ supporting them for all types, this test should be made
+ appropriately conditional. */
+#ifndef FLT_SNAN
+#error "FLT_SNAN undefined"
+#endif
+#ifndef DBL_SNAN
+#error "DBL_SNAN undefined"
+#endif
+#ifndef LDBL_SNAN
+#error "LDBL_SNAN undefined"
+#endif
+
+volatile float f = FLT_SNAN;
+volatile double d = DBL_SNAN;
+volatile long double ld = LDBL_SNAN;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ feclearexcept (FE_ALL_EXCEPT);
+ f += f;
+ if (!fetestexcept (FE_INVALID))
+ abort ();
+ feclearexcept (FE_ALL_EXCEPT);
+ d += d;
+ if (!fetestexcept (FE_INVALID))
+ abort ();
+ feclearexcept (FE_ALL_EXCEPT);
+ ld += ld;
+ if (!fetestexcept (FE_INVALID))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-float-8.c b/gcc/testsuite/gcc.dg/c2x-float-8.c
new file mode 100644
index 0000000..b10cb85
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-8.c
@@ -0,0 +1,7 @@
+/* Test including <math.h> then <float.h> does not result in errors
+ from duplicate NAN and INFINITY macros. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include <math.h>
+#include <float.h>
diff --git a/gcc/testsuite/gcc.dg/c2x-float-9.c b/gcc/testsuite/gcc.dg/c2x-float-9.c
new file mode 100644
index 0000000..0a54bc2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-9.c
@@ -0,0 +1,7 @@
+/* Test including <float.h> then <math.h> does not result in errors
+ from duplicate NAN and INFINITY macros. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include <float.h>
+#include <math.h>
diff --git a/gcc/testsuite/gcc.dg/c2x-float-no-dfp-3.c b/gcc/testsuite/gcc.dg/c2x-float-no-dfp-3.c
new file mode 100644
index 0000000..aa790c8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-no-dfp-3.c
@@ -0,0 +1,26 @@
+/* Test DFP macros not defined in <float.h> if no DFP support.
+ Infinity and NaN macros. */
+/* { dg-do compile { target { ! dfp } } } */
+/* { dg-options "-std=c2x" } */
+
+#include <float.h>
+
+#ifdef DEC_INFINITY
+# error "DEC_INFINITY defined"
+#endif
+
+#ifdef DEC_NAN
+# error "DEC_NAN defined"
+#endif
+
+#ifdef DEC32_SNAN
+# error "DEC32_SNAN defined"
+#endif
+
+#ifdef DEC64_SNAN
+# error "DEC64_SNAN defined"
+#endif
+
+#ifdef DEC128_SNAN
+# error "DEC128_SNAN defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-float-no-dfp-4.c b/gcc/testsuite/gcc.dg/c2x-float-no-dfp-4.c
new file mode 100644
index 0000000..855922a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-no-dfp-4.c
@@ -0,0 +1,10 @@
+/* Test DFP macros not defined in <float.h> if no DFP support.
+ Infinity and NaN macros. Test with feature test macros
+ defined. */
+/* { dg-do compile { target { ! dfp } } } */
+/* { dg-options "-std=c2x" } */
+
+#define __STDC_WANT_DEC_FP__
+#define __STDC_WANT_IEC_60559_DFP_EXT__
+
+#include "c2x-float-no-dfp-3.c"
diff --git a/gcc/testsuite/gcc.dg/c2x-has-c-attribute-1.c b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-1.c
new file mode 100644
index 0000000..fe06abf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-1.c
@@ -0,0 +1,28 @@
+/* Test __has_c_attribute. Test basic properties. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#ifdef __has_c_attribute
+/* OK. */
+#else
+#error "__has_c_attribute not defined"
+#endif
+
+#ifndef __has_c_attribute
+#error "__has_c_attribute not defined"
+#endif
+
+#if defined __has_c_attribute
+/* OK. */
+#else
+#error "__has_c_attribute not defined"
+#endif
+
+#if __has_c_attribute(foo)
+#error "foo attribute supported"
+#endif
+
+#if 0
+#elif __has_c_attribute(foo)
+#error "foo attribute supported"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-has-c-attribute-2.c b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-2.c
new file mode 100644
index 0000000..d6c4c6d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-2.c
@@ -0,0 +1,41 @@
+/* Test __has_c_attribute. Test supported attributes. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#if __has_c_attribute ( nodiscard ) != 202003L
+#error "bad result for nodiscard"
+#endif
+
+#if __has_c_attribute ( __nodiscard__ ) != 202003L
+#error "bad result for __nodiscard__"
+#endif
+
+#if __has_c_attribute(maybe_unused) != 201904L
+#error "bad result for maybe_unused"
+#endif
+
+#if __has_c_attribute(__maybe_unused__) != 201904L
+#error "bad result for __maybe_unused__"
+#endif
+
+#if __has_c_attribute (deprecated) != 201904L
+#error "bad result for deprecated"
+#endif
+
+#if __has_c_attribute (__deprecated__) != 201904L
+#error "bad result for __deprecated__"
+#endif
+
+#if __has_c_attribute (fallthrough) != 201904L
+#error "bad result for fallthrough"
+#endif
+
+#if __has_c_attribute (__fallthrough__) != 201904L
+#error "bad result for __fallthrough__"
+#endif
+
+/* Macros in the attribute name are expanded. */
+#define foo deprecated
+#if __has_c_attribute (foo) != 201904L
+#error "bad result for foo"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-has-c-attribute-3.c b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-3.c
new file mode 100644
index 0000000..36842ed
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-3.c
@@ -0,0 +1,25 @@
+/* Test __has_c_attribute. Test GNU attributes. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#if __has_c_attribute (gnu::packed) != 1
+#error "bad result for gnu::packed"
+#endif
+
+#if __has_c_attribute (__gnu__::__packed__) != 1
+#error "bad result for __gnu__::__packed__"
+#endif
+
+#if __has_c_attribute (gnu::__packed__) != 1
+#error "bad result for gnu::__packed__"
+#endif
+
+#if __has_c_attribute (__gnu__::packed) != 1
+#error "bad result for __gnu__::packed"
+#endif
+
+/* GNU attributes should not be reported as accepted without a scope
+ specified. */
+#if __has_c_attribute (packed) != 0
+#error "bad result for packed"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-has-c-attribute-4.c b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-4.c
new file mode 100644
index 0000000..acd35d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-4.c
@@ -0,0 +1,18 @@
+/* Test __has_c_attribute. Test syntax errors. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#if __has_c_attribute /* { dg-error "missing '\\('" } */
+#endif
+
+#if __has_c_attribute 0 /* { dg-error "missing '\\('" } */
+#endif
+
+#if __has_c_attribute (0 /* { dg-error "requires an identifier" } */
+#endif
+
+#if __has_c_attribute (x /* { dg-error "missing '\\)'" } */
+#endif
+
+#if __has_c_attribute (x::0) /* { dg-error "required after scope" } */
+#endif
diff --git a/gcc/testsuite/gcc.dg/c99-compare-incomplete-1.c b/gcc/testsuite/gcc.dg/c99-compare-incomplete-1.c
new file mode 100644
index 0000000..dfafc39
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c99-compare-incomplete-1.c
@@ -0,0 +1,52 @@
+/* Test comparisons of pointers to complete and incomplete types are
+ diagnosed in C99 mode: -pedantic. */
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -pedantic" } */
+
+int
+f (int (*p)[], int (*q)[3])
+{
+ return p < q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+f2 (int (*p)[], int (*q)[3])
+{
+ return p <= q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+f3 (int (*p)[], int (*q)[3])
+{
+ return p > q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+f4 (int (*p)[], int (*q)[3])
+{
+ return p >= q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g (int (*p)[], int (*q)[3])
+{
+ return q < p; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g2 (int (*p)[], int (*q)[3])
+{
+ return q <= p; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g3 (int (*p)[], int (*q)[3])
+{
+ return q > p; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g4 (int (*p)[], int (*q)[3])
+{
+ return q >= p; /* { dg-warning "complete and incomplete" } */
+}
diff --git a/gcc/testsuite/gcc.dg/c99-compare-incomplete-2.c b/gcc/testsuite/gcc.dg/c99-compare-incomplete-2.c
new file mode 100644
index 0000000..5ae7f30
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c99-compare-incomplete-2.c
@@ -0,0 +1,52 @@
+/* Test comparisons of pointers to complete and incomplete types are
+ diagnosed in C99 mode: -pedantic-errors. */
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -pedantic-errors" } */
+
+int
+f (int (*p)[], int (*q)[3])
+{
+ return p < q; /* { dg-error "complete and incomplete" } */
+}
+
+int
+f2 (int (*p)[], int (*q)[3])
+{
+ return p <= q; /* { dg-error "complete and incomplete" } */
+}
+
+int
+f3 (int (*p)[], int (*q)[3])
+{
+ return p > q; /* { dg-error "complete and incomplete" } */
+}
+
+int
+f4 (int (*p)[], int (*q)[3])
+{
+ return p >= q; /* { dg-error "complete and incomplete" } */
+}
+
+int
+g (int (*p)[], int (*q)[3])
+{
+ return q < p; /* { dg-error "complete and incomplete" } */
+}
+
+int
+g2 (int (*p)[], int (*q)[3])
+{
+ return q <= p; /* { dg-error "complete and incomplete" } */
+}
+
+int
+g3 (int (*p)[], int (*q)[3])
+{
+ return q > p; /* { dg-error "complete and incomplete" } */
+}
+
+int
+g4 (int (*p)[], int (*q)[3])
+{
+ return q >= p; /* { dg-error "complete and incomplete" } */
+}
diff --git a/gcc/testsuite/gcc.dg/cond-constqual-1.c b/gcc/testsuite/gcc.dg/cond-constqual-1.c
index 3354c72..b5a09cb 100644
--- a/gcc/testsuite/gcc.dg/cond-constqual-1.c
+++ b/gcc/testsuite/gcc.dg/cond-constqual-1.c
@@ -11,5 +11,5 @@ test (void)
__typeof__ (1 ? foo (0) : 0) texpr;
__typeof__ (1 ? i : 0) texpr2;
texpr = 0; /* { dg-bogus "read-only variable" "conditional expression with call to const function" } */
- texpr2 = 0; /* { dg-error "read-only variable" "conditional expression with const variable" } */
+ texpr2 = 0; /* { dg-bogus "read-only variable" "conditional expression with const variable" } */
}
diff --git a/gcc/testsuite/gcc.dg/cpp/line10.c b/gcc/testsuite/gcc.dg/cpp/line10.c
new file mode 100644
index 0000000..9f5f079
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/line10.c
@@ -0,0 +1,5 @@
+/* Test #line overflow checks: bug 97602. */
+/* { dg-do preprocess } */
+/* { dg-options "-pedantic" } */
+
+#line 4294967296 /* { dg-warning "line number out of range" } */
diff --git a/gcc/testsuite/gcc.dg/cpp/line9.c b/gcc/testsuite/gcc.dg/cpp/line9.c
new file mode 100644
index 0000000..8060aff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/line9.c
@@ -0,0 +1,5 @@
+/* Test #line overflow checks: bug 97602. */
+/* { dg-do preprocess } */
+/* { dg-options "-pedantic" } */
+
+#line 5000000000 /* { dg-warning "line number out of range" } */
diff --git a/gcc/testsuite/gcc.dg/cpp/pr97989-1.c b/gcc/testsuite/gcc.dg/cpp/pr97989-1.c
new file mode 100644
index 0000000..108dcba
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/pr97989-1.c
@@ -0,0 +1,8 @@
+/* PR debug/97989 */
+/* { dg-do preprocess } */
+/* { dg-options "-g3 -g2 -P" } */
+
+#define foo bar
+int i;
+
+/* { dg-final { scan-file-not pr97989-1.i "(^|\\n)#define foo bar($|\\n)" } } */
diff --git a/gcc/testsuite/gcc.dg/cpp/pr97989-2.c b/gcc/testsuite/gcc.dg/cpp/pr97989-2.c
new file mode 100644
index 0000000..77a295a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/pr97989-2.c
@@ -0,0 +1,8 @@
+/* PR debug/97989 */
+/* { dg-do preprocess } */
+/* { dg-options "-g2 -g3 -P" } */
+
+#define foo bar
+int i;
+
+/* { dg-final { scan-file pr97989-2.i "(^|\\n)#define foo bar($|\\n)" } } */
diff --git a/gcc/testsuite/gcc.dg/cr-decimal-dig-3.c b/gcc/testsuite/gcc.dg/cr-decimal-dig-3.c
new file mode 100644
index 0000000..8e07b67
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cr-decimal-dig-3.c
@@ -0,0 +1,14 @@
+/* Test C2x CR_DECIMAL_DIG: defined for __STDC_WANT_IEC_60559_EXT__. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x" } */
+
+#define __STDC_WANT_IEC_60559_EXT__
+#include <float.h>
+
+#ifndef CR_DECIMAL_DIG
+#error "CR_DECIMAL_DIG not defined"
+#endif
+
+#if CR_DECIMAL_DIG < DECIMAL_DIG + 3
+#error "CR_DECIMAL_DIG too small"
+#endif
diff --git a/gcc/testsuite/gcc.dg/darwin-sections.c b/gcc/testsuite/gcc.dg/darwin-sections.c
index dbe3702..5fc2860 100644
--- a/gcc/testsuite/gcc.dg/darwin-sections.c
+++ b/gcc/testsuite/gcc.dg/darwin-sections.c
@@ -10,7 +10,9 @@ typedef struct _empty {} e_s;
/* These should go in .comm */
char ub;
e_s ea;
+/* { dg-final { scan-assembler-symbol-section {^_a$} {\.data} } } */
/* { dg-final { scan-assembler ".comm\[\t \]_ub,1" } } */
+/* { dg-final { scan-assembler-symbol-section {^_b$} {\.data} } } */
/* { dg-final { scan-assembler ".comm\[\t \]_ea,1" } } */
/* These should go into __DATA,__common */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr97060.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr97060.c
new file mode 100644
index 0000000..c07b904
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr97060.c
@@ -0,0 +1,13 @@
+/* PR debug/97060 */
+/* { dg-do compile } */
+/* { dg-options "-g -dA" } */
+/* { dg-final { scan-assembler-times "DW_AT_declaration" 2 } } */
+
+extern int foo (unsigned int, unsigned int);
+
+int
+bar (void)
+{
+ foo (1, 2);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-4.c b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-4.c
new file mode 100644
index 0000000..58ee74d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-4.c
@@ -0,0 +1,25 @@
+/* Test DEC_INFINITY defined in <float.h> with DFP support. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x" } */
+
+#include <float.h>
+
+#ifndef DEC_INFINITY
+# error "DEC_INFINITY not defined"
+#endif
+
+volatile _Decimal32 d = DEC_INFINITY;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ (void) _Generic (DEC_INFINITY, _Decimal32 : 0);
+ if (!(DEC_INFINITY > DEC32_MAX))
+ abort ();
+ if (!(d > DEC32_MAX))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-5.c b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-5.c
new file mode 100644
index 0000000..8d09725
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-5.c
@@ -0,0 +1,25 @@
+/* Test DEC_NAN defined in <float.h> with DFP support. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x" } */
+
+#include <float.h>
+
+#ifndef DEC_NAN
+# error "DEC_NAN not defined"
+#endif
+
+volatile _Decimal32 d = DEC_NAN;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ (void) _Generic (DEC_NAN, _Decimal32 : 0);
+ if (!__builtin_isnan (DEC_NAN))
+ abort ();
+ if (!__builtin_isnan (d))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-6.c b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-6.c
new file mode 100644
index 0000000..4533c61
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-6.c
@@ -0,0 +1,28 @@
+/* Test DEC_NAN macro. Runtime exceptions test, to verify NaN is
+ quiet not signaling. (This would only actually fail for a
+ signaling NaN in the hardware DFP case, because the software DFP
+ support in libgcc does not integrate with hardware exceptions.) */
+/* { dg-do run } */
+/* { dg-require-effective-target fenv_exceptions } */
+/* { dg-options "-std=c2x" } */
+
+#include <fenv.h>
+#include <float.h>
+
+#ifndef DEC_NAN
+# error "DEC_NAN not defined"
+#endif
+
+volatile _Decimal32 d = DEC_NAN;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ d += d;
+ if (fetestexcept (FE_INVALID))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-7.c b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-7.c
new file mode 100644
index 0000000..dec6b50
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-7.c
@@ -0,0 +1,45 @@
+/* Test DEC*_SNAN macros defined in <float.h> with DFP support. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x" } */
+
+#include <float.h>
+
+#ifndef DEC32_SNAN
+# error "DEC32_SNAN not defined"
+#endif
+
+#ifndef DEC64_SNAN
+# error "DEC64_SNAN not defined"
+#endif
+
+#ifndef DEC128_SNAN
+# error "DEC128_SNAN not defined"
+#endif
+
+volatile _Decimal32 d32 = DEC32_SNAN;
+volatile _Decimal64 d64 = DEC64_SNAN;
+volatile _Decimal128 d128 = DEC128_SNAN;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ (void) _Generic (DEC32_SNAN, _Decimal32 : 0);
+ if (!__builtin_isnan (DEC32_SNAN))
+ abort ();
+ if (!__builtin_isnan (d32))
+ abort ();
+ (void) _Generic (DEC64_SNAN, _Decimal64 : 0);
+ if (!__builtin_isnan (DEC64_SNAN))
+ abort ();
+ if (!__builtin_isnan (d64))
+ abort ();
+ (void) _Generic (DEC128_SNAN, _Decimal128 : 0);
+ if (!__builtin_isnan (DEC128_SNAN))
+ abort ();
+ if (!__builtin_isnan (d128))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-8.c b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-8.c
new file mode 100644
index 0000000..4169602
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-8.c
@@ -0,0 +1,45 @@
+/* Test DEC*_SNAN macros. Test requiring runtime exceptions
+ support. */
+/* { dg-do run } */
+/* { dg-require-effective-target fenv_exceptions_dfp } */
+/* { dg-options "-std=c2x" } */
+
+#include <fenv.h>
+#include <float.h>
+
+volatile _Decimal32 d32 = DEC32_SNAN;
+volatile _Decimal64 d64 = DEC64_SNAN;
+volatile _Decimal128 d128 = DEC128_SNAN;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ feclearexcept (FE_ALL_EXCEPT);
+ d32 += d32;
+ if (!fetestexcept (FE_INVALID))
+ abort ();
+ feclearexcept (FE_ALL_EXCEPT);
+ d32 += d32;
+ if (fetestexcept (FE_INVALID))
+ abort ();
+ feclearexcept (FE_ALL_EXCEPT);
+ d64 += d64;
+ if (!fetestexcept (FE_INVALID))
+ abort ();
+ feclearexcept (FE_ALL_EXCEPT);
+ d64 += d64;
+ if (fetestexcept (FE_INVALID))
+ abort ();
+ feclearexcept (FE_ALL_EXCEPT);
+ d128 += d128;
+ if (!fetestexcept (FE_INVALID))
+ abort ();
+ feclearexcept (FE_ALL_EXCEPT);
+ d128 += d128;
+ if (fetestexcept (FE_INVALID))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/fold-isfinite-1.c b/gcc/testsuite/gcc.dg/fold-isfinite-1.c
new file mode 100644
index 0000000..2ea0192
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-isfinite-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target inf } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo(int x)
+{
+ return __builtin_finite((double)x);
+}
+
+int foof(int x)
+{
+ return __builtin_finitef((float)x);
+}
+
+int fool(int x)
+{
+ return __builtin_finitel((long double)x);
+}
+
+/* { dg-final { scan-tree-dump-times "_finite" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " u> " 0 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/fold-isfinite-2.c b/gcc/testsuite/gcc.dg/fold-isfinite-2.c
new file mode 100644
index 0000000..ff70d8d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-isfinite-2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target inf } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo(unsigned int x)
+{
+ return __builtin_finite((double)x);
+}
+
+int foof(unsigned int x)
+{
+ return __builtin_finitef((float)x);
+}
+
+int fool(unsigned int x)
+{
+ return __builtin_finitel((long double)x);
+}
+
+/* { dg-final { scan-tree-dump-times "_finite" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " u> " 0 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/fold-isinf-1.c b/gcc/testsuite/gcc.dg/fold-isinf-1.c
new file mode 100644
index 0000000..485816e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-isinf-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target inf } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo(int x)
+{
+ return __builtin_isinf((double)x);
+}
+
+int foof(int x)
+{
+ return __builtin_isinff((float)x);
+}
+
+int fool(int x)
+{
+ return __builtin_isinfl((long double)x);
+}
+
+/* { dg-final { scan-tree-dump-times "_isinf" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " u<= " 0 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/fold-isinf-2.c b/gcc/testsuite/gcc.dg/fold-isinf-2.c
new file mode 100644
index 0000000..a236ca1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-isinf-2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target inf } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo(unsigned int x)
+{
+ return __builtin_isinf((double)x);
+}
+
+int foof(unsigned int x)
+{
+ return __builtin_isinff((float)x);
+}
+
+int fool(unsigned int x)
+{
+ return __builtin_isinfl((long double)x);
+}
+
+/* { dg-final { scan-tree-dump-times "_isinf" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " u<= " 0 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/fold-isnan-1.c b/gcc/testsuite/gcc.dg/fold-isnan-1.c
new file mode 100644
index 0000000..05ee930
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-isnan-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target inf } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo(int x)
+{
+ return __builtin_isnan((double)x);
+}
+
+int foof(int x)
+{
+ return __builtin_isnanf((float)x);
+}
+
+int fool(int x)
+{
+ return __builtin_isnanl((long double)x);
+}
+
+/* { dg-final { scan-tree-dump-times "_isnan" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " unord " 0 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/fold-isnan-2.c b/gcc/testsuite/gcc.dg/fold-isnan-2.c
new file mode 100644
index 0000000..32b8833
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-isnan-2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target inf } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo(unsigned int x)
+{
+ return __builtin_isnan((double)x);
+}
+
+int foof(unsigned int x)
+{
+ return __builtin_isnanf((float)x);
+}
+
+int fool(unsigned int x)
+{
+ return __builtin_isnanl((long double)x);
+}
+
+/* { dg-final { scan-tree-dump-times "_isnan" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " unord " 0 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c b/gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c
index d8c51ea..f46f155 100644
--- a/gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c
+++ b/gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c
@@ -9,13 +9,33 @@
#include "format.h"
void
-foo (int i, char *s, size_t n, va_list v0, va_list v1, va_list v2, va_list v3,
+foo (int i, char *s, size_t n, long l, llong ll, double d,
+ long double ld, va_list v0, va_list v1, va_list v2, va_list v3,
va_list v4, va_list v5, va_list v6, va_list v7)
{
fprintf (stdout, "%d", i);
fprintf (stdout, "%ld", i); /* { dg-warning "format" "fprintf" } */
printf ("%d", i);
printf ("%ld", i); /* { dg-warning "format" "printf" } */
+ /* These are accepted since MSVCR80, MSVCRT from Vista, UCRT,
+ * and mingw-w64 8.0 with C99/C++11. */
+ printf ("%lld", i); /* { dg-warning "format" "printf" } */
+ printf ("%lld", l); /* { dg-warning "format" "printf" } */
+ printf ("%lld", ll);
+ printf ("%llu", i); /* { dg-warning "format" "printf" } */
+ printf ("%llu", l); /* { dg-warning "format" "printf" } */
+ printf ("%llu", ll);
+ printf ("%llx", i); /* { dg-warning "format" "printf" } */
+ printf ("%llx", l); /* { dg-warning "format" "printf" } */
+ printf ("%llx", ll);
+ /* As MSABI uses an 8-byte `long double`, `%Lg` matches GCC's
+ * `double` instead of `long double` which takes 10 bytes. */
+ printf ("%Lg", d);
+ printf ("%Lg", ld); /* { dg-warning "format" "printf" } */
+ printf ("%Le", d);
+ printf ("%Le", ld); /* { dg-warning "format" "printf" } */
+ printf ("%Lf", d);
+ printf ("%Lf", ld); /* { dg-warning "format" "printf" } */
/* The "unlocked" functions shouldn't warn in c99 mode. */
fprintf_unlocked (stdout, "%ld", i);
printf_unlocked ("%ld", i);
diff --git a/gcc/testsuite/gcc.dg/goacc/tile-1.c b/gcc/testsuite/gcc.dg/goacc/tile-1.c
new file mode 100644
index 0000000..6898397
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/goacc/tile-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+
+/* PR c/97880 */
+
+void f ()
+{
+ #pragma acc parallel loop tile(2, 3)
+ for (int i = 0; i < 8; i++)
+ for (long j = 0; j < 8; j++);
+}
diff --git a/gcc/testsuite/gcc.dg/guality/pr59776.c b/gcc/testsuite/gcc.dg/guality/pr59776.c
index 6c1c816..7c95a9f 100644
--- a/gcc/testsuite/gcc.dg/guality/pr59776.c
+++ b/gcc/testsuite/gcc.dg/guality/pr59776.c
@@ -6,7 +6,7 @@
struct S { float f, g; };
-__attribute__((noinline, noclone)) void
+__attribute__((noipa)) void
foo (struct S *p)
{
struct S s1, s2; /* { dg-final { gdb-test pr59776.c:17 "s1.f" "5.0" } } */
diff --git a/gcc/testsuite/gcc.dg/hwasan/hwasan.exp b/gcc/testsuite/gcc.dg/hwasan/hwasan.exp
new file mode 100644
index 0000000..5c040ae
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/hwasan/hwasan.exp
@@ -0,0 +1,36 @@
+# Copyright (C) 2012-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/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gcc-dg.exp
+load_lib hwasan-dg.exp
+
+# Initialize `dg'.
+dg-init
+hwasan_init
+
+# Main loop.
+if [check_effective_target_fsanitize_hwaddress] {
+ gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/hwasan/*.c]] "" ""
+}
+
+# All done.
+hwasan_finish
+dg-finish
diff --git a/gcc/testsuite/gcc.dg/hwasan/nested-functions-0.c b/gcc/testsuite/gcc.dg/hwasan/nested-functions-0.c
new file mode 100644
index 0000000..0afcc10
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/hwasan/nested-functions-0.c
@@ -0,0 +1,53 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+
+/*
+ Tests of nested funtions are:
+ 0) Accessing closed over variables works.
+ 1) Accesses outside of variables is caught.
+ 2) Accessing variable out of scope is caught.
+
+ Here we test that accessing closed over variables works.
+ */
+
+/* We need a second layer of indirection so that GCC doesn't notice we're
+ returning the address of a local variable and put 0 in it's place. */
+__attribute__((noinline))
+int *Ident(void *x) {
+ return x;
+}
+
+int __attribute__ ((noinline))
+intermediate (void (*f) (int, char),
+ char num)
+{
+ if (num == 1)
+ /* NOTE: We need to overrun by an amount greater than the "extra data" in a
+ nonlocal goto structure. The entire structure is allocated on the stack
+ with a single tag, which means hwasan can't tell if a closed-over buffer
+ was overrun by an amount small enough that the access was still to some
+ data in that nonlocal goto structure. */
+ f (100, 100);
+ else
+ f (3, 100);
+ /* Just return something ... */
+ return num % 3;
+}
+
+int* __attribute__ ((noinline))
+nested_function (char num)
+{
+ int big_array[16];
+ int other_array[16];
+ void store (int index, char value)
+ { big_array[index] = value; }
+ return Ident(&other_array[intermediate (store, num)]);
+}
+
+#ifndef MAIN
+int main ()
+{
+ nested_function (0);
+ return 0;
+}
+#endif
diff --git a/gcc/testsuite/gcc.dg/hwasan/nested-functions-1.c b/gcc/testsuite/gcc.dg/hwasan/nested-functions-1.c
new file mode 100644
index 0000000..0161281
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/hwasan/nested-functions-1.c
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+
+/*
+ Tests of nested funtions are:
+ 0) Accessing closed over variables works.
+ 1) Accesses outside of variables is caught.
+ 2) Accessing variable out of scope is caught.
+
+ Here we test option 1.
+ */
+
+#define MAIN 0
+#include "nested-functions-0.c"
+#undef MAIN
+
+int main ()
+{
+ nested_function (1);
+ return 0;
+}
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* { dg-output "WRITE of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/gcc.dg/hwasan/nested-functions-2.c b/gcc/testsuite/gcc.dg/hwasan/nested-functions-2.c
new file mode 100644
index 0000000..b1a033f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/hwasan/nested-functions-2.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+
+/*
+ Tests of nested funtions are:
+ 0) Accessing closed over variables works.
+ 1) Accesses outside of variables is caught.
+ 2) Accessing variable out of scope is caught.
+
+ Here we test option 2.
+ */
+
+#define MAIN 0
+#include "nested-functions-0.c"
+#undef MAIN
+
+int main ()
+{
+ int *retval = nested_function (2);
+ *retval = 100;
+ return 0;
+}
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* { dg-output "WRITE of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/gcc.dg/ipa/modref-2.c b/gcc/testsuite/gcc.dg/ipa/modref-2.c
index 5ac2c65..51ac658 100644
--- a/gcc/testsuite/gcc.dg/ipa/modref-2.c
+++ b/gcc/testsuite/gcc.dg/ipa/modref-2.c
@@ -11,5 +11,6 @@ test2 (double x, double *y)
__builtin_modf (x,y);
}
/* 321*8 */
-/* { dg-final { scan-ipa-dump "Parm 0 param offset:0 offset:0 size:-1 max_size:2568" "modref" } } */
-/* { dg-final { scan-ipa-dump "Parm 1 param offset:0 offset:0 size:-1 max_size:64" "modref" } } */
+/* { dg-final { scan-ipa-dump "Parm 0 param offset:0 offset:0 size:-1 max_size:2568" "modref" } } */
+/* { dg-final { scan-ipa-dump "Parm 1 param offset:0 offset:0 size:-1 max_size:64" "modref" { target lp64 } } } */
+/* { dg-final { scan-ipa-dump "Parm 1 param offset:0 offset:0 size:-1 max_size:32" "modref" { target ilp32 } } } */
diff --git a/gcc/testsuite/gcc.dg/lto/modref-3_0.c b/gcc/testsuite/gcc.dg/lto/modref-3_0.c
new file mode 100644
index 0000000..bd8f96f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/modref-3_0.c
@@ -0,0 +1,17 @@
+/* { dg-lto-do run } */
+/* { dg-lto-options { {-O2 -flto-partition=max -fdump-ipa-modref -fno-ipa-sra -fno-ipa-cp -flto} } } */
+extern void copy (int *a, int *b);
+extern void barrier ();
+extern int *ptr;
+int
+main()
+{
+ int a = 1, b = 2;
+ copy (&a,&b);
+ barrier ();
+ *ptr = 1;
+ if (!__builtin_constant_p (b == 2))
+ __builtin_abort ();
+ return 0;
+}
+/* { dg-final { scan-wpa-ipa-dump "parm 1 flags: nodirectescape" "modref" } } */
diff --git a/gcc/testsuite/gcc.dg/lto/modref-3_1.c b/gcc/testsuite/gcc.dg/lto/modref-3_1.c
new file mode 100644
index 0000000..c36f3d1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/modref-3_1.c
@@ -0,0 +1,13 @@
+__attribute__ ((noinline))
+void
+copy (int *a, int *b)
+{
+ *a=*b;
+}
+int p, *ptr = &p;
+__attribute__ ((noinline))
+void
+barrier ()
+{
+ asm ("":"=r"(ptr):"0"(ptr));
+}
diff --git a/gcc/testsuite/gcc.dg/lto/modref-4_0.c b/gcc/testsuite/gcc.dg/lto/modref-4_0.c
new file mode 100644
index 0000000..db90b4f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/modref-4_0.c
@@ -0,0 +1,17 @@
+/* { dg-lto-do run } */
+/* { dg-lto-options { {-O2 -flto-partition=max -fdump-ipa-modref -fno-ipa-sra -flto} } } */
+extern void copy (int *a, int *b);
+extern void barrier ();
+extern int *ptr;
+int
+main()
+{
+ int a = 1, b = 2;
+ copy (&a,&b);
+ barrier ();
+ *ptr = 1;
+ if (!__builtin_constant_p (b == 2))
+ __builtin_abort ();
+ return 0;
+}
+/* { dg-final { scan-wpa-ipa-dump "parm 1 flags: nodirectescape" "modref" } } */
diff --git a/gcc/testsuite/gcc.dg/lto/modref-4_1.c b/gcc/testsuite/gcc.dg/lto/modref-4_1.c
new file mode 100644
index 0000000..c36f3d1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/modref-4_1.c
@@ -0,0 +1,13 @@
+__attribute__ ((noinline))
+void
+copy (int *a, int *b)
+{
+ *a=*b;
+}
+int p, *ptr = &p;
+__attribute__ ((noinline))
+void
+barrier ()
+{
+ asm ("":"=r"(ptr):"0"(ptr));
+}
diff --git a/gcc/testsuite/gcc.dg/lvalue-11.c b/gcc/testsuite/gcc.dg/lvalue-11.c
new file mode 100644
index 0000000..d8b5a60c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lvalue-11.c
@@ -0,0 +1,40 @@
+/* test that lvalue conversions drops qualifiers, Bug 97702 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+
+const int jc;
+extern int j;
+extern typeof(0,jc) j;
+extern typeof(+jc) j;
+extern typeof(-jc) j;
+extern typeof(1?jc:0) j;
+extern typeof((int)jc) j;
+extern typeof((const int)jc) j;
+
+volatile int kv;
+extern int k;
+extern typeof(0,kv) k;
+extern typeof(+kv) k;
+extern typeof(-kv) k;
+extern typeof(1?kv:0) k;
+extern typeof((int)kv) k;
+extern typeof((volatile int)kv) k;
+
+_Atomic int la;
+extern int l;
+extern typeof(0,la) l;
+extern typeof(+la) l;
+extern typeof(-la) l;
+extern typeof(1?la:0) l;
+extern typeof((int)la) l;
+extern typeof((_Atomic int)la) l;
+
+int * restrict mr;
+extern int *m;
+extern typeof(0,mr) m;
+extern typeof(1?mr:0) m;
+extern typeof((int *)mr) m;
+extern typeof((int * restrict)mr) m;
+
+
diff --git a/gcc/testsuite/gcc.dg/memchr-3.c b/gcc/testsuite/gcc.dg/memchr-3.c
new file mode 100644
index 0000000..c38d9cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/memchr-3.c
@@ -0,0 +1,25 @@
+/* PR middle-end/97956 - ICE due to type mismatch in pointer_plus_expr
+ during memchr folding
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+typedef __INT8_TYPE__ int8_t;
+typedef __INT32_TYPE__ int32_t;
+
+extern void* memchr (const void*, int, long);
+
+struct SX
+{
+ int32_t n;
+ int8_t a[];
+};
+
+const struct SX sx = { 0x1221 };
+const char sx_rep[] = { };
+
+void test_find (void)
+{
+ int n = 0, nb = (const char*)&sx.a - (const char*)&sx;
+ const char *p = (const char*)&sx, *q = sx_rep;
+ n += p + 1 == memchr (p, q[1], nb);
+}
diff --git a/gcc/testsuite/gcc.dg/nextafter-1.c b/gcc/testsuite/gcc.dg/nextafter-1.c
index 1916ac2..646a741 100644
--- a/gcc/testsuite/gcc.dg/nextafter-1.c
+++ b/gcc/testsuite/gcc.dg/nextafter-1.c
@@ -6,12 +6,14 @@
/* { dg-final { scan-tree-dump-not "nextafter" "optimized" } } */
/* { dg-final { scan-tree-dump-not "nexttoward" "optimized" } } */
+#ifndef _NEXT_AFTER_2
float nextafterf (float, float);
double nextafter (double, double);
long double nextafterl (long double, long double);
float nexttowardf (float, long double);
double nexttoward (double, long double);
long double nexttowardl (long double, long double);
+#endif
#define CHECK(x) if (!(x)) __builtin_abort ()
diff --git a/gcc/testsuite/gcc.dg/nextafter-2.c b/gcc/testsuite/gcc.dg/nextafter-2.c
index e51ae94..b36bc8b 100644
--- a/gcc/testsuite/gcc.dg/nextafter-2.c
+++ b/gcc/testsuite/gcc.dg/nextafter-2.c
@@ -6,6 +6,18 @@
#include <stdlib.h>
+/* In order to run on systems like the PowerPC that have 3 different long
+ double types, include math.h so it can choose what is the appropriate
+ nextafterl function to use.
+
+ If we didn't use -fno-builtin for this test, the PowerPC compiler would have
+ changed the names of the built-in functions that use long double. The
+ nextafter-1.c function runs with this mapping.
+
+ Since this test uses -fno-builtin, include math.h, so that math.h can make
+ the appropriate choice to use. */
+#include <math.h>
+
#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
# if !__GLIBC_PREREQ (2, 24)
/* Workaround buggy nextafterl in glibc 2.23 and earlier,
@@ -13,4 +25,7 @@
# define NO_LONG_DOUBLE 1
# endif
#endif
+
+#define _NEXT_AFTER_2
+
#include "nextafter-1.c"
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c
new file mode 100644
index 0000000..05133d5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c
@@ -0,0 +1,436 @@
+/* Proof-of-concept of a -fanalyzer plugin.
+ Detect (some) uses of CPython API outside of the Global Interpreter Lock.
+ https://docs.python.org/3/c-api/init.html#thread-state-and-the-global-interpreter-lock
+*/
+/* { dg-options "-g" } */
+
+#include "gcc-plugin.h"
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "diagnostic.h"
+#include "tree.h"
+#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
+#include "diagnostic-event-id.h"
+#include "analyzer/analyzer.h"
+#include "analyzer/analyzer-logging.h"
+#include "json.h"
+#include "analyzer/sm.h"
+#include "analyzer/pending-diagnostic.h"
+
+int plugin_is_GPL_compatible;
+
+#if ENABLE_ANALYZER
+
+namespace ana {
+
+static bool
+type_based_on_pyobject_p (tree type)
+{
+ /* Ideally we'd also check for "subclasses" here by iterating up the
+ first field of each struct. */
+ if (TREE_CODE (type) != RECORD_TYPE)
+ return false;
+ tree name = TYPE_IDENTIFIER (type);
+ if (!name)
+ return false;
+ return id_equal (name, "PyObject");
+}
+
+/* An experimental state machine, for tracking whether the GIL is held,
+ as global state.. */
+
+class gil_state_machine : public state_machine
+{
+public:
+ gil_state_machine (logger *logger);
+
+ bool inherited_state_p () const FINAL OVERRIDE { return false; }
+
+ bool on_stmt (sm_context *sm_ctxt,
+ const supernode *node,
+ const gimple *stmt) const FINAL OVERRIDE;
+
+ void on_condition (sm_context *sm_ctxt,
+ const supernode *node,
+ const gimple *stmt,
+ tree lhs,
+ enum tree_code op,
+ tree rhs) const FINAL OVERRIDE;
+
+ bool can_purge_p (state_t s) const FINAL OVERRIDE;
+
+ void check_for_pyobject_usage_without_gil (sm_context *sm_ctxt,
+ const supernode *node,
+ const gimple *stmt,
+ tree op) const;
+
+ private:
+ void check_for_pyobject_in_call (sm_context *sm_ctxt,
+ const supernode *node,
+ const gcall *call,
+ tree callee_fndecl) const;
+
+ public:
+ /* These states are "global", rather than per-expression. */
+
+ /* State for when we've released the GIL. */
+ state_t m_released_gil;
+
+ /* Stop state. */
+ state_t m_stop;
+};
+
+/* Subclass for diagnostics involving the GIL. */
+
+class gil_diagnostic : public pending_diagnostic
+{
+public:
+ location_t fixup_location (location_t loc) const FINAL OVERRIDE
+ {
+ /* Ideally we'd check for specific macros here, and only
+ resolve certain macros. */
+ if (linemap_location_from_macro_expansion_p (line_table, loc))
+ loc = linemap_resolve_location (line_table, loc,
+ LRK_MACRO_EXPANSION_POINT, NULL);
+ return loc;
+ }
+
+ label_text describe_state_change (const evdesc::state_change &change)
+ FINAL OVERRIDE
+ {
+ if (change.is_global_p ()
+ && change.m_new_state == m_sm.m_released_gil)
+ return change.formatted_print ("releasing the GIL here");
+ if (change.is_global_p ()
+ && change.m_new_state == m_sm.get_start_state ())
+ return change.formatted_print ("acquiring the GIL here");
+ return label_text ();
+ }
+
+ protected:
+ gil_diagnostic (const gil_state_machine &sm) : m_sm (sm)
+ {
+ }
+
+ private:
+ const gil_state_machine &m_sm;
+};
+
+class double_save_thread : public gil_diagnostic
+{
+ public:
+ double_save_thread (const gil_state_machine &sm, const gcall *call)
+ : gil_diagnostic (sm), m_call (call)
+ {}
+
+ const char *get_kind () const FINAL OVERRIDE
+ {
+ return "double_save_thread";
+ }
+
+ bool subclass_equal_p (const pending_diagnostic &base_other) const OVERRIDE
+ {
+ const double_save_thread &sub_other
+ = (const double_save_thread &)base_other;
+ return m_call == sub_other.m_call;
+ }
+
+ bool emit (rich_location *rich_loc) FINAL OVERRIDE
+ {
+ return warning_at (rich_loc, 0,
+ "nested usage of %qs", "Py_BEGIN_ALLOW_THREADS");
+ }
+
+ label_text describe_final_event (const evdesc::final_event &ev) FINAL OVERRIDE
+ {
+ return ev.formatted_print ("nested usage of %qs here",
+ "Py_BEGIN_ALLOW_THREADS");
+ }
+
+ private:
+ const gcall *m_call;
+};
+
+class fncall_without_gil : public gil_diagnostic
+{
+ public:
+ fncall_without_gil (const gil_state_machine &sm, const gcall *call,
+ tree callee_fndecl, unsigned arg_idx)
+ : gil_diagnostic (sm), m_call (call), m_callee_fndecl (callee_fndecl),
+ m_arg_idx (arg_idx)
+ {}
+
+ const char *get_kind () const FINAL OVERRIDE
+ {
+ return "fncall_without_gil";
+ }
+
+ bool subclass_equal_p (const pending_diagnostic &base_other) const OVERRIDE
+ {
+ const fncall_without_gil &sub_other
+ = (const fncall_without_gil &)base_other;
+ return (m_call == sub_other.m_call
+ && m_callee_fndecl == sub_other.m_callee_fndecl
+ && m_arg_idx == sub_other.m_arg_idx);
+ }
+
+ bool emit (rich_location *rich_loc) FINAL OVERRIDE
+ {
+ auto_diagnostic_group d;
+ /* There isn't a warning ID for use to use. */
+ if (m_callee_fndecl)
+ return warning_at (rich_loc, 0,
+ "use of PyObject as argument %i of %qE"
+ " without the GIL",
+ m_arg_idx + 1, m_callee_fndecl);
+ else
+ return warning_at (rich_loc, 0,
+ "use of PyObject as argument %i of call"
+ " without the GIL",
+ m_arg_idx + 1, m_callee_fndecl);
+ }
+
+ label_text describe_final_event (const evdesc::final_event &ev) FINAL OVERRIDE
+ {
+ if (m_callee_fndecl)
+ return ev.formatted_print ("use of PyObject as argument %i of %qE here"
+ " without the GIL",
+ m_arg_idx + 1, m_callee_fndecl);
+ else
+ return ev.formatted_print ("use of PyObject as argument %i of call here"
+ " without the GIL",
+ m_arg_idx + 1, m_callee_fndecl);
+ }
+
+ private:
+ const gcall *m_call;
+ tree m_callee_fndecl;
+ unsigned m_arg_idx;
+};
+
+class pyobject_usage_without_gil : public gil_diagnostic
+{
+ public:
+ pyobject_usage_without_gil (const gil_state_machine &sm, tree expr)
+ : gil_diagnostic (sm), m_expr (expr)
+ {}
+
+ const char *get_kind () const FINAL OVERRIDE
+ {
+ return "pyobject_usage_without_gil";
+ }
+
+ bool subclass_equal_p (const pending_diagnostic &base_other) const OVERRIDE
+ {
+ return same_tree_p (m_expr,
+ ((const pyobject_usage_without_gil&)base_other).m_expr);
+ }
+
+ bool emit (rich_location *rich_loc) FINAL OVERRIDE
+ {
+ auto_diagnostic_group d;
+ /* There isn't a warning ID for use to use. */
+ return warning_at (rich_loc, 0,
+ "use of PyObject %qE without the GIL", m_expr);
+ }
+
+ label_text describe_final_event (const evdesc::final_event &ev) FINAL OVERRIDE
+ {
+ return ev.formatted_print ("PyObject %qE used here without the GIL",
+ m_expr);
+ }
+
+ private:
+ tree m_expr;
+};
+
+/* gil_state_machine's ctor. */
+
+gil_state_machine::gil_state_machine (logger *logger)
+: state_machine ("gil", logger)
+{
+ m_released_gil = add_state ("released_gil");
+ m_stop = add_state ("stop");
+}
+
+struct cb_data
+{
+ cb_data (const gil_state_machine &sm, sm_context *sm_ctxt,
+ const supernode *snode, const gimple *stmt)
+ : m_sm (sm), m_sm_ctxt (sm_ctxt), m_snode (snode), m_stmt (stmt)
+ {
+ }
+
+ const gil_state_machine &m_sm;
+ sm_context *m_sm_ctxt;
+ const supernode *m_snode;
+ const gimple *m_stmt;
+};
+
+static bool
+check_for_pyobject (gimple *, tree op, tree, void *data)
+{
+ cb_data *d = (cb_data *)data;
+ d->m_sm.check_for_pyobject_usage_without_gil (d->m_sm_ctxt, d->m_snode,
+ d->m_stmt, op);
+ return true;
+}
+
+/* Assuming that the GIL has been released, complain about any
+ PyObject * arguments passed to CALL. */
+
+void
+gil_state_machine::check_for_pyobject_in_call (sm_context *sm_ctxt,
+ const supernode *node,
+ const gcall *call,
+ tree callee_fndecl) const
+{
+ for (unsigned i = 0; i < gimple_call_num_args (call); i++)
+ {
+ tree arg = gimple_call_arg (call, i);
+ if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
+ continue;
+ tree type = TREE_TYPE (TREE_TYPE (arg));
+ if (type_based_on_pyobject_p (type))
+ {
+ sm_ctxt->warn (node, call, NULL_TREE,
+ new fncall_without_gil (*this, call,
+ callee_fndecl,
+ i));
+ sm_ctxt->set_global_state (m_stop);
+ }
+ }
+}
+
+/* Implementation of state_machine::on_stmt vfunc for gil_state_machine. */
+
+bool
+gil_state_machine::on_stmt (sm_context *sm_ctxt,
+ const supernode *node,
+ const gimple *stmt) const
+{
+ const state_t global_state = sm_ctxt->get_global_state ();
+ if (const gcall *call = dyn_cast <const gcall *> (stmt))
+ {
+ if (tree callee_fndecl = sm_ctxt->get_fndecl_for_call (call))
+ {
+ if (is_named_call_p (callee_fndecl, "PyEval_SaveThread", call, 0))
+ {
+ if (0)
+ inform (input_location, "found call to %qs",
+ "PyEval_SaveThread");
+ if (global_state == m_released_gil)
+ {
+ sm_ctxt->warn (node, stmt, NULL_TREE,
+ new double_save_thread (*this, call));
+ sm_ctxt->set_global_state (m_stop);
+ }
+ else
+ sm_ctxt->set_global_state (m_released_gil);
+ return true;
+ }
+ else if (is_named_call_p (callee_fndecl, "PyEval_RestoreThread",
+ call, 1))
+ {
+ if (0)
+ inform (input_location, "found call to %qs",
+ "PyEval_SaveThread");
+ if (global_state == m_released_gil)
+ sm_ctxt->set_global_state (m_start);
+ return true;
+ }
+ else if (global_state == m_released_gil)
+ {
+ /* Find PyObject * args of calls to fns with unknown bodies. */
+ if (!fndecl_has_gimple_body_p (callee_fndecl))
+ check_for_pyobject_in_call (sm_ctxt, node, call, callee_fndecl);
+ }
+ }
+ else if (global_state == m_released_gil)
+ check_for_pyobject_in_call (sm_ctxt, node, call, NULL);
+ }
+ else
+ if (global_state == m_released_gil)
+ {
+ /* Walk the stmt, finding uses of PyObject (or "subclasses"). */
+ cb_data d (*this, sm_ctxt, node, stmt);
+ walk_stmt_load_store_addr_ops (const_cast <gimple *> (stmt), &d,
+ check_for_pyobject,
+ check_for_pyobject,
+ check_for_pyobject);
+ }
+ return false;
+}
+
+/* Implementation of state_machine::on_condition vfunc for
+ gil_state_machine. */
+
+void
+gil_state_machine::on_condition (sm_context *sm_ctxt ATTRIBUTE_UNUSED,
+ const supernode *node ATTRIBUTE_UNUSED,
+ const gimple *stmt ATTRIBUTE_UNUSED,
+ tree lhs ATTRIBUTE_UNUSED,
+ enum tree_code op ATTRIBUTE_UNUSED,
+ tree rhs ATTRIBUTE_UNUSED) const
+{
+ // Empty
+}
+
+bool
+gil_state_machine::can_purge_p (state_t s ATTRIBUTE_UNUSED) const
+{
+ return true;
+}
+
+void
+gil_state_machine::check_for_pyobject_usage_without_gil (sm_context *sm_ctxt,
+ const supernode *node,
+ const gimple *stmt,
+ tree op) const
+{
+ tree type = TREE_TYPE (op);
+ if (type_based_on_pyobject_p (type))
+ {
+ sm_ctxt->warn (node, stmt, NULL_TREE,
+ new pyobject_usage_without_gil (*this, op));
+ sm_ctxt->set_global_state (m_stop);
+ }
+}
+
+/* Callback handler for the PLUGIN_ANALYZER_INIT event. */
+
+static void
+gil_analyzer_init_cb (void *gcc_data, void */*user_data*/)
+{
+ ana::plugin_analyzer_init_iface *iface
+ = (ana::plugin_analyzer_init_iface *)gcc_data;
+ LOG_SCOPE (iface->get_logger ());
+ if (0)
+ inform (input_location, "got here: gil_analyzer_init_cb");
+ iface->register_state_machine (new gil_state_machine (iface->get_logger ()));
+}
+
+} // namespace ana
+
+#endif /* #if ENABLE_ANALYZER */
+
+int
+plugin_init (struct plugin_name_args *plugin_info,
+ struct plugin_gcc_version *version)
+{
+#if ENABLE_ANALYZER
+ const char *plugin_name = plugin_info->base_name;
+ if (0)
+ inform (input_location, "got here; %qs", plugin_name);
+ register_callback (plugin_info->base_name,
+ PLUGIN_ANALYZER_INIT,
+ ana::gil_analyzer_init_cb,
+ NULL); /* void *user_data */
+#else
+ sorry_no_analyzer ();
+#endif
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/gil-1.c b/gcc/testsuite/gcc.dg/plugin/gil-1.c
new file mode 100644
index 0000000..4e8f535
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/gil-1.c
@@ -0,0 +1,90 @@
+/* { dg-do compile } */
+/* { dg-options "-fanalyzer" } */
+
+#include "gil.h"
+
+void test_1 (void)
+{
+ Py_BEGIN_ALLOW_THREADS
+ Py_END_ALLOW_THREADS
+}
+
+void test_2 (PyObject *obj)
+{
+ Py_BEGIN_ALLOW_THREADS /* { dg-message "releasing the GIL here" } */
+
+ Py_INCREF (obj); /* { dg-warning "use of PyObject '\\*\\(obj\\)' without the GIL" } */
+ Py_DECREF (obj);
+
+ Py_END_ALLOW_THREADS
+}
+
+void test_3 (PyObject *obj)
+{
+ Py_BEGIN_ALLOW_THREADS /* { dg-message "releasing the GIL here" } */
+
+ Py_BEGIN_ALLOW_THREADS /* { dg-warning "nested usage of 'Py_BEGIN_ALLOW_THREADS'" } */
+ Py_END_ALLOW_THREADS
+
+ Py_END_ALLOW_THREADS
+}
+
+void test_4 (PyObject *obj)
+{
+ /* These aren't nested, so should be OK. */
+ Py_BEGIN_ALLOW_THREADS
+ Py_END_ALLOW_THREADS
+
+ Py_BEGIN_ALLOW_THREADS
+ Py_END_ALLOW_THREADS
+}
+
+/* Interprocedural example of erroneously nested usage. */
+
+static void __attribute__((noinline))
+called_by_test_5 (void)
+{
+ Py_BEGIN_ALLOW_THREADS /* { dg-warning "nested usage of 'Py_BEGIN_ALLOW_THREADS'" } */
+ Py_END_ALLOW_THREADS
+}
+
+void test_5 (PyObject *obj)
+{
+ Py_BEGIN_ALLOW_THREADS /* { dg-message "releasing the GIL here" } */
+ called_by_test_5 ();
+ Py_END_ALLOW_THREADS
+}
+
+/* Interprocedural example of bogusly using a PyObject outside of GIL. */
+
+static void __attribute__((noinline))
+called_by_test_6 (PyObject *obj)
+{
+ Py_INCREF (obj); /* { dg-warning "use of PyObject '\\*\\(obj\\)' without the GIL" } */
+ Py_DECREF (obj);
+}
+
+void test_6 (PyObject *obj)
+{
+ Py_BEGIN_ALLOW_THREADS /* { dg-message "releasing the GIL here" } */
+ called_by_test_6 (obj);
+ Py_END_ALLOW_THREADS
+}
+
+extern void called_by_test_7 (PyObject *obj);
+
+void test_7 (PyObject *obj)
+{
+ Py_BEGIN_ALLOW_THREADS /* { dg-message "releasing the GIL here" } */
+ called_by_test_7 (obj); /* { dg-warning "use of PyObject as argument 1 of 'called_by_test_7' without the GIL" } */
+ Py_END_ALLOW_THREADS
+}
+
+typedef void (*callback_t) (PyObject *);
+
+void test_8 (PyObject *obj, callback_t cb)
+{
+ Py_BEGIN_ALLOW_THREADS /* { dg-message "releasing the GIL here" } */
+ cb (obj); /* { dg-warning "use of PyObject as argument 1 of call without the GIL" } */
+ Py_END_ALLOW_THREADS
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/gil.h b/gcc/testsuite/gcc.dg/plugin/gil.h
new file mode 100644
index 0000000..b0610cd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/gil.h
@@ -0,0 +1,32 @@
+/* Adapted from CPython 3.8's ceval.h. */
+typedef struct PyThreadState PyThreadState;
+extern PyThreadState * PyEval_SaveThread(void);
+extern void PyEval_RestoreThread(PyThreadState *);
+
+#define Py_BEGIN_ALLOW_THREADS { \
+ PyThreadState *_save; \
+ _save = PyEval_SaveThread();
+#define Py_BLOCK_THREADS PyEval_RestoreThread(_save);
+#define Py_UNBLOCK_THREADS _save = PyEval_SaveThread();
+#define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \
+ }
+
+/* Adapted/hacked up from CPython 3.8's object.h. */
+
+typedef struct _object {
+ int ob_refcnt;
+} PyObject;
+
+#define _PyObject_CAST(op) ((PyObject*)(op))
+
+extern void _Py_Dealloc(PyObject *);
+
+#define _Py_INCREF(OP) do { (OP)->ob_refcnt++; } while (0);
+#define _Py_DECREF(OP) do { \
+ if (--(OP)->ob_refcnt == 0) { \
+ _Py_Dealloc(OP); \
+ } \
+ } while (0)
+
+#define Py_INCREF(op) _Py_INCREF(_PyObject_CAST(op))
+#define Py_DECREF(op) _Py_DECREF(_PyObject_CAST(op))
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp
index 5dd102a..7f0ffd6 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugin.exp
+++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp
@@ -118,6 +118,8 @@ set plugin_test_list [list \
{ dump_plugin.c \
dump-1.c \
dump-2.c } \
+ { analyzer_gil_plugin.c \
+ gil-1.c } \
]
foreach plugin_test $plugin_test_list {
diff --git a/gcc/testsuite/gcc.dg/pr25376.c b/gcc/testsuite/gcc.dg/pr25376.c
index 3008b09..d66f2e1 100644
--- a/gcc/testsuite/gcc.dg/pr25376.c
+++ b/gcc/testsuite/gcc.dg/pr25376.c
@@ -7,3 +7,4 @@ void simple (void)
}
/* { dg-final { scan-assembler "my_named_section" } } */
+/* { dg-final { scan-assembler-symbol-section {simple$} {^\.?my_named_section|simple\[DS\]|^\"\.opd\"} } } */
diff --git a/gcc/testsuite/gcc.dg/pr46309-2.c b/gcc/testsuite/gcc.dg/pr46309-2.c
index f56df42..2903fff 100644
--- a/gcc/testsuite/gcc.dg/pr46309-2.c
+++ b/gcc/testsuite/gcc.dg/pr46309-2.c
@@ -1,6 +1,6 @@
/* PR tree-optimization/46309 */
/* { dg-do compile } */
-/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-reassoc-details" } */
+/* { dg-options "-O2 -fno-ipa-icf -fno-jump-tables -fno-bit-tests -fdump-tree-reassoc-details" } */
int foo (void);
diff --git a/gcc/testsuite/gcc.dg/pr60195.c b/gcc/testsuite/gcc.dg/pr60195.c
index 0a50a30..8eccf7f 100644
--- a/gcc/testsuite/gcc.dg/pr60195.c
+++ b/gcc/testsuite/gcc.dg/pr60195.c
@@ -15,7 +15,7 @@ atomic_int
fn2 (void)
{
atomic_int y = 0;
- y;
+ y; /* { dg-warning "statement with no effect" } */
return y;
}
diff --git a/gcc/testsuite/gcc.dg/pr83072.c b/gcc/testsuite/gcc.dg/pr83072.c
new file mode 100644
index 0000000..3bed8d8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr83072.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp -fno-tree-ccp -fno-tree-forwprop -fno-tree-fre" } */
+
+void kill (void);
+
+int f(int c){
+ c |= 1;
+ if (c == 0)
+ kill ();
+
+ return c;
+}
+
+/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/pr85811.c b/gcc/testsuite/gcc.dg/pr85811.c
new file mode 100644
index 0000000..868f66c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr85811.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+#include <stdio.h>
+
+int main() {
+ const double negval = -1.0;
+ const double nanval = 0.0 / 0.0;
+ const double val = __builtin_fmax(negval, nanval);
+ const double absval = __builtin_fabs(val);
+ printf("fabs(%.16e) = %.16e\n", val, absval);
+ return absval >= 0 ? 0 : 1;
+}
+
+/* We hope not to see: printf ("fabs(%.16e) = %.16e\n", val_4, val_4); */
+/* { dg-final { scan-tree-dump-not "val_\[0-9\]*, val_\[0-9\]*" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/pr91029.c b/gcc/testsuite/gcc.dg/pr91029.c
new file mode 100644
index 0000000..4904764
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr91029.c
@@ -0,0 +1,48 @@
+/* PR tree-optimization/91029 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void kill (void);
+int xx;
+
+void f1 (int i)
+{
+ if ((i % 7) == 3)
+ {
+ xx = (i < 0);
+ if (xx)
+ kill ();
+ }
+}
+
+void f2 (int i)
+{
+ if ((i % 7) > 0)
+ {
+ xx = (i < 0);
+ if (xx)
+ kill ();
+ }
+}
+
+void f3 (int i)
+{
+ if ((i % 7) == -3)
+ {
+ xx = (i > 0);
+ if (xx)
+ kill ();
+ }
+}
+
+void f4 (int i)
+{
+ if ((i % 7) < 0)
+ {
+ xx = (i > 0);
+ if (xx)
+ kill ();
+ }
+}
+
+/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/pr95853.c b/gcc/testsuite/gcc.dg/pr95853.c
new file mode 100644
index 0000000..fdd3c30
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr95853.c
@@ -0,0 +1,59 @@
+/* PR tree-optimization/95853 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-widening_mul" } */
+
+#if __SIZEOF_INT128__
+typedef __uint128_t W;
+typedef unsigned long long T;
+#else
+typedef unsigned long long W;
+typedef unsigned int T;
+#endif
+
+struct S { int p; T r; };
+
+struct S
+foo (T x, T y)
+{
+ W z = (W) x + y;
+ return (struct S) { z > ~(T) 0, (T) z };
+}
+
+struct S
+bar (T x)
+{
+ W z = (W) x + 132;
+ return (struct S) { z > ~(T) 0, (T) z };
+}
+
+struct S
+baz (T x, unsigned short y)
+{
+ W z = (W) x + y;
+ return (struct S) { z > ~(T) 0, (T) z };
+}
+
+struct S
+qux (unsigned short x, T y)
+{
+ W z = (W) x + y;
+ return (struct S) { z > ~(T) 0, (T) z };
+}
+
+struct S
+corge (T x, T y)
+{
+ T w = x + y;
+ W z = (W) x + y;
+ return (struct S) { z > ~(T) 0, w };
+}
+
+struct S
+garple (T x, T y)
+{
+ W z = (W) x + y;
+ T w = x + y;
+ return (struct S) { z > ~(T) 0, w };
+}
+
+/* { dg-final { scan-tree-dump-times "ADD_OVERFLOW" 6 "widening_mul" { target { i?86-*-* x86_64-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/pr96708-negative.c b/gcc/testsuite/gcc.dg/pr96708-negative.c
new file mode 100644
index 0000000..91964d3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96708-negative.c
@@ -0,0 +1,48 @@
+/* { dg-do run } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+#include <stdbool.h>
+
+bool __attribute__ ((noinline))
+test1 (int a, int b)
+{
+ int tmp = (a < b) ? b : a;
+ return tmp <= a;
+}
+
+bool __attribute__ ((noinline))
+test2 (int a, int b)
+{
+ int tmp = (a < b) ? b : a;
+ return tmp > a;
+}
+
+bool __attribute__ ((noinline))
+test3 (int a, int b)
+{
+ int tmp = (a > b) ? b : a;
+ return tmp >= a;
+}
+
+bool __attribute__ ((noinline))
+test4 (int a, int b)
+{
+ int tmp = (a > b) ? b : a;
+ return tmp < a;
+}
+
+int main()
+{
+ if (test1 (1, 2) || !test1 (2, 1) ||
+ !test2 (1, 2) || test2 (2, 1) ||
+ !test3 (1, 2) || test3 (2, 1) ||
+ test4 (1, 2) || !test4 (2, 1)) {
+ __builtin_abort();
+ }
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 0;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-not { "return 1;" } "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/pr96708-positive.c b/gcc/testsuite/gcc.dg/pr96708-positive.c
new file mode 100644
index 0000000..65af853
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96708-positive.c
@@ -0,0 +1,48 @@
+/* { dg-do run } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+#include <stdbool.h>
+
+bool __attribute__ ((noinline))
+test1(int a, int b)
+{
+ int tmp = (a < b) ? b : a;
+ return tmp >= a;
+}
+
+bool __attribute__ ((noinline))
+test2(int a, int b)
+{
+ int tmp = (a < b) ? b : a;
+ return tmp < a;
+}
+
+bool __attribute__ ((noinline))
+test3(int a, int b)
+{
+ int tmp = (a > b) ? b : a;
+ return tmp <= a;
+}
+
+bool __attribute__ ((noinline))
+test4(int a, int b)
+{
+ int tmp = (a > b) ? b : a;
+ return tmp > a;
+}
+
+int main()
+{
+ if (!test1 (1, 2) || !test1 (2, 1) ||
+ test2 (1, 2) || test2 (2, 1) ||
+ !test3 (1, 2) || !test3 (2, 1) ||
+ test4 (1, 2) || test4 (2, 1)) {
+ __builtin_abort();
+ }
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "return 0;" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 1;" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-not { "MAX_EXPR" } "optimized" } } */
+/* { dg-final { scan-tree-dump-not { "MIN_EXPR" } "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/pr97459-1.c b/gcc/testsuite/gcc.dg/pr97459-1.c
new file mode 100644
index 0000000..96c7ab6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97459-1.c
@@ -0,0 +1,54 @@
+/* PR rtl-optimization/97459 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-DEXPENSIVE" { target run_expensive_tests } } */
+
+#ifdef __SIZEOF_INT128__
+typedef __uint128_t T;
+#else
+typedef unsigned long long T;
+#endif
+
+T __attribute__((noipa)) foo (T x, T n) { return x % n; }
+#define C(n) T __attribute__((noipa)) foo##n (T x) { return x % (n - 10000); }
+
+#define C1(n) C(n##1) C(n##3) C(n##5) C(n##7) C(n##9)
+#define C2(n) C1(n##0) C1(n##1) C1(n##2) C1(n##3) C1(n##4) \
+ C1(n##5) C1(n##6) C1(n##7) C1(n##8) C1(n##9)
+#ifdef EXPENSIVE
+#define C3(n) C2(n##0) C2(n##1) C2(n##2) C2(n##3) C2(n##4) \
+ C2(n##5) C2(n##6) C2(n##7) C2(n##8) C2(n##9)
+#define C4(n) C3(n##0) C3(n##1) C3(n##2) C3(n##3) C3(n##4) \
+ C3(n##5) C3(n##6) C3(n##7) C3(n##8) C3(n##9)
+#else
+#define C3(n) C2(n##0) C2(n##4) C2(n##9)
+#define C4(n) C3(n##0) C3(n##3) C3(n##7)
+#endif
+#define TESTS C4(1) C1(10010) C1(10012) C1(16144)
+
+TESTS
+
+struct S { T x; T (*foo) (T); };
+
+#undef C
+#define C(n) { n - 10000, foo##n },
+
+struct S tests[] = {
+TESTS
+ { 0, 0 }
+};
+
+int
+main ()
+{
+ int i, j, k;
+ for (k = 0; tests[k].x; k++)
+ for (i = 0; i < sizeof (T) * __CHAR_BIT__; i++)
+ for (j = -5; j <= 5; j++)
+ {
+ T x = ((T) 1 << i) + j;
+ if (foo (x, tests[k].x) != tests[k].foo (x))
+ __builtin_abort ();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97459-2.c b/gcc/testsuite/gcc.dg/pr97459-2.c
new file mode 100644
index 0000000..0e2bfbd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97459-2.c
@@ -0,0 +1,57 @@
+/* PR rtl-optimization/97459 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-DEXPENSIVE" { target run_expensive_tests } } */
+
+#ifdef __SIZEOF_INT128__
+typedef __int128_t T;
+typedef __uint128_t U;
+#else
+typedef long long T;
+typedef unsigned long long U;
+#endif
+
+T __attribute__((noipa)) foo (T x, T n) { return x % n; }
+#define C(n) T __attribute__((noipa)) foo##n (T x) { return x % (n - 10000); }
+
+#define C1(n) C(n##1) C(n##3) C(n##5) C(n##7) C(n##9)
+#define C2(n) C1(n##0) C1(n##1) C1(n##2) C1(n##3) C1(n##4) \
+ C1(n##5) C1(n##6) C1(n##7) C1(n##8) C1(n##9)
+#ifdef EXPENSIVE
+#define C3(n) C2(n##0) C2(n##1) C2(n##2) C2(n##3) C2(n##4) \
+ C2(n##5) C2(n##6) C2(n##7) C2(n##8) C2(n##9)
+#define C4(n) C3(n##0) C3(n##1) C3(n##2) C3(n##3) C3(n##4) \
+ C3(n##5) C3(n##6) C3(n##7) C3(n##8) C3(n##9)
+#else
+#define C3(n) C2(n##0) C2(n##4) C2(n##9)
+#define C4(n) C3(n##0) C3(n##3) C3(n##7)
+#endif
+#define TESTS C4(1) C1(10010) C1(10012) C1(16144)
+
+TESTS
+
+struct S { T x; T (*foo) (T); };
+
+#undef C
+#define C(n) { n - 10000, foo##n },
+
+struct S tests[] = {
+TESTS
+ { 0, 0 }
+};
+
+int
+main ()
+{
+ int i, j, k;
+ for (k = 0; tests[k].x; k++)
+ for (i = 0; i < sizeof (T) * __CHAR_BIT__; i++)
+ for (j = -5; j <= 5; j++)
+ {
+ U x = ((U) 1 << i) + j;
+ if (foo ((T) x, tests[k].x) != tests[k].foo ((T) x)
+ || foo ((T) -x, tests[k].x) != tests[k].foo ((T) -x))
+ __builtin_abort ();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97459-3.c b/gcc/testsuite/gcc.dg/pr97459-3.c
new file mode 100644
index 0000000..7fbb7ee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97459-3.c
@@ -0,0 +1,54 @@
+/* PR rtl-optimization/97459 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-DEXPENSIVE" { target run_expensive_tests } } */
+
+#ifdef __SIZEOF_INT128__
+typedef __uint128_t T;
+#else
+typedef unsigned long long T;
+#endif
+
+T __attribute__((noipa)) foo (T x, T n) { return x / n; }
+#define C(n) T __attribute__((noipa)) foo##n (T x) { return x / (n - 10000); }
+
+#define C1(n) C(n##1) C(n##3) C(n##5) C(n##7) C(n##9)
+#define C2(n) C1(n##0) C1(n##1) C1(n##2) C1(n##3) C1(n##4) \
+ C1(n##5) C1(n##6) C1(n##7) C1(n##8) C1(n##9)
+#ifdef EXPENSIVE
+#define C3(n) C2(n##0) C2(n##1) C2(n##2) C2(n##3) C2(n##4) \
+ C2(n##5) C2(n##6) C2(n##7) C2(n##8) C2(n##9)
+#define C4(n) C3(n##0) C3(n##1) C3(n##2) C3(n##3) C3(n##4) \
+ C3(n##5) C3(n##6) C3(n##7) C3(n##8) C3(n##9)
+#else
+#define C3(n) C2(n##0) C2(n##4) C2(n##9)
+#define C4(n) C3(n##0) C3(n##3) C3(n##7)
+#endif
+#define TESTS C4(1) C1(10010) C1(10012) C1(16144)
+
+TESTS
+
+struct S { T x; T (*foo) (T); };
+
+#undef C
+#define C(n) { n - 10000, foo##n },
+
+struct S tests[] = {
+TESTS
+ { 0, 0 }
+};
+
+int
+main ()
+{
+ int i, j, k;
+ for (k = 0; tests[k].x; k++)
+ for (i = 0; i < sizeof (T) * __CHAR_BIT__; i++)
+ for (j = -5; j <= 5; j++)
+ {
+ T x = ((T) 1 << i) + j;
+ if (foo (x, tests[k].x) != tests[k].foo (x))
+ __builtin_abort ();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97459-4.c b/gcc/testsuite/gcc.dg/pr97459-4.c
new file mode 100644
index 0000000..33e49a9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97459-4.c
@@ -0,0 +1,57 @@
+/* PR rtl-optimization/97459 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-DEXPENSIVE" { target run_expensive_tests } } */
+
+#ifdef __SIZEOF_INT128__
+typedef __int128_t T;
+typedef __uint128_t U;
+#else
+typedef long long T;
+typedef unsigned long long U;
+#endif
+
+T __attribute__((noipa)) foo (T x, T n) { return x / n; }
+#define C(n) T __attribute__((noipa)) foo##n (T x) { return x / (n - 10000); }
+
+#define C1(n) C(n##1) C(n##3) C(n##5) C(n##7) C(n##9)
+#define C2(n) C1(n##0) C1(n##1) C1(n##2) C1(n##3) C1(n##4) \
+ C1(n##5) C1(n##6) C1(n##7) C1(n##8) C1(n##9)
+#ifdef EXPENSIVE
+#define C3(n) C2(n##0) C2(n##1) C2(n##2) C2(n##3) C2(n##4) \
+ C2(n##5) C2(n##6) C2(n##7) C2(n##8) C2(n##9)
+#define C4(n) C3(n##0) C3(n##1) C3(n##2) C3(n##3) C3(n##4) \
+ C3(n##5) C3(n##6) C3(n##7) C3(n##8) C3(n##9)
+#else
+#define C3(n) C2(n##0) C2(n##4) C2(n##9)
+#define C4(n) C3(n##0) C3(n##3) C3(n##7)
+#endif
+#define TESTS C4(1) C1(10010) C1(10012) C1(16144)
+
+TESTS
+
+struct S { T x; T (*foo) (T); };
+
+#undef C
+#define C(n) { n - 10000, foo##n },
+
+struct S tests[] = {
+TESTS
+ { 0, 0 }
+};
+
+int
+main ()
+{
+ int i, j, k;
+ for (k = 0; tests[k].x; k++)
+ for (i = 0; i < sizeof (T) * __CHAR_BIT__; i++)
+ for (j = -5; j <= 5; j++)
+ {
+ U x = ((U) 1 << i) + j;
+ if (foo ((T) x, tests[k].x) != tests[k].foo ((T) x)
+ || foo ((T) -x, tests[k].x) != tests[k].foo ((T) -x))
+ __builtin_abort ();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97459-5.c b/gcc/testsuite/gcc.dg/pr97459-5.c
new file mode 100644
index 0000000..f658a5a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97459-5.c
@@ -0,0 +1,56 @@
+/* PR rtl-optimization/97459 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-DEXPENSIVE" { target run_expensive_tests } } */
+
+#ifdef __SIZEOF_INT128__
+typedef __uint128_t T;
+#else
+typedef unsigned long long T;
+#endif
+
+T __attribute__((noipa)) foo (T x, T n, T *r) { *r = x % n; return x / n; }
+#define C(n) T __attribute__((noipa)) foo##n (T x, T *r) { *r = x % (n - 10000); return x / (n - 10000); }
+
+#define C1(n) C(n##1) C(n##3) C(n##5) C(n##7) C(n##9)
+#define C2(n) C1(n##0) C1(n##1) C1(n##2) C1(n##3) C1(n##4) \
+ C1(n##5) C1(n##6) C1(n##7) C1(n##8) C1(n##9)
+#ifdef EXPENSIVE
+#define C3(n) C2(n##0) C2(n##1) C2(n##2) C2(n##3) C2(n##4) \
+ C2(n##5) C2(n##6) C2(n##7) C2(n##8) C2(n##9)
+#define C4(n) C3(n##0) C3(n##1) C3(n##2) C3(n##3) C3(n##4) \
+ C3(n##5) C3(n##6) C3(n##7) C3(n##8) C3(n##9)
+#else
+#define C3(n) C2(n##0) C2(n##4) C2(n##9)
+#define C4(n) C3(n##0) C3(n##3) C3(n##7)
+#endif
+#define TESTS C4(1) C1(10010) C1(10012) C1(16144)
+
+TESTS
+
+struct S { T x; T (*foo) (T, T *); };
+
+#undef C
+#define C(n) { n - 10000, foo##n },
+
+struct S tests[] = {
+TESTS
+ { 0, 0 }
+};
+
+int
+main ()
+{
+ int i, j, k;
+ for (k = 0; tests[k].x; k++)
+ for (i = 0; i < sizeof (T) * __CHAR_BIT__; i++)
+ for (j = -5; j <= 5; j++)
+ {
+ T x = ((T) 1 << i) + j;
+ T r1, r2;
+ if (foo (x, tests[k].x, &r1) != tests[k].foo (x, &r2)
+ || r1 != r2)
+ __builtin_abort ();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97459-6.c b/gcc/testsuite/gcc.dg/pr97459-6.c
new file mode 100644
index 0000000..d4602be
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97459-6.c
@@ -0,0 +1,62 @@
+/* PR rtl-optimization/97459 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-DEXPENSIVE" { target run_expensive_tests } } */
+
+#ifdef __SIZEOF_INT128__
+typedef __int128_t T;
+typedef __uint128_t U;
+#else
+typedef long long T;
+typedef unsigned long long U;
+#endif
+
+T __attribute__((noipa)) foo (T x, T n, T *r) { *r = x % n; return x / n; }
+#define C(n) T __attribute__((noipa)) foo##n (T x, T *r) { *r = x % (n - 10000); return x / (n - 10000); }
+
+#define C1(n) C(n##1) C(n##3) C(n##5) C(n##7) C(n##9)
+#define C2(n) C1(n##0) C1(n##1) C1(n##2) C1(n##3) C1(n##4) \
+ C1(n##5) C1(n##6) C1(n##7) C1(n##8) C1(n##9)
+#ifdef EXPENSIVE
+#define C3(n) C2(n##0) C2(n##1) C2(n##2) C2(n##3) C2(n##4) \
+ C2(n##5) C2(n##6) C2(n##7) C2(n##8) C2(n##9)
+#define C4(n) C3(n##0) C3(n##1) C3(n##2) C3(n##3) C3(n##4) \
+ C3(n##5) C3(n##6) C3(n##7) C3(n##8) C3(n##9)
+#else
+#define C3(n) C2(n##0) C2(n##4) C2(n##9)
+#define C4(n) C3(n##0) C3(n##3) C3(n##7)
+#endif
+#define TESTS C4(1) C1(10010) C1(10012) C1(16144)
+
+TESTS
+
+struct S { T x; T (*foo) (T, T *); };
+
+#undef C
+#define C(n) { n - 10000, foo##n },
+
+struct S tests[] = {
+TESTS
+ { 0, 0 }
+};
+
+int
+main ()
+{
+ int i, j, k;
+ for (k = 0; tests[k].x; k++)
+ for (i = 0; i < sizeof (T) * __CHAR_BIT__; i++)
+ for (j = -5; j <= 5; j++)
+ {
+ U x = ((U) 1 << i) + j;
+ T r1 = 0, r2 = 0;
+ if (foo ((T) x, tests[k].x, &r1) != tests[k].foo ((T) x, &r2)
+ || r1 != r2)
+ __builtin_abort ();
+ r1 = 0; r2 = 0;
+ if (foo ((T) -x, tests[k].x, &r1) != tests[k].foo ((T) -x, &r2)
+ || r1 != r2)
+ __builtin_abort ();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97515.c b/gcc/testsuite/gcc.dg/pr97515.c
index 84f145a..b4f2481 100644
--- a/gcc/testsuite/gcc.dg/pr97515.c
+++ b/gcc/testsuite/gcc.dg/pr97515.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-evrp" } */
+/* { dg-options "-O2 -fdump-tree-ccp2" } */
int
e7 (int gg)
@@ -20,6 +20,8 @@ e7 (int gg)
return xe;
}
-/* EVRP should be able to reduce this to a single goto. */
+/* EVRP should be able to reduce this to a single goto when we can
+ * revisit statements to try folding again based on changed inputs.
+ * Until then, make sure its gone by ccp2. */
-/* { dg-final { scan-tree-dump-times "goto" 1 "evrp" } } */
+/* { dg-final { scan-tree-dump-times "goto" 1 "ccp2" } } */
diff --git a/gcc/testsuite/gcc.dg/pr97534.c b/gcc/testsuite/gcc.dg/pr97534.c
new file mode 100644
index 0000000..b363a32
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97534.c
@@ -0,0 +1,9 @@
+/* PR target/97534 - ICE in decompose on arm*-*-*. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -O2 -g" } */
+
+int f (int a)
+{
+ int b;
+ __atomic_fetch_sub(&b, (int)(-__INT_MAX__ - 1), (int)0);
+}
diff --git a/gcc/testsuite/gcc.dg/pr97579.c b/gcc/testsuite/gcc.dg/pr97579.c
new file mode 100644
index 0000000..5cd5427
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97579.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 --param=max-unswitch-insns=1024" } */
+/* { dg-additional-options "-mavx512vl" { target x86_64-*-* i?86-*-* } } */
+
+int bad_odd_rows_0_0, rows_bad_row1, rows_bad_group_okay, calc_rows_row2;
+
+int
+rows_bad() {
+ int i, in_zeroes;
+ char block;
+ i = 0;
+ for (; i < 5; i++)
+ if (rows_bad_row1 & i)
+ in_zeroes = 0;
+ else {
+ if (!in_zeroes)
+ in_zeroes = 1;
+ if (block & 1)
+ rows_bad_group_okay = 1;
+ }
+ if (in_zeroes)
+ return rows_bad_group_okay;
+}
+
+void
+calc_rows() {
+ for (; calc_rows_row2; calc_rows_row2++) {
+ rows_bad();
+ bad_odd_rows_0_0 = rows_bad();
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/pr97806.c b/gcc/testsuite/gcc.dg/pr97806.c
new file mode 100644
index 0000000..9ec3299
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97806.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int b;
+long c;
+int g();
+void h(long *);
+void i(long *);
+void d() {
+ int e, f = b - e;
+ if (g())
+ h(&c + f);
+ else
+ i(&c + f);
+ __builtin_memset(0, 0, f * 8);
+}
diff --git a/gcc/testsuite/gcc.dg/pr97830.c b/gcc/testsuite/gcc.dg/pr97830.c
new file mode 100644
index 0000000..3729a65
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97830.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef enum { LangC } cLanguage;
+typedef enum { FunctionOneArg, FunctionStandard } cFunctionType;
+void *CCTK_CallFunction_function;
+cLanguage CCTK_CallFunction_fdata_0;
+cFunctionType CCTK_CallFunction_fdata_1;
+void CCTK_CallFunction_data() {
+ void (*standardfunc)();
+ int (*oneargfunc)();
+ switch (CCTK_CallFunction_fdata_1) {
+ case FunctionOneArg:
+ oneargfunc = CCTK_CallFunction_function;
+ oneargfunc(CCTK_CallFunction_data);
+ break;
+ case FunctionStandard:
+ switch (CCTK_CallFunction_fdata_0) {
+ case LangC:
+ standardfunc = CCTK_CallFunction_function;
+ standardfunc(CCTK_CallFunction_data);
+ }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/pr97860.c b/gcc/testsuite/gcc.dg/pr97860.c
new file mode 100644
index 0000000..04c0f19
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97860.c
@@ -0,0 +1,11 @@
+/* PR c/97860 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+foo (int n)
+{
+ typedef int T[0];
+ typedef T V[n];
+ void bar (V);
+}
diff --git a/gcc/testsuite/gcc.dg/pr97897.c b/gcc/testsuite/gcc.dg/pr97897.c
new file mode 100644
index 0000000..084c1cd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97897.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void h ();
+void f () __attribute__ ((returns_twice));
+void g (_Complex int a)
+{
+ f ();
+ if (a != 0)
+ {
+ a = 0;
+ h ();
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/pr97953.c b/gcc/testsuite/gcc.dg/pr97953.c
new file mode 100644
index 0000000..6219619
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97953.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-tree-fre" } */
+
+int __attribute__((noipa))
+foo (int flag, int *p)
+{
+ int val = *p;
+ if (flag)
+ {
+ if (val != 1)
+ __builtin_unreachable ();
+ return 0;
+ }
+ int val2 = *p;
+ return val2 == 2;
+}
+
+int main()
+{
+ int i = 2;
+ if (foo (0, &i) != 1)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97954.c b/gcc/testsuite/gcc.dg/pr97954.c
new file mode 100644
index 0000000..178e1d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97954.c
@@ -0,0 +1,12 @@
+/* PR rtl-optimization/97954 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (void)
+{
+ int x;
+ lab:
+ asm goto ("": "=r" (x) : : : lab);
+ return x;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97955.c b/gcc/testsuite/gcc.dg/pr97955.c
new file mode 100644
index 0000000..a5236c7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97955.c
@@ -0,0 +1,7 @@
+/* PR 97955 - ICE in build_array_type_1 on invalid redeclaration of function
+ with VLA parameter
+ { dg-do compile }
+ { dg-options "-Wall" } */
+
+void f (int n, int a[n]);
+void f (int *b) { } // { dg-error "conflicting types" }
diff --git a/gcc/testsuite/gcc.dg/pr97979.c b/gcc/testsuite/gcc.dg/pr97979.c
new file mode 100644
index 0000000..44aaff2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97979.c
@@ -0,0 +1,13 @@
+/* PR tree-optimization/97979 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-ccp" } */
+
+short a = 0;
+int b = 0;
+
+void
+foo (void)
+{
+ unsigned short d = b;
+ a = d >> -2U; /* { dg-warning "right shift count >= width of type" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr98099.c b/gcc/testsuite/gcc.dg/pr98099.c
new file mode 100644
index 0000000..34909f2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr98099.c
@@ -0,0 +1,12 @@
+/* PR middle-end/98099 */
+/* Reported by G. Steinmetz <gscfq@t-online.de> */
+
+/* { dg-do compile } */
+/* { dg-options "-fsso-struct=big-endian" } */
+
+struct S { _Decimal128 a; };
+
+_Decimal128 f (struct S x)
+{
+ return x.a; /* { dg-message "sorry, unimplemented: reverse storage order" "" { target { ! int128 } } } */
+}
diff --git a/gcc/testsuite/gcc.dg/profile-info-section.c b/gcc/testsuite/gcc.dg/profile-info-section.c
new file mode 100644
index 0000000..8f31f3b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/profile-info-section.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-skip-if "profile-info-section" { powerpc-ibm-aix* } } */
+/* { dg-options "-fprofile-arcs -fprofile-info-section -fdump-tree-optimized" } */
+
+int foo()
+{
+ return 0;
+}
+
+int bar()
+{
+ return 1;
+}
+
+int main ()
+{
+ return foo ();
+}
+
+/* { dg-final { scan-tree-dump-not "__gcov_init" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "__gcov_exit" "optimized" } } */
+/* { dg-final { scan-assembler "\.gcov_info" } } */
diff --git a/gcc/testsuite/gcc.dg/strncmp-2.c b/gcc/testsuite/gcc.dg/strncmp-2.c
index 6818b30..0d84f93 100644
--- a/gcc/testsuite/gcc.dg/strncmp-2.c
+++ b/gcc/testsuite/gcc.dg/strncmp-2.c
@@ -40,6 +40,7 @@ static void test_driver_strncmp (void (test_strncmp)(const char *, const char *,
e = lib_memcmp(buf1,p2,sz);
(*test_memcmp)(buf1,p2,e);
}
+ mprotect (buf2+pgsz,pgsz,PROT_READ|PROT_WRITE);
free(buf2);
}
diff --git a/gcc/testsuite/gcc.dg/system-binary-constants-1.c b/gcc/testsuite/gcc.dg/system-binary-constants-1.c
index 921ee20..ca16215 100644
--- a/gcc/testsuite/gcc.dg/system-binary-constants-1.c
+++ b/gcc/testsuite/gcc.dg/system-binary-constants-1.c
@@ -14,5 +14,5 @@ foo (void)
warning. */
return 23;
#endif
- return 0b1101; /* { dg-warning "binary constants are a GCC extension" } */
+ return 0b1101; /* { dg-warning "binary constants are a C2X feature or GCC extension" } */
}
diff --git a/gcc/testsuite/gcc.dg/torture/float128-nan-floath.c b/gcc/testsuite/gcc.dg/torture/float128-nan-floath.c
new file mode 100644
index 0000000..69fd45a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float128-nan-floath.c
@@ -0,0 +1,11 @@
+/* Test _Float128 NaNs in <float.h>. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -fsignaling-nans" } */
+/* { dg-add-options float128 } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target float128_runtime } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#define WIDTH 128
+#define EXT 0
+#include "floatn-nan-floath.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float128x-nan-floath.c b/gcc/testsuite/gcc.dg/torture/float128x-nan-floath.c
new file mode 100644
index 0000000..5be4c07
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float128x-nan-floath.c
@@ -0,0 +1,11 @@
+/* Test _Float128x NaNs in <float.h>. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -fsignaling-nans" } */
+/* { dg-add-options float128x } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target float128x_runtime } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#define WIDTH 128
+#define EXT 1
+#include "floatn-nan-floath.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float16-nan-floath.c b/gcc/testsuite/gcc.dg/torture/float16-nan-floath.c
new file mode 100644
index 0000000..cf03b45
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float16-nan-floath.c
@@ -0,0 +1,11 @@
+/* Test _Float16 NaNs in <float.h>. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -fsignaling-nans" } */
+/* { dg-add-options float16 } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target float16_runtime } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#define WIDTH 16
+#define EXT 0
+#include "floatn-nan-floath.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float32-nan-floath.c b/gcc/testsuite/gcc.dg/torture/float32-nan-floath.c
new file mode 100644
index 0000000..2976a40
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float32-nan-floath.c
@@ -0,0 +1,11 @@
+/* Test _Float32 NaNs in <float.h>. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -fsignaling-nans" } */
+/* { dg-add-options float32 } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target float32_runtime } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#define WIDTH 32
+#define EXT 0
+#include "floatn-nan-floath.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float32x-nan-floath.c b/gcc/testsuite/gcc.dg/torture/float32x-nan-floath.c
new file mode 100644
index 0000000..0aab4be
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float32x-nan-floath.c
@@ -0,0 +1,11 @@
+/* Test _Float32x NaNs in <float.h>. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -fsignaling-nans" } */
+/* { dg-add-options float32x } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target float32x_runtime } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#define WIDTH 32
+#define EXT 1
+#include "floatn-nan-floath.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float64-nan-floath.c b/gcc/testsuite/gcc.dg/torture/float64-nan-floath.c
new file mode 100644
index 0000000..1f5298b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float64-nan-floath.c
@@ -0,0 +1,11 @@
+/* Test _Float64 NaNs in <float.h>. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -fsignaling-nans" } */
+/* { dg-add-options float64 } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target float64_runtime } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#define WIDTH 64
+#define EXT 0
+#include "floatn-nan-floath.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float64x-nan-floath.c b/gcc/testsuite/gcc.dg/torture/float64x-nan-floath.c
new file mode 100644
index 0000000..fbc8676
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float64x-nan-floath.c
@@ -0,0 +1,11 @@
+/* Test _Float64x NaNs in <float.h>. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -fsignaling-nans" } */
+/* { dg-add-options float64x } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target float64x_runtime } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#define WIDTH 64
+#define EXT 1
+#include "floatn-nan-floath.h"
diff --git a/gcc/testsuite/gcc.dg/torture/floatn-nan-floath.h b/gcc/testsuite/gcc.dg/torture/floatn-nan-floath.h
new file mode 100644
index 0000000..9892fd0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/floatn-nan-floath.h
@@ -0,0 +1,36 @@
+/* Tests for _FloatN / _FloatNx types: compile and execution tests for
+ NaNs, SNAN macros in <float.h>. Before including this file, define
+ WIDTH as the value N; define EXT to 1 for _FloatNx and 0 for
+ _FloatN. */
+
+#define CONCATX(X, Y) X ## Y
+#define CONCAT(X, Y) CONCATX (X, Y)
+#define CONCAT3(X, Y, Z) CONCAT (CONCAT (X, Y), Z)
+#define CONCAT4(W, X, Y, Z) CONCAT (CONCAT (CONCAT (W, X), Y), Z)
+
+#if EXT
+# define TYPE CONCAT3 (_Float, WIDTH, x)
+# define SNAN CONCAT3 (FLT, WIDTH, X_SNAN)
+#else
+# define TYPE CONCAT (_Float, WIDTH)
+# define SNAN CONCAT3 (FLT, WIDTH, _SNAN)
+#endif
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <fenv.h>
+#include <float.h>
+
+extern void exit (int);
+extern void abort (void);
+
+volatile TYPE nans_cst = SNAN;
+
+int
+main (void)
+{
+ volatile TYPE r;
+ r = nans_cst + nans_cst;
+ if (!fetestexcept (FE_INVALID))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr97812.c b/gcc/testsuite/gcc.dg/torture/pr97812.c
new file mode 100644
index 0000000..4d468ad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr97812.c
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fdisable-tree-evrp" } */
+
+unsigned char c;
+
+int main() {
+volatile short b = 4066;
+ unsigned short bp = b;
+ unsigned d = bp & 2305;
+ signed char e = d;
+ c = e ? : e;
+ if (!d)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr97901.c b/gcc/testsuite/gcc.dg/torture/pr97901.c
new file mode 100644
index 0000000..a6a89ef
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr97901.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+int a[1], b, *c, *d;
+
+int main() {
+L:
+ d = c;
+ for (b = 0; b < 2; b++)
+ d = &a[0];
+ if (c)
+ goto L;
+ if (*d)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c
index 99a5488..85b6806 100644
--- a/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c
+++ b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c
@@ -6,11 +6,14 @@ struct Foo {
int *p;
};
+struct Foo *ff;
+
void __attribute__((noinline))
foo (void *p)
{
struct Foo *f = (struct Foo *)p - 1;
*f->p = 0;
+ ff = f;
}
int bar (void)
diff --git a/gcc/testsuite/gcc.dg/torture/ssa-fre-5.c b/gcc/testsuite/gcc.dg/torture/ssa-fre-5.c
index 180fd72..1915b9a 100644
--- a/gcc/testsuite/gcc.dg/torture/ssa-fre-5.c
+++ b/gcc/testsuite/gcc.dg/torture/ssa-fre-5.c
@@ -11,14 +11,14 @@ foo ()
int * p;
int i;
int x[4];
- long unsigned int _1;
- long unsigned int _2;
+ __SIZETYPE__ _1;
+ __SIZETYPE__ _2;
int _7;
__BB(2):
i_3 = 0;
- _1 = (long unsigned int) i_3;
- _2 = _1 * 4ul;
+ _1 = (__SIZETYPE__) i_3;
+ _2 = _1 * _Literal (__SIZETYPE__) 4;
p_4 = _Literal (int *) &x + _2;
__MEM <v4si> ((v4si *)p_4) = _Literal (v4si) { 1, 2, 3, 4 };
_7 = x[0];
diff --git a/gcc/testsuite/gcc.dg/torture/ssa-fre-6.c b/gcc/testsuite/gcc.dg/torture/ssa-fre-6.c
index 2c4235f..041d921 100644
--- a/gcc/testsuite/gcc.dg/torture/ssa-fre-6.c
+++ b/gcc/testsuite/gcc.dg/torture/ssa-fre-6.c
@@ -11,14 +11,14 @@ foo ()
int * p;
int i;
int x[4];
- long unsigned int _1;
- long unsigned int _2;
+ __SIZETYPE__ _1;
+ __SIZETYPE__ _2;
int _7;
__BB(2):
i_3 = 0;
- _1 = (long unsigned int) i_3;
- _2 = _1 * 4ul;
+ _1 = (__SIZETYPE__) i_3;
+ _2 = _1 * _Literal (__SIZETYPE__) 4;
p_4 = _Literal (int *) &x + _2;
__MEM <v4si> ((v4si *)p_4) = _Literal (v4si) {};
_7 = x[0];
diff --git a/gcc/testsuite/gcc.dg/tree-prof/stringop-2.c b/gcc/testsuite/gcc.dg/tree-prof/stringop-2.c
index b7471bf..e8b1644 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/stringop-2.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/stringop-2.c
@@ -20,6 +20,6 @@ main()
return 0;
}
/* autofdo doesn't support value profiling for now: */
-/* { dg-final-use-not-autofdo { scan-ipa-dump "Transformation done: single value 4 stringop" "profile"} } */
+/* { dg-final-use-not-autofdo { scan-ipa-dump "Transformation done: single value 4 stringop" "profile" { target { ! aarch64*-*-* } } } } */
/* The versioned memset of size 4 should be optimized to an assignment.
- { dg-final-use-not-autofdo { scan-tree-dump "MEM <\[a-z \]+> \\\[\\(void .\\)&a\\\] = 168430090" "optimized" } } */
+ { dg-final-use-not-autofdo { scan-tree-dump "MEM <\[a-z \]+> \\\[\\(void .\\)&a\\\] = 168430090" "optimized" { target { ! aarch64*-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c
index a94d123..0cc03ff 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c
@@ -112,17 +112,21 @@ void test_sprintf_c_const (void)
T ( 3, "%1$c%2$c", '1', '2');
/* Verify that a warning is issued for exceeding INT_MAX bytes and
- not otherwise. */
+ not otherwise. In ILP32 the maximum object size is INT_MAX - 1
+ bytes so the calls are diagnosed due to the overflow. */
T (-1, "%*c", INT_MAX - 1, '1');
- T (-1, "%*c", INT_MAX, '1');
- T (-1, "X%*c", INT_MAX - 1, '1');
- T (-1, "X%*c", INT_MAX, '1'); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
+ T (-1, "%*c", INT_MAX, '1'); /* { dg-warning "writing a terminating nul past the end " "ilp32" { target ilp32 } } */
+ T (-1, "X%*c", INT_MAX - 1, '1'); /* { dg-warning "writing a terminating nul past the end " "ilp32" { target ilp32 } } */
+ T (-1, "X%*c", INT_MAX, '1'); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." "lp64" { target lp64 } } */
+ /* { dg-warning "directive writing 2147483647 bytes into a region of size 2147483646" "ilp32" { target ilp32 } .-1 } */
- T (-1, "%*c%*c", INT_MAX - 1, '1', INT_MAX - 1, '2'); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
+ T (-1, "%*c%*c", INT_MAX - 1, '1', INT_MAX - 1, '2'); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." "lp64" { target lp64 } } */
+ /* { dg-warning "directive writing 2147483646 bytes into a region of size 1" "ilp32" { target ilp32 } .-1 } */
T (-1, "%*cX", INT_MAX - 2, '1');
- T (-1, "%*cX", INT_MAX - 1, '1');
- T (-1, "%*cX", INT_MAX, '1'); /* { dg-warning "output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
+ T (-1, "%*cX", INT_MAX - 1, '1'); /* { dg-warning "writing a terminating nul past the end of the destination" "ilp32" { target ilp32 } } */
+ T (-1, "%*cX", INT_MAX, '1'); /* { dg-warning "output of \[0-9\]+ bytes causes result to exceed .INT_MAX." "lp64" { target lp64 } } */
+ /* { dg-warning "directive writing 1 byte into a region of size 0" "ilp32" { target ilp32 } .-1 } */
}
/* Verify that no warning is issued for calls that write into a flexible
@@ -288,8 +292,9 @@ void test_sprintf_chk_s_const (void)
/* Verify that output in excess of INT_MAX bytes is diagnosed even
when the size of the destination object is unknown. */
T (-1, "%*s", INT_MAX - 1, "");
- T (-1, "%*s", INT_MAX, "");
- T (-1, "X%*s", INT_MAX, ""); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
+ T (-1, "%*s", INT_MAX, ""); /* { dg-warning "writing a terminating nul past the end" "ilp32" { target ilp32 } } */
+ T (-1, "X%*s", INT_MAX, ""); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." "lp64" { target lp64 } } */
+ /* { dg-warning "directive writing 2147483647 bytes into a region of size 2147483646" "ilp32" { target ilp32 } .-1 } */
/* Multiple directives. */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-11.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-11.c
index 02072b5..134967d 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-11.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-11.c
@@ -197,17 +197,21 @@ void test_narrow_string_with_width_and_precision (void)
IR (imax / 9, imax / 8), IR (imax / 7, imax / 6), SR (x, y),
IR (imax / 5, imax / 4), IR (imax / 3, imax / 2), SR (x, y));
- /* The two directives below combined convert to [INT_MAX, INT_MAX + 1].
+ /* The two directives below combined convert to [INT_MAX -1, INT_MAX + 1].
Since the lower end of the range doesn't exceed INT_MAX no warning
is expected. */
T (-1, "%*.*s%*.*s",
- IR (imax - 5, imax - 3), IR (1, 2), SR (x, y),
+ IR (imax - 6, imax - 3), IR (1, 2), SR (x, y),
IR ( 5, 6), IR (3, 4), SR (x, y));
/* The three directives below (the two %s plus the space in between)
combined convert to [INT_MAX + 1, INT_MAX + 2]. Since the lower
- end of the range exceeds INT_MAX a warning is expected. */
- T (-1, "%*.*s %*.*s", /* { dg-warning "INT_MAX" } */
+ end of the range exceeds INT_MAX a warning is expected. In ILP32,
+ the output overflows the maximum object size. */
+ T (-1, "%*.*s %*.*s",
+ /* { dg-warning "INT_MAX" "LP64" { target lp64 } .-1 }
+ { dg-warning "directive writing between 5 and 6 bytes into a region of size between 2 and 4" "ILP32" { target ilp32 } .-2 }
+ */
IR (imax - 5, imax - 3), IR (1, 2), SR (x, y),
IR ( 5, 6), IR (3, 4), SR (x, y));
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-18.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-18.c
index 6a18f17..2c410b1 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-18.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-18.c
@@ -117,10 +117,10 @@ void test_width_and_precision_out_of_range (char *d)
{
/* The range here happens to be a property of the compiler, not
one of the target. */
- T ("%9223372036854775808i", 0); /* { dg-warning "width out of range" "first" } */
- /* { dg-warning "exceeds .INT_MAX." "second" { target *-*-* } .-1 } */
- T ("%.9223372036854775808i", 0); /* { dg-warning "precision out of range" "first" } */
- /* { dg-warning "exceeds .INT_MAX." "second" { target *-*-* } .-1 } */
+ T ("%9223372036854775808i", 0); /* { dg-warning "width out of range|exceeds 'INT_MAX'" "first" } */
+ /* { dg-warning "directive writing \\d+ bytes into a region of size \\d+" "" { target ilp32 } .-1 } */
+ T ("%.9223372036854775808i", 0); /* { dg-warning "precision out of range|exceeds 'INT_MAX'" "first" } */
+ /* { dg-warning "directive writing \\d+ bytes into a region of size \\d+" "ilp32" { target ilp32 } .-1 } */
/* The following is diagnosed by -Wformat (disabled here). */
/* T ("%9223372036854775808$i", 0); */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-25.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-25.c
new file mode 100644
index 0000000..df46023
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-25.c
@@ -0,0 +1,76 @@
+/* PR middle-end/97373 - missing warning on sprintf into allocated destination
+ { dg-do compile }
+ { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
+
+#include "../range.h"
+
+extern void* alloca (size_t);
+extern void* malloc (size_t);
+
+extern int sprintf (char*, const char*, ...);
+#define sprintf(d, ...) (sprintf (d, __VA_ARGS__), sink (d))
+
+void sink (void*, ...);
+
+void test_alloca_range (void)
+{
+ int n1_2 = UR (1, 2);
+ int n5_9 = UR (5, 9);
+
+ char *d = (char*)alloca (n5_9);
+
+ sprintf (d, "%i", 12345);
+
+ d += n1_2;
+ sprintf (d, "%i", 12345);
+
+ d += n1_2;
+ sprintf (d, "%i", 12345);
+
+ d += n1_2;
+ sprintf (d, "%i", 12345);
+
+ d += n1_2;
+ sprintf (d, "%i", 12345); // { dg-warning "writing a terminating nul past the end of the destination" }
+
+ d += n1_2;
+ sprintf (d, "%i", 12345); // { dg-warning "'%i' directive writing 5 bytes into a region of size 4" }
+}
+
+
+void test_malloc_range (void)
+{
+ int n2_3 = UR (2, 3);
+ int n5_9 = UR (5, 9);
+
+ char *d = (char*)malloc (n5_9);
+
+ sprintf (d, "%i", 12345);
+
+ d += n2_3;
+ sprintf (d, "%i", 12345);
+
+ d += n2_3;
+ sprintf (d, "%i", 12345); // { dg-warning "writing a terminating nul past the end of the destination" }
+
+ d += n2_3;
+ sprintf (d, "%i", 12345); // { dg-warning "'%i' directive writing 5 bytes into a region of size 3" }
+}
+
+
+void test_vla_range (void)
+{
+ int n3_4 = UR (3, 4);
+ int n5_9 = UR (5, 9);
+
+ char vla[n5_9];
+ char *d = vla;
+
+ sprintf (d, "%i", 12345);
+
+ d += n3_4;
+ sprintf (d, "%i", 12345);
+
+ d += n3_4;
+ sprintf (d, "%i", 12345); // { dg-warning "'%i' directive writing 5 bytes into a region of size 3" }
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp20.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp20.c
new file mode 100644
index 0000000..7d4d55f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp20.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void call (void);
+
+void foo (int base)
+{
+ unsigned i;
+
+ // Ranger should be able to remove the (i > 123) comparison.
+ for (i = base; i < 10; i++)
+ if (i > 123)
+ {
+ call ();
+ return;
+ }
+}
+
+/* { dg-final { scan-tree-dump-not "call" "evrp"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp21.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp21.c
new file mode 100644
index 0000000..dae788c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp21.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+extern void vrp_keep (void);
+extern void vrp_kill (void);
+
+void
+f2 (int s, int b)
+{
+ if (s > 4)
+ s = 4;
+ if (s < -16)
+ s = -16;
+ /* s in [-16, 4]. */
+ b = (b & 1) + 1;
+ /* b in range [1, 2]. */
+ b = s << b;
+ /* b in range [-64, 16]. */
+ if (b == -2)
+ vrp_keep ();
+ if (b <= -65)
+ vrp_kill ();
+ if (b >= 17)
+ vrp_kill ();
+}
+
+/* { dg-final { scan-tree-dump-times "vrp_keep \\(" 1 "evrp"} } */
+/* { dg-final { scan-tree-dump-times "vrp_kill \\(" 0 "evrp"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp22.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp22.c
new file mode 100644
index 0000000..3dd47e5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp22.c
@@ -0,0 +1,43 @@
+/* See backwards thru casts if the range fits the LHS type. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+extern void kill(int i);
+extern void keep(int i);
+
+void
+foo (int i)
+{
+ if (i >= 10)
+ {
+ if (i <= 100)
+ {
+ /* i has a range of [10, 100] */
+ char c = (char) i;
+ if (c < 30)
+ {
+ /* If we wind back thru the cast with the range of c being [10,29]
+ * from the branch, and recognize that the range of i fits within
+ * a cast to c, then there is no missing information in a cast
+ * back to int. We can use the range calculated for 'c' with 'i'
+ * as well and Ranger should be able to kill the call. */
+ if (i > 29)
+ kill (i);
+ }
+ }
+ /* i has a range of [10, MAX] */
+ char d = (char) i;
+ if (d < 30)
+ {
+ /* Here, a cast to a char and back is NOT equivalent, so we cannot use
+ * the value of d to remove the call. */
+ if (i > 29)
+ keep (i);
+ }
+
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "kill \\(" 0 "evrp"} } */
+/* { dg-final { scan-tree-dump-times "keep \\(" 1 "evrp"} } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-1.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-1.c
new file mode 100644
index 0000000..e66fa73
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-1.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+int global;
+int foo ();
+
+int main(int argc, char **argv)
+{
+ if (argc == 1)
+ foo ();
+ else if (argc == 2)
+ {
+ global += 1;
+ }
+ else if (argc == 3)
+ {
+ foo ();
+ foo ();
+ }
+ else if (argc == 4)
+ {
+ foo ();
+ }
+ else if (argc == 5)
+ {
+ global = 2;
+ }
+ else
+ global -= 123;
+
+ global -= 12;
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump "Condition chain with \[^\n\r]\* BBs transformed into a switch statement." "iftoswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-2.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-2.c
new file mode 100644
index 0000000..252bea6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+int isMyRandomCharacter(int aChar)
+{
+ return aChar == 0x0001 || aChar == 0x000A ||
+ aChar == 0x000C || aChar == 0x000E ||
+ aChar == 0x0020;
+}
+
+/* { dg-final { scan-tree-dump "Condition chain with \[^\n\r]\* BBs transformed into a switch statement." "iftoswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-3.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-3.c
new file mode 100644
index 0000000..707e630
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+int IsMySuperRandomChar(int aChar)
+{
+ return aChar == 0x0009 || aChar == 0x000A ||
+ aChar == 0x000C || aChar == 0x000D ||
+ aChar == 0x0020 || aChar == 0x0030;
+}
+
+/* { dg-final { scan-tree-dump "Condition chain with \[^\n\r]\* BBs transformed into a switch statement." "iftoswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-4.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-4.c
new file mode 100644
index 0000000..6a03588
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-4.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+int global;
+int foo ();
+
+int main(int argc, char **argv)
+{
+ if (argc == 1)
+ foo ();
+ else if (argc == 2)
+ {
+ global += 1;
+ }
+ else if (argc == 3)
+ {
+ foo ();
+ foo ();
+ }
+ else if (argc == 4)
+ {
+ foo ();
+ }
+ /* This will be removed with EVRP. */
+ else if (argc == 1)
+ {
+ global = 2;
+ }
+ else
+ global -= 123;
+
+ global -= 12;
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "Condition chain" "iftoswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-5.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-5.c
new file mode 100644
index 0000000..ceeae90
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-5.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+int crud (unsigned char c)
+{
+ return (((((((((((int) c == 46) || (int) c == 44)
+ || (int) c == 58) || (int) c == 59) || (int) c == 60)
+ || (int) c == 62) || (int) c == 34) || (int) c == 92)
+ || (int) c == 39) != 0);
+}
+
+/* { dg-final { scan-tree-dump "Condition chain with \[^\n\r]\* BBs transformed into a switch statement." "iftoswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-6.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-6.c
new file mode 100644
index 0000000..464b1fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-6.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+int global;
+int foo ();
+
+int main(int argc, char **argv)
+{
+ if (argc >= 1 && argc <= 10)
+ foo ();
+ else if (argc == 12)
+ {
+ global += 1;
+ }
+ else if (argc == 13)
+ {
+ foo ();
+ foo ();
+ }
+ else if (argc == 14)
+ {
+ foo ();
+ }
+ /* This will be removed with EVRP. */
+ else if (argc == 5)
+ {
+ global = 2;
+ }
+ /* This will be removed with EVRP. */
+ else if (argc >= 7 && argc <= 9)
+ {
+ global = 2;
+ }
+
+ else
+ global -= 123;
+
+ global -= 12;
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "Condition chain" "iftoswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-7.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-7.c
new file mode 100644
index 0000000..4a176f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-7.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+int global;
+
+int foo(int a)
+{
+ int x = 0;
+ for (unsigned i = 0; i < a; i++)
+ {
+ if (a == 2)
+ {
+ global += 123;
+ x = 1;
+ }
+ else if (a == 3)
+ x = 2;
+ else if (a == 10)
+ x = 3;
+ }
+
+ return x;
+}
+
+/* { dg-final { scan-tree-dump-not "Condition chain " "iftoswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-8.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-8.c
new file mode 100644
index 0000000..f43ce7d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-8.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+int global;
+int global1;
+int global2;
+int global3;
+
+int foo(int a, int b)
+{
+ int x = 0;
+ for (unsigned i = 0; i < a; i++)
+ {
+ if (b == 1)
+ global += 2;
+ else if (a == 2)
+ global = 123;
+ else if (a == 3)
+ global1 = 1234;
+ else if (a == 10)
+ global2 = 12345;
+ else if (a == 1)
+ global2 = 123456;
+ }
+}
+
+/* { dg-final { scan-tree-dump-not "Condition chain" "iftoswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-9.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-9.c
new file mode 100644
index 0000000..e67198b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-9.c
@@ -0,0 +1,11 @@
+/* PR tree-optimization/88702 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+int IsHTMLWhitespace(int aChar) {
+ return aChar == 0x0009 || aChar == 0x000A ||
+ aChar == 0x000C || aChar == 0x000D ||
+ aChar == 0x0020;
+}
+
+/* { dg-final { scan-tree-dump "Condition chain with \[^\n\r]\* BBs transformed into a switch statement." "iftoswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loopclosedphi.c b/gcc/testsuite/gcc.dg/tree-ssa/loopclosedphi.c
new file mode 100644
index 0000000..d71b757
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loopclosedphi.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fno-tree-ch -w -fdump-tree-loopdone-details" } */
+
+void
+t6 (int qz, int wh)
+{
+ int jl = wh;
+
+ while (1.0 * qz / wh < 1)
+ {
+ qz = wh * (wh + 2);
+
+ while (wh < 1)
+ jl = 0;
+ }
+
+ while (qz < 1)
+ qz = jl * wh;
+}
+
+/* { dg-final { scan-tree-dump-times "Replacing" 2 "loopdone"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-5.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-5.c
new file mode 100644
index 0000000..fde3177
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-5.c
@@ -0,0 +1,27 @@
+/* { dg-options "-O2 -fdump-tree-modref1" } */
+/* { dg-do run } */
+__attribute__ ((noinline))
+void
+copy (int *a, int *b)
+{
+ *a=*b;
+}
+int p, *ptr = &p;
+__attribute__ ((noinline))
+void
+barrier ()
+{
+ asm ("":"=r"(ptr):"0"(ptr));
+}
+int
+main()
+{
+ int a = 1, b = 2;
+ copy (&a,&b);
+ barrier ();
+ *ptr = 1;
+ if (!__builtin_constant_p (b == 2))
+ __builtin_abort ();
+ return 0;
+}
+/* { dg-final { scan-tree-dump "parm 1 flags: nodirectescape" "modref1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23401.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23401.c
index fb8aebf..a93fcaf 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr23401.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23401.c
@@ -19,5 +19,5 @@ int ffff(int i)
/* We should not use extra temporaries apart from for i1 + i2. */
-/* { dg-final { scan-tree-dump-times "int" 5 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "int" 6 "gimple" } } */
/* { dg-final { scan-tree-dump-times "int D\\\." 1 "gimple" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr27810.c b/gcc/testsuite/gcc.dg/tree-ssa/pr27810.c
index 84dfcc9..5c1945b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr27810.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr27810.c
@@ -13,5 +13,5 @@ int qqq (int a)
/* We should not use an extra temporary for the result of the
function call. */
-/* { dg-final { scan-tree-dump-times "int" 3 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "int" 4 "gimple" } } */
/* { dg-final { scan-tree-dump-times "int D\\\." 1 "gimple" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr78655.c b/gcc/testsuite/gcc.dg/tree-ssa/pr78655.c
new file mode 100644
index 0000000..e9158e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr78655.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-ccp -fno-tree-forwprop -fno-tree-fre -fdump-tree-evrp" } */
+
+struct A{int a,b;};
+inline int*f1(struct A*p){return&p->a;} /* offset of 0. */
+inline int*f2(struct A*p){return&p->b;} /* Offset of non-zero. */
+inline int*g(struct A*p){return(int*)p+1;} /* Always non-zero offet. */
+
+/* Should be able to eliminate all calls to bad(). */
+
+void bad(void);
+
+int
+main()
+{
+ struct A* ptr = 0;
+ struct A addr;
+
+ if (f1 (ptr) != 0)
+ bad();
+ if (f1 (&addr) == 0)
+ bad();
+
+ if (f2 (ptr) == 0)
+ bad();
+ if (f2 (&addr) == 0)
+ bad();
+
+ if (g (ptr) == 0)
+ bad();
+ if (g (&addr) == 0)
+ bad();
+
+}
+
+/* { dg-final { scan-tree-dump-not "bad" "evrp"} } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr91029-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr91029-1.c
new file mode 100644
index 0000000..d52734b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr91029-1.c
@@ -0,0 +1,68 @@
+/* PR tree-optimization/91029 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void kill (void);
+int xx;
+
+void f1 (int i, int j)
+{
+ if ((i % j) == 3)
+ {
+ xx = (i < 3);
+ if (xx)
+ kill ();
+ }
+}
+
+void f2 (int i, int j)
+{
+ if ((i % j) > 0)
+ {
+ xx = (i <= 0);
+ if (xx)
+ kill ();
+ }
+}
+
+void f3 (int i, int j)
+{
+ if ((i % j) == -3)
+ {
+ xx = (i > -3);
+ if (xx)
+ kill ();
+ }
+}
+
+void f4 (int i, int j)
+{
+ if ((i % j) < 0)
+ {
+ xx = (i >= 0);
+ if (xx)
+ kill ();
+ }
+}
+
+void f5 (int i, int j)
+{
+ if ((i % j) > 42)
+ {
+ xx = (i <= 42);
+ if (xx)
+ kill ();
+ }
+}
+
+void f6 (int i, int j)
+{
+ if ((i % j) < -124)
+ {
+ xx = (i >= -124);
+ if (xx)
+ kill ();
+ }
+}
+
+/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr91029-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr91029-2.c
new file mode 100644
index 0000000..ad9213a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr91029-2.c
@@ -0,0 +1,98 @@
+/* PR tree-optimization/91029 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void kill (void);
+int xx;
+
+void f1 (int i, int j)
+{
+ if ((i % j) == 3)
+ {
+ xx = (j <= 3 && j >= -3);
+ if (xx)
+ kill ();
+ }
+}
+
+void f2 (int i, int j)
+{
+ if ((i % j) > 0)
+ {
+ xx = (j <= 1 && j >= -1);
+ if (xx)
+ kill ();
+ }
+}
+
+void f3 (int i, int j)
+{
+ if ((i % j) == -3)
+ {
+ xx = (j <= 3 && j >= -3);
+ if (xx)
+ kill ();
+ }
+}
+
+void f4 (int i, int j)
+{
+ if ((i % j) < 0)
+ {
+ xx = (j <= 1 && j >= -1);
+ if (xx)
+ kill ();
+ }
+}
+
+void f5 (int i, int j)
+{
+ if ((i % j) > 42)
+ {
+ xx = (j <= 43 && j >= -43);
+ if (xx)
+ kill ();
+ }
+}
+
+void f6 (int i, int j)
+{
+ if ((i % j) < -124)
+ {
+ xx = (j <= 125 && j >= -125);
+ if (xx)
+ kill ();
+ }
+}
+
+void f7 (unsigned int i, unsigned int j)
+{
+ if ((i % j) == 3)
+ {
+ xx = (j <= 3);
+ if (xx)
+ kill ();
+ }
+}
+
+void f8 (unsigned int i, unsigned int j)
+{
+ if ((i % j) > 0)
+ {
+ xx = (j <= 1);
+ if (xx)
+ kill ();
+ }
+}
+
+void f9 (unsigned int i, unsigned int j)
+{
+ if ((i % j) >= 124)
+ {
+ xx = (j <= 124);
+ if (xx)
+ kill ();
+ }
+}
+
+/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr93781-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr93781-1.c
new file mode 100644
index 0000000..5ebd805
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr93781-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void kill (void);
+
+void foo (unsigned int arg)
+{
+ int a = arg - 3;
+ unsigned int b = 4;
+ int x = 0x1 << arg;
+
+ if (a < 0)
+ b = x;
+
+ /* In the fullness of time, we will delete this call. */
+ if (b >= 5)
+ kill ();;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr93781-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr93781-2.c
new file mode 100644
index 0000000..c9b2878
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr93781-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void kill (void);
+
+void foo (unsigned int arg)
+{
+ unsigned int C000003FE = 4;
+
+ if (arg + 1 < 4) // work for if (arg < 3)
+ C000003FE = 0x1 << arg;
+
+ if (C000003FE >= 5)
+ kill ();
+}
+
+/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr93781-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr93781-3.c
new file mode 100644
index 0000000..e1d2be0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr93781-3.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void kill (void);
+
+void foo (unsigned int arg)
+{
+ int a = arg - 3;
+ unsigned int b = 4;
+
+ if (a < 0)
+ {
+ int x = 0x1 << arg;
+ b = x;
+ }
+
+ if (b >= 5)
+ kill ();
+}
+
+/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96480.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96480.c
index f2a91ef..fc2103d 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr96480.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96480.c
@@ -1,6 +1,6 @@
/* PR tree-optimization/96480 */
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fdump-tree-optimized -fno-bit-tests -fno-jump-tables" } */
/* { dg-final { scan-tree-dump " = _\[0-9]* <= 3;" "optimized" } } */
int v[4];
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96789.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96789.c
index d6139a0..5704952 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr96789.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96789.c
@@ -1,5 +1,8 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -funroll-loops -ftree-vectorize -fdump-tree-dse-details" } */
+/* Disable loop vectorization to avoid that loop vectorizer
+ optimizes those two loops that operate tmp array so that
+ subsequent dse3 won't eliminate expected tmp stores. */
+/* { dg-options "-O2 -funroll-loops -ftree-slp-vectorize -fno-tree-loop-vectorize -fdump-tree-dse-details" } */
/* Test if scalar cleanup pass takes effects, mainly check
its secondary pass DSE can remove dead stores on array
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96929.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96929.c
new file mode 100644
index 0000000..65b6147
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96929.c
@@ -0,0 +1,21 @@
+/* PR tree-optimization/96929 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump "baz \\\(\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return -1;" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-not " >> " "optimized" } } */
+
+int baz (void);
+
+int
+foo (void)
+{
+ return -1 >> baz ();
+}
+
+int
+bar (int y)
+{
+ int z = -1;
+ return z >> y;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr97849.c b/gcc/testsuite/gcc.dg/tree-ssa/pr97849.c
new file mode 100644
index 0000000..57a31e3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr97849.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -ftree-vectorize" } */
+/* { dg-additional-options "-march=armv8.2-a+sve" { target aarch64*-*-* } } */
+
+int a, b, c;
+
+int g() {
+ char i = 0;
+ for (c = 0; c <= 8; c++)
+ --i;
+
+ while (b) {
+ _Bool f = i <= 0;
+ a = (a == 0) ? 0 : f / a;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr97964.c b/gcc/testsuite/gcc.dg/tree-ssa/pr97964.c
new file mode 100644
index 0000000..0ee0196
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr97964.c
@@ -0,0 +1,18 @@
+/* PR tree-optimization/97964 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not "link_failure \\\(\\\);" "optimized" } } */
+
+void link_failure (void);
+
+void
+foo (int a)
+{
+ long b = -2;
+ int c = a > 0;
+ int d = b * c;
+ int e = 1 - d;
+ int t = (-1 / e) == 1;
+ if (t != 0)
+ link_failure ();
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr97997-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr97997-1.c
new file mode 100644
index 0000000..3c4b468
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr97997-1.c
@@ -0,0 +1,52 @@
+/* PR tree-optimization/97997 */
+/* { dg-do compile { target { ilp32 || lp64 } } } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times "return x_\[0-9]*\\\(D\\\);" 6 "optimized" } } */
+/* { dg-final { scan-tree-dump-not " / " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " \\* " "optimized" } } */
+
+unsigned short
+f1 (unsigned short x)
+{
+ return x * 10 / 10;
+}
+
+unsigned short
+f2 (unsigned short x)
+{
+ int a = x;
+ int b = 10;
+ int c = 10;
+ return a * b / c;
+}
+
+unsigned short
+f3 (unsigned short x)
+{
+ return x * 10U / 10;
+}
+
+unsigned short
+f4 (unsigned short x)
+{
+ unsigned a = x;
+ unsigned b = 10;
+ unsigned c = 10;
+ return a * b / c;
+}
+
+unsigned short
+f5 (unsigned short x, unsigned short y)
+{
+ return (unsigned) x * y / y;
+}
+
+unsigned int
+f6 (unsigned int x, unsigned int y)
+{
+ if (x >= 30000)
+ __builtin_unreachable ();
+ if (y >= ~0U / 30000)
+ __builtin_unreachable ();
+ return x * y / y;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr97997-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr97997-2.c
new file mode 100644
index 0000000..a9d5075
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr97997-2.c
@@ -0,0 +1,41 @@
+/* PR tree-optimization/97997 */
+/* { dg-do compile { target { ilp32 || lp64 } } } */
+/* { dg-options "-O2 -fdump-tree-optimized -fwrapv" } */
+/* { dg-final { scan-tree-dump-times "return x_\[0-9]*\\\(D\\\);" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-not " / " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " \\* " "optimized" } } */
+
+unsigned short
+f1 (unsigned short x)
+{
+ return x * 10 / 10;
+}
+
+unsigned short
+f2 (unsigned short x)
+{
+ int a = x;
+ int b = 10;
+ int c = 10;
+ return a * b / c;
+}
+
+short
+f3 (short x, short y)
+{
+ return x * y / y;
+}
+
+int
+f4 (int x, int y)
+{
+ if (x >= 30000)
+ __builtin_unreachable ();
+ if (x <= -30000)
+ __builtin_unreachable ();
+ if (y >= __INT_MAX__ / 30000)
+ __builtin_unreachable ();
+ if (y <= -__INT_MAX__ / 30000)
+ __builtin_unreachable ();
+ return x * y / y;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr98084.c b/gcc/testsuite/gcc.dg/tree-ssa/pr98084.c
new file mode 100644
index 0000000..6379624
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr98084.c
@@ -0,0 +1,26 @@
+/* PR tree-optimization/98084 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+enum {
+ JSON_VARIANT_STRING,
+ JSON_VARIANT_UNSIGNED,
+ JSON_VARIANT_REAL,
+ JSON_VARIANT_ARRAY,
+ _JSON_VARIANT_TYPE_INVALID,
+ _JSON_VARIANT_MAGIC_ZERO_UNSIGNED,
+ _JSON_VARIANT_MAGIC_ZERO_REAL,
+ _JSON_VARIANT_MAGIC_EMPTY_STRING,
+ _JSON_VARIANT_MAGIC_EMPTY_ARRAY
+} json_variant_type(int *v) {
+ if (!v)
+ return _JSON_VARIANT_TYPE_INVALID;
+ if (v == (int *)_JSON_VARIANT_MAGIC_ZERO_UNSIGNED)
+ return JSON_VARIANT_UNSIGNED;
+ if (v == (int *)_JSON_VARIANT_MAGIC_ZERO_REAL)
+ return JSON_VARIANT_REAL;
+ if (v == (int *)_JSON_VARIANT_MAGIC_EMPTY_STRING)
+ return JSON_VARIANT_STRING;
+ if (v == (int *)_JSON_VARIANT_MAGIC_EMPTY_ARRAY)
+ return JSON_VARIANT_ARRAY;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr98094.c b/gcc/testsuite/gcc.dg/tree-ssa/pr98094.c
new file mode 100644
index 0000000..f88534a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr98094.c
@@ -0,0 +1,21 @@
+/* PR tree-optimization/98084 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+struct
+{
+ unsigned a : 10;
+} b;
+
+int c;
+void e();
+void d ()
+{
+ c = b.a;
+ if (c == 8 || c == 0)
+ ;
+ else if (c > 8 * 8)
+ ;
+ else if (c < 8 * 8)
+ e ();
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-32.c b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-32.c
index 944362a..093e7a5 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-32.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-32.c
@@ -1,6 +1,6 @@
/* { dg-do run { target { ! "m68k*-*-* mmix*-*-* bfin*-*-* v850*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
-/* { dg-options "-O2 -fno-inline -fdump-tree-reassoc1-details --param logical-op-non-short-circuit=1" } */
+/* { dg-options "-O2 -fno-inline -fdump-tree-reassoc1-details --param logical-op-non-short-circuit=1 -fno-bit-tests" } */
/* { dg-additional-options "-mbranch-cost=2" { target branch_cost } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-8.c b/gcc/testsuite/gcc.dg/tree-ssa/slsr-8.c
index 585b660..479f40f 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/slsr-8.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-8.c
@@ -23,7 +23,7 @@ f (int s, int *c, int *d)
However, this proves to be a useful test for introducing an
initializer with a cast, so we'll keep it as is. */
-/* There are 4 ' * ' instances in the decls (since "int * iftmp.0;" is
- added), 2 parms, 3 in the code. The second one in the code may
- be a widening multiply (for example, on AArch64). */
-/* { dg-final { scan-tree-dump-times " w?\\* " 9 "optimized" } } */
+/* There are 5 ' * ' instances in the decls (since "int * iftmp.0;" is
+ added), 2 parms, 3 in the code, and the return value. The second one
+ in the code may be a widening multiply (for example, on AArch64). */
+/* { dg-final { scan-tree-dump-times " w?\\* " 10 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-3.c
index 51ba59c..de3051b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-3.c
@@ -15,4 +15,4 @@ int test (int a, int b, int c, int g)
/* We should hoist and CSE only the multiplication. */
/* { dg-final { scan-tree-dump-times " \\* " 1 "pre" } } */
-/* { dg-final { scan-tree-dump "Insertions: 1" "pre" } } */
+/* { dg-final { scan-tree-dump "HOIST inserted: 1" "pre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-7.c
index ce9cec6..fdb6a3e 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-7.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-7.c
@@ -49,6 +49,6 @@ void foo (int a, int b, int c, int d, int e, int x, int y, int z)
/* Now inserting x + y five times is unnecessary but the cascading
cannot be avoided with the simple-minded dataflow. But make sure
- we do the insertions all in the first iteration. */
-/* { dg-final { scan-tree-dump "insert iterations == 2" "pre" } } */
+ we do not iterate PRE insertion. */
+/* { dg-final { scan-tree-dump "insert iterations == 1" "pre" } } */
/* { dg-final { scan-tree-dump "HOIST inserted: 5" "pre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c
index 59af63a..cf93173 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c
@@ -24,4 +24,4 @@ bar (int b, int x)
/* We should see the partial redundant loads of f even though they
are using different types (of the same size). */
-/* { dg-final { scan-tree-dump-times "Replaced MEM" 2 "pre" } } */
+/* { dg-final { scan-tree-dump-times "Replaced MEM" 3 "pre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/switch-1.c b/gcc/testsuite/gcc.dg/tree-ssa/switch-1.c
index 149687c..6f70c9d 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/switch-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/switch-1.c
@@ -54,7 +54,7 @@ int foo3 (int x)
}
}
-/* { dg-final { scan-tree-dump ";; GIMPLE switch case clusters: JT:0-62" "switchlower1" } } */
+/* { dg-final { scan-tree-dump ";; GIMPLE switch case clusters: BT:0-62" "switchlower1" } } */
int foo4 (int x)
{
@@ -77,7 +77,7 @@ int foo4 (int x)
}
}
-/* { dg-final { scan-tree-dump ";; GIMPLE switch case clusters: -100 JT:10-62 600-700" "switchlower1" } } */
+/* { dg-final { scan-tree-dump ";; GIMPLE switch case clusters: -100 BT:10-62 600-700" "switchlower1" } } */
int foo5 (int x)
{
@@ -107,4 +107,4 @@ int foo5 (int x)
}
}
-/* { dg-final { scan-tree-dump ";; GIMPLE switch case clusters: JT:10-62 600-700 JT:1000-1021 111111" "switchlower1" } } */
+/* { dg-final { scan-tree-dump ";; GIMPLE switch case clusters: BT:10-62 600-700 JT:1000-1021 111111" "switchlower1" } } */
diff --git a/gcc/testsuite/gcc.dg/typeof-2.c b/gcc/testsuite/gcc.dg/typeof-2.c
index 21ef5b0..68f91c6 100644
--- a/gcc/testsuite/gcc.dg/typeof-2.c
+++ b/gcc/testsuite/gcc.dg/typeof-2.c
@@ -1,21 +1,23 @@
-/* Test qualifier discard of typeof for atomic types. */
+/* Test qualifier preservation of typeof and discarded for __auto_type. */
/* { dg-do compile } */
/* { dg-options "-std=c11" } */
-/* Check that the qualifiers are discarded for atomic types. */
+/* Check that the qualifiers are preserved for atomic types. */
extern int i;
extern int * p;
extern int _Atomic const ci;
-extern __typeof (ci) i;
+extern __typeof (ci) ci;
extern int _Atomic volatile vi;
-extern __typeof (vi) i;
+extern __typeof (vi) vi;
extern int * _Atomic restrict ri;
-extern __typeof (ri) p;
+extern __typeof (ri) ri;
+
+/* Check that the qualifiers are discarded for atomic types. */
void f(void)
{
@@ -46,14 +48,16 @@ extern __typeof (nvi) k;
extern int * restrict nri;
extern __typeof (nri) q;
+/* Check that the qualifiers are discarded for non-atomic types. */
+
void g(void)
{
__auto_type aci = nci;
- int const *paci = &aci;
+ int *paci = &aci;
__auto_type avi = nvi;
- int volatile *pavi = &avi;
+ int *pavi = &avi;
__auto_type ari = nri;
- int * restrict *pari = &ari;
+ int **pari = &ari;
}
diff --git a/gcc/testsuite/gcc.dg/vect/aligned-section-anchors-nest-1.c b/gcc/testsuite/gcc.dg/vect/aligned-section-anchors-nest-1.c
index f8c36a8..24b2fa8 100644
--- a/gcc/testsuite/gcc.dg/vect/aligned-section-anchors-nest-1.c
+++ b/gcc/testsuite/gcc.dg/vect/aligned-section-anchors-nest-1.c
@@ -30,4 +30,4 @@ int *foo(void)
return &c[0][0];
}
-/* { dg-final { scan-ipa-dump-times "Increasing alignment of decl" 3 "increase_alignment" } } */
+/* { dg-final { scan-ipa-dump-times "Increasing alignment of decl" 3 "increase_alignment" { xfail vect_element_align_preferred } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-43.c b/gcc/testsuite/gcc.dg/vect/bb-slp-43.c
index a65d951..40bd2e0 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-43.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-43.c
@@ -14,4 +14,4 @@ f (int *restrict x, short *restrict y)
}
/* { dg-final { scan-tree-dump-not "mixed mask and nonmask" "slp2" } } */
-/* { dg-final { scan-tree-dump-not "vector operands from scalars" "slp2" { target { { vect_int && vect_bool_cmp } && { vect_unpack && vect_hw_misalign } } xfail vect_variable_length } } } */
+/* { dg-final { scan-tree-dump-not "vector operands from scalars" "slp2" { target { { vect_int && vect_bool_cmp } && { vect_unpack && vect_hw_misalign } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr68892.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr68892.c
index 8cd3a6a..e9909cf 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr68892.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr68892.c
@@ -15,6 +15,6 @@ void foo(void)
/* ??? Due to the gaps we fall back to scalar loads which makes the
vectorization profitable. */
-/* { dg-final { scan-tree-dump "not profitable" "slp2" { xfail *-*-* } } } */
-/* { dg-final { scan-tree-dump-times "BB vectorization with gaps at the end of a load is not supported" 1 "slp2" } } */
-/* { dg-final { scan-tree-dump-times "Basic block will be vectorized" 1 "slp2" } } */
+/* { dg-final { scan-tree-dump "not profitable" "slp2" { xfail { ! aarch64*-*-* } } } } */
+/* { dg-final { scan-tree-dump "BB vectorization with gaps at the end of a load is not supported" "slp2" } } */
+/* { dg-final { scan-tree-dump-times "Basic block will be vectorized" 1 "slp2" { xfail aarch64*-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-3.c b/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-3.c
index fe36f90..e27f956 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-3.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-3.c
@@ -38,4 +38,7 @@ main (int argc, char **argv)
}
/* { dg-final { scan-tree-dump-times "Basic block will be vectorized using SLP" 1 "slp2" } } */
-/* { dg-final { scan-tree-dump-times "optimized: basic block" 2 "slp2" } } */
+/* Because we disable the cost model, targets with variable-length
+ vectors can end up vectorizing the store to a[0..7] on its own.
+ With the cost model we do something sensible. */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 2 "slp2" { xfail vect_variable_length } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-vect-call-1.c b/gcc/testsuite/gcc.dg/vect/fast-math-vect-call-1.c
index 877de4e..495c031 100644
--- a/gcc/testsuite/gcc.dg/vect/fast-math-vect-call-1.c
+++ b/gcc/testsuite/gcc.dg/vect/fast-math-vect-call-1.c
@@ -97,4 +97,4 @@ main ()
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" { target { vect_call_copysignf && vect_call_sqrtf } } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" { target { vect_call_copysignf && vect_call_sqrtf } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" { target { { vect_call_copysignf && vect_call_sqrtf } && vect_perm3_int } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-1.c b/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-1.c
index 3bfe498..6834b9a 100644
--- a/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-1.c
+++ b/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-1.c
@@ -5,8 +5,8 @@ void
vadd (int *dst, int *op1, int *op2, int count)
{
/* { dg-prune-output " version\[^\n\r]* alignment" } */
-/* { dg-optimized "loop vectorized" "" { target *-*-* } .+2 } */
-/* { dg-optimized "loop versioned for vectorization because of possible aliasing" "" { target *-*-* } .+1 } */
+/* { dg-optimized "21: loop vectorized" "" { target *-*-* } .+2 } */
+/* { dg-optimized "21: loop versioned for vectorization because of possible aliasing" "" { target *-*-* } .+1 } */
for (int i = 0; i < count; ++i)
dst[i] = op1[i] + op2[i];
}
diff --git a/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-2.c b/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-2.c
index 94c55a9..23a3b39 100644
--- a/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-2.c
+++ b/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-2.c
@@ -6,7 +6,7 @@ extern void accumulate (int x, int *a);
int test_missing_function_defn (int *arr, int n) /* { dg-message "vectorized 0 loops in function" } */
{
int sum = 0;
- for (int i = 0; i < n; ++i) /* { dg-missed "couldn't vectorize loop" } */
- accumulate (arr[i], &sum); /* { dg-missed "statement clobbers memory: accumulate \\(.*\\);" } */
+ for (int i = 0; i < n; ++i) /* { dg-missed "21: couldn't vectorize loop" } */
+ accumulate (arr[i], &sum); /* { dg-missed "5: statement clobbers memory: accumulate \\(.*\\);" } */
return sum;
}
diff --git a/gcc/testsuite/gcc.dg/vect/pr65947-8.c b/gcc/testsuite/gcc.dg/vect/pr65947-8.c
index a2a940d..d042679 100644
--- a/gcc/testsuite/gcc.dg/vect/pr65947-8.c
+++ b/gcc/testsuite/gcc.dg/vect/pr65947-8.c
@@ -41,6 +41,6 @@ main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-not "LOOP VECTORIZED" "vect" { target { ! amdgcn*-*-* } } } } */
-/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target amdgcn*-*-* } } } */
-/* { dg-final { scan-tree-dump "multiple types in double reduction or condition reduction" "vect" { target { ! amdgcn*-*-* } } } } */
+/* { dg-final { scan-tree-dump-not "LOOP VECTORIZED" "vect" { target { ! { amdgcn*-*-* || aarch64_sve } } } } } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { amdgcn*-*-* || aarch64_sve } } } } */
+/* { dg-final { scan-tree-dump "multiple types in double reduction or condition reduction" "vect" { target { ! { amdgcn*-*-* || aarch64_sve } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr91750.c b/gcc/testsuite/gcc.dg/vect/pr91750.c
index fe914b2..3586f11 100644
--- a/gcc/testsuite/gcc.dg/vect/pr91750.c
+++ b/gcc/testsuite/gcc.dg/vect/pr91750.c
@@ -11,5 +11,5 @@ foo (int n)
}
/* Make sure the induction IV uses an unsigned increment. */
-/* { dg-final { scan-tree-dump "vector\\\(\[0-9\]*\\\) unsigned int" "vect" } } */
+/* { dg-final { scan-tree-dump {vector\([][0-9,]*\) unsigned int} "vect" } } */
/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr97678.c b/gcc/testsuite/gcc.dg/vect/pr97678.c
index ebe4a35..d9ffb7a 100644
--- a/gcc/testsuite/gcc.dg/vect/pr97678.c
+++ b/gcc/testsuite/gcc.dg/vect/pr97678.c
@@ -26,4 +26,5 @@ main ()
}
/* The init loop should be vectorized with SLP. */
-/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */
+/* We don't yet support SLP inductions for variable length vectors. */
+/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" { xfail vect_variable_length } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr97693.c b/gcc/testsuite/gcc.dg/vect/pr97693.c
new file mode 100644
index 0000000..4da44c7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr97693.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+extern short a[];
+int b;
+short c, d;
+unsigned e() {
+ if (c)
+ return c;
+ return d;
+}
+void f() {
+ for (unsigned g = b; g; g += 6)
+ for (_Bool h = 0; h < (_Bool)e(); h = 1)
+ a[g] = 1 / b;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr97730.c b/gcc/testsuite/gcc.dg/vect/pr97730.c
new file mode 100644
index 0000000..af4bca4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr97730.c
@@ -0,0 +1,12 @@
+/* { dg-additional-options "-O1" } */
+unsigned b = 0xce8e5a48, c = 0xb849691a;
+unsigned a[8080];
+int main() {
+ a[0] = b;
+ c = c;
+ unsigned f = 0xb1e8;
+ for (int h = 0; h < 5; h++)
+ a[h] = (b & c) ^ f;
+ if (a[0] != 0x8808f9e0)
+ __builtin_abort();
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr97835.c b/gcc/testsuite/gcc.dg/vect/pr97835.c
new file mode 100644
index 0000000..a90c773
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr97835.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+
+struct co {
+ int gx;
+ int ty;
+};
+
+void
+x0 (struct co *yy, long int kc, int wi, int md)
+{
+ while (wi < 1)
+ {
+ yy[wi].gx = md;
+ yy[wi].ty = wi;
+ md += kc;
+ ++wi;
+ }
+}
+
+/* We don't yet support SLP inductions for variable length vectors. */
+/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" { xfail vect_variable_length } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr97838.c b/gcc/testsuite/gcc.dg/vect/pr97838.c
new file mode 100644
index 0000000..06ec035
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr97838.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+
+int a, b, c, d;
+
+void f() {
+ while (c++) {
+ int e = -1;
+ d = a ? e / a : e;
+ b ^= ~d;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr98048.c b/gcc/testsuite/gcc.dg/vect/pr98048.c
new file mode 100644
index 0000000..e61a376
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr98048.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+extern short var_0;
+extern int var_3;
+extern int arr_277[];
+int a(int b, int c) { return b < c ? b : c; }
+int e;
+void test()
+{
+ e = var_0;
+ for (int d = 0; d < 9; d++)
+ if (var_3)
+ arr_277[d] = a(var_0, -var_0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/slp-21.c b/gcc/testsuite/gcc.dg/vect/slp-21.c
index 1f8c82e..117d65c 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-21.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-21.c
@@ -201,6 +201,16 @@ int main (void)
/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" { target { vect_strided4 || vect_extract_even_odd } } } } */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! { vect_strided4 || vect_extract_even_odd } } } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target vect_strided4 } } } */
+/* Some targets can vectorize the second of the three main loops using
+ hybrid SLP. For 128-bit vectors, the required 4->3 permutations are:
+
+ { 0, 1, 2, 4, 5, 6, 8, 9 }
+ { 2, 4, 5, 6, 8, 9, 10, 12 }
+ { 5, 6, 8, 9, 10, 12, 13, 14 }
+
+ Not all vect_perm targets support that, and it's a bit too specific to have
+ its own effective-target selector, so we just test targets directly. */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target { aarch64*-*-* arm*-*-* } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_strided4 && { ! { aarch64*-*-* arm*-*-* } } } } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target { ! { vect_strided4 } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-46.c b/gcc/testsuite/gcc.dg/vect/slp-46.c
index 58a238a..18476a4 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-46.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-46.c
@@ -94,4 +94,4 @@ main ()
return 0;
}
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { xfail vect_load_lanes } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-49.c b/gcc/testsuite/gcc.dg/vect/slp-49.c
index 3f53baf..4141a09 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-49.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-49.c
@@ -34,5 +34,6 @@ main()
return 0;
}
-/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */
+/* We don't yet support SLP inductions for variable length vectors. */
+/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" { xfail vect_variable_length } } } */
/* { dg-final { scan-tree-dump "Loop contains only SLP stmts" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-1.c b/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
index 4128cca..ca7803e 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
@@ -80,9 +80,7 @@ int main (int argc, const char* argv[])
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_perm } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && {! vect_partial_vectors_usage_1 } } } } } } */
-/* The epilogues are vectorized using partial vectors. */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && vect_partial_vectors_usage_1 } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_int && {! vect_load_lanes } } } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */
/* { dg-final { scan-tree-dump "Built SLP cancelled: can use load/store-lanes" "vect" { target { vect_perm3_int && vect_load_lanes } } } } */
/* { dg-final { scan-tree-dump "LOAD_LANES" "vect" { target vect_load_lanes } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-5.c b/gcc/testsuite/gcc.dg/vect/slp-perm-5.c
index b137821..b86a3dc 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-5.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-5.c
@@ -104,9 +104,7 @@ int main (int argc, const char* argv[])
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_perm } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && {! vect_partial_vectors_usage_1 } } } } } } */
-/* The epilogues are vectorized using partial vectors. */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && vect_partial_vectors_usage_1 } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_int && { ! vect_load_lanes } } } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */
/* { dg-final { scan-tree-dump "Built SLP cancelled: can use load/store-lanes" "vect" { target { vect_perm3_int && vect_load_lanes } } } } */
/* { dg-final { scan-tree-dump "LOAD_LANES" "vect" { target vect_load_lanes } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-6.c b/gcc/testsuite/gcc.dg/vect/slp-perm-6.c
index cc863de..bec1544 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-6.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-6.c
@@ -103,10 +103,7 @@ int main (int argc, const char* argv[])
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_perm } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && {! vect_partial_vectors_usage_1 } } } } } } */
-/* The epilogues are vectorized using partial vectors. */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && vect_partial_vectors_usage_1 } } } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target vect_load_lanes } } } */
-/* { dg-final { scan-tree-dump "Built SLP cancelled: can use load/store-lanes" "vect" { target { vect_perm3_int && vect_load_lanes } xfail { vect_perm3_int && vect_load_lanes } } } } */
-/* { dg-final { scan-tree-dump "LOAD_LANES" "vect" { target { vect_load_lanes } xfail { vect_load_lanes } } } } */
-/* { dg-final { scan-tree-dump "STORE_LANES" "vect" { target { vect_load_lanes } xfail { vect_load_lanes } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target vect_perm3_int } } } */
+/* { dg-final { scan-tree-dump "Built SLP cancelled: can use load/store-lanes" "vect" { target { vect_perm3_int && vect_load_lanes } xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump "LOAD_LANES" "vect" { target vect_load_lanes xfail vect_perm3_int } } } */
+/* { dg-final { scan-tree-dump "STORE_LANES" "vect" { target vect_load_lanes xfail vect_perm3_int } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-7.c b/gcc/testsuite/gcc.dg/vect/slp-perm-7.c
index 498999a..346411f 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-7.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-7.c
@@ -96,9 +96,7 @@ int main (int argc, const char* argv[])
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_perm } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && {! vect_partial_vectors_usage_1 } } } } } } */
-/* The epilogues are vectorized using partial vectors. */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && vect_partial_vectors_usage_1 } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_int && { ! vect_load_lanes } } } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */
/* { dg-final { scan-tree-dump "Built SLP cancelled: can use load/store-lanes" "vect" { target { vect_perm3_int && vect_load_lanes } } } } */
/* { dg-final { scan-tree-dump "LOAD_LANES" "vect" { target vect_load_lanes } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-4.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-4.c
index 266b439..cffb011 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-reduc-4.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-4.c
@@ -57,6 +57,8 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_int_min_max } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail { vect_no_int_min_max || vect_variable_length } } } } */
-/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" } } */
+/* For variable-length SVE, the number of scalar statements in the
+ reduction exceeds the number of elements in a 128-bit granule. */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail { vect_no_int_min_max || { aarch64_sve && vect_variable_length } } } } } */
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" { xfail { aarch64_sve && vect_variable_length } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-7.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-7.c
index 05cc9ed..7a958f2 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-reduc-7.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-7.c
@@ -55,5 +55,7 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_int_add } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail { vect_no_int_add || vect_variable_length } } } } */
-/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" } } */
+/* For variable-length SVE, the number of scalar statements in the
+ reduction exceeds the number of elements in a 128-bit granule. */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail { vect_no_int_add || { aarch64_sve && vect_variable_length } } } } } */
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" { xfail { aarch64_sve && vect_variable_length } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-35-big-array.c b/gcc/testsuite/gcc.dg/vect/vect-35-big-array.c
index ca57a10..28a99c9 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-35-big-array.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-35-big-array.c
@@ -20,10 +20,6 @@ int main1 ()
s.b[i] = i;
}
- /* Dependence analysis fails cause s.a and s.b may overlap.
- Try to use runtime aliasing test with versioning, and
- later versioning/vectorization are skipped because the
- overlap is proven at compilation time. */
for (i = 0; i < N; i++)
{
s.a[i] = s.b[i] + 1;
@@ -47,5 +43,4 @@ int main (void)
}
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { ia64-*-* sparc*-*-* } } } } */
-/* { dg-final { scan-tree-dump "can't determine dependence between" "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail { ia64-*-* sparc*-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-35.c b/gcc/testsuite/gcc.dg/vect/vect-35.c
index 76fe32d..a7ec0f16 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-35.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-35.c
@@ -20,10 +20,6 @@ int main1 ()
s.b[i] = i;
}
- /* Dependence analysis fails cause s.a and s.b may overlap.
- Try to use runtime aliasing test with versioning, and
- later versioning/vectorization are skipped because the
- overlap is proven at compilation time. */
for (i = 0; i < N; i++)
{
s.a[i] = s.b[i] + 1;
@@ -47,5 +43,4 @@ int main (void)
}
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { ia64-*-* sparc*-*-* } } } } */
-/* { dg-final { scan-tree-dump "can't determine dependence between" "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail { ia64-*-* sparc*-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-cost-model-1.c b/gcc/testsuite/gcc.dg/vect/vect-cost-model-1.c
new file mode 100644
index 0000000..0737da5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-cost-model-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -ftree-vectorize -fvect-cost-model=cheap" } */
+
+void
+f (int *x, int *y)
+{
+ for (unsigned int i = 0; i < 1024; ++i)
+ x[i] += y[i];
+}
+
+/* { dg-final { scan-tree-dump {LOOP VECTORIZED} vect { target vect_int } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-cost-model-2.c b/gcc/testsuite/gcc.dg/vect/vect-cost-model-2.c
new file mode 100644
index 0000000..fa9bdb6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-cost-model-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -ftree-vectorize -fvect-cost-model=very-cheap" } */
+
+void
+f (int *x, int *y)
+{
+ for (unsigned int i = 0; i < 1024; ++i)
+ x[i] += y[i];
+}
+
+/* { dg-final { scan-tree-dump-not {LOOP VECTORIZED} vect { target vect_int } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-cost-model-3.c b/gcc/testsuite/gcc.dg/vect/vect-cost-model-3.c
new file mode 100644
index 0000000..d7c6cfd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-cost-model-3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -ftree-vectorize -fvect-cost-model=cheap" } */
+
+void
+f (int *restrict x, int *restrict y)
+{
+ for (unsigned int i = 0; i < 1024; ++i)
+ x[i] += y[i];
+}
+
+/* { dg-final { scan-tree-dump {LOOP VECTORIZED} vect { target vect_int } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-cost-model-4.c b/gcc/testsuite/gcc.dg/vect/vect-cost-model-4.c
new file mode 100644
index 0000000..bb018ad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-cost-model-4.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -ftree-vectorize -fvect-cost-model=very-cheap" } */
+
+int x[1024], y[1024];
+
+void
+f (void)
+{
+ for (unsigned int i = 0; i < 1024; ++i)
+ x[i] += y[i];
+}
+
+/* { dg-final { scan-tree-dump {LOOP VECTORIZED} vect { target vect_int } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-cost-model-5.c b/gcc/testsuite/gcc.dg/vect/vect-cost-model-5.c
new file mode 100644
index 0000000..536ec0a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-cost-model-5.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -ftree-vectorize -fvect-cost-model=cheap" } */
+
+void
+f (int *restrict x, int *restrict y)
+{
+ for (unsigned int i = 0; i < 1023; ++i)
+ x[i] += y[i];
+}
+
+/* { dg-final { scan-tree-dump {LOOP VECTORIZED} vect { target vect_int } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-cost-model-6.c b/gcc/testsuite/gcc.dg/vect/vect-cost-model-6.c
new file mode 100644
index 0000000..552febb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-cost-model-6.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -ftree-vectorize -fvect-cost-model=very-cheap" } */
+
+void
+f (int *restrict x, int *restrict y)
+{
+ for (unsigned int i = 0; i < 1023; ++i)
+ x[i] += y[i];
+}
+
+/* { dg-final { scan-tree-dump {LOOP VECTORIZED} vect { target { vect_int && vect_partial_vectors_usage_2 } } } } */
+/* { dg-final { scan-tree-dump-not {LOOP VECTORIZED} vect { target { vect_int && { ! vect_partial_vectors_usage_2 } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-epilogues.c b/gcc/testsuite/gcc.dg/vect/vect-epilogues.c
index a146bb6..ab7e8a1 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-epilogues.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-epilogues.c
@@ -16,4 +16,4 @@ void pixel_avg( unsigned char *dst, int i_dst_stride,
}
}
-/* { dg-final { scan-tree-dump "LOOP EPILOGUE VECTORIZED" "vect" { target vect_multiple_sizes xfail { arm32 && be } } } } */
+/* { dg-final { scan-tree-dump "LOOP EPILOGUE VECTORIZED" "vect" { target vect_multiple_sizes xfail { { arm32 && be } || vect_partial_vectors_usage_2 } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-slp-1.c b/gcc/testsuite/gcc.dg/vect/vect-outer-slp-1.c
index 62b18bd..445157d 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-outer-slp-1.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-outer-slp-1.c
@@ -27,5 +27,6 @@ void foo (void)
/* We should vectorize this outer loop with SLP. */
/* { dg-final { scan-tree-dump "OUTER LOOP VECTORIZED" "vect" } } */
-/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */
+/* We don't yet support SLP inductions for variable length vectors. */
+/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" { xfail vect_variable_length } } } */
/* { dg-final { scan-tree-dump-not "VEC_PERM_EXPR" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-slp-2.c b/gcc/testsuite/gcc.dg/vect/vect-outer-slp-2.c
index 08b4fc5..ec1e103 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-outer-slp-2.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-outer-slp-2.c
@@ -48,4 +48,5 @@ int main ()
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */
+/* We don't yet support SLP inductions for variable length vectors. */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail vect_variable_length } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-slp-3.c b/gcc/testsuite/gcc.dg/vect/vect-outer-slp-3.c
index c67d369..53865d4 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-outer-slp-3.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-outer-slp-3.c
@@ -59,4 +59,5 @@ int main ()
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */
+/* We don't yet support SLP inductions for variable length vectors. */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail vect_variable_length } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-sdiv-pow2-1.c b/gcc/testsuite/gcc.dg/vect/vect-sdiv-pow2-1.c
index be70bc6..484efb1 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-sdiv-pow2-1.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-sdiv-pow2-1.c
@@ -62,7 +62,10 @@ main (void)
{
int p = power2 (fns[i].po2);
for (int j = 0; j < N; j++)
- a[j] = ((p << 4) * j) / (N - 1) - (p << 5);
+ {
+ a[j] = ((p << 4) * j) / (N - 1) - (p << 5);
+ asm volatile ("" ::: "memory");
+ }
fns[i].div (b, a, N);
fns[i].mod (c, a, N);
diff --git a/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c b/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c
index 02f6f3d..2afd2b5 100644
--- a/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c
+++ b/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c
@@ -143,11 +143,11 @@ T (v0 ? b[1] : "", bsz);
T (v0 ? b[2] : "", bsz);
T (v0 ? b[3] : "", bsz);
-T (v0 ? "" : b[0], bsz + 1);
+T (v0 ? "" : b[0], bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" } */
T (v0 ? "" : b[1], bsz + 1);
T (v0 ? "" : b[2], bsz + 1);
T (v0 ? "" : b[3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
-T (v0 ? b[0] : "", bsz + 1);
+T (v0 ? b[0] : "", bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" } */
T (v0 ? b[1] : "", bsz + 1);
T (v0 ? b[2] : "", bsz + 1);
T (v0 ? b[3] : "", bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
@@ -185,8 +185,8 @@ T (v0 ? "1234" : b[i3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfa
T (v0 ? b[3] : "1234", bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
T (v0 ? b[i3] : "1234", bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
-T (v0 ? a : b[3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
-T (v0 ? b[0] : b[2], bsz + 1);
+T (v0 ? a : b[3], bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" "pr86937" { xfail *-*-*} } */
+T (v0 ? b[0] : b[2], bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" "pr86937" } */
T (v0 ? b[2] : b[3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
T (v0 ? b[3] : b[2], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/abitest-2.h b/gcc/testsuite/gcc.target/aarch64/aapcs64/abitest-2.h
index 5749219..b917938 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/abitest-2.h
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/abitest-2.h
@@ -66,7 +66,7 @@ MYFUNCTYPE myfunc () PCSATTR;
of bugs like a short vector being returned in X0 after copied from V0. */
#undef FUNC_VAL_CHECK
#define FUNC_VAL_CHECK(id, type, var, offset, layout) \
-__attribute__ ((noinline)) type FUNC_NAME (id) (int i, double d, type t) \
+__attribute__ ((noipa)) type FUNC_NAME (id) (int i, double d, type t) \
{ \
asm (""::"r" (i),"r" (d)); /* asm prevents function from getting \
optimized away. Using i and d prevents \
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/abitest.h b/gcc/testsuite/gcc.target/aarch64/aapcs64/abitest.h
index af70937..667f4d0f 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/abitest.h
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/abitest.h
@@ -73,7 +73,7 @@ MYFUNCTYPE myfunc(
/* Dummy function to help reset parameter passing registers, i.e. X0-X7
and V0-V7 (by being passed 0 in W0-W7 and 0.f in S0-S7). */
-__attribute__ ((noinline)) void
+__attribute__ ((noipa)) void
dummy_func (int w0, int w1, int w2, int w3, int w4, int w5, int w6, int w7,
float s0, float s1, float s2, float s3, float s4, float s5,
float s6, float s7)
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bf16_vstN_lane_2.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bf16_vstN_lane_2.c
index f70c34d..822968d 100644
--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bf16_vstN_lane_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bf16_vstN_lane_2.c
@@ -11,15 +11,13 @@ test_vst2_lane_bf16 (bfloat16_t *ptr, bfloat16x4x2_t b)
vst2_lane_bf16 (ptr, b, 2);
}
-/* { dg-final { scan-assembler-times "st2\\t{v2.h - v3.h}\\\[2\\\], \\\[x0\\\]" 1 } } */
-
void
test_vst2q_lane_bf16 (bfloat16_t *ptr, bfloat16x8x2_t b)
{
vst2q_lane_bf16 (ptr, b, 2);
}
-/* { dg-final { scan-assembler-times "st2\\t{v0.h - v1.h}\\\[2\\\], \\\[x0\\\]" 1 } } */
+/* { dg-final { scan-assembler-times "st2\\t{v\[0-9\]+.h - v\[0-9\]+.h}\\\[2\\\], \\\[x\[0-9\]+\\\]" 2 } } */
void
test_vst3_lane_bf16 (bfloat16_t *ptr, bfloat16x4x3_t b)
@@ -33,7 +31,7 @@ test_vst3q_lane_bf16 (bfloat16_t *ptr, bfloat16x8x3_t b)
vst3q_lane_bf16 (ptr, b, 2);
}
-/* { dg-final { scan-assembler-times "st3\\t{v4.h - v6.h}\\\[2\\\], \\\[x0\\\]" 2 } } */
+/* { dg-final { scan-assembler-times "st3\\t{v\[0-9\]+.h - v\[0-9\]+.h}\\\[2\\\], \\\[x\[0-9\]+\\\]" 2 } } */
void
test_vst4_lane_bf16 (bfloat16_t *ptr, bfloat16x4x4_t b)
@@ -41,12 +39,10 @@ test_vst4_lane_bf16 (bfloat16_t *ptr, bfloat16x4x4_t b)
vst4_lane_bf16 (ptr, b, 2);
}
-/* { dg-final { scan-assembler-times "st4\\t{v4.h - v7.h}\\\[2\\\], \\\[x0\\\]" 1 } } */
-
void
test_vst4q_lane_bf16 (bfloat16_t *ptr, bfloat16x8x4_t b)
{
vst4q_lane_bf16 (ptr, b, 2);
}
-/* { dg-final { scan-assembler-times "st4\\t{v0.h - v3.h}\\\[2\\\], \\\[x0\\\]" 1 } } */
+/* { dg-final { scan-assembler-times "st4\\t{v\[0-9\]+.h - v\[0-9\]+.h}\\\[2\\\], \\\[x\[0-9\]+\\\]" 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/memset-corner-cases.c b/gcc/testsuite/gcc.target/aarch64/memset-corner-cases.c
new file mode 100644
index 0000000..c43f019
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/memset-corner-cases.c
@@ -0,0 +1,88 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target lp64 } */
+
+#include <stdint.h>
+
+/* One byte variable set should be scalar
+**set1byte:
+** strb w1, \[x0\]
+** ret
+*/
+void __attribute__((__noinline__))
+set1byte (int64_t *src, char c)
+{
+ __builtin_memset (src, c, 1);
+}
+
+/* Special cases for setting 0. */
+/* 1-byte should be STRB with wzr
+**set0byte:
+** strb wzr, \[x0\]
+** ret
+*/
+void __attribute__((__noinline__))
+set0byte (int64_t *src)
+{
+ __builtin_memset (src, 0, 1);
+}
+
+/* 35bytes would become 4 scalar instructions. So favour NEON.
+**set0neon:
+** movi v0.4s, 0
+** stp q0, q0, \[x0\]
+** str wzr, \[x0, 31\]
+** ret
+*/
+void __attribute__((__noinline__))
+set0neon (int64_t *src)
+{
+ __builtin_memset (src, 0, 35);
+}
+
+/* 36bytes should be scalar however.
+**set0scalar:
+** stp xzr, xzr, \[x0\]
+** stp xzr, xzr, \[x0, 16\]
+** str wzr, \[x0, 32\]
+** ret
+*/
+void __attribute__((__noinline__))
+set0scalar (int64_t *src)
+{
+ __builtin_memset (src, 0, 36);
+}
+
+
+/* 256-bytes expanded
+**set256byte:
+** dup v0.16b, w1
+** stp q0, q0, \[x0\]
+** stp q0, q0, \[x0, 32\]
+** stp q0, q0, \[x0, 64\]
+** stp q0, q0, \[x0, 96\]
+** stp q0, q0, \[x0, 128\]
+** stp q0, q0, \[x0, 160\]
+** stp q0, q0, \[x0, 192\]
+** stp q0, q0, \[x0, 224\]
+** ret
+*/
+void __attribute__((__noinline__))
+set256byte (int64_t *src, char c)
+{
+ __builtin_memset (src, c, 256);
+}
+
+/* More than 256 bytes goes to memset
+**set257byte:
+** mov x2, 257
+** mov w1, 99
+** b memset
+*/
+void __attribute__((__noinline__))
+set257byte (int64_t *src)
+{
+ __builtin_memset (src, 'c', 257);
+}
+
+/* { dg-final { check-function-bodies "**" "" "" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/memset-q-reg.c b/gcc/testsuite/gcc.target/aarch64/memset-q-reg.c
new file mode 100644
index 0000000..156146b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/memset-q-reg.c
@@ -0,0 +1,81 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target lp64 } */
+
+#include <stdint.h>
+
+/*
+**set128bits:
+** dup v0.16b, w1
+** str q0, \[x0\]
+** ret
+*/
+void __attribute__((__noinline__))
+set128bits (int64_t *src, char c)
+{
+ __builtin_memset (src, c, 2*sizeof(int64_t));
+}
+
+/*
+**set128bitszero:
+** stp xzr, xzr, \[x0\]
+** ret
+*/
+void __attribute__((__noinline__))
+set128bitszero (int64_t *src)
+{
+ __builtin_memset (src, 0, 2*sizeof(int64_t));
+}
+
+/*
+** set128bitsplus:
+** dup v0.16b, w1
+** str q0, \[x0\]
+** str q0, \[x0, 12\]
+** ret
+*/
+void __attribute__((__noinline__))
+set128bitsplus (int64_t *src, char c)
+{
+ __builtin_memset (src, c, 7*sizeof(int32_t));
+}
+
+/*
+** set256bits:
+** movi v0.16b, 0x63
+** stp q0, q0, \[x0\]
+** ret
+*/
+void __attribute__((__noinline__))
+set256bits (int64_t *src)
+{
+ __builtin_memset (src, 'c', 4*sizeof(int64_t));
+}
+
+/*
+**set256bitszero:
+** stp xzr, xzr, \[x0\]
+** stp xzr, xzr, \[x0, 16\]
+** ret
+*/
+void __attribute__((__noinline__))
+set256bitszero (int64_t *src)
+{
+ __builtin_memset (src, 0, 4*sizeof(int64_t));
+}
+
+/*
+** set256bitsplus:
+** movi v0.16b, 0x63
+** stp q0, q0, \[x0\]
+** str q0, \[x0, 32\]
+** str d0, \[x0, 48\]
+** ret
+*/
+void __attribute__((__noinline__))
+set256bitsplus (int64_t *src)
+{
+ __builtin_memset (src, 'c', 7*sizeof(int64_t));
+}
+
+/* { dg-final { check-function-bodies "**" "" "" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_f16.c
index 2aa8736..0960532 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_f16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (abs_f16_x_tied1, svfloat16_t,
/*
** abs_f16_x_untied:
+** movprfx z0, z1
** fabs z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_f32.c
index 30286af..797a418 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_f32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (abs_f32_x_tied1, svfloat32_t,
/*
** abs_f32_x_untied:
+** movprfx z0, z1
** fabs z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_f64.c
index 28ef9fb..4290ac3 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_f64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (abs_f64_x_tied1, svfloat64_t,
/*
** abs_f64_x_untied:
+** movprfx z0, z1
** fabs z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s16.c
index 3b16a9c..fcd5c34 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (abs_s16_x_tied1, svint16_t,
/*
** abs_s16_x_untied:
+** movprfx z0, z1
** abs z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s32.c
index 14bcbd5..58d183e 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (abs_s32_x_tied1, svint32_t,
/*
** abs_s32_x_untied:
+** movprfx z0, z1
** abs z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s64.c
index c7b60ff..2842048 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (abs_s64_x_tied1, svint64_t,
/*
** abs_s64_x_untied:
+** movprfx z0, z1
** abs z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s8.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s8.c
index 0bc64c0..ec0d89d 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s8.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abs_s8.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (abs_s8_x_tied1, svint8_t,
/*
** abs_s8_x_untied:
+** movprfx z0, z1
** abs z0\.b, p0/m, z1\.b
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s16.c
index 7af3123..5f82612 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s16.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (cls_s16_z, svuint16_t, svint16_t,
/*
** cls_s16_x:
+** movprfx z0, z4
** cls z0\.h, p0/m, z4\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s32.c
index 813876f..0db651f 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s32.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (cls_s32_z, svuint32_t, svint32_t,
/*
** cls_s32_x:
+** movprfx z0, z4
** cls z0\.s, p0/m, z4\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s64.c
index 660a205..e809e2f 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s64.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (cls_s64_z, svuint64_t, svint64_t,
/*
** cls_s64_x:
+** movprfx z0, z4
** cls z0\.d, p0/m, z4\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s8.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s8.c
index 56f5c26..f296c9f 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s8.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cls_s8.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (cls_s8_z, svuint8_t, svint8_t,
/*
** cls_s8_x:
+** movprfx z0, z4
** cls z0\.b, p0/m, z4\.b
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s16.c
index 58f8900..dc2c4e9 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s16.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (clz_s16_z, svuint16_t, svint16_t,
/*
** clz_s16_x:
+** movprfx z0, z4
** clz z0\.h, p0/m, z4\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s32.c
index a919807..17f54bc 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s32.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (clz_s32_z, svuint32_t, svint32_t,
/*
** clz_s32_x:
+** movprfx z0, z4
** clz z0\.s, p0/m, z4\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s64.c
index 02c0c99..a42b730 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s64.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (clz_s64_z, svuint64_t, svint64_t,
/*
** clz_s64_x:
+** movprfx z0, z4
** clz z0\.d, p0/m, z4\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s8.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s8.c
index 642d298..66c2359 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s8.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_s8.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (clz_s8_z, svuint8_t, svint8_t,
/*
** clz_s8_x:
+** movprfx z0, z4
** clz z0\.b, p0/m, z4\.b
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u16.c
index f087230..ab31f56 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (clz_u16_x_tied1, svuint16_t,
/*
** clz_u16_x_untied:
+** movprfx z0, z1
** clz z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u32.c
index e004241..2a74404 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (clz_u32_x_tied1, svuint32_t,
/*
** clz_u32_x_untied:
+** movprfx z0, z1
** clz z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u64.c
index e879e1b..8ff73c4 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (clz_u64_x_tied1, svuint64_t,
/*
** clz_u64_x_untied:
+** movprfx z0, z1
** clz z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u8.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u8.c
index ce6cb8f..89d8c540 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u8.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/clz_u8.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (clz_u8_x_tied1, svuint8_t,
/*
** clz_u8_x_untied:
+** movprfx z0, z1
** clz z0\.b, p0/m, z1\.b
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s16.c
index 19d46be..8f047fb 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (cnot_s16_x_tied1, svint16_t,
/*
** cnot_s16_x_untied:
+** movprfx z0, z1
** cnot z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s32.c
index 041b59a..f5b3395 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (cnot_s32_x_tied1, svint32_t,
/*
** cnot_s32_x_untied:
+** movprfx z0, z1
** cnot z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s64.c
index c7135cb..64121e3f 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (cnot_s64_x_tied1, svint64_t,
/*
** cnot_s64_x_untied:
+** movprfx z0, z1
** cnot z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s8.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s8.c
index 0560f97..e5dab42 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s8.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_s8.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (cnot_s8_x_tied1, svint8_t,
/*
** cnot_s8_x_untied:
+** movprfx z0, z1
** cnot z0\.b, p0/m, z1\.b
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u16.c
index 7ea9ff71..74c72c9 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (cnot_u16_x_tied1, svuint16_t,
/*
** cnot_u16_x_untied:
+** movprfx z0, z1
** cnot z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u32.c
index 972c775..b0f7531e 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (cnot_u32_x_tied1, svuint32_t,
/*
** cnot_u32_x_untied:
+** movprfx z0, z1
** cnot z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u64.c
index f25e001..9aa698d 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (cnot_u64_x_tied1, svuint64_t,
/*
** cnot_u64_x_untied:
+** movprfx z0, z1
** cnot z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u8.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u8.c
index e135a72..67c46a2 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u8.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnot_u8.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (cnot_u8_x_tied1, svuint8_t,
/*
** cnot_u8_x_untied:
+** movprfx z0, z1
** cnot z0\.b, p0/m, z1\.b
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_bf16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_bf16.c
index d92fbc1..bebf361 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_bf16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_bf16.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (cnt_bf16_z, svuint16_t, svbfloat16_t,
/*
** cnt_bf16_x:
+** movprfx z0, z4
** cnt z0\.h, p0/m, z4\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_f16.c
index b8061bb..20c95d6 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_f16.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (cnt_f16_z, svuint16_t, svfloat16_t,
/*
** cnt_f16_x:
+** movprfx z0, z4
** cnt z0\.h, p0/m, z4\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_f32.c
index b9292c9..8afeb49 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_f32.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (cnt_f32_z, svuint32_t, svfloat32_t,
/*
** cnt_f32_x:
+** movprfx z0, z4
** cnt z0\.s, p0/m, z4\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_f64.c
index 4976ee4..b7683a9 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_f64.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (cnt_f64_z, svuint64_t, svfloat64_t,
/*
** cnt_f64_x:
+** movprfx z0, z4
** cnt z0\.d, p0/m, z4\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s16.c
index a8ff8f3..824c42a 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s16.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (cnt_s16_z, svuint16_t, svint16_t,
/*
** cnt_s16_x:
+** movprfx z0, z4
** cnt z0\.h, p0/m, z4\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s32.c
index 3d16041..d6653d5 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s32.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (cnt_s32_z, svuint32_t, svint32_t,
/*
** cnt_s32_x:
+** movprfx z0, z4
** cnt z0\.s, p0/m, z4\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s64.c
index 8c8871b..c28db82 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s64.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (cnt_s64_z, svuint64_t, svint64_t,
/*
** cnt_s64_x:
+** movprfx z0, z4
** cnt z0\.d, p0/m, z4\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s8.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s8.c
index 8d85c8e..e741b4c 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s8.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_s8.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (cnt_s8_z, svuint8_t, svint8_t,
/*
** cnt_s8_x:
+** movprfx z0, z4
** cnt z0\.b, p0/m, z4\.b
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u16.c
index f173d31..49236cd 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (cnt_u16_x_tied1, svuint16_t,
/*
** cnt_u16_x_untied:
+** movprfx z0, z1
** cnt z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u32.c
index 11969a6..d302e32 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (cnt_u32_x_tied1, svuint32_t,
/*
** cnt_u32_x_untied:
+** movprfx z0, z1
** cnt z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u64.c
index 4eb69ea..b6e26ba 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (cnt_u64_x_tied1, svuint64_t,
/*
** cnt_u64_x_untied:
+** movprfx z0, z1
** cnt z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u8.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u8.c
index 30e7983..464dc4e 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u8.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cnt_u8.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (cnt_u8_x_tied1, svuint8_t,
/*
** cnt_u8_x_untied:
+** movprfx z0, z1
** cnt z0\.b, p0/m, z1\.b
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_bf16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_bf16.c
index 52baa1f..d4f9150 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_bf16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_bf16.c
@@ -66,6 +66,7 @@ TEST_DUAL_Z_REV (cvt_bf16_f32_x_tied1, svbfloat16_t, svfloat32_t,
/*
** cvt_bf16_f32_x_untied:
+** movprfx z0, z4
** bfcvt z0\.h, p0/m, z4\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_f16.c
index 5dcd480..dbb042d 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_f16.c
@@ -421,6 +421,7 @@ TEST_DUAL_Z_REV (cvt_f16_f32_x_tied1, svfloat16_t, svfloat32_t,
/*
** cvt_f16_f32_x_untied:
+** movprfx z0, z4
** fcvt z0\.h, p0/m, z4\.s
** ret
*/
@@ -439,6 +440,7 @@ TEST_DUAL_Z_REV (cvt_f16_f64_x_tied1, svfloat16_t, svfloat64_t,
/*
** cvt_f16_f64_x_untied:
+** movprfx z0, z4
** fcvt z0\.h, p0/m, z4\.d
** ret
*/
@@ -457,6 +459,7 @@ TEST_DUAL_Z_REV (cvt_f16_s16_x_tied1, svfloat16_t, svint16_t,
/*
** cvt_f16_s16_x_untied:
+** movprfx z0, z4
** scvtf z0\.h, p0/m, z4\.h
** ret
*/
@@ -475,6 +478,7 @@ TEST_DUAL_Z_REV (cvt_f16_s32_x_tied1, svfloat16_t, svint32_t,
/*
** cvt_f16_s32_x_untied:
+** movprfx z0, z4
** scvtf z0\.h, p0/m, z4\.s
** ret
*/
@@ -493,6 +497,7 @@ TEST_DUAL_Z_REV (cvt_f16_s64_x_tied1, svfloat16_t, svint64_t,
/*
** cvt_f16_s64_x_untied:
+** movprfx z0, z4
** scvtf z0\.h, p0/m, z4\.d
** ret
*/
@@ -511,6 +516,7 @@ TEST_DUAL_Z_REV (cvt_f16_u16_x_tied1, svfloat16_t, svuint16_t,
/*
** cvt_f16_u16_x_untied:
+** movprfx z0, z4
** ucvtf z0\.h, p0/m, z4\.h
** ret
*/
@@ -529,6 +535,7 @@ TEST_DUAL_Z_REV (cvt_f16_u32_x_tied1, svfloat16_t, svuint32_t,
/*
** cvt_f16_u32_x_untied:
+** movprfx z0, z4
** ucvtf z0\.h, p0/m, z4\.s
** ret
*/
@@ -547,6 +554,7 @@ TEST_DUAL_Z_REV (cvt_f16_u64_x_tied1, svfloat16_t, svuint64_t,
/*
** cvt_f16_u64_x_untied:
+** movprfx z0, z4
** ucvtf z0\.h, p0/m, z4\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_f32.c
index c164699..f7bfe57 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_f32.c
@@ -319,6 +319,7 @@ TEST_DUAL_Z_REV (cvt_f32_f16_x_tied1, svfloat32_t, svfloat16_t,
/*
** cvt_f32_f16_x_untied:
+** movprfx z0, z4
** fcvt z0\.s, p0/m, z4\.h
** ret
*/
@@ -337,6 +338,7 @@ TEST_DUAL_Z_REV (cvt_f32_f64_x_tied1, svfloat32_t, svfloat64_t,
/*
** cvt_f32_f64_x_untied:
+** movprfx z0, z4
** fcvt z0\.s, p0/m, z4\.d
** ret
*/
@@ -355,6 +357,7 @@ TEST_DUAL_Z_REV (cvt_f32_s32_x_tied1, svfloat32_t, svint32_t,
/*
** cvt_f32_s32_x_untied:
+** movprfx z0, z4
** scvtf z0\.s, p0/m, z4\.s
** ret
*/
@@ -373,6 +376,7 @@ TEST_DUAL_Z_REV (cvt_f32_s64_x_tied1, svfloat32_t, svint64_t,
/*
** cvt_f32_s64_x_untied:
+** movprfx z0, z4
** scvtf z0\.s, p0/m, z4\.d
** ret
*/
@@ -391,6 +395,7 @@ TEST_DUAL_Z_REV (cvt_f32_u32_x_tied1, svfloat32_t, svuint32_t,
/*
** cvt_f32_u32_x_untied:
+** movprfx z0, z4
** ucvtf z0\.s, p0/m, z4\.s
** ret
*/
@@ -409,6 +414,7 @@ TEST_DUAL_Z_REV (cvt_f32_u64_x_tied1, svfloat32_t, svuint64_t,
/*
** cvt_f32_u64_x_untied:
+** movprfx z0, z4
** ucvtf z0\.s, p0/m, z4\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_f64.c
index 1d08e6e..bfa36ba 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_f64.c
@@ -319,6 +319,7 @@ TEST_DUAL_Z_REV (cvt_f64_f16_x_tied1, svfloat64_t, svfloat16_t,
/*
** cvt_f64_f16_x_untied:
+** movprfx z0, z4
** fcvt z0\.d, p0/m, z4\.h
** ret
*/
@@ -337,6 +338,7 @@ TEST_DUAL_Z_REV (cvt_f64_f32_x_tied1, svfloat64_t, svfloat32_t,
/*
** cvt_f64_f32_x_untied:
+** movprfx z0, z4
** fcvt z0\.d, p0/m, z4\.s
** ret
*/
@@ -355,6 +357,7 @@ TEST_DUAL_Z_REV (cvt_f64_s32_x_tied1, svfloat64_t, svint32_t,
/*
** cvt_f64_s32_x_untied:
+** movprfx z0, z4
** scvtf z0\.d, p0/m, z4\.s
** ret
*/
@@ -373,6 +376,7 @@ TEST_DUAL_Z_REV (cvt_f64_s64_x_tied1, svfloat64_t, svint64_t,
/*
** cvt_f64_s64_x_untied:
+** movprfx z0, z4
** scvtf z0\.d, p0/m, z4\.d
** ret
*/
@@ -391,6 +395,7 @@ TEST_DUAL_Z_REV (cvt_f64_u32_x_tied1, svfloat64_t, svuint32_t,
/*
** cvt_f64_u32_x_untied:
+** movprfx z0, z4
** ucvtf z0\.d, p0/m, z4\.s
** ret
*/
@@ -409,6 +414,7 @@ TEST_DUAL_Z_REV (cvt_f64_u64_x_tied1, svfloat64_t, svuint64_t,
/*
** cvt_f64_u64_x_untied:
+** movprfx z0, z4
** ucvtf z0\.d, p0/m, z4\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_s16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_s16.c
index 81761ab..6b6883b 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_s16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_s16.c
@@ -64,6 +64,7 @@ TEST_DUAL_Z_REV (cvt_s16_f16_x_tied1, svint16_t, svfloat16_t,
/*
** cvt_s16_f16_x_untied:
+** movprfx z0, z4
** fcvtzs z0\.h, p0/m, z4\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_s32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_s32.c
index d30da5c..bf87356 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_s32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_s32.c
@@ -166,6 +166,7 @@ TEST_DUAL_Z_REV (cvt_s32_f16_x_tied1, svint32_t, svfloat16_t,
/*
** cvt_s32_f16_x_untied:
+** movprfx z0, z4
** fcvtzs z0\.s, p0/m, z4\.h
** ret
*/
@@ -184,6 +185,7 @@ TEST_DUAL_Z_REV (cvt_s32_f32_x_tied1, svint32_t, svfloat32_t,
/*
** cvt_s32_f32_x_untied:
+** movprfx z0, z4
** fcvtzs z0\.s, p0/m, z4\.s
** ret
*/
@@ -202,6 +204,7 @@ TEST_DUAL_Z_REV (cvt_s32_f64_x_tied1, svint32_t, svfloat64_t,
/*
** cvt_s32_f64_x_untied:
+** movprfx z0, z4
** fcvtzs z0\.s, p0/m, z4\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_s64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_s64.c
index 68cd807..9be3e05 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_s64.c
@@ -166,6 +166,7 @@ TEST_DUAL_Z_REV (cvt_s64_f16_x_tied1, svint64_t, svfloat16_t,
/*
** cvt_s64_f16_x_untied:
+** movprfx z0, z4
** fcvtzs z0\.d, p0/m, z4\.h
** ret
*/
@@ -184,6 +185,7 @@ TEST_DUAL_Z_REV (cvt_s64_f32_x_tied1, svint64_t, svfloat32_t,
/*
** cvt_s64_f32_x_untied:
+** movprfx z0, z4
** fcvtzs z0\.d, p0/m, z4\.s
** ret
*/
@@ -202,6 +204,7 @@ TEST_DUAL_Z_REV (cvt_s64_f64_x_tied1, svint64_t, svfloat64_t,
/*
** cvt_s64_f64_x_untied:
+** movprfx z0, z4
** fcvtzs z0\.d, p0/m, z4\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_u16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_u16.c
index 4db0dff..33a608b 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_u16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_u16.c
@@ -64,6 +64,7 @@ TEST_DUAL_Z_REV (cvt_u16_f16_x_tied1, svuint16_t, svfloat16_t,
/*
** cvt_u16_f16_x_untied:
+** movprfx z0, z4
** fcvtzu z0\.h, p0/m, z4\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_u32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_u32.c
index 52ef49f..4791d27 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_u32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_u32.c
@@ -166,6 +166,7 @@ TEST_DUAL_Z_REV (cvt_u32_f16_x_tied1, svuint32_t, svfloat16_t,
/*
** cvt_u32_f16_x_untied:
+** movprfx z0, z4
** fcvtzu z0\.s, p0/m, z4\.h
** ret
*/
@@ -184,6 +185,7 @@ TEST_DUAL_Z_REV (cvt_u32_f32_x_tied1, svuint32_t, svfloat32_t,
/*
** cvt_u32_f32_x_untied:
+** movprfx z0, z4
** fcvtzu z0\.s, p0/m, z4\.s
** ret
*/
@@ -202,6 +204,7 @@ TEST_DUAL_Z_REV (cvt_u32_f64_x_tied1, svuint32_t, svfloat64_t,
/*
** cvt_u32_f64_x_untied:
+** movprfx z0, z4
** fcvtzu z0\.s, p0/m, z4\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_u64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_u64.c
index 0c43758..e6c10c1 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_u64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/cvt_u64.c
@@ -166,6 +166,7 @@ TEST_DUAL_Z_REV (cvt_u64_f16_x_tied1, svuint64_t, svfloat16_t,
/*
** cvt_u64_f16_x_untied:
+** movprfx z0, z4
** fcvtzu z0\.d, p0/m, z4\.h
** ret
*/
@@ -184,6 +185,7 @@ TEST_DUAL_Z_REV (cvt_u64_f32_x_tied1, svuint64_t, svfloat32_t,
/*
** cvt_u64_f32_x_untied:
+** movprfx z0, z4
** fcvtzu z0\.d, p0/m, z4\.s
** ret
*/
@@ -202,6 +204,7 @@ TEST_DUAL_Z_REV (cvt_u64_f64_x_tied1, svuint64_t, svfloat64_t,
/*
** cvt_u64_f64_x_untied:
+** movprfx z0, z4
** fcvtzu z0\.d, p0/m, z4\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extb_s16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extb_s16.c
index 32e836f..76c7143 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extb_s16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extb_s16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (extb_s16_x_tied1, svint16_t,
/*
** extb_s16_x_untied:
+** movprfx z0, z1
** sxtb z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extb_s32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extb_s32.c
index e2f13f4..084c1c1 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extb_s32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extb_s32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (extb_s32_x_tied1, svint32_t,
/*
** extb_s32_x_untied:
+** movprfx z0, z1
** sxtb z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extb_s64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extb_s64.c
index 83363ef..8f3ee8d 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extb_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extb_s64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (extb_s64_x_tied1, svint64_t,
/*
** extb_s64_x_untied:
+** movprfx z0, z1
** sxtb z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/exth_s32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/exth_s32.c
index 3bb0bf31..d15cf7a 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/exth_s32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/exth_s32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (exth_s32_x_tied1, svint32_t,
/*
** exth_s32_x_untied:
+** movprfx z0, z1
** sxth z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/exth_s64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/exth_s64.c
index 0718b67..d8adf52 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/exth_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/exth_s64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (exth_s64_x_tied1, svint64_t,
/*
** exth_s64_x_untied:
+** movprfx z0, z1
** sxth z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extw_s64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extw_s64.c
index a6edadf..978a622 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extw_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/extw_s64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (extw_s64_x_tied1, svint64_t,
/*
** extw_s64_x_untied:
+** movprfx z0, z1
** sxtw z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_f16.c
index c31eba9..c43c6eb 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_f16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (neg_f16_x_tied1, svfloat16_t,
/*
** neg_f16_x_untied:
+** movprfx z0, z1
** fneg z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_f32.c
index a57d264..3e9fd5b 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_f32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (neg_f32_x_tied1, svfloat32_t,
/*
** neg_f32_x_untied:
+** movprfx z0, z1
** fneg z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_f64.c
index 90cadd4..880f5e8 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_f64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (neg_f64_x_tied1, svfloat64_t,
/*
** neg_f64_x_untied:
+** movprfx z0, z1
** fneg z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s16.c
index 80b2ee0..6a43bb2 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (neg_s16_x_tied1, svint16_t,
/*
** neg_s16_x_untied:
+** movprfx z0, z1
** neg z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s32.c
index b880503..ea92412 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (neg_s32_x_tied1, svint32_t,
/*
** neg_s32_x_untied:
+** movprfx z0, z1
** neg z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s64.c
index 82abe67..911d1f3 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (neg_s64_x_tied1, svint64_t,
/*
** neg_s64_x_untied:
+** movprfx z0, z1
** neg z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s8.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s8.c
index b7c9949..ace74b7 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s8.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/neg_s8.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (neg_s8_x_tied1, svint8_t,
/*
** neg_s8_x_untied:
+** movprfx z0, z1
** neg z0\.b, p0/m, z1\.b
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s16.c
index bacd6b1..9cafba9 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (not_s16_x_tied1, svint16_t,
/*
** not_s16_x_untied:
+** movprfx z0, z1
** not z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s32.c
index 8b15d6e..2185b78 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (not_s32_x_tied1, svint32_t,
/*
** not_s32_x_untied:
+** movprfx z0, z1
** not z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s64.c
index 8e7f7b9..09b3c25 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (not_s64_x_tied1, svint64_t,
/*
** not_s64_x_untied:
+** movprfx z0, z1
** not z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s8.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s8.c
index e807f08..029909e 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s8.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_s8.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (not_s8_x_tied1, svint8_t,
/*
** not_s8_x_untied:
+** movprfx z0, z1
** not z0\.b, p0/m, z1\.b
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u16.c
index c812005..fc33c99 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (not_u16_x_tied1, svuint16_t,
/*
** not_u16_x_untied:
+** movprfx z0, z1
** not z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u32.c
index 7b7e9ca..3f5e822 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (not_u32_x_tied1, svuint32_t,
/*
** not_u32_x_untied:
+** movprfx z0, z1
** not z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u64.c
index 27b92ad..01dde36e 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (not_u64_x_tied1, svuint64_t,
/*
** not_u64_x_untied:
+** movprfx z0, z1
** not z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u8.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u8.c
index bd2f36c..e8553e3 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u8.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/not_u8.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (not_u8_x_tied1, svuint8_t,
/*
** not_u8_x_untied:
+** movprfx z0, z1
** not z0\.b, p0/m, z1\.b
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s16.c
index 4f794f6..5889c92 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rbit_s16_x_tied1, svint16_t,
/*
** rbit_s16_x_untied:
+** movprfx z0, z1
** rbit z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s32.c
index 8b5e1a4..1414e3e 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rbit_s32_x_tied1, svint32_t,
/*
** rbit_s32_x_untied:
+** movprfx z0, z1
** rbit z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s64.c
index cec27a4..3b76f54 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rbit_s64_x_tied1, svint64_t,
/*
** rbit_s64_x_untied:
+** movprfx z0, z1
** rbit z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s8.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s8.c
index 9c15211..1fc80e3 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s8.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_s8.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rbit_s8_x_tied1, svint8_t,
/*
** rbit_s8_x_untied:
+** movprfx z0, z1
** rbit z0\.b, p0/m, z1\.b
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u16.c
index 001ef2b..6479337 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rbit_u16_x_tied1, svuint16_t,
/*
** rbit_u16_x_untied:
+** movprfx z0, z1
** rbit z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u32.c
index 4d91e95..3e95964 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rbit_u32_x_tied1, svuint32_t,
/*
** rbit_u32_x_untied:
+** movprfx z0, z1
** rbit z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u64.c
index 77f88d1..5163b82 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rbit_u64_x_tied1, svuint64_t,
/*
** rbit_u64_x_untied:
+** movprfx z0, z1
** rbit z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u8.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u8.c
index fa347e4..2372398 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u8.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rbit_u8.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rbit_u8_x_tied1, svuint8_t,
/*
** rbit_u8_x_untied:
+** movprfx z0, z1
** rbit z0\.b, p0/m, z1\.b
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/recpx_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/recpx_f16.c
index 2dd7ada..da63f26 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/recpx_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/recpx_f16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (recpx_f16_x_tied1, svfloat16_t,
/*
** recpx_f16_x_untied:
+** movprfx z0, z1
** frecpx z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/recpx_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/recpx_f32.c
index 6364fb8..ea8cb78 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/recpx_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/recpx_f32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (recpx_f32_x_tied1, svfloat32_t,
/*
** recpx_f32_x_untied:
+** movprfx z0, z1
** frecpx z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/recpx_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/recpx_f64.c
index ca52323..1eaca67 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/recpx_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/recpx_f64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (recpx_f64_x_tied1, svfloat64_t,
/*
** recpx_f64_x_untied:
+** movprfx z0, z1
** frecpx z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_s16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_s16.c
index ecfabe6..a99260f 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_s16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_s16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (revb_s16_x_tied1, svint16_t,
/*
** revb_s16_x_untied:
+** movprfx z0, z1
** revb z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_s32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_s32.c
index a46a819..adbf128 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_s32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_s32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (revb_s32_x_tied1, svint32_t,
/*
** revb_s32_x_untied:
+** movprfx z0, z1
** revb z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_s64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_s64.c
index 2154723..d21db75 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_s64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (revb_s64_x_tied1, svint64_t,
/*
** revb_s64_x_untied:
+** movprfx z0, z1
** revb z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_u16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_u16.c
index d58bd3d..d48704f 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_u16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_u16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (revb_u16_x_tied1, svuint16_t,
/*
** revb_u16_x_untied:
+** movprfx z0, z1
** revb z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_u32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_u32.c
index 33df990..cf9293b 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_u32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_u32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (revb_u32_x_tied1, svuint32_t,
/*
** revb_u32_x_untied:
+** movprfx z0, z1
** revb z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_u64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_u64.c
index 50ad618..54db72d 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_u64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revb_u64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (revb_u64_x_tied1, svuint64_t,
/*
** revb_u64_x_untied:
+** movprfx z0, z1
** revb z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_s32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_s32.c
index 07d512d..fb63c17 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_s32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_s32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (revh_s32_x_tied1, svint32_t,
/*
** revh_s32_x_untied:
+** movprfx z0, z1
** revh z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_s64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_s64.c
index b144634..967600a 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_s64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (revh_s64_x_tied1, svint64_t,
/*
** revh_s64_x_untied:
+** movprfx z0, z1
** revh z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_u32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_u32.c
index 9ea5188..265f865 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_u32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_u32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (revh_u32_x_tied1, svuint32_t,
/*
** revh_u32_x_untied:
+** movprfx z0, z1
** revh z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_u64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_u64.c
index 7b2da27..733b229 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_u64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revh_u64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (revh_u64_x_tied1, svuint64_t,
/*
** revh_u64_x_untied:
+** movprfx z0, z1
** revh z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revw_s64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revw_s64.c
index 26ca0f0..0894131 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revw_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revw_s64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (revw_s64_x_tied1, svint64_t,
/*
** revw_s64_x_untied:
+** movprfx z0, z1
** revw z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revw_u64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revw_u64.c
index c70cdb4..ebde929 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revw_u64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/revw_u64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (revw_u64_x_tied1, svuint64_t,
/*
** revw_u64_x_untied:
+** movprfx z0, z1
** revw z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinta_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinta_f16.c
index 99a6042..3e1a788 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinta_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinta_f16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rinta_f16_x_tied1, svfloat16_t,
/*
** rinta_f16_x_untied:
+** movprfx z0, z1
** frinta z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinta_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinta_f32.c
index b4e3714..ae6fe65 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinta_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinta_f32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rinta_f32_x_tied1, svfloat32_t,
/*
** rinta_f32_x_untied:
+** movprfx z0, z1
** frinta z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinta_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinta_f64.c
index 24d6b7d..2f7be6c 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinta_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinta_f64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rinta_f64_x_tied1, svfloat64_t,
/*
** rinta_f64_x_untied:
+** movprfx z0, z1
** frinta z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinti_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinti_f16.c
index 1f0ac85..ec3b908 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinti_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinti_f16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rinti_f16_x_tied1, svfloat16_t,
/*
** rinti_f16_x_untied:
+** movprfx z0, z1
** frinti z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinti_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinti_f32.c
index cf54fde..061f5c8 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinti_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinti_f32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rinti_f32_x_tied1, svfloat32_t,
/*
** rinti_f32_x_untied:
+** movprfx z0, z1
** frinti z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinti_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinti_f64.c
index 08b861c..eca3be0 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinti_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rinti_f64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rinti_f64_x_tied1, svfloat64_t,
/*
** rinti_f64_x_untied:
+** movprfx z0, z1
** frinti z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintm_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintm_f16.c
index 194d01c..35cb976 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintm_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintm_f16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rintm_f16_x_tied1, svfloat16_t,
/*
** rintm_f16_x_untied:
+** movprfx z0, z1
** frintm z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintm_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintm_f32.c
index 6c3297a..d65baf5 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintm_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintm_f32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rintm_f32_x_tied1, svfloat32_t,
/*
** rintm_f32_x_untied:
+** movprfx z0, z1
** frintm z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintm_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintm_f64.c
index ecbb244..d3824ec 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintm_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintm_f64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rintm_f64_x_tied1, svfloat64_t,
/*
** rintm_f64_x_untied:
+** movprfx z0, z1
** frintm z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintn_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintn_f16.c
index 273307e..cc2bf0e 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintn_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintn_f16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rintn_f16_x_tied1, svfloat16_t,
/*
** rintn_f16_x_untied:
+** movprfx z0, z1
** frintn z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintn_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintn_f32.c
index bafd431..aa0c65a 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintn_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintn_f32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rintn_f32_x_tied1, svfloat32_t,
/*
** rintn_f32_x_untied:
+** movprfx z0, z1
** frintn z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintn_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintn_f64.c
index 0142315..a9317ad 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintn_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintn_f64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rintn_f64_x_tied1, svfloat64_t,
/*
** rintn_f64_x_untied:
+** movprfx z0, z1
** frintn z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintp_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintp_f16.c
index 0e85c34..f511452 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintp_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintp_f16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rintp_f16_x_tied1, svfloat16_t,
/*
** rintp_f16_x_untied:
+** movprfx z0, z1
** frintp z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintp_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintp_f32.c
index cec360d..34596c4 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintp_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintp_f32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rintp_f32_x_tied1, svfloat32_t,
/*
** rintp_f32_x_untied:
+** movprfx z0, z1
** frintp z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintp_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintp_f64.c
index 1305fb6..a68a579 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintp_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintp_f64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rintp_f64_x_tied1, svfloat64_t,
/*
** rintp_f64_x_untied:
+** movprfx z0, z1
** frintp z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintx_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintx_f16.c
index 96f7f2c..a86e063 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintx_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintx_f16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rintx_f16_x_tied1, svfloat16_t,
/*
** rintx_f16_x_untied:
+** movprfx z0, z1
** frintx z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintx_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintx_f32.c
index 1c42d2a..9565150 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintx_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintx_f32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rintx_f32_x_tied1, svfloat32_t,
/*
** rintx_f32_x_untied:
+** movprfx z0, z1
** frintx z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintx_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintx_f64.c
index bee806b..a5c7a01 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintx_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintx_f64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rintx_f64_x_tied1, svfloat64_t,
/*
** rintx_f64_x_untied:
+** movprfx z0, z1
** frintx z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintz_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintz_f16.c
index be13d82..cb61080 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintz_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintz_f16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rintz_f16_x_tied1, svfloat16_t,
/*
** rintz_f16_x_untied:
+** movprfx z0, z1
** frintz z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintz_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintz_f32.c
index 873c0d4..a479909 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintz_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintz_f32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rintz_f32_x_tied1, svfloat32_t,
/*
** rintz_f32_x_untied:
+** movprfx z0, z1
** frintz z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintz_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintz_f64.c
index e6c9d1f..f80f907 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintz_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/rintz_f64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rintz_f64_x_tied1, svfloat64_t,
/*
** rintz_f64_x_untied:
+** movprfx z0, z1
** frintz z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sqrt_f16.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sqrt_f16.c
index 6dc5940..335fb86 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sqrt_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sqrt_f16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (sqrt_f16_x_tied1, svfloat16_t,
/*
** sqrt_f16_x_untied:
+** movprfx z0, z1
** fsqrt z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sqrt_f32.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sqrt_f32.c
index 71d1f8f..0887996 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sqrt_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sqrt_f32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (sqrt_f32_x_tied1, svfloat32_t,
/*
** sqrt_f32_x_untied:
+** movprfx z0, z1
** fsqrt z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sqrt_f64.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sqrt_f64.c
index 7771df5..7dbab87 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sqrt_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sqrt_f64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (sqrt_f64_x_tied1, svfloat64_t,
/*
** sqrt_f64_x_untied:
+** movprfx z0, z1
** fsqrt z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr98037.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr98037.c
new file mode 100644
index 0000000..b91e940
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr98037.c
@@ -0,0 +1,6 @@
+/* { dg-options "-msve-vector-bits=1024 -O3" } */
+
+typedef __SVInt8_t vec __attribute__((arm_sve_vector_bits(1024)));
+struct pair { vec v[2]; };
+void use (struct pair *);
+vec f (struct pair p) { vec v = p.v[1]; use (&p); return v; }
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/undef_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/undef_1.c
new file mode 100644
index 0000000..793593b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/undef_1.c
@@ -0,0 +1,12 @@
+/* { dg-options "-O2 -W -Wall -Werror" } */
+
+#include <arm_sve.h>
+
+svfloat32x2_t
+foo (svfloat32_t x, svfloat32_t y)
+{
+ svfloat32x2_t res = svundef2_f32 ();
+ res = svset2 (res, 0, x);
+ res = svset2 (res, 1, y);
+ return res;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cmp_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cmp_1.c
new file mode 100644
index 0000000..7cf66c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cmp_1.c
@@ -0,0 +1,57 @@
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define TEST_PAIR(TYPE1, TYPE2) \
+ void \
+ f_##TYPE1##_##TYPE2 (TYPE1 *restrict x, \
+ TYPE2 *restrict g, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ if (g[i] < 4) \
+ x[i] += 1; \
+ }
+
+#define TEST_SINGLE(TYPE) \
+ TEST_PAIR (TYPE, int8_t) \
+ TEST_PAIR (TYPE, uint8_t) \
+ TEST_PAIR (TYPE, int16_t) \
+ TEST_PAIR (TYPE, uint16_t) \
+ TEST_PAIR (TYPE, int32_t) \
+ TEST_PAIR (TYPE, uint32_t) \
+ TEST_PAIR (TYPE, int64_t) \
+ TEST_PAIR (TYPE, uint64_t)
+
+TEST_SINGLE (int8_t)
+TEST_SINGLE (uint8_t)
+TEST_SINGLE (int16_t)
+TEST_SINGLE (uint16_t)
+TEST_SINGLE (int32_t)
+TEST_SINGLE (uint32_t)
+TEST_SINGLE (int64_t)
+TEST_SINGLE (uint64_t)
+
+/* { dg-final { scan-assembler-times {\tld1b\tz[0-9]+\.b,} 8 } } */
+/* { dg-final { scan-assembler-times {\tld1b\tz[0-9]+\.h,} 8 } } */
+/* { dg-final { scan-assembler-times {\tld1b\tz[0-9]+\.s,} 8 } } */
+/* { dg-final { scan-assembler-times {\tld1b\tz[0-9]+\.d,} 8 } } */
+
+/* { dg-final { scan-assembler-times {\tld1h\tz[0-9]+\.h,} 16 } } */
+/* { dg-final { scan-assembler-times {\tld1h\tz[0-9]+\.s,} 8 } } */
+/* { dg-final { scan-assembler-times {\tld1h\tz[0-9]+\.d,} 8 } } */
+
+/* { dg-final { scan-assembler-times {\tld1w\tz[0-9]+\.s,} 24 } } */
+/* { dg-final { scan-assembler-times {\tld1w\tz[0-9]+\.d,} 8 } } */
+
+/* { dg-final { scan-assembler-times {\tld1d\tz[0-9]+\.d,} 32 } } */
+
+/* { dg-final { scan-assembler-times {\tcmpl[et]\tp[0-9]+\.b,} 8 } } */
+/* { dg-final { scan-assembler-times {\tcmpl[so]\tp[0-9]+\.b,} 8 } } */
+/* { dg-final { scan-assembler-times {\tcmpl[et]\tp[0-9]+\.h,} 8 } } */
+/* { dg-final { scan-assembler-times {\tcmpl[so]\tp[0-9]+\.h,} 8 } } */
+/* { dg-final { scan-assembler-times {\tcmpl[et]\tp[0-9]+\.s,} 8 } } */
+/* { dg-final { scan-assembler-times {\tcmpl[so]\tp[0-9]+\.s,} 8 } } */
+/* { dg-final { scan-assembler-times {\tcmpl[et]\tp[0-9]+\.d,} 8 } } */
+/* { dg-final { scan-assembler-times {\tcmpl[so]\tp[0-9]+\.d,} 8 } } */
+
+/* { dg-final { scan-assembler-not {\tpunpk} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cmp_2.c b/gcc/testsuite/gcc.target/aarch64/sve/cmp_2.c
new file mode 100644
index 0000000..b221206
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cmp_2.c
@@ -0,0 +1,72 @@
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define TEST_PAIR(TYPE1, TYPE2) \
+ void \
+ f_##TYPE1##_##TYPE2 (TYPE1 *restrict x, TYPE1 y, TYPE1 z, \
+ TYPE2 *restrict g, TYPE2 h, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = g[i] < h ? y : z; \
+ }
+
+#define TEST_SINGLE(TYPE) \
+ TEST_PAIR (TYPE, int8_t) \
+ TEST_PAIR (TYPE, uint8_t) \
+ TEST_PAIR (TYPE, int16_t) \
+ TEST_PAIR (TYPE, uint16_t) \
+ TEST_PAIR (TYPE, int32_t) \
+ TEST_PAIR (TYPE, uint32_t) \
+ TEST_PAIR (TYPE, int64_t) \
+ TEST_PAIR (TYPE, uint64_t)
+
+TEST_SINGLE (int8_t)
+TEST_SINGLE (uint8_t)
+TEST_SINGLE (int16_t)
+TEST_SINGLE (uint16_t)
+TEST_SINGLE (int32_t)
+TEST_SINGLE (uint32_t)
+TEST_SINGLE (float)
+TEST_SINGLE (int64_t)
+TEST_SINGLE (uint64_t)
+TEST_SINGLE (double)
+
+/* { dg-final { scan-assembler-times {\tld1b\tz[0-9]+\.b,} 4 } } */
+/* { dg-final { scan-assembler-times {\tld1b\tz[0-9]+\.h,} 4 } } */
+/* { dg-final { scan-assembler-times {\tld1b\tz[0-9]+\.s,} 6 } } */
+/* { dg-final { scan-assembler-times {\tld1b\tz[0-9]+\.d,} 6 } } */
+
+/* { dg-final { scan-assembler-times {\tld1h\tz[0-9]+\.h,} 8 } } */
+/* { dg-final { scan-assembler-times {\tld1h\tz[0-9]+\.s,} 6 } } */
+/* { dg-final { scan-assembler-times {\tld1h\tz[0-9]+\.d,} 6 } } */
+
+/* { dg-final { scan-assembler-times {\tld1w\tz[0-9]+\.s,} 14 } } */
+/* { dg-final { scan-assembler-times {\tld1w\tz[0-9]+\.d,} 6 } } */
+
+/* { dg-final { scan-assembler-times {\tld1d\tz[0-9]+\.d,} 20 } } */
+
+/* { dg-final { scan-assembler-times {\tst1b\tz[0-9]+\.b,} 4 } } */
+/* { dg-final { scan-assembler-times {\tst1b\tz[0-9]+\.h,} 4 } } */
+/* { dg-final { scan-assembler-times {\tst1b\tz[0-9]+\.s,} 4 } } */
+/* { dg-final { scan-assembler-times {\tst1b\tz[0-9]+\.d,} 4 } } */
+
+/* { dg-final { scan-assembler-times {\tst1h\tz[0-9]+\.h,} 8 } } */
+/* { dg-final { scan-assembler-times {\tst1h\tz[0-9]+\.s,} 4 } } */
+/* { dg-final { scan-assembler-times {\tst1h\tz[0-9]+\.d,} 4 } } */
+
+/* { dg-final { scan-assembler-times {\tst1w\tz[0-9]+\.s,} 18 } } */
+/* { dg-final { scan-assembler-times {\tst1w\tz[0-9]+\.d,} 6 } } */
+
+/* { dg-final { scan-assembler-times {\tst1d\tz[0-9]+\.d,} 24 } } */
+
+/* { dg-final { scan-assembler-times {\tcmp(?:h[is]|l[os])\tp[0-9]+\.b,} 10 } } */
+/* { dg-final { scan-assembler-times {\tcmp[lg][et]\tp[0-9]+\.b,} 10 } } */
+/* { dg-final { scan-assembler-times {\tcmp(?:h[is]|l[os])\tp[0-9]+\.h,} 10 } } */
+/* { dg-final { scan-assembler-times {\tcmp[lg][et]\tp[0-9]+\.h,} 10 } } */
+/* { dg-final { scan-assembler-times {\tcmp(?:h[is]|l[os])\tp[0-9]+\.s,} 10 } } */
+/* { dg-final { scan-assembler-times {\tcmp[lg][et]\tp[0-9]+\.s,} 10 } } */
+/* { dg-final { scan-assembler-times {\tcmp(?:h[is]|l[os])\tp[0-9]+\.d,} 10 } } */
+/* { dg-final { scan-assembler-times {\tcmp[lg][et]\tp[0-9]+\.d,} 10 } } */
+
+/* { dg-final { scan-assembler-not {\tpunpk} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_arith_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_arith_1.c
index 52138d2..d831e9c 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/cond_arith_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_arith_1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -ftree-vectorize" } */
+/* { dg-options "-O2 -ftree-vectorize --param aarch64-sve-compare-costs=0" } */
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_arith_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_arith_1_run.c
index 876f98f..5808e0a 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/cond_arith_1_run.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_arith_1_run.c
@@ -1,5 +1,5 @@
/* { dg-do run { target aarch64_sve_hw } } */
-/* { dg-options "-O2 -ftree-vectorize" } */
+/* { dg-options "-O2 -ftree-vectorize --param aarch64-sve-compare-costs=0" } */
#include "cond_arith_1.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_arith_3.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_arith_3.c
index 94eb255..068e0b6 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/cond_arith_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_arith_3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -ftree-vectorize" } */
+/* { dg-options "-O2 -ftree-vectorize --param aarch64-sve-compare-costs=0" } */
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_arith_3_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_arith_3_run.c
index 31457da..d258004 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/cond_arith_3_run.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_arith_3_run.c
@@ -1,5 +1,5 @@
/* { dg-do run { target aarch64_sve_hw } } */
-/* { dg-options "-O2 -ftree-vectorize" } */
+/* { dg-options "-O2 -ftree-vectorize --param aarch64-sve-compare-costs=0" } */
#include "cond_arith_3.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_1.c
index bd87766..49f0b18 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_1.c
@@ -31,5 +31,4 @@ TEST_ALL (DEF_LOOP)
/* { 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 *-*-* } } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_1.c
index 2b5f9c3..0492476 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_1.c
@@ -54,6 +54,4 @@ TEST_ALL (DEF_LOOP)
/* { 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 *-*-* } } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/mask_gather_load_7.c b/gcc/testsuite/gcc.target/aarch64/sve/mask_gather_load_7.c
index cd2661e..687716e 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/mask_gather_load_7.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/mask_gather_load_7.c
@@ -1,5 +1,5 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
-/* { dg-options "-O2 -ftree-vectorize -ffast-math --save-temps" } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math --save-temps --param aarch64-sve-compare-costs=0" } */
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/mask_load_slp_1.c b/gcc/testsuite/gcc.target/aarch64/sve/mask_load_slp_1.c
index 78c70b2..a38b92d 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/mask_load_slp_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/mask_load_slp_1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -ftree-vectorize" } */
+/* { dg-options "-O2 -ftree-vectorize --param aarch64-sve-compare-costs=0" } */
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vcond_11.c b/gcc/testsuite/gcc.target/aarch64/sve/vcond_11.c
index 3c9e340..4efcf3a 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/vcond_11.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vcond_11.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -ftree-vectorize -march=armv8-a+sve" } */
+/* { dg-options "-O2 -ftree-vectorize -march=armv8-a+sve --param aarch64-sve-compare-costs=0" } */
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vcond_11_run.c b/gcc/testsuite/gcc.target/aarch64/sve/vcond_11_run.c
index 9a4edb8..4cbe4a6 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/vcond_11_run.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vcond_11_run.c
@@ -1,5 +1,5 @@
/* { dg-do run { target aarch64_sve_hw } } */
-/* { dg-options "-O2 -ftree-vectorize -march=armv8-a+sve" } */
+/* { dg-options "-O2 -ftree-vectorize -march=armv8-a+sve --param aarch64-sve-compare-costs=0" } */
#include "vcond_11.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/cvtlt_f32.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/cvtlt_f32.c
index 911defa..f66fa90 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/cvtlt_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/cvtlt_f32.c
@@ -42,7 +42,13 @@ TEST_DUAL_Z_REV (cvtlt_f32_f16_x_tied1, svfloat32_t, svfloat16_t,
/*
** cvtlt_f32_f16_x_untied:
-** fcvtlt z0\.s, p0/m, z4\.h
+** (
+** mov z0\.d, z4\.d
+** fcvtlt z0\.s, p0/m, z0\.h
+** |
+** fcvtlt z4\.s, p0/m, z4\.h
+** mov z0\.d, z4\.d
+** )
** ret
*/
TEST_DUAL_Z (cvtlt_f32_f16_x_untied, svfloat32_t, svfloat16_t,
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/cvtlt_f64.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/cvtlt_f64.c
index c34947b..b262e25 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/cvtlt_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/cvtlt_f64.c
@@ -42,7 +42,13 @@ TEST_DUAL_Z_REV (cvtlt_f64_f32_x_tied1, svfloat64_t, svfloat32_t,
/*
** cvtlt_f64_f32_x_untied:
-** fcvtlt z0\.d, p0/m, z4\.s
+** (
+** mov z0\.d, z4\.d
+** fcvtlt z0\.d, p0/m, z0\.s
+** |
+** fcvtlt z4\.d, p0/m, z4\.s
+** mov z0\.d, z4\.d
+** )
** ret
*/
TEST_DUAL_Z (cvtlt_f64_f32_x_untied, svfloat64_t, svfloat32_t,
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/cvtx_f32.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/cvtx_f32.c
index 21724c8..85fbc79 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/cvtx_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/cvtx_f32.c
@@ -64,6 +64,7 @@ TEST_DUAL_Z_REV (cvtx_f32_f64_x_tied1, svfloat32_t, svfloat64_t,
/*
** cvtx_f32_f64_x_untied:
+** movprfx z0, z4
** fcvtx z0\.s, p0/m, z4\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/logb_f16.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/logb_f16.c
index bc68156..fe65e64 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/logb_f16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/logb_f16.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (logb_f16_z, svint16_t, svfloat16_t,
/*
** logb_f16_x:
+** movprfx z0, z4
** flogb z0\.h, p0/m, z4\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/logb_f32.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/logb_f32.c
index 35bdcd1..847e1b1 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/logb_f32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/logb_f32.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (logb_f32_z, svint32_t, svfloat32_t,
/*
** logb_f32_x:
+** movprfx z0, z4
** flogb z0\.s, p0/m, z4\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/logb_f64.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/logb_f64.c
index c7c2cb2..4113a37 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/logb_f64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/logb_f64.c
@@ -33,6 +33,7 @@ TEST_DUAL_Z (logb_f64_z, svint64_t, svfloat64_t,
/*
** logb_f64_x:
+** movprfx z0, z4
** flogb z0\.d, p0/m, z4\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s16.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s16.c
index 0756488..d7acf47 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (qabs_s16_x_tied1, svint16_t,
/*
** qabs_s16_x_untied:
+** movprfx z0, z1
** sqabs z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s32.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s32.c
index 5341f78..fc35d10 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (qabs_s32_x_tied1, svint32_t,
/*
** qabs_s32_x_untied:
+** movprfx z0, z1
** sqabs z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s64.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s64.c
index 3679e65..b572785 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (qabs_s64_x_tied1, svint64_t,
/*
** qabs_s64_x_untied:
+** movprfx z0, z1
** sqabs z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s8.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s8.c
index dca25f9..48b8560 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s8.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qabs_s8.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (qabs_s8_x_tied1, svint8_t,
/*
** qabs_s8_x_untied:
+** movprfx z0, z1
** sqabs z0\.b, p0/m, z1\.b
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s16.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s16.c
index ca78f9d..d8b6c87 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s16.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s16.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (qneg_s16_x_tied1, svint16_t,
/*
** qneg_s16_x_untied:
+** movprfx z0, z1
** sqneg z0\.h, p0/m, z1\.h
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s32.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s32.c
index 3d2ed87..2342504 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (qneg_s32_x_tied1, svint32_t,
/*
** qneg_s32_x_untied:
+** movprfx z0, z1
** sqneg z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s64.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s64.c
index e137986..61ccb98 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s64.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (qneg_s64_x_tied1, svint64_t,
/*
** qneg_s64_x_untied:
+** movprfx z0, z1
** sqneg z0\.d, p0/m, z1\.d
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s8.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s8.c
index 13c60ef..c7ec611 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s8.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/qneg_s8.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (qneg_s8_x_tied1, svint8_t,
/*
** qneg_s8_x_untied:
+** movprfx z0, z1
** sqneg z0\.b, p0/m, z1\.b
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/recpe_u32.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/recpe_u32.c
index 17c6a72..c484cec 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/recpe_u32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/recpe_u32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (recpe_u32_x_tied1, svuint32_t,
/*
** recpe_u32_x_untied:
+** movprfx z0, z1
** urecpe z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/rsqrte_u32.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/rsqrte_u32.c
index e9e4fb7..082a810 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/rsqrte_u32.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/rsqrte_u32.c
@@ -73,6 +73,7 @@ TEST_UNIFORM_Z (rsqrte_u32_x_tied1, svuint32_t,
/*
** rsqrte_u32_x_untied:
+** movprfx z0, z1
** ursqrte z0\.s, p0/m, z1\.s
** ret
*/
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/bcax_1.c b/gcc/testsuite/gcc.target/aarch64/sve2/bcax_1.c
index 4b0d5a9..7c31afc 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve2/bcax_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/bcax_1.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details --save-temps" } */
-#define OP(x,y,z) ((x) ^ ((y) & (z)))
+#define OP(x,y,z) ((x) ^ (~(y) & (z)))
#include "bitsel_1.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/vect-widen-add.c b/gcc/testsuite/gcc.target/aarch64/vect-widen-add.c
new file mode 100644
index 0000000..220bd93
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/vect-widen-add.c
@@ -0,0 +1,92 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -save-temps" } */
+#include <stdint.h>
+#include <string.h>
+
+#pragma GCC target "+nosve"
+
+#define ARR_SIZE 1024
+
+/* Should produce an uaddl */
+void uadd_opt (uint32_t *foo, uint16_t *a, uint16_t *b)
+{
+ for( int i = 0; i < ARR_SIZE - 3;i=i+4)
+ {
+ foo[i] = a[i] + b[i];
+ foo[i+1] = a[i+1] + b[i+1];
+ foo[i+2] = a[i+2] + b[i+2];
+ foo[i+3] = a[i+3] + b[i+3];
+ }
+}
+
+__attribute__((optimize (0)))
+void uadd_nonopt (uint32_t *foo, uint16_t *a, uint16_t *b)
+{
+ for( int i = 0; i < ARR_SIZE - 3;i=i+4)
+ {
+ foo[i] = a[i] + b[i];
+ foo[i+1] = a[i+1] + b[i+1];
+ foo[i+2] = a[i+2] + b[i+2];
+ foo[i+3] = a[i+3] + b[i+3];
+ }
+}
+
+/* Should produce an saddl */
+void sadd_opt (int32_t *foo, int16_t *a, int16_t *b)
+{
+ for( int i = 0; i < ARR_SIZE - 3;i=i+4)
+ {
+ foo[i] = a[i] + b[i];
+ foo[i+1] = a[i+1] + b[i+1];
+ foo[i+2] = a[i+2] + b[i+2];
+ foo[i+3] = a[i+3] + b[i+3];
+ }
+}
+
+__attribute__((optimize (0)))
+void sadd_nonopt (int32_t *foo, int16_t *a, int16_t *b)
+{
+ for( int i = 0; i < ARR_SIZE - 3;i=i+4)
+ {
+ foo[i] = a[i] + b[i];
+ foo[i+1] = a[i+1] + b[i+1];
+ foo[i+2] = a[i+2] + b[i+2];
+ foo[i+3] = a[i+3] + b[i+3];
+ }
+}
+
+
+void __attribute__((optimize (0)))
+init(uint16_t *a, uint16_t *b)
+{
+ for( int i = 0; i < ARR_SIZE;i++)
+ {
+ a[i] = i;
+ b[i] = 2*i;
+ }
+}
+
+int __attribute__((optimize (0)))
+main()
+{
+ uint32_t foo_arr[ARR_SIZE];
+ uint32_t bar_arr[ARR_SIZE];
+ uint16_t a[ARR_SIZE];
+ uint16_t b[ARR_SIZE];
+
+ init(a, b);
+ uadd_opt(foo_arr, a, b);
+ uadd_nonopt(bar_arr, a, b);
+ if (memcmp(foo_arr, bar_arr, ARR_SIZE) != 0)
+ return 1;
+ sadd_opt((int32_t*) foo_arr, (int16_t*) a, (int16_t*) b);
+ sadd_nonopt((int32_t*) bar_arr, (int16_t*) a, (int16_t*) b);
+ if (memcmp(foo_arr, bar_arr, ARR_SIZE) != 0)
+ return 1;
+ return 0;
+}
+
+/* { dg-final { scan-assembler-times {\tuaddl\t} 1} } */
+/* { dg-final { scan-assembler-times {\tuaddl2\t} 1} } */
+/* { dg-final { scan-assembler-times {\tsaddl\t} 1} } */
+/* { dg-final { scan-assembler-times {\tsaddl2\t} 1} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/vect-widen-lshift.c b/gcc/testsuite/gcc.target/aarch64/vect-widen-lshift.c
new file mode 100644
index 0000000..48a3719
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/vect-widen-lshift.c
@@ -0,0 +1,62 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -save-temps" } */
+#include <stdint.h>
+#include <string.h>
+
+#pragma GCC target "+nosve"
+
+#define ARR_SIZE 1024
+
+/* Should produce an shll,shll2 pair*/
+void sshll_opt (int32_t *foo, int16_t *a, int16_t *b)
+{
+ for( int i = 0; i < ARR_SIZE - 3;i=i+4)
+ {
+ foo[i] = a[i] << 16;
+ foo[i+1] = a[i+1] << 16;
+ foo[i+2] = a[i+2] << 16;
+ foo[i+3] = a[i+3] << 16;
+ }
+}
+
+__attribute__((optimize (0)))
+void sshll_nonopt (int32_t *foo, int16_t *a, int16_t *b)
+{
+ for( int i = 0; i < ARR_SIZE - 3;i=i+4)
+ {
+ foo[i] = a[i] << 16;
+ foo[i+1] = a[i+1] << 16;
+ foo[i+2] = a[i+2] << 16;
+ foo[i+3] = a[i+3] << 16;
+ }
+}
+
+
+void __attribute__((optimize (0)))
+init(uint16_t *a, uint16_t *b)
+{
+ for( int i = 0; i < ARR_SIZE;i++)
+ {
+ a[i] = i;
+ b[i] = 2*i;
+ }
+}
+
+int __attribute__((optimize (0)))
+main()
+{
+ uint32_t foo_arr[ARR_SIZE];
+ uint32_t bar_arr[ARR_SIZE];
+ uint16_t a[ARR_SIZE];
+ uint16_t b[ARR_SIZE];
+
+ init(a, b);
+ sshll_opt(foo_arr, a, b);
+ sshll_nonopt(bar_arr, a, b);
+ if (memcmp(foo_arr, bar_arr, ARR_SIZE) != 0)
+ return 1;
+ return 0;
+}
+
+/* { dg-final { scan-assembler-times {\tshll\t} 1} } */
+/* { dg-final { scan-assembler-times {\tshll2\t} 1} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/vect-widen-sub.c b/gcc/testsuite/gcc.target/aarch64/vect-widen-sub.c
new file mode 100644
index 0000000..a2bed63
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/vect-widen-sub.c
@@ -0,0 +1,92 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -save-temps" } */
+#include <stdint.h>
+#include <string.h>
+
+#pragma GCC target "+nosve"
+
+#define ARR_SIZE 1024
+
+/* Should produce an usubl */
+void usub_opt (uint32_t *foo, uint16_t *a, uint16_t *b)
+{
+ for( int i = 0; i < ARR_SIZE - 3;i=i+4)
+ {
+ foo[i] = a[i] - b[i];
+ foo[i+1] = a[i+1] - b[i+1];
+ foo[i+2] = a[i+2] - b[i+2];
+ foo[i+3] = a[i+3] - b[i+3];
+ }
+}
+
+__attribute__((optimize (0)))
+void usub_nonopt (uint32_t *foo, uint16_t *a, uint16_t *b)
+{
+ for( int i = 0; i < ARR_SIZE - 3;i=i+4)
+ {
+ foo[i] = a[i] - b[i];
+ foo[i+1] = a[i+1] - b[i+1];
+ foo[i+2] = a[i+2] - b[i+2];
+ foo[i+3] = a[i+3] - b[i+3];
+ }
+}
+
+/* Should produce an ssubl */
+void ssub_opt (int32_t *foo, int16_t *a, int16_t *b)
+{
+ for( int i = 0; i < ARR_SIZE - 3;i=i+4)
+ {
+ foo[i] = a[i] - b[i];
+ foo[i+1] = a[i+1] - b[i+1];
+ foo[i+2] = a[i+2] - b[i+2];
+ foo[i+3] = a[i+3] - b[i+3];
+ }
+}
+
+__attribute__((optimize (0)))
+void ssub_nonopt (int32_t *foo, int16_t *a, int16_t *b)
+{
+ for( int i = 0; i < ARR_SIZE - 3;i=i+4)
+ {
+ foo[i] = a[i] - b[i];
+ foo[i+1] = a[i+1] - b[i+1];
+ foo[i+2] = a[i+2] - b[i+2];
+ foo[i+3] = a[i+3] - b[i+3];
+ }
+}
+
+
+void __attribute__((optimize (0)))
+init(uint16_t *a, uint16_t *b)
+{
+ for( int i = 0; i < ARR_SIZE;i++)
+ {
+ a[i] = i;
+ b[i] = 2*i;
+ }
+}
+
+int __attribute__((optimize (0)))
+main()
+{
+ uint32_t foo_arr[ARR_SIZE];
+ uint32_t bar_arr[ARR_SIZE];
+ uint16_t a[ARR_SIZE];
+ uint16_t b[ARR_SIZE];
+
+ init(a, b);
+ usub_opt(foo_arr, a, b);
+ usub_nonopt(bar_arr, a, b);
+ if (memcmp(foo_arr, bar_arr, ARR_SIZE) != 0)
+ return 1;
+ ssub_opt((int32_t*) foo_arr, (int16_t*) a, (int16_t*) b);
+ ssub_nonopt((int32_t*) bar_arr, (int16_t*) a, (int16_t*) b);
+ if (memcmp(foo_arr, bar_arr, ARR_SIZE) != 0)
+ return 1;
+ return 0;
+}
+
+/* { dg-final { scan-assembler-times {\tusubl\t} 1} } */
+/* { dg-final { scan-assembler-times {\tusubl2\t} 1} } */
+/* { dg-final { scan-assembler-times {\tssubl\t} 1} } */
+/* { dg-final { scan-assembler-times {\tssubl2\t} 1} } */
diff --git a/gcc/testsuite/gcc.target/arm/cortex-m55-nodsp-flag-hard.c b/gcc/testsuite/gcc.target/arm/cortex-m55-nodsp-flag-hard.c
index b3c7fd0..92c1511 100644
--- a/gcc/testsuite/gcc.target/arm/cortex-m55-nodsp-flag-hard.c
+++ b/gcc/testsuite/gcc.target/arm/cortex-m55-nodsp-flag-hard.c
@@ -1,6 +1,6 @@
/* { dg-do assemble } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
-/* { dg-additional-options "-mcpu=cortex-m55+nodsp -mfloat-abi=hard -mfpu=auto --save-temps" } */
+/* { dg-additional-options "-mcpu=cortex-m55+nodsp -mthumb -mfloat-abi=hard -mfpu=auto --save-temps" } */
/* { dg-final { scan-assembler "\.arch_extension fp" } } */
/* { dg-final { scan-assembler "\.arch_extension fp.dp" } } */
/* { dg-final { scan-assembler-not "\.arch_extension dsp" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cortex-m55-nodsp-flag-softfp.c b/gcc/testsuite/gcc.target/arm/cortex-m55-nodsp-flag-softfp.c
index 3806554..89d778f 100644
--- a/gcc/testsuite/gcc.target/arm/cortex-m55-nodsp-flag-softfp.c
+++ b/gcc/testsuite/gcc.target/arm/cortex-m55-nodsp-flag-softfp.c
@@ -1,6 +1,6 @@
/* { dg-do assemble } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
-/* { dg-additional-options "-mcpu=cortex-m55+nodsp -mfloat-abi=softfp -mfpu=auto --save-temps" } */
+/* { dg-additional-options "-mcpu=cortex-m55+nodsp -mthumb -mfloat-abi=softfp -mfpu=auto --save-temps" } */
/* { dg-final { scan-assembler "\.arch_extension fp" } } */
/* { dg-final { scan-assembler "\.arch_extension fp.dp" } } */
/* { dg-final { scan-assembler-not "\.arch_extension dsp" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cortex-m55-nodsp-nofp-flag-softfp.c b/gcc/testsuite/gcc.target/arm/cortex-m55-nodsp-nofp-flag-softfp.c
index d22eb4e..405090c 100644
--- a/gcc/testsuite/gcc.target/arm/cortex-m55-nodsp-nofp-flag-softfp.c
+++ b/gcc/testsuite/gcc.target/arm/cortex-m55-nodsp-nofp-flag-softfp.c
@@ -1,6 +1,6 @@
/* { dg-do assemble } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
-/* { dg-additional-options "-mcpu=cortex-m55+nodsp+nofp -mfloat-abi=softfp -mfpu=auto --save-temps" } */
+/* { dg-additional-options "-mcpu=cortex-m55+nodsp+nofp -mthumb -mfloat-abi=softfp -mfpu=auto --save-temps" } */
/* { dg-final { scan-assembler-not "\.arch_extension fp" } } */
/* { dg-final { scan-assembler-not "\.arch_extension fp.dp" } } */
/* { dg-final { scan-assembler-not "\.arch_extension dsp" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cortex-m55-nofp-flag-hard.c b/gcc/testsuite/gcc.target/arm/cortex-m55-nofp-flag-hard.c
index da1cc25..6a92ded 100644
--- a/gcc/testsuite/gcc.target/arm/cortex-m55-nofp-flag-hard.c
+++ b/gcc/testsuite/gcc.target/arm/cortex-m55-nofp-flag-hard.c
@@ -1,6 +1,6 @@
/* { dg-do assemble } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
-/* { dg-additional-options "-mcpu=cortex-m55+nofp -mfloat-abi=hard -mfpu=auto --save-temps" } */
+/* { dg-additional-options "-mcpu=cortex-m55+nofp -mthumb -mfloat-abi=hard -mfpu=auto --save-temps" } */
/* { dg-final { scan-assembler "\.arch_extension mve" } } */
/* { dg-final { scan-assembler "\.arch_extension dsp" } } */
/* { dg-final { scan-assembler-not "\.arch_extension fp" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cortex-m55-nofp-flag-softfp.c b/gcc/testsuite/gcc.target/arm/cortex-m55-nofp-flag-softfp.c
index 0a4fb14..25e80e9 100644
--- a/gcc/testsuite/gcc.target/arm/cortex-m55-nofp-flag-softfp.c
+++ b/gcc/testsuite/gcc.target/arm/cortex-m55-nofp-flag-softfp.c
@@ -1,6 +1,6 @@
/* { dg-do assemble } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
-/* { dg-additional-options "-mcpu=cortex-m55+nofp -mfloat-abi=softfp -mfpu=auto --save-temps" } */
+/* { dg-additional-options "-mcpu=cortex-m55+nofp -mthumb -mfloat-abi=softfp -mfpu=auto --save-temps" } */
/* { dg-final { scan-assembler "\.arch_extension mve" } } */
/* { dg-final { scan-assembler "\.arch_extension dsp" } } */
/* { dg-final { scan-assembler-not "\.arch_extension fp" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cortex-m55-nofp-nomve-flag-softfp.c b/gcc/testsuite/gcc.target/arm/cortex-m55-nofp-nomve-flag-softfp.c
index 2ae7f34..38042cc 100644
--- a/gcc/testsuite/gcc.target/arm/cortex-m55-nofp-nomve-flag-softfp.c
+++ b/gcc/testsuite/gcc.target/arm/cortex-m55-nofp-nomve-flag-softfp.c
@@ -1,6 +1,6 @@
/* { dg-do assemble } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
-/* { dg-additional-options "-mcpu=cortex-m55+nomve+nofp -mfloat-abi=softfp -mfpu=auto --save-temps" } */
+/* { dg-additional-options "-mcpu=cortex-m55+nomve+nofp -mthumb -mfloat-abi=softfp -mfpu=auto --save-temps" } */
/* { dg-final { scan-assembler-not "\.arch_extension mve" } } */
/* { dg-final { scan-assembler-not "\.arch_extension mve.fp" } } */
/* { dg-final { scan-assembler-not "\.arch_extension fp" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cortex-m55-nomve-flag-hard.c b/gcc/testsuite/gcc.target/arm/cortex-m55-nomve-flag-hard.c
index a6ccd7b..2366e99 100644
--- a/gcc/testsuite/gcc.target/arm/cortex-m55-nomve-flag-hard.c
+++ b/gcc/testsuite/gcc.target/arm/cortex-m55-nomve-flag-hard.c
@@ -1,6 +1,6 @@
/* { dg-do assemble } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
-/* { dg-additional-options "-mcpu=cortex-m55+nomve -mfloat-abi=hard -mfpu=auto --save-temps" } */
+/* { dg-additional-options "-mcpu=cortex-m55+nomve -mthumb -mfloat-abi=hard -mfpu=auto --save-temps" } */
/* { dg-final { scan-assembler-not "\.arch_extension mve" } } */
/* { dg-final { scan-assembler "\.arch_extension dsp" } } */
/* { dg-final { scan-assembler "\.arch_extension fp" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cortex-m55-nomve-flag-softfp.c b/gcc/testsuite/gcc.target/arm/cortex-m55-nomve-flag-softfp.c
index 2ad976a..eb2d63d 100644
--- a/gcc/testsuite/gcc.target/arm/cortex-m55-nomve-flag-softfp.c
+++ b/gcc/testsuite/gcc.target/arm/cortex-m55-nomve-flag-softfp.c
@@ -1,6 +1,6 @@
/* { dg-do assemble } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
-/* { dg-additional-options "-mcpu=cortex-m55+nomve -mfloat-abi=softfp -mfpu=auto --save-temps" } */
+/* { dg-additional-options "-mcpu=cortex-m55+nomve -mthumb -mfloat-abi=softfp -mfpu=auto --save-temps" } */
/* { dg-final { scan-assembler-not "\.arch_extension mve" } } */
/* { dg-final { scan-assembler "\.arch_extension dsp" } } */
/* { dg-final { scan-assembler "\.arch_extension fp" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cortex-m55-nomve.fp-flag-hard.c b/gcc/testsuite/gcc.target/arm/cortex-m55-nomve.fp-flag-hard.c
index 40d54b8..e7e57d9 100644
--- a/gcc/testsuite/gcc.target/arm/cortex-m55-nomve.fp-flag-hard.c
+++ b/gcc/testsuite/gcc.target/arm/cortex-m55-nomve.fp-flag-hard.c
@@ -1,6 +1,6 @@
/* { dg-do assemble } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
-/* { dg-additional-options "-mcpu=cortex-m55+nomve.fp -mfloat-abi=hard -mfpu=auto --save-temps" } */
+/* { dg-additional-options "-mcpu=cortex-m55+nomve.fp -mthumb -mfloat-abi=hard -mfpu=auto --save-temps" } */
/* { dg-final { scan-assembler-not "\.arch_extension mve.fp" } } */
/* { dg-final { scan-assembler "\.arch_extension mve" } } */
/* { dg-final { scan-assembler "\.arch_extension dsp" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cortex-m55-nomve.fp-flag-softfp.c b/gcc/testsuite/gcc.target/arm/cortex-m55-nomve.fp-flag-softfp.c
index c726803..42889aa 100644
--- a/gcc/testsuite/gcc.target/arm/cortex-m55-nomve.fp-flag-softfp.c
+++ b/gcc/testsuite/gcc.target/arm/cortex-m55-nomve.fp-flag-softfp.c
@@ -1,6 +1,6 @@
/* { dg-do assemble } */
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
-/* { dg-additional-options "-mcpu=cortex-m55+nomve.fp -mfloat-abi=softfp -mfpu=auto --save-temps" } */
+/* { dg-additional-options "-mcpu=cortex-m55+nomve.fp -mthumb -mfloat-abi=softfp -mfpu=auto --save-temps" } */
/* { dg-final { scan-assembler-not "\.arch_extension mve.fp" } } */
/* { dg-final { scan-assembler "\.arch_extension mve" } } */
/* { dg-final { scan-assembler "\.arch_extension dsp" } } */
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr97327.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr97327.c
index 8f6d360..d19bde5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr97327.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr97327.c
@@ -1,6 +1,6 @@
/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
/* { dg-skip-if "Incompatible float ABI" { *-*-* } { "-mfloat-abi=hard" } { "" } } */
-/* { dg-additional-options "-mcpu=cortex-m55 -mfloat-abi=soft -mfpu=auto -Werror" } */
+/* { dg-additional-options "-mcpu=cortex-m55 -mthumb -mfloat-abi=soft -mfpu=auto -Werror" } */
int main ()
{
diff --git a/gcc/testsuite/gcc.target/arm/pr91816.c b/gcc/testsuite/gcc.target/arm/pr91816.c
new file mode 100644
index 0000000..f126914
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr91816.c
@@ -0,0 +1,64 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-additional-options "-mthumb" } */
+/* { dg-timeout-factor 4.0 } */
+
+int printf(const char *, ...);
+
+#define HW0 printf("Hello World!\n");
+#define HW1 HW0 HW0 HW0 HW0 HW0 HW0 HW0 HW0 HW0 HW0
+#define HW2 HW1 HW1 HW1 HW1 HW1 HW1 HW1 HW1 HW1 HW1
+#define HW3 HW2 HW2 HW2 HW2 HW2 HW2 HW2 HW2 HW2 HW2
+#define HW4 HW3 HW3 HW3 HW3 HW3 HW3 HW3 HW3 HW3 HW3
+#define HW5 HW4 HW4 HW4 HW4 HW4 HW4 HW4 HW4 HW4 HW4
+#define HW6 HW5 HW5
+
+__attribute__((noinline,noclone)) void f1 (int a)
+{
+ if (a) { HW0 }
+}
+
+__attribute__((noinline,noclone)) void f2 (int a)
+{
+ if (a) { HW3 }
+}
+
+
+__attribute__((noinline,noclone)) void f3 (int a)
+{
+ if (a) { HW6 }
+}
+
+__attribute__((noinline,noclone)) void f4 (int a)
+{
+ if (a == 1) { HW0 }
+}
+
+__attribute__((noinline,noclone)) void f5 (int a)
+{
+ if (a == 1) { HW3 }
+}
+
+
+__attribute__((noinline,noclone)) void f6 (int a)
+{
+ if (a == 1) { HW6 }
+}
+
+
+int main(void)
+{
+ f1(0);
+ f2(0);
+ f3(0);
+ f4(0);
+ f5(0);
+ f6(0);
+ return 0;
+}
+
+
+/* { dg-final { scan-assembler-times "beq\\t.L\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "beq\\t.Lbcond\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-times "bne\\t.L\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "bne\\t.Lbcond\[0-9\]" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/pr97528.c b/gcc/testsuite/gcc.target/arm/pr97528.c
new file mode 100644
index 0000000..6cc59f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr97528.c
@@ -0,0 +1,28 @@
+/* PR target/97528 */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-O1" } */
+/* { dg-add-options arm_neon } */
+
+#include <arm_neon.h>
+
+typedef __simd64_int16_t T;
+typedef __simd64_uint16_t U;
+unsigned short c;
+int d;
+U e;
+
+void
+foo (void)
+{
+ unsigned short *dst = &c;
+ int g = d, b = 4;
+ U dc = e;
+ for (int h = 0; h < b; h++)
+ {
+ unsigned short *i = dst;
+ U j = dc;
+ vst1_s16 ((int16_t *) i, (T) j);
+ dst += g;
+ }
+}
diff --git a/gcc/testsuite/gcc.target/arm/simd/bf16_vldn_1.c b/gcc/testsuite/gcc.target/arm/simd/bf16_vldn_1.c
index 222e7af..663e769 100644
--- a/gcc/testsuite/gcc.target/arm/simd/bf16_vldn_1.c
+++ b/gcc/testsuite/gcc.target/arm/simd/bf16_vldn_1.c
@@ -10,8 +10,8 @@
/*
**test_vld2_bf16:
** ...
-** vld2.16 {d0-d1}, \[r0\]
-** bx lr
+** vld[0-9]+.16 {d[0-9]+-d[0-9]+}, \[r[0-9]+\]
+** ...
*/
bfloat16x4x2_t
test_vld2_bf16 (bfloat16_t * ptr)
@@ -22,8 +22,8 @@ test_vld2_bf16 (bfloat16_t * ptr)
/*
**test_vld2q_bf16:
** ...
-** vld2.16 {d0-d3}, \[r0\]
-** bx lr
+** vld[0-9]+.16 {d[0-9]+-d[0-9]+}, \[r[0-9]+\]
+** ...
*/
bfloat16x8x2_t
test_vld2q_bf16 (bfloat16_t * ptr)
@@ -34,8 +34,8 @@ test_vld2q_bf16 (bfloat16_t * ptr)
/*
**test_vld2_dup_bf16:
** ...
-** vld2.16 {d0\[\], d1\[\]}, \[r0\]
-** bx lr
+** vld[0-9]+.16 {d[0-9]+\[\], d[0-9]+\[\]}, \[r[0-9]+\]
+** ...
*/
bfloat16x4x2_t
test_vld2_dup_bf16 (bfloat16_t * ptr)
@@ -46,8 +46,8 @@ test_vld2_dup_bf16 (bfloat16_t * ptr)
/*
**test_vld2q_dup_bf16:
** ...
-** vld2.16 {d0, d1, d2, d3}, \[r0\]
-** bx lr
+** vld[0-9]+.16 {d[0-9]+, d[0-9]+, d[0-9]+, d[0-9]+}, \[r[0-9]+\]
+** ...
*/
bfloat16x8x2_t
test_vld2q_dup_bf16 (bfloat16_t * ptr)
@@ -58,8 +58,8 @@ test_vld2q_dup_bf16 (bfloat16_t * ptr)
/*
**test_vld3_bf16:
** ...
-** vld3.16 {d0-d2}, \[r0\]
-** bx lr
+** vld[0-9]+.16 {d[0-9]+-d[0-9]+}, \[r[0-9]+\]
+** ...
*/
bfloat16x4x3_t
test_vld3_bf16 (bfloat16_t * ptr)
@@ -70,8 +70,8 @@ test_vld3_bf16 (bfloat16_t * ptr)
/*
**test_vld3q_bf16:
** ...
-** vld3.16 {d1, d3, d5}, \[r0\]
-** bx lr
+** vld[0-9]+.16 {d[0-9]+, d[0-9]+, d[0-9]+}, \[r[0-9]+\]
+** ...
*/
bfloat16x8x3_t
test_vld3q_bf16 (bfloat16_t * ptr)
@@ -82,8 +82,8 @@ test_vld3q_bf16 (bfloat16_t * ptr)
/*
**test_vld3_dup_bf16:
** ...
-** vld3.16 {d0\[\], d1\[\], d2\[\]}, \[r0\]
-** bx lr
+** vld[0-9]+.16 {d[0-9]+\[\], d[0-9]+\[\], d[0-9]+\[\]}, \[r[0-9]+\]
+** ...
*/
bfloat16x4x3_t
test_vld3_dup_bf16 (bfloat16_t * ptr)
@@ -94,8 +94,8 @@ test_vld3_dup_bf16 (bfloat16_t * ptr)
/*
**test_vld3q_dup_bf16:
** ...
-** vld3.16 {d0\[\], d1\[\], d2\[\]}, \[r0\]
-** bx lr
+** vld[0-9]+.16 {d[0-9]+\[\], d[0-9]+\[\], d[0-9]+\[\]}, \[r[0-9]+\]
+** ...
*/
bfloat16x8x3_t
test_vld3q_dup_bf16 (bfloat16_t * ptr)
@@ -106,8 +106,8 @@ test_vld3q_dup_bf16 (bfloat16_t * ptr)
/*
**test_vld4_bf16:
** ...
-** vld4.16 {d0-d3}, \[r0\]
-** bx lr
+** vld4.16 {d[0-9]+-d[0-9]+}, \[r[0-9]+\]
+** ...
*/
bfloat16x4x4_t
test_vld4_bf16 (bfloat16_t * ptr)
@@ -118,8 +118,8 @@ test_vld4_bf16 (bfloat16_t * ptr)
/*
**test_vld4q_bf16:
** ...
-** vld4.16 {d1, d3, d5, d7}, \[r0\]
-** bx lr
+** vld4.16 {d[0-9]+, d[0-9]+, d[0-9]+, d[0-9]+}, \[r[0-9]+\]
+** ...
*/
bfloat16x8x4_t
test_vld4q_bf16 (bfloat16_t * ptr)
@@ -130,8 +130,8 @@ test_vld4q_bf16 (bfloat16_t * ptr)
/*
**test_vld4_dup_bf16:
** ...
-** vld4.16 {d0\[\], d1\[\], d2\[\], d3\[\]}, \[r0\]
-** bx lr
+** vld4.16 {d[0-9]+\[\], d[0-9]+\[\], d[0-9]+\[\], d[0-9]+\[\]}, \[r[0-9]+\]
+** ...
*/
bfloat16x4x4_t
test_vld4_dup_bf16 (bfloat16_t * ptr)
@@ -142,8 +142,8 @@ test_vld4_dup_bf16 (bfloat16_t * ptr)
/*
**test_vld4q_dup_bf16:
** ...
-** vld4.16 {d0\[\], d1\[\], d2\[\], d3\[\]}, \[r0\]
-** bx lr
+** vld4.16 {d[0-9]+\[\], d[0-9]+\[\], d[0-9]+\[\], d[0-9]+\[\]}, \[r[0-9]+\]
+** ...
*/
bfloat16x8x4_t
test_vld4q_dup_bf16 (bfloat16_t * ptr)
diff --git a/gcc/testsuite/gcc.target/arm/simd/vldn_lane_bf16_1.c b/gcc/testsuite/gcc.target/arm/simd/vldn_lane_bf16_1.c
index 58153ed..b235b1f 100644
--- a/gcc/testsuite/gcc.target/arm/simd/vldn_lane_bf16_1.c
+++ b/gcc/testsuite/gcc.target/arm/simd/vldn_lane_bf16_1.c
@@ -8,8 +8,9 @@
/*
**test_vld2_lane_bf16:
-** vld2.16 {d0\[2\], d1\[2\]}, \[r0\]
-** bx lr
+** ...
+** vld2.16 {d[0-9]+\[2\], d[0-9]+\[2\]}, \[r[0-9]+\]
+** ...
*/
bfloat16x4x2_t
test_vld2_lane_bf16 (const bfloat16_t *a, bfloat16x4x2_t b)
@@ -19,8 +20,9 @@ test_vld2_lane_bf16 (const bfloat16_t *a, bfloat16x4x2_t b)
/*
**test_vld2q_lane_bf16:
-** vld2.16 {d0\[2\], d2\[2\]}, \[r0\]
-** bx lr
+** ...
+** vld2.16 {d[0-9]+\[2\], d[0-9]+\[2\]}, \[r[0-9]+\]
+** ...
*/
bfloat16x8x2_t
test_vld2q_lane_bf16 (const bfloat16_t *a, bfloat16x8x2_t b)
@@ -30,8 +32,9 @@ test_vld2q_lane_bf16 (const bfloat16_t *a, bfloat16x8x2_t b)
/*
**test_vld3_lane_bf16:
-** vld3.16 {d0\[2\], d1\[2\], d2\[2\]}, \[r0\]
-** bx lr
+** ...
+** vld3.16 {d[0-9]+\[2\], d[0-9]+\[2\], d[0-9]+\[2\]}, \[r[0-9]+\]
+** ...
*/
bfloat16x4x3_t
test_vld3_lane_bf16 (const bfloat16_t *a, bfloat16x4x3_t b)
@@ -41,8 +44,9 @@ test_vld3_lane_bf16 (const bfloat16_t *a, bfloat16x4x3_t b)
/*
**test_vld3q_lane_bf16:
-** vld3.16 {d0\[2\], d2\[2\], d4\[2\]}, \[r0\]
-** bx lr
+** ...
+** vld3.16 {d[0-9]+\[2\], d[0-9]+\[2\], d[0-9]+\[2\]}, \[r0\]
+** ...
*/
bfloat16x8x3_t
test_vld3q_lane_bf16 (const bfloat16_t *a, bfloat16x8x3_t b)
@@ -52,8 +56,9 @@ test_vld3q_lane_bf16 (const bfloat16_t *a, bfloat16x8x3_t b)
/*
**test_vld4_lane_bf16:
-** vld4.16 {d0\[2\], d1\[2\], d2\[2\], d3\[2\]}, \[r0\]
-** bx lr
+** ...
+** vld4.16 {d[0-9]+\[2\], d[0-9]+\[2\], d[0-9]+\[2\], d[0-9]+\[2\]}, \[r0\]
+** ...
*/
bfloat16x4x4_t
test_vld4_lane_bf16 (const bfloat16_t *a, bfloat16x4x4_t b)
@@ -63,8 +68,9 @@ test_vld4_lane_bf16 (const bfloat16_t *a, bfloat16x4x4_t b)
/*
**test_vld4q_lane_bf16:
-** vld4.16 {d0\[2\], d2\[2\], d4\[2\], d6\[2\]}, \[r0\]
-** bx lr
+** ...
+** vld4.16 {d[0-9]+\[2\], d[0-9]+\[2\], d[0-9]+\[2\], d[0-9]+\[2\]}, \[r0\]
+** ...
*/
bfloat16x8x4_t
test_vld4q_lane_bf16 (const bfloat16_t *a, bfloat16x8x4_t b)
diff --git a/gcc/testsuite/gcc.target/arm/simd/vmmla_1.c b/gcc/testsuite/gcc.target/arm/simd/vmmla_1.c
index fa512d9..aeb4a35 100644
--- a/gcc/testsuite/gcc.target/arm/simd/vmmla_1.c
+++ b/gcc/testsuite/gcc.target/arm/simd/vmmla_1.c
@@ -1,6 +1,6 @@
/* { dg-do assemble } */
/* { dg-require-effective-target arm_v8_2a_i8mm_ok } */
-/* { dg-options "-save-temps -O2 -march=armv8.2-a+i8mm" } */
+/* { dg-options "-save-temps -O2 -march=armv8.2-a+i8mm -mfloat-abi=hard" } */
#include "arm_neon.h"
diff --git a/gcc/testsuite/gcc.target/h8300/add-2.c b/gcc/testsuite/gcc.target/h8300/add-2.c
new file mode 100644
index 0000000..27f9b2f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/h8300/add-2.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-ms -mint32 -O2" } */
+/* { dg-final { scan-assembler-not "cmp" } } */
+
+#include "add.c"
diff --git a/gcc/testsuite/gcc.target/h8300/add-3.c b/gcc/testsuite/gcc.target/h8300/add-3.c
new file mode 100644
index 0000000..20de647
--- /dev/null
+++ b/gcc/testsuite/gcc.target/h8300/add-3.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-msx -mint32 -O2" } */
+/* { dg-final { scan-assembler-not "cmp" } } */
+
+#include "add.c"
diff --git a/gcc/testsuite/gcc.target/h8300/add.c b/gcc/testsuite/gcc.target/h8300/add.c
new file mode 100644
index 0000000..ebeea57
--- /dev/null
+++ b/gcc/testsuite/gcc.target/h8300/add.c
@@ -0,0 +1,118 @@
+/* { dg-do compile } */
+/* { dg-options "-mh -mint32 -O2" } */
+/* { dg-final { scan-assembler-not "cmp" } } */
+
+typedef unsigned char uchar;
+typedef signed char schar;
+typedef unsigned short ushort;
+typedef unsigned long ulong;
+
+volatile void abort (void);
+
+
+#define ADD(T)\
+T addE##T (T x, T y) { T t = x + y ; if (t == 0) abort (); return t; } \
+T addNE##T (T x, T y) { T t = x + y ; if (t != 0) return t; abort (); } \
+T addGE##T (T x, T y) { T t = x + y ; if (t >= 0) abort (); return t; } \
+T addLT##T (T x, T y) { T t = x + y ; if (t < 0) abort (); return t; }
+
+#define ADDC(T,N)\
+T addEQ##N##T (T a) { T t = a + N; if (t == 0) abort (); return t; } \
+T addNE##N##T (T a) { T t = a + N; if (t != 0) return t; abort (); } \
+T addGE##N##T (T a) { T t = a + N; if (t >= 0) abort (); return t; } \
+T addLT##N##T (T a) { T t = a + N; if (t < 0) abort (); return t; }
+
+#define ADDNC(T,N)\
+T addEQN##N##T (T a) { T t = a + -N; if (t == 0) abort (); return t; } \
+T addNEN##N##T (T a) { T t = a + -N; if (t != 0) return t; abort (); } \
+T addGEN##N##T (T a) { T t = a + -N; if (t >= 0) abort (); return t; } \
+T addLTN##N##T (T a) { T t = a + -N; if (t < 0) abort (); return t; }
+
+
+ADD (schar)
+ADD (short)
+ADD (long)
+ADD (uchar)
+ADD (ushort)
+ADD (ulong)
+
+
+
+ADDC (schar,1)
+ADDC (schar,2)
+ADDC (schar,3)
+ADDC (schar,4)
+ADDC (schar,6)
+ADDC (schar,8)
+ADDNC (schar,1)
+ADDNC (schar,2)
+ADDNC (schar,3)
+ADDNC (schar,4)
+ADDNC (schar,6)
+ADDNC (schar,8)
+
+ADDC (uchar,1)
+ADDC (uchar,2)
+ADDC (uchar,3)
+ADDC (uchar,4)
+ADDC (uchar,6)
+ADDC (uchar,8)
+ADDNC (uchar,1)
+ADDNC (uchar,2)
+ADDNC (uchar,3)
+ADDNC (uchar,4)
+ADDNC (uchar,6)
+ADDNC (uchar,8)
+
+ADDC (short,1)
+ADDC (short,2)
+ADDC (short,3)
+ADDC (short,4)
+ADDC (short,6)
+ADDC (short,8)
+ADDNC (short,1)
+ADDNC (short,2)
+ADDNC (short,3)
+ADDNC (short,4)
+ADDNC (short,6)
+ADDNC (short,8)
+
+ADDC (ushort,1)
+ADDC (ushort,2)
+ADDC (ushort,3)
+ADDC (ushort,4)
+ADDC (ushort,6)
+ADDC (ushort,8)
+ADDNC (ushort,1)
+ADDNC (ushort,2)
+ADDNC (ushort,3)
+ADDNC (ushort,4)
+ADDNC (ushort,6)
+ADDNC (ushort,8)
+
+ADDC (long,1)
+ADDC (long,2)
+ADDC (long,3)
+ADDC (long,4)
+ADDC (long,6)
+ADDC (long,8)
+ADDNC (long,1)
+ADDNC (long,2)
+ADDNC (long,3)
+ADDNC (long,4)
+ADDNC (long,6)
+ADDNC (long,8)
+
+ADDC (ulong,1)
+ADDC (ulong,2)
+ADDC (ulong,3)
+ADDC (ulong,4)
+ADDC (ulong,6)
+ADDC (ulong,8)
+ADDNC (ulong,1)
+ADDNC (ulong,2)
+ADDNC (ulong,3)
+ADDNC (ulong,4)
+ADDNC (ulong,6)
+ADDNC (ulong,8)
+
diff --git a/gcc/testsuite/gcc.target/h8300/sub-2.c b/gcc/testsuite/gcc.target/h8300/sub-2.c
new file mode 100644
index 0000000..c2914bd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/h8300/sub-2.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-ms -mint32 -O2" } */
+/* { dg-final { scan-assembler-not "cmp" } } */
+
+#include "sub.c"
diff --git a/gcc/testsuite/gcc.target/h8300/sub-3.c b/gcc/testsuite/gcc.target/h8300/sub-3.c
new file mode 100644
index 0000000..72bcf04
--- /dev/null
+++ b/gcc/testsuite/gcc.target/h8300/sub-3.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-msx -mint32 -O2" } */
+/* { dg-final { scan-assembler-not "cmp" } } */
+
+#include "sub.c"
diff --git a/gcc/testsuite/gcc.target/h8300/sub.c b/gcc/testsuite/gcc.target/h8300/sub.c
new file mode 100644
index 0000000..66b63ab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/h8300/sub.c
@@ -0,0 +1,118 @@
+/* { dg-do compile } */
+/* { dg-options "-mh -mint32 -O2" } */
+/* { dg-final { scan-assembler-not "cmp" } } */
+
+typedef unsigned char uchar;
+typedef signed char schar;
+typedef unsigned short ushort;
+typedef unsigned long ulong;
+
+volatile void abort (void);
+
+
+#define SUB(T)\
+T subE##T (T x, T y) { T t = x - y ; if (t == 0) abort (); return t; } \
+T subNE##T (T x, T y) { T t = x - y ; if (t != 0) return t; abort (); } \
+T subGE##T (T x, T y) { T t = x - y ; if (t >= 0) abort (); return t; } \
+T subLT##T (T x, T y) { T t = x - y ; if (t < 0) abort (); return t; }
+
+#define SUBC(T,N)\
+T subEQ##N##T (T a) { T t = a - N; if (t == 0) abort (); return t; } \
+T subNE##N##T (T a) { T t = a - N; if (t != 0) return t; abort (); } \
+T subGE##N##T (T a) { T t = a - N; if (t >= 0) abort (); return t; } \
+T subLT##N##T (T a) { T t = a - N; if (t < 0) abort (); return t; }
+
+#define SUBNC(T,N)\
+T subEQN##N##T (T a) { T t = a - -N; if (t == 0) abort (); return t; } \
+T subNEN##N##T (T a) { T t = a - -N; if (t != 0) return t; abort (); } \
+T subGEN##N##T (T a) { T t = a - -N; if (t >= 0) abort (); return t; } \
+T subLTN##N##T (T a) { T t = a - -N; if (t < 0) abort (); return t; }
+
+
+SUB (schar)
+SUB (short)
+SUB (long)
+SUB (uchar)
+SUB (ushort)
+SUB (ulong)
+
+
+
+SUBC (schar,1)
+SUBC (schar,2)
+SUBC (schar,3)
+SUBC (schar,4)
+SUBC (schar,6)
+SUBC (schar,8)
+SUBNC (schar,1)
+SUBNC (schar,2)
+SUBNC (schar,3)
+SUBNC (schar,4)
+SUBNC (schar,6)
+SUBNC (schar,8)
+
+SUBC (uchar,1)
+SUBC (uchar,2)
+SUBC (uchar,3)
+SUBC (uchar,4)
+SUBC (uchar,6)
+SUBC (uchar,8)
+SUBNC (uchar,1)
+SUBNC (uchar,2)
+SUBNC (uchar,3)
+SUBNC (uchar,4)
+SUBNC (uchar,6)
+SUBNC (uchar,8)
+
+SUBC (short,1)
+SUBC (short,2)
+SUBC (short,3)
+SUBC (short,4)
+SUBC (short,6)
+SUBC (short,8)
+SUBNC (short,1)
+SUBNC (short,2)
+SUBNC (short,3)
+SUBNC (short,4)
+SUBNC (short,6)
+SUBNC (short,8)
+
+SUBC (ushort,1)
+SUBC (ushort,2)
+SUBC (ushort,3)
+SUBC (ushort,4)
+SUBC (ushort,6)
+SUBC (ushort,8)
+SUBNC (ushort,1)
+SUBNC (ushort,2)
+SUBNC (ushort,3)
+SUBNC (ushort,4)
+SUBNC (ushort,6)
+SUBNC (ushort,8)
+
+SUBC (long,1)
+SUBC (long,2)
+SUBC (long,3)
+SUBC (long,4)
+SUBC (long,6)
+SUBC (long,8)
+SUBNC (long,1)
+SUBNC (long,2)
+SUBNC (long,3)
+SUBNC (long,4)
+SUBNC (long,6)
+SUBNC (long,8)
+
+SUBC (ulong,1)
+SUBC (ulong,2)
+SUBC (ulong,3)
+SUBC (ulong,4)
+SUBC (ulong,6)
+SUBC (ulong,8)
+SUBNC (ulong,1)
+SUBNC (ulong,2)
+SUBNC (ulong,3)
+SUBNC (ulong,4)
+SUBNC (ulong,6)
+SUBNC (ulong,8)
+
diff --git a/gcc/testsuite/gcc.target/i386/avx-vnni-1.c b/gcc/testsuite/gcc.target/i386/avx-vnni-1.c
new file mode 100644
index 0000000..a22d12a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vnni-1.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-mavxvnni -O2" } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+
+
+#include <immintrin.h>
+
+volatile __m256i x,y,z;
+volatile __m128i x_,y_,z_;
+
+void extern
+avxvnni_test (void)
+{
+ x = _mm256_dpbusd_epi32 (x, y, z);
+ x_ = _mm_dpbusd_epi32 (x_, y_, z_);
+ x = _mm256_dpbusds_epi32 (x, y, z);
+ x_ = _mm_dpbusds_epi32 (x_, y_, z_);
+ x = _mm256_dpwssd_epi32 (x, y, z);
+ x_ = _mm_dpwssd_epi32 (x_, y_, z_);
+ x = _mm256_dpwssds_epi32 (x, y, z);
+ x_ = _mm_dpwssds_epi32 (x_, y_, z_);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-vnni-2.c b/gcc/testsuite/gcc.target/i386/avx-vnni-2.c
new file mode 100644
index 0000000..4ab6f0c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vnni-2.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+
+
+#include <immintrin.h>
+
+volatile __m256i x,y,z;
+volatile __m128i x_,y_,z_;
+
+__attribute__((target("avxvnni")))
+void
+avxvnni_test (void)
+{
+ x = _mm256_dpbusd_epi32 (x, y, z);
+ x_ = _mm_dpbusd_epi32 (x_, y_, z_);
+ x = _mm256_dpbusds_epi32 (x, y, z);
+ x_ = _mm_dpbusds_epi32 (x_, y_, z_);
+ x = _mm256_dpwssd_epi32 (x, y, z);
+ x_ = _mm_dpwssd_epi32 (x_, y_, z_);
+ x = _mm256_dpwssds_epi32 (x, y, z);
+ x_ = _mm_dpwssds_epi32 (x_, y_, z_);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-vnni-3.c b/gcc/testsuite/gcc.target/i386/avx-vnni-3.c
new file mode 100644
index 0000000..fdea7f9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vnni-3.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=x86-64" } */
+
+__attribute__ ((__gnu_inline__, __always_inline__, target("avxvnni")))
+inline int
+foo (void) /* { dg-error "inlining failed in call to 'always_inline' .* target specific option mismatch" } */
+{
+ return 0;
+}
+
+__attribute__ ((target("avx512vnni,avx512vl")))
+int
+bar (void)
+{
+ return foo (); /* { dg-message "called from here" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-vnni-4.c b/gcc/testsuite/gcc.target/i386/avx-vnni-4.c
new file mode 100644
index 0000000..1ef3edc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vnni-4.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=x86-64" } */
+
+__attribute__ ((__gnu_inline__, __always_inline__, target("avx512vnni,avx512vl")))
+inline int
+foo (void) /* { dg-error "inlining failed in call to 'always_inline' .* target specific option mismatch" } */
+{
+ return 0;
+}
+
+__attribute__ ((target("avxvnni")))
+int
+bar (void)
+{
+ return foo (); /* { dg-message "called from here" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-vnni-5.c b/gcc/testsuite/gcc.target/i386/avx-vnni-5.c
new file mode 100644
index 0000000..6556a32
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vnni-5.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavxvnni -mavx512vnni -mavx512vl" } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+
+
+#include <immintrin.h>
+
+volatile __m256i x,y,z;
+volatile __m128i x_,y_,z_;
+
+void
+avxvnni_test (void)
+{
+ x = _mm256_dpbusd_epi32 (x, y, z);
+ x_ = _mm_dpbusd_epi32 (x_, y_, z_);
+ x = _mm256_dpbusds_epi32 (x, y, z);
+ x_ = _mm_dpbusds_epi32 (x_, y_, z_);
+ x = _mm256_dpwssd_epi32 (x, y, z);
+ x_ = _mm_dpwssd_epi32 (x_, y_, z_);
+ x = _mm256_dpwssds_epi32 (x, y, z);
+ x_ = _mm_dpwssds_epi32 (x_, y_, z_);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-vnni-6.c b/gcc/testsuite/gcc.target/i386/avx-vnni-6.c
new file mode 100644
index 0000000..2c42627
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vnni-6.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-mavxvnni -O2" } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+
+
+#include <immintrin.h>
+
+volatile __m256i x,y,z;
+volatile __m128i x_,y_,z_;
+
+void extern
+avxvnni_test (void)
+{
+ x = _mm256_dpbusd_avx_epi32 (x, y, z);
+ x_ = _mm_dpbusd_avx_epi32 (x_, y_, z_);
+ x = _mm256_dpbusds_avx_epi32 (x, y, z);
+ x_ = _mm_dpbusds_avx_epi32 (x_, y_, z_);
+ x = _mm256_dpwssd_avx_epi32 (x, y, z);
+ x_ = _mm_dpwssd_avx_epi32 (x_, y_, z_);
+ x = _mm256_dpwssds_avx_epi32 (x, y, z);
+ x_ = _mm_dpwssds_avx_epi32 (x_, y_, z_);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-vpdpbusd-2.c b/gcc/testsuite/gcc.target/i386/avx-vpdpbusd-2.c
new file mode 100644
index 0000000..d4b8d89
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vpdpbusd-2.c
@@ -0,0 +1,74 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -mavxvnni" } */
+/* { dg-require-effective-target avxvnni } */
+
+#ifndef CHECK
+#define CHECK "avx-check.h"
+#endif
+
+#ifndef TEST
+#define TEST avx_test
+#endif
+
+#include CHECK
+
+static void
+CALC (int *r, int *dst, unsigned char *s1, char *s2, int size)
+{
+ short tempres[32];
+ for (int i = 0; i < size; i++) {
+ tempres[i] = ((unsigned short)(s1[i]) * (short)(s2[i]));
+ }
+ for (int i = 0; i < size / 4; i++) {
+ long long test = (long long)dst[i] + tempres[i*4] + tempres[i*4 + 1] + tempres[i*4 + 2] + tempres[i*4 + 3];
+ r[i] = test;
+ }
+}
+
+void
+TEST (void)
+{
+ int i;
+ union256i_d res_256;
+ union256i_b src2_256;
+ union256i_ub src1_256;
+ int res_ref_256[8];
+
+ if (!__builtin_cpu_supports ("avxvnni"))
+ return;
+
+ for (i = 0; i < 32; i++)
+ {
+ int sign = i % 2 ? 1 : -1;
+ src1_256.a[i] = 10 + 3*i + sign;
+ src2_256.a[i] = sign*10*i*i;
+ }
+
+ for (i = 0; i < 8; i++)
+ res_256.a[i] = 0x7fffffff;
+
+ CALC (res_ref_256, res_256.a, src1_256.a, src2_256.a, 32);
+ res_256.x = _mm256_dpbusd_avx_epi32 (res_256.x, src1_256.x, src2_256.x);
+ if (check_union256i_d (res_256, res_ref_256))
+ abort ();
+
+ union128i_d res_128;
+ union128i_b src2_128;
+ union128i_ub src1_128;
+ int res_ref_128[4];
+
+ for (i = 0; i < 16; i++)
+ {
+ int sign = i % 2 ? 1 : -1;
+ src1_128.a[i] = 10 + 3*i*i + sign;
+ src2_128.a[i] = sign*10*i*i;
+ }
+
+ for (i = 0; i < 4; i++)
+ res_128.a[i] = 0x7fffffff;
+
+ CALC (res_ref_128, res_128.a, src1_128.a, src2_128.a, 16);
+ res_128.x = _mm_dpbusd_avx_epi32 (res_128.x, src1_128.x, src2_128.x);
+ if (check_union128i_d (res_128, res_ref_128))
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-vpdpbusds-2.c b/gcc/testsuite/gcc.target/i386/avx-vpdpbusds-2.c
new file mode 100644
index 0000000..5041ffe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vpdpbusds-2.c
@@ -0,0 +1,74 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -mavxvnni " } */
+/* { dg-require-effective-target avxvnni } */
+
+#ifndef CHECK
+#define CHECK "avx-check.h"
+#endif
+
+#ifndef TEST
+#define TEST avx_test
+#endif
+
+#include CHECK
+
+static void
+CALC (int *r, int *dst, unsigned char *s1, char *s2, int size)
+{
+ short tempres[32];
+ for (int i = 0; i < size; i++) {
+ tempres[i] = ((unsigned short)(s1[i]) * (short)(s2[i]));
+ }
+ for (int i = 0; i < size / 4; i++) {
+ long long test = (long long)dst[i] + tempres[i*4] + tempres[i*4 + 1] + tempres[i*4 + 2] + tempres[i*4 + 3];
+ r[i] = test > 0x7FFFFFFF ? 0x7FFFFFFF : test;
+ }
+}
+
+void
+TEST (void)
+{
+ int i;
+ union256i_d res_256;
+ union256i_b src2_256;
+ union256i_ub src1_256;
+ int res_ref_256[8];
+
+ if (!__builtin_cpu_supports ("avxvnni"))
+ return;
+
+ for (i = 0; i < 32; i++)
+ {
+ int sign = i % 2 ? 1 : -1;
+ src1_256.a[i] = 10 + 3*i*i + sign;
+ src2_256.a[i] = sign*10*i*i;
+ }
+
+ for (i = 0; i < 8; i++)
+ res_256.a[i] = 0x7fffffff;
+
+ CALC (res_ref_256, res_256.a, src1_256.a, src2_256.a, 32);
+ res_256.x = _mm256_dpbusds_avx_epi32 (res_256.x, src1_256.x, src2_256.x);
+ if (check_union256i_d (res_256, res_ref_256))
+ abort ();
+
+ union128i_d res_128;
+ union128i_b src2_128;
+ union128i_ub src1_128;
+ int res_ref_128[4];
+
+ for (i = 0; i < 16; i++)
+ {
+ int sign = i % 2 ? 1 : -1;
+ src1_128.a[i] = 10 + 3*i*i + sign;
+ src2_128.a[i] = sign*10*i*i;
+ }
+
+ for (i = 0; i < 4; i++)
+ res_128.a[i] = 0x7fffffff;
+
+ CALC (res_ref_128, res_128.a, src1_128.a, src2_128.a, 16);
+ res_128.x = _mm_dpbusds_avx_epi32 (res_128.x, src1_128.x, src2_128.x);
+ if (check_union128i_d (res_128, res_ref_128))
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-vpdpwssd-2.c b/gcc/testsuite/gcc.target/i386/avx-vpdpwssd-2.c
new file mode 100644
index 0000000..2630c97
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vpdpwssd-2.c
@@ -0,0 +1,70 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -mavxvnni" } */
+/* { dg-require-effective-target avxvnni } */
+
+#ifndef CHECK
+#define CHECK "avx-check.h"
+#endif
+
+#ifndef TEST
+#define TEST avx_test
+#endif
+
+#include CHECK
+
+static void
+CALC (int *r, int *dst, short *s1, short *s2, int size)
+{
+ short tempres[16];
+ for (int i = 0; i < size; i++) {
+ tempres[i] = ((int)(s1[i]) * (int)(s2[i]));
+ }
+ for (int i = 0; i < size / 2; i++) {
+ long long test = (long long)dst[i] + tempres[i*2] + tempres[i*2 + 1];
+ r[i] = test;
+ }
+}
+
+void
+TEST (void)
+{
+ int i;
+ union256i_d res_256;
+ union256i_w src1_256, src2_256;
+ int res_ref_256[8];
+
+ if (!__builtin_cpu_supports ("avxvnni"))
+ return;
+
+ for (i = 0; i < 16; i++)
+ {
+ src1_256.a[i] = 1 + i;
+ src2_256.a[i] = 2 + 2*i + i * i;
+ }
+
+ for (i = 0; i < 8; i++)
+ res_256.a[i] = 0x7fffffff;
+
+ CALC (res_ref_256, res_256.a, src1_256.a, src2_256.a, 16);
+ res_256.x = _mm256_dpwssd_avx_epi32 (res_256.x, src1_256.x, src2_256.x);
+ if (check_union256i_d (res_256, res_ref_256))
+ abort ();
+
+ union128i_d res_128;
+ union128i_w src1_128, src2_128;
+ int res_ref_128[4];
+
+ for (i = 0; i < 8; i++)
+ {
+ src1_128.a[i] = 1 + i;
+ src2_128.a[i] = 2 + 2*i + i * i;
+ }
+
+ for (i = 0; i < 4; i++)
+ res_128.a[i] = 0x7fffffff;
+
+ CALC (res_ref_128, res_128.a, src1_128.a, src2_128.a, 8);
+ res_128.x = _mm_dpwssd_avx_epi32 (res_128.x, src1_128.x, src2_128.x);
+ if (check_union128i_d (res_128, res_ref_128))
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-vpdpwssds-2.c b/gcc/testsuite/gcc.target/i386/avx-vpdpwssds-2.c
new file mode 100644
index 0000000..bc4395a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vpdpwssds-2.c
@@ -0,0 +1,70 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -mavxvnni" } */
+/* { dg-require-effective-target avxvnni } */
+
+#ifndef CHECK
+#define CHECK "avx-check.h"
+#endif
+
+#ifndef TEST
+#define TEST avx_test
+#endif
+
+#include CHECK
+
+static void
+CALC (int *r, int *dst, short *s1, short *s2, int size)
+{
+ short tempres[16];
+ for (int i = 0; i < size; i++) {
+ tempres[i] = ((int)(s1[i]) * (int)(s2[i]));
+ }
+ for (int i = 0; i < size / 2; i++) {
+ long long test = (long long)dst[i] + tempres[i*2] + tempres[i*2 + 1];
+ r[i] = test > 0x7FFFFFFF ? 0x7FFFFFFF : test;
+ }
+}
+
+void
+TEST (void)
+{
+ int i;
+ union256i_d res_256;
+ union256i_w src1_256, src2_256;
+ int res_ref_256[8];
+
+ if (!__builtin_cpu_supports ("avxvnni"))
+ return;
+
+ for (i = 0; i < 16; i++)
+ {
+ src1_256.a[i] = 1 + i;
+ src2_256.a[i] = 2 + 2*i + i * i;
+ }
+
+ for (i = 0; i < 8; i++)
+ res_256.a[i] = 0x7fffffff;
+
+ CALC (res_ref_256, res_256.a, src1_256.a, src2_256.a, 16);
+ res_256.x = _mm256_dpwssds_avx_epi32 (res_256.x, src1_256.x, src2_256.x);
+ if (check_union256i_d (res_256, res_ref_256))
+ abort ();
+
+ union128i_d res_128;
+ union128i_w src1_128, src2_128;
+ int res_ref_128[4];
+
+ for (i = 0; i < 8; i++)
+ {
+ src1_128.a[i] = 1 + i;
+ src2_128.a[i] = 2 + 2*i + i * i;
+ }
+
+ for (i = 0; i < 4; i++)
+ res_128.a[i] = 0x7fffffff;
+
+ CALC (res_ref_128, res_128.a, src1_128.a, src2_128.a, 8);
+ res_128.x = _mm_dpwssds_avx_epi32 (res_128.x, src1_128.x, src2_128.x);
+ if (check_union128i_d (res_128, res_ref_128))
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx2-vec-set-1.c b/gcc/testsuite/gcc.target/i386/avx2-vec-set-1.c
new file mode 100644
index 0000000..4c16ec5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx2-vec-set-1.c
@@ -0,0 +1,49 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx2 -O2 -mno-avx512f" } */
+/* { dg-final { scan-assembler-times {(?n)vpcmpeq[bwdq]} 12 } } */
+/* { dg-final { scan-assembler-times {(?n)vp?blendv} 12 } } */
+
+typedef char v32qi __attribute__ ((vector_size (32)));
+typedef char v16qi __attribute__ ((vector_size (16)));
+
+typedef short v16hi __attribute__ ((vector_size (32)));
+typedef short v8hi __attribute__ ((vector_size (16)));
+
+typedef int v8si __attribute__ ((vector_size (32)));
+typedef int v4si __attribute__ ((vector_size (16)));
+
+typedef long long v4di __attribute__ ((vector_size (32)));
+typedef long long v2di __attribute__ ((vector_size (16)));
+
+typedef float v8sf __attribute__ ((vector_size (32)));
+typedef float v4sf __attribute__ ((vector_size (16)));
+
+typedef double v4df __attribute__ ((vector_size (32)));
+typedef double v2df __attribute__ ((vector_size (16)));
+
+#define FOO(VTYPE, TYPE) \
+ VTYPE \
+ __attribute__ ((noipa)) \
+ foo_##VTYPE (VTYPE a, TYPE b, unsigned int c) \
+ { \
+ a[c] = b; \
+ return a; \
+ } \
+
+FOO (v16qi, char);
+FOO (v32qi, char);
+
+FOO (v8hi, short);
+FOO (v16hi, short);
+
+FOO (v4si, int);
+FOO (v8si, int);
+
+FOO (v2di, long long);
+FOO (v4di, long long);
+
+FOO (v4sf, float);
+FOO (v8sf, float);
+
+FOO (v2df, double);
+FOO (v4df, double);
diff --git a/gcc/testsuite/gcc.target/i386/avx2-vec-set-2.c b/gcc/testsuite/gcc.target/i386/avx2-vec-set-2.c
new file mode 100644
index 0000000..9086ef4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx2-vec-set-2.c
@@ -0,0 +1,50 @@
+/* { dg-do run } */
+/* { dg-require-effective-target avx2 } */
+/* { dg-options "-O2 -mavx2" } */
+
+
+#ifndef CHECK
+#define CHECK "avx2-check.h"
+#endif
+
+#ifndef TEST
+#define TEST avx2_test
+#endif
+
+#include CHECK
+
+#include "avx2-vec-set-1.c"
+
+#define CALC_TEST(vtype, type, N, idx) \
+do \
+ { \
+ int i,val = idx * idx - idx * 3 + 16; \
+ type res[N],exp[N]; \
+ vtype resv; \
+ for (i = 0; i < N; i++) \
+ { \
+ res[i] = i * i - i * 3 + 15; \
+ exp[i] = res[i]; \
+ } \
+ exp[idx] = val; \
+ resv = foo_##vtype (*(vtype *)&res[0], val, idx); \
+ for (i = 0; i < N; i++) \
+ { \
+ if (resv[i] != exp[i]) \
+ abort (); \
+ } \
+ } \
+while (0)
+
+static void
+TEST (void)
+{
+ CALC_TEST (v32qi, char, 32, 17);
+ CALC_TEST (v16qi, char, 16, 5);
+ CALC_TEST (v16hi, short, 16, 9);
+ CALC_TEST (v8hi, short, 8, 6);
+ CALC_TEST (v8si, int, 8, 3);
+ CALC_TEST (v4si, int, 4, 2);
+ CALC_TEST (v4di, long long, 4, 1);
+ CALC_TEST (v2di, long long, 2, 0);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512bitalg-pr97770-1.c b/gcc/testsuite/gcc.target/i386/avx512bitalg-pr97770-1.c
new file mode 100644
index 0000000..c83a477
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bitalg-pr97770-1.c
@@ -0,0 +1,60 @@
+/* PR target/97770 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx512bitalg -mavx512vl -mprefer-vector-width=512" } */
+/* Add xfail since no IFN for QI/HImode popcount */
+/* { dg-final { scan-assembler-times "vpopcntb\[ \\t\]+\[^\\n\\r\]*xmm" 1 {xfail *-*-*} } } */
+/* { dg-final { scan-assembler-times "vpopcntw\[ \\t\]+\[^\\n\\r\]*xmm" 1 {xfail *-*-*} } } */
+/* { dg-final { scan-assembler-times "vpopcntb\[ \\t\]+\[^\\n\\r\]*ymm" 1 {xfail *-*-*} } } */
+/* { dg-final { scan-assembler-times "vpopcntw\[ \\t\]+\[^\\n\\r\]*ymm" 1 {xfail *-*-*} } } */
+/* { dg-final { scan-assembler-times "vpopcntb\[ \\t\]+\[^\\n\\r\]*zmm" 1 {xfail *-*-*} } } */
+/* { dg-final { scan-assembler-times "vpopcntw\[ \\t\]+\[^\\n\\r\]*zmm" 1 {xfail *-*-*} } } */
+
+#include <immintrin.h>
+
+void
+__attribute__ ((noipa, optimize("-O3")))
+popcountb_128 (char * __restrict dest, char* src)
+{
+ for (int i = 0; i != 16; i++)
+ dest[i] = __builtin_popcount (src[i]);
+}
+
+void
+__attribute__ ((noipa, optimize("-O3")))
+popcountw_128 (short* __restrict dest, short* src)
+{
+ for (int i = 0; i != 8; i++)
+ dest[i] = __builtin_popcount (src[i]);
+}
+
+void
+__attribute__ ((noipa, optimize("-O3")))
+popcountb_256 (char * __restrict dest, char* src)
+{
+ for (int i = 0; i != 32; i++)
+ dest[i] = __builtin_popcount (src[i]);
+}
+
+void
+__attribute__ ((noipa, optimize("-O3")))
+popcountw_256 (short* __restrict dest, short* src)
+{
+ for (int i = 0; i != 16; i++)
+ dest[i] = __builtin_popcount (src[i]);
+}
+
+void
+__attribute__ ((noipa, optimize("-O3")))
+popcountb_512 (char * __restrict dest, char* src)
+{
+ for (int i = 0; i != 64; i++)
+ dest[i] = __builtin_popcount (src[i]);
+}
+
+void
+__attribute__ ((noipa, optimize("-O3")))
+popcountw_512 (short* __restrict dest, short* src)
+{
+ for (int i = 0; i != 32; i++)
+ dest[i] = __builtin_popcount (src[i]);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-pr96906-1.c b/gcc/testsuite/gcc.target/i386/avx512bw-pr96906-1.c
new file mode 100644
index 0000000..81d7e06
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-pr96906-1.c
@@ -0,0 +1,68 @@
+/* PR target/96906 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx512bw -mavx512vl -masm=att" } */
+/* { dg-final { scan-assembler-times {(?n)vpcmpub[ \t]*\$2} 9 } } */
+/* { dg-final { scan-assembler-times {(?n)vpcmpub[ \t]*\$6} 9 } } */
+/* { dg-final { scan-assembler-times {(?n)vpcmpuw[ \t]*\$2} 9 } } */
+/* { dg-final { scan-assembler-times {(?n)vpcmpuw[ \t]*\$6} 9 } } */
+
+
+#include<immintrin.h>
+
+#define FOO(LENGTH,SUFFIX,TYPE,UTYPE,RTYPE,PRED) \
+ __mmask##RTYPE \
+ foo_##LENGTH##_##TYPE##_##PRED (__m##LENGTH##i x, __m##LENGTH##i y) \
+ { \
+ return \
+ _mm##SUFFIX##_cmp_##TYPE##_mask (_mm##SUFFIX##_subs_##UTYPE (x, y), \
+ _mm##SUFFIX##_setzero_si##LENGTH (), \
+ PRED); \
+ } \
+
+FOO (128,, epi16, epu16, 8, 0);
+FOO (128,, epi16, epu16, 8, 4);
+
+FOO (128,, epu16, epu16, 8, 0);
+FOO (128,, epu16, epu16, 8, 2);
+FOO (128,, epu16, epu16, 8, 4);
+FOO (128,, epu16, epu16, 8, 6);
+
+FOO (256, 256, epi16, epu16, 16, 0);
+FOO (256, 256, epi16, epu16, 16, 4);
+
+FOO (256, 256, epu16, epu16, 16, 0);
+FOO (256, 256, epu16, epu16, 16, 2);
+FOO (256, 256, epu16, epu16, 16, 4);
+FOO (256, 256, epu16, epu16, 16, 6);
+
+FOO (512, 512, epi16, epu16, 32, 0);
+FOO (512, 512, epi16, epu16, 32, 4);
+
+FOO (512, 512, epu16, epu16, 32, 0);
+FOO (512, 512, epu16, epu16, 32, 2);
+FOO (512, 512, epu16, epu16, 32, 4);
+FOO (512, 512, epu16, epu16, 32, 6);
+
+FOO (128,, epi8, epu8, 16, 0);
+FOO (128,, epi8, epu8, 16, 4);
+
+FOO (128,, epu8, epu8, 16, 0);
+FOO (128,, epu8, epu8, 16, 2);
+FOO (128,, epu8, epu8, 16, 4);
+FOO (128,, epu8, epu8, 16, 6);
+
+FOO (256, 256, epi8, epu8, 32, 0);
+FOO (256, 256, epi8, epu8, 32, 4);
+
+FOO (256, 256, epu8, epu8, 32, 0);
+FOO (256, 256, epu8, epu8, 32, 2);
+FOO (256, 256, epu8, epu8, 32, 4);
+FOO (256, 256, epu8, epu8, 32, 6);
+
+FOO (512, 512, epi8, epu8, 64, 0);
+FOO (512, 512, epi8, epu8, 64, 4);
+
+FOO (512, 512, epu8, epu8, 64, 0);
+FOO (512, 512, epu8, epu8, 64, 2);
+FOO (512, 512, epu8, epu8, 64, 4);
+FOO (512, 512, epu8, epu8, 64, 6);
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vec-set-1.c b/gcc/testsuite/gcc.target/i386/avx512bw-vec-set-1.c
new file mode 100644
index 0000000..5cfbc85
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-vec-set-1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx512vl -mavx512bw -O2" } */
+/* { dg-final { scan-assembler-times {(?n)(?:vp?broadcast|vmovddup)} 36 } } */
+/* { dg-final { scan-assembler-times {(?n)vpcmp[bwdq][ \t]+\$0} 18 } } */
+
+typedef char v64qi __attribute__ ((vector_size (64)));
+typedef short v32hi __attribute__ ((vector_size (64)));
+typedef int v16si __attribute__ ((vector_size (64)));
+typedef long long v8di __attribute__ ((vector_size (64)));
+typedef float v16sf __attribute__ ((vector_size (64)));
+typedef double v8df __attribute__ ((vector_size (64)));
+
+#include "avx2-vec-set-1.c"
+
+FOO (v64qi, char);
+FOO (v32hi, short);
+FOO (v16si, int);
+FOO (v8di, long long);
+FOO (v16sf, float);
+FOO (v8df, double);
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vec-set-2.c b/gcc/testsuite/gcc.target/i386/avx512bw-vec-set-2.c
new file mode 100644
index 0000000..22e6418
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-vec-set-2.c
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+/* { dg-require-effective-target avx512bw } */
+/* { dg-options "-O2 -mavx512bw" } */
+
+
+#ifndef CHECK
+#define CHECK "avx512f-check.h"
+#endif
+
+#define AVX512BW
+
+#include CHECK
+
+#include "avx512bw-vec-set-1.c"
+
+#define CALC_TEST(vtype, type, N, idx) \
+do \
+ { \
+ int i,val = idx * idx - idx * 3 + 16; \
+ type res[N],exp[N]; \
+ vtype resv; \
+ for (i = 0; i < N; i++) \
+ { \
+ res[i] = i * i - i * 3 + 15; \
+ exp[i] = res[i]; \
+ } \
+ exp[idx] = val; \
+ resv = foo_##vtype (*(vtype *)&res[0], val, idx); \
+ for (i = 0; i < N; i++) \
+ { \
+ if (resv[i] != exp[i]) \
+ abort (); \
+ } \
+ } \
+while (0)
+
+static void
+test_512 (void)
+{
+ CALC_TEST (v64qi, char, 64, 50);
+ CALC_TEST (v32hi, short, 32, 30);
+ CALC_TEST (v16si, int, 16, 15);
+ CALC_TEST (v8di, long long, 8, 7);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu16-1.c b/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu16-1.c
index dcb8caa..8603a19 100644
--- a/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu16-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu16-1.c
@@ -1,8 +1,8 @@
/* { dg-do compile } */
/* { dg-options "-mavx512bw -mavx512vl -O2" } */
-/* { dg-final { scan-assembler-times "(?:vmovdqu16|vpblendmw)\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
-/* { dg-final { scan-assembler-times "(?:vmovdqu16|vpblendmw)\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
-/* { dg-final { scan-assembler-times "(?:vmovdqu16|vpblendmw)\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqu16\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqu16\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqu16\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqu16\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqu16\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqu16\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu8-1.c b/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu8-1.c
index a335bca..d1e3392 100644
--- a/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu8-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu8-1.c
@@ -1,8 +1,8 @@
/* { dg-do compile } */
/* { dg-options "-mavx512bw -mavx512vl -O2" } */
-/* { dg-final { scan-assembler-times "(?:vmovdqu8|vpblendmb)\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
-/* { dg-final { scan-assembler-times "(?:vmovdqu8|vpblendmb)\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
-/* { dg-final { scan-assembler-times "(?:vmovdqu8|vpblendmb)\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqu8\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqu8\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqu8\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqu8\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqu8\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqu8\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vec-set-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vec-set-2.c
new file mode 100644
index 0000000..8f2aa03
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vec-set-2.c
@@ -0,0 +1,42 @@
+/* { dg-do run } */
+/* { dg-require-effective-target avx512f } */
+/* { dg-options "-O2 -mavx512f -mno-avx512bw" } */
+
+
+#ifndef CHECK
+#define CHECK "avx512f-check.h"
+#endif
+
+#define AVX512F
+
+#include CHECK
+
+#include "avx512bw-vec-set-1.c"
+
+#define CALC_TEST(vtype, type, N, idx) \
+do \
+ { \
+ int i,val = idx * idx - idx * 3 + 16; \
+ type res[N],exp[N]; \
+ vtype resv; \
+ for (i = 0; i < N; i++) \
+ { \
+ res[i] = i * i - i * 3 + 15; \
+ exp[i] = res[i]; \
+ } \
+ exp[idx] = val; \
+ resv = foo_##vtype (*(vtype *)&res[0], val, idx); \
+ for (i = 0; i < N; i++) \
+ { \
+ if (resv[i] != exp[i]) \
+ abort (); \
+ } \
+ } \
+while (0)
+
+static void
+test_512 (void)
+{
+ CALC_TEST (v64qi, char, 64, 50);
+ CALC_TEST (v32hi, short, 32, 30);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vmovapd-1.c b/gcc/testsuite/gcc.target/i386/avx512f-vmovapd-1.c
index 7fc84b1..e869f70 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vmovapd-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vmovapd-1.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-mavx512f -O2" } */
-/* { dg-final { scan-assembler-times "(?:vmovapd|vblendmpd)\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vmovapd\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovapd\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovapd\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovapd\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vmovaps-1.c b/gcc/testsuite/gcc.target/i386/avx512f-vmovaps-1.c
index c2e2655..a7635a3 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vmovaps-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vmovaps-1.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-mavx512f -O2" } */
-/* { dg-final { scan-assembler-times "(?:vmovaps|vblendmps)\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vmovaps\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovaps\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovaps\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovaps\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vmovdqa32-1.c b/gcc/testsuite/gcc.target/i386/avx512f-vmovdqa32-1.c
index 8fb816c..b93727d 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vmovdqa32-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vmovdqa32-1.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-mavx512f -O2" } */
-/* { dg-final { scan-assembler-times "(?:vmovdqa32|vpblendmd)\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa32\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqa32\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqa32\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqa32\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vmovdqa64-1.c b/gcc/testsuite/gcc.target/i386/avx512f-vmovdqa64-1.c
index 4352b12..1c372c4 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vmovdqa64-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vmovdqa64-1.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-mavx512f -O2" } */
-/* { dg-final { scan-assembler-times "(?:vmovdqa64|vpblendmq)\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa64\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqa64\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqa64\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqa64\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%zmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vec-set-2.c b/gcc/testsuite/gcc.target/i386/avx512vl-vec-set-2.c
new file mode 100644
index 0000000..4f32742
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vec-set-2.c
@@ -0,0 +1,55 @@
+/* { dg-do run } */
+/* { dg-require-effective-target avx512bw } */
+/* { dg-require-effective-target avx512vl } */
+/* { dg-options "-O2 -mavx512bw -mavx512vl" } */
+
+
+#ifndef CHECK
+#define CHECK "avx512f-check.h"
+#endif
+
+#define AVX512VL
+#define AVX512BW
+
+#include CHECK
+
+#include "avx512bw-vec-set-1.c"
+
+#define CALC_TEST(vtype, type, N, idx) \
+do \
+ { \
+ int i,val = idx * idx - idx * 3 + 16; \
+ type res[N],exp[N]; \
+ vtype resv; \
+ for (i = 0; i < N; i++) \
+ { \
+ res[i] = i * i - i * 3 + 15; \
+ exp[i] = res[i]; \
+ } \
+ exp[idx] = val; \
+ resv = foo_##vtype (*(vtype *)&res[0], val, idx); \
+ for (i = 0; i < N; i++) \
+ { \
+ if (resv[i] != exp[i]) \
+ abort (); \
+ } \
+ } \
+while (0)
+
+static void
+test_256 (void)
+{
+ CALC_TEST (v32qi, char, 32, 17);
+ CALC_TEST (v16hi, short, 16, 9);
+ CALC_TEST (v8si, int, 8, 3);
+ CALC_TEST (v4di, long long, 4, 1);
+}
+
+static void
+test_128 (void)
+{
+ CALC_TEST (v16qi, char, 16, 5);
+ CALC_TEST (v8hi, short, 8, 6);
+ CALC_TEST (v4si, int, 4, 2);
+ CALC_TEST (v2di, long long, 2, 0);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vmovapd-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-vmovapd-1.c
index fd59660..89c3ebe 100644
--- a/gcc/testsuite/gcc.target/i386/avx512vl-vmovapd-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vmovapd-1.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-mavx512vl -O2" } */
-/* { dg-final { scan-assembler-times "(?:vmovapd|vblendmpd)\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
-/* { dg-final { scan-assembler-times "(?:vmovapd|vblendmpd)\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vmovapd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vmovapd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovapd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovapd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovapd\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vmovaps-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-vmovaps-1.c
index 455b1a9..2196ebb 100644
--- a/gcc/testsuite/gcc.target/i386/avx512vl-vmovaps-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vmovaps-1.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-mavx512vl -O2" } */
-/* { dg-final { scan-assembler-times "(?:vmovaps|vblendmps)\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
-/* { dg-final { scan-assembler-times "(?:vmovaps|vblendmps)\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vmovaps\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vmovaps\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovaps\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovaps\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovaps\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqa32-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqa32-1.c
index 5c6a3d0..9f991db 100644
--- a/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqa32-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqa32-1.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-mavx512vl -O2" } */
-/* { dg-final { scan-assembler-times "(?:vmovdqa32|vpblendmd)\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
-/* { dg-final { scan-assembler-times "(?:vmovdqa32|vpblendmd)\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa32\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa32\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqa32\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqa32\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqa32\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqa64-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqa64-1.c
index 592541a..d20b4a7 100644
--- a/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqa64-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqa64-1.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-mavx512vl -O2" } */
-/* { dg-final { scan-assembler-times "(?:vmovdqa64|vpblendmq)\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
-/* { dg-final { scan-assembler-times "(?:vmovdqa64|vpblendmq)\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa64\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vmovdqa64\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqa64\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqa64\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
/* { dg-final { scan-assembler-times "vmovdqa\[ \\t\]+\\(\[^\n\]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 2 { target nonpic } } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vnni-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-vnni-1a.c
index e63bc19..e63bc19 100644
--- a/gcc/testsuite/gcc.target/i386/avx512vl-vnni-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vnni-1a.c
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vnni-1b.c b/gcc/testsuite/gcc.target/i386/avx512vl-vnni-1b.c
new file mode 100644
index 0000000..067e631
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vnni-1b.c
@@ -0,0 +1,69 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx512vl -mavx512vnni -mavx512bw -mavxvnni -O2" } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vpdpbusd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\\n\\r]*%ymm\[0-9\]+\[^\\n\\r\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vpdpbusd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\\n\\r]*%ymm\[0-9\]+\[^\\n\\r\]*%ymm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vpdpbusd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\\n\\r]*%xmm\[0-9\]+\[^\\n\\r\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vpdpbusd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\\n\\r]*%xmm\[0-9\]+\[^\\n\\r\]*%xmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vpdpbusds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\\n\\r]*%ymm\[0-9\]+\[^\\n\\r\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vpdpbusds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\\n\\r]*%ymm\[0-9\]+\[^\\n\\r\]*%ymm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpbusds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vpdpbusds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\\n\\r]*%xmm\[0-9\]+\[^\\n\\r\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vpdpbusds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\\n\\r]*%xmm\[0-9\]+\[^\\n\\r\]*%xmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vpdpwssd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\\n\\r]*%ymm\[0-9\]+\[^\\n\\r\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vpdpwssd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\\n\\r]*%ymm\[0-9\]+\[^\\n\\r\]*%ymm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vpdpwssd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\\n\\r]*%xmm\[0-9\]+\[^\\n\\r\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vpdpwssd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\\n\\r]*%xmm\[0-9\]+\[^\\n\\r\]*%xmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vpdpwssds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\\n\\r]*%ymm\[0-9\]+\[^\\n\\r\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vpdpwssds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\\n\\r]*%ymm\[0-9\]+\[^\\n\\r\]*%ymm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\{vex\} vpdpwssds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vpdpwssds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\\n\\r]*%xmm\[0-9\]+\[^\\n\\r\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vpdpwssds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\\n\\r]*%xmm\[0-9\]+\[^\\n\\r\]*%xmm\[0-9\]+\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)" 1 } } */
+
+
+#include <immintrin.h>
+
+volatile __m256i x,y,z;
+volatile __m128i x_,y_,z_;
+volatile __mmask32 m;
+
+void extern
+avx512f_test (void)
+{
+ x = _mm256_dpbusd_epi32 (x, y, z);
+ x = _mm256_mask_dpbusd_epi32 (x, m, y, z);
+ x = _mm256_maskz_dpbusd_epi32 (m, x, y, z);
+
+ x_ = _mm_dpbusd_epi32 (x_, y_, z_);
+ x_ = _mm_mask_dpbusd_epi32 (x_, m, y_, z_);
+ x_ = _mm_maskz_dpbusd_epi32 (m, x_, y_, z_);
+
+ x = _mm256_dpbusds_epi32 (x, y, z);
+ x = _mm256_mask_dpbusds_epi32 (x, m, y, z);
+ x = _mm256_maskz_dpbusds_epi32 (m, x, y, z);
+
+ x_ = _mm_dpbusds_epi32 (x_, y_, z_);
+ x_ = _mm_mask_dpbusds_epi32 (x_, m, y_, z_);
+ x_ = _mm_maskz_dpbusds_epi32 (m, x_, y_, z_);
+
+ x = _mm256_dpwssd_epi32 (x, y, z);
+ x = _mm256_mask_dpwssd_epi32 (x, m, y, z);
+ x = _mm256_maskz_dpwssd_epi32 (m, x, y, z);
+
+ x_ = _mm_dpwssd_epi32 (x_, y_, z_);
+ x_ = _mm_mask_dpwssd_epi32 (x_, m, y_, z_);
+ x_ = _mm_maskz_dpwssd_epi32 (m, x_, y_, z_);
+
+ x = _mm256_dpwssds_epi32 (x, y, z);
+ x = _mm256_mask_dpwssds_epi32 (x, m, y, z);
+ x = _mm256_maskz_dpwssds_epi32 (m, x, y, z);
+
+ x_ = _mm_dpwssds_epi32 (x_, y_, z_);
+ x_ = _mm_mask_dpwssds_epi32 (x_, m, y_, z_);
+ x_ = _mm_maskz_dpwssds_epi32 (m, x_, y_, z_);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vnni-2.c b/gcc/testsuite/gcc.target/i386/avx512vl-vnni-2.c
new file mode 100644
index 0000000..d4b4635
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vnni-2.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-times "\\tvpdpbusd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\\tvpdpbusd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\\tvpdpbusds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\\tvpdpbusds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\\tvpdpwssd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\\tvpdpwssd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\\tvpdpwssds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\\tvpdpwssds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+
+
+#include <immintrin.h>
+
+volatile __m256i x,y,z;
+volatile __m128i x_,y_,z_;
+
+__attribute__((target("avx512vnni,avx512vl")))
+void
+avxvnni_test (void)
+{
+ x = _mm256_dpbusd_epi32 (x, y, z);
+ x_ = _mm_dpbusd_epi32 (x_, y_, z_);
+ x = _mm256_dpbusds_epi32 (x, y, z);
+ x_ = _mm_dpbusds_epi32 (x_, y_, z_);
+ x = _mm256_dpwssd_epi32 (x, y, z);
+ x_ = _mm_dpwssd_epi32 (x_, y_, z_);
+ x = _mm256_dpwssds_epi32 (x, y, z);
+ x_ = _mm_dpwssds_epi32 (x_, y_, z_);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vnni-3.c b/gcc/testsuite/gcc.target/i386/avx512vl-vnni-3.c
new file mode 100644
index 0000000..15a95ab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vnni-3.c
@@ -0,0 +1,47 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavxvnni -mavx512vnni -mavx512vl" } */
+/* { dg-final { scan-assembler-times "\\tvpdpbusd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\\tvpdpbusd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\\tvpdpbusds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\\tvpdpbusds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\\tvpdpwssd\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\\tvpdpwssd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\\tvpdpwssds\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+\[^\n\r]*%ymm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "\\tvpdpwssds\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+\[^\n\r]*%xmm\[0-9\]+(?:\n|\[ \\t\]+#)" 1 } } */
+
+
+#include <immintrin.h>
+
+volatile __m256i x,y,z;
+volatile __m128i x_,y_,z_;
+
+void
+avxvnni_test (void)
+{
+ register __m256i a __asm ("xmm16");
+ register __m128i a_ __asm ("xmm26");
+ a = _mm256_dpbusd_epi32 (x, y, z);
+ asm volatile ("" : "+v" (a));
+ x = a;
+ a_ = _mm_dpbusd_epi32 (x_, y_, z_);
+ asm volatile ("" : "+v" (a_));
+ x_ = a_;
+ a = _mm256_dpbusds_epi32 (x, y, z);
+ asm volatile ("" : "+v" (a));
+ x = a;
+ a_ = _mm_dpbusds_epi32 (x_, y_, z_);
+ asm volatile ("" : "+v" (a_));
+ x_ = a_;
+ a = _mm256_dpwssd_epi32 (x, y, z);
+ asm volatile ("" : "+v" (a));
+ x = a;
+ a_ = _mm_dpwssd_epi32 (x_, y_, z_);
+ asm volatile ("" : "+v" (a_));
+ x_ = a_;
+ a = _mm256_dpwssds_epi32 (x, y, z);
+ asm volatile ("" : "+v" (a));
+ x = a;
+ a_ = _mm_dpwssds_epi32 (x_, y_, z_);
+ asm volatile ("" : "+v" (a_));
+ x_ = a_;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512vnnivl-builtin.c b/gcc/testsuite/gcc.target/i386/avx512vnnivl-builtin.c
new file mode 100644
index 0000000..97aaba0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vnnivl-builtin.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -mno-avxvnni -mavx512vnni -mavx512vl" } */
+typedef int v8si __attribute__ ((vector_size (32)));
+v8si
+foo (v8si a, v8si b, v8si c)
+{
+ return __builtin_ia32_vpdpbusd_v8si (a, b, c);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512vpopcntdq-pr97770-1.c b/gcc/testsuite/gcc.target/i386/avx512vpopcntdq-pr97770-1.c
new file mode 100644
index 0000000..63bb00d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vpopcntdq-pr97770-1.c
@@ -0,0 +1,63 @@
+/* PR target/97770 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx512vpopcntdq -mavx512vl -mprefer-vector-width=512" } */
+/* { dg-final { scan-assembler-times "vpopcntd\[ \\t\]+\[^\\n\\r\]*xmm" 1 } } */
+/* { dg-final { scan-assembler-times "vpopcntd\[ \\t\]+\[^\\n\\r\]*ymm" 1 } } */
+/* { dg-final { scan-assembler-times "vpopcntd\[ \\t\]+\[^\\n\\r\]*zmm" 1 } } */
+/* Add xfail since current vectorizor cannot generate expected code for DImode popcount */
+/* { dg-final { scan-assembler-times "vpopcntq\[ \\t\]+\[^\\n\\r\]*xmm" 1 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "vpopcntq\[ \\t\]+\[^\\n\\r\]*ymm" 1 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "vpopcntq\[ \\t\]+\[^\\n\\r\]*zmm" 1 { xfail *-*-* } } } */
+#ifndef AVX512VPOPCNTQ_H_INCLUDED
+#define AVX512VPOPCNTQ_H_INCLUDED
+
+#include <immintrin.h>
+
+void
+__attribute__ ((noipa, optimize("-O3")))
+popcountd_128 (int* __restrict dest, int* src)
+{
+ for (int i = 0; i != 4; i++)
+ dest[i] = __builtin_popcount (src[i]);
+}
+
+void
+__attribute__ ((noipa, optimize("-O3")))
+popcountq_128 (long long* __restrict dest, long long* src)
+{
+ for (int i = 0; i != 2; i++)
+ dest[i] = __builtin_popcountll (src[i]);
+}
+
+void
+__attribute__ ((noipa, optimize("-O3")))
+popcountd_256 (int* __restrict dest, int* src)
+{
+ for (int i = 0; i != 8; i++)
+ dest[i] = __builtin_popcount (src[i]);
+}
+
+void
+__attribute__ ((noipa, optimize("-O3")))
+popcountq_256 (long long* __restrict dest, long long* src)
+{
+ for (int i = 0; i != 4; i++)
+ dest[i] = __builtin_popcountll (src[i]);
+}
+
+void
+__attribute__ ((noipa, optimize("-O3")))
+popcountd_512 (int* __restrict dest, int* src)
+{
+ for (int i = 0; i != 16; i++)
+ dest[i] = __builtin_popcount (src[i]);
+}
+
+void
+__attribute__ ((noipa, optimize("-O3")))
+popcountq_512 (long long* __restrict dest, long long* src)
+{
+ for (int i = 0; i != 8; i++)
+ dest[i] = __builtin_popcountll (src[i]);
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/i386/avx512vpopcntdq-pr97770-2.c b/gcc/testsuite/gcc.target/i386/avx512vpopcntdq-pr97770-2.c
new file mode 100644
index 0000000..339dc29
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vpopcntdq-pr97770-2.c
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -mavx512vpopcntdq" } */
+
+#define AVX512VPOPCNTDQ
+
+#include "avx512f-helper.h"
+#include "avx512vpopcntdq-pr97770-1.c"
+
+#define SIZE_D AVX512F_LEN / 32
+#define SIZE_Q AVX512F_LEN / 64
+
+
+#define RTEST(TYPE, LEN, SIZE, MODE) \
+ do \
+ { \
+ TYPE res[SIZE], src[SIZE], res_ref[SIZE], v; \
+ int i, j, ret; \
+ for (i = 0; i < SIZE; i++) \
+ { \
+ v = src[i] = i * 2 + 3; \
+ ret = 0; \
+ for (j = 0; j < sizeof(v) * 8; j++) \
+ if ((v & ((TYPE)1 << (TYPE) j))) \
+ ret++; \
+ res_ref[i] = ret; \
+ } \
+ EVAL(popcount, MODE, LEN) (res, src); \
+ for (i = 0; i < SIZE; i++) \
+ if (res[i] != res_ref[i]) \
+ abort (); \
+ } \
+ while (0)
+
+void
+TEST (void)
+{
+ RTEST (long long, AVX512F_LEN, SIZE_Q, q_);
+ RTEST (int, AVX512F_LEN, SIZE_D, d_);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512vpopcntdqvl-pr97770-1.c b/gcc/testsuite/gcc.target/i386/avx512vpopcntdqvl-pr97770-1.c
new file mode 100644
index 0000000..7a34f15
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vpopcntdqvl-pr97770-1.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -mavx512vpopcntdq -mavx512vl" } */
+
+#define AVX512VL
+#define AVX512F_LEN 256
+#define AVX512F_LEN_HALF 128
+#include "avx512vpopcntdq-pr97770-2.c"
+
+#undef AVX512F_LEN
+#undef AVX512F_LEN_HALF
+
+#define AVX512F_LEN 128
+#define AVX512F_LEN_HALF 128
+#include "avx512vpopcntdq-pr97770-2.c"
diff --git a/gcc/testsuite/gcc.target/i386/avxvnni-builtin.c b/gcc/testsuite/gcc.target/i386/avxvnni-builtin.c
new file mode 100644
index 0000000..893a62a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avxvnni-builtin.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -mavxvnni -mno-avx512vnni" } */
+typedef int v8si __attribute__ ((vector_size (32)));
+v8si
+foo (v8si a, v8si b, v8si c)
+{
+ return __builtin_ia32_vpdpbusd_v8si (a, b, c);
+}
diff --git a/gcc/testsuite/gcc.target/i386/fma4-256-maccXX.c b/gcc/testsuite/gcc.target/i386/fma4-256-maccXX.c
index 134200a..ee0ddf1 100644
--- a/gcc/testsuite/gcc.target/i386/fma4-256-maccXX.c
+++ b/gcc/testsuite/gcc.target/i386/fma4-256-maccXX.c
@@ -17,7 +17,6 @@ union
double d[NUM * 4];
} dst, res, src1, src2, src3;
-
/* Note that in macc*,msub*,mnmacc* and mnsub* instructions, the intermdediate
product is not rounded, only the addition is rounded. */
@@ -56,7 +55,7 @@ check_maccps ()
if (dst.f[i + j] != res.f[i + j])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static int
@@ -70,7 +69,7 @@ check_maccpd ()
if (dst.d[i + j] != res.d[i + j])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static void
diff --git a/gcc/testsuite/gcc.target/i386/fma4-256-msubXX.c b/gcc/testsuite/gcc.target/i386/fma4-256-msubXX.c
index d6cafb4..0251eb2 100644
--- a/gcc/testsuite/gcc.target/i386/fma4-256-msubXX.c
+++ b/gcc/testsuite/gcc.target/i386/fma4-256-msubXX.c
@@ -55,7 +55,7 @@ check_msubps ()
if (dst.f[i + j] != res.f[i + j])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static int
@@ -69,7 +69,7 @@ check_msubpd ()
if (dst.d[i + j] != res.d[i + j])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static void
@@ -92,5 +92,4 @@ fma4_test (void)
if (check_msubpd ())
abort ();
-
}
diff --git a/gcc/testsuite/gcc.target/i386/fma4-256-nmaccXX.c b/gcc/testsuite/gcc.target/i386/fma4-256-nmaccXX.c
index 261f302..d9671f3 100644
--- a/gcc/testsuite/gcc.target/i386/fma4-256-nmaccXX.c
+++ b/gcc/testsuite/gcc.target/i386/fma4-256-nmaccXX.c
@@ -55,7 +55,7 @@ check_nmaccps ()
if (dst.f[i + j] != res.f[i + j])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static int
@@ -69,7 +69,7 @@ check_nmaccpd ()
if (dst.d[i + j] != res.d[i + j])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static void
@@ -92,5 +92,4 @@ fma4_test (void)
if (check_nmaccpd ())
abort ();
-
}
diff --git a/gcc/testsuite/gcc.target/i386/fma4-256-nmsubXX.c b/gcc/testsuite/gcc.target/i386/fma4-256-nmsubXX.c
index ccbdf0e..385cd95 100644
--- a/gcc/testsuite/gcc.target/i386/fma4-256-nmsubXX.c
+++ b/gcc/testsuite/gcc.target/i386/fma4-256-nmsubXX.c
@@ -55,7 +55,7 @@ check_nmsubps ()
if (dst.f[i + j] != res.f[i + j])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static int
@@ -69,7 +69,7 @@ check_nmsubpd ()
if (dst.d[i + j] != res.d[i + j])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static void
@@ -92,5 +92,4 @@ fma4_test (void)
if (check_nmsubpd (&dst.y[i], &src1.d[i * 2], &src2.d[i * 2], &src3.d[i * 2]))
abort ();
-
}
diff --git a/gcc/testsuite/gcc.target/i386/fma4-maccXX.c b/gcc/testsuite/gcc.target/i386/fma4-maccXX.c
index 4b4c005..d401d4e 100644
--- a/gcc/testsuite/gcc.target/i386/fma4-maccXX.c
+++ b/gcc/testsuite/gcc.target/i386/fma4-maccXX.c
@@ -17,7 +17,6 @@ union
double d[NUM * 2];
} dst, res, src1, src2, src3;
-
/* Note that in macc*,msub*,mnmacc* and mnsub* instructions, the intermdediate
product is not rounded, only the addition is rounded. */
@@ -56,7 +55,7 @@ check_maccps ()
if (dst.f[i + j] != res.f[i + j])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static int
@@ -70,7 +69,7 @@ check_maccpd ()
if (dst.d[i + j] != res.d[i + j])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
@@ -84,7 +83,7 @@ check_maccss ()
if (dst.f[i] != res.f[i])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static int
@@ -97,7 +96,7 @@ check_maccsd ()
if (dst.d[i] != res.d[i])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static void
@@ -132,5 +131,4 @@ fma4_test (void)
if (check_maccsd ())
abort ();
-
}
diff --git a/gcc/testsuite/gcc.target/i386/fma4-msubXX.c b/gcc/testsuite/gcc.target/i386/fma4-msubXX.c
index eed7558..192cb5d 100644
--- a/gcc/testsuite/gcc.target/i386/fma4-msubXX.c
+++ b/gcc/testsuite/gcc.target/i386/fma4-msubXX.c
@@ -55,7 +55,7 @@ check_msubps ()
if (dst.f[i + j] != res.f[i + j])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static int
@@ -69,10 +69,9 @@ check_msubpd ()
if (dst.d[i + j] != res.d[i + j])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
-
static int
check_msubss ()
{
@@ -83,7 +82,7 @@ check_msubss ()
if (dst.f[i] != res.f[i])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static int
@@ -96,7 +95,7 @@ check_msubsd ()
if (dst.d[i] != res.d[i])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static void
diff --git a/gcc/testsuite/gcc.target/i386/fma4-nmaccXX.c b/gcc/testsuite/gcc.target/i386/fma4-nmaccXX.c
index 9abf746..7a89fb0 100644
--- a/gcc/testsuite/gcc.target/i386/fma4-nmaccXX.c
+++ b/gcc/testsuite/gcc.target/i386/fma4-nmaccXX.c
@@ -55,7 +55,7 @@ check_nmaccps ()
if (dst.f[i + j] != res.f[i + j])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static int
@@ -69,10 +69,9 @@ check_nmaccpd ()
if (dst.d[i + j] != res.d[i + j])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
-
static int
check_nmaccss ()
{
@@ -83,7 +82,7 @@ check_nmaccss ()
if (dst.f[i] != res.f[i])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static int
@@ -96,7 +95,7 @@ check_nmaccsd ()
if (dst.d[i] != res.d[i])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static void
@@ -112,7 +111,6 @@ fma4_test (void)
if (check_nmaccps ())
abort ();
-
for (i = 0; i < NUM; i++)
dst.x[i] = _mm_nmacc_ss (src1.x[i], src2.x[i], src3.x[i]);
@@ -126,12 +124,10 @@ fma4_test (void)
if (check_nmaccpd ())
abort ();
-
for (i = 0; i < NUM; i++)
dst.y[i] = _mm_nmacc_sd (src1.y[i], src2.y[i], src3.y[i]);
if (check_nmaccsd ())
abort ();
-
}
diff --git a/gcc/testsuite/gcc.target/i386/fma4-nmsubXX.c b/gcc/testsuite/gcc.target/i386/fma4-nmsubXX.c
index 85fbecd..c0bce41 100644
--- a/gcc/testsuite/gcc.target/i386/fma4-nmsubXX.c
+++ b/gcc/testsuite/gcc.target/i386/fma4-nmsubXX.c
@@ -55,7 +55,7 @@ check_nmsubps ()
if (dst.f[i + j] != res.f[i + j])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static int
@@ -69,10 +69,9 @@ check_nmsubpd ()
if (dst.d[i + j] != res.d[i + j])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
-
static int
check_nmsubss ()
{
@@ -83,7 +82,7 @@ check_nmsubss ()
if (dst.f[i] != res.f[i])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static int
@@ -96,7 +95,7 @@ check_nmsubsd ()
if (dst.d[i] != res.d[i])
check_fails++;
}
- return check_fails++;
+ return check_fails;
}
static void
@@ -111,7 +110,6 @@ fma4_test (void)
if (check_nmsubps (&dst.x[i], &src1.f[i * 4], &src2.f[i * 4], &src3.f[i * 4]))
abort ();
-
for (i = 0; i < NUM; i++)
dst.x[i] = _mm_nmsub_ss (src1.x[i], src2.x[i], src3.x[i]);
@@ -126,12 +124,10 @@ fma4_test (void)
if (check_nmsubpd (&dst.y[i], &src1.d[i * 2], &src2.d[i * 2], &src3.d[i * 2]))
abort ();
-
for (i = 0; i < NUM; i++)
dst.y[i] = _mm_nmsub_sd (src1.y[i], src2.y[i], src3.y[i]);
if (check_nmsubsd (&dst.y[i], &src1.d[i * 2], &src2.d[i * 2], &src3.d[i * 2]))
abort ();
-
}
diff --git a/gcc/testsuite/gcc.target/i386/funcspec-56.inc b/gcc/testsuite/gcc.target/i386/funcspec-56.inc
index b8e3b1f..395a21c 100644
--- a/gcc/testsuite/gcc.target/i386/funcspec-56.inc
+++ b/gcc/testsuite/gcc.target/i386/funcspec-56.inc
@@ -78,6 +78,7 @@ extern void test_uintr (void) __attribute__((__target__("uintr")));
extern void test_hreset (void) __attribute__((__target__("hreset")));
extern void test_keylocker (void) __attribute__((__target__("kl")));
extern void test_widekl (void) __attribute__((__target__("widekl")));
+extern void test_avxvnni (void) __attribute__((__target__("avxvnni")));
extern void test_no_sgx (void) __attribute__((__target__("no-sgx")));
extern void test_no_avx5124fmaps(void) __attribute__((__target__("no-avx5124fmaps")));
@@ -157,6 +158,7 @@ extern void test_no_uintr (void) __attribute__((__target__("no-uintr")));
extern void test_no_hreset (void) __attribute__((__target__("no-hreset")));
extern void test_no_keylocker (void) __attribute__((__target__("no-kl")));
extern void test_no_widekl (void) __attribute__((__target__("no-widekl")));
+extern void test_no_avxvnni (void) __attribute__((__target__("no-avxvnni")));
extern void test_arch_nocona (void) __attribute__((__target__("arch=nocona")));
extern void test_arch_core2 (void) __attribute__((__target__("arch=core2")));
diff --git a/gcc/testsuite/gcc.target/i386/pr31799.c b/gcc/testsuite/gcc.target/i386/pr31799.c
new file mode 100644
index 0000000..c72c4ea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr31799.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void
+foo (int x, int *y, int *z)
+{
+ *z = ++x;
+ if (x != 0)
+ *y = 1;
+}
+
+/* { dg-final { scan-assembler-not "test" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr92180.c b/gcc/testsuite/gcc.target/i386/pr92180.c
new file mode 100644
index 0000000..177af74
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr92180.c
@@ -0,0 +1,9 @@
+/* PR rtl-optimization/92180 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned int foo() {
+ return __builtin_ia32_rdtsc();
+}
+
+/* { dg-final { scan-assembler-not "sal" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr96906-1.c b/gcc/testsuite/gcc.target/i386/pr96906-1.c
new file mode 100644
index 0000000..b1b41bf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr96906-1.c
@@ -0,0 +1,62 @@
+/* PR target/96906 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx2 -mno-avx512f" } */
+/* { dg-final { scan-assembler-times "\tvpminub\[^\n\r]*xmm" 2 } } */
+/* { dg-final { scan-assembler-times "\tvpminuw\[^\n\r]*xmm" 2 } } */
+/* { dg-final { scan-assembler-times "\tvpminub\[^\n\r]*ymm" 2 } } */
+/* { dg-final { scan-assembler-times "\tvpminuw\[^\n\r]*ymm" 2 } } */
+/* { dg-final { scan-assembler-times "\tvpcmpeqb\[^\n\r]*xmm" 2 } } */
+/* { dg-final { scan-assembler-times "\tvpcmpeqw\[^\n\r]*xmm" 2 } } */
+/* { dg-final { scan-assembler-times "\tvpcmpeqb\[^\n\r]*ymm" 2 } } */
+/* { dg-final { scan-assembler-times "\tvpcmpeqw\[^\n\r]*ymm" 2 } } */
+/* { dg-final { scan-assembler-not "\tvpsubus\[bw]" } } */
+
+#include <x86intrin.h>
+
+__m128i
+f1 (__m128i x, __m128i y)
+{
+ return _mm_cmpeq_epi16 (_mm_subs_epu16 (x, y), _mm_setzero_si128 ());
+}
+
+__m128i
+f2 (__m128i x, __m128i y)
+{
+ return _mm_cmpeq_epi16 (_mm_min_epu16 (x, y), x);
+}
+
+__m128i
+f3 (__m128i x, __m128i y)
+{
+ return _mm_cmpeq_epi8 (_mm_subs_epu8 (x, y), _mm_setzero_si128 ());
+}
+
+__m128i
+f4 (__m128i x, __m128i y)
+{
+ return _mm_cmpeq_epi8 (_mm_min_epu8 (x, y), x);
+}
+
+__m256i
+f5 (__m256i x, __m256i y)
+{
+ return _mm256_cmpeq_epi16 (_mm256_subs_epu16 (x, y), _mm256_setzero_si256 ());
+}
+
+__m256i
+f6 (__m256i x, __m256i y)
+{
+ return _mm256_cmpeq_epi16 (_mm256_min_epu16 (x, y), x);
+}
+
+__m256i
+f7 (__m256i x, __m256i y)
+{
+ return _mm256_cmpeq_epi8 (_mm256_subs_epu8 (x, y), _mm256_setzero_si256 ());
+}
+
+__m256i
+f8 (__m256i x, __m256i y)
+{
+ return _mm256_cmpeq_epi8 (_mm256_min_epu8 (x, y), x);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr97282.c b/gcc/testsuite/gcc.target/i386/pr97282.c
index 6fb10c8..94ce50b 100644
--- a/gcc/testsuite/gcc.target/i386/pr97282.c
+++ b/gcc/testsuite/gcc.target/i386/pr97282.c
@@ -18,8 +18,8 @@ foo (T x)
unsigned long ret = 0;
while (x > 0)
{
- ret = ret + x % 10;
- x = x / 10;
+ ret = ret + x % 123456;
+ x = x / 123456;
}
return ret;
}
diff --git a/gcc/testsuite/gcc.target/i386/pr97642-1.c b/gcc/testsuite/gcc.target/i386/pr97642-1.c
new file mode 100644
index 0000000..f511440
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr97642-1.c
@@ -0,0 +1,41 @@
+/* PR target/97642 */
+/* { dg-do compile } */
+/* { dg-options "-mavx512vl -O2" } */
+/* { dg-final { scan-assembler-not { k[0-8] } } } */
+
+#include <immintrin.h>
+__m128i
+foo1 (__m128i src, void const* P)
+{
+ return _mm_mask_loadu_epi32 (src, 15, P);
+}
+
+__m256i
+foo2 (__m256i src, void const* P)
+{
+ return _mm256_mask_loadu_epi32 (src, 255, P);
+}
+
+__m512i
+foo3 (__m512i src, void const* P)
+{
+ return _mm512_mask_loadu_epi32 (src, 65535 , P);
+}
+
+__m128i
+foo4 (__m128i src, void const* P)
+{
+ return _mm_mask_loadu_epi32 (src, -1, P);
+}
+
+__m256i
+foo5 (__m256i src, void const* P)
+{
+ return _mm256_mask_loadu_epi32 (src, -1, P);
+}
+
+__m512i
+foo6 (__m512i src, void const* P)
+{
+ return _mm512_mask_loadu_epi32 (src, -1 , P);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr97642-2.c b/gcc/testsuite/gcc.target/i386/pr97642-2.c
new file mode 100644
index 0000000..53a6154
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr97642-2.c
@@ -0,0 +1,77 @@
+/* PR target/97642 */
+/* { dg-do run { target *-*-linux* } } */
+/* { dg-options "-O2 -mavx512dq -mavx512vl -mavx512bw" } */
+/* { dg-require-effective-target avx512vl } */
+/* { dg-require-effective-target avx512dq } */
+/* { dg-require-effective-target avx512bw } */
+
+#include <assert.h>
+#include <immintrin.h>
+#include <stdint.h>
+#include <sys/mman.h>
+
+#define N 5
+
+// Faults with GCC because usage of vpblendd
+__m256i __attribute__((noinline)) mask_load(uint32_t * arr) {
+ __m256i tmp;
+ return _mm256_mask_loadu_epi32(tmp, (1 << N) - 1, arr);
+}
+
+// Faults
+__m256i __attribute__((noinline)) blend_load_asm(uint32_t * arr) {
+ __m256i tmp = _mm256_set1_epi64x(0);
+ asm volatile("vpblendd %[m], (%[arr]), %[tmp], %[tmp]\n\t"
+ : [ tmp ] "+x"(tmp)
+ : [ arr ] "r"(arr), [ m ] "i"(((1 << N) - 1))
+ :);
+ return tmp;
+}
+
+// Does not fault
+__m256i __attribute__((noinline)) mask_load_asm(uint32_t * arr) {
+ __m256i tmp;
+ asm volatile(
+ "movb %[m], %%al\n\t"
+ "kmovb %%eax, %%k1\n\t"
+ "vmovdqu32 (%[arr]), %[tmp] %{%%k1} %{z%}\n\t"
+ : [ tmp ] "+x"(tmp)
+ : [ arr ] "r"(arr), [ m ] "i"(((1 << N) - 1))
+ : "eax", "k1");
+ return tmp;
+}
+
+
+void __attribute__((noinline)) mask_store(uint32_t * arr, __m256i v) {
+ return _mm256_mask_storeu_epi32(arr, (1 << N) - 1, v);
+}
+
+
+#define NPAGES (2)
+#define END_OF_PAGE (1024 - N)
+
+#ifndef LOAD_METHOD
+#define LOAD_METHOD mask_load // mask_load_asm does not fault
+#endif
+
+
+int
+main() {
+ if (!(__builtin_cpu_supports ("avx512dq")
+ && __builtin_cpu_supports ("avx512vl")
+ && __builtin_cpu_supports ("avx512bw")))
+ return 0;
+
+ uint32_t * addr =
+ (uint32_t *)mmap(NULL, NPAGES * 4096, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+
+ for (uint32_t i = 0; i < NPAGES; i += 2) {
+
+ uint32_t page_offset = 1024 * i + END_OF_PAGE;
+ uint32_t next_page_offset = 1024 * (i + 1);
+
+ assert(!mprotect(addr + next_page_offset, 4096, PROT_NONE));
+ mask_store(addr + page_offset, LOAD_METHOD(addr + page_offset));
+ }
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr97777.c b/gcc/testsuite/gcc.target/i386/pr97777.c
new file mode 100644
index 0000000..fcefc09
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr97777.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O -fzero-call-used-regs=used -ffinite-math-only" } */
+
+float
+foo (void)
+{
+ return __builtin_fmod (0, 0);
+}
+
diff --git a/gcc/testsuite/gcc.target/i386/pr97873-1.c b/gcc/testsuite/gcc.target/i386/pr97873-1.c
new file mode 100644
index 0000000..48c1d27
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr97873-1.c
@@ -0,0 +1,12 @@
+/* PR target/97873 */
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -mavx512vl -mstv -mno-stackrealign" } */
+/* { dg-final { scan-assembler "pabsq" } } */
+
+extern long long z;
+
+void
+foo (long long x)
+{
+ z = (x < 0) ? -x : x;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr97873-2.c b/gcc/testsuite/gcc.target/i386/pr97873-2.c
new file mode 100644
index 0000000..22519ab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr97873-2.c
@@ -0,0 +1,23 @@
+/* PR target/97873 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2 -mno-sse3 -mtune=generic" } */
+
+#ifdef __SIZEOF_INT128__
+typedef __int128_t T;
+#else
+typedef long long T;
+#endif
+
+T test_abs (T x)
+{
+ return (x < 0) ? -x : x;
+}
+
+/* { dg-final { scan-assembler "adc" } } */
+
+T test_smin (T x, T y)
+{
+ return (x < y) ? x : y;
+}
+
+/* { dg-final { scan-assembler "sbb" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr97873-3.c b/gcc/testsuite/gcc.target/i386/pr97873-3.c
new file mode 100644
index 0000000..e682f14
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr97873-3.c
@@ -0,0 +1,27 @@
+/* PR target/97873 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2 -mno-sse3 -mtune=generic" } */
+
+short test_absw (short x)
+{
+ return (x < 0) ? -x : x;
+}
+
+short test_sminw (short x, short y)
+{
+ return (x < y) ? x : y;
+}
+
+/* { dg-final { scan-assembler-not "movswl" } } */
+
+char test_absb (char x)
+{
+ return (x < 0) ? -x : x;
+}
+
+char test_sminb (char x, char y)
+{
+ return (x < y) ? x : y;
+}
+
+/* { dg-final { scan-assembler-not "movsbl" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr97873.c b/gcc/testsuite/gcc.target/i386/pr97873.c
new file mode 100644
index 0000000..ec598f9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr97873.c
@@ -0,0 +1,9 @@
+/* PR target/97873 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2 -mno-sse3 -mtune=generic" } */
+/* { dg-final { scan-assembler-not "test|cmp" } } */
+
+int foo (int x)
+{
+ return (x < 0) ? -x : x;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr97887.c b/gcc/testsuite/gcc.target/i386/pr97887.c
new file mode 100644
index 0000000..b457f05
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr97887.c
@@ -0,0 +1,15 @@
+/* PR target/97887 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2 -mfpmath=sse" } */
+
+float f (float a)
+{
+ return -a / a;
+}
+
+double d (double a)
+{
+ return -a / a;
+}
+
+/* { dg-final { scan-assembler-not "fchs" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr97950.c b/gcc/testsuite/gcc.target/i386/pr97950.c
new file mode 100644
index 0000000..277311d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr97950.c
@@ -0,0 +1,153 @@
+/* PR target/95950 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=generic" } */
+/* { dg-final { scan-assembler-times "\tseta\t" 4 } } */
+/* { dg-final { scan-assembler-times "\tseto\t" 16 } } */
+/* { dg-final { scan-assembler-times "\tsetc\t" 4 } } */
+/* { dg-final { scan-assembler-not "\tjn?a\t" } } */
+/* { dg-final { scan-assembler-not "\tjn?o\t" } } */
+/* { dg-final { scan-assembler-not "\tjn?c\t" } } */
+
+char
+f1 (short a, short b)
+{
+ return __builtin_mul_overflow_p (a, b, (short) 0);
+}
+
+char
+f2 (short a, short b)
+{
+ return __builtin_add_overflow_p (a, b, (short) 0);
+}
+
+char
+f3 (short a, short b)
+{
+ return __builtin_sub_overflow_p (a, b, (short) 0);
+}
+
+char
+f4 (unsigned short a, unsigned short b)
+{
+ return __builtin_mul_overflow_p (a, b, (unsigned short) 0);
+}
+
+char
+f5 (unsigned short a, unsigned short b)
+{
+ return __builtin_add_overflow_p (a, b, (unsigned short) 0);
+}
+
+char
+f6 (unsigned short a, unsigned short b)
+{
+ return __builtin_sub_overflow_p (a, b, (unsigned short) 0);
+}
+
+char
+f7 (short a, short b)
+{
+ return __builtin_mul_overflow_p (a, b, (short) 0);
+}
+
+char
+f8 (short a, short b)
+{
+ return __builtin_add_overflow_p (a, b, (short) 0);
+}
+
+char
+f9 (short a, short b)
+{
+ return __builtin_sub_overflow_p (a, b, (short) 0);
+}
+
+char
+f10 (unsigned short a, unsigned short b)
+{
+ return __builtin_mul_overflow_p (a, b, (unsigned short) 0);
+}
+
+char
+f11 (unsigned short a, unsigned short b)
+{
+ return __builtin_add_overflow_p (a, b, (unsigned short) 0);
+}
+
+char
+f12 (unsigned short a, unsigned short b)
+{
+ return __builtin_sub_overflow_p (a, b, (unsigned short) 0);
+}
+
+unsigned short
+f13 (short a, short b)
+{
+ return __builtin_mul_overflow_p (a, b, (short) 0);
+}
+
+unsigned short
+f14 (short a, short b)
+{
+ return __builtin_add_overflow_p (a, b, (short) 0);
+}
+
+unsigned short
+f15 (short a, short b)
+{
+ return __builtin_sub_overflow_p (a, b, (short) 0);
+}
+
+unsigned short
+f16 (unsigned short a, unsigned short b)
+{
+ return __builtin_mul_overflow_p (a, b, (unsigned short) 0);
+}
+
+unsigned short
+f17 (unsigned short a, unsigned short b)
+{
+ return __builtin_add_overflow_p (a, b, (unsigned short) 0);
+}
+
+unsigned short
+f18 (unsigned short a, unsigned short b)
+{
+ return __builtin_sub_overflow_p (a, b, (unsigned short) 0);
+}
+
+unsigned short
+f19 (short a, short b)
+{
+ return __builtin_mul_overflow_p (a, b, (short) 0);
+}
+
+unsigned short
+f20 (short a, short b)
+{
+ return __builtin_add_overflow_p (a, b, (short) 0);
+}
+
+unsigned short
+f21 (short a, short b)
+{
+ return __builtin_sub_overflow_p (a, b, (short) 0);
+}
+
+unsigned short
+f22 (unsigned short a, unsigned short b)
+{
+ return __builtin_mul_overflow_p (a, b, (unsigned short) 0);
+}
+
+unsigned short
+f23 (unsigned short a, unsigned short b)
+{
+ return __builtin_add_overflow_p (a, b, (unsigned short) 0);
+}
+
+unsigned short
+f24 (unsigned short a, unsigned short b)
+{
+ return __builtin_sub_overflow_p (a, b, (unsigned short) 0);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr98063.c b/gcc/testsuite/gcc.target/i386/pr98063.c
new file mode 100644
index 0000000..f76435a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr98063.c
@@ -0,0 +1,13 @@
+/* PR target/98063 */
+/* { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-O2 -fpic -mcmodel=large -fno-plt -save-temps" } */
+/* { dg-final { scan-assembler-not "puts@GOTPCREL" } } */
+
+int
+main ()
+{
+ __builtin_puts ("Hello, world!");
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr98079.c b/gcc/testsuite/gcc.target/i386/pr98079.c
new file mode 100644
index 0000000..8de0ec3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr98079.c
@@ -0,0 +1,13 @@
+/* PR target/98079 */
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -march=pentium3" } */
+
+typedef __UINT8_TYPE__ uint8_t;
+
+uint8_t foo (uint8_t x)
+{
+ if (x & 0x80)
+ x = -x;
+
+ return x;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr98086.c b/gcc/testsuite/gcc.target/i386/pr98086.c
new file mode 100644
index 0000000..254a3b9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr98086.c
@@ -0,0 +1,17 @@
+/* PR target/98086 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+#ifdef __x86_64__
+typedef __int128 T;
+#else
+typedef long long T;
+#endif
+
+T x;
+
+void
+foo (void)
+{
+ __asm ("" : "=@ccc" (x));
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse-12.c b/gcc/testsuite/gcc.target/i386/sse-12.c
index f1e05e6..375d4d1 100644
--- a/gcc/testsuite/gcc.target/i386/sse-12.c
+++ b/gcc/testsuite/gcc.target/i386/sse-12.c
@@ -3,7 +3,7 @@
popcntintrin.h gfniintrin.h and mm_malloc.h are usable
with -O -std=c89 -pedantic-errors. */
/* { dg-do compile } */
-/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512bw -mavx512dq -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl" } */
+/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512bw -mavx512dq -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni" } */
#include <x86intrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/sse-13.c b/gcc/testsuite/gcc.target/i386/sse-13.c
index 7f96331..7029771 100644
--- a/gcc/testsuite/gcc.target/i386/sse-13.c
+++ b/gcc/testsuite/gcc.target/i386/sse-13.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl" } */
+/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni" } */
/* { dg-add-options bind_pic_locally } */
#include <mm_malloc.h>
diff --git a/gcc/testsuite/gcc.target/i386/sse-14.c b/gcc/testsuite/gcc.target/i386/sse-14.c
index 27704c3..4ce0fff 100644
--- a/gcc/testsuite/gcc.target/i386/sse-14.c
+++ b/gcc/testsuite/gcc.target/i386/sse-14.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mpconfig -mwbnoinvd -mavx512vl -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl" } */
+/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mpconfig -mwbnoinvd -mavx512vl -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni" } */
/* { dg-add-options bind_pic_locally } */
#include <mm_malloc.h>
diff --git a/gcc/testsuite/gcc.target/i386/sse-22.c b/gcc/testsuite/gcc.target/i386/sse-22.c
index 789c8be..6e8b6f3 100644
--- a/gcc/testsuite/gcc.target/i386/sse-22.c
+++ b/gcc/testsuite/gcc.target/i386/sse-22.c
@@ -103,7 +103,7 @@
#ifndef DIFFERENT_PRAGMAS
-#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,avx512vl,avx512bw,avx512dq,avx512vbmi,avx512vbmi2,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl")
+#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,avx512vl,avx512bw,avx512dq,avx512vbmi,avx512vbmi2,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni")
#endif
/* Following intrinsics require immediate arguments. They
@@ -220,7 +220,7 @@ test_4 (_mm_cmpestrz, int, __m128i, int, __m128i, int, 1)
/* immintrin.h (AVX/AVX2/RDRND/FSGSBASE/F16C/RTM/AVX512F/SHA) */
#ifdef DIFFERENT_PRAGMAS
-#pragma GCC target ("avx,avx2,rdrnd,fsgsbase,f16c,rtm,avx512f,avx512er,avx512cd,avx512pf,sha,avx512vl,avx512bw,avx512dq,avx512ifma,avx512vbmi,avx512vbmi2,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl")
+#pragma GCC target ("avx,avx2,rdrnd,fsgsbase,f16c,rtm,avx512f,avx512er,avx512cd,avx512pf,sha,avx512vl,avx512bw,avx512dq,avx512ifma,avx512vbmi,avx512vbmi2,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,gfni,avx512bitalg,avx512bf16,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni")
#endif
#include <immintrin.h>
test_1 (_cvtss_sh, unsigned short, float, 1)
diff --git a/gcc/testsuite/gcc.target/i386/sse-23.c b/gcc/testsuite/gcc.target/i386/sse-23.c
index 3e5e3e9..7faa053 100644
--- a/gcc/testsuite/gcc.target/i386/sse-23.c
+++ b/gcc/testsuite/gcc.target/i386/sse-23.c
@@ -708,6 +708,6 @@
#define __builtin_ia32_vpclmulqdq_v2di(A, B, C) __builtin_ia32_vpclmulqdq_v2di(A, B, 1)
#define __builtin_ia32_vpclmulqdq_v8di(A, B, C) __builtin_ia32_vpclmulqdq_v8di(A, B, 1)
-#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl")
+#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni")
#include <x86intrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/vnni_inline_error.c b/gcc/testsuite/gcc.target/i386/vnni_inline_error.c
new file mode 100644
index 0000000..eaed984
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vnni_inline_error.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -mavx512vnni -mavx512vl -mno-popcnt" } */
+
+inline int __attribute__ ((__gnu_inline__, __always_inline__, target("popcnt")))
+foo () /* { dg-error "inlining failed in call to 'always_inline' .* target specific option mismatch" } */
+{
+ return 0;
+}
+
+int bar()
+{
+ return foo (); /* { dg-message "called from here" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/x86-needed-1.c b/gcc/testsuite/gcc.target/i386/x86-needed-1.c
new file mode 100644
index 0000000..b4584df
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/x86-needed-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-fcf-protection -march=x86-64 -mneeded" } */
+/* { dg-final { scan-assembler-times ".note.gnu.property" 1 } } */
+/* { dg-final { scan-assembler-times ".long 0xc0000002" 1 } } */
+/* { dg-final { scan-assembler-times ".long 0xc0008002" 1 } } */
+
+extern void foo (void);
+
+void
+bar (void)
+{
+ foo ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/x86-needed-2.c b/gcc/testsuite/gcc.target/i386/x86-needed-2.c
new file mode 100644
index 0000000..2d91656
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/x86-needed-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fcf-protection=none -march=x86-64 -mno-needed" } */
+/* { dg-final { scan-assembler-not ".note.gnu.property" } } */
+
+extern void foo (void);
+
+void
+bar (void)
+{
+ foo ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/x86-needed-3.c b/gcc/testsuite/gcc.target/i386/x86-needed-3.c
new file mode 100644
index 0000000..1d93726
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/x86-needed-3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-fcf-protection=none -march=i686 -msoft-float -mneeded" } */
+/* { dg-final { scan-assembler-not ".note.gnu.property" } } */
+
+extern void foo (void);
+
+void
+bar (void)
+{
+ foo ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/xop-haddX.c b/gcc/testsuite/gcc.target/i386/xop-haddX.c
index 7d3220b..68f2752 100644
--- a/gcc/testsuite/gcc.target/i386/xop-haddX.c
+++ b/gcc/testsuite/gcc.target/i386/xop-haddX.c
@@ -34,7 +34,6 @@ init_sword ()
src1.si[i] = i;
}
-
static void
init_sdword ()
{
@@ -58,6 +57,7 @@ check_sbyte2word ()
check_fails++;
}
}
+ return check_fails;
}
static int
@@ -76,7 +76,7 @@ check_sbyte2dword ()
check_fails++;
}
}
- return check_fails++;
+ return check_fails;
}
static int
@@ -96,14 +96,14 @@ check_sbyte2qword ()
check_fails++;
}
}
- return check_fails++;
+ return check_fails;
}
static int
check_sword2dword ()
{
int i, j, s, t, check_fails = 0;
- for (i = 0; i < (NUM * 8); i = i + 8)
+ for (i = 0; i < NUM * 8; i = i + 8)
{
for (j = 0; j < 4; j++)
{
@@ -114,6 +114,7 @@ check_sword2dword ()
check_fails++;
}
}
+ return check_fails;
}
static int
@@ -132,14 +133,14 @@ check_sword2qword ()
check_fails++;
}
}
- return check_fails++;
+ return check_fails;
}
static int
check_dword2qword ()
{
int i, j, s, t, check_fails = 0;
- for (i = 0; i < (NUM * 4); i = i + 4)
+ for (i = 0; i < NUM * 4; i = i + 4)
{
for (j = 0; j < 2; j++)
{
@@ -150,6 +151,7 @@ check_dword2qword ()
check_fails++;
}
}
+ return check_fails;
}
static void
@@ -163,15 +165,13 @@ xop_test (void)
dst.x[i] = _mm_haddw_epi8 (src1.x[i]);
if (check_sbyte2word())
- abort ();
-
+ abort ();
- for (i = 0; i < (NUM ); i++)
+ for (i = 0; i < NUM; i++)
dst.x[i] = _mm_haddd_epi8 (src1.x[i]);
if (check_sbyte2dword())
abort ();
-
for (i = 0; i < NUM; i++)
dst.x[i] = _mm_haddq_epi8 (src1.x[i]);
@@ -179,10 +179,9 @@ xop_test (void)
if (check_sbyte2qword())
abort ();
-
init_sword ();
- for (i = 0; i < (NUM ); i++)
+ for (i = 0; i < NUM; i++)
dst.x[i] = _mm_haddd_epi16 (src1.x[i]);
if (check_sword2dword())
@@ -193,14 +192,12 @@ xop_test (void)
if (check_sword2qword())
abort ();
-
init_sdword ();
- for (i = 0; i < NUM; i++)
+ for (i = 0; i < NUM; i++)
dst.x[i] = _mm_haddq_epi32 (src1.x[i]);
if (check_dword2qword())
abort ();
-
}
diff --git a/gcc/testsuite/gcc.target/i386/xop-hadduX.c b/gcc/testsuite/gcc.target/i386/xop-hadduX.c
index 9c7ea9a..06a4a2e 100644
--- a/gcc/testsuite/gcc.target/i386/xop-hadduX.c
+++ b/gcc/testsuite/gcc.target/i386/xop-hadduX.c
@@ -34,7 +34,6 @@ init_word ()
src1.si[i] = i;
}
-
static void
init_dword ()
{
@@ -58,6 +57,7 @@ check_byte2word ()
check_fails++;
}
}
+ return check_fails;
}
static int
@@ -76,7 +76,7 @@ check_byte2dword ()
check_fails++;
}
}
- return check_fails++;
+ return check_fails;
}
static int
@@ -96,14 +96,14 @@ check_byte2qword ()
check_fails++;
}
}
- return check_fails++;
+ return check_fails;
}
static int
check_word2dword ()
{
int i, j, s, t, check_fails = 0;
- for (i = 0; i < (NUM * 8); i = i + 8)
+ for (i = 0; i < NUM * 8; i = i + 8)
{
for (j = 0; j < 4; j++)
{
@@ -114,6 +114,7 @@ check_word2dword ()
check_fails++;
}
}
+ return check_fails;
}
static int
@@ -132,14 +133,14 @@ check_word2qword ()
check_fails++;
}
}
- return check_fails++;
+ return check_fails;
}
static int
check_dword2qword ()
{
int i, j, s, t, check_fails = 0;
- for (i = 0; i < (NUM * 4); i = i + 4)
+ for (i = 0; i < NUM * 4; i = i + 4)
{
for (j = 0; j < 2; j++)
{
@@ -150,6 +151,7 @@ check_dword2qword ()
check_fails++;
}
}
+ return check_fails;
}
static void
@@ -167,7 +169,7 @@ xop_test (void)
abort ();
/* Check haddubd */
- for (i = 0; i < (NUM ); i++)
+ for (i = 0; i < NUM; i++)
dst.x[i] = _mm_haddd_epu8 (src1.x[i]);
if (check_byte2dword())
@@ -183,14 +185,13 @@ xop_test (void)
/* Check hadduwd */
init_word ();
- for (i = 0; i < (NUM ); i++)
+ for (i = 0; i < NUM; i++)
dst.x[i] = _mm_haddd_epu16 (src1.x[i]);
if (check_word2dword())
abort ();
/* Check haddbuwq */
-
for (i = 0; i < NUM; i++)
dst.x[i] = _mm_haddq_epu16 (src1.x[i]);
@@ -199,7 +200,8 @@ xop_test (void)
/* Check hadudq */
init_dword ();
- for (i = 0; i < NUM; i++)
+
+ for (i = 0; i < NUM; i++)
dst.x[i] = _mm_haddq_epu32 (src1.x[i]);
if (check_dword2qword())
diff --git a/gcc/testsuite/gcc.target/i386/xop-hsubX.c b/gcc/testsuite/gcc.target/i386/xop-hsubX.c
index f0fa9b3..e4c4373 100644
--- a/gcc/testsuite/gcc.target/i386/xop-hsubX.c
+++ b/gcc/testsuite/gcc.target/i386/xop-hsubX.c
@@ -34,7 +34,6 @@ init_sword ()
src1.si[i] = i;
}
-
static void
init_sdword ()
{
@@ -58,13 +57,14 @@ check_sbyte2word ()
check_fails++;
}
}
+ return check_fails;
}
static int
check_sword2dword ()
{
int i, j, s, t, check_fails = 0;
- for (i = 0; i < (NUM * 8); i = i + 8)
+ for (i = 0; i < NUM * 8; i = i + 8)
{
for (j = 0; j < 4; j++)
{
@@ -75,13 +75,14 @@ check_sword2dword ()
check_fails++;
}
}
+ return check_fails;
}
static int
check_dword2qword ()
{
int i, j, s, t, check_fails = 0;
- for (i = 0; i < (NUM * 4); i = i + 4)
+ for (i = 0; i < NUM * 4; i = i + 4)
{
for (j = 0; j < 2; j++)
{
@@ -92,6 +93,7 @@ check_dword2qword ()
check_fails++;
}
}
+ return check_fails;
}
static void
@@ -106,13 +108,12 @@ xop_test (void)
dst.x[i] = _mm_hsubw_epi8 (src1.x[i]);
if (check_sbyte2word())
- abort ();
-
+ abort ();
/* Check hsubwd */
init_sword ();
- for (i = 0; i < (NUM ); i++)
+ for (i = 0; i < NUM; i++)
dst.x[i] = _mm_hsubd_epi16 (src1.x[i]);
if (check_sword2dword())
@@ -120,7 +121,8 @@ xop_test (void)
/* Check hsubdq */
init_sdword ();
- for (i = 0; i < NUM; i++)
+
+ for (i = 0; i < NUM; i++)
dst.x[i] = _mm_hsubq_epi32 (src1.x[i]);
if (check_dword2qword())
diff --git a/gcc/testsuite/gcc.target/microblaze/others/strings1.c b/gcc/testsuite/gcc.target/microblaze/others/strings1.c
index 7a63faf..efaf3c6 100644
--- a/gcc/testsuite/gcc.target/microblaze/others/strings1.c
+++ b/gcc/testsuite/gcc.target/microblaze/others/strings1.c
@@ -1,13 +1,14 @@
/* { dg-options "-O3" } */
+/* { dg-final { scan-assembler "\.rodata*" } } */
+/* { dg-final { scan-assembler "addik\tr(\[0-9]\|\[1-2]\[0-9]\|3\[0-1]),r(\[0-9]\|\[1-2]\[0-9]\|3\[0-1]),\\\$LC.*" } } */
+/* { dg-final { scan-assembler "\lwi\tr(\[0-9]\|\[1-2]\[0-9]\|3\[0-1]),r(\[0-9]\|\[1-2]\[0-9]\|3\[0-1]),*" } } */
#include <string.h>
-/* { dg-final { scan-assembler "\.rodata*" } } */
extern void somefunc (char *);
int testfunc ()
{
char string2[80];
-/* { dg-final { scan-assembler "\lwi\tr(\[0-9]\|\[1-2]\[0-9]\|3\[0-1]),r0,.LC*" } } */
strcpy (string2, "hello");
somefunc (string2);
}
diff --git a/gcc/testsuite/gcc.target/msp430/data-attributes-2.c b/gcc/testsuite/gcc.target/msp430/data-attributes-2.c
index 6113e99..cf456f1 100644
--- a/gcc/testsuite/gcc.target/msp430/data-attributes-2.c
+++ b/gcc/testsuite/gcc.target/msp430/data-attributes-2.c
@@ -7,16 +7,17 @@
These attributes also conflict with the "section" attribute, since they
specify sections to put the variables into. */
int __attribute__((persistent)) p = 10;
-int __attribute__((persistent,lower)) pl = 20; /* { dg-warning "ignoring attribute 'lower' because it conflicts with attribute 'persistent'" } */
+int __attribute__((persistent,lower)) pl = 20;
int __attribute__((persistent,upper)) pu = 20; /* { dg-warning "ignoring attribute 'upper' because it conflicts with attribute 'persistent'" } */
int __attribute__((persistent,either)) pe = 20; /* { dg-warning "ignoring attribute 'either' because it conflicts with attribute 'persistent'" } */
/* This one results in an error because the handler for persistent sets the
section to .persistent there and then. */
-int __attribute__((persistent,section(".data.foo"))) ps = 20; /* { dg-error "section of 'ps' conflicts with previous declaration" } */
-int __attribute__((persistent,noinit)) pn = 2; /* { dg-warning "'noinit' attribute cannot be applied to variables with specific sections" } */
+int __attribute__((persistent,section(".data.foo"))) ps = 20; /* { dg-warning "ignoring attribute 'section' because it conflicts with attribute 'persistent'" } */
+int __attribute__((persistent,noinit)) pn = 2; /* { dg-warning "ignoring attribute 'noinit' because it conflicts with attribute 'persistent'" } */
+int __attribute__((persistent)) zz; /* { dg-warning "ignoring 'persistent' attribute set on uninitialized variable" } */
int __attribute__((noinit)) n;
-int __attribute__((noinit,lower)) nl; /* { dg-warning "ignoring attribute 'lower' because it conflicts with attribute 'noinit'" } */
+int __attribute__((noinit,lower)) nl;
int __attribute__((noinit,upper)) nu; /* { dg-warning "ignoring attribute 'upper' because it conflicts with attribute 'noinit'" } */
int __attribute__((noinit,either)) ne; /* { dg-warning "ignoring attribute 'either' because it conflicts with attribute 'noinit'" } */
int __attribute__((noinit,persistent)) np; /* { dg-warning "ignoring attribute 'persistent' because it conflicts with attribute 'noinit'" } */
@@ -25,8 +26,8 @@ int __attribute__((noinit,section(".data.foo"))) ns; /* { dg-warning "ignoring a
int __attribute__((lower)) l = 20;
int __attribute__((lower,upper)) lu = 20; /* { dg-warning "ignoring attribute 'upper' because it conflicts with attribute 'lower'" } */
int __attribute__((lower,either)) le = 20; /* { dg-warning "ignoring attribute 'either' because it conflicts with attribute 'lower'" } */
-int __attribute__((lower,persistent)) lp = 20; /* { dg-warning "ignoring attribute 'persistent' because it conflicts with attribute 'lower'" } */
-int __attribute__((lower,noinit)) ln; /* { dg-warning "ignoring attribute 'noinit' because it conflicts with attribute 'lower'" } */
+int __attribute__((lower,persistent)) lp = 20;
+int __attribute__((lower,noinit)) ln;
int __attribute__((lower,section(".data.foo"))) ls = 30;
int __attribute__((upper)) u = 20;
diff --git a/gcc/testsuite/gcc.target/msp430/pr78818-auto-warn.c b/gcc/testsuite/gcc.target/msp430/pr78818-auto-warn.c
index 3dba361..7ed5ca8 100644
--- a/gcc/testsuite/gcc.target/msp430/pr78818-auto-warn.c
+++ b/gcc/testsuite/gcc.target/msp430/pr78818-auto-warn.c
@@ -8,8 +8,8 @@ static __attribute__((persistent)) int persistent_4_g = 0;
int
main (void)
{
- __attribute__((persistent)) int persistent_1 = 1; /* { dg-warning "attribute has no effect on automatic" } */
- __attribute__((persistent)) int persistent_2 = 0; /* { dg-warning "attribute has no effect on automatic" } */
+ __attribute__((persistent)) int persistent_1 = 1; /* { dg-error "'persistent' attribute cannot be specified for local variables" } */
+ __attribute__((persistent)) int persistent_2 = 0; /* { dg-error "'persistent' attribute cannot be specified for local variables" } */
static __attribute__((persistent)) int persistent_3 = 1;
static __attribute__((persistent)) int persistent_4 = 0;
return 0;
diff --git a/gcc/testsuite/gcc.target/msp430/rtx-cost-O3-default.c b/gcc/testsuite/gcc.target/msp430/rtx-cost-O3-default.c
new file mode 100644
index 0000000..1bd6a14
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/rtx-cost-O3-default.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/* Verify the MSP430 cost model is working as expected for the default ISA
+ (msp430x) and hwmult (none), when compiling at -O3. */
+
+char arr[2];
+char a;
+char *ptr;
+
+/*
+** foo:
+** ...
+** MOV.B \&a, \&arr\+1
+** MOV.* #arr\+2, \&ptr
+** ...
+*/
+
+void
+foo (void)
+{
+ arr[1] = a;
+ ptr = arr + 2;
+}
+
+extern void ext (void);
+
+/*
+** bar:
+** ...
+** CALL.* #ext
+** CALL.* #ext
+** ...
+*/
+
+void
+bar (void)
+{
+ ext ();
+ ext ();
+}
diff --git a/gcc/testsuite/gcc.target/msp430/rtx-cost-O3-f5series.c b/gcc/testsuite/gcc.target/msp430/rtx-cost-O3-f5series.c
new file mode 100644
index 0000000..1e48625
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/rtx-cost-O3-f5series.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mhwmult=f5series" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/* Verify the MSP430 cost model is working as expected for the default ISA
+ (msp430x) and f5series hwmult, when compiling at -O3. */
+
+volatile unsigned long a;
+volatile unsigned int b;
+volatile unsigned long c;
+unsigned long res1;
+unsigned long res2;
+unsigned long res3;
+
+/*
+** foo:
+** ...
+** MOV.B #16, R14
+** CALL.* #__mspabi_slll
+** ...
+** MOV.* \&res2.*
+** ...
+** RLA.*RLC.*
+** ...
+** MOV.* \&res3.*
+** ...
+** RLA.*RLC.*
+** ...
+*/
+void foo (void)
+{
+ /* Use the shift library function for this. */
+ res1 = (a << 16) | b;
+ /* Emit 7 inline shifts for this. */
+ res2 *= 128;
+ /* Perform this multiplication inline, using addition and shifts. */
+ res3 *= 100;
+}
diff --git a/gcc/testsuite/gcc.target/msp430/rtx-cost-Os-default.c b/gcc/testsuite/gcc.target/msp430/rtx-cost-Os-default.c
new file mode 100644
index 0000000..8f3d1b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/rtx-cost-Os-default.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/* Verify the MSP430 cost model is working as expected for the default ISA
+ (msp430x) and hwmult (none), when compiling at -Os. */
+
+char arr[2];
+char a;
+char *ptr;
+
+/*
+** foo:
+** ...
+** MOV.B \&a, \&arr\+1
+** MOV.* #arr\+2, \&ptr
+** ...
+*/
+
+void
+foo (void)
+{
+ arr[1] = a;
+ ptr = arr + 2;
+}
+
+extern void ext (void);
+
+/*
+** bar:
+** ...
+** MOV.* #ext, R10
+** CALL.* R10
+** CALL.* R10
+** ...
+*/
+
+void
+bar (void)
+{
+ ext ();
+ ext ();
+}
diff --git a/gcc/testsuite/gcc.target/msp430/rtx-cost-Os-f5series.c b/gcc/testsuite/gcc.target/msp430/rtx-cost-Os-f5series.c
new file mode 100644
index 0000000..67d9198
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/rtx-cost-Os-f5series.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -mhwmult=f5series" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/* Verify the MSP430 cost model is working as expected for the default ISA
+ (msp430x) and f5series hwmult, when compiling at -Os. */
+
+volatile unsigned long a;
+volatile unsigned int b;
+volatile unsigned long c;
+unsigned long res1;
+unsigned long res2;
+unsigned long res3;
+
+/*
+** foo:
+** ...
+** MOV.B #16, R14
+** CALL.* #__mspabi_slll
+** ...
+** MOV.B #7, R14
+** CALL.* #__mspabi_slll
+** ...
+** MOV.B #100, R14
+** MOV.B #0, R15
+** ...
+** CALL.* #__mspabi_mpyl_f5hw
+** ...
+*/
+void foo (void)
+{
+ /* Use the shift library function for this. */
+ res1 = (a << 16) | b;
+ /* Likewise. */
+ res2 *= 128;
+ /* Use the hardware multiply library function for this. */
+ res3 *= 100;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/mma-double-test.c b/gcc/testsuite/gcc.target/powerpc/mma-double-test.c
index 5384379..254af7f 100755
--- a/gcc/testsuite/gcc.target/powerpc/mma-double-test.c
+++ b/gcc/testsuite/gcc.target/powerpc/mma-double-test.c
@@ -181,6 +181,9 @@ main (int argc, char *argv[])
printf ("MMA double test fail: %d errors\n",ret);
else
printf ("MMA single test success: 0 MMA errors\n");
+#else
+ if (ret)
+ abort();
#endif
return ret;
diff --git a/gcc/testsuite/gcc.target/powerpc/mma-single-test.c b/gcc/testsuite/gcc.target/powerpc/mma-single-test.c
index ac4125b..ebbc5ae 100755
--- a/gcc/testsuite/gcc.target/powerpc/mma-single-test.c
+++ b/gcc/testsuite/gcc.target/powerpc/mma-single-test.c
@@ -189,6 +189,9 @@ main (int argc, char *argv[])
printf ("MMA single test fail: %d errors\n",ret);
else
printf ("MMA single test success: 0 MMA errors\n");
+#else
+ if (ret)
+ abort();
#endif
return ret;
diff --git a/gcc/testsuite/gcc.target/powerpc/pr96506.c b/gcc/testsuite/gcc.target/powerpc/pr96506-1.c
index b1b40c5..91835ce 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr96506.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr96506-1.c
@@ -40,27 +40,3 @@ foo3 (void)
vquad_t v;
bar3 (v); /* { dg-error "invalid use of MMA operand of type .__vector_quad. as a function parameter" } */
}
-
-__vector_pair
-foo4 (__vector_pair *src) /* { dg-error "invalid use of MMA type .__vector_pair. as a function return value" } */
-{
- return *src;
-}
-
-vpair_t
-foo5 (vpair_t *src) /* { dg-error "invalid use of MMA type .__vector_pair. as a function return value" } */
-{
- return *src;
-}
-
-__vector_quad
-foo6 (__vector_quad *src) /* { dg-error "invalid use of MMA type .__vector_quad. as a function return value" } */
-{
- return *src;
-}
-
-vquad_t
-foo7 (vquad_t *src) /* { dg-error "invalid use of MMA type .__vector_quad. as a function return value" } */
-{
- return *src;
-}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr96506-2.c b/gcc/testsuite/gcc.target/powerpc/pr96506-2.c
new file mode 100644
index 0000000..9cffd25
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr96506-2.c
@@ -0,0 +1,38 @@
+/* PR target/96506 */
+/* { dg-do compile } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+
+extern void bar0();
+extern void bar1();
+extern void bar2();
+extern void bar3();
+
+typedef __vector_pair vpair_t;
+typedef __vector_quad vquad_t;
+
+/* Verify we flag errors on the following. */
+
+__vector_pair
+foo4 (__vector_pair *src)
+{ /* { dg-error "invalid use of MMA type .__vector_pair. as a function return value" } */
+ return *src;
+}
+
+vpair_t
+foo5 (vpair_t *src)
+{ /* { dg-error "invalid use of MMA type .__vector_pair. as a function return value" } */
+ return *src;
+}
+
+__vector_quad
+foo6 (__vector_quad *src)
+{ /* { dg-error "invalid use of MMA type .__vector_quad. as a function return value" } */
+ return *src;
+}
+
+vquad_t
+foo7 (vquad_t *src)
+{ /* { dg-error "invalid use of MMA type .__vector_quad. as a function return value" } */
+ return *src;
+}
diff --git a/gcc/testsuite/gcc.target/pru/halt.c b/gcc/testsuite/gcc.target/pru/halt.c
new file mode 100644
index 0000000..8aed576
--- /dev/null
+++ b/gcc/testsuite/gcc.target/pru/halt.c
@@ -0,0 +1,9 @@
+/* Test HALT builtin. */
+
+void
+test_halt (void)
+{
+ /* { dg-final { scan-assembler "halt" } } */
+ __halt();
+}
+
diff --git a/gcc/testsuite/gcc.target/pru/lmbd.c b/gcc/testsuite/gcc.target/pru/lmbd.c
new file mode 100644
index 0000000..bfe4beb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/pru/lmbd.c
@@ -0,0 +1,14 @@
+/* Test LMBD builtin. */
+
+/* { dg-options "-O1" } */
+
+/* -O1 in the options is significant. Without it zero_extend
+ operation may not be optimized. */
+
+unsigned int
+test_lmbd (unsigned char a, unsigned short b)
+{
+ /* { dg-final { scan-assembler "lmbd\\tr14, r14.w1, r14.b0" } } */
+ return __lmbd(b, a);
+}
+
diff --git a/gcc/testsuite/gcc.target/riscv/arch-10.c b/gcc/testsuite/gcc.target/riscv/arch-10.c
new file mode 100644
index 0000000..47dbda3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-10.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=rv32gf2 -mabi=ilp32" } */
+int foo()
+{
+}
+/* { dg-error "Extension `f' appear more than one time." "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.target/riscv/arch-11.c b/gcc/testsuite/gcc.target/riscv/arch-11.c
new file mode 100644
index 0000000..129d8f7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-11.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=rv32g_zicsr2 -mabi=ilp32" } */
+int foo()
+{
+}
diff --git a/gcc/testsuite/gcc.target/riscv/arch-8.c b/gcc/testsuite/gcc.target/riscv/arch-8.c
new file mode 100644
index 0000000..d7760fc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-8.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-O -march=rv32id_zicsr_zifence -mabi=ilp32" } */
+int foo()
+{
+}
diff --git a/gcc/testsuite/gcc.target/riscv/arch-9.c b/gcc/testsuite/gcc.target/riscv/arch-9.c
new file mode 100644
index 0000000..74e6410
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-9.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=rv32g2 -mabi=ilp32" } */
+int foo()
+{
+}
+/* { dg-warning "version of `g` will be omitted, please specify version for individual extension." "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-11.c b/gcc/testsuite/gcc.target/riscv/attribute-11.c
index a864950..98bd8d4 100644
--- a/gcc/testsuite/gcc.target/riscv/attribute-11.c
+++ b/gcc/testsuite/gcc.target/riscv/attribute-11.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O -mriscv-attribute -march=rv32id -mabi=ilp32" } */
+/* { dg-options "-O -mriscv-attribute -march=rv32id -mabi=ilp32 -misa-spec=2.2" } */
int foo()
{
}
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-12.c b/gcc/testsuite/gcc.target/riscv/attribute-12.c
index df27fc3..44fccad 100644
--- a/gcc/testsuite/gcc.target/riscv/attribute-12.c
+++ b/gcc/testsuite/gcc.target/riscv/attribute-12.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O -mriscv-attribute -march=rv32ifd -mabi=ilp32" } */
+/* { dg-options "-O -mriscv-attribute -march=rv32ifd -mabi=ilp32 -misa-spec=2.2" } */
int foo()
{
}
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-13.c b/gcc/testsuite/gcc.target/riscv/attribute-13.c
index 1e86001..1b8f93c 100644
--- a/gcc/testsuite/gcc.target/riscv/attribute-13.c
+++ b/gcc/testsuite/gcc.target/riscv/attribute-13.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O -mriscv-attribute -march=rv32if3d -mabi=ilp32" } */
+/* { dg-options "-O -mriscv-attribute -march=rv32if3d -mabi=ilp32 -misa-spec=2.2" } */
int foo()
{
}
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-14.c b/gcc/testsuite/gcc.target/riscv/attribute-14.c
new file mode 100644
index 0000000..2591c1f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-14.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O -mriscv-attribute -march=rv32if -mabi=ilp32 -misa-spec=20190608" } */
+int foo()
+{
+}
+/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_f2p2_zicsr2p0\"" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-15.c b/gcc/testsuite/gcc.target/riscv/attribute-15.c
new file mode 100644
index 0000000..9cae1a2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-15.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O -mriscv-attribute -march=rv32gc -mabi=ilp32 -misa-spec=2.2" } */
+int foo()
+{
+}
+/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p0_m2p0_a2p0_f2p0_d2p0_c2p0\"" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-16.c b/gcc/testsuite/gcc.target/riscv/attribute-16.c
new file mode 100644
index 0000000..f090363
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-16.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O -mriscv-attribute -march=rv32gc -mabi=ilp32 -misa-spec=20190608" } */
+int foo()
+{
+}
+/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_m2p0_a2p0_f2p2_d2p2_c2p0_zicsr2p0" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-17.c b/gcc/testsuite/gcc.target/riscv/attribute-17.c
new file mode 100644
index 0000000..19ef540
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-17.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O -mriscv-attribute -march=rv32gc -mabi=ilp32 -misa-spec=20191213" } */
+int foo()
+{
+}
+/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-6.c b/gcc/testsuite/gcc.target/riscv/attribute-6.c
deleted file mode 100644
index c75b0d6..0000000
--- a/gcc/testsuite/gcc.target/riscv/attribute-6.c
+++ /dev/null
@@ -1,6 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O -mriscv-attribute -march=rv32g2p0 -mabi=ilp32" } */
-int foo()
-{
-}
-/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p0_m2p0_a2p0_f2p0_d2p0\"" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-8.c b/gcc/testsuite/gcc.target/riscv/attribute-8.c
index 1d16176..90f5a40 100644
--- a/gcc/testsuite/gcc.target/riscv/attribute-8.c
+++ b/gcc/testsuite/gcc.target/riscv/attribute-8.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
-/* { dg-options "-O -mriscv-attribute -march=rv32i2p0xv5_xabc -mabi=ilp32" } */
+/* { dg-options "-O -mriscv-attribute -march=rv32i2p0xabc_xv5 -mabi=ilp32" } */
int foo()
{
}
-/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p0_xv5p0_xabc2p0\"" } } */
+/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p0_xabc_xv5p0\"" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-9.c b/gcc/testsuite/gcc.target/riscv/attribute-9.c
index bc4db0e..4598872 100644
--- a/gcc/testsuite/gcc.target/riscv/attribute-9.c
+++ b/gcc/testsuite/gcc.target/riscv/attribute-9.c
@@ -3,4 +3,4 @@
int foo()
{
}
-/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p0_sabc2p0_xbar2p0\"" } } */
+/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p0_sabc_xbar\"" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/interrupt-3.c b/gcc/testsuite/gcc.target/riscv/interrupt-3.c
index bc9e0c1..3d1d44d 100644
--- a/gcc/testsuite/gcc.target/riscv/interrupt-3.c
+++ b/gcc/testsuite/gcc.target/riscv/interrupt-3.c
@@ -1,4 +1,4 @@
-/* Verify t1 is saved before use. */
+/* Verify t0 is saved before use. */
/* { dg-do compile } */
/* { dg-options "-O0 -fomit-frame-pointer" } */
void __attribute__ ((interrupt))
@@ -6,4 +6,4 @@ foo (void)
{
char array[4096];
}
-/* { dg-final { scan-assembler "s\[wd\]\tt1" } } */
+/* { dg-final { scan-assembler "s\[wd\]\tt0" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/interrupt-4.c b/gcc/testsuite/gcc.target/riscv/interrupt-4.c
index b6fdd19..658aa17 100644
--- a/gcc/testsuite/gcc.target/riscv/interrupt-4.c
+++ b/gcc/testsuite/gcc.target/riscv/interrupt-4.c
@@ -1,4 +1,4 @@
-/* Verify t1 is saved before use. */
+/* Verify t0 is saved before use. */
/* { dg-do compile } */
/* { dg-options "-O0 -fomit-frame-pointer" } */
void __attribute__ ((interrupt))
@@ -15,4 +15,4 @@ foo2 (void)
COUNTER++;
#endif
}
-/* { dg-final { scan-assembler "s\[wd\]\tt1" } } */
+/* { dg-final { scan-assembler "s\[wd\]\tt0" } } */
diff --git a/gcc/testsuite/gcc.target/s390/builtin-constant-p-threading.c b/gcc/testsuite/gcc.target/s390/builtin-constant-p-threading.c
new file mode 100644
index 0000000..5f0acdc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/builtin-constant-p-threading.c
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=z196 -mzarch" } */
+
+typedef struct
+{
+ int counter;
+} atomic_t;
+
+static inline __attribute__ ((__gnu_inline__)) int
+__atomic_add (int val, int *ptr)
+{
+ int old;
+ asm volatile("laa %[old],%[val],%[ptr]\n"
+ : [old] "=d" (old), [ptr] "+Q"(*ptr)
+ : [val] "d" (val)
+ : "cc", "memory");
+ return old;
+}
+
+static inline __attribute__ ((__gnu_inline__)) void
+__atomic_add_const (int val, int *ptr)
+{
+ asm volatile("asi %[ptr],%[val]\n"
+ : [ptr] "+Q" (*ptr)
+ : [val] "i" (val)
+ : "cc", "memory");
+}
+
+static inline __attribute__ ((__gnu_inline__)) void
+atomic_add (int i, atomic_t *v)
+{
+ if (__builtin_constant_p (i) && (i > -129) && (i < 128))
+ {
+ __atomic_add_const (i, &v->counter);
+ return;
+ }
+ __atomic_add (i, &v->counter);
+}
+
+static atomic_t num_active_cpus = { (0) };
+
+void
+ledtrig_cpu (_Bool is_active)
+{
+ atomic_add (is_active ? 1 : -1, &num_active_cpus);
+}
diff --git a/gcc/testsuite/gcc.target/s390/float_t-1.c b/gcc/testsuite/gcc.target/s390/float_t-1.c
new file mode 100644
index 0000000..3455694
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/float_t-1.c
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+/* { dg-options "-std=c99" } */
+#include <math.h>
+#include <stdlib.h>
+
+int main()
+{
+ /* In standard-compliant mode, the size of float_t and FLT_EVAL_METHOD must
+ match. */
+ if (sizeof(float_t) == sizeof(double) && __FLT_EVAL_METHOD__ != 1)
+ abort();
+ if (sizeof(float_t) == sizeof(float) && __FLT_EVAL_METHOD__ != 0)
+ abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/s390/float_t-2.c b/gcc/testsuite/gcc.target/s390/float_t-2.c
new file mode 100644
index 0000000..ebeda28
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/float_t-2.c
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+/* { dg-options "-std=gnu99" } */
+#include <math.h>
+#include <stdlib.h>
+
+int main()
+{
+ /* In gnuXY mode, the size of float_t and FLT_EVAL_METHOD must
+ match, with the historic exception of permitting double and 0. */
+ if (sizeof(float_t) == sizeof(float) && __FLT_EVAL_METHOD__ == 1)
+ abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/s390/load-imm64-1.c b/gcc/testsuite/gcc.target/s390/load-imm64-1.c
new file mode 100644
index 0000000..03d17f5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/load-imm64-1.c
@@ -0,0 +1,14 @@
+/* Test that large 64-bit constants are loaded with llihf + oilf when lgrl is
+ not available. */
+
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=z9-109" } */
+
+unsigned long
+magic (void)
+{
+ return 0x3f08c5392f756cd;
+}
+
+/* { dg-final { scan-assembler-times {\n\tllihf\t} 1 { target lp64 } } } */
+/* { dg-final { scan-assembler-times {\n\toilf\t} 1 { target lp64 } } } */
diff --git a/gcc/testsuite/gcc.target/s390/load-imm64-2.c b/gcc/testsuite/gcc.target/s390/load-imm64-2.c
new file mode 100644
index 0000000..ee0ff3b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/load-imm64-2.c
@@ -0,0 +1,14 @@
+/* Test that large 64-bit constants are loaded with llihf + oilf when lgrl is
+ available. */
+
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=z10" } */
+
+unsigned long
+magic (void)
+{
+ return 0x3f08c5392f756cd;
+}
+
+/* { dg-final { scan-assembler-times {\n\tllihf\t} 1 { target lp64 } } } */
+/* { dg-final { scan-assembler-times {\n\toilf\t} 1 { target lp64 } } } */
diff --git a/gcc/testsuite/gcc.target/s390/s390.exp b/gcc/testsuite/gcc.target/s390/s390.exp
index 387a720..00e0555 100644
--- a/gcc/testsuite/gcc.target/s390/s390.exp
+++ b/gcc/testsuite/gcc.target/s390/s390.exp
@@ -192,6 +192,16 @@ proc check_effective_target_s390_z13_hw { } {
}
}] "-march=z13 -m64 -mzarch" ] } { return 0 } else { return 1 }
}
+proc check_effective_target_s390_z14_hw { } {
+ if { ![check_runtime s390_check_s390_z14_hw [subst {
+ int main (void)
+ {
+ int x = 0;
+ asm ("msgrkc %%0,%%0,%%0" : "+r" (x) : );
+ return x;
+ }
+ }] "-march=z14 -m64 -mzarch" ] } { return 0 } else { return 1 }
+}
# If a testcase doesn't have special options, use these.
global DEFAULT_CFLAGS
diff --git a/gcc/testsuite/gcc.target/s390/stack-clash-4.c b/gcc/testsuite/gcc.target/s390/stack-clash-4.c
new file mode 100644
index 0000000..619d99d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/stack-clash-4.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -m31 -mzarch -fstack-clash-protection" } */
+
+extern void c(char*);
+
+void
+a() {
+ char *b = __builtin_alloca(3);
+ c(b);
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-caller-abi-run.c b/gcc/testsuite/gcc.target/s390/vector/long-double-caller-abi-run.c
index f3a41ba..f7315f6 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-caller-abi-run.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-caller-abi-run.c
@@ -1,4 +1,5 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include "long-double-callee-abi-scan.c"
#include "long-double-caller-abi-scan.c"
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-copysign.c b/gcc/testsuite/gcc.target/s390/vector/long-double-copysign.c
index 3115195..5d69e0f 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-copysign.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-copysign.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-from-double.c b/gcc/testsuite/gcc.target/s390/vector/long-double-from-double.c
index 5eb31f8..d98e44d 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-from-double.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-from-double.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
__attribute__ ((noipa)) static long double
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-from-float.c b/gcc/testsuite/gcc.target/s390/vector/long-double-from-float.c
index 0449f0c..0ddd47d 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-from-float.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-from-float.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
__attribute__ ((noipa)) static long double
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-from-i16.c b/gcc/testsuite/gcc.target/s390/vector/long-double-from-i16.c
index 68b164d..f7d37c9 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-from-i16.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-from-i16.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-from-i32.c b/gcc/testsuite/gcc.target/s390/vector/long-double-from-i32.c
index ad8443b..49d919d 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-from-i32.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-from-i32.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-from-i64.c b/gcc/testsuite/gcc.target/s390/vector/long-double-from-i64.c
index 3d2c424..986a5eb 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-from-i64.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-from-i64.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-from-i8.c b/gcc/testsuite/gcc.target/s390/vector/long-double-from-i8.c
index 44c8c9d..9356af1 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-from-i8.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-from-i8.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-from-u16.c b/gcc/testsuite/gcc.target/s390/vector/long-double-from-u16.c
index f10c298..3aafeb4 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-from-u16.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-from-u16.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-from-u32.c b/gcc/testsuite/gcc.target/s390/vector/long-double-from-u32.c
index 2763fb4..655f5d7 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-from-u32.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-from-u32.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-from-u64.c b/gcc/testsuite/gcc.target/s390/vector/long-double-from-u64.c
index 4686dfd..601ff9c 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-from-u64.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-from-u64.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-from-u8.c b/gcc/testsuite/gcc.target/s390/vector/long-double-from-u8.c
index 3e6eb92..a43b4c8 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-from-u8.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-from-u8.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-to-double.c b/gcc/testsuite/gcc.target/s390/vector/long-double-to-double.c
index 88aa053..71ed8b2 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-to-double.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-to-double.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
__attribute__ ((noipa)) static double
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-to-float.c b/gcc/testsuite/gcc.target/s390/vector/long-double-to-float.c
index 36fd429..a2855e0 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-to-float.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-to-float.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
__attribute__ ((noipa)) static float
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-to-i16.c b/gcc/testsuite/gcc.target/s390/vector/long-double-to-i16.c
index ddfc668..1dd0e81 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-to-i16.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-to-i16.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-to-i32.c b/gcc/testsuite/gcc.target/s390/vector/long-double-to-i32.c
index 975a5de..0d5678b 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-to-i32.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-to-i32.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-to-i64.c b/gcc/testsuite/gcc.target/s390/vector/long-double-to-i64.c
index 6bd5079..2dbbb5d 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-to-i64.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-to-i64.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-to-i8.c b/gcc/testsuite/gcc.target/s390/vector/long-double-to-i8.c
index 46e6d6b..9b0b45d 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-to-i8.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-to-i8.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-to-u16.c b/gcc/testsuite/gcc.target/s390/vector/long-double-to-u16.c
index 0690f3d..f9ad0c6 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-to-u16.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-to-u16.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-to-u32.c b/gcc/testsuite/gcc.target/s390/vector/long-double-to-u32.c
index aa0e318..37b0616 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-to-u32.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-to-u32.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-to-u64.c b/gcc/testsuite/gcc.target/s390/vector/long-double-to-u64.c
index e37b65e..051934d 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-to-u64.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-to-u64.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-to-u8.c b/gcc/testsuite/gcc.target/s390/vector/long-double-to-u8.c
index bddbff8..cf3204c 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-to-u8.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-to-u8.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-wfaxb.c b/gcc/testsuite/gcc.target/s390/vector/long-double-wfaxb.c
index 1b35c1c..5a10bd1 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-wfaxb.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-wfaxb.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
__attribute__ ((noipa)) static long double
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-wfdxb.c b/gcc/testsuite/gcc.target/s390/vector/long-double-wfdxb.c
index 16b4893..db517e9 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-wfdxb.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-wfdxb.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
__attribute__ ((noipa)) static long double
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-wfsxb-1.c b/gcc/testsuite/gcc.target/s390/vector/long-double-wfsxb-1.c
index 20960d0..06750a6 100644
--- a/gcc/testsuite/gcc.target/s390/vector/long-double-wfsxb-1.c
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-wfsxb-1.c
@@ -1,5 +1,6 @@
-/* { dg-do run } */
+/* { dg-do compile } */
/* { dg-options "-O3 -march=z14 -mzarch" } */
+/* { dg-do run { target { s390_z14_hw } } } */
#include <assert.h>
typedef float tf __attribute__ ((mode (TF)));
diff --git a/gcc/testsuite/gcc.target/s390/zvector/autovec-double-quiet-uneq.c b/gcc/testsuite/gcc.target/s390/zvector/autovec-double-quiet-uneq.c
index 3d6da30..7c9b20f 100644
--- a/gcc/testsuite/gcc.target/s390/zvector/autovec-double-quiet-uneq.c
+++ b/gcc/testsuite/gcc.target/s390/zvector/autovec-double-quiet-uneq.c
@@ -5,6 +5,9 @@
AUTOVEC_DOUBLE (QUIET_UNEQ);
+/* { dg-final { scan-assembler {\n\tvzero\t} } } */
+/* { dg-final { scan-assembler {\n\tvgmg\t} } } */
/* { dg-final { scan-assembler-times {\n\tvfchdb\t} 2 } } */
/* { dg-final { scan-assembler {\n\tvo\t} } } */
-/* { dg-final { scan-assembler {\n\tvx\t} } } */
+/* { dg-final { scan-assembler {\n\tvsel\t} } } */
+/* { dg-final { scan-assembler-not {\n\tvx\t} } } */
diff --git a/gcc/testsuite/gcc.target/s390/zvector/autovec-float-quiet-uneq.c b/gcc/testsuite/gcc.target/s390/zvector/autovec-float-quiet-uneq.c
index 1df53a9..5ab9337 100644
--- a/gcc/testsuite/gcc.target/s390/zvector/autovec-float-quiet-uneq.c
+++ b/gcc/testsuite/gcc.target/s390/zvector/autovec-float-quiet-uneq.c
@@ -5,6 +5,9 @@
AUTOVEC_FLOAT (QUIET_UNEQ);
+/* { dg-final { scan-assembler {\n\tvzero\t} } } */
+/* { dg-final { scan-assembler {\n\tvgmf\t} } } */
/* { dg-final { scan-assembler-times {\n\tvfchsb\t} 2 } } */
/* { dg-final { scan-assembler {\n\tvo\t} } } */
-/* { dg-final { scan-assembler {\n\tvx\t} } } */
+/* { dg-final { scan-assembler {\n\tvsel\t} } } */
+/* { dg-final { scan-assembler-not {\n\tvx\t} } } */
diff --git a/gcc/testsuite/gcc.target/sparc/overflow-6.c b/gcc/testsuite/gcc.target/sparc/overflow-6.c
new file mode 100644
index 0000000..11aafc5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sparc/overflow-6.c
@@ -0,0 +1,20 @@
+/* PR target/97939 */
+/* Reported by Vincent Lefevre <vincent-gcc@vinc17.net> */
+
+/* { dg-do run } */
+
+#include <limits.h>
+
+long add (long i)
+{
+ long r;
+ if (!__builtin_add_overflow (i, 4096, &r))
+ __builtin_abort ();
+ return r;
+}
+
+int main (void)
+{
+ add (LONG_MAX);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/vax/bswapdi-1.c b/gcc/testsuite/gcc.target/vax/bswapdi-1.c
index c658d91..1baa018 100644
--- a/gcc/testsuite/gcc.target/vax/bswapdi-1.c
+++ b/gcc/testsuite/gcc.target/vax/bswapdi-1.c
@@ -1,3 +1,5 @@
+/* { dg-options "" } */
+
typedef int DItype __attribute__ ((mode (DI)));
DItype
__bswapdi2 (DItype u)
diff --git a/gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-1-exp-F.S b/gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-1-exp-F.S
new file mode 100644
index 0000000..b4d5b47
--- /dev/null
+++ b/gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-1-exp-F.S
@@ -0,0 +1,13 @@
+// Test the scan-symbol-section directive.
+// scan-symbol-section should fail with 'FAIL' if a symbol has a different
+// section than expected.
+
+// { dg-do preprocess }
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-1-exp-F.i" {^_test_symbol_.*$} {nomatch} } }
+// The above assertion should fail with the following messages:
+// FAIL: gcc.test-framework/dg-scan-symbol-section-1-exp-F.S scan-symbol-section symbol ^_test_symbol_.*$ (found _test_symbol_1) has section nomatch (found .text)
+// FAIL: gcc.test-framework/dg-scan-symbol-section-1-exp-F.S scan-symbol-section symbol ^_test_symbol_.*$ (found _test_symbol_2) has section nomatch (found .data)
+ .text
+_test_symbol_1:
+ .data
+_test_symbol_2:
diff --git a/gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-2-exp-F.S b/gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-2-exp-F.S
new file mode 100644
index 0000000..0187275
--- /dev/null
+++ b/gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-2-exp-F.S
@@ -0,0 +1,9 @@
+// Test the scan-symbol-section directive.
+// scan-symbol-section should fail with 'UNSUPPORTED' if a symbol has no
+// associated section.
+
+// { dg-do preprocess }
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-2-exp-F.i" {^_test_symbol$} {^\.text$} } }
+// The above assertion should fail with the following message:
+// FAIL: gcc.test-framework/dg-scan-symbol-section-2-exp-F.S scan-symbol-section symbol ^_test_symbol$ (found _test_symbol) has section ^\\.text$ (no section detected)
+_test_symbol:
diff --git a/gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-3-exp-F.S b/gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-3-exp-F.S
new file mode 100644
index 0000000..87b09a3
--- /dev/null
+++ b/gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-3-exp-F.S
@@ -0,0 +1,10 @@
+// Test the scan-symbol-section directive.
+// scan-symbol-section should fail with 'UNSUPPORTED' if a symbol has no
+// associated section.
+
+// { dg-do preprocess }
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-3-exp-F.i" {^_test_symbol$} {^\.text$} } }
+// The above assertion should fail with the following message:
+// FAIL: gcc.test-framework/dg-scan-symbol-section-3-exp-F.S scan-symbol-section symbol ^_test_symbol$ (no symbol detected) has section ^\\.text$
+ .text
+_test_wrong_symbol:
diff --git a/gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-exp-P.S b/gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-exp-P.S
new file mode 100644
index 0000000..4e7df41
--- /dev/null
+++ b/gcc/testsuite/gcc.test-framework/dg-scan-symbol-section-exp-P.S
@@ -0,0 +1,50 @@
+// Test the scan-symbol-section directive.
+
+// { dg-do preprocess }
+
+// The .section directive changes the section for all following symbols.
+ .section .text
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i" {^_test_function_1$} {^\.text$} } }
+_test_function_1:
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i" {^_test_function_2$} {^\.text$} } }
+_test_function_2:
+
+// For ELF targets, the .section directive can take multiple arguments.
+ .section .other_text_section,"ax",progbits
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i" {^_test_elf_function$} {^\.other_text_section$} } }
+_test_elf_function:
+
+// For Mach-O targets, the .section directive takes a segment name and a section name.
+ .section __TEXT,__my_text_section
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i" {^_test_macho_function$} {^__TEXT,__my_text_section$} } }
+_test_macho_function:
+// Extra whitespace between .section arguments should be ignored.
+ .section __DATA , __testsection
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i" {^_test_macho_var$} {^__DATA,__testsection$} } }
+_test_macho_var:
+
+// The .data directive sets the section for all following symbols to '.data'.
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i" {^_test_var_1$} {^\.data$} } }
+ .data
+_test_var_1:
+
+// The .text directive sets the section for all following symbols to '.text'.
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i" {^_test_function_3$} {^\.text$} } }
+ .text
+_test_function_3:
+
+// The .const directive sets the section for all following symbols to '.const'.
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i" {^_test_data_1$} {^\.const$} } }
+ .const
+_test_data_1:
+
+// Other directives do not affect the section of following symbols.
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i" {^_test_var_2$} {^\.data$} } }
+ .data
+ .p2align 2
+ .size _test_var_2, 4
+_test_var_2:
+
+// Symbol name patterns can match multiple symbols, and section name patterns
+// can match multiple sections.
+// { dg-final { scan-symbol-section "dg-scan-symbol-section-exp-P.i" {^_test_function_} {^(\.|__TEXT,).*text} } }
diff --git a/gcc/testsuite/gcc.test-framework/test-framework.exp b/gcc/testsuite/gcc.test-framework/test-framework.exp
index c269594..45328bf 100644
--- a/gcc/testsuite/gcc.test-framework/test-framework.exp
+++ b/gcc/testsuite/gcc.test-framework/test-framework.exp
@@ -23,6 +23,7 @@ if { ![info exists env(CHECK_TEST_FRAMEWORK)] } {
}
load_lib gcc-dg.exp
+load_lib scanasm.exp
proc dg-require-true { args } {
verbose "dg-require-true" 2
@@ -59,7 +60,7 @@ set dg-do-what-default compile
dg-init
# Run tests from the source directory.
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/dg-*.c]] "" ""
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/dg-*.S $srcdir/$subdir/dg-*.c]] "" ""
# Skip generated tests unless CHECK_TEST_FRAMEWORK is 1.
if { $env(CHECK_TEST_FRAMEWORK) != 1 } {
diff --git a/gcc/testsuite/gdc.dg/intrinsics.d b/gcc/testsuite/gdc.dg/intrinsics.d
index 5888361..a775237 100644
--- a/gcc/testsuite/gdc.dg/intrinsics.d
+++ b/gcc/testsuite/gdc.dg/intrinsics.d
@@ -8,65 +8,77 @@ import core.stdc.stdarg;
//////////////////////////////////////////////////////
// core.bitop
-// { dg-final { scan-tree-dump-not " bsf " "original" } }
+// { dg-final { scan-tree-dump " __builtin_ctz " "original" } }
int test_bsf(uint a) { return bsf(a); }
+// { dg-final { scan-tree-dump " __builtin_ctz(l|ll) " "original" } }
int test_bsf(ulong a) { return bsf(a); }
-// { dg-final { scan-tree-dump-not " bsr " "original" } }
+// { dg-final { scan-tree-dump " __builtin_clz " "original" } }
int test_bsr(uint a) { return bsr(a); }
+// { dg-final { scan-tree-dump " __builtin_clz(l|ll) " "original" } }
int test_bsr(ulong a) { return bsr(a); }
-// { dg-final { scan-tree-dump-not " bt " "original" } }
+// { dg-final { scan-tree-dump-not " <retval> = bt " "original" } }
int test_bt(size_t *a, size_t b) { return bt(a, b); }
-// { dg-final { scan-tree-dump-not " btc " "original" } }
+// { dg-final { scan-tree-dump-not " <retval> = btc " "original" } }
int test_btc(size_t *a, size_t b) { return btc(a, b); }
-// { dg-final { scan-tree-dump-not " btr " "original" } }
+// { dg-final { scan-tree-dump-not " <retval> = btr " "original" } }
int test_btr(size_t *a, size_t b) { return btr(a, b); }
-// { dg-final { scan-tree-dump-not " bts " "original" } }
+// { dg-final { scan-tree-dump-not " <retval> = bts " "original" } }
int test_bts(size_t *a, size_t b) { return bts(a, b); }
-// { dg-final { scan-tree-dump-not " bswap " "original" } }
+// { dg-final { scan-tree-dump " __builtin_bswap32 " "original" } }
uint test_bswap(uint a) { return bswap(a); }
+// { dg-final { scan-tree-dump " __builtin_bswap64 " "original" } }
ulong test_bswap(ulong a) { return bswap(a); }
-// { dg-final { scan-tree-dump-not " popcnt " "original" } }
+// { dg-final { scan-tree-dump " __builtin_popcount " "original" } }
int test_popcnt(uint a) { return popcnt(a); }
+// { dg-final { scan-tree-dump " __builtin_popcount(l|ll) " "original" } }
int test_popcnt(ulong a) { return popcnt(a); }
-// { dg-final { scan-tree-dump-not " volatileLoad " "original" } }
+// { dg-final { scan-tree-dump "\\(volatile ubyte \\*\\) a;" "original" } }
ubyte test_volatileLoad(ubyte *a) { return volatileLoad(a); }
+// { dg-final { scan-tree-dump "\\(volatile ushort \\*\\) a;" "original" } }
ushort test_volatileLoad(ushort *a) { return volatileLoad(a); }
+// { dg-final { scan-tree-dump "\\(volatile uint \\*\\) a;" "original" } }
uint test_volatileLoad(uint *a) { return volatileLoad(a); }
+// { dg-final { scan-tree-dump "\\(volatile ulong \\*\\) a;" "original" } }
ulong test_volatileLoad(ulong *a) { return volatileLoad(a); }
-// { dg-final { scan-tree-dump-not " volatileStore " "original" } }
+// { dg-final { scan-tree-dump "\\(volatile ubyte \\*\\) a = b" "original" } }
void test_volatileStore(ubyte *a, ubyte b) { return volatileStore(a, b); }
+// { dg-final { scan-tree-dump "\\(volatile ushort \\*\\) a = b" "original" } }
void test_volatileStore(ushort *a, ushort b) { return volatileStore(a, b); }
+// { dg-final { scan-tree-dump "\\(volatile uint \\*\\) a = b" "original" } }
void test_volatileStore(uint *a, uint b) { return volatileStore(a, b); }
+// { dg-final { scan-tree-dump "\\(volatile ulong \\*\\) a = b" "original" } }
void test_volatileStore(ulong *a, ulong b) { return volatileStore(a, b); }
-// { dg-final { scan-tree-dump-not " rol " "original" } }
+// { dg-final { scan-tree-dump " a r<< b;" "original" } }
ubyte test_rol(ubyte a, uint b) { return rol!ubyte(a, b); }
+// { dg-final { scan-tree-dump " a r>> 31;" "original" } }
uint test_rol(uint a) { return rol!(1, uint)(a); }
-// { dg-final { scan-tree-dump-not " ror " "original" } }
+// { dg-final { scan-tree-dump " a r>> b;" "original" } }
ushort test_ror(ushort a, uint b) { return ror!ushort(a, b); }
+// { dg-final { scan-tree-dump " a r>> 1;" "original" } }
ulong test_ror(ulong a) { return ror!(1, ulong)(a); }
//////////////////////////////////////////////////////
// core.checkedint
-// { dg-final { scan-tree-dump-not " adds " "original" } }
+// { dg-final { scan-tree-dump-not " <retval> = adds " "original" } }
int test_adds(int a, int b, ref bool c) { return adds(a, b, c); }
long test_adds(long a, long b, ref bool c) { return adds(a, b, c); }
-// { dg-final { scan-tree-dump-not " addu " "original" } }
+// { dg-final { scan-tree-dump-not " <retval> = addu " "original" } }
uint test_addu(uint a, uint b, ref bool c) { return addu(a, b, c); }
ulong test_addu(ulong a, ulong b, ref bool c) { return addu(a, b, c); }
-// { dg-final { scan-tree-dump-not " subs " "original" } }
+// { dg-final { scan-tree-dump-not " <retval> = subs " "original" } }
int test_subs(int a, int b, ref bool c) { return subs(a, b, c); }
long test_subs(long a, long b, ref bool c) { return subs(a, b, c); }
-// { dg-final { scan-tree-dump-not " subu " "original" } }
+// { dg-final { scan-tree-dump-not " <retval> = subu " "original" } }
uint test_subu(uint a, uint b, ref bool c) { return subu(a, b, c); }
ulong test_subu(ulong a, ulong b, ref bool c) { return subu(a, b, c); }
-// { dg-final { scan-tree-dump-not " negs " "original" } }
+// { dg-final { scan-tree-dump-not " <retval> = negs " "original" } }
int test_negs(int a, ref bool b) { return negs(a, b); }
long test_negs(long a, ref bool b) { return negs(a, b); }
-// { dg-final { scan-tree-dump-not " muls " "original" } }
+// { dg-final { scan-tree-dump-not " <retval> = muls " "original" } }
int test_muls(int a, int b, ref bool c) { return muls(a, b, c); }
long test_muls(long a, long b, ref bool c) { return muls(a, b, c); }
-// { dg-final { scan-tree-dump-not " mulu " "original" } }
+// { dg-final { scan-tree-dump-not " <retval> = mulu " "original" } }
uint test_mulu(uint a, uint b, ref bool c) { return mulu(a, b, c); }
ulong test_mulu(ulong a, uint b, ref bool c) { return mulu(a, b, c); }
ulong test_mulu(ulong a, ulong b, ref bool c) { return mulu(a, b, c); }
@@ -74,50 +86,62 @@ ulong test_mulu(ulong a, ulong b, ref bool c) { return mulu(a, b, c); }
//////////////////////////////////////////////////////
// core.math
-// { dg-final { scan-tree-dump-not " cos " "original" } }
+// { dg-final { scan-tree-dump " __builtin_cosf " "original" } }
float test_cos(float a) { return cos(a); }
+// { dg-final { scan-tree-dump " __builtin_cos " "original" } }
double test_cos(double a) { return cos(a); }
+// { dg-final { scan-tree-dump " __builtin_cosl " "original" } }
real test_cos(real a) { return cos(a); }
-// { dg-final { scan-tree-dump-not " sin " "original" } }
+// { dg-final { scan-tree-dump " __builtin_sinf " "original" } }
float test_sin(float a) { return sin(a); }
+// { dg-final { scan-tree-dump " __builtin_sin " "original" } }
double test_sin(double a) { return sin(a); }
+// { dg-final { scan-tree-dump " __builtin_sinl " "original" } }
real test_sin(real a) { return sin(a); }
-// { dg-final { scan-tree-dump-not " rndtol " "original" } }
+// { dg-final { scan-tree-dump " __builtin_llroundf " "original" } }
long test_rndtol(float a) { return rndtol(a); }
+// { dg-final { scan-tree-dump " __builtin_llround " "original" } }
long test_rndtol(double a) { return rndtol(a); }
+// { dg-final { scan-tree-dump " __builtin_llroundl " "original" } }
long test_rndtol(real a) { return rndtol(a); }
-// { dg-final { scan-tree-dump-not " sqrt " "original" } }
+// { dg-final { scan-tree-dump " __builtin_sqrtf " "original" } }
float test_sqrt(float a) { return sqrt(a); }
+// { dg-final { scan-tree-dump " __builtin_sqrt " "original" } }
double test_sqrt(double a) { return sqrt(a); }
+// { dg-final { scan-tree-dump " __builtin_sqrtl " "original" } }
real test_sqrt(real a) { return sqrt(a); }
-// { dg-final { scan-tree-dump-not " ldexp " "original" } }
+// { dg-final { scan-tree-dump " __builtin_ldexpf " "original" } }
float test_ldexp(float a, int b) { return ldexp(a, b); }
+// { dg-final { scan-tree-dump " __builtin_ldexp " "original" } }
double test_ldexp(double a, int b) { return ldexp(a, b); }
+// { dg-final { scan-tree-dump " __builtin_ldexpl " "original" } }
real test_ldexp(real a, int b) { return ldexp(a, b); }
-// { dg-final { scan-tree-dump-not " fabs " "original" } }
+// { dg-final { scan-tree-dump-not " <retval> = fabs " "original" } }
float test_fabs(float a) { return fabs(a); }
double test_fabs(double a) { return fabs(a); }
real test_fabs(real a) { return fabs(a); }
-// { dg-final { scan-tree-dump-not " rint " "original" } }
+// { dg-final { scan-tree-dump " __builtin_rintf " "original" } }
float test_rint(float a) { return rint(a); }
+// { dg-final { scan-tree-dump " __builtin_rint " "original" } }
double test_rint(double a) { return rint(a); }
+// { dg-final { scan-tree-dump " __builtin_rintl " "original" } }
real test_rint(real a) { return rint(a); }
-// { dg-final { scan-tree-dump-not " toPrec " "original" } }
-float test_toPrec(float a) { return toPrec!float(a); }
-float test_toPrec(double a) { return toPrec!float(a); }
-float test_toPrec(real a) { return toPrec!float(a); }
+// { dg-final { scan-tree-dump-not " <retval> = toPrec " "original" } }
+float test_toPrecf(float a) { return toPrec!float(a); }
+float test_toPrecf(double a) { return toPrec!float(a); }
+float test_toPrecf(real a) { return toPrec!float(a); }
double test_toPrec(float a) { return toPrec!double(a); }
double test_toPrec(double a) { return toPrec!double(a); }
double test_toPrec(real a) { return toPrec!double(a); }
-real test_toPrec(float a) { return toPrec!real(a); }
-real test_toPrec(double a) { return toPrec!real(a); }
-real test_toPrec(real a) { return toPrec!real(a); }
+real test_toPrecl(float a) { return toPrec!real(a); }
+real test_toPrecl(double a) { return toPrec!real(a); }
+real test_toPrecl(real a) { return toPrec!real(a); }
//////////////////////////////////////////////////////
// core.stdc.stdarg
// { dg-final { scan-tree-dump-not " va_arg " "original" } }
-void test_va_arg(...) { int a; return va_arg!int(_argptr, a); }
+void test_va_argc(...) { int a; return va_arg!int(_argptr, a); }
int test_va_arg(...) { return va_arg!int(_argptr); }
// { dg-final { scan-tree-dump-not " va_start " "original" } }
void test_va_start(int a, ...) { return va_start(_argptr, a); }
diff --git a/gcc/testsuite/gdc.dg/pr92216.d b/gcc/testsuite/gdc.dg/pr92216.d
index 6a87025..3aff160 100644
--- a/gcc/testsuite/gdc.dg/pr92216.d
+++ b/gcc/testsuite/gdc.dg/pr92216.d
@@ -1,8 +1,8 @@
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92216
// { dg-options "-I $srcdir/gdc.dg" }
// { dg-do compile }
-// { dg-final { scan-assembler "_DT(4|8|16)_D7imports7pr922161B8__mixin24getSMFZPv\[: \t\n\]" } }
-// { dg-final { scan-assembler-not "(.globl|.global)\[ \]+_DT(4|8|16)_D7imports7pr922161B8__mixin24getSMFZPv" } }
+// { dg-final { scan-assembler "_DTi(4|8|16)_D7imports7pr922161B8__mixin24getSMFZPv\[: \t\n\]" } }
+// { dg-final { scan-assembler-not "(.globl|.global)\[ \]+_DTi(4|8|16)_D7imports7pr922161B8__mixin24getSMFZPv" } }
module pr92216;
private import imports.pr92216;
diff --git a/gcc/testsuite/gdc.dg/torture/pr97843.d b/gcc/testsuite/gdc.dg/torture/pr97843.d
new file mode 100644
index 0000000..1a417b3
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/pr97843.d
@@ -0,0 +1,37 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97843
+// { dg-additional-options "-fmain -funittest" }
+// { dg-do run }
+// { dg-skip-if "needs gcc/config.d" { ! d_runtime } }
+
+struct Sdtor
+{
+ int value;
+ ~this() { }
+}
+
+Sdtor sum(Sdtor[] sdtors)
+{
+ int result;
+ foreach (s; sdtors)
+ result += s.value;
+ return Sdtor(result);
+}
+
+uint sum(uint[] ints)
+{
+ uint result;
+ foreach(i; ints)
+ result += i;
+ return result;
+}
+
+unittest
+{
+ Sdtor[] sdtors = [Sdtor(0), Sdtor(1)];
+ sdtors ~= sum(sdtors);
+ assert(sdtors == [Sdtor(0), Sdtor(1), Sdtor(1)]);
+
+ uint[] ints = [0, 1];
+ ints ~= ints.sum;
+ assert(ints == [0, 1, 1]);
+}
diff --git a/gcc/testsuite/gdc.dg/torture/pr97889.d b/gcc/testsuite/gdc.dg/torture/pr97889.d
new file mode 100644
index 0000000..9135c8f
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/pr97889.d
@@ -0,0 +1,29 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97889
+// { dg-additional-options "-fmain -funittest" }
+// { dg-do run }
+// { dg-skip-if "needs gcc/config.d" { ! d_runtime } }
+
+auto cat11ret3(T)(ref T s)
+{
+ s ~= 11;
+ return [3];
+}
+
+unittest
+{
+ static auto test1(int[] val) { val ~= cat11ret3(val); return val; }
+ assert(test1([1]) == [1, 11, 3]);
+ static assert(test1([1]) == [1, 11, 3]);
+
+ static auto test2(int[] val) { val = val ~ cat11ret3(val); return val; }
+ // FIXME: assert(test2([1]) == [1, 3]);
+ static assert(test2([1]) == [1, 3]);
+
+ static auto test3(int[] val) { (val ~= 7) ~= cat11ret3(val); return val; }
+ assert(test3([2]) == [2, 7, 11, 3]);
+ static assert(test3([2]) == [2, 7, 11, 3]);
+
+ static auto test4(int[] val) { (val ~= cat11ret3(val)) ~= 7; return val; }
+ assert(test4([2]) == [2, 11, 3, 7]);
+ static assert(test4([2]) == [2, 11, 3, 7]);
+}
diff --git a/gcc/testsuite/gdc.test/compilable/callconv.d b/gcc/testsuite/gdc.test/compilable/callconv.d
index fbb78ed..145ebb1 100644
--- a/gcc/testsuite/gdc.test/compilable/callconv.d
+++ b/gcc/testsuite/gdc.test/compilable/callconv.d
@@ -11,24 +11,6 @@ ABC abc;
int x,y,z;
-extern (Pascal):
-ABC test1(int xx, int yy, int zz)
-{
- x = xx;
- y = yy;
- z = zz;
- return abc;
-}
-
-extern (Pascal):
-ABC test1v(int xx, int yy, int zz, ...)
-{
- x = xx;
- y = yy;
- z = zz;
- return abc;
-}
-
extern (C):
ABC test2v(int xx, int yy, int zz, ...)
{
@@ -71,5 +53,3 @@ ABC test4v(int xx, int yy, int zz, ...)
z = zz;
return abc;
}
-
-
diff --git a/gcc/testsuite/gdc.test/compilable/test17419.d b/gcc/testsuite/gdc.test/compilable/test17419.d
index d67c5b9..295c563 100644
--- a/gcc/testsuite/gdc.test/compilable/test17419.d
+++ b/gcc/testsuite/gdc.test/compilable/test17419.d
@@ -10,14 +10,12 @@ static assert(__traits(getLinkage, aliasc) == "C");
extern (D) int food();
extern (C++) int foocpp();
extern (Windows) int foow();
-extern (Pascal) int foop();
extern (Objective-C) int fooobjc();
extern (System) int foos();
static assert(__traits(getLinkage, food) == "D");
static assert(__traits(getLinkage, foocpp) == "C++");
static assert(__traits(getLinkage, foow) == "Windows");
-static assert(__traits(getLinkage, foop) == "Pascal");
static assert(__traits(getLinkage, fooobjc) == "Objective-C");
version (Windows)
static assert(__traits(getLinkage, foos) == "Windows");
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail18970.d b/gcc/testsuite/gdc.test/fail_compilation/fail18970.d
new file mode 100644
index 0000000..0ec53c8
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail18970.d
@@ -0,0 +1,37 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail18970.d(22): Error: no property `y` for type `S`
+fail_compilation/fail18970.d(29): Error: no property `yyy` for type `S2`
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=18970
+
+struct S
+{
+ auto opDispatch(string name)(int)
+ {
+ alias T = typeof(x);
+ static assert(!is(T.U));
+ return 0;
+ }
+}
+void f()
+{
+ S().y(1);
+}
+
+struct S2
+{
+ this(int)
+ {
+ this.yyy;
+ }
+
+ auto opDispatch(string name)()
+ {
+ alias T = typeof(x);
+ static if(is(T.U)) {}
+ }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/test21164a.d b/gcc/testsuite/gdc.test/fail_compilation/imports/test21164a.d
new file mode 100644
index 0000000..e5fcd43
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/test21164a.d
@@ -0,0 +1,9 @@
+struct D(E)
+{
+ void G() {
+ import imports.test21164d;
+ I;
+ }
+
+}
+
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/test21164b.d b/gcc/testsuite/gdc.test/fail_compilation/imports/test21164b.d
new file mode 100644
index 0000000..ece5476
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/test21164b.d
@@ -0,0 +1,4 @@
+import imports.test21164c;
+enum N = O();
+alias Q = R!(N, S);
+
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/test21164c.d b/gcc/testsuite/gdc.test/fail_compilation/imports/test21164c.d
new file mode 100644
index 0000000..21a252f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/test21164c.d
@@ -0,0 +1,10 @@
+enum S = 1;
+
+struct O
+{
+}
+
+struct R(O U, int W)
+{
+}
+
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/test21164d.d b/gcc/testsuite/gdc.test/fail_compilation/imports/test21164d.d
new file mode 100644
index 0000000..08f83ea
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/test21164d.d
@@ -0,0 +1,9 @@
+auto AB()
+{
+static if}
+
+auto I()
+{
+AB;
+}
+
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21164.d b/gcc/testsuite/gdc.test/fail_compilation/test21164.d
new file mode 100644
index 0000000..f42c4bc
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21164.d
@@ -0,0 +1,13 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/imports/test21164d.d(3): Error: (expression) expected following `static if`
+fail_compilation/imports/test21164d.d(3): Error: found `}` instead of statement
+fail_compilation/test21164.d(11): Error: template instance `test21164a.D!(R!(O(), 1))` error instantiating
+---
+*/
+import imports.test21164a;
+import imports.test21164b;
+auto GB(D!Q)
+{
+}
diff --git a/gcc/testsuite/gdc.test/runnable/dhry.d b/gcc/testsuite/gdc.test/runnable/dhry.d
deleted file mode 100644
index 40f9ccff..0000000
--- a/gcc/testsuite/gdc.test/runnable/dhry.d
+++ /dev/null
@@ -1,927 +0,0 @@
-// PERMUTE_ARGS:
-// REQUIRED_ARGS: -release -O -g -inline
-// DISABLED: freebsd
-
-/*
- *************************************************************************
- *
- * "DHRYSTONE" Benchmark Program
- * -----------------------------
- *
- * Version: C, Version 2.1
- *
- * File: dhry.h (part 1 of 3)
- *
- * Date: May 25, 1988
- *
- * Author: Reinhold P. Weicker
- * Siemens Nixdorf Inf. Syst.
- * STM OS 32
- * Otto-Hahn-Ring 6
- * W-8000 Muenchen 83
- * Germany
- * Phone: [+49]-89-636-42436
- * (8-17 Central European Time)
- * UUCP: weicker@ztivax.uucp@unido.uucp
- * Internet: weicker@ztivax.siemens.com
- *
- * Original Version (in Ada) published in
- * "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
- * pp. 1013 - 1030, together with the statistics
- * on which the distribution of statements etc. is based.
- *
- * In this C version, the following C library functions are
- * used:
- * - strcpy, strcmp (inside the measurement loop)
- * - printf, scanf (outside the measurement loop)
- *
- * Collection of Results:
- * Reinhold Weicker (address see above) and
- *
- * Rick Richardson
- * PC Research. Inc.
- * 94 Apple Orchard Drive
- * Tinton Falls, NJ 07724
- * Phone: (201) 834-1378 (9-17 EST)
- * UUCP: ...!uunet!pcrat!rick
- *
- * Please send results to Rick Richardson and/or Reinhold Weicker.
- * Complete information should be given on hardware and software
- * used. Hardware information includes: Machine type, CPU, type and
- * size of caches; for microprocessors: clock frequency, memory speed
- * (number of wait states). Software information includes: Compiler
- * (and runtime library) manufacturer and version, compilation
- * switches, OS version. The Operating System version may give an
- * indication about the compiler; Dhrystone itself performs no OS
- * calls in the measurement loop.
- *
- * The complete output generated by the program should be mailed
- * such that at least some checks for correctness can be made.
- *
- *************************************************************************
- *
- * History: This version C/2.1 has been made for two reasons:
- *
- * 1) There is an obvious need for a common C version of
- * Dhrystone, since C is at present the most popular system
- * programming language for the class of processors
- * (microcomputers, minicomputers) where Dhrystone is used
- * most. There should be, as far as possible, only one C
- * version of Dhrystone such that results can be compared
- * without restrictions. In the past, the C versions
- * distributed by Rick Richardson (Version 1.1) and by
- * Reinhold Weicker had small (though not significant)
- * differences.
- *
- * 2) As far as it is possible without changes to the
- * Dhrystone statistics, optimizing compilers should be
- * prevented from removing significant statements.
- *
- * This C version has been developed in cooperation with
- * Rick Richardson (Tinton Falls, NJ), it incorporates many
- * ideas from the "Version 1.1" distributed previously by
- * him over the UNIX network Usenet.
- * I also thank Chaim Benedelac (National Semiconductor),
- * David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
- * Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
- * for their help with comments on earlier versions of the
- * benchmark.
- *
- * Changes: In the initialization part, this version follows mostly
- * Rick Richardson's version distributed via Usenet, not the
- * version distributed earlier via floppy disk by Reinhold
- * Weicker. As a concession to older compilers, names have
- * been made unique within the first 8 characters. Inside the
- * measurement loop, this version follows the version
- * previously distributed by Reinhold Weicker.
- *
- * At several places in the benchmark, code has been added,
- * but within the measurement loop only in branches that
- * are not executed. The intention is that optimizing
- * compilers should be prevented from moving code out of the
- * measurement loop, or from removing code altogether. Since
- * the statements that are executed within the measurement
- * loop have NOT been changed, the numbers defining the
- * "Dhrystone distribution" (distribution of statements,
- * operand types and locality) still hold. Except for
- * sophisticated optimizing compilers, execution times for
- * this version should be the same as for previous versions.
- *
- * Since it has proven difficult to subtract the time for the
- * measurement loop overhead in a correct way, the loop check
- * has been made a part of the benchmark. This does have
- * an impact - though a very minor one - on the distribution
- * statistics which have been updated for this version.
- *
- * All changes within the measurement loop are described
- * and discussed in the companion paper "Rationale for
- * Dhrystone version 2".
- *
- * Because of the self-imposed limitation that the order and
- * distribution of the executed statements should not be
- * changed, there are still cases where optimizing compilers
- * may not generate code for some statements. To a certain
- * degree, this is unavoidable for small synthetic
- * benchmarks. Users of the benchmark are advised to check
- * code listings whether code is generated for all statements
- * of Dhrystone.
- *
- * Version 2.1 is identical to version 2.0 distributed via
- * the UNIX network Usenet in March 1988 except that it
- * corrects some minor deficiencies that were found by users
- * of version 2.0. The only change within the measurement
- * loop is that a non-executed "else" part was added to the
- * "if" statement in Func_3, and a non-executed "else" part
- * removed from Proc_3.
- *
- *************************************************************************
- *
- * Defines: The following "Defines" are possible:
- * -DROPT (default: Not defined)
- * As an approximation to what an average C
- * programmer might do, the "register" storage class
- * is applied (if enabled by -DROPT)
- * - for local variables, if they are used
- * (dynamically) five or more times
- * - for parameters if they are used (dynamically)
- * six or more times
- * Note that an optimal "register" strategy is
- * compiler-dependent, and that "register"
- * declarations do not necessarily lead to faster
- * execution.
- * -DNOSTRUCTASSIGN (default: Not defined)
- * Define if the C compiler does not support
- * assignment of structures.
- * -DNOENUMS (default: Not defined)
- * Define if the C compiler does not support
- * enumeration types.
- *
- *************************************************************************
- *
- * Compilation model and measurement (IMPORTANT):
- *
- * This C version of Dhrystone consists of three files:
- * - dhry.h (this file, containing global definitions and comments)
- * - dhry_1.c (containing the code corresponding to Ada package Pack_1)
- * - dhry_2.c (containing the code corresponding to Ada package Pack_2)
- *
- * The following "ground rules" apply for measurements:
- * - Separate compilation
- * - No procedure merging
- * - Otherwise, compiler optimizations are allowed but should be
- * indicated
- * - Default results are those without register declarations
- * See the companion paper "Rationale for Dhrystone Version 2" for a more
- * detailed discussion of these ground rules.
- *
- * For 16-Bit processors (e.g. 80186, 80286), times for all compilation
- * models ("small", "medium", "large" etc.) should be given if possible,
- * together with a definition of these models for the compiler system
- * used.
- *
- *************************************************************************
- *
- * Dhrystone (C version) statistics:
- *
- * [Comment from the first distribution, updated for version 2.
- * Note that because of language differences, the numbers are slightly
- * different from the Ada version.]
- *
- * The following program contains statements of a high level programming
- * language (here: C) in a distribution considered representative:
- *
- * assignments 52 (51.0 %)
- * control statements 33 (32.4 %)
- * procedure, function calls 17 (16.7 %)
- *
- * 103 statements are dynamically executed. The program is balanced with
- * respect to the three aspects:
- *
- * - statement type
- * - operand type
- * - operand locality
- * operand global, local, parameter, or constant.
- *
- * The combination of these three aspects is balanced only approximately.
- *
- * 1. Statement Type:
- * ----------------- number
- *
- * V1 = V2 9
- * (incl. V1 = F(..)
- * V = Constant 12
- * Assignment, 7
- * with array element
- * Assignment, 6
- * with record component
- * --
- * 34 34
- *
- * X = Y +|-|"&&"|"|" Z 5
- * X = Y +|-|"==" Constant 6
- * X = X +|- 1 3
- * X = Y *|/ Z 2
- * X = Expression, 1
- * two operators
- * X = Expression, 1
- * three operators
- * --
- * 18 18
- *
- * if .... 14
- * with "else" 7
- * without "else" 7
- * executed 3
- * not executed 4
- * for ... 7 | counted every time
- * while ... 4 | the loop condition
- * do ... while 1 | is evaluated
- * switch ... 1
- * break 1
- * declaration with 1
- * initialization
- * --
- * 34 34
- *
- * P (...) procedure call 11
- * user procedure 10
- * library procedure 1
- * X = F (...)
- * function call 6
- * user function 5
- * library function 1
- * --
- * 17 17
- * ---
- * 103
- *
- * The average number of parameters in procedure or function calls
- * is 1.82 (not counting the function values as implicit parameters).
- *
- *
- * 2. Operators
- * ------------
- * number approximate
- * percentage
- *
- * Arithmetic 32 50.8
- *
- * + 21 33.3
- * - 7 11.1
- * * 3 4.8
- * / (int div) 1 1.6
- *
- * Comparison 27 42.8
- *
- * == 9 14.3
- * /= 4 6.3
- * > 1 1.6
- * < 3 4.8
- * >= 1 1.6
- * <= 9 14.3
- *
- * Logic 4 6.3
- *
- * && (AND-THEN) 1 1.6
- * | (OR) 1 1.6
- * ! (NOT) 2 3.2
- *
- * -- -----
- * 63 100.1
- *
- *
- * 3. Operand Type (counted once per operand reference):
- * ---------------
- * number approximate
- * percentage
- *
- * Integer 175 72.3 %
- * Character 45 18.6 %
- * Pointer 12 5.0 %
- * String30 6 2.5 %
- * Array 2 0.8 %
- * Record 2 0.8 %
- * --- -------
- * 242 100.0 %
- *
- * When there is an access path leading to the final operand (e.g. a
- * record component), only the final data type on the access path is
- * counted.
- *
- *
- * 4. Operand Locality:
- * -------------------
- * number approximate
- * percentage
- *
- * local variable 114 47.1 %
- * global variable 22 9.1 %
- * parameter 45 18.6 %
- * value 23 9.5 %
- * reference 22 9.1 %
- * function result 6 2.5 %
- * constant 55 22.7 %
- * --- -------
- * 242 100.0 %
- *
- *
- * The program does not compute anything meaningful, but it is
- * syntactically and semantically correct. All variables have a value
- * assigned to them before they are used as a source operand.
- *
- * There has been no explicit effort to account for the effects of a
- * cache, or to balance the use of long or short displacements for code
- * or data.
- *
- *************************************************************************
- */
-
-import core.stdc.stdio;
-import core.stdc.string;
-import core.stdc.stdlib;
-import std.string;
-
-
-/* Compiler and system dependent definitions: */
-
-const double Mic_secs_Per_Second = 1000000.0;
- /* Berkeley UNIX C returns process times in seconds/HZ */
-
-enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
-alias int Enumeration;
- /* for boolean and enumeration types in Ada, Pascal */
-
-/* General definitions: */
-
-const int StrLen = 30;
-
-alias int One_Thirty;
-alias int One_Fifty;
-alias char Capital_Letter;
-alias bool Boolean;
-alias char Str_30 [StrLen];
-alias int Arr_1_Dim [50];
-alias int Arr_2_Dim [50] [50];
-
-struct record
-{
- record *Ptr_Comp;
- Enumeration Discr;
- union V {
- struct V1 {
- Enumeration Enum_Comp;
- int Int_Comp;
- char Str_Comp [StrLen];
- }
- V1 var_1;
- struct V2 {
- Enumeration E_Comp_2;
- char Str_2_Comp [StrLen];
- }
- V2 var_2;
- struct V3 {
- char Ch_1_Comp;
- char Ch_2_Comp;
- }
- V3 var_3;
- }
- V variant;
-}
-
-alias record Rec_Type;
-alias record *Rec_Pointer;
-
-
-/* Global Variables: */
-
-Rec_Pointer Ptr_Glob,
- Next_Ptr_Glob;
-int Int_Glob;
-Boolean Bool_Glob;
-char Ch_1_Glob,
- Ch_2_Glob;
-int Arr_1_Glob [50];
-int Arr_2_Glob [50] [50];
-
-char[StrLen] Reg_Define = "Register option selected.";
-
-/* variables for time measurement: */
-
-const int Too_Small_Time = 2;
- /* Measurements should last at least 2 seconds */
-
-double Begin_Time,
- End_Time,
- User_Time;
-
-double Microseconds,
- Dhrystones_Per_Second,
- Vax_Mips;
-
-/* end of variables for time measurement */
-
-
-void main ()
-/*****/
-
- /* main program, corresponds to procedures */
- /* Main and Proc_0 in the Ada version */
-{
- One_Fifty Int_1_Loc;
- One_Fifty Int_2_Loc;
- One_Fifty Int_3_Loc;
- char Ch_Index;
- Enumeration Enum_Loc;
- Str_30 Str_1_Loc;
- Str_30 Str_2_Loc;
- int Run_Index;
- int Number_Of_Runs;
-
-/+
- FILE *Ap;
-
- /* Initializations */
-
- if ((Ap = fopen("dhry.res","a+")) == null)
- {
- printf("Can not open dhry.res\n\n");
- exit(1);
- }
-+/
-
- Next_Ptr_Glob = cast(Rec_Pointer) malloc (Rec_Type.sizeof);
- Ptr_Glob = cast(Rec_Pointer) malloc (Rec_Type.sizeof);
-
- Ptr_Glob.Ptr_Comp = Next_Ptr_Glob;
- Ptr_Glob.Discr = Ident_1;
- Ptr_Glob.variant.var_1.Enum_Comp = Ident_3;
- Ptr_Glob.variant.var_1.Int_Comp = 40;
-// strcpy (Ptr_Glob.variant.var_1.Str_Comp,
-// "DHRYSTONE PROGRAM, SOME STRING");
-// strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
- Ptr_Glob.variant.var_1.Str_Comp[] = "DHRYSTONE PROGRAM, SOME STRING";
- Str_1_Loc[] = "DHRYSTONE PROGRAM, 1'ST STRING";
-
- Arr_2_Glob [8][7] = 10;
- /* Was missing in published program. Without this statement, */
- /* Arr_2_Glob [8][7] would have an undefined value. */
- /* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
- /* overflow may occur for this array element. */
-
- printf ("\n");
- printf ("Dhrystone Benchmark, Version 2.1 (Language: D)\n");
- printf ("\n");
- printf ("Please give the number of runs through the benchmark: ");
- {
- int n;
- //scanf ("%d", &n);
- n = 10000000;
- Number_Of_Runs = n;
- }
- printf ("\n");
-
- printf ("Execution starts, %d runs through Dhrystone\n",Number_Of_Runs);
-
- /***************/
- /* Start timer */
- /***************/
-
- Begin_Time = dtime();
-
- for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
- {
-
- Proc_5();
- Proc_4();
- /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
- Int_1_Loc = 2;
- Int_2_Loc = 3;
- //strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
- Str_2_Loc[] = "DHRYSTONE PROGRAM, 2'ND STRING";
- Enum_Loc = Ident_2;
- Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
- /* Bool_Glob == 1 */
- while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
- {
- Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
- /* Int_3_Loc == 7 */
- Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
- /* Int_3_Loc == 7 */
- Int_1_Loc += 1;
- } /* while */
- /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
- Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
- /* Int_Glob == 5 */
- Proc_1 (Ptr_Glob);
- for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
- /* loop body executed twice */
- {
- if (Enum_Loc == Func_1 (Ch_Index, 'C'))
- /* then, not executed */
- {
- Proc_6 (Ident_1, &Enum_Loc);
- //strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
- Str_2_Loc[] = "DHRYSTONE PROGRAM, 3'RD STRING";
- Int_2_Loc = Run_Index;
- Int_Glob = Run_Index;
- }
- }
- /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
- Int_2_Loc = Int_2_Loc * Int_1_Loc;
- Int_1_Loc = Int_2_Loc / Int_3_Loc;
- Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
- /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
- Proc_2 (&Int_1_Loc);
- /* Int_1_Loc == 5 */
-
- } /* loop "for Run_Index" */
-
- /**************/
- /* Stop timer */
- /**************/
-
- End_Time = dtime();
-
- printf ("Execution ends\n");
- printf ("\n");
- printf ("Final values of the variables used in the benchmark:\n");
- printf ("\n");
- printf ("Int_Glob: %d\n", Int_Glob);
- printf (" should be: %d\n", 5);
- printf ("Bool_Glob: %d\n", Bool_Glob);
- printf (" should be: %d\n", 1);
- printf ("Ch_1_Glob: %c\n", Ch_1_Glob);
- printf (" should be: %c\n", cast(int)'A');
- printf ("Ch_2_Glob: %c\n", Ch_2_Glob);
- printf (" should be: %c\n", cast(int)'B');
- printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]);
- printf (" should be: %d\n", 7);
- printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]);
- printf (" should be: Number_Of_Runs + 10\n");
- printf ("Ptr_Glob.\n");
- printf (" Ptr_Comp: %d\n", cast(int) Ptr_Glob.Ptr_Comp);
- printf (" should be: (implementation-dependent)\n");
- printf (" Discr: %d\n", Ptr_Glob.Discr);
- printf (" should be: %d\n", 0);
- printf (" Enum_Comp: %d\n", Ptr_Glob.variant.var_1.Enum_Comp);
- printf (" should be: %d\n", 2);
- printf (" Int_Comp: %d\n", Ptr_Glob.variant.var_1.Int_Comp);
- printf (" should be: %d\n", 17);
- printf (" Str_Comp: %.*s\n", Ptr_Glob.variant.var_1.Str_Comp.length, Ptr_Glob.variant.var_1.Str_Comp.ptr);
- printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
- printf ("Next_Ptr_Glob.\n");
- printf (" Ptr_Comp: %d\n", cast(int) Next_Ptr_Glob.Ptr_Comp);
- printf (" should be: (implementation-dependent), same as above\n");
- printf (" Discr: %d\n", Next_Ptr_Glob.Discr);
- printf (" should be: %d\n", 0);
- printf (" Enum_Comp: %d\n", Next_Ptr_Glob.variant.var_1.Enum_Comp);
- printf (" should be: %d\n", 1);
- printf (" Int_Comp: %d\n", Next_Ptr_Glob.variant.var_1.Int_Comp);
- printf (" should be: %d\n", 18);
- printf (" Str_Comp: %.*s\n", Next_Ptr_Glob.variant.var_1.Str_Comp.length, Next_Ptr_Glob.variant.var_1.Str_Comp.ptr);
- printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
- printf ("Int_1_Loc: %d\n", Int_1_Loc);
- printf (" should be: %d\n", 5);
- printf ("Int_2_Loc: %d\n", Int_2_Loc);
- printf (" should be: %d\n", 13);
- printf ("Int_3_Loc: %d\n", Int_3_Loc);
- printf (" should be: %d\n", 7);
- printf ("Enum_Loc: %d\n", Enum_Loc);
- printf (" should be: %d\n", 1);
- printf ("Str_1_Loc: %.*s\n", Str_1_Loc.length, Str_1_Loc.ptr);
- printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
- printf ("Str_2_Loc: %.*s\n", Str_2_Loc.length, Str_2_Loc.ptr);
- printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
- printf ("\n");
-
- User_Time = End_Time - Begin_Time;
-
- if (User_Time < Too_Small_Time)
- {
- printf ("Measured time too small to obtain meaningful results\n");
- printf ("Please increase number of runs\n");
- printf ("\n");
- }
- else
- {
- Microseconds = User_Time * Mic_secs_Per_Second
- / cast(double) Number_Of_Runs;
- Dhrystones_Per_Second = cast(double) Number_Of_Runs / User_Time;
- Vax_Mips = Dhrystones_Per_Second / 1757.0;
-
- printf ("Register option selected? NO\n");
- strcpy(Reg_Define.ptr, "Register option not selected.");
- printf ("Microseconds for one run through Dhrystone: ");
- printf ("%7.1lf \n", Microseconds);
- printf ("Dhrystones per Second: ");
- printf ("%10.1lf \n", Dhrystones_Per_Second);
- printf ("VAX MIPS rating = %10.3lf \n",Vax_Mips);
- printf ("\n");
-
- /+
- fprintf(Ap,"\n");
- fprintf(Ap,"Dhrystone Benchmark, Version 2.1 (Language: D)\n");
- fprintf(Ap,"%.*s\n",Reg_Define.length, Reg_Define.ptr);
- fprintf(Ap,"Microseconds for one loop: %7.1lf\n",Microseconds);
- fprintf(Ap,"Dhrystones per second: %10.1lf\n",Dhrystones_Per_Second);
- fprintf(Ap,"VAX MIPS rating: %10.3lf\n",Vax_Mips);
- fclose(Ap);
- +/
-
- }
-
-}
-
-void Proc_1 (Rec_Pointer Ptr_Val_Par)
-/******************/
-
- /* executed once */
-{
- Rec_Pointer Next_Record = Ptr_Val_Par.Ptr_Comp;
- /* == Ptr_Glob_Next */
- /* Local variable, initialized with Ptr_Val_Par.Ptr_Comp, */
- /* corresponds to "rename" in Ada, "with" in Pascal */
-
- *Ptr_Val_Par.Ptr_Comp = *Ptr_Glob;
- Ptr_Val_Par.variant.var_1.Int_Comp = 5;
- Next_Record.variant.var_1.Int_Comp
- = Ptr_Val_Par.variant.var_1.Int_Comp;
- Next_Record.Ptr_Comp = Ptr_Val_Par.Ptr_Comp;
- Proc_3 (&Next_Record.Ptr_Comp);
- /* Ptr_Val_Par.Ptr_Comp.Ptr_Comp
- == Ptr_Glob.Ptr_Comp */
- if (Next_Record.Discr == Ident_1)
- /* then, executed */
- {
- Next_Record.variant.var_1.Int_Comp = 6;
- Proc_6 (Ptr_Val_Par.variant.var_1.Enum_Comp,
- &Next_Record.variant.var_1.Enum_Comp);
- Next_Record.Ptr_Comp = Ptr_Glob.Ptr_Comp;
- Proc_7 (Next_Record.variant.var_1.Int_Comp, 10,
- &Next_Record.variant.var_1.Int_Comp);
- }
- else /* not executed */
- *Ptr_Val_Par = *Ptr_Val_Par.Ptr_Comp;
-} /* Proc_1 */
-
-void Proc_2 (One_Fifty *Int_Par_Ref)
-/******************/
- /* executed once */
- /* *Int_Par_Ref == 1, becomes 4 */
-{
- One_Fifty Int_Loc;
- Enumeration Enum_Loc;
-
- Int_Loc = *Int_Par_Ref + 10;
- do /* executed once */
- if (Ch_1_Glob == 'A')
- /* then, executed */
- {
- Int_Loc -= 1;
- *Int_Par_Ref = Int_Loc - Int_Glob;
- Enum_Loc = Ident_1;
- } /* if */
- while (Enum_Loc != Ident_1); /* true */
-} /* Proc_2 */
-
-
-void Proc_3 (Rec_Pointer *Ptr_Ref_Par)
-/******************/
- /* executed once */
- /* Ptr_Ref_Par becomes Ptr_Glob */
-
-{
- if (Ptr_Glob != null)
- /* then, executed */
- *Ptr_Ref_Par = Ptr_Glob.Ptr_Comp;
- Proc_7 (10, Int_Glob, &Ptr_Glob.variant.var_1.Int_Comp);
-} /* Proc_3 */
-
-void Proc_4 () /* without parameters */
-/*******/
- /* executed once */
-{
- Boolean Bool_Loc;
-
- Bool_Loc = Ch_1_Glob == 'A';
- Bool_Glob = Bool_Loc | Bool_Glob;
- Ch_2_Glob = 'B';
-} /* Proc_4 */
-
-
-void Proc_5 () /* without parameters */
-/*******/
- /* executed once */
-{
- Ch_1_Glob = 'A';
- Bool_Glob = false;
-} /* Proc_5 */
-
-
-void Proc_6 (Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par)
-/*********************************/
- /* executed once */
- /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
-{
- *Enum_Ref_Par = Enum_Val_Par;
- if (! Func_3 (Enum_Val_Par))
- /* then, not executed */
- *Enum_Ref_Par = Ident_4;
- final switch (Enum_Val_Par)
- {
- case Ident_1:
- *Enum_Ref_Par = Ident_1;
- break;
- case Ident_2:
- if (Int_Glob > 100)
- /* then */
- *Enum_Ref_Par = Ident_1;
- else *Enum_Ref_Par = Ident_4;
- break;
- case Ident_3: /* executed */
- *Enum_Ref_Par = Ident_2;
- break;
- case Ident_4: break;
- case Ident_5:
- *Enum_Ref_Par = Ident_3;
- break;
- } /* switch */
-} /* Proc_6 */
-
-
-void Proc_7 (One_Fifty Int_1_Par_Val, One_Fifty Int_2_Par_Val, One_Fifty *Int_Par_Ref)
-/**********************************************/
- /* executed three times */
- /* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
- /* Int_Par_Ref becomes 7 */
- /* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
- /* Int_Par_Ref becomes 17 */
- /* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
- /* Int_Par_Ref becomes 18 */
-{
- One_Fifty Int_Loc;
-
- Int_Loc = Int_1_Par_Val + 2;
- *Int_Par_Ref = Int_2_Par_Val + Int_Loc;
-} /* Proc_7 */
-
-
-void Proc_8 (ref Arr_1_Dim Arr_1_Par_Ref, ref Arr_2_Dim Arr_2_Par_Ref, int Int_1_Par_Val, int Int_2_Par_Val)
-/*********************************************************************/
- /* executed once */
- /* Int_Par_Val_1 == 3 */
- /* Int_Par_Val_2 == 7 */
-{
- One_Fifty Int_Index;
- One_Fifty Int_Loc;
-
- Int_Loc = Int_1_Par_Val + 5;
- Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
- Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
- Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
- for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
- Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
- Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
- Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
- Int_Glob = 5;
-} /* Proc_8 */
-
-
-Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val)
-/*************************************************/
- /* executed three times */
- /* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
- /* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
- /* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
-{
- Capital_Letter Ch_1_Loc;
- Capital_Letter Ch_2_Loc;
-
- Ch_1_Loc = Ch_1_Par_Val;
- Ch_2_Loc = Ch_1_Loc;
- if (Ch_2_Loc != Ch_2_Par_Val)
- /* then, executed */
- return (Ident_1);
- else /* not executed */
- {
- Ch_1_Glob = Ch_1_Loc;
- return (Ident_2);
- }
-} /* Func_1 */
-
-
-Boolean Func_2 (Str_30 Str_1_Par_Ref, Str_30 Str_2_Par_Ref)
-/*************************************************/
- /* executed once */
- /* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
- /* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
-{
- One_Thirty Int_Loc;
- Capital_Letter Ch_Loc;
-
- Int_Loc = 2;
- while (Int_Loc <= 2) /* loop body executed once */
- if (Func_1 (Str_1_Par_Ref[Int_Loc],
- Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
- /* then, executed */
- {
- Ch_Loc = 'A';
- Int_Loc += 1;
- } /* if, while */
- if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
- /* then, not executed */
- Int_Loc = 7;
- if (Ch_Loc == 'R')
- /* then, not executed */
- return (true);
- else /* executed */
- {
- //if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
- //if (memcmp (Str_1_Par_Ref, Str_2_Par_Ref, 30) > 0)
- if (Str_1_Par_Ref > Str_2_Par_Ref)
- /* then, not executed */
- {
- Int_Loc += 7;
- Int_Glob = Int_Loc;
- return (true);
- }
- else /* executed */
- return (false);
- } /* if Ch_Loc */
-} /* Func_2 */
-
-
-Boolean Func_3 (Enumeration Enum_Par_Val)
-/***************************/
- /* executed once */
- /* Enum_Par_Val == Ident_3 */
-{
- Enumeration Enum_Loc;
-
- Enum_Loc = Enum_Par_Val;
- if (Enum_Loc == Ident_3)
- /* then, executed */
- return (true);
- else /* not executed */
- return (false);
-} /* Func_3 */
-
-version (Windows)
-{
- import core.sys.windows.windows;
-
- double dtime()
- {
- double q;
-
- q = cast(double)GetTickCount() * 1.0e-03;
-
- return q;
- }
-}
-
-version (linux)
-{
- import core.stdc.time;
-
- double dtime()
- {
- double q;
-
- q = cast(double)time(null);
-
- return q;
- }
-}
-
-version (OSX) // supplied by Anders F Bjorklund
-{
- import core.sys.posix.sys.time;
-
- double dtime()
- {
- double q;
- timeval tv;
-
- gettimeofday(&tv,null);
- q = cast(double)tv.tv_sec + cast(double)tv.tv_usec * 1.0e-6;
-
- return q;
- }
-}
-
-version (NetBSD)
-{
- import core.sys.posix.sys.time;
-
- double dtime()
- {
- double q;
- timeval tv;
-
- gettimeofday(&tv,null);
- q = cast(double)tv.tv_sec + cast(double)tv.tv_usec * 1.0e-6;
-
- return q;
- }
-}
diff --git a/gcc/testsuite/gdc.test/runnable/nested.d b/gcc/testsuite/gdc.test/runnable/nested.d
index 98261ff..fa012b5 100644
--- a/gcc/testsuite/gdc.test/runnable/nested.d
+++ b/gcc/testsuite/gdc.test/runnable/nested.d
@@ -790,18 +790,9 @@ void test33()
return 3;
}
- extern (Pascal) int Foo4(int a, int b, int c)
- {
- assert(a == 1);
- assert(b == 2);
- assert(c == 3);
- return 4;
- }
-
assert(Foo1(1, 2, 3) == 1);
assert(Foo2(1, 2, 3) == 2);
assert(Foo3(1, 2, 3) == 3);
- assert(Foo4(1, 2, 3) == 4);
printf("test33 success\n");
}
diff --git a/gcc/testsuite/gdc.test/runnable/test4.d b/gcc/testsuite/gdc.test/runnable/test4.d
index b5263e7..1d03572 100644
--- a/gcc/testsuite/gdc.test/runnable/test4.d
+++ b/gcc/testsuite/gdc.test/runnable/test4.d
@@ -605,11 +605,6 @@ extern (C) int cfc(int x, int y)
return x * 10 + y;
}
-extern (Pascal) int cfp(int x, int y)
-{
- return x * 10 + y;
-}
-
int cfd(int x, int y)
{
return x * 10 + y;
@@ -618,7 +613,6 @@ int cfd(int x, int y)
extern (Windows) int function (int, int) fpw;
extern (C) int function (int, int) fpc;
-extern (Pascal) int function (int, int) fpp;
int function (int, int) fpd;
void test20()
@@ -628,7 +622,6 @@ void test20()
fpw = &cfw;
fpc = &cfc;
- fpp = &cfp;
fpd = &cfd;
//printf("test w\n");
@@ -639,10 +632,6 @@ void test20()
i = (*fpc)(3, 4);
assert(i == 34);
-//printf("test p\n");
- i = (*fpp)(5, 6);
- assert(i == 56);
-
//printf("test d\n");
i = (*fpd)(7, 8);
assert(i == 78);
@@ -1480,4 +1469,3 @@ int main()
printf("Success\n");
return 0;
}
-
diff --git a/gcc/testsuite/gfortran.dg/entry_23.f b/gcc/testsuite/gfortran.dg/entry_23.f
new file mode 100644
index 0000000..ebc5f66
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/entry_23.f
@@ -0,0 +1,57 @@
+! { dg-do run }
+! PR 97799 - this used to segfault intermittently.
+! Test case by George Hockney.
+ PROGRAM MAIN
+ IMPLICIT NONE
+
+ character *(20) CA(4) ! four cells of length 20
+
+ call CHAR_ENTRY(CA) ! call char_sub through entry
+
+ write (*,*) CA ! write result -- not needed for bug
+ call CHAR_SUB(CA) ! call char_sb directly -- not needed
+ write (*,*) CA ! write result -- not needed for bug
+ STOP
+ END
+
+
+
+ SUBROUTINE CHAR_SUB(CARRAY) ! sets carray cells to 'Something'
+ IMPLICIT NONE
+
+ CHARACTER*(*) CARRAY(*)
+
+ integer i
+ integer nelts
+
+ nelts = 4 ! same as size of array in main program
+ write (*,*) 'CHAR_SUB'
+ write (*,*) 'len(carray(1))', len(carray(1)) ! len is OK at 20
+ call flush() ! since the next loop segfaults
+ do 1 i=1, nelts
+ CARRAY(i) = 'Something'
+ 1 continue
+ RETURN
+ END
+
+
+ SUBROUTINE TOP_ENTRY
+!
+! TOP_ENTRY is never called directly. It organizes entry points
+! and sometimes saves variables for other entry points. Its
+! signature does not matter for the failure
+!
+ IMPLICIT NONE
+!
+! Declare input variables for all entry points. Just one here
+!
+ CHARACTER*(*) CARRAY(*)
+!
+! Entry point CHAR_ENTRY
+!
+ ENTRY CHAR_ENTRY( CARRAY)
+ CALL CHAR_SUB(CARRAY)
+ RETURN
+
+ END SUBROUTINE TOP_ENTRY
+
diff --git a/gcc/testsuite/gfortran.dg/goacc-gomp/fixed-1.f b/gcc/testsuite/gfortran.dg/goacc-gomp/fixed-1.f
new file mode 100644
index 0000000..b6bab4c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc-gomp/fixed-1.f
@@ -0,0 +1,81 @@
+! { dg-additional-options "-fdump-tree-original -Wunused-variable" }
+ implicit none
+ integer :: a,b,c,d,e,f,g,h,i,j,k,ll
+
+c$bogus
+!$bogus
+*$bogus
+
+c$ bogus
+!$ bogus
+*$ bogus
+
+c$a23 bogus
+!$ a bogus
+*$12a bogus
+
+! The following should be parsed as OpenMP conditional sentinel
+! If not, expect a unused-variable warning
+
+c$ a = 1
+!$ b = 2
+*$ c = 3
+
+c$ 1 d = 4
+!$ 22 e = 5
+*$34 f = 6
+
+c$ g =
+c$ *7
+!$ 2 h =
+*$ & 8
+*$ 3 i
+!$ & = 9
+
+c$ j
+*$ &=
+c$ *10
+!$ 5 k
+*$ * =
+c$ & 1
+*$ & 1
+*$9 9 ll
+!$ & =
+!$ * 12
+
+c$ bogus
+!$ bogus
+*$ bogus
+
+c$bogus
+!$bogus
+*$bogus
+
+c$ acc bogus
+!$ acc bogus
+*$ acc bogus
+
+c$ omp bogus
+!$ omp bogus
+*$ omp bogus
+ end
+
+!{ dg-final { scan-tree-dump-times "a = 1;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "b = 2;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "c = 3;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "d = 4;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "e = 5;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "f = 6;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "g = 7;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "h = 8;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "i = 9;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "j = 10;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "k = 11;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "ll = 12;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "__label_000001:;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "__label_000022:;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "__label_000034:;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "__label_000002:;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "__label_000003:;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "__label_000005:;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "__label_000099:;" 1 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/goacc-gomp/free-1.f90 b/gcc/testsuite/gfortran.dg/goacc-gomp/free-1.f90
new file mode 100644
index 0000000..0d6f2b2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc-gomp/free-1.f90
@@ -0,0 +1,34 @@
+! { dg-additional-options "-fdump-tree-original -Wunused-variable" }
+implicit none
+integer :: a,b,c,d,e,f,g,h
+
+!$bogus
+
+ !$bogus
+!$& bogus
+ !$& bogus
+
+!$ a = 1
+!$ b = 2
+!$ c = &
+!$3
+
+!$ d = &
+!$&4
+
+ !$ e = 5
+ !$ f = 6
+ !$ g = &
+ !$7
+
+ !$ h = &
+!$&8
+ end
+
+!{ dg-final { scan-tree-dump-times "a = 1;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "b = 2;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "c = 3;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "d = 4;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "e = 5;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "f = 6;" 1 "original" } }
+!{ dg-final { scan-tree-dump-times "g = 7;" 1 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/goacc/classify-kernels-unparallelized.f95 b/gcc/testsuite/gfortran.dg/goacc/classify-kernels-unparallelized.f95
index 0877242..6cca3d6 100644
--- a/gcc/testsuite/gfortran.dg/goacc/classify-kernels-unparallelized.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/classify-kernels-unparallelized.f95
@@ -19,8 +19,8 @@ program main
call setup(a, b)
- !$acc kernels copyin (a(0:n-1), b(0:n-1)) copyout (c(0:n-1))
- do i = 0, n - 1 ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+ !$acc kernels copyin (a(0:n-1), b(0:n-1)) copyout (c(0:n-1)) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+ do i = 0, n - 1
c(i) = a(f (i)) + b(f (i))
end do
!$acc end kernels
diff --git a/gcc/testsuite/gfortran.dg/goacc/classify-kernels.f95 b/gcc/testsuite/gfortran.dg/goacc/classify-kernels.f95
index f2c4736..715a983 100644
--- a/gcc/testsuite/gfortran.dg/goacc/classify-kernels.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/classify-kernels.f95
@@ -15,8 +15,8 @@ program main
call setup(a, b)
- !$acc kernels copyin (a(0:n-1), b(0:n-1)) copyout (c(0:n-1))
- do i = 0, n - 1 ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+ !$acc kernels copyin (a(0:n-1), b(0:n-1)) copyout (c(0:n-1)) ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+ do i = 0, n - 1
c(i) = a(i) + b(i)
end do
!$acc end kernels
diff --git a/gcc/testsuite/gfortran.dg/goacc/classify-parallel.f95 b/gcc/testsuite/gfortran.dg/goacc/classify-parallel.f95
index a23ea81..01f06bb 100644
--- a/gcc/testsuite/gfortran.dg/goacc/classify-parallel.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/classify-parallel.f95
@@ -22,10 +22,10 @@ program main
end program main
! Check the offloaded function's attributes.
-! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(omp target entrypoint\\)\\)" 1 "ompexp" } }
+! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc parallel, omp target entrypoint\\)\\)" 1 "ompexp" } }
! Check the offloaded function's classification and compute dimensions (will
! always be 1 x 1 x 1 for non-offloading compilation).
! { dg-final { scan-tree-dump-times "(?n)Function is OpenACC parallel offload" 1 "oaccdevlow" } }
! { dg-final { scan-tree-dump-times "(?n)Compute dimensions \\\[1, 1, 1\\\]" 1 "oaccdevlow" } }
-! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(1, 1, 1\\), omp target entrypoint\\)\\)" 1 "oaccdevlow" } }
+! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(1, 1, 1\\), oacc parallel, omp target entrypoint\\)\\)" 1 "oaccdevlow" } }
diff --git a/gcc/testsuite/gfortran.dg/goacc/classify-serial.f95 b/gcc/testsuite/gfortran.dg/goacc/classify-serial.f95
new file mode 100644
index 0000000..51061af
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/classify-serial.f95
@@ -0,0 +1,31 @@
+! Check offloaded function's attributes and classification for OpenACC
+! serial.
+
+! { dg-additional-options "-O2" }
+! { dg-additional-options "-fopt-info-optimized-omp" }
+! { dg-additional-options "-fdump-tree-ompexp" }
+! { dg-additional-options "-fdump-tree-oaccdevlow" }
+
+program main
+ implicit none
+ integer, parameter :: n = 1024
+ integer, dimension (0:n-1) :: a, b, c
+ integer :: i
+
+ call setup(a, b)
+
+ !$acc serial loop copyin (a(0:n-1), b(0:n-1)) copyout (c(0:n-1)) ! { dg-message "optimized: assigned OpenACC gang vector loop parallelism" }
+ do i = 0, n - 1
+ c(i) = a(i) + b(i)
+ end do
+ !$acc end serial loop
+end program main
+
+! Check the offloaded function's attributes.
+! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc serial, omp target entrypoint\\)\\)" 1 "ompexp" } }
+
+! Check the offloaded function's classification and compute dimensions (will
+! always be 1 x 1 x 1 for non-offloading compilation).
+! { dg-final { scan-tree-dump-times "(?n)Function is OpenACC serial offload" 1 "oaccdevlow" } }
+! { dg-final { scan-tree-dump-times "(?n)Compute dimensions \\\[1, 1, 1\\\]" 1 "oaccdevlow" } }
+! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(1, 1, 1\\), oacc serial, omp target entrypoint\\)\\)" 1 "oaccdevlow" } }
diff --git a/gcc/testsuite/gfortran.dg/goacc/fixed-5.f b/gcc/testsuite/gfortran.dg/goacc/fixed-5.f
new file mode 100644
index 0000000..ab51b21
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/fixed-5.f
@@ -0,0 +1,30 @@
+! Check that OpenMP conditional compilations sentinels ('!$ ') are ignored
+
+c$ bogus
+!$ bogus
+*$ bogus
+c$ bogus
+!$ bogus
+*$ bogus
+
+c$a23 bogus
+!$ a bogus
+*$12a bogus
+
+c$ 1 bogus
+!$ 22 bogus
+*$34 bogus
+
+c$bogus
+!$bogus
+*$bogus
+
+c$ acc bogus
+!$ acc bogus
+*$ acc bogus
+
+c$ acc bogus
+!$ acc bogus
+*$ acc bogus
+
+ end
diff --git a/gcc/testsuite/gfortran.dg/goacc/kernels-decompose-1.f95 b/gcc/testsuite/gfortran.dg/goacc/kernels-decompose-1.f95
new file mode 100644
index 0000000..7e513f8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/kernels-decompose-1.f95
@@ -0,0 +1,89 @@
+! Test OpenACC 'kernels' construct decomposition.
+
+! { dg-additional-options "-fopt-info-omp-all" }
+! { dg-additional-options "-fdump-tree-gimple" }
+! { dg-additional-options "-fopenacc-kernels=decompose" }
+! { dg-additional-options "-fdump-tree-omp_oacc_kernels_decompose" }
+
+! See also '../../c-c++-common/goacc/kernels-decompose-1.c'.
+
+! It's only with Tcl 8.5 (released in 2007) that "the variable 'varName'
+! passed to 'incr' may be unset, and in that case, it will be set to [...]",
+! so to maintain compatibility with earlier Tcl releases, we manually
+! initialize counter variables:
+! { dg-line l_dummy[variable c_loop_i 0] }
+! { dg-message "dummy" "" { target iN-VAl-Id } l_dummy } to avoid
+! "WARNING: dg-line var l_dummy defined, but not used".
+
+program main
+ implicit none
+ integer, parameter :: N = 1024
+ integer, dimension (1:N) :: a
+ integer :: i, sum
+
+ !$acc kernels copyin(a(1:N)) copy(sum)
+ ! { dg-bogus "optimized: assigned OpenACC seq loop parallelism" "TODO" { xfail *-*-* } .-1 }
+ !TODO Is this maybe the report that belongs to the XFAILed report further down? */
+
+ !$acc loop ! { dg-line l_loop_i[incr c_loop_i] }
+ ! { dg-message "note: forwarded loop nest in OpenACC 'kernels' region to 'parloops' for analysis" "" { target *-*-* } l_loop_i$c_loop_i }
+ ! { dg-optimized "assigned OpenACC seq loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i }
+ do i = 1, N
+ sum = sum + a(i)
+ end do
+
+ sum = sum + 1 ! { dg-message "note: beginning 'gang-single' part in OpenACC 'kernels' region" }
+ a(1) = a(1) + 1
+
+ !$acc loop independent ! { dg-line l_loop_i[incr c_loop_i] }
+ ! { dg-message "note: parallelized loop nest in OpenACC 'kernels' region" "" { target *-*-* } l_loop_i$c_loop_i }
+ ! { dg-optimized "assigned OpenACC gang vector loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i }
+ do i = 1, N
+ sum = sum + a(i)
+ end do
+
+ if (sum .gt. 10) then ! { dg-message "note: beginning 'parloops' part in OpenACC 'kernels' region" }
+ !$acc loop ! { dg-line l_loop_i[incr c_loop_i] }
+ ! { dg-missed "unparallelized loop nest in OpenACC 'kernels' region: it's executed conditionally" "" { target *-*-* } l_loop_i$c_loop_i }
+ !TODO { dg-optimized "assigned OpenACC seq loop parallelism" "TODO" { xfail *-*-* } l_loop_i$c_loop_i }
+ do i = 1, N
+ sum = sum + a(i)
+ end do
+ end if
+
+ !$acc loop auto ! { dg-line l_loop_i[incr c_loop_i] }
+ ! { dg-message "note: forwarded loop nest in OpenACC 'kernels' region to 'parloops' for analysis" "" { target *-*-* } l_loop_i$c_loop_i }
+ ! { dg-optimized "assigned OpenACC seq loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i }
+ do i = 1, N
+ sum = sum + a(i)
+ end do
+
+ !$acc end kernels
+end program main
+
+! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_kernels map\(to:a\[_[0-9]+\] \[len: _[0-9]+\]\) map\(alloc:a \[pointer assign, bias: _[0-9]+\]\) map\(tofrom:sum \[len: [0-9]+\]\)$} 1 "gimple" } }
+
+! { dg-final { scan-tree-dump-times {(?n)#pragma acc loop private\(i\)$} 2 "gimple" } }
+! { dg-final { scan-tree-dump-times {(?n)#pragma acc loop private\(i\) independent$} 1 "gimple" } }
+! { dg-final { scan-tree-dump-times {(?n)#pragma acc loop private\(i\) auto$} 1 "gimple" } }
+! { dg-final { scan-tree-dump-times {(?n)#pragma acc loop} 4 "gimple" } }
+
+! Check that the OpenACC 'kernels' got decomposed into 'data' and an enclosed
+! sequence of compute constructs.
+! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_data_kernels map\(to:a\[_[0-9]+\] \[len: _[0-9]+\]\) map\(tofrom:sum \[len: [0-9]+\]\)$} 1 "omp_oacc_kernels_decompose" } }
+! As noted above, we get three "old-style" kernel regions, one gang-single region, and one parallelized loop region.
+! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_kernels async\(-1\) map\(force_present:a\[_[0-9]+\] \[len: _[0-9]+\]\) map\(alloc:a \[pointer assign, bias: _[0-9]+\]\) map\(force_present:sum \[len: [0-9]+\]\)$} 3 "omp_oacc_kernels_decompose" } }
+! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_parallel_kernels_parallelized async\(-1\) map\(force_present:a\[_[0-9]+\] \[len: _[0-9]+\]\) map\(alloc:a \[pointer assign, bias: _[0-9]+\]\) map\(force_present:sum \[len: [0-9]+\]\)$} 1 "omp_oacc_kernels_decompose" } }
+! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_parallel_kernels_gang_single async\(-1\) num_gangs\(1\) map\(force_present:a\[_[0-9]+\] \[len: _[0-9]+\]\) map\(alloc:a \[pointer assign, bias: _[0-9]+\]\) map\(force_present:sum \[len: [0-9]+\]\)$} 1 "omp_oacc_kernels_decompose" } }
+!
+! 'data' plus five CCs.
+! { dg-final { scan-tree-dump-times {(?n)#pragma omp target } 6 "omp_oacc_kernels_decompose" } }
+
+! { dg-final { scan-tree-dump-times {(?n)#pragma acc loop private\(i\)$} 2 "omp_oacc_kernels_decompose" } }
+! { dg-final { scan-tree-dump-times {(?n)#pragma acc loop private\(i\) independent$} 1 "omp_oacc_kernels_decompose" } }
+! { dg-final { scan-tree-dump-times {(?n)#pragma acc loop private\(i\) auto} 1 "omp_oacc_kernels_decompose" } }
+! { dg-final { scan-tree-dump-times {(?n)#pragma acc loop} 4 "omp_oacc_kernels_decompose" } }
+
+! Each of the parallel regions is async, and there is a final call to
+! __builtin_GOACC_wait.
+! { dg-final { scan-tree-dump-times "__builtin_GOACC_wait" 1 "omp_oacc_kernels_decompose" } }
diff --git a/gcc/testsuite/gfortran.dg/goacc/kernels-decompose-2.f95 b/gcc/testsuite/gfortran.dg/goacc/kernels-decompose-2.f95
new file mode 100644
index 0000000..22f65e5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/kernels-decompose-2.f95
@@ -0,0 +1,150 @@
+! Test OpenACC 'kernels' construct decomposition.
+
+! { dg-additional-options "-fopt-info-omp-all" }
+! { dg-additional-options "-fopenacc-kernels=decompose" }
+! { dg-additional-options "-O2" } for 'parloops'.
+
+! See also '../../c-c++-common/goacc/kernels-decompose-2.c'.
+
+! It's only with Tcl 8.5 (released in 2007) that "the variable 'varName'
+! passed to 'incr' may be unset, and in that case, it will be set to [...]",
+! so to maintain compatibility with earlier Tcl releases, we manually
+! initialize counter variables:
+! { dg-line l_dummy[variable c_loop_i 0 c_loop_j 0 c_loop_k 0 c_part 0] }
+! { dg-message "dummy" "" { target iN-VAl-Id } l_dummy } to avoid
+! "WARNING: dg-line var l_dummy defined, but not used".
+
+program main
+ implicit none
+
+ integer, external :: f_g
+ !$acc routine (f_g) gang
+ integer, external :: f_w
+ !$acc routine (f_w) worker
+ integer, external :: f_v
+ !$acc routine (f_v) vector
+ integer, external :: f_s
+ !$acc routine (f_s) seq
+
+ integer :: i, j, k
+ integer :: x, y, z
+ logical :: y_l
+ integer, parameter :: N = 10
+ integer :: a(N), b(N), c(N)
+
+ !$acc kernels
+ x = 0 ! { dg-message "note: beginning 'gang-single' part in OpenACC 'kernels' region" }
+ y = 0
+ y_l = x < 10
+ z = x
+ x = x + 1
+ ;
+ !$acc end kernels
+
+ !$acc kernels ! { dg-optimized "assigned OpenACC gang loop parallelism" }
+ do i = 1, N ! { dg-message "note: beginning 'parloops' part in OpenACC 'kernels' region" }
+ a(i) = 0
+ end do
+ !$acc end kernels
+
+ !$acc kernels loop ! { dg-line l_loop_i[incr c_loop_i] }
+ ! { dg-message "note: forwarded loop nest in OpenACC 'kernels' region to 'parloops' for analysis" "" { target *-*-* } l_loop_i$c_loop_i }
+ ! { dg-optimized "assigned OpenACC seq loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i }
+ do i = 1, N
+ b(i) = a(N - i + 1)
+ end do
+
+ !$acc kernels
+ !$acc loop ! { dg-line l_loop_i[incr c_loop_i] }
+ ! { dg-message "note: forwarded loop nest in OpenACC 'kernels' region to 'parloops' for analysis" "" { target *-*-* } l_loop_i$c_loop_i }
+ ! { dg-optimized "assigned OpenACC seq loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i }
+ do i = 1, N
+ b(i) = a(N - i + 1)
+ end do
+
+ !$acc loop ! { dg-line l_loop_i[incr c_loop_i] }
+ ! { dg-message "note: forwarded loop nest in OpenACC 'kernels' region to 'parloops' for analysis" "" { target *-*-* } l_loop_i$c_loop_i }
+ ! { dg-optimized "assigned OpenACC seq loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i }
+ do i = 1, N
+ c(i) = a(i) * b(i)
+ end do
+
+ a(z) = 0 ! { dg-message "note: beginning 'gang-single' part in OpenACC 'kernels' region" }
+
+ !$acc loop ! { dg-line l_loop_i[incr c_loop_i] }
+ ! { dg-message "note: forwarded loop nest in OpenACC 'kernels' region to 'parloops' for analysis" "" { target *-*-* } l_loop_i$c_loop_i }
+ ! { dg-optimized "assigned OpenACC seq loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i }
+ do i = 1, N
+ c(i) = c(i) + a(i)
+ end do
+
+ !$acc loop seq ! { dg-line l_loop_i[incr c_loop_i] }
+ ! { dg-message "note: parallelized loop nest in OpenACC 'kernels' region" "" { target *-*-* } l_loop_i$c_loop_i }
+ ! { dg-optimized "assigned OpenACC seq loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i }
+ do i = 1 + 1, N
+ c(i) = c(i) + c(i - 1)
+ end do
+ !$acc end kernels
+
+ !$acc kernels
+ !TODO What does this mean?
+ !TODO { dg-optimized "assigned OpenACC worker vector loop parallelism" "" { target *-*-* } .-2 }
+ !$acc loop independent ! { dg-line l_loop_i[incr c_loop_i] }
+ ! { dg-message "note: parallelized loop nest in OpenACC 'kernels' region" "" { target *-*-* } l_loop_i$c_loop_i }
+ ! { dg-optimized "assigned OpenACC gang loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i }
+ do i = 1, N
+ !$acc loop independent ! { dg-line l_loop_j[incr c_loop_j] }
+ ! { dg-optimized "assigned OpenACC worker loop parallelism" "" { target *-*-* } l_loop_j$c_loop_j }
+ do j = 1, N
+ !$acc loop independent ! { dg-line l_loop_k[incr c_loop_k] }
+ ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } l_loop_k$c_loop_k }
+ ! { dg-optimized "assigned OpenACC seq loop parallelism" "" { target *-*-* } l_loop_k$c_loop_k }
+ do k = 1, N
+ a(1 + mod(i + j + k, N)) &
+ = b(j) &
+ + f_v (c(k)) ! { dg-optimized "assigned OpenACC vector loop parallelism" }
+ end do
+ end do
+ end do
+
+ !TODO Should the following turn into "gang-single" instead of "parloops"?
+ !TODO The problem is that the first STMT is 'if (y <= 4) goto <D.2547>; else goto <D.2548>;', thus "parloops".
+ if (y < 5) then ! { dg-message "note: beginning 'parloops' part in OpenACC 'kernels' region" }
+ !$acc loop independent ! { dg-line l_loop_j[incr c_loop_j] }
+ ! { dg-missed "unparallelized loop nest in OpenACC 'kernels' region: it's executed conditionally" "" { target *-*-* } l_loop_j$c_loop_j }
+ do j = 1, N
+ b(j) = f_w (c(j))
+ end do
+ end if
+ !$acc end kernels
+
+ !$acc kernels
+ y = f_g (a(5)) ! { dg-line l_part[incr c_part] }
+ !TODO If such a construct is placed in its own part (like it is, here), can't this actually use gang paralelism, instead of "gang-single"?
+ ! { dg-message "note: beginning 'gang-single' part in OpenACC 'kernels' region" "" { target *-*-* } l_part$c_part }
+ ! { dg-optimized "assigned OpenACC gang worker vector loop parallelism" "" { target *-*-* } l_part$c_part }
+
+ !$acc loop independent ! { dg-line l_loop_j[incr c_loop_j] }
+ ! { dg-message "note: parallelized loop nest in OpenACC 'kernels' region" "" { target *-*-* } l_loop_j$c_loop_j }
+ ! { dg-optimized "assigned OpenACC gang loop parallelism" "" { target *-*-* } l_loop_j$c_loop_j }
+ do j = 1, N
+ b(j) = y + f_w (c(j)) ! { dg-optimized "assigned OpenACC worker vector loop parallelism" }
+ end do
+ !$acc end kernels
+
+ !$acc kernels
+ y = 3 ! { dg-message "note: beginning 'gang-single' part in OpenACC 'kernels' region" }
+
+ !$acc loop independent ! { dg-line l_loop_j[incr c_loop_j] }
+ ! { dg-message "note: parallelized loop nest in OpenACC 'kernels' region" "" { target *-*-* } l_loop_j$c_loop_j }
+ ! { dg-optimized "assigned OpenACC gang worker loop parallelism" "" { target *-*-* } l_loop_j$c_loop_j }
+ do j = 1, N
+ b(j) = y + f_v (c(j)) ! { dg-optimized "assigned OpenACC vector loop parallelism" }
+ end do
+
+ z = 2 ! { dg-message "note: beginning 'gang-single' part in OpenACC 'kernels' region" }
+ !$acc end kernels
+
+ !$acc kernels ! { dg-message "note: beginning 'gang-single' part in OpenACC 'kernels' region" }
+ !$acc end kernels
+end program main
diff --git a/gcc/testsuite/gfortran.dg/goacc/kernels-tree.f95 b/gcc/testsuite/gfortran.dg/goacc/kernels-tree.f95
index 5583ffb..d01eee2 100644
--- a/gcc/testsuite/gfortran.dg/goacc/kernels-tree.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/kernels-tree.f95
@@ -1,5 +1,7 @@
! { dg-do compile }
! { dg-additional-options "-fdump-tree-original" }
+! { dg-additional-options "-fopenacc-kernels=decompose" }
+! { dg-additional-options "-fdump-tree-omp_oacc_kernels_decompose" }
program test
implicit none
@@ -34,3 +36,6 @@ end program test
! { dg-final { scan-tree-dump-times "map\\(alloc:t\\)" 1 "original" } }
! { dg-final { scan-tree-dump-times "map\\(force_deviceptr:u\\)" 1 "original" } }
+
+! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_data_kernels if\(D\.[0-9]+\)$} 1 "omp_oacc_kernels_decompose" } }
+! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_parallel_kernels_gang_single num_gangs\(1\) if\(D\.[0-9]+\) async\(-1\)$} 1 "omp_oacc_kernels_decompose" } }
diff --git a/gcc/testsuite/gfortran.dg/goacc/sentinel-free-form.f95 b/gcc/testsuite/gfortran.dg/goacc/sentinel-free-form.f95
index 1a3189c..00dac66 100644
--- a/gcc/testsuite/gfortran.dg/goacc/sentinel-free-form.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/sentinel-free-form.f95
@@ -10,7 +10,10 @@ program test
x = 0.0 !$acc parallel ! comment
! sentinel must appear as a single word
! $acc parallel ! comment
- !$ acc parallel ! { dg-error "Unclassifiable statement" }
+
+ ! note that '!$ ' is OpenMP's conditional compilation sentinel
+ !$ acc ignored_due_to_space ! comment
+
! directive lines must have space after sentinel
!$accparallel ! { dg-warning "followed by a space" }
do i = 1,10
@@ -18,4 +21,4 @@ program test
enddo
!$acc end parallel ! { dg-error "Unexpected" }
print *, x
-end \ No newline at end of file
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-target-4.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-target-4.f90
index 6e3f91e..8947b88 100644
--- a/gcc/testsuite/gfortran.dg/gomp/declare-target-4.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/declare-target-4.f90
@@ -71,11 +71,11 @@ end module m2
! { dg-final { scan-tree-dump-times "omp declare target" 7 "original" } }
! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(" 7 "original" } }
-! { dg-final { scan-tree-dump-times "\[\n\r]\[\n\r]f1" 1 "original" } }
-! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(any\\)\\)\\)\\)\[\n\r]f2" 1 "original" } }
-! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(any\\)\\)\\)\\)\[\n\r]f3" 1 "original" } }
-! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(host\\)\\)\\)\\)\[\n\r]f4" 1 "original" } }
-! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(nohost\\)\\)\\)\\)\[\n\r]f5" 1 "original" } }
-! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(any\\)\\)\\)\\)\[\n\r]s1" 1 "original" } }
-! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(nohost\\)\\)\\)\\)\[\n\r]s2" 1 "original" } }
-! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(host\\)\\)\\)\\)\[\n\r]s3" 1 "original" } }
+! { dg-final { scan-tree-dump-not "__attribute__\\(\\(omp declare target \[^\n\r\]*\[\n\r\]void f1" "original" } }
+! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(any\\)\\)\\)\\)\[\n\r]__attribute__\[^\n\r]+\[\n\r]void f2" 1 "original" } }
+! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(any\\)\\)\\)\\)\[\n\r]__attribute__\[^\n\r]+\[\n\r\]void f3" 1 "original" } }
+! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(host\\)\\)\\)\\)\[\n\r]__attribute__\[^\n\r]+\[\n\r\]void f4" 1 "original" } }
+! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(nohost\\)\\)\\)\\)\[\n\r]__attribute__\[^\n\r]+\[\n\r\]void f5" 1 "original" } }
+! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(any\\)\\)\\)\\)\[\n\r]__attribute__\[^\n\r]+\[\n\r\]void s1" 1 "original" } }
+! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(nohost\\)\\)\\)\\)\[\n\r]__attribute__\[^\n\r]+\[\n\r\]void s2" 1 "original" } }
+! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(host\\)\\)\\)\\)\[\n\r]__attribute__\[^\n\r]+\[\n\r\]void s3" 1 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/reduction4.f90 b/gcc/testsuite/gfortran.dg/gomp/reduction4.f90
new file mode 100644
index 0000000..af8c91b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/reduction4.f90
@@ -0,0 +1,171 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original" }
+!
+! (in_)reduction clause
+! Test all in-principle valid combinations, even if
+! not valid in this context (some fail at ME level)
+!
+implicit none
+integer :: a, b, i
+a = 0
+
+! ------------ parallel ------------
+!$omp parallel reduction(+:a)
+do i=1,10
+ a = a + 1
+end do
+!$omp end parallel
+
+!$omp parallel reduction(default,+:a)
+do i=1,10
+ a = a + 1
+end do
+!$omp end parallel
+
+!$omp parallel reduction(task,+:a)
+do i=1,10
+ a = a + 1
+end do
+!$omp end parallel
+
+!$omp parallel reduction(inscan,+:a) ! { dg-error "'inscan' 'reduction' clause on 'parallel' construct" }
+do i=1,10
+ a = a + 1
+end do
+!$omp end parallel
+
+! ------------ simd ------------
+!$omp simd reduction(+:a)
+do i=1,10
+ a = a + 1
+end do
+
+!$omp simd reduction(default,+:a)
+do i=1,10
+ a = a + 1
+end do
+
+!$omp simd reduction(task,+:a) ! { dg-error "invalid 'task' reduction modifier on construct other than 'parallel', 'do' or 'sections'" }
+do i=1,10
+ a = a + 1
+end do
+
+!$omp simd reduction(inscan,+:a) ! { dg-error "'inscan' 'reduction' clause but not in 'scan' directive clause" }
+do i=1,10
+ a = a + 1
+end do
+
+! ------------ do ------------
+!$omp parallel
+!$omp do reduction(+:a)
+do i=1,10
+ a = a + 1
+end do
+!$omp end parallel
+
+!$omp parallel
+!$omp do reduction(default,+:a)
+do i=1,10
+ a = a + 1
+end do
+!$omp end parallel
+
+!$omp parallel
+!$omp do reduction(task,+:a)
+do i=1,10
+ a = a + 1
+end do
+!$omp end parallel
+
+!$omp parallel
+!$omp do reduction(inscan,+:a) ! { dg-error "'a' specified in 'inscan' 'reduction' clause but not in 'scan' directive clause" }
+do i=1,10
+ a = a + 1
+end do
+!$omp end parallel
+
+! ------------ section ------------
+!$omp parallel
+!$omp sections reduction(+:a)
+ !$omp section
+ a = a + 1
+!$omp end sections
+!$omp end parallel
+
+!$omp parallel
+!$omp sections reduction(default,+:a)
+ !$omp section
+ a = a + 1
+!$omp end sections
+!$omp end parallel
+
+!$omp parallel
+!$omp sections reduction(task,+:a)
+ !$omp section
+ a = a + 1
+!$omp end sections
+!$omp end parallel
+
+!$omp parallel
+!$omp sections reduction(inscan,+:a) ! { dg-error "'inscan' 'reduction' clause on 'sections' construct" }
+ !$omp section
+ a = a + 1
+!$omp end sections
+!$omp end parallel
+
+! ------------ task ------------
+!$omp task in_reduction(+:a)
+ a = a + 1
+!$omp end task
+
+! ------------ taskloop ------------
+!$omp taskloop reduction(+:a) in_reduction(+:b)
+do i=1,10
+ a = a + 1
+end do
+
+!$omp taskloop reduction(default,+:a) in_reduction(+:b)
+do i=1,10
+ a = a + 1
+end do
+
+! ------------ target ------------
+!$omp target in_reduction(+:b)
+ a = a + 1
+!$omp end target
+
+! ------------ teams ------------
+!$omp teams reduction(+:b)
+ a = a + 1
+!$omp end teams
+
+!$omp teams reduction(default, +:b)
+ a = a + 1
+!$omp end teams
+
+! ------------ taskgroup --------
+
+!$omp taskgroup task_reduction(+:b)
+ a = a + 1
+!$omp end taskgroup
+
+end
+
+! { dg-final { scan-tree-dump-times "#pragma omp for reduction\\(\\\+:a\\)" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp for reduction\\(inscan,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp for reduction\\(task,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel\[\n\r\]" 8 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel private\\(i\\) reduction\\(\\\+:a\\)" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel private\\(i\\) reduction\\(inscan,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel private\\(i\\) reduction\\(task,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp section\[\n\r\]" 4 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp sections reduction\\(\\\+:a\\)" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp sections reduction\\(inscan,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp sections reduction\\(task,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\) reduction\\(\\\+:a\\)" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\) reduction\\(inscan,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\) reduction\\(task,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target in_reduction\\(\\\+:b\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task in_reduction\\(\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp teams reduction\\(\\\+:b\\)" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp taskloop reduction\\(\\\+:a\\) in_reduction\\(\\\+:b\\)" 2 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/reduction5.f90 b/gcc/testsuite/gfortran.dg/gomp/reduction5.f90
new file mode 100644
index 0000000..df915f1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/reduction5.f90
@@ -0,0 +1,41 @@
+! { dg-do compile }
+!
+implicit none
+integer :: a, b, i
+a = 0
+
+!$omp parallel reduction(foo,+:a) ! { dg-error "26: Failed to match clause" }
+do i=1,10
+ a = a + 1
+end do
+!$omp end parallel ! { dg-error "Unexpected !.OMP END PARALLEL statement" }
+
+!$omp parallel reduction(task +:a) ! { dg-error "30: Comma expected at" }
+do i=1,10
+ a = a + 1
+end do
+!$omp end parallel ! { dg-error "Unexpected !.OMP END PARALLEL statement" }
+
+!$omp task in_reduction(foo,+:a) ! { dg-error "25: Failed to match clause" }
+ a = a + 1
+!$omp end task ! { dg-error "Unexpected !.OMP END TASK statement" }
+
+!$omp taskloop reduction(inscan,+:a) in_reduction(+:b) ! { dg-error "34: Only DEFAULT permitted as reduction-modifier in REDUCTION clause" }
+do i=1,10
+ a = a + 1
+end do
+
+!$omp taskloop reduction(task,+:a) in_reduction(+:b) ! { dg-error "32: Only DEFAULT permitted as reduction-modifier in REDUCTION clause" }
+do i=1,10
+ a = a + 1
+end do
+
+!$omp teams reduction(inscan,+:b) ! { dg-error "31: Only DEFAULT permitted as reduction-modifier in REDUCTION clause" }
+ a = a + 1
+!$omp end teams
+
+!$omp teams reduction(task, +:b) ! { dg-error "30: Only DEFAULT permitted as reduction-modifier in REDUCTION clause" }
+ a = a + 1
+!$omp end teams
+
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/requires-4.f90 b/gcc/testsuite/gfortran.dg/gomp/requires-4.f90
index e0eb4db..b17aceb 100644
--- a/gcc/testsuite/gfortran.dg/gomp/requires-4.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/requires-4.f90
@@ -26,11 +26,11 @@ program main
!$omp requires reverse_offload
contains
subroutine foo
- !$target
- !$end target
+ !$omp target
+ !$omp end target
end subroutine
subroutine bar
- !$omp requires unified_addres ! { dg-error "must appear in the specification part of a program unit" }
+ !$omp requires unified_address ! { dg-error "must appear in the specification part of a program unit" }
end subroutine bar
end
! { dg-prune-output "not yet supported" }
diff --git a/gcc/testsuite/gfortran.dg/gomp/schedule-modifiers-2.f90 b/gcc/testsuite/gfortran.dg/gomp/schedule-modifiers-2.f90
index 0be53cc..537fba2 100644
--- a/gcc/testsuite/gfortran.dg/gomp/schedule-modifiers-2.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/schedule-modifiers-2.f90
@@ -3,16 +3,16 @@
subroutine foo
integer :: i
- !$omp do schedule (nonmonotonic: static, 2) ! { dg-error "NONMONOTONIC modifier specified for STATIC schedule kind" }
+ !$omp do schedule (nonmonotonic: static, 2)
do i = 0, 64
end do
- !$omp do schedule (nonmonotonic : static) ! { dg-error "NONMONOTONIC modifier specified for STATIC schedule kind" }
+ !$omp do schedule (nonmonotonic : static)
do i = 0, 64
end do
- !$omp do schedule (nonmonotonic : runtime) ! { dg-error "NONMONOTONIC modifier specified for RUNTIME schedule kind" }
+ !$omp do schedule (nonmonotonic : runtime)
do i = 0, 64
end do
- !$omp do schedule (nonmonotonic : auto) ! { dg-error "NONMONOTONIC modifier specified for AUTO schedule kind" }
+ !$omp do schedule (nonmonotonic : auto)
do i = 0, 64
end do
!$omp do schedule (nonmonotonic : dynamic) ordered ! { dg-error "NONMONOTONIC schedule modifier specified with ORDERED clause" }
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-1.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-1.f90
new file mode 100644
index 0000000..3e639d2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-1.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 0, 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_maybe_nonmonotonic_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (runtime)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-10.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-10.f90
new file mode 100644
index 0000000..e71ac3f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-10.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (nonmonotonic: static, 2)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-11.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-11.f90
new file mode 100644
index 0000000..9420220
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-11.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (dynamic)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-12.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-12.f90
new file mode 100644
index 0000000..66c6eb1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-12.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (monotonic: dynamic)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-13.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-13.f90
new file mode 100644
index 0000000..89782d2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-13.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (nonmonotonic: dynamic)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-14.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-14.f90
new file mode 100644
index 0000000..16b3e01
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-14.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (dynamic, 3)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-15.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-15.f90
new file mode 100644
index 0000000..8bf126c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-15.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483650|-2147483646), 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (monotonic: dynamic, 3)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-16.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-16.f90
new file mode 100644
index 0000000..fe8d1ae
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-16.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (nonmonotonic: dynamic, 3)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-17.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-17.f90
new file mode 100644
index 0000000..1f2823d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-17.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (guided)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-18.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-18.f90
new file mode 100644
index 0000000..ad0856a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-18.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483651|-2147483645), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (monotonic: guided)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-19.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-19.f90
new file mode 100644
index 0000000..e884dbf
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-19.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (nonmonotonic: guided)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-2.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-2.f90
new file mode 100644
index 0000000..2f78c0b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-2.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483648|-2147483648), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (monotonic: runtime)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-20.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-20.f90
new file mode 100644
index 0000000..8a4d6df
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-20.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (guided, 3)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-21.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-21.f90
new file mode 100644
index 0000000..2d9362b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-21.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483651|-2147483645), 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (monotonic: guided, 3)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-22.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-22.f90
new file mode 100644
index 0000000..485171f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-22.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (nonmonotonic: guided, 3)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-23.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-23.f90
new file mode 100644
index 0000000..45dc000
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-23.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (auto)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-24.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-24.f90
new file mode 100644
index 0000000..e7fbe92
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-24.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (monotonic: auto)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-25.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-25.f90
new file mode 100644
index 0000000..d5554c4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-25.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (nonmonotonic: auto)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90
new file mode 100644
index 0000000..d98f589
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-26.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 0, 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_maybe_nonmonotonic_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (runtime)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90
new file mode 100644
index 0000000..99a94f8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-27.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, (?:2147483648|-2147483648), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (monotonic: runtime)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90
new file mode 100644
index 0000000..bf28cba
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-28.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 4, 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (nonmonotonic: runtime)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-29.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-29.f90
new file mode 100644
index 0000000..316b72e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-29.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90
new file mode 100644
index 0000000..bf28cba
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-3.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 4, 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (nonmonotonic: runtime)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-30.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-30.f90
new file mode 100644
index 0000000..b9406d6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-30.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (static)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-31.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-31.f90
new file mode 100644
index 0000000..4a24604
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-31.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (monotonic: static)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-32.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-32.f90
new file mode 100644
index 0000000..a7062d9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-32.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (nonmonotonic: static)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-33.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-33.f90
new file mode 100644
index 0000000..67c25c8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-33.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (static, 2)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-34.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-34.f90
new file mode 100644
index 0000000..f1e4d89
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-34.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (monotonic: static, 2)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-35.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-35.f90
new file mode 100644
index 0000000..7d7c271
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-35.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (nonmonotonic: static, 2)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90
new file mode 100644
index 0000000..bfddf84
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-36.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (dynamic)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90
new file mode 100644
index 0000000..183d30b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-37.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (monotonic: dynamic)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90
new file mode 100644
index 0000000..3343388
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-38.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 2, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (nonmonotonic: dynamic)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90
new file mode 100644
index 0000000..a86a1e8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-39.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (dynamic, 3)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-4.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-4.f90
new file mode 100644
index 0000000..c774427
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-4.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90
new file mode 100644
index 0000000..fedbd8f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-40.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, (?:2147483650|-2147483646), 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (monotonic: dynamic, 3)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90
new file mode 100644
index 0000000..a208b49
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-41.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 2, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (nonmonotonic: dynamic, 3)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90
new file mode 100644
index 0000000..0542eca
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-42.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (guided)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90
new file mode 100644
index 0000000..bfd35c9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-43.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, (?:2147483651|-2147483645), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (monotonic: guided)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90
new file mode 100644
index 0000000..0cdc314
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-44.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 3, 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (nonmonotonic: guided)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90
new file mode 100644
index 0000000..a7130e9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-45.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (guided, 3)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90
new file mode 100644
index 0000000..e769574
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-46.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, (?:2147483651|-2147483645), 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (monotonic: guided, 3)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90
new file mode 100644
index 0000000..06170d7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-47.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_start \[^\n\r]*, 3, 3, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_nonmonotonic_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (nonmonotonic: guided, 3)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-48.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-48.f90
new file mode 100644
index 0000000..1370010
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-48.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (auto)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-49.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-49.f90
new file mode 100644
index 0000000..ab2591f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-49.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (monotonic: auto)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-5.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-5.f90
new file mode 100644
index 0000000..ce3db0f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-5.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (static)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-50.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-50.f90
new file mode 100644
index 0000000..8b89427
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-50.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_ull\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (nonmonotonic: auto)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-51.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-51.f90
new file mode 100644
index 0000000..13bde3a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-51.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_start \[^\n\r]*, (?:2147483648|-2147483648), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_start " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do ordered reduction (task, *: j) schedule (runtime)
+ do i = a, b, c
+ call bar (j)
+ !$omp ordered
+ j = j + 1
+ !$omp end ordered
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-52.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-52.f90
new file mode 100644
index 0000000..50dce3d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-52.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_start \[^\n\r]*, (?:2147483649|-2147483647), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_start " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_static_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do ordered reduction (task, *: j)
+ do i = a, b, c
+ call bar (j)
+ !$omp ordered
+ j = j + 1
+ !$omp end ordered
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-53.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-53.f90
new file mode 100644
index 0000000..0184209
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-53.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_start \[^\n\r]*, (?:2147483650|-2147483646), 4, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_start " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do ordered reduction (task, *: j) schedule (dynamic, 4)
+ do i = a, b, c
+ call bar (j)
+ !$omp ordered
+ j = j + 1
+ !$omp end ordered
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-54.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-54.f90
new file mode 100644
index 0000000..0681e43
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-54.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_start \[^\n\r]*, (?:2147483651|-2147483645), 6, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_start " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_ordered_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_ordered_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do ordered reduction (task, *: j) schedule (guided, 6)
+ do i = a, b, c
+ call bar (j)
+ !$omp ordered
+ j = j + 1
+ !$omp end ordered
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-55.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-55.f90
new file mode 100644
index 0000000..4d2e1e5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-55.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_doacross_start \[^\n\r]*, (?:2147483648|-2147483648), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_post " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_wait " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_runtime_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do ordered(1) reduction (task, *: j) schedule (runtime)
+ do i = a, b, c
+ call bar (j)
+ !$omp ordered depend(sink: i - 1)
+ j = j + 1
+ !$omp ordered depend(source)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90
new file mode 100644
index 0000000..a5fa4c0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-56.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_doacross_start \[^\n\r]*, (?:2147483649|-2147483647), 0, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)?_post " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)?_wait " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_static_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do ordered(1) reduction (task, *: j)
+ do i = a, b, c
+ call bar (j)
+ !$omp ordered depend(sink: i - 1)
+ j = j + 1
+ !$omp ordered depend(source)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90
new file mode 100644
index 0000000..6c52aba
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-57.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_doacross_start \[^\n\r]*, (?:2147483650|-2147483646), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)?_post " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross(?:_ull)?_wait " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop(?:_ull)?_dynamic_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer(8) :: j
+ interface
+ subroutine bar(i)
+ integer(8) :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer(8) :: a, b ,c
+ integer(8) :: i
+ !$omp parallel
+ !$omp do ordered(1) reduction (task, *: j) schedule (dynamic)
+ do i = a, b, c
+ call bar (j)
+ !$omp ordered depend(sink: i - 1)
+ j = j + 1
+ !$omp ordered depend(source)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-58.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-58.f90
new file mode 100644
index 0000000..ae4f8bc
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-58.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_doacross_start \[^\n\r]*, (?:2147483651|-2147483645), 1, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_post " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_doacross_wait " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_guided_next " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do ordered(1) reduction (task, *: j) schedule (guided)
+ do i = a, b, c
+ call bar (j)
+ !$omp ordered depend(sink: i - 1)
+ j = j + 1
+ !$omp ordered depend(source)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-6.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-6.f90
new file mode 100644
index 0000000..147f14a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-6.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (monotonic: static)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-7.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-7.f90
new file mode 100644
index 0000000..dc99a75
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-7.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (nonmonotonic: static)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-8.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-8.f90
new file mode 100644
index 0000000..9d0a1ce
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-8.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (static, 2)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-9.f90 b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-9.f90
new file mode 100644
index 0000000..c613746
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/workshare-reduction-9.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-optimized" }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_start \[^\n\r]*, (?:2147483649|-2147483647), 0, 0B, 0B, " 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_loop_end " 1 "optimized" } }
+! { dg-final { scan-tree-dump-not "__builtin_GOMP_loop\[^\n\r]*_next " "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_workshare_task_reduction_unregister \\(0\\)" 1 "optimized" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel " 1 "optimized" } }
+
+module m
+ implicit none (type, external)
+ integer :: j
+ interface
+ subroutine bar(i)
+ integer :: i
+ end subroutine
+ end interface
+end module m
+
+subroutine foo(a, b, c)
+ use m
+ implicit none (type, external)
+ integer :: a, b ,c
+ integer :: i
+ !$omp parallel
+ !$omp do reduction (task, *: j) schedule (monotonic: static, 2)
+ do i = a, b, c
+ j = j + 1
+ call bar (j)
+ end do
+ !$omp end parallel
+end
diff --git a/gcc/testsuite/gfortran.dg/ipcp-array-2.f90 b/gcc/testsuite/gfortran.dg/ipcp-array-2.f90
new file mode 100644
index 0000000..9af8fff
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/ipcp-array-2.f90
@@ -0,0 +1,45 @@
+! { dg-do compile }
+! { dg-options "-O3 -fno-inline -fwhole-program -fdump-ipa-cp-details -fdump-tree-lversion-details" }
+
+module x
+ implicit none
+contains
+ subroutine foo(a, b)
+ real :: a(:,:)
+ real :: b
+ integer :: i,j
+ b = 0.
+ do j=1,size(a,2)
+ do i=1,size(a,1)
+ b = b + a(i,j) * i * j
+ end do
+ end do
+ end subroutine foo
+
+ subroutine bar(a, b)
+ real :: a(:,:)
+ real :: b
+ call foo (a,b)
+ end subroutine bar
+
+end module x
+
+program main
+ use x
+ implicit none
+ integer :: n, m
+ real, dimension(4,3) :: a
+ real, dimension(3,4) :: c
+ real :: b
+ call random_number(a)
+ call bar(a,b)
+ print *,b
+
+ call random_number(c)
+ call bar(c,b)
+ print *,b
+
+end program main
+
+! { dg-final { scan-ipa-dump "op assert_expr 1" "cp" } }
+! { dg-final { scan-tree-dump-not "versioned this loop for when certain strides are 1" "lversion" } }
diff --git a/gcc/testsuite/gfortran.dg/pr48958.f90 b/gcc/testsuite/gfortran.dg/pr48958.f90
new file mode 100644
index 0000000..2b10937
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr48958.f90
@@ -0,0 +1,25 @@
+! { dg-do run }
+! { dg-options "-fcheck=pointer -fdump-tree-original" }
+! { dg-shouldfail "Fortran runtime error: Allocatable argument 'a' is not allocated" }
+! { dg-output "At line 13 .*" }
+! PR48958 - Add runtime diagnostics for SIZE intrinsic function
+
+program p
+ integer :: n
+ integer, allocatable :: a(:)
+ integer, pointer :: b(:)
+ class(*), allocatable :: c(:)
+ integer :: d(10)
+ print *, size (a)
+ print *, size (b)
+ print *, size (c)
+ print *, size (d)
+ print *, size (f(n))
+contains
+ function f (n)
+ integer, intent(in) :: n
+ real, allocatable :: f(:)
+ end function f
+end
+
+! { dg-final { scan-tree-dump-times "_gfortran_runtime_error_at" 4 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/pr85796.f90 b/gcc/testsuite/gfortran.dg/pr85796.f90
new file mode 100644
index 0000000..7868378
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr85796.f90
@@ -0,0 +1,8 @@
+! { dg-do compile }
+! PR fortran/85796 - Floating point exception with implied do in data statement
+
+program p
+ implicit none
+ integer :: i, j, x(2,2)
+ data ((x(i,j),i=1,2,j-1),j=1,2) /3*789/ ! { dg-error "step of implied-do loop" }
+end
diff --git a/gcc/testsuite/gfortran.dg/pr95342.f90 b/gcc/testsuite/gfortran.dg/pr95342.f90
new file mode 100644
index 0000000..41c987d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr95342.f90
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! PR fortran/95342 - ICE in gfc_match_subroutine, at fortran/decl.c:7913
+
+module m1
+ interface
+ module subroutine s()
+ end
+ subroutine s() bind(c) ! { dg-error "EXTERNAL attribute conflicts" }
+ end ! { dg-error "END INTERFACE" }
+ end interface
+end
+
+module m2
+ interface
+ module function f()
+ end
+ function f() bind(c)
+ end ! { dg-error "Duplicate EXTERNAL attribute" }
+ end interface
+end
diff --git a/gcc/testsuite/gfortran.dg/pr97768_1.f90 b/gcc/testsuite/gfortran.dg/pr97768_1.f90
new file mode 100644
index 0000000..fce01e3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr97768_1.f90
@@ -0,0 +1,25 @@
+! PR fortran/97768
+! { dg-do compile }
+
+module pr97768_1
+ interface operator(.in.)
+ module procedure substr_in_str
+ end interface
+contains
+ pure function to_upper (in_str) result (string)
+ character(len=*), intent(in) :: in_str
+ character(len=len(in_str)) :: string
+ string = in_str
+ end function to_upper
+ logical pure function substr_in_str (substring, string)
+ character(len=*), intent(in) :: string, substring
+ substr_in_str=.false.
+ end function
+end module
+function foo ()
+ use pr97768_1, only : to_upper, operator(.in.)
+ logical :: foo
+ character(len=8) :: str
+ str = 'abcde'
+ foo = 'b' .in. to_upper (str)
+end function foo
diff --git a/gcc/testsuite/gfortran.dg/pr97768_2.f90 b/gcc/testsuite/gfortran.dg/pr97768_2.f90
new file mode 100644
index 0000000..5dc1987
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr97768_2.f90
@@ -0,0 +1,53 @@
+! PR fortran/97768
+! { dg-do compile }
+
+module pr97768_2
+ interface operator(.in.)
+ module procedure substr_in_str
+ end interface
+contains
+ pure function to_upper (in_str) result (string)
+ character(len=*), intent(in) :: in_str
+ character(len=len(in_str)) :: string
+ string = in_str
+ end function to_upper
+ logical pure function substr_in_str (substring, string)
+ character(len=*), intent(in) :: string, substring
+ substr_in_str=.false.
+ end function
+end module
+function foo ()
+ use pr97768_2, only : to_upper, operator(.in.)
+ logical :: foo
+ character(len=8) :: str
+ str = 'abcde'
+ foo = to_upper (str) .in. 32 ! { dg-error "are CHARACTER/INTEGER" }
+end function foo
+function bar (str)
+ use pr97768_2, only : operator(.in.)
+ logical :: bar
+ character(len=*) :: str
+ foo = str .in. 32 ! { dg-error "are CHARACTER\\(\\*\\)/INTEGER" }
+end function bar
+function baz (lenstr)
+ use pr97768_2, only : operator(.in.)
+ logical :: baz
+ integer :: lenstr
+ character(len=lenstr) :: str
+ str = 'abc'
+ foo = str .in. 32 ! { dg-error "are CHARACTER/INTEGER" }
+end function baz
+function qux ()
+ use pr97768_2, only : operator(.in.)
+ logical :: qux
+ character(len=8) :: str
+ str = 'def'
+ foo = str .in. 32 ! { dg-error "are CHARACTER\\(8\\)/INTEGER" }
+end function qux
+function corge ()
+ use pr97768_2, only : operator(.in.)
+ logical :: corge
+ character(len=:), allocatable :: str
+ str = 'ghijk'
+ foo = str .in. 32 ! { dg-error "are CHARACTER\\(:\\)/INTEGER" }
+end function corge
diff --git a/gcc/testsuite/gfortran.dg/pr98017.f90 b/gcc/testsuite/gfortran.dg/pr98017.f90
new file mode 100644
index 0000000..ab60407
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr98017.f90
@@ -0,0 +1,14 @@
+! { dg-do run }
+! PR98017 - [8/9/10/11 Regression] Suspected regression using PACK
+
+program p
+ implicit none
+ character(*), parameter :: s(1) = ['abc()']
+ character(*), parameter :: t(*) = s(:)(:1)
+ if (len (pack (s, s(:)(:1) == 'a')) /= len (s)) stop 1
+ if (any (pack (s, s(:)(:1) == 'a') /= s)) stop 2
+ if (len (pack (s, t == 'a')) /= len (s)) stop 3
+ if (any (pack (s, t == 'a') /= s)) stop 4
+ if (len (pack (s(:)(1:5), t == 'a')) /= len (s)) stop 5
+ if (any (pack (s(:)(1:5), t == 'a') /= s)) stop 6
+end
diff --git a/gcc/testsuite/gnat.dg/bias2.adb b/gcc/testsuite/gnat.dg/bias2.adb
new file mode 100644
index 0000000..a32e9a3
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/bias2.adb
@@ -0,0 +1,33 @@
+-- { dg-do run }
+
+procedure Bias2 is
+
+ type Biased_T is range 1 .. 2 ** 6;
+ for Biased_T'Size use 6; -- { dg-warning "biased representation" }
+ X, Y : Biased_T;
+
+begin
+ X := 1;
+ Y := 1;
+ if X + Y /= 2 then
+ raise Program_Error;
+ end if;
+
+ X := 2;
+ Y := 1;
+ if X - Y /= 1 then
+ raise Program_Error;
+ end if;
+
+ X := 2;
+ Y := 3;
+ if X * Y /= 6 then
+ raise Program_Error;
+ end if;
+
+ X := 24;
+ Y := 3;
+ if X / Y /= 8 then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/multfixed.adb b/gcc/testsuite/gnat.dg/multfixed.adb
index 572cd32..6eeda88 100644
--- a/gcc/testsuite/gnat.dg/multfixed.adb
+++ b/gcc/testsuite/gnat.dg/multfixed.adb
@@ -1,6 +1,7 @@
-- { dg-do run }
with Ada.Exceptions; use Ada.Exceptions;
+with Ada.Strings.Fixed; use Ada.Strings.Fixed;
procedure Multfixed is
Z : constant := 4387648782261400837.0;
@@ -18,7 +19,7 @@ begin
raise Program_Error;
exception
when Exc : Constraint_Error =>
- if Exception_Message (Exc) /= "System.Arith_64.Impl.Raise_Error: Double arithmetic overflow" then
+ if Count (Exception_Message (Exc), "overflow") = 0 then
raise Program_Error;
end if;
end Multfixed;
diff --git a/gcc/testsuite/gnat.dg/opt89.adb b/gcc/testsuite/gnat.dg/opt89.adb
new file mode 100644
index 0000000..3752008
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt89.adb
@@ -0,0 +1,18 @@
+-- { dg-do run }
+-- { dg-options "-O" }
+
+procedure Opt89 is
+
+ type Rec is record
+ I : Integer := 3;
+ end record;
+
+ subtype Index is Natural range 0..0;
+
+ type Arr is array (Index range <>) of Rec;
+
+ X : Arr (0 .. -1);
+
+begin
+ null;
+end;
diff --git a/gcc/testsuite/gnat.dg/opt90a.adb b/gcc/testsuite/gnat.dg/opt90a.adb
new file mode 100644
index 0000000..7de6289
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt90a.adb
@@ -0,0 +1,16 @@
+-- { dg-do run }
+-- { dg-options "-O2" }
+
+with Ada.Calendar; use Ada.Calendar;
+with Opt90a_Pkg; use Opt90a_Pkg;
+
+procedure Opt90a is
+ B : constant Integer := Year (Clock);
+ V : Data;
+
+begin
+ V := (R => (A => 0, B => B, C => "000000000000"));
+ if V.R.B /= B then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/opt90a_pkg.ads b/gcc/testsuite/gnat.dg/opt90a_pkg.ads
new file mode 100644
index 0000000..10a527b
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt90a_pkg.ads
@@ -0,0 +1,15 @@
+package Opt90a_Pkg is
+
+ type Rec is record
+ A : Short_Short_Integer;
+ B : Integer;
+ C : String (1 .. 12);
+ end record;
+ pragma Pack (Rec);
+ for Rec'Alignment use 1;
+
+ type Data is tagged record
+ R : Rec;
+ end record;
+
+end Opt90a_Pkg;
diff --git a/gcc/testsuite/gnat.dg/opt90b.adb b/gcc/testsuite/gnat.dg/opt90b.adb
new file mode 100644
index 0000000..6da58bb
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt90b.adb
@@ -0,0 +1,16 @@
+-- { dg-do run }
+-- { dg-options "-O2" }
+
+with Ada.Calendar; use Ada.Calendar;
+with Opt90b_Pkg; use Opt90b_Pkg;
+
+procedure Opt90b is
+ B : constant Integer := Year (Clock);
+ V : Data;
+
+begin
+ V := (R => (A => 0, B => B, C => 0, D => "000000000000"));
+ if V.R.B /= B then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/opt90b_pkg.ads b/gcc/testsuite/gnat.dg/opt90b_pkg.ads
new file mode 100644
index 0000000..f0b233c
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt90b_pkg.ads
@@ -0,0 +1,16 @@
+package Opt90b_Pkg is
+
+ type Rec is record
+ A : Short_Short_Integer;
+ B : Integer;
+ C : Short_Integer;
+ D : String (1 .. 12);
+ end record;
+ pragma Pack (Rec);
+ for Rec'Alignment use 1;
+
+ type Data is tagged record
+ R : Rec;
+ end record;
+
+end Opt90b_Pkg;
diff --git a/gcc/testsuite/gnat.dg/opt90c.adb b/gcc/testsuite/gnat.dg/opt90c.adb
new file mode 100644
index 0000000..b4f4c27
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt90c.adb
@@ -0,0 +1,16 @@
+-- { dg-do run }
+-- { dg-options "-O2" }
+
+with Ada.Calendar; use Ada.Calendar;
+with Opt90c_Pkg; use Opt90c_Pkg;
+
+procedure Opt90c is
+ B : constant Integer := Year (Clock);
+ V : Data;
+
+begin
+ V := (R => (A => 0, B => B, C => 0, D => "000000000000"));
+ if V.R.B /= B then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/opt90c_pkg.ads b/gcc/testsuite/gnat.dg/opt90c_pkg.ads
new file mode 100644
index 0000000..e772340
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt90c_pkg.ads
@@ -0,0 +1,16 @@
+package Opt90c_Pkg is
+
+ type Rec is record
+ D : String (1 .. 12);
+ B : Integer;
+ A : Short_Short_Integer;
+ C : Short_Integer;
+ end record;
+ pragma Pack (Rec);
+ for Rec'Alignment use 1;
+
+ type Data is tagged record
+ R : Rec;
+ end record;
+
+end Opt90c_Pkg;
diff --git a/gcc/testsuite/gnat.dg/opt90d.adb b/gcc/testsuite/gnat.dg/opt90d.adb
new file mode 100644
index 0000000..32ecb68
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt90d.adb
@@ -0,0 +1,16 @@
+-- { dg-do run }
+-- { dg-options "-O2" }
+
+with Ada.Calendar; use Ada.Calendar;
+with Opt90d_Pkg; use Opt90d_Pkg;
+
+procedure Opt90d is
+ B : constant Integer := Year (Clock);
+ V : Data;
+
+begin
+ V := (R => (A => 0, B => B, C => 0, D => "000000000000"));
+ if V.R.B /= B then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/opt90d_pkg.ads b/gcc/testsuite/gnat.dg/opt90d_pkg.ads
new file mode 100644
index 0000000..a68b224
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt90d_pkg.ads
@@ -0,0 +1,16 @@
+package Opt90d_Pkg is
+
+ type Rec is record
+ D : String (1 .. 12);
+ C : Short_Integer;
+ A : Short_Short_Integer;
+ B : Integer;
+ end record;
+ pragma Pack (Rec);
+ for Rec'Alignment use 1;
+
+ type Data is tagged record
+ R : Rec;
+ end record;
+
+end Opt90d_Pkg;
diff --git a/gcc/testsuite/gnat.dg/opt90e.adb b/gcc/testsuite/gnat.dg/opt90e.adb
new file mode 100644
index 0000000..6d62774
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt90e.adb
@@ -0,0 +1,16 @@
+-- { dg-do run }
+-- { dg-options "-O2" }
+
+with Ada.Calendar; use Ada.Calendar;
+with Opt90e_Pkg; use Opt90e_Pkg;
+
+procedure Opt90e is
+ B : constant Integer := Year (Clock);
+ V : Data;
+
+begin
+ V := (R => (A => 0, B => B, C => 0, D => "000000000000"));
+ if V.R.B /= B then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/opt90e_pkg.ads b/gcc/testsuite/gnat.dg/opt90e_pkg.ads
new file mode 100644
index 0000000..fba16d7
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt90e_pkg.ads
@@ -0,0 +1,16 @@
+package Opt90e_Pkg is
+
+ type Rec is record
+ D : String (1 .. 12);
+ A : Short_Short_Integer;
+ B : Integer;
+ C : Short_Integer;
+ end record;
+ pragma Pack (Rec);
+ for Rec'Alignment use 1;
+
+ type Data is tagged record
+ R : Rec;
+ end record;
+
+end Opt90e_Pkg;
diff --git a/gcc/testsuite/gnat.dg/shift1.adb b/gcc/testsuite/gnat.dg/shift1.adb
new file mode 100644
index 0000000..85a0fec
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/shift1.adb
@@ -0,0 +1,15 @@
+-- { dg-do compile }
+-- { dg-options "-gnatws" }
+
+procedure Shift1 is
+
+ type T_Integer_8 is range -2 ** 7 .. 2 ** 7 - 1
+ with Size => 8;
+
+ pragma Provide_Shift_Operators (T_Integer_8);
+
+ X : T_Integer_8;
+
+begin
+ X := Shift_Right (X, 1);
+end;
diff --git a/gcc/testsuite/go.test/go-test.exp b/gcc/testsuite/go.test/go-test.exp
index 51f9b38..8f17cb3 100644
--- a/gcc/testsuite/go.test/go-test.exp
+++ b/gcc/testsuite/go.test/go-test.exp
@@ -105,7 +105,7 @@ proc errchk { test opts } {
set copy_line $out_line
}
- regsub "// \(GCCGO_\)?ERROR \"\(\[^\"\]*\)\".*$" $copy_line "// \{ dg-error \"\\2\" \}" out_line
+ regsub "// \(GCCGO_\)?ERROR \"\(\[^\"\]*\)\" *\(\\*/\)?$" $copy_line "// \{ dg-error \"\\2\" \}\\3" out_line
if [string match "*dg-error*\\\[*" $out_line] {
set index [string first "dg-error" $out_line]
regsub -start $index -all "\\\\\\\[" $out_line "\\\\\\\\\\\[" out_line
@@ -648,7 +648,7 @@ proc go-gc-tests { } {
set last [lindex $packages end]
set packages [lreplace $packages end end]
foreach p $packages {
- dg-test -keep-output [lrange $p 1 end] "-O" "-w $DEFAULT_GOCFLAGS"
+ dg-test -keep-output [lrange $p 1 end] "-O -I." "-w $DEFAULT_GOCFLAGS"
lappend del "[file rootname [file tail [lindex $p 1]]].o"
}
errchk [lindex $last 1] "[lrange $last 2 end]"
@@ -692,7 +692,7 @@ proc go-gc-tests { } {
if { [llength $packages] > 0 } {
set del [list]
foreach p $packages {
- dg-test -keep-output [lindex $p 1] "[lrange $p 2 end] -O" "-w $DEFAULT_GOCFLAGS"
+ dg-test -keep-output [lindex $p 1] "[lrange $p 2 end] -O -I." "-w $DEFAULT_GOCFLAGS"
lappend del "[file rootname [file tail [lindex $p 1]]].o"
}
foreach f $del {
@@ -712,7 +712,7 @@ proc go-gc-tests { } {
set last [lindex $packages end]
set packages [lreplace $packages end end]
foreach p $packages {
- dg-test -keep-output [lrange $p 1 end] "-O" "-w $DEFAULT_GOCFLAGS"
+ dg-test -keep-output [lrange $p 1 end] "-O -I." "-w $DEFAULT_GOCFLAGS"
lappend del "[file rootname [file tail [lindex $p 1]]].o"
}
set dg-do-what-default "link"
@@ -737,11 +737,11 @@ proc go-gc-tests { } {
set last [lindex $packages end]
set packages [lreplace $packages end end]
foreach p $packages {
- dg-test -keep-output [lrange $p 1 end] "-O" "-w $DEFAULT_GOCFLAGS"
+ dg-test -keep-output [lrange $p 1 end] "-O -I." "-w $DEFAULT_GOCFLAGS"
lappend del "[file rootname [file tail [lindex $p 1]]].o"
}
set dg-do-what-default "link"
- dg-test -keep-output [lrange $last 1 end] "$del -O" "-w $DEFAULT_GOCFLAGS"
+ dg-test -keep-output [lrange $last 1 end] "$del -O -I." "-w $DEFAULT_GOCFLAGS"
set base "[file rootname [file tail [lindex $last 1]]]"
set output_file "./$base.exe"
lappend del $output_file
diff --git a/gcc/testsuite/go.test/test/alias.go b/gcc/testsuite/go.test/test/alias.go
index ec93a2d..aabaef8 100644
--- a/gcc/testsuite/go.test/test/alias.go
+++ b/gcc/testsuite/go.test/test/alias.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/alias1.go b/gcc/testsuite/go.test/test/alias1.go
index 42cf693..5707917 100644
--- a/gcc/testsuite/go.test/test/alias1.go
+++ b/gcc/testsuite/go.test/test/alias1.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/alias2.go b/gcc/testsuite/go.test/test/alias2.go
new file mode 100644
index 0000000..1c141ac
--- /dev/null
+++ b/gcc/testsuite/go.test/test/alias2.go
@@ -0,0 +1,104 @@
+// errorcheck
+
+// Copyright 2016 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.
+
+// Test basic restrictions on type aliases.
+
+package p
+
+import (
+ "reflect"
+ . "reflect"
+)
+
+type T0 struct{}
+
+// Valid type alias declarations.
+
+type _ = T0
+type _ = int
+type _ = struct{}
+type _ = reflect.Value
+type _ = Value
+
+type (
+ A0 = T0
+ A1 = int
+ A2 = struct{}
+ A3 = reflect.Value
+ A4 = Value
+ A5 = Value
+
+ N0 A0
+)
+
+// Methods can be declared on the original named type and the alias.
+func (T0) m1() {} // GCCGO_ERROR "previous"
+func (*T0) m1() {} // ERROR "method redeclared: T0\.m1|redefinition of .m1."
+func (A0) m1() {} // ERROR "T0\.m1 redeclared in this block|redefinition of .m1."
+func (A0) m1() {} // ERROR "T0\.m1 redeclared in this block|redefinition of .m1."
+func (A0) m2() {}
+
+// Type aliases and the original type name can be used interchangeably.
+var _ A0 = T0{}
+var _ T0 = A0{}
+
+// But aliases and original types cannot be used with new types based on them.
+var _ N0 = T0{} // ERROR "cannot use T0{} \(type T0\) as type N0 in assignment|incompatible type"
+var _ N0 = A0{} // ERROR "cannot use T0{} \(type T0\) as type N0 in assignment|incompatible type"
+
+var _ A5 = Value{}
+
+var _ interface {
+ m1()
+ m2()
+} = T0{}
+
+var _ interface {
+ m1()
+ m2()
+} = A0{}
+
+func _() {
+ type _ = T0
+ type _ = int
+ type _ = struct{}
+ type _ = reflect.Value
+ type _ = Value
+
+ type (
+ A0 = T0
+ A1 = int
+ A2 = struct{}
+ A3 = reflect.Value
+ A4 = Value
+ A5 Value
+
+ N0 A0
+ )
+
+ var _ A0 = T0{}
+ var _ T0 = A0{}
+
+ var _ N0 = T0{} // ERROR "cannot use T0{} \(type T0\) as type N0 in assignment|incompatible type"
+ var _ N0 = A0{} // ERROR "cannot use T0{} \(type T0\) as type N0 in assignment|incompatible type"
+
+ var _ A5 = Value{} // ERROR "cannot use reflect\.Value{} \(type reflect.Value\) as type A5 in assignment|incompatible type"
+}
+
+// Invalid type alias declarations.
+
+type _ = reflect.ValueOf // ERROR "reflect.ValueOf is not a type|expected type"
+
+func (A1) m() {} // ERROR "cannot define new methods on non-local type int|may not define methods on non-local type"
+func (A2) m() {} // ERROR "invalid receiver type"
+func (A3) m() {} // ERROR "cannot define new methods on non-local type reflect.Value|may not define methods on non-local type"
+func (A4) m() {} // ERROR "cannot define new methods on non-local type reflect.Value|may not define methods on non-local type"
+
+type B1 = struct{}
+
+func (B1) m() {} // ERROR "invalid receiver type"
+
+// TODO(gri) expand
diff --git a/gcc/testsuite/go.test/test/alias3.dir/a.go b/gcc/testsuite/go.test/test/alias3.dir/a.go
new file mode 100644
index 0000000..09b3408
--- /dev/null
+++ b/gcc/testsuite/go.test/test/alias3.dir/a.go
@@ -0,0 +1,42 @@
+// Copyright 2017 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 a
+
+import "go/build"
+
+type (
+ Float64 = float64
+ Rune = rune
+)
+
+type (
+ Int int
+ IntAlias = Int
+ IntAlias2 = IntAlias
+ S struct {
+ Int
+ IntAlias
+ IntAlias2
+ }
+)
+
+type (
+ Context = build.Context
+)
+
+type (
+ I1 interface {
+ M1(IntAlias2) Float64
+ M2() Context
+ }
+
+ I2 = interface {
+ M1(Int) float64
+ M2() build.Context
+ }
+)
+
+var i1 I1
+var i2 I2 = i1
diff --git a/gcc/testsuite/go.test/test/alias3.dir/b.go b/gcc/testsuite/go.test/test/alias3.dir/b.go
new file mode 100644
index 0000000..8a86cc0
--- /dev/null
+++ b/gcc/testsuite/go.test/test/alias3.dir/b.go
@@ -0,0 +1,26 @@
+// Copyright 2017 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 b
+
+import (
+ "./a"
+ . "go/build"
+)
+
+func F(x float64) a.Float64 {
+ return x
+}
+
+type MyContext = Context // = build.Context
+
+var C a.Context = Default
+
+type S struct{}
+
+func (S) M1(x a.IntAlias) float64 { return a.Float64(x) }
+func (S) M2() Context { return Default }
+
+var _ a.I1 = S{}
+var _ a.I2 = S{}
diff --git a/gcc/testsuite/go.test/test/alias3.dir/c.go b/gcc/testsuite/go.test/test/alias3.dir/c.go
new file mode 100644
index 0000000..161d593
--- /dev/null
+++ b/gcc/testsuite/go.test/test/alias3.dir/c.go
@@ -0,0 +1,25 @@
+// Copyright 2017 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 main
+
+import (
+ "./a"
+ "./b"
+)
+
+func main() {
+ var _ float64 = b.F(0)
+ var _ a.Rune = int32(0)
+
+ // embedded types can have different names but the same types
+ var s a.S
+ s.Int = 1
+ s.IntAlias = s.Int
+ s.IntAlias2 = s.Int
+
+ // aliases denote identical types across packages
+ var c a.Context = b.C
+ var _ b.MyContext = c
+}
diff --git a/gcc/testsuite/go.test/test/alias3.go b/gcc/testsuite/go.test/test/alias3.go
new file mode 100644
index 0000000..c3732c3
--- /dev/null
+++ b/gcc/testsuite/go.test/test/alias3.go
@@ -0,0 +1,7 @@
+// rundir
+
+// Copyright 2017 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 ignored
diff --git a/gcc/testsuite/go.test/test/append.go b/gcc/testsuite/go.test/test/append.go
index 3f6251e..3d16063 100644
--- a/gcc/testsuite/go.test/test/append.go
+++ b/gcc/testsuite/go.test/test/append.go
@@ -13,14 +13,12 @@ import (
"reflect"
)
-
func verify(name string, result, expected interface{}) {
if !reflect.DeepEqual(result, expected) {
panic(name)
}
}
-
func main() {
for _, t := range tests {
verify(t.name, t.result, t.expected)
@@ -30,6 +28,10 @@ func main() {
verifyType()
}
+var (
+ zero int = 0
+ one int = 1
+)
var tests = []struct {
name string
@@ -49,7 +51,6 @@ var tests = []struct {
{"bool i", append([]bool{true, false, true}, []bool{true}...), []bool{true, false, true, true}},
{"bool j", append([]bool{true, false, true}, []bool{true, true, true}...), []bool{true, false, true, true, true, true}},
-
{"byte a", append([]byte{}), []byte{}},
{"byte b", append([]byte{}, 0), []byte{0}},
{"byte c", append([]byte{}, 0, 1, 2, 3), []byte{0, 1, 2, 3}},
@@ -84,7 +85,6 @@ var tests = []struct {
{"int16 i", append([]int16{0, 1, 2}, []int16{3}...), []int16{0, 1, 2, 3}},
{"int16 j", append([]int16{0, 1, 2}, []int16{3, 4, 5}...), []int16{0, 1, 2, 3, 4, 5}},
-
{"uint32 a", append([]uint32{}), []uint32{}},
{"uint32 b", append([]uint32{}, 0), []uint32{0}},
{"uint32 c", append([]uint32{}, 0, 1, 2, 3), []uint32{0, 1, 2, 3}},
@@ -99,7 +99,6 @@ var tests = []struct {
{"uint32 i", append([]uint32{0, 1, 2}, []uint32{3}...), []uint32{0, 1, 2, 3}},
{"uint32 j", append([]uint32{0, 1, 2}, []uint32{3, 4, 5}...), []uint32{0, 1, 2, 3, 4, 5}},
-
{"float64 a", append([]float64{}), []float64{}},
{"float64 b", append([]float64{}, 0), []float64{0}},
{"float64 c", append([]float64{}, 0, 1, 2, 3), []float64{0, 1, 2, 3}},
@@ -114,7 +113,6 @@ var tests = []struct {
{"float64 i", append([]float64{0, 1, 2}, []float64{3}...), []float64{0, 1, 2, 3}},
{"float64 j", append([]float64{0, 1, 2}, []float64{3, 4, 5}...), []float64{0, 1, 2, 3, 4, 5}},
-
{"complex128 a", append([]complex128{}), []complex128{}},
{"complex128 b", append([]complex128{}, 0), []complex128{0}},
{"complex128 c", append([]complex128{}, 0, 1, 2, 3), []complex128{0, 1, 2, 3}},
@@ -129,7 +127,6 @@ var tests = []struct {
{"complex128 i", append([]complex128{0, 1, 2}, []complex128{3}...), []complex128{0, 1, 2, 3}},
{"complex128 j", append([]complex128{0, 1, 2}, []complex128{3, 4, 5}...), []complex128{0, 1, 2, 3, 4, 5}},
-
{"string a", append([]string{}), []string{}},
{"string b", append([]string{}, "0"), []string{"0"}},
{"string c", append([]string{}, "0", "1", "2", "3"), []string{"0", "1", "2", "3"}},
@@ -143,8 +140,19 @@ var tests = []struct {
{"string i", append([]string{"0", "1", "2"}, []string{"3"}...), []string{"0", "1", "2", "3"}},
{"string j", append([]string{"0", "1", "2"}, []string{"3", "4", "5"}...), []string{"0", "1", "2", "3", "4", "5"}},
-}
+ {"make a", append([]string{}, make([]string, 0)...), []string{}},
+ {"make b", append([]string(nil), make([]string, 0)...), []string(nil)},
+
+ {"make c", append([]struct{}{}, make([]struct{}, 0)...), []struct{}{}},
+ {"make d", append([]struct{}{}, make([]struct{}, 2)...), make([]struct{}, 2)},
+
+ {"make e", append([]int{0, 1}, make([]int, 0)...), []int{0, 1}},
+ {"make f", append([]int{0, 1}, make([]int, 2)...), []int{0, 1, 0, 0}},
+
+ {"make g", append([]*int{&zero, &one}, make([]*int, 0)...), []*int{&zero, &one}},
+ {"make h", append([]*int{&zero, &one}, make([]*int, 2)...), []*int{&zero, &one, nil, nil}},
+}
func verifyStruct() {
type T struct {
@@ -185,7 +193,6 @@ func verifyStruct() {
verify("struct m", append(s, e...), r)
}
-
func verifyInterface() {
type T interface{}
type S []T
diff --git a/gcc/testsuite/go.test/test/assign.go b/gcc/testsuite/go.test/test/assign.go
index da0192f..62fd3b5 100644
--- a/gcc/testsuite/go.test/test/assign.go
+++ b/gcc/testsuite/go.test/test/assign.go
@@ -53,4 +53,16 @@ func main() {
_ = x
_ = y
}
+ {
+ var x = 1
+ {
+ x, x := 2, 3 // ERROR ".*x.* repeated on left side of :="
+ _ = x
+ }
+ _ = x
+ }
+ {
+ a, a := 1, 2 // ERROR ".*a.* repeated on left side of :="
+ _ = a
+ }
}
diff --git a/gcc/testsuite/go.test/test/bench/garbage/Makefile b/gcc/testsuite/go.test/test/bench/garbage/Makefile
index 9883845..c10ef0a 100644
--- a/gcc/testsuite/go.test/test/bench/garbage/Makefile
+++ b/gcc/testsuite/go.test/test/bench/garbage/Makefile
@@ -1,4 +1,4 @@
-# Copyright 2010 The Go Authors. All rights reserved.
+# Copyright 2010 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/bench/garbage/parser.go b/gcc/testsuite/go.test/test/bench/garbage/parser.go
index d85110b..817afa9 100644
--- a/gcc/testsuite/go.test/test/bench/garbage/parser.go
+++ b/gcc/testsuite/go.test/test/bench/garbage/parser.go
@@ -1,4 +1,4 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -85,7 +85,7 @@ func main() {
var t0 time.Time
var numGC uint32
var pauseTotalNs uint64
- pkgroot := runtime.GOROOT() + "/src/pkg/"
+ pkgroot := runtime.GOROOT() + "/src/"
for pass := 0; pass < 2; pass++ {
// Once the heap is grown to full size, reset counters.
// This hides the start-up pauses, which are much smaller
diff --git a/gcc/testsuite/go.test/test/bench/garbage/stats.go b/gcc/testsuite/go.test/test/bench/garbage/stats.go
index 6dc0aeb..937e00f 100644
--- a/gcc/testsuite/go.test/test/bench/garbage/stats.go
+++ b/gcc/testsuite/go.test/test/bench/garbage/stats.go
@@ -1,4 +1,4 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/bench/garbage/tree.go b/gcc/testsuite/go.test/test/bench/garbage/tree.go
index 0a3ec23..524cfeb 100644
--- a/gcc/testsuite/go.test/test/bench/garbage/tree.go
+++ b/gcc/testsuite/go.test/test/bench/garbage/tree.go
@@ -28,7 +28,7 @@ POSSIBILITY OF SUCH DAMAGE.
*/
/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
+ * https://benchmarksgame-team.pages.debian.net/benchmarksgame/
*
* contributed by The Go Authors.
* based on C program by Kevin Carson
diff --git a/gcc/testsuite/go.test/test/bench/garbage/tree2.go b/gcc/testsuite/go.test/test/bench/garbage/tree2.go
index a171c69..a70a106 100644
--- a/gcc/testsuite/go.test/test/bench/garbage/tree2.go
+++ b/gcc/testsuite/go.test/test/bench/garbage/tree2.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/bench/go1/binarytree_test.go b/gcc/testsuite/go.test/test/bench/go1/binarytree_test.go
index c64c4b8..e5e49d5 100644
--- a/gcc/testsuite/go.test/test/bench/go1/binarytree_test.go
+++ b/gcc/testsuite/go.test/test/bench/go1/binarytree_test.go
@@ -1,4 +1,4 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/bench/go1/fannkuch_test.go b/gcc/testsuite/go.test/test/bench/go1/fannkuch_test.go
index ae45bfd..0cf6115 100644
--- a/gcc/testsuite/go.test/test/bench/go1/fannkuch_test.go
+++ b/gcc/testsuite/go.test/test/bench/go1/fannkuch_test.go
@@ -1,4 +1,4 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/bench/go1/fasta_test.go b/gcc/testsuite/go.test/test/bench/go1/fasta_test.go
index bff056f..af4fbac 100644
--- a/gcc/testsuite/go.test/test/bench/go1/fasta_test.go
+++ b/gcc/testsuite/go.test/test/bench/go1/fasta_test.go
@@ -1,4 +1,4 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -12,11 +12,11 @@ var fastabytes = makefasta()
func makefasta() []byte {
var n int = 25e6
- if runtime.GOARCH == "arm" {
+ if runtime.GOARCH == "arm" || runtime.GOARCH == "mips" || runtime.GOARCH == "mips64" {
// TODO(dfc) remove this limitation after precise gc.
- // A value of 25e6 consumes 465mb of heap on 32bit
- // platforms, which is too much for most ARM systems.
- // A value of 25e5 produces a memory layout that
+ // A value of 25e6 consumes 465mb of heap on 32bit
+ // platforms, which is too much for some systems.
+ // A value of 25e5 produces a memory layout that
// confuses the gc on 32bit platforms. So 25e4 it is.
n = 25e4
}
diff --git a/gcc/testsuite/go.test/test/bench/go1/gob_test.go b/gcc/testsuite/go.test/test/bench/go1/gob_test.go
index b172b80..224beff 100644
--- a/gcc/testsuite/go.test/test/bench/go1/gob_test.go
+++ b/gcc/testsuite/go.test/test/bench/go1/gob_test.go
@@ -1,4 +1,4 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/bench/go1/gzip_test.go b/gcc/testsuite/go.test/test/bench/go1/gzip_test.go
index fe4c480..648eec5 100644
--- a/gcc/testsuite/go.test/test/bench/go1/gzip_test.go
+++ b/gcc/testsuite/go.test/test/bench/go1/gzip_test.go
@@ -1,4 +1,4 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/bench/go1/http_test.go b/gcc/testsuite/go.test/test/bench/go1/http_test.go
index 34e789f..7ece9b2 100644
--- a/gcc/testsuite/go.test/test/bench/go1/http_test.go
+++ b/gcc/testsuite/go.test/test/bench/go1/http_test.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/bench/go1/json_test.go b/gcc/testsuite/go.test/test/bench/go1/json_test.go
index 1d42619..5ff1f8b 100644
--- a/gcc/testsuite/go.test/test/bench/go1/json_test.go
+++ b/gcc/testsuite/go.test/test/bench/go1/json_test.go
@@ -1,4 +1,4 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/bench/go1/jsondata_test.go b/gcc/testsuite/go.test/test/bench/go1/jsondata_test.go
index cf0fac1..281b6ca 100644
--- a/gcc/testsuite/go.test/test/bench/go1/jsondata_test.go
+++ b/gcc/testsuite/go.test/test/bench/go1/jsondata_test.go
@@ -1,4 +1,4 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -1816,4 +1816,4 @@ zJE6zEudHD27ZzbOeSgpk/HnkQbT7twqaaJXNvUzMuUt1hyhU7ceZcph42+VTlXU
cZ9UZZJyYojLjaeJHfJU1UZUEmBfLumu8yW5skuyE9uh2BmVxJZi6KxaXBNwSolw
BqBcQLj3ucNZIYZLYtirLu3brW6UYgZgZJiDIGiwpsgg7g1AITkgM6FHITxDDnGt
4SDHzZbL5s8fec5PCq5DOzDRdWS+0h5Y2INZak1D29cpVyb2aVrV3Wlt7rQhLa3e
-m3ZwPNcXywE2Qesk1XN24HvZ2Xa6nlm8Pf/xdyRThQkO1NjuAA== `)
+m3ZwPNcXywE2Qesk1XN24HvZ2Xa6nlm8Pf/xdyRThQkO1NjuAA==`)
diff --git a/gcc/testsuite/go.test/test/bench/go1/mandel_test.go b/gcc/testsuite/go.test/test/bench/go1/mandel_test.go
index 888c5e4..dd543b2 100644
--- a/gcc/testsuite/go.test/test/bench/go1/mandel_test.go
+++ b/gcc/testsuite/go.test/test/bench/go1/mandel_test.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/bench/go1/parserdata_test.go b/gcc/testsuite/go.test/test/bench/go1/parserdata_test.go
index 113e5e3..8255d18 100644
--- a/gcc/testsuite/go.test/test/bench/go1/parserdata_test.go
+++ b/gcc/testsuite/go.test/test/bench/go1/parserdata_test.go
@@ -1,10 +1,10 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
// Input for parser benchmark.
-// This was generated by starting with a the contents of
-// src/pkg/go/parser/parser.go at rev 9b455eb64690, then
+// This was generated by starting with the contents of
+// src/pkg/go/parser/parser.go at rev 9b455eb64690, then
// compressing with bzip2 -9, then encoding to base64.
// We compile the data into the binary so that the benchmark is
// a stand-alone binary that can be copied easily from machine to
diff --git a/gcc/testsuite/go.test/test/bench/go1/revcomp_test.go b/gcc/testsuite/go.test/test/bench/go1/revcomp_test.go
index 6b6c1e5..7d57bd6 100644
--- a/gcc/testsuite/go.test/test/bench/go1/revcomp_test.go
+++ b/gcc/testsuite/go.test/test/bench/go1/revcomp_test.go
@@ -1,4 +1,4 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/bench/go1/template_test.go b/gcc/testsuite/go.test/test/bench/go1/template_test.go
index db4839a..10dacaa 100644
--- a/gcc/testsuite/go.test/test/bench/go1/template_test.go
+++ b/gcc/testsuite/go.test/test/bench/go1/template_test.go
@@ -1,4 +1,4 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/bench/shootout/binary-tree-freelist.go b/gcc/testsuite/go.test/test/bench/shootout/binary-tree-freelist.go
deleted file mode 100644
index 071a4e06..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/binary-tree-freelist.go
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by The Go Authors.
- * based on C program by Kevin Carson
- */
-
-package main
-
-import (
- "flag"
- "fmt"
-)
-
-var n = flag.Int("n", 15, "depth")
-
-type Node struct {
- item int
- left, right *Node
-}
-
-type Arena struct {
- head *Node
-}
-
-var arena Arena
-
-func (n *Node) free() {
- if n.left != nil {
- n.left.free()
- }
- if n.right != nil {
- n.right.free()
- }
- n.left = arena.head
- arena.head = n
-}
-
-func (a *Arena) New(item int, left, right *Node) *Node {
- if a.head == nil {
- nodes := make([]Node, 3<<uint(*n))
- for i := 0; i < len(nodes)-1; i++ {
- nodes[i].left = &nodes[i+1]
- }
- a.head = &nodes[0]
- }
- n := a.head
- a.head = a.head.left
- n.item = item
- n.left = left
- n.right = right
- return n
-}
-
-func bottomUpTree(item, depth int) *Node {
- if depth <= 0 {
- return arena.New(item, nil, nil)
- }
- return arena.New(item, bottomUpTree(2*item-1, depth-1), bottomUpTree(2*item, depth-1))
-}
-
-func (n *Node) itemCheck() int {
- if n.left == nil {
- return n.item
- }
- return n.item + n.left.itemCheck() - n.right.itemCheck()
-}
-
-const minDepth = 4
-
-func main() {
- flag.Parse()
-
- maxDepth := *n
- if minDepth+2 > *n {
- maxDepth = minDepth + 2
- }
- stretchDepth := maxDepth + 1
-
- check := bottomUpTree(0, stretchDepth).itemCheck()
- fmt.Printf("stretch tree of depth %d\t check: %d\n", stretchDepth, check)
-
- longLivedTree := bottomUpTree(0, maxDepth)
-
- for depth := minDepth; depth <= maxDepth; depth += 2 {
- iterations := 1 << uint(maxDepth-depth+minDepth)
- check = 0
-
- for i := 1; i <= iterations; i++ {
- t := bottomUpTree(i, depth)
- check += t.itemCheck()
- t.free()
- t = bottomUpTree(-i, depth)
- check += t.itemCheck()
- t.free()
- }
- fmt.Printf("%d\t trees of depth %d\t check: %d\n", iterations*2, depth, check)
- }
- fmt.Printf("long lived tree of depth %d\t check: %d\n", maxDepth, longLivedTree.itemCheck())
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/binary-tree-freelist.txt b/gcc/testsuite/go.test/test/bench/shootout/binary-tree-freelist.txt
deleted file mode 100644
index f8286dd..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/binary-tree-freelist.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-stretch tree of depth 16 check: -1
-65536 trees of depth 4 check: -65536
-16384 trees of depth 6 check: -16384
-4096 trees of depth 8 check: -4096
-1024 trees of depth 10 check: -1024
-256 trees of depth 12 check: -256
-64 trees of depth 14 check: -64
-long lived tree of depth 15 check: -1
diff --git a/gcc/testsuite/go.test/test/bench/shootout/binary-tree.c b/gcc/testsuite/go.test/test/bench/shootout/binary-tree.c
deleted file mode 100644
index 9c35ac5..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/binary-tree.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Shootout Benchmarks
- http://shootout.alioth.debian.org/
-
- contributed by Kevin Carson
- compilation:
- gcc -O3 -fomit-frame-pointer -funroll-loops -static binary-trees.c -lm
- icc -O3 -ip -unroll -static binary-trees.c -lm
-*/
-
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-
-typedef struct tn {
- struct tn* left;
- struct tn* right;
- long item;
-} treeNode;
-
-
-treeNode* NewTreeNode(treeNode* left, treeNode* right, long item)
-{
- treeNode* new;
-
- new = (treeNode*)malloc(sizeof(treeNode));
-
- new->left = left;
- new->right = right;
- new->item = item;
-
- return new;
-} /* NewTreeNode() */
-
-
-long ItemCheck(treeNode* tree)
-{
- if (tree->left == NULL)
- return tree->item;
- else
- return tree->item + ItemCheck(tree->left) - ItemCheck(tree->right);
-} /* ItemCheck() */
-
-
-treeNode* BottomUpTree(long item, unsigned depth)
-{
- if (depth > 0)
- return NewTreeNode
- (
- BottomUpTree(2 * item - 1, depth - 1),
- BottomUpTree(2 * item, depth - 1),
- item
- );
- else
- return NewTreeNode(NULL, NULL, item);
-} /* BottomUpTree() */
-
-
-void DeleteTree(treeNode* tree)
-{
- if (tree->left != NULL)
- {
- DeleteTree(tree->left);
- DeleteTree(tree->right);
- }
-
- free(tree);
-} /* DeleteTree() */
-
-
-int main(int argc, char* argv[])
-{
- unsigned N, depth, minDepth, maxDepth, stretchDepth;
- treeNode *stretchTree, *longLivedTree, *tempTree;
-
- N = atol(argv[1]);
-
- minDepth = 4;
-
- if ((minDepth + 2) > N)
- maxDepth = minDepth + 2;
- else
- maxDepth = N;
-
- stretchDepth = maxDepth + 1;
-
- stretchTree = BottomUpTree(0, stretchDepth);
- printf
- (
- "stretch tree of depth %u\t check: %li\n",
- stretchDepth,
- ItemCheck(stretchTree)
- );
-
- DeleteTree(stretchTree);
-
- longLivedTree = BottomUpTree(0, maxDepth);
-
- for (depth = minDepth; depth <= maxDepth; depth += 2)
- {
- long i, iterations, check;
-
- iterations = pow(2, maxDepth - depth + minDepth);
-
- check = 0;
-
- for (i = 1; i <= iterations; i++)
- {
- tempTree = BottomUpTree(i, depth);
- check += ItemCheck(tempTree);
- DeleteTree(tempTree);
-
- tempTree = BottomUpTree(-i, depth);
- check += ItemCheck(tempTree);
- DeleteTree(tempTree);
- } /* for(i = 1...) */
-
- printf
- (
- "%li\t trees of depth %u\t check: %li\n",
- iterations * 2,
- depth,
- check
- );
- } /* for(depth = minDepth...) */
-
- printf
- (
- "long lived tree of depth %u\t check: %li\n",
- maxDepth,
- ItemCheck(longLivedTree)
- );
-
- return 0;
-} /* main() */
diff --git a/gcc/testsuite/go.test/test/bench/shootout/binary-tree.go b/gcc/testsuite/go.test/test/bench/shootout/binary-tree.go
deleted file mode 100644
index 9f867d1..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/binary-tree.go
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by The Go Authors.
- * based on C program by Kevin Carson
- */
-
-package main
-
-import (
- "flag"
- "fmt"
-)
-
-var n = flag.Int("n", 15, "depth")
-
-type Node struct {
- item int
- left, right *Node
-}
-
-func bottomUpTree(item, depth int) *Node {
- if depth <= 0 {
- return &Node{item: item}
- }
- return &Node{item, bottomUpTree(2*item-1, depth-1), bottomUpTree(2*item, depth-1)}
-}
-
-func (n *Node) itemCheck() int {
- if n.left == nil {
- return n.item
- }
- return n.item + n.left.itemCheck() - n.right.itemCheck()
-}
-
-const minDepth = 4
-
-func main() {
- flag.Parse()
-
- maxDepth := *n
- if minDepth+2 > *n {
- maxDepth = minDepth + 2
- }
- stretchDepth := maxDepth + 1
-
- check := bottomUpTree(0, stretchDepth).itemCheck()
- fmt.Printf("stretch tree of depth %d\t check: %d\n", stretchDepth, check)
-
- longLivedTree := bottomUpTree(0, maxDepth)
-
- for depth := minDepth; depth <= maxDepth; depth += 2 {
- iterations := 1 << uint(maxDepth-depth+minDepth)
- check = 0
-
- for i := 1; i <= iterations; i++ {
- check += bottomUpTree(i, depth).itemCheck()
- check += bottomUpTree(-i, depth).itemCheck()
- }
- fmt.Printf("%d\t trees of depth %d\t check: %d\n", iterations*2, depth, check)
- }
- fmt.Printf("long lived tree of depth %d\t check: %d\n", maxDepth, longLivedTree.itemCheck())
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/binary-tree.txt b/gcc/testsuite/go.test/test/bench/shootout/binary-tree.txt
deleted file mode 100644
index f8286dd..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/binary-tree.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-stretch tree of depth 16 check: -1
-65536 trees of depth 4 check: -65536
-16384 trees of depth 6 check: -16384
-4096 trees of depth 8 check: -4096
-1024 trees of depth 10 check: -1024
-256 trees of depth 12 check: -256
-64 trees of depth 14 check: -64
-long lived tree of depth 15 check: -1
diff --git a/gcc/testsuite/go.test/test/bench/shootout/chameneosredux.c b/gcc/testsuite/go.test/test/bench/shootout/chameneosredux.c
deleted file mode 100644
index ed78c31..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/chameneosredux.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- http://shootout.alioth.debian.org/
-
- contributed by Michael Barker
- based on a Java contribution by Luzius Meisser
-
- convert to C by dualamd
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <pthread.h>
-
-
-enum Colour
-{
- blue = 0,
- red = 1,
- yellow = 2,
- Invalid = 3
-};
-
-const char* ColourName[] = {"blue", "red", "yellow"};
-const int STACK_SIZE = 32*1024;
-
-typedef unsigned int BOOL;
-const BOOL TRUE = 1;
-const BOOL FALSE = 0;
-
-int CreatureID = 0;
-
-
-enum Colour doCompliment(enum Colour c1, enum Colour c2)
-{
- switch (c1)
- {
- case blue:
- switch (c2)
- {
- case blue:
- return blue;
- case red:
- return yellow;
- case yellow:
- return red;
- default:
- goto errlb;
- }
- case red:
- switch (c2)
- {
- case blue:
- return yellow;
- case red:
- return red;
- case yellow:
- return blue;
- default:
- goto errlb;
- }
- case yellow:
- switch (c2)
- {
- case blue:
- return red;
- case red:
- return blue;
- case yellow:
- return yellow;
- default:
- goto errlb;
- }
- default:
- break;
- }
-
-errlb:
- printf("Invalid colour\n");
- exit( 1 );
-}
-
-/* convert integer to number string: 1234 -> "one two three four" */
-char* formatNumber(int n, char* outbuf)
-{
- int ochar = 0, ichar = 0;
- int i;
- char tmp[64];
-
- const char* NUMBERS[] =
- {
- "zero", "one", "two", "three", "four", "five",
- "six", "seven", "eight", "nine"
- };
-
- ichar = sprintf(tmp, "%d", n);
-
- for (i = 0; i < ichar; i++)
- ochar += sprintf( outbuf + ochar, " %s", NUMBERS[ tmp[i] - '0' ] );
-
- return outbuf;
-}
-
-
-struct MeetingPlace
-{
- pthread_mutex_t mutex;
- int meetingsLeft;
- struct Creature* firstCreature;
-};
-
-struct Creature
-{
- pthread_t ht;
- pthread_attr_t stack_att;
-
- struct MeetingPlace* place;
- int count;
- int sameCount;
-
- enum Colour colour;
- int id;
-
- BOOL two_met;
- BOOL sameid;
-};
-
-
-void MeetingPlace_Init(struct MeetingPlace* m, int meetings )
-{
- pthread_mutex_init( &m->mutex, 0 );
- m->meetingsLeft = meetings;
- m->firstCreature = 0;
-}
-
-
-BOOL Meet( struct Creature* cr)
-{
- BOOL retval = TRUE;
-
- struct MeetingPlace* mp = cr->place;
- pthread_mutex_lock( &(mp->mutex) );
-
- if ( mp->meetingsLeft > 0 )
- {
- if ( mp->firstCreature == 0 )
- {
- cr->two_met = FALSE;
- mp->firstCreature = cr;
- }
- else
- {
- struct Creature* first;
- enum Colour newColour;
-
- first = mp->firstCreature;
- newColour = doCompliment( cr->colour, first->colour );
-
- cr->sameid = cr->id == first->id;
- cr->colour = newColour;
- cr->two_met = TRUE;
-
- first->sameid = cr->sameid;
- first->colour = newColour;
- first->two_met = TRUE;
-
- mp->firstCreature = 0;
- mp->meetingsLeft--;
- }
- }
- else
- retval = FALSE;
-
- pthread_mutex_unlock( &(mp->mutex) );
- return retval;
-}
-
-
-void* CreatureThreadRun(void* param)
-{
- struct Creature* cr = (struct Creature*)param;
-
- while (TRUE)
- {
- if ( Meet(cr) )
- {
- while (cr->two_met == FALSE)
- sched_yield();
-
- if (cr->sameid)
- cr->sameCount++;
- cr->count++;
- }
- else
- break;
- }
-
- return 0;
-}
-
-void Creature_Init( struct Creature *cr, struct MeetingPlace* place, enum Colour colour )
-{
- cr->place = place;
- cr->count = cr->sameCount = 0;
-
- cr->id = ++CreatureID;
- cr->colour = colour;
- cr->two_met = FALSE;
-
- pthread_attr_init( &cr->stack_att );
- pthread_attr_setstacksize( &cr->stack_att, STACK_SIZE );
- pthread_create( &cr->ht, &cr->stack_att, &CreatureThreadRun, (void*)(cr) );
-}
-
-/* format meeting times of each creature to string */
-char* Creature_getResult(struct Creature* cr, char* str)
-{
- char numstr[256];
- formatNumber(cr->sameCount, numstr);
-
- sprintf( str, "%u%s", cr->count, numstr );
- return str;
-}
-
-
-void runGame( int n_meeting, int ncolor, const enum Colour* colours )
-{
- int i;
- int total = 0;
- char str[256];
-
- struct MeetingPlace place;
- struct Creature *creatures = (struct Creature*) calloc( ncolor, sizeof(struct Creature) );
-
- MeetingPlace_Init( &place, n_meeting );
-
- /* print initial color of each creature */
- for (i = 0; i < ncolor; i++)
- {
- printf( "%s ", ColourName[ colours[i] ] );
- Creature_Init( &(creatures[i]), &place, colours[i] );
- }
- printf("\n");
-
- /* wait for them to meet */
- for (i = 0; i < ncolor; i++)
- pthread_join( creatures[i].ht, 0 );
-
- /* print meeting times of each creature */
- for (i = 0; i < ncolor; i++)
- {
- printf( "%s\n", Creature_getResult(&(creatures[i]), str) );
- total += creatures[i].count;
- }
-
- /* print total meeting times, should equal n_meeting */
- printf( "%s\n\n", formatNumber(total, str) );
-
- /* cleaup & quit */
- pthread_mutex_destroy( &place.mutex );
- free( creatures );
-}
-
-
-void printColours( enum Colour c1, enum Colour c2 )
-{
- printf( "%s + %s -> %s\n",
- ColourName[c1],
- ColourName[c2],
- ColourName[doCompliment(c1, c2)] );
-}
-
-void printColoursTable(void)
-{
- printColours(blue, blue);
- printColours(blue, red);
- printColours(blue, yellow);
- printColours(red, blue);
- printColours(red, red);
- printColours(red, yellow);
- printColours(yellow, blue);
- printColours(yellow, red);
- printColours(yellow, yellow);
-}
-
-int main(int argc, char** argv)
-{
- int n = (argc == 2) ? atoi(argv[1]) : 600;
-
- printColoursTable();
- printf("\n");
-
- const enum Colour r1[] = { blue, red, yellow };
- const enum Colour r2[] = { blue, red, yellow,
- red, yellow, blue,
- red, yellow, red, blue };
-
- runGame( n, sizeof(r1) / sizeof(r1[0]), r1 );
- runGame( n, sizeof(r2) / sizeof(r2[0]), r2 );
-
- return 0;
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/chameneosredux.go b/gcc/testsuite/go.test/test/bench/shootout/chameneosredux.go
deleted file mode 100644
index 3395798..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/chameneosredux.go
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by The Go Authors.
- */
-
-package main
-
-import (
- "flag"
- "fmt"
- "strconv"
-)
-
-const (
- blue = iota
- red
- yellow
- ncol
-)
-
-var complement = [...]int{
- red | red<<2: red,
- red | yellow<<2: blue,
- red | blue<<2: yellow,
- yellow | red<<2: blue,
- yellow | yellow<<2: yellow,
- yellow | blue<<2: red,
- blue | red<<2: yellow,
- blue | yellow<<2: red,
- blue | blue<<2: blue,
-}
-
-var colname = [...]string{
- blue: "blue",
- red: "red",
- yellow: "yellow",
-}
-
-// information about the current state of a creature.
-type info struct {
- colour int // creature's current colour.
- name int // creature's name.
-}
-
-// exclusive access data-structure kept inside meetingplace.
-// if mate is nil, it indicates there's no creature currently waiting;
-// otherwise the creature's info is stored in info, and
-// it is waiting to receive its mate's information on the mate channel.
-type rendez struct {
- n int // current number of encounters.
- mate chan<- info // creature waiting when non-nil.
- info info // info about creature waiting.
-}
-
-// result sent by each creature at the end of processing.
-type result struct {
- met int
- same int
-}
-
-var n = 600
-
-func main() {
- flag.Parse()
- if flag.NArg() > 0 {
- n, _ = strconv.Atoi(flag.Arg(0))
- }
-
- for c0 := 0; c0 < ncol; c0++ {
- for c1 := 0; c1 < ncol; c1++ {
- fmt.Printf("%s + %s -> %s\n", colname[c0], colname[c1], colname[complement[c0|c1<<2]])
- }
- }
- fmt.Print("\n")
-
- pallmall([]int{blue, red, yellow})
- pallmall([]int{blue, red, yellow, red, yellow, blue, red, yellow, red, blue})
-}
-
-func pallmall(cols []int) {
-
- // invariant: meetingplace always contains a value unless a creature
- // is currently dealing with it (whereupon it must put it back).
- meetingplace := make(chan rendez, 1)
- meetingplace <- rendez{n: 0}
-
- ended := make(chan result)
- msg := ""
- for i, col := range cols {
- go creature(info{col, i}, meetingplace, ended)
- msg += " " + colname[col]
- }
- fmt.Println(msg)
- tot := 0
- // wait for all results
- for _ = range cols {
- result := <-ended
- tot += result.met
- fmt.Printf("%v%v\n", result.met, spell(result.same, true))
- }
- fmt.Printf("%v\n\n", spell(tot, true))
-}
-
-// in this function, variables ending in 0 refer to the local creature,
-// variables ending in 1 to the creature we've met.
-func creature(info0 info, meetingplace chan rendez, ended chan result) {
- c0 := make(chan info)
- met := 0
- same := 0
- for {
- var othername int
- // get access to rendez data and decide what to do.
- switch r := <-meetingplace; {
- case r.n >= n:
- // if no more meetings left, then send our result data and exit.
- meetingplace <- rendez{n: r.n}
- ended <- result{met, same}
- return
- case r.mate == nil:
- // no creature waiting; wait for someone to meet us,
- // get their info and send our info in reply.
- meetingplace <- rendez{n: r.n, info: info0, mate: c0}
- info1 := <-c0
- othername = info1.name
- info0.colour = complement[info0.colour|info1.colour<<2]
- default:
- // another creature is waiting for us with its info;
- // increment meeting count,
- // send them our info in reply.
- r.n++
- meetingplace <- rendez{n: r.n, mate: nil}
- r.mate <- info0
- othername = r.info.name
- info0.colour = complement[info0.colour|r.info.colour<<2]
- }
- if othername == info0.name {
- same++
- }
- met++
- }
-}
-
-var digits = [...]string{"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}
-
-func spell(n int, required bool) string {
- if n == 0 && !required {
- return ""
- }
- return spell(n/10, false) + " " + digits[n%10]
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/chameneosredux.txt b/gcc/testsuite/go.test/test/bench/shootout/chameneosredux.txt
deleted file mode 100644
index 6016d59..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/chameneosredux.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-blue + blue -> blue
-blue + red -> yellow
-blue + yellow -> red
-red + blue -> yellow
-red + red -> red
-red + yellow -> blue
-yellow + blue -> red
-yellow + red -> blue
-yellow + yellow -> yellow
-
- blue red yellow
-400 zero
-400 zero
-400 zero
- one two zero zero
-
- blue red yellow red yellow blue red yellow red blue
-120 zero
-120 zero
-120 zero
-120 zero
-120 zero
-120 zero
-120 zero
-120 zero
-120 zero
-120 zero
- one two zero zero
-
diff --git a/gcc/testsuite/go.test/test/bench/shootout/fannkuch-parallel.go b/gcc/testsuite/go.test/test/bench/shootout/fannkuch-parallel.go
deleted file mode 100644
index 7e9b98d..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/fannkuch-parallel.go
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*
- * The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by The Go Authors.
- * Based on fannkuch.scala by Rex Kerr
- */
-
-package main
-
-import (
- "flag"
- "fmt"
- "runtime"
-)
-
-var n = flag.Int("n", 7, "count")
-var nCPU = flag.Int("ncpu", 4, "number of cpus")
-
-type Job struct {
- start []int
- n int
-}
-
-type Found struct {
- who *Kucher
- k int
-}
-
-type Kucher struct {
- perm []int
- temp []int
- flip []int
- in chan Job
-}
-
-func NewKucher(length int) *Kucher {
- return &Kucher{
- perm: make([]int, length),
- temp: make([]int, length),
- flip: make([]int, length),
- in: make(chan Job),
- }
-}
-
-func (k *Kucher) permute(n int) bool {
- i := 0
- for ; i < n-1 && k.flip[i] == 0; i++ {
- t := k.perm[0]
- j := 0
- for ; j <= i; j++ {
- k.perm[j] = k.perm[j+1]
- }
- k.perm[j] = t
- }
- k.flip[i]--
- for i > 0 {
- i--
- k.flip[i] = i
- }
- return k.flip[n-1] >= 0
-}
-
-func (k *Kucher) count() int {
- K := 0
- copy(k.temp, k.perm)
- for k.temp[0] != 0 {
- m := k.temp[0]
- for i := 0; i < m; i++ {
- k.temp[i], k.temp[m] = k.temp[m], k.temp[i]
- m--
- }
- K++
- }
- return K
-}
-
-func (k *Kucher) Run(foreman chan<- Found) {
- for job := range k.in {
- verbose := 30
- copy(k.perm, job.start)
- for i, v := range k.perm {
- if v != i {
- verbose = 0
- }
- k.flip[i] = i
- }
- K := 0
- for {
- if verbose > 0 {
- for _, p := range k.perm {
- fmt.Print(p + 1)
- }
- fmt.Println()
- verbose--
- }
- count := k.count()
- if count > K {
- K = count
- }
- if !k.permute(job.n) {
- break
- }
- }
- foreman <- Found{k, K}
- }
-}
-
-type Fanner struct {
- jobind int
- jobsdone int
- k int
- jobs []Job
- workers []*Kucher
- in chan Found
- result chan int
-}
-
-func NewFanner(jobs []Job, workers []*Kucher) *Fanner {
- return &Fanner{
- jobs: jobs, workers: workers,
- in: make(chan Found),
- result: make(chan int),
- }
-}
-
-func (f *Fanner) Run(N int) {
- for msg := range f.in {
- if msg.k > f.k {
- f.k = msg.k
- }
- if msg.k >= 0 {
- f.jobsdone++
- }
- if f.jobind < len(f.jobs) {
- msg.who.in <- f.jobs[f.jobind]
- f.jobind++
- } else if f.jobsdone == len(f.jobs) {
- f.result <- f.k
- return
- }
- }
-}
-
-func swapped(a []int, i, j int) []int {
- b := make([]int, len(a))
- copy(b, a)
- b[i], b[j] = a[j], a[i]
- return b
-}
-
-func main() {
- flag.Parse()
- runtime.GOMAXPROCS(*nCPU)
- N := *n
- base := make([]int, N)
- for i := range base {
- base[i] = i
- }
-
- njobs := 1
- if N > 8 {
- njobs += (N*(N-1))/2 - 28 // njobs = 1 + sum(8..N-1) = 1 + sum(1..N-1) - sum(1..7)
- }
- jobs := make([]Job, njobs)
- jobsind := 0
-
- firstN := N
- if firstN > 8 {
- firstN = 8
- }
- jobs[jobsind] = Job{base, firstN}
- jobsind++
- for i := N - 1; i >= 8; i-- {
- for j := 0; j < i; j++ {
- jobs[jobsind] = Job{swapped(base, i, j), i}
- jobsind++
- }
- }
-
- nworkers := *nCPU
- if njobs < nworkers {
- nworkers = njobs
- }
- workers := make([]*Kucher, nworkers)
- foreman := NewFanner(jobs, workers)
- go foreman.Run(N)
- for i := range workers {
- k := NewKucher(N)
- workers[i] = k
- go k.Run(foreman.in)
- foreman.in <- Found{k, -1}
- }
- fmt.Printf("Pfannkuchen(%d) = %d\n", N, <-foreman.result)
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/fannkuch-parallel.txt b/gcc/testsuite/go.test/test/bench/shootout/fannkuch-parallel.txt
deleted file mode 100644
index e66f779..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/fannkuch-parallel.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-1234567
-2134567
-2314567
-3214567
-3124567
-1324567
-2341567
-3241567
-3421567
-4321567
-4231567
-2431567
-3412567
-4312567
-4132567
-1432567
-1342567
-3142567
-4123567
-1423567
-1243567
-2143567
-2413567
-4213567
-2345167
-3245167
-3425167
-4325167
-4235167
-2435167
-Pfannkuchen(7) = 16
diff --git a/gcc/testsuite/go.test/test/bench/shootout/fannkuch.c b/gcc/testsuite/go.test/test/bench/shootout/fannkuch.c
deleted file mode 100644
index e576b54..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/fannkuch.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*
- * The Computer Language Shootout
- * http://shootout.alioth.debian.org/
- * Contributed by Heiner Marxen
- *
- * "fannkuch" for C gcc
- *
- * $Id: fannkuch.1.gcc.code,v 1.15 2009-04-28 15:39:31 igouy-guest Exp $
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#define Int int
-#define Aint int
-
- static long
-fannkuch( int n )
-{
- Aint* perm;
- Aint* perm1;
- Aint* count;
- long flips;
- long flipsMax;
- Int r;
- Int i;
- Int k;
- Int didpr;
- const Int n1 = n - 1;
-
- if( n < 1 ) return 0;
-
- perm = calloc(n, sizeof(*perm ));
- perm1 = calloc(n, sizeof(*perm1));
- count = calloc(n, sizeof(*count));
-
- for( i=0 ; i<n ; ++i ) perm1[i] = i; /* initial (trivial) permu */
-
- r = n; didpr = 0; flipsMax = 0;
- for(;;) {
- if( didpr < 30 ) {
- for( i=0 ; i<n ; ++i ) printf("%d", (int)(1+perm1[i]));
- printf("\n");
- ++didpr;
- }
- for( ; r!=1 ; --r ) {
- count[r-1] = r;
- }
-
-#define XCH(x,y) { Aint t_mp; t_mp=(x); (x)=(y); (y)=t_mp; }
-
- if( ! (perm1[0]==0 || perm1[n1]==n1) ) {
- flips = 0;
- for( i=1 ; i<n ; ++i ) { /* perm = perm1 */
- perm[i] = perm1[i];
- }
- k = perm1[0]; /* cache perm[0] in k */
- do { /* k!=0 ==> k>0 */
- Int j;
- for( i=1, j=k-1 ; i<j ; ++i, --j ) {
- XCH(perm[i], perm[j])
- }
- ++flips;
- /*
- * Now exchange k (caching perm[0]) and perm[k]... with care!
- * XCH(k, perm[k]) does NOT work!
- */
- j=perm[k]; perm[k]=k ; k=j;
- }while( k );
- if( flipsMax < flips ) {
- flipsMax = flips;
- }
- }
-
- for(;;) {
- if( r == n ) {
- return flipsMax;
- }
- /* rotate down perm[0..r] by one */
- {
- Int perm0 = perm1[0];
- i = 0;
- while( i < r ) {
- k = i+1;
- perm1[i] = perm1[k];
- i = k;
- }
- perm1[r] = perm0;
- }
- if( (count[r] -= 1) > 0 ) {
- break;
- }
- ++r;
- }
- }
-}
-
- int
-main( int argc, char* argv[] )
-{
- int n = (argc>1) ? atoi(argv[1]) : 0;
-
- printf("Pfannkuchen(%d) = %ld\n", n, fannkuch(n));
- return 0;
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/fannkuch.go b/gcc/testsuite/go.test/test/bench/shootout/fannkuch.go
deleted file mode 100644
index b554c77..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/fannkuch.go
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*
- * The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by The Go Authors.
- * Based on fannkuch.c by Heiner Marxen
- */
-
-package main
-
-import (
- "flag"
- "fmt"
-)
-
-var n = flag.Int("n", 7, "count")
-
-func fannkuch(n int) int {
- if n < 1 {
- return 0
- }
-
- n1 := n - 1
- perm := make([]int, n)
- perm1 := make([]int, n)
- count := make([]int, n)
-
- for i := 0; i < n; i++ {
- perm1[i] = i // initial (trivial) permutation
- }
-
- r := n
- didpr := 0
- flipsMax := 0
- for {
- if didpr < 30 {
- for i := 0; i < n; i++ {
- fmt.Printf("%d", 1+perm1[i])
- }
- fmt.Printf("\n")
- didpr++
- }
- for ; r != 1; r-- {
- count[r-1] = r
- }
-
- if perm1[0] != 0 && perm1[n1] != n1 {
- flips := 0
- for i := 1; i < n; i++ { // perm = perm1
- perm[i] = perm1[i]
- }
- k := perm1[0] // cache perm[0] in k
- for { // k!=0 ==> k>0
- for i, j := 1, k-1; i < j; i, j = i+1, j-1 {
- perm[i], perm[j] = perm[j], perm[i]
- }
- flips++
- // Now exchange k (caching perm[0]) and perm[k]... with care!
- j := perm[k]
- perm[k] = k
- k = j
- if k == 0 {
- break
- }
- }
- if flipsMax < flips {
- flipsMax = flips
- }
- }
-
- for ; r < n; r++ {
- // rotate down perm[0..r] by one
- perm0 := perm1[0]
- for i := 0; i < r; i++ {
- perm1[i] = perm1[i+1]
- }
- perm1[r] = perm0
- count[r]--
- if count[r] > 0 {
- break
- }
- }
- if r == n {
- return flipsMax
- }
- }
- return 0
-}
-
-func main() {
- flag.Parse()
- fmt.Printf("Pfannkuchen(%d) = %d\n", *n, fannkuch(*n))
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/fannkuch.txt b/gcc/testsuite/go.test/test/bench/shootout/fannkuch.txt
deleted file mode 100644
index e66f779..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/fannkuch.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-1234567
-2134567
-2314567
-3214567
-3124567
-1324567
-2341567
-3241567
-3421567
-4321567
-4231567
-2431567
-3412567
-4312567
-4132567
-1432567
-1342567
-3142567
-4123567
-1423567
-1243567
-2143567
-2413567
-4213567
-2345167
-3245167
-3425167
-4325167
-4235167
-2435167
-Pfannkuchen(7) = 16
diff --git a/gcc/testsuite/go.test/test/bench/shootout/fasta-1000.out b/gcc/testsuite/go.test/test/bench/shootout/fasta-1000.out
deleted file mode 100644
index f1caba0..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/fasta-1000.out
+++ /dev/null
@@ -1,171 +0,0 @@
->ONE Homo sapiens alu
-GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA
-TCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACT
-AAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAG
-GCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCG
-CCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGT
-GGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCA
-GGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAA
-TTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAG
-AATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCA
-GCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGT
-AATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACC
-AGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTG
-GTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACC
-CGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAG
-AGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTT
-TGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACA
-TGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCT
-GTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGG
-TTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGT
-CTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGG
-CGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCG
-TCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTA
-CTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCG
-AGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCG
-GGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACC
-TGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAA
-TACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGA
-GGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACT
-GCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTC
-ACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGT
-TCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGC
-CGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCG
-CTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTG
-GGCGACAGAGCGAGACTCCG
->TWO IUB ambiguity codes
-cttBtatcatatgctaKggNcataaaSatgtaaaDcDRtBggDtctttataattcBgtcg
-tactDtDagcctatttSVHtHttKtgtHMaSattgWaHKHttttagacatWatgtRgaaa
-NtactMcSMtYtcMgRtacttctWBacgaaatatagScDtttgaagacacatagtVgYgt
-cattHWtMMWcStgttaggKtSgaYaaccWStcgBttgcgaMttBYatcWtgacaYcaga
-gtaBDtRacttttcWatMttDBcatWtatcttactaBgaYtcttgttttttttYaaScYa
-HgtgttNtSatcMtcVaaaStccRcctDaataataStcYtRDSaMtDttgttSagtRRca
-tttHatSttMtWgtcgtatSSagactYaaattcaMtWatttaSgYttaRgKaRtccactt
-tattRggaMcDaWaWagttttgacatgttctacaaaRaatataataaMttcgDacgaSSt
-acaStYRctVaNMtMgtaggcKatcttttattaaaaagVWaHKYagtttttatttaacct
-tacgtVtcVaattVMBcttaMtttaStgacttagattWWacVtgWYagWVRctDattBYt
-gtttaagaagattattgacVatMaacattVctgtBSgaVtgWWggaKHaatKWcBScSWa
-accRVacacaaactaccScattRatatKVtactatatttHttaagtttSKtRtacaaagt
-RDttcaaaaWgcacatWaDgtDKacgaacaattacaRNWaatHtttStgttattaaMtgt
-tgDcgtMgcatBtgcttcgcgaDWgagctgcgaggggVtaaScNatttacttaatgacag
-cccccacatYScaMgtaggtYaNgttctgaMaacNaMRaacaaacaKctacatagYWctg
-ttWaaataaaataRattagHacacaagcgKatacBttRttaagtatttccgatctHSaat
-actcNttMaagtattMtgRtgaMgcataatHcMtaBSaRattagttgatHtMttaaKagg
-YtaaBataSaVatactWtataVWgKgttaaaacagtgcgRatatacatVtHRtVYataSa
-KtWaStVcNKHKttactatccctcatgWHatWaRcttactaggatctataDtDHBttata
-aaaHgtacVtagaYttYaKcctattcttcttaataNDaaggaaaDYgcggctaaWSctBa
-aNtgctggMBaKctaMVKagBaactaWaDaMaccYVtNtaHtVWtKgRtcaaNtYaNacg
-gtttNattgVtttctgtBaWgtaattcaagtcaVWtactNggattctttaYtaaagccgc
-tcttagHVggaYtgtNcDaVagctctctKgacgtatagYcctRYHDtgBattDaaDgccK
-tcHaaStttMcctagtattgcRgWBaVatHaaaataYtgtttagMDMRtaataaggatMt
-ttctWgtNtgtgaaaaMaatatRtttMtDgHHtgtcattttcWattRSHcVagaagtacg
-ggtaKVattKYagactNaatgtttgKMMgYNtcccgSKttctaStatatNVataYHgtNa
-BKRgNacaactgatttcctttaNcgatttctctataScaHtataRagtcRVttacDSDtt
-aRtSatacHgtSKacYagttMHtWataggatgactNtatSaNctataVtttRNKtgRacc
-tttYtatgttactttttcctttaaacatacaHactMacacggtWataMtBVacRaSaatc
-cgtaBVttccagccBcttaRKtgtgcctttttRtgtcagcRttKtaaacKtaaatctcac
-aattgcaNtSBaaccgggttattaaBcKatDagttactcttcattVtttHaaggctKKga
-tacatcBggScagtVcacattttgaHaDSgHatRMaHWggtatatRgccDttcgtatcga
-aacaHtaagttaRatgaVacttagattVKtaaYttaaatcaNatccRttRRaMScNaaaD
-gttVHWgtcHaaHgacVaWtgttScactaagSgttatcttagggDtaccagWattWtRtg
-ttHWHacgattBtgVcaYatcggttgagKcWtKKcaVtgaYgWctgYggVctgtHgaNcV
-taBtWaaYatcDRaaRtSctgaHaYRttagatMatgcatttNattaDttaattgttctaa
-ccctcccctagaWBtttHtBccttagaVaatMcBHagaVcWcagBVttcBtaYMccagat
-gaaaaHctctaacgttagNWRtcggattNatcRaNHttcagtKttttgWatWttcSaNgg
-gaWtactKKMaacatKatacNattgctWtatctaVgagctatgtRaHtYcWcttagccaa
-tYttWttaWSSttaHcaaaaagVacVgtaVaRMgattaVcDactttcHHggHRtgNcctt
-tYatcatKgctcctctatVcaaaaKaaaagtatatctgMtWtaaaacaStttMtcgactt
-taSatcgDataaactaaacaagtaaVctaggaSccaatMVtaaSKNVattttgHccatca
-cBVctgcaVatVttRtactgtVcaattHgtaaattaaattttYtatattaaRSgYtgBag
-aHSBDgtagcacRHtYcBgtcacttacactaYcgctWtattgSHtSatcataaatataHt
-cgtYaaMNgBaatttaRgaMaatatttBtttaaaHHKaatctgatWatYaacttMctctt
-ttVctagctDaaagtaVaKaKRtaacBgtatccaaccactHHaagaagaaggaNaaatBW
-attccgStaMSaMatBttgcatgRSacgttVVtaaDMtcSgVatWcaSatcttttVatag
-ttactttacgatcaccNtaDVgSRcgVcgtgaacgaNtaNatatagtHtMgtHcMtagaa
-attBgtataRaaaacaYKgtRccYtatgaagtaataKgtaaMttgaaRVatgcagaKStc
-tHNaaatctBBtcttaYaBWHgtVtgacagcaRcataWctcaBcYacYgatDgtDHccta
->THREE Homo sapiens frequency
-aacacttcaccaggtatcgtgaaggctcaagattacccagagaacctttgcaatataaga
-atatgtatgcagcattaccctaagtaattatattctttttctgactcaaagtgacaagcc
-ctagtgtatattaaatcggtatatttgggaaattcctcaaactatcctaatcaggtagcc
-atgaaagtgatcaaaaaagttcgtacttataccatacatgaattctggccaagtaaaaaa
-tagattgcgcaaaattcgtaccttaagtctctcgccaagatattaggatcctattactca
-tatcgtgtttttctttattgccgccatccccggagtatctcacccatccttctcttaaag
-gcctaatattacctatgcaaataaacatatattgttgaaaattgagaacctgatcgtgat
-tcttatgtgtaccatatgtatagtaatcacgcgactatatagtgctttagtatcgcccgt
-gggtgagtgaatattctgggctagcgtgagatagtttcttgtcctaatatttttcagatc
-gaatagcttctatttttgtgtttattgacatatgtcgaaactccttactcagtgaaagtc
-atgaccagatccacgaacaatcttcggaatcagtctcgttttacggcggaatcttgagtc
-taacttatatcccgtcgcttactttctaacaccccttatgtatttttaaaattacgttta
-ttcgaacgtacttggcggaagcgttattttttgaagtaagttacattgggcagactcttg
-acattttcgatacgactttctttcatccatcacaggactcgttcgtattgatatcagaag
-ctcgtgatgattagttgtcttctttaccaatactttgaggcctattctgcgaaatttttg
-ttgccctgcgaacttcacataccaaggaacacctcgcaacatgccttcatatccatcgtt
-cattgtaattcttacacaatgaatcctaagtaattacatccctgcgtaaaagatggtagg
-ggcactgaggatatattaccaagcatttagttatgagtaatcagcaatgtttcttgtatt
-aagttctctaaaatagttacatcgtaatgttatctcgggttccgcgaataaacgagatag
-attcattatatatggccctaagcaaaaacctcctcgtattctgttggtaattagaatcac
-acaatacgggttgagatattaattatttgtagtacgaagagatataaaaagatgaacaat
-tactcaagtcaagatgtatacgggatttataataaaaatcgggtagagatctgctttgca
-attcagacgtgccactaaatcgtaatatgtcgcgttacatcagaaagggtaactattatt
-aattaataaagggcttaatcactacatattagatcttatccgatagtcttatctattcgt
-tgtatttttaagcggttctaattcagtcattatatcagtgctccgagttctttattattg
-ttttaaggatgacaaaatgcctcttgttataacgctgggagaagcagactaagagtcgga
-gcagttggtagaatgaggctgcaaaagacggtctcgacgaatggacagactttactaaac
-caatgaaagacagaagtagagcaaagtctgaagtggtatcagcttaattatgacaaccct
-taatacttccctttcgccgaatactggcgtggaaaggttttaaaagtcgaagtagttaga
-ggcatctctcgctcataaataggtagactactcgcaatccaatgtgactatgtaatactg
-ggaacatcagtccgcgatgcagcgtgtttatcaaccgtccccactcgcctggggagacat
-gagaccacccccgtggggattattagtccgcagtaatcgactcttgacaatccttttcga
-ttatgtcatagcaatttacgacagttcagcgaagtgactactcggcgaaatggtattact
-aaagcattcgaacccacatgaatgtgattcttggcaatttctaatccactaaagcttttc
-cgttgaatctggttgtagatatttatataagttcactaattaagatcacggtagtatatt
-gatagtgatgtctttgcaagaggttggccgaggaatttacggattctctattgatacaat
-ttgtctggcttataactcttaaggctgaaccaggcgtttttagacgacttgatcagctgt
-tagaatggtttggactccctctttcatgtcagtaacatttcagccgttattgttacgata
-tgcttgaacaatattgatctaccacacacccatagtatattttataggtcatgctgttac
-ctacgagcatggtattccacttcccattcaatgagtattcaacatcactagcctcagaga
-tgatgacccacctctaataacgtcacgttgcggccatgtgaaacctgaacttgagtagac
-gatatcaagcgctttaaattgcatataacatttgagggtaaagctaagcggatgctttat
-ataatcaatactcaataataagatttgattgcattttagagttatgacacgacatagttc
-actaacgagttactattcccagatctagactgaagtactgatcgagacgatccttacgtc
-gatgatcgttagttatcgacttaggtcgggtctctagcggtattggtacttaaccggaca
-ctatactaataacccatgatcaaagcataacagaatacagacgataatttcgccaacata
-tatgtacagaccccaagcatgagaagctcattgaaagctatcattgaagtcccgctcaca
-atgtgtcttttccagacggtttaactggttcccgggagtcctggagtttcgacttacata
-aatggaaacaatgtattttgctaatttatctatagcgtcatttggaccaatacagaatat
-tatgttgcctagtaatccactataacccgcaagtgctgatagaaaatttttagacgattt
-ataaatgccccaagtatccctcccgtgaatcctccgttatactaattagtattcgttcat
-acgtataccgcgcatatatgaacatttggcgataaggcgcgtgaattgttacgtgacaga
-gatagcagtttcttgtgatatggttaacagacgtacatgaagggaaactttatatctata
-gtgatgcttccgtagaaataccgccactggtctgccaatgatgaagtatgtagctttagg
-tttgtactatgaggctttcgtttgtttgcagagtataacagttgcgagtgaaaaaccgac
-gaatttatactaatacgctttcactattggctacaaaatagggaagagtttcaatcatga
-gagggagtatatggatgctttgtagctaaaggtagaacgtatgtatatgctgccgttcat
-tcttgaaagatacataagcgataagttacgacaattataagcaacatccctaccttcgta
-acgatttcactgttactgcgcttgaaatacactatggggctattggcggagagaagcaga
-tcgcgccgagcatatacgagacctataatgttgatgatagagaaggcgtctgaattgata
-catcgaagtacactttctttcgtagtatctctcgtcctctttctatctccggacacaaga
-attaagttatatatatagagtcttaccaatcatgttgaatcctgattctcagagttcttt
-ggcgggccttgtgatgactgagaaacaatgcaatattgctccaaatttcctaagcaaatt
-ctcggttatgttatgttatcagcaaagcgttacgttatgttatttaaatctggaatgacg
-gagcgaagttcttatgtcggtgtgggaataattcttttgaagacagcactccttaaataa
-tatcgctccgtgtttgtatttatcgaatgggtctgtaaccttgcacaagcaaatcggtgg
-tgtatatatcggataacaattaatacgatgttcatagtgacagtatactgatcgagtcct
-ctaaagtcaattacctcacttaacaatctcattgatgttgtgtcattcccggtatcgccc
-gtagtatgtgctctgattgaccgagtgtgaaccaaggaacatctactaatgcctttgtta
-ggtaagatctctctgaattccttcgtgccaacttaaaacattatcaaaatttcttctact
-tggattaactacttttacgagcatggcaaattcccctgtggaagacggttcattattatc
-ggaaaccttatagaaattgcgtgttgactgaaattagatttttattgtaagagttgcatc
-tttgcgattcctctggtctagcttccaatgaacagtcctcccttctattcgacatcgggt
-ccttcgtacatgtctttgcgatgtaataattaggttcggagtgtggccttaatgggtgca
-actaggaatacaacgcaaatttgctgacatgatagcaaatcggtatgccggcaccaaaac
-gtgctccttgcttagcttgtgaatgagactcagtagttaaataaatccatatctgcaatc
-gattccacaggtattgtccactatctttgaactactctaagagatacaagcttagctgag
-accgaggtgtatatgactacgctgatatctgtaaggtaccaatgcaggcaaagtatgcga
-gaagctaataccggctgtttccagctttataagattaaaatttggctgtcctggcggcct
-cagaattgttctatcgtaatcagttggttcattaattagctaagtacgaggtacaactta
-tctgtcccagaacagctccacaagtttttttacagccgaaacccctgtgtgaatcttaat
-atccaagcgcgttatctgattagagtttacaactcagtattttatcagtacgttttgttt
-ccaacattacccggtatgacaaaatgacgccacgtgtcgaataatggtctgaccaatgta
-ggaagtgaaaagataaatat
diff --git a/gcc/testsuite/go.test/test/bench/shootout/fasta.c b/gcc/testsuite/go.test/test/bench/shootout/fasta.c
deleted file mode 100644
index 64c1c52..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/fasta.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*
- * http://shootout.alioth.debian.org/u32/program.php?test=fasta&lang=gcc&id=3
- */
-
-/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by Petr Prokhorenkov
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef fwrite_unlocked
-// not available on OS X
-#define fwrite_unlocked fwrite
-#define fputc_unlocked fputc
-#define fputs_unlocked fputs
-#endif
-
-#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
-#define unlikely(x) __builtin_expect((x), 0)
-
-#define IM 139968
-#define IA 3877
-#define IC 29573
-
-#define LINE_LEN 60
-#define LOOKUP_SIZE 4096
-#define LOOKUP_SCALE ((float)(LOOKUP_SIZE - 1))
-
-typedef unsigned random_t;
-
-void
-random_init(random_t *random) {
- *random = 42;
-}
-
-// Special version with result rescaled to LOOKUP_SCALE.
-static inline
-float
-random_next_lookup(random_t *random) {
- *random = (*random*IA + IC)%IM;
-
- return (*random)*(LOOKUP_SCALE/IM);
-}
-
-struct amino_acid {
- char sym;
- float prob;
- float cprob_lookup;
-};
-
-void
-repeat(const char *alu, const char *title, int n) {
- int len = strlen(alu);
- char buffer[len + LINE_LEN];
- int pos = 0;
-
- memcpy(buffer, alu, len);
- memcpy(buffer + len, alu, LINE_LEN);
-
- fputs_unlocked(title, stdout);
- while (n > 0) {
- int bytes = n > LINE_LEN ? LINE_LEN : n;
-
- fwrite_unlocked(buffer + pos, bytes, 1, stdout);
- pos += bytes;
- if (pos > len) {
- pos -= len;
- }
- fputc_unlocked('\n', stdout);
- n -= bytes;
- }
-}
-
-/*
- * Lookup table contains mapping from real values to cumulative
- * probabilities. Careful selection of table size allows lookup
- * virtually in constant time.
- *
- * All cumulative probabilities are rescaled to LOOKUP_SCALE,
- * this allows to save one multiplication operation on each iteration
- * in randomize().
- */
-
-void *
-fill_lookup(struct amino_acid **lookup, struct amino_acid *amino_acid, int amino_acid_size) {
- float p = 0;
- int i, j;
-
- for (i = 0; i < amino_acid_size; i++) {
- p += amino_acid[i].prob;
- amino_acid[i].cprob_lookup = p*LOOKUP_SCALE;
- }
-
- // Prevent rounding error.
- amino_acid[amino_acid_size - 1].cprob_lookup = LOOKUP_SIZE - 1;
-
- for (i = 0, j = 0; i < LOOKUP_SIZE; i++) {
- while (amino_acid[j].cprob_lookup < i) {
- j++;
- }
- lookup[i] = &amino_acid[j];
- }
-
- return 0;
-}
-
-void
-randomize(struct amino_acid *amino_acid, int amino_acid_size,
- const char *title, int n, random_t *rand) {
- struct amino_acid *lookup[LOOKUP_SIZE];
- char line_buffer[LINE_LEN + 1];
- int i, j;
-
- line_buffer[LINE_LEN] = '\n';
-
- fill_lookup(lookup, amino_acid, amino_acid_size);
-
- fputs_unlocked(title, stdout);
-
- for (i = 0, j = 0; i < n; i++, j++) {
- if (j == LINE_LEN) {
- fwrite_unlocked(line_buffer, LINE_LEN + 1, 1, stdout);
- j = 0;
- }
-
- float r = random_next_lookup(rand);
- struct amino_acid *u = lookup[(short)r];
- while (unlikely(u->cprob_lookup < r)) {
- ++u;
- }
- line_buffer[j] = u->sym;
- }
- line_buffer[j] = '\n';
- fwrite_unlocked(line_buffer, j + 1, 1, stdout);
-}
-
-struct amino_acid amino_acid[] = {
- { 'a', 0.27 },
- { 'c', 0.12 },
- { 'g', 0.12 },
- { 't', 0.27 },
-
- { 'B', 0.02 },
- { 'D', 0.02 },
- { 'H', 0.02 },
- { 'K', 0.02 },
- { 'M', 0.02 },
- { 'N', 0.02 },
- { 'R', 0.02 },
- { 'S', 0.02 },
- { 'V', 0.02 },
- { 'W', 0.02 },
- { 'Y', 0.02 },
-};
-
-struct amino_acid homo_sapiens[] = {
- { 'a', 0.3029549426680 },
- { 'c', 0.1979883004921 },
- { 'g', 0.1975473066391 },
- { 't', 0.3015094502008 },
-};
-
-static const char alu[] =
- "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTG"
- "GGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGA"
- "GACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAA"
- "AATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT"
- "CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAAC"
- "CCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTG"
- "CACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
-
-int
-main(int argc, const char **argv) {
- int n = argc > 1 ? atoi( argv[1] ) : 512;
- random_t rand;
-
- random_init(&rand);
-
- repeat(alu, ">ONE Homo sapiens alu\n", n*2);
- randomize(amino_acid, ARRAY_SIZE(amino_acid),
- ">TWO IUB ambiguity codes\n", n*3, &rand);
- randomize(homo_sapiens, ARRAY_SIZE(homo_sapiens),
- ">THREE Homo sapiens frequency\n", n*5, &rand);
-
- return 0;
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/fasta.go b/gcc/testsuite/go.test/test/bench/shootout/fasta.go
deleted file mode 100644
index 17ff5da..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/fasta.go
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by The Go Authors.
- * Based on C program by by Petr Prokhorenkov.
- */
-
-package main
-
-import (
- "flag"
- "os"
-)
-
-var out = make(buffer, 0, 32768)
-
-var n = flag.Int("n", 1000, "length of result")
-
-const Line = 60
-
-func Repeat(alu []byte, n int) {
- buf := append(alu, alu...)
- off := 0
- for n > 0 {
- m := n
- if m > Line {
- m = Line
- }
- buf1 := out.NextWrite(m + 1)
- copy(buf1, buf[off:])
- buf1[m] = '\n'
- if off += m; off >= len(alu) {
- off -= len(alu)
- }
- n -= m
- }
-}
-
-const (
- IM = 139968
- IA = 3877
- IC = 29573
-
- LookupSize = 4096
- LookupScale float64 = LookupSize - 1
-)
-
-var rand uint32 = 42
-
-type Acid struct {
- sym byte
- prob float64
- cprob float64
- next *Acid
-}
-
-func computeLookup(acid []Acid) *[LookupSize]*Acid {
- var lookup [LookupSize]*Acid
- var p float64
- for i := range acid {
- p += acid[i].prob
- acid[i].cprob = p * LookupScale
- if i > 0 {
- acid[i-1].next = &acid[i]
- }
- }
- acid[len(acid)-1].cprob = 1.0 * LookupScale
-
- j := 0
- for i := range lookup {
- for acid[j].cprob < float64(i) {
- j++
- }
- lookup[i] = &acid[j]
- }
-
- return &lookup
-}
-
-func Random(acid []Acid, n int) {
- lookup := computeLookup(acid)
- for n > 0 {
- m := n
- if m > Line {
- m = Line
- }
- buf := out.NextWrite(m + 1)
- f := LookupScale / IM
- myrand := rand
- for i := 0; i < m; i++ {
- myrand = (myrand*IA + IC) % IM
- r := float64(int(myrand)) * f
- a := lookup[int(r)]
- for a.cprob < r {
- a = a.next
- }
- buf[i] = a.sym
- }
- rand = myrand
- buf[m] = '\n'
- n -= m
- }
-}
-
-func main() {
- defer out.Flush()
-
- flag.Parse()
-
- iub := []Acid{
- {prob: 0.27, sym: 'a'},
- {prob: 0.12, sym: 'c'},
- {prob: 0.12, sym: 'g'},
- {prob: 0.27, sym: 't'},
- {prob: 0.02, sym: 'B'},
- {prob: 0.02, sym: 'D'},
- {prob: 0.02, sym: 'H'},
- {prob: 0.02, sym: 'K'},
- {prob: 0.02, sym: 'M'},
- {prob: 0.02, sym: 'N'},
- {prob: 0.02, sym: 'R'},
- {prob: 0.02, sym: 'S'},
- {prob: 0.02, sym: 'V'},
- {prob: 0.02, sym: 'W'},
- {prob: 0.02, sym: 'Y'},
- }
-
- homosapiens := []Acid{
- {prob: 0.3029549426680, sym: 'a'},
- {prob: 0.1979883004921, sym: 'c'},
- {prob: 0.1975473066391, sym: 'g'},
- {prob: 0.3015094502008, sym: 't'},
- }
-
- alu := []byte(
- "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG" +
- "GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA" +
- "CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT" +
- "ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA" +
- "GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG" +
- "AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC" +
- "AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA")
-
- out.WriteString(">ONE Homo sapiens alu\n")
- Repeat(alu, 2**n)
- out.WriteString(">TWO IUB ambiguity codes\n")
- Random(iub, 3**n)
- out.WriteString(">THREE Homo sapiens frequency\n")
- Random(homosapiens, 5**n)
-}
-
-type buffer []byte
-
-func (b *buffer) Flush() {
- p := *b
- if len(p) > 0 {
- os.Stdout.Write(p)
- }
- *b = p[0:0]
-}
-
-func (b *buffer) WriteString(s string) {
- p := b.NextWrite(len(s))
- copy(p, s)
-}
-
-func (b *buffer) NextWrite(n int) []byte {
- p := *b
- if len(p)+n > cap(p) {
- b.Flush()
- p = *b
- }
- out := p[len(p) : len(p)+n]
- *b = p[:len(p)+n]
- return out
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/fasta.txt b/gcc/testsuite/go.test/test/bench/shootout/fasta.txt
deleted file mode 100644
index f1caba0..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/fasta.txt
+++ /dev/null
@@ -1,171 +0,0 @@
->ONE Homo sapiens alu
-GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA
-TCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACT
-AAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAG
-GCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCG
-CCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGT
-GGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCA
-GGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAA
-TTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAG
-AATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCA
-GCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGT
-AATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACC
-AGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTG
-GTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACC
-CGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAG
-AGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTT
-TGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACA
-TGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCT
-GTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGG
-TTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGT
-CTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGG
-CGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCG
-TCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTA
-CTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCG
-AGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCG
-GGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACC
-TGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAA
-TACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGA
-GGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACT
-GCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTC
-ACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGT
-TCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGC
-CGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCG
-CTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTG
-GGCGACAGAGCGAGACTCCG
->TWO IUB ambiguity codes
-cttBtatcatatgctaKggNcataaaSatgtaaaDcDRtBggDtctttataattcBgtcg
-tactDtDagcctatttSVHtHttKtgtHMaSattgWaHKHttttagacatWatgtRgaaa
-NtactMcSMtYtcMgRtacttctWBacgaaatatagScDtttgaagacacatagtVgYgt
-cattHWtMMWcStgttaggKtSgaYaaccWStcgBttgcgaMttBYatcWtgacaYcaga
-gtaBDtRacttttcWatMttDBcatWtatcttactaBgaYtcttgttttttttYaaScYa
-HgtgttNtSatcMtcVaaaStccRcctDaataataStcYtRDSaMtDttgttSagtRRca
-tttHatSttMtWgtcgtatSSagactYaaattcaMtWatttaSgYttaRgKaRtccactt
-tattRggaMcDaWaWagttttgacatgttctacaaaRaatataataaMttcgDacgaSSt
-acaStYRctVaNMtMgtaggcKatcttttattaaaaagVWaHKYagtttttatttaacct
-tacgtVtcVaattVMBcttaMtttaStgacttagattWWacVtgWYagWVRctDattBYt
-gtttaagaagattattgacVatMaacattVctgtBSgaVtgWWggaKHaatKWcBScSWa
-accRVacacaaactaccScattRatatKVtactatatttHttaagtttSKtRtacaaagt
-RDttcaaaaWgcacatWaDgtDKacgaacaattacaRNWaatHtttStgttattaaMtgt
-tgDcgtMgcatBtgcttcgcgaDWgagctgcgaggggVtaaScNatttacttaatgacag
-cccccacatYScaMgtaggtYaNgttctgaMaacNaMRaacaaacaKctacatagYWctg
-ttWaaataaaataRattagHacacaagcgKatacBttRttaagtatttccgatctHSaat
-actcNttMaagtattMtgRtgaMgcataatHcMtaBSaRattagttgatHtMttaaKagg
-YtaaBataSaVatactWtataVWgKgttaaaacagtgcgRatatacatVtHRtVYataSa
-KtWaStVcNKHKttactatccctcatgWHatWaRcttactaggatctataDtDHBttata
-aaaHgtacVtagaYttYaKcctattcttcttaataNDaaggaaaDYgcggctaaWSctBa
-aNtgctggMBaKctaMVKagBaactaWaDaMaccYVtNtaHtVWtKgRtcaaNtYaNacg
-gtttNattgVtttctgtBaWgtaattcaagtcaVWtactNggattctttaYtaaagccgc
-tcttagHVggaYtgtNcDaVagctctctKgacgtatagYcctRYHDtgBattDaaDgccK
-tcHaaStttMcctagtattgcRgWBaVatHaaaataYtgtttagMDMRtaataaggatMt
-ttctWgtNtgtgaaaaMaatatRtttMtDgHHtgtcattttcWattRSHcVagaagtacg
-ggtaKVattKYagactNaatgtttgKMMgYNtcccgSKttctaStatatNVataYHgtNa
-BKRgNacaactgatttcctttaNcgatttctctataScaHtataRagtcRVttacDSDtt
-aRtSatacHgtSKacYagttMHtWataggatgactNtatSaNctataVtttRNKtgRacc
-tttYtatgttactttttcctttaaacatacaHactMacacggtWataMtBVacRaSaatc
-cgtaBVttccagccBcttaRKtgtgcctttttRtgtcagcRttKtaaacKtaaatctcac
-aattgcaNtSBaaccgggttattaaBcKatDagttactcttcattVtttHaaggctKKga
-tacatcBggScagtVcacattttgaHaDSgHatRMaHWggtatatRgccDttcgtatcga
-aacaHtaagttaRatgaVacttagattVKtaaYttaaatcaNatccRttRRaMScNaaaD
-gttVHWgtcHaaHgacVaWtgttScactaagSgttatcttagggDtaccagWattWtRtg
-ttHWHacgattBtgVcaYatcggttgagKcWtKKcaVtgaYgWctgYggVctgtHgaNcV
-taBtWaaYatcDRaaRtSctgaHaYRttagatMatgcatttNattaDttaattgttctaa
-ccctcccctagaWBtttHtBccttagaVaatMcBHagaVcWcagBVttcBtaYMccagat
-gaaaaHctctaacgttagNWRtcggattNatcRaNHttcagtKttttgWatWttcSaNgg
-gaWtactKKMaacatKatacNattgctWtatctaVgagctatgtRaHtYcWcttagccaa
-tYttWttaWSSttaHcaaaaagVacVgtaVaRMgattaVcDactttcHHggHRtgNcctt
-tYatcatKgctcctctatVcaaaaKaaaagtatatctgMtWtaaaacaStttMtcgactt
-taSatcgDataaactaaacaagtaaVctaggaSccaatMVtaaSKNVattttgHccatca
-cBVctgcaVatVttRtactgtVcaattHgtaaattaaattttYtatattaaRSgYtgBag
-aHSBDgtagcacRHtYcBgtcacttacactaYcgctWtattgSHtSatcataaatataHt
-cgtYaaMNgBaatttaRgaMaatatttBtttaaaHHKaatctgatWatYaacttMctctt
-ttVctagctDaaagtaVaKaKRtaacBgtatccaaccactHHaagaagaaggaNaaatBW
-attccgStaMSaMatBttgcatgRSacgttVVtaaDMtcSgVatWcaSatcttttVatag
-ttactttacgatcaccNtaDVgSRcgVcgtgaacgaNtaNatatagtHtMgtHcMtagaa
-attBgtataRaaaacaYKgtRccYtatgaagtaataKgtaaMttgaaRVatgcagaKStc
-tHNaaatctBBtcttaYaBWHgtVtgacagcaRcataWctcaBcYacYgatDgtDHccta
->THREE Homo sapiens frequency
-aacacttcaccaggtatcgtgaaggctcaagattacccagagaacctttgcaatataaga
-atatgtatgcagcattaccctaagtaattatattctttttctgactcaaagtgacaagcc
-ctagtgtatattaaatcggtatatttgggaaattcctcaaactatcctaatcaggtagcc
-atgaaagtgatcaaaaaagttcgtacttataccatacatgaattctggccaagtaaaaaa
-tagattgcgcaaaattcgtaccttaagtctctcgccaagatattaggatcctattactca
-tatcgtgtttttctttattgccgccatccccggagtatctcacccatccttctcttaaag
-gcctaatattacctatgcaaataaacatatattgttgaaaattgagaacctgatcgtgat
-tcttatgtgtaccatatgtatagtaatcacgcgactatatagtgctttagtatcgcccgt
-gggtgagtgaatattctgggctagcgtgagatagtttcttgtcctaatatttttcagatc
-gaatagcttctatttttgtgtttattgacatatgtcgaaactccttactcagtgaaagtc
-atgaccagatccacgaacaatcttcggaatcagtctcgttttacggcggaatcttgagtc
-taacttatatcccgtcgcttactttctaacaccccttatgtatttttaaaattacgttta
-ttcgaacgtacttggcggaagcgttattttttgaagtaagttacattgggcagactcttg
-acattttcgatacgactttctttcatccatcacaggactcgttcgtattgatatcagaag
-ctcgtgatgattagttgtcttctttaccaatactttgaggcctattctgcgaaatttttg
-ttgccctgcgaacttcacataccaaggaacacctcgcaacatgccttcatatccatcgtt
-cattgtaattcttacacaatgaatcctaagtaattacatccctgcgtaaaagatggtagg
-ggcactgaggatatattaccaagcatttagttatgagtaatcagcaatgtttcttgtatt
-aagttctctaaaatagttacatcgtaatgttatctcgggttccgcgaataaacgagatag
-attcattatatatggccctaagcaaaaacctcctcgtattctgttggtaattagaatcac
-acaatacgggttgagatattaattatttgtagtacgaagagatataaaaagatgaacaat
-tactcaagtcaagatgtatacgggatttataataaaaatcgggtagagatctgctttgca
-attcagacgtgccactaaatcgtaatatgtcgcgttacatcagaaagggtaactattatt
-aattaataaagggcttaatcactacatattagatcttatccgatagtcttatctattcgt
-tgtatttttaagcggttctaattcagtcattatatcagtgctccgagttctttattattg
-ttttaaggatgacaaaatgcctcttgttataacgctgggagaagcagactaagagtcgga
-gcagttggtagaatgaggctgcaaaagacggtctcgacgaatggacagactttactaaac
-caatgaaagacagaagtagagcaaagtctgaagtggtatcagcttaattatgacaaccct
-taatacttccctttcgccgaatactggcgtggaaaggttttaaaagtcgaagtagttaga
-ggcatctctcgctcataaataggtagactactcgcaatccaatgtgactatgtaatactg
-ggaacatcagtccgcgatgcagcgtgtttatcaaccgtccccactcgcctggggagacat
-gagaccacccccgtggggattattagtccgcagtaatcgactcttgacaatccttttcga
-ttatgtcatagcaatttacgacagttcagcgaagtgactactcggcgaaatggtattact
-aaagcattcgaacccacatgaatgtgattcttggcaatttctaatccactaaagcttttc
-cgttgaatctggttgtagatatttatataagttcactaattaagatcacggtagtatatt
-gatagtgatgtctttgcaagaggttggccgaggaatttacggattctctattgatacaat
-ttgtctggcttataactcttaaggctgaaccaggcgtttttagacgacttgatcagctgt
-tagaatggtttggactccctctttcatgtcagtaacatttcagccgttattgttacgata
-tgcttgaacaatattgatctaccacacacccatagtatattttataggtcatgctgttac
-ctacgagcatggtattccacttcccattcaatgagtattcaacatcactagcctcagaga
-tgatgacccacctctaataacgtcacgttgcggccatgtgaaacctgaacttgagtagac
-gatatcaagcgctttaaattgcatataacatttgagggtaaagctaagcggatgctttat
-ataatcaatactcaataataagatttgattgcattttagagttatgacacgacatagttc
-actaacgagttactattcccagatctagactgaagtactgatcgagacgatccttacgtc
-gatgatcgttagttatcgacttaggtcgggtctctagcggtattggtacttaaccggaca
-ctatactaataacccatgatcaaagcataacagaatacagacgataatttcgccaacata
-tatgtacagaccccaagcatgagaagctcattgaaagctatcattgaagtcccgctcaca
-atgtgtcttttccagacggtttaactggttcccgggagtcctggagtttcgacttacata
-aatggaaacaatgtattttgctaatttatctatagcgtcatttggaccaatacagaatat
-tatgttgcctagtaatccactataacccgcaagtgctgatagaaaatttttagacgattt
-ataaatgccccaagtatccctcccgtgaatcctccgttatactaattagtattcgttcat
-acgtataccgcgcatatatgaacatttggcgataaggcgcgtgaattgttacgtgacaga
-gatagcagtttcttgtgatatggttaacagacgtacatgaagggaaactttatatctata
-gtgatgcttccgtagaaataccgccactggtctgccaatgatgaagtatgtagctttagg
-tttgtactatgaggctttcgtttgtttgcagagtataacagttgcgagtgaaaaaccgac
-gaatttatactaatacgctttcactattggctacaaaatagggaagagtttcaatcatga
-gagggagtatatggatgctttgtagctaaaggtagaacgtatgtatatgctgccgttcat
-tcttgaaagatacataagcgataagttacgacaattataagcaacatccctaccttcgta
-acgatttcactgttactgcgcttgaaatacactatggggctattggcggagagaagcaga
-tcgcgccgagcatatacgagacctataatgttgatgatagagaaggcgtctgaattgata
-catcgaagtacactttctttcgtagtatctctcgtcctctttctatctccggacacaaga
-attaagttatatatatagagtcttaccaatcatgttgaatcctgattctcagagttcttt
-ggcgggccttgtgatgactgagaaacaatgcaatattgctccaaatttcctaagcaaatt
-ctcggttatgttatgttatcagcaaagcgttacgttatgttatttaaatctggaatgacg
-gagcgaagttcttatgtcggtgtgggaataattcttttgaagacagcactccttaaataa
-tatcgctccgtgtttgtatttatcgaatgggtctgtaaccttgcacaagcaaatcggtgg
-tgtatatatcggataacaattaatacgatgttcatagtgacagtatactgatcgagtcct
-ctaaagtcaattacctcacttaacaatctcattgatgttgtgtcattcccggtatcgccc
-gtagtatgtgctctgattgaccgagtgtgaaccaaggaacatctactaatgcctttgtta
-ggtaagatctctctgaattccttcgtgccaacttaaaacattatcaaaatttcttctact
-tggattaactacttttacgagcatggcaaattcccctgtggaagacggttcattattatc
-ggaaaccttatagaaattgcgtgttgactgaaattagatttttattgtaagagttgcatc
-tttgcgattcctctggtctagcttccaatgaacagtcctcccttctattcgacatcgggt
-ccttcgtacatgtctttgcgatgtaataattaggttcggagtgtggccttaatgggtgca
-actaggaatacaacgcaaatttgctgacatgatagcaaatcggtatgccggcaccaaaac
-gtgctccttgcttagcttgtgaatgagactcagtagttaaataaatccatatctgcaatc
-gattccacaggtattgtccactatctttgaactactctaagagatacaagcttagctgag
-accgaggtgtatatgactacgctgatatctgtaaggtaccaatgcaggcaaagtatgcga
-gaagctaataccggctgtttccagctttataagattaaaatttggctgtcctggcggcct
-cagaattgttctatcgtaatcagttggttcattaattagctaagtacgaggtacaactta
-tctgtcccagaacagctccacaagtttttttacagccgaaacccctgtgtgaatcttaat
-atccaagcgcgttatctgattagagtttacaactcagtattttatcagtacgttttgttt
-ccaacattacccggtatgacaaaatgacgccacgtgtcgaataatggtctgaccaatgta
-ggaagtgaaaagataaatat
diff --git a/gcc/testsuite/go.test/test/bench/shootout/k-nucleotide-parallel.go b/gcc/testsuite/go.test/test/bench/shootout/k-nucleotide-parallel.go
deleted file mode 100644
index 96c80d8..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/k-nucleotide-parallel.go
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by The Go Authors.
- */
-
-package main
-
-import (
- "bufio"
- "bytes"
- "fmt"
- "io/ioutil"
- "os"
- "runtime"
- "sort"
-)
-
-func count(data string, n int) map[string]int {
- counts := make(map[string]int)
- top := len(data) - n
- for i := 0; i <= top; i++ {
- s := data[i : i+n]
- counts[s]++
- }
- return counts
-}
-
-func countOne(data string, s string) int {
- return count(data, len(s))[s]
-}
-
-type kNuc struct {
- name string
- count int
-}
-
-type kNucArray []kNuc
-
-func (kn kNucArray) Len() int { return len(kn) }
-func (kn kNucArray) Swap(i, j int) { kn[i], kn[j] = kn[j], kn[i] }
-func (kn kNucArray) Less(i, j int) bool {
- if kn[i].count == kn[j].count {
- return kn[i].name > kn[j].name // sort down
- }
- return kn[i].count > kn[j].count
-}
-
-func sortedArray(m map[string]int) kNucArray {
- kn := make(kNucArray, len(m))
- i := 0
- for k, v := range m {
- kn[i] = kNuc{k, v}
- i++
- }
- sort.Sort(kn)
- return kn
-}
-
-func printKnucs(a kNucArray) {
- sum := 0
- for _, kn := range a {
- sum += kn.count
- }
- for _, kn := range a {
- fmt.Printf("%s %.3f\n", kn.name, 100*float64(kn.count)/float64(sum))
- }
- fmt.Print("\n")
-}
-
-func main() {
- runtime.GOMAXPROCS(4)
- in := bufio.NewReader(os.Stdin)
- three := []byte(">THREE ")
- for {
- line, err := in.ReadSlice('\n')
- if err != nil {
- fmt.Fprintln(os.Stderr, "ReadLine err:", err)
- os.Exit(2)
- }
- if line[0] == '>' && bytes.Equal(line[0:len(three)], three) {
- break
- }
- }
- data, err := ioutil.ReadAll(in)
- if err != nil {
- fmt.Fprintln(os.Stderr, "ReadAll err:", err)
- os.Exit(2)
- }
- // delete the newlines and convert to upper case
- j := 0
- for i := 0; i < len(data); i++ {
- if data[i] != '\n' {
- data[j] = data[i] &^ ' ' // upper case
- j++
- }
- }
- str := string(data[0:j])
-
- var arr1, arr2 kNucArray
- countsdone := make(chan bool)
- go func() {
- arr1 = sortedArray(count(str, 1))
- countsdone <- true
- }()
- go func() {
- arr2 = sortedArray(count(str, 2))
- countsdone <- true
- }()
-
- interests := []string{"GGT", "GGTA", "GGTATT", "GGTATTTTAATT", "GGTATTTTAATTTATAGT"}
- results := make([]chan string, len(interests))
- for i, s := range interests {
- ch := make(chan string)
- results[i] = ch
- go func(result chan string, ss string) {
- result <- fmt.Sprintf("%d %s\n", countOne(str, ss), ss)
- }(ch, s)
- }
- <-countsdone
- <-countsdone
- printKnucs(arr1)
- printKnucs(arr2)
- for _, rc := range results {
- fmt.Print(<-rc)
- }
-
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/k-nucleotide-parallel.txt b/gcc/testsuite/go.test/test/bench/shootout/k-nucleotide-parallel.txt
deleted file mode 100644
index 84169b8..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/k-nucleotide-parallel.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-T 31.520
-A 29.600
-C 19.480
-G 19.400
-
-AT 9.922
-TT 9.602
-TA 9.402
-AA 8.402
-GA 6.321
-TC 6.301
-TG 6.201
-GT 6.041
-CT 5.961
-AG 5.841
-CA 5.461
-AC 5.441
-CC 4.041
-CG 4.021
-GC 3.701
-GG 3.341
-
-54 GGT
-24 GGTA
-4 GGTATT
-0 GGTATTTTAATT
-0 GGTATTTTAATTTATAGT
diff --git a/gcc/testsuite/go.test/test/bench/shootout/k-nucleotide.c b/gcc/testsuite/go.test/test/bench/shootout/k-nucleotide.c
deleted file mode 100644
index 9c30620..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/k-nucleotide.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <glib.h>
-
-typedef struct stat_s stat_t;
-struct stat_s
-{
- const gchar *key;
- long stat;
-};
-
-#define MAX_ELM (8192 / sizeof (stat_t))
-
-static int
-generate_frequencies (int fl, char *buffer, long buflen,
- GHashTable *ht, GTrashStack **ts, GPtrArray *roots, GStringChunk *sc)
-{
- gchar *key;
- long i;
-
- if (fl > buflen) return 0;
- if (fl == 0) return 0;
-
- for (i = 0; i < buflen - fl + 1; ++i)
- {
- char nulled;
- stat_t *stat;
-
- nulled = buffer[i + fl];
- buffer[i + fl] = '\0';
-
- key = g_string_chunk_insert_const(sc, buffer + i);
-
- stat = g_hash_table_lookup(ht, key);
- if (!stat)
- {
- stat = g_trash_stack_pop(ts);
- if (!stat)
- {
- int j;
-
- stat = malloc(sizeof (stat_t) * MAX_ELM);
- g_ptr_array_add(roots, stat);
-
- for (j = 1; j < MAX_ELM; ++j)
- g_trash_stack_push(ts, stat + j);
- }
- stat->stat = 1;
- stat->key = key;
-
- g_hash_table_insert(ht, key, stat);
- }
- else
- stat->stat++;
-
- buffer[i + fl] = nulled;
- }
-
- return buflen - fl + 1;
-}
-
-static int
-cmp_func(gconstpointer a, gconstpointer b)
-{
- const stat_t *left = a;
- const stat_t *right = b;
-
- return right->stat - left->stat;
-}
-
-static void
-sorted_list(gpointer key, gpointer value, gpointer user_data)
-{
- stat_t *data = value;
- GList **lst = user_data;
-
- *lst = g_list_insert_sorted(*lst, data, cmp_func);
-}
-
-static void
-display_stat(gpointer data, gpointer user_data)
-{
- long *total = user_data;
- stat_t *st = data;
-
- printf("%s %.3f\n", st->key, 100 * (float) st->stat / *total);
-}
-
-void
-write_frequencies (int fl, char *buffer, long buflen, GTrashStack **ts, GPtrArray *roots)
-{
- GStringChunk *sc;
- GHashTable *ht;
- GList *lst;
- long total;
-
- ht = g_hash_table_new_full(g_str_hash, g_str_equal, NULL /* free key */, NULL /* free value */);
- sc = g_string_chunk_new(buflen);
- lst = NULL;
-
- total = generate_frequencies (fl, buffer, buflen, ht, ts, roots, sc);
-
- if (!total) goto on_error;
-
- g_hash_table_foreach(ht, sorted_list, &lst);
- g_list_foreach(lst, display_stat, &total);
- g_list_free(lst);
-
- on_error:
- g_hash_table_destroy(ht);
- g_string_chunk_free(sc);
-}
-
-void
-write_count (char *searchFor, char *buffer, long buflen, GTrashStack **ts, GPtrArray *roots)
-{
- GStringChunk *sc;
- GHashTable *ht;
- stat_t *result;
- GList *lst;
- long total;
- long fl;
-
- fl = strlen(searchFor);
-
- ht = g_hash_table_new_full(g_str_hash, g_str_equal, NULL /* free key */, NULL /* free value */);
- sc = g_string_chunk_new(buflen);
- lst = NULL;
- result = NULL;
-
- total = generate_frequencies (fl, buffer, buflen, ht, ts, roots, sc);
-
- if (!total) goto on_error;
-
- result = g_hash_table_lookup(ht, searchFor);
-
- on_error:
- printf("%ld\t%s\n", result ? result->stat : 0, searchFor);
-
- g_hash_table_destroy(ht);
- g_string_chunk_free(sc);
-}
-
-int
-main ()
-{
- char buffer[4096];
- GTrashStack *ts;
- GPtrArray *roots;
- GString *stuff;
- gchar *s;
- int len;
-
- roots = g_ptr_array_new();
- ts = NULL;
-
- while (fgets(buffer, sizeof (buffer), stdin))
- if (strncmp(buffer, ">THREE", 6) == 0)
- break;
-
- stuff = g_string_new(NULL);
-
- while (fgets(buffer, sizeof (buffer), stdin))
- {
- size_t sz;
-
- if (buffer[0] == '>')
- break;
-
- sz = strlen(buffer);
- if (buffer[sz - 1] == '\n')
- --sz;
-
- stuff = g_string_append_len(stuff, buffer, sz);
- }
-
- stuff = g_string_ascii_up(stuff);
- len = stuff->len;
- s = g_string_free(stuff, FALSE);
-
- write_frequencies(1, s, len, &ts, roots);
- printf("\n");
- write_frequencies(2, s, len, &ts, roots);
- printf("\n");
- write_count("GGT", s, len, &ts, roots);
- write_count("GGTA", s, len, &ts, roots);
- write_count("GGTATT", s, len, &ts, roots);
- write_count("GGTATTTTAATT", s, len, &ts, roots);
- write_count("GGTATTTTAATTTATAGT", s, len, &ts, roots);
-
- free(s);
-
- g_ptr_array_foreach(roots, (GFunc)free, NULL);
- g_ptr_array_free(roots, TRUE);
-
- return 0;
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/k-nucleotide.go b/gcc/testsuite/go.test/test/bench/shootout/k-nucleotide.go
deleted file mode 100644
index fdc98ed..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/k-nucleotide.go
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by The Go Authors.
- */
-
-package main
-
-import (
- "bufio"
- "bytes"
- "fmt"
- "io/ioutil"
- "os"
- "sort"
-)
-
-var in *bufio.Reader
-
-func count(data string, n int) map[string]int {
- counts := make(map[string]int)
- top := len(data) - n
- for i := 0; i <= top; i++ {
- s := data[i : i+n]
- counts[s]++
- }
- return counts
-}
-
-func countOne(data string, s string) int {
- return count(data, len(s))[s]
-}
-
-type kNuc struct {
- name string
- count int
-}
-
-type kNucArray []kNuc
-
-func (kn kNucArray) Len() int { return len(kn) }
-func (kn kNucArray) Swap(i, j int) { kn[i], kn[j] = kn[j], kn[i] }
-func (kn kNucArray) Less(i, j int) bool {
- if kn[i].count == kn[j].count {
- return kn[i].name > kn[j].name // sort down
- }
- return kn[i].count > kn[j].count
-}
-
-func sortedArray(m map[string]int) kNucArray {
- kn := make(kNucArray, len(m))
- i := 0
- for k, v := range m {
- kn[i].name = k
- kn[i].count = v
- i++
- }
- sort.Sort(kn)
- return kn
-}
-
-func print(m map[string]int) {
- a := sortedArray(m)
- sum := 0
- for _, kn := range a {
- sum += kn.count
- }
- for _, kn := range a {
- fmt.Printf("%s %.3f\n", kn.name, 100*float64(kn.count)/float64(sum))
- }
-}
-
-func main() {
- in = bufio.NewReader(os.Stdin)
- three := []byte(">THREE ")
- for {
- line, err := in.ReadSlice('\n')
- if err != nil {
- fmt.Fprintln(os.Stderr, "ReadLine err:", err)
- os.Exit(2)
- }
- if line[0] == '>' && bytes.Equal(line[0:len(three)], three) {
- break
- }
- }
- data, err := ioutil.ReadAll(in)
- if err != nil {
- fmt.Fprintln(os.Stderr, "ReadAll err:", err)
- os.Exit(2)
- }
- // delete the newlines and convert to upper case
- j := 0
- for i := 0; i < len(data); i++ {
- if data[i] != '\n' {
- data[j] = data[i] &^ ' ' // upper case
- j++
- }
- }
- str := string(data[0:j])
-
- print(count(str, 1))
- fmt.Print("\n")
-
- print(count(str, 2))
- fmt.Print("\n")
-
- interests := []string{"GGT", "GGTA", "GGTATT", "GGTATTTTAATT", "GGTATTTTAATTTATAGT"}
- for _, s := range interests {
- fmt.Printf("%d %s\n", countOne(str, s), s)
- }
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/k-nucleotide.txt b/gcc/testsuite/go.test/test/bench/shootout/k-nucleotide.txt
deleted file mode 100644
index 84169b8..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/k-nucleotide.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-T 31.520
-A 29.600
-C 19.480
-G 19.400
-
-AT 9.922
-TT 9.602
-TA 9.402
-AA 8.402
-GA 6.321
-TC 6.301
-TG 6.201
-GT 6.041
-CT 5.961
-AG 5.841
-CA 5.461
-AC 5.441
-CC 4.041
-CG 4.021
-GC 3.701
-GG 3.341
-
-54 GGT
-24 GGTA
-4 GGTATT
-0 GGTATTTTAATT
-0 GGTATTTTAATTTATAGT
diff --git a/gcc/testsuite/go.test/test/bench/shootout/mandelbrot.c b/gcc/testsuite/go.test/test/bench/shootout/mandelbrot.c
deleted file mode 100644
index c177c08..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/mandelbrot.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Shootout
- http://shootout.alioth.debian.org/
-
- contributed by Greg Buchholz
-
- for the debian (AMD) machine...
- compile flags: -O3 -ffast-math -march=athlon-xp -funroll-loops
-
- for the gp4 (Intel) machine...
- compile flags: -O3 -ffast-math -march=pentium4 -funroll-loops
-*/
-
-#include<stdio.h>
-
-int main (int argc, char **argv)
-{
- int w, h, bit_num = 0;
- char byte_acc = 0;
- int i, iter = 50;
- double x, y, limit = 2.0;
- double Zr, Zi, Cr, Ci, Tr, Ti;
-
- w = h = atoi(argv[1]);
-
- printf("P4\n%d %d\n",w,h);
-
- for(y=0;y<h;++y)
- {
- for(x=0;x<w;++x)
- {
- Zr = Zi = Tr = Ti = 0.0;
- Cr = (2.0*x/w - 1.5); Ci=(2.0*y/h - 1.0);
-
- for (i=0;i<iter && (Tr+Ti <= limit*limit);++i)
- {
- Zi = 2.0*Zr*Zi + Ci;
- Zr = Tr - Ti + Cr;
- Tr = Zr * Zr;
- Ti = Zi * Zi;
- }
-
- byte_acc <<= 1;
- if(Tr+Ti <= limit*limit) byte_acc |= 0x01;
-
- ++bit_num;
-
- if(bit_num == 8)
- {
- putc(byte_acc,stdout);
- byte_acc = 0;
- bit_num = 0;
- }
- else if(x == w-1)
- {
- byte_acc <<= (8-w%8);
- putc(byte_acc,stdout);
- byte_acc = 0;
- bit_num = 0;
- }
- }
- }
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/mandelbrot.go b/gcc/testsuite/go.test/test/bench/shootout/mandelbrot.go
deleted file mode 100644
index df60343..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/mandelbrot.go
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by The Go Authors.
- * Based on mandelbrot.c contributed by Greg Buchholz
- */
-
-package main
-
-import (
- "bufio"
- "flag"
- "fmt"
- "os"
-)
-
-var n = flag.Int("n", 200, "size")
-
-func main() {
- flag.Parse()
- out := bufio.NewWriter(os.Stdout)
- defer out.Flush()
-
- w := float64(*n)
- h := float64(*n)
- bit_num := 0
- byte_acc := byte(0)
- const Iter = 50
- const Zero float64 = 0
- const Limit = 2.0
-
- fmt.Fprintf(out, "P4\n%d %d\n", *n, *n)
-
- for y := 0.0; y < h; y++ {
- for x := 0.0; x < w; x++ {
- Zr, Zi, Tr, Ti := Zero, Zero, Zero, Zero
- Cr := (2*x/w - 1.5)
- Ci := (2*y/h - 1.0)
-
- for i := 0; i < Iter && (Tr+Ti <= Limit*Limit); i++ {
- Zi = 2*Zr*Zi + Ci
- Zr = Tr - Ti + Cr
- Tr = Zr * Zr
- Ti = Zi * Zi
- }
-
- byte_acc <<= 1
- if Tr+Ti <= Limit*Limit {
- byte_acc |= 0x01
- }
-
- bit_num++
-
- if bit_num == 8 {
- out.WriteByte(byte_acc)
- byte_acc = 0
- bit_num = 0
- } else if x == w-1 {
- byte_acc <<= uint(8 - uint(*n)%8)
- out.WriteByte(byte_acc)
- byte_acc = 0
- bit_num = 0
- }
- }
- }
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/mandelbrot.txt b/gcc/testsuite/go.test/test/bench/shootout/mandelbrot.txt
deleted file mode 100644
index 2f7bbbc..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/mandelbrot.txt
+++ /dev/null
Binary files differ
diff --git a/gcc/testsuite/go.test/test/bench/shootout/meteor-contest.c b/gcc/testsuite/go.test/test/bench/shootout/meteor-contest.c
deleted file mode 100644
index 19c4340..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/meteor-contest.c
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by Christian Vosteen
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#define TRUE 1
-#define FALSE 0
-
-/* The board is a 50 cell hexagonal pattern. For . . . . .
- * maximum speed the board will be implemented as . . . . .
- * 50 bits, which will fit into a 64 bit long long . . . . .
- * int. . . . . .
- * . . . . .
- * I will represent 0's as empty cells and 1's . . . . .
- * as full cells. . . . . .
- * . . . . .
- * . . . . .
- * . . . . .
- */
-
-unsigned long long board = 0xFFFC000000000000ULL;
-
-/* The puzzle pieces must be specified by the path followed
- * from one end to the other along 12 hexagonal directions.
- *
- * Piece 0 Piece 1 Piece 2 Piece 3 Piece 4
- *
- * O O O O O O O O O O O O O O O
- * O O O O O O O
- * O O O
- *
- * Piece 5 Piece 6 Piece 7 Piece 8 Piece 9
- *
- * O O O O O O O O O O O O O
- * O O O O O O O O O
- * O O O
- *
- * I had to make it 12 directions because I wanted all of the
- * piece definitions to fit into the same size arrays. It is
- * not possible to define piece 4 in terms of the 6 cardinal
- * directions in 4 moves.
- */
-
-#define E 0
-#define ESE 1
-#define SE 2
-#define S 3
-#define SW 4
-#define WSW 5
-#define W 6
-#define WNW 7
-#define NW 8
-#define N 9
-#define NE 10
-#define ENE 11
-#define PIVOT 12
-
-char piece_def[10][4] = {
- { E, E, E, SE},
- { SE, E, NE, E},
- { E, E, SE, SW},
- { E, E, SW, SE},
- { SE, E, NE, S},
- { E, E, SW, E},
- { E, SE, SE, NE},
- { E, SE, SE, W},
- { E, SE, E, E},
- { E, E, E, SW}
-};
-
-
-/* To minimize the amount of work done in the recursive solve function below,
- * I'm going to allocate enough space for all legal rotations of each piece
- * at each position on the board. That's 10 pieces x 50 board positions x
- * 12 rotations. However, not all 12 rotations will fit on every cell, so
- * I'll have to keep count of the actual number that do.
- * The pieces are going to be unsigned long long ints just like the board so
- * they can be bitwise-anded with the board to determine if they fit.
- * I'm also going to record the next possible open cell for each piece and
- * location to reduce the burden on the solve function.
- */
-unsigned long long pieces[10][50][12];
-int piece_counts[10][50];
-char next_cell[10][50][12];
-
-/* Returns the direction rotated 60 degrees clockwise */
-char rotate(char dir) {
- return (dir + 2) % PIVOT;
-}
-
-/* Returns the direction flipped on the horizontal axis */
-char flip(char dir) {
- return (PIVOT - dir) % PIVOT;
-}
-
-
-/* Returns the new cell index from the specified cell in the
- * specified direction. The index is only valid if the
- * starting cell and direction have been checked by the
- * out_of_bounds function first.
- */
-char shift(char cell, char dir) {
- switch(dir) {
- case E:
- return cell + 1;
- case ESE:
- if((cell / 5) % 2)
- return cell + 7;
- else
- return cell + 6;
- case SE:
- if((cell / 5) % 2)
- return cell + 6;
- else
- return cell + 5;
- case S:
- return cell + 10;
- case SW:
- if((cell / 5) % 2)
- return cell + 5;
- else
- return cell + 4;
- case WSW:
- if((cell / 5) % 2)
- return cell + 4;
- else
- return cell + 3;
- case W:
- return cell - 1;
- case WNW:
- if((cell / 5) % 2)
- return cell - 6;
- else
- return cell - 7;
- case NW:
- if((cell / 5) % 2)
- return cell - 5;
- else
- return cell - 6;
- case N:
- return cell - 10;
- case NE:
- if((cell / 5) % 2)
- return cell - 4;
- else
- return cell - 5;
- case ENE:
- if((cell / 5) % 2)
- return cell - 3;
- else
- return cell - 4;
- default:
- return cell;
- }
-}
-
-/* Returns wether the specified cell and direction will land outside
- * of the board. Used to determine if a piece is at a legal board
- * location or not.
- */
-char out_of_bounds(char cell, char dir) {
- char i;
- switch(dir) {
- case E:
- return cell % 5 == 4;
- case ESE:
- i = cell % 10;
- return i == 4 || i == 8 || i == 9 || cell >= 45;
- case SE:
- return cell % 10 == 9 || cell >= 45;
- case S:
- return cell >= 40;
- case SW:
- return cell % 10 == 0 || cell >= 45;
- case WSW:
- i = cell % 10;
- return i == 0 || i == 1 || i == 5 || cell >= 45;
- case W:
- return cell % 5 == 0;
- case WNW:
- i = cell % 10;
- return i == 0 || i == 1 || i == 5 || cell < 5;
- case NW:
- return cell % 10 == 0 || cell < 5;
- case N:
- return cell < 10;
- case NE:
- return cell % 10 == 9 || cell < 5;
- case ENE:
- i = cell % 10;
- return i == 4 || i == 8 || i == 9 || cell < 5;
- default:
- return FALSE;
- }
-}
-
-/* Rotate a piece 60 degrees clockwise */
-void rotate_piece(int piece) {
- int i;
- for(i = 0; i < 4; i++)
- piece_def[piece][i] = rotate(piece_def[piece][i]);
-}
-
-/* Flip a piece along the horizontal axis */
-void flip_piece(int piece) {
- int i;
- for(i = 0; i < 4; i++)
- piece_def[piece][i] = flip(piece_def[piece][i]);
-}
-
-/* Convenience function to quickly calculate all of the indices for a piece */
-void calc_cell_indices(char *cell, int piece, char index) {
- cell[0] = index;
- cell[1] = shift(cell[0], piece_def[piece][0]);
- cell[2] = shift(cell[1], piece_def[piece][1]);
- cell[3] = shift(cell[2], piece_def[piece][2]);
- cell[4] = shift(cell[3], piece_def[piece][3]);
-}
-
-/* Convenience function to quickly calculate if a piece fits on the board */
-int cells_fit_on_board(char *cell, int piece) {
- return (!out_of_bounds(cell[0], piece_def[piece][0]) &&
- !out_of_bounds(cell[1], piece_def[piece][1]) &&
- !out_of_bounds(cell[2], piece_def[piece][2]) &&
- !out_of_bounds(cell[3], piece_def[piece][3]));
-}
-
-/* Returns the lowest index of the cells of a piece.
- * I use the lowest index that a piece occupies as the index for looking up
- * the piece in the solve function.
- */
-char minimum_of_cells(char *cell) {
- char minimum = cell[0];
- minimum = cell[1] < minimum ? cell[1] : minimum;
- minimum = cell[2] < minimum ? cell[2] : minimum;
- minimum = cell[3] < minimum ? cell[3] : minimum;
- minimum = cell[4] < minimum ? cell[4] : minimum;
- return minimum;
-}
-
-/* Calculate the lowest possible open cell if the piece is placed on the board.
- * Used to later reduce the amount of time searching for open cells in the
- * solve function.
- */
-char first_empty_cell(char *cell, char minimum) {
- char first_empty = minimum;
- while(first_empty == cell[0] || first_empty == cell[1] ||
- first_empty == cell[2] || first_empty == cell[3] ||
- first_empty == cell[4])
- first_empty++;
- return first_empty;
-}
-
-/* Generate the unsigned long long int that will later be anded with the
- * board to determine if it fits.
- */
-unsigned long long bitmask_from_cells(char *cell) {
- unsigned long long piece_mask = 0ULL;
- int i;
- for(i = 0; i < 5; i++)
- piece_mask |= 1ULL << cell[i];
- return piece_mask;
-}
-
-/* Record the piece and other important information in arrays that will
- * later be used by the solve function.
- */
-void record_piece(int piece, int minimum, char first_empty,
- unsigned long long piece_mask) {
- pieces[piece][minimum][piece_counts[piece][minimum]] = piece_mask;
- next_cell[piece][minimum][piece_counts[piece][minimum]] = first_empty;
- piece_counts[piece][minimum]++;
-}
-
-
-/* Fill the entire board going cell by cell. If any cells are "trapped"
- * they will be left alone.
- */
-void fill_contiguous_space(char *board, int index) {
- if(board[index] == 1)
- return;
- board[index] = 1;
- if(!out_of_bounds(index, E))
- fill_contiguous_space(board, shift(index, E));
- if(!out_of_bounds(index, SE))
- fill_contiguous_space(board, shift(index, SE));
- if(!out_of_bounds(index, SW))
- fill_contiguous_space(board, shift(index, SW));
- if(!out_of_bounds(index, W))
- fill_contiguous_space(board, shift(index, W));
- if(!out_of_bounds(index, NW))
- fill_contiguous_space(board, shift(index, NW));
- if(!out_of_bounds(index, NE))
- fill_contiguous_space(board, shift(index, NE));
-}
-
-
-/* To thin the number of pieces, I calculate if any of them trap any empty
- * cells at the edges. There are only a handful of exceptions where the
- * the board can be solved with the trapped cells. For example: piece 8 can
- * trap 5 cells in the corner, but piece 3 can fit in those cells, or piece 0
- * can split the board in half where both halves are viable.
- */
-int has_island(char *cell, int piece) {
- char temp_board[50];
- char c;
- int i;
- for(i = 0; i < 50; i++)
- temp_board[i] = 0;
- for(i = 0; i < 5; i++)
- temp_board[((int)cell[i])] = 1;
- i = 49;
- while(temp_board[i] == 1)
- i--;
- fill_contiguous_space(temp_board, i);
- c = 0;
- for(i = 0; i < 50; i++)
- if(temp_board[i] == 0)
- c++;
- if(c == 0 || (c == 5 && piece == 8) || (c == 40 && piece == 8) ||
- (c % 5 == 0 && piece == 0))
- return FALSE;
- else
- return TRUE;
-}
-
-
-/* Calculate all six rotations of the specified piece at the specified index.
- * We calculate only half of piece 3's rotations. This is because any solution
- * found has an identical solution rotated 180 degrees. Thus we can reduce the
- * number of attempted pieces in the solve algorithm by not including the 180-
- * degree-rotated pieces of ONE of the pieces. I chose piece 3 because it gave
- * me the best time ;)
- */
- void calc_six_rotations(char piece, char index) {
- char rotation, cell[5];
- char minimum, first_empty;
- unsigned long long piece_mask;
-
- for(rotation = 0; rotation < 6; rotation++) {
- if(piece != 3 || rotation < 3) {
- calc_cell_indices(cell, piece, index);
- if(cells_fit_on_board(cell, piece) && !has_island(cell, piece)) {
- minimum = minimum_of_cells(cell);
- first_empty = first_empty_cell(cell, minimum);
- piece_mask = bitmask_from_cells(cell);
- record_piece(piece, minimum, first_empty, piece_mask);
- }
- }
- rotate_piece(piece);
- }
-}
-
-/* Calculate every legal rotation for each piece at each board location. */
-void calc_pieces(void) {
- char piece, index;
-
- for(piece = 0; piece < 10; piece++) {
- for(index = 0; index < 50; index++) {
- calc_six_rotations(piece, index);
- flip_piece(piece);
- calc_six_rotations(piece, index);
- }
- }
-}
-
-
-
-/* Calculate all 32 possible states for a 5-bit row and all rows that will
- * create islands that follow any of the 32 possible rows. These pre-
- * calculated 5-bit rows will be used to find islands in a partially solved
- * board in the solve function.
- */
-#define ROW_MASK 0x1F
-#define TRIPLE_MASK 0x7FFF
-char all_rows[32] = {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, 29, 30, 31};
-int bad_even_rows[32][32];
-int bad_odd_rows[32][32];
-int bad_even_triple[32768];
-int bad_odd_triple[32768];
-
-int rows_bad(char row1, char row2, int even) {
- /* even is referring to row1 */
- int i, in_zeroes, group_okay;
- char block, row2_shift;
- /* Test for blockages at same index and shifted index */
- if(even)
- row2_shift = ((row2 << 1) & ROW_MASK) | 0x01;
- else
- row2_shift = (row2 >> 1) | 0x10;
- block = ((row1 ^ row2) & row2) & ((row1 ^ row2_shift) & row2_shift);
- /* Test for groups of 0's */
- in_zeroes = FALSE;
- group_okay = FALSE;
- for(i = 0; i < 5; i++) {
- if(row1 & (1 << i)) {
- if(in_zeroes) {
- if(!group_okay)
- return TRUE;
- in_zeroes = FALSE;
- group_okay = FALSE;
- }
- } else {
- if(!in_zeroes)
- in_zeroes = TRUE;
- if(!(block & (1 << i)))
- group_okay = TRUE;
- }
- }
- if(in_zeroes)
- return !group_okay;
- else
- return FALSE;
-}
-
-/* Check for cases where three rows checked sequentially cause a false
- * positive. One scenario is when 5 cells may be surrounded where piece 5
- * or 7 can fit. The other scenario is when piece 2 creates a hook shape.
- */
-int triple_is_okay(char row1, char row2, char row3, int even) {
- if(even) {
- /* There are four cases:
- * row1: 00011 00001 11001 10101
- * row2: 01011 00101 10001 10001
- * row3: 011?? 00110 ????? ?????
- */
- return ((row1 == 0x03) && (row2 == 0x0B) && ((row3 & 0x1C) == 0x0C)) ||
- ((row1 == 0x01) && (row2 == 0x05) && (row3 == 0x06)) ||
- ((row1 == 0x19) && (row2 == 0x11)) ||
- ((row1 == 0x15) && (row2 == 0x11));
- } else {
- /* There are two cases:
- * row1: 10011 10101
- * row2: 10001 10001
- * row3: ????? ?????
- */
- return ((row1 == 0x13) && (row2 == 0x11)) ||
- ((row1 == 0x15) && (row2 == 0x11));
- }
-}
-
-
-void calc_rows(void) {
- int row1, row2, row3;
- int result1, result2;
- for(row1 = 0; row1 < 32; row1++) {
- for(row2 = 0; row2 < 32; row2++) {
- bad_even_rows[row1][row2] = rows_bad(row1, row2, TRUE);
- bad_odd_rows[row1][row2] = rows_bad(row1, row2, FALSE);
- }
- }
- for(row1 = 0; row1 < 32; row1++) {
- for(row2 = 0; row2 < 32; row2++) {
- for(row3 = 0; row3 < 32; row3++) {
- result1 = bad_even_rows[row1][row2];
- result2 = bad_odd_rows[row2][row3];
- if(result1 == FALSE && result2 == TRUE
- && triple_is_okay(row1, row2, row3, TRUE))
- bad_even_triple[row1+(row2*32)+(row3*1024)] = FALSE;
- else
- bad_even_triple[row1+(row2*32)+(row3*1024)] = result1 || result2;
-
- result1 = bad_odd_rows[row1][row2];
- result2 = bad_even_rows[row2][row3];
- if(result1 == FALSE && result2 == TRUE
- && triple_is_okay(row1, row2, row3, FALSE))
- bad_odd_triple[row1+(row2*32)+(row3*1024)] = FALSE;
- else
- bad_odd_triple[row1+(row2*32)+(row3*1024)] = result1 || result2;
- }
- }
- }
-}
-
-
-
-/* Calculate islands while solving the board.
- */
-int boardHasIslands(char cell) {
- /* Too low on board, don't bother checking */
- if(cell >= 40)
- return FALSE;
- int current_triple = (board >> ((cell / 5) * 5)) & TRIPLE_MASK;
- if((cell / 5) % 2)
- return bad_odd_triple[current_triple];
- else
- return bad_even_triple[current_triple];
-}
-
-
-/* The recursive solve algorithm. Try to place each permutation in the upper-
- * leftmost empty cell. Mark off available pieces as it goes along.
- * Because the board is a bit mask, the piece number and bit mask must be saved
- * at each successful piece placement. This data is used to create a 50 char
- * array if a solution is found.
- */
-short avail = 0x03FF;
-char sol_nums[10];
-unsigned long long sol_masks[10];
-signed char solutions[2100][50];
-int solution_count = 0;
-int max_solutions = 2100;
-
-void record_solution(void) {
- int sol_no, index;
- unsigned long long sol_mask;
- for(sol_no = 0; sol_no < 10; sol_no++) {
- sol_mask = sol_masks[sol_no];
- for(index = 0; index < 50; index++) {
- if(sol_mask & 1ULL) {
- solutions[solution_count][index] = sol_nums[sol_no];
- /* Board rotated 180 degrees is a solution too! */
- solutions[solution_count+1][49-index] = sol_nums[sol_no];
- }
- sol_mask = sol_mask >> 1;
- }
- }
- solution_count += 2;
-}
-
-void solve(int depth, int cell) {
- int piece, rotation, max_rots;
- unsigned long long *piece_mask;
- short piece_no_mask;
-
- if(solution_count >= max_solutions)
- return;
-
- while(board & (1ULL << cell))
- cell++;
-
- for(piece = 0; piece < 10; piece++) {
- piece_no_mask = 1 << piece;
- if(!(avail & piece_no_mask))
- continue;
- avail ^= piece_no_mask;
- max_rots = piece_counts[piece][cell];
- piece_mask = pieces[piece][cell];
- for(rotation = 0; rotation < max_rots; rotation++) {
- if(!(board & *(piece_mask + rotation))) {
- sol_nums[depth] = piece;
- sol_masks[depth] = *(piece_mask + rotation);
- if(depth == 9) {
- /* Solution found!!!!!11!!ONE! */
- record_solution();
- avail ^= piece_no_mask;
- return;
- }
- board |= *(piece_mask + rotation);
- if(!boardHasIslands(next_cell[piece][cell][rotation]))
- solve(depth + 1, next_cell[piece][cell][rotation]);
- board ^= *(piece_mask + rotation);
- }
- }
- avail ^= piece_no_mask;
- }
-}
-
-
-/* qsort comparator - used to find first and last solutions */
-int solution_sort(const void *elem1, const void *elem2) {
- signed char *char1 = (signed char *) elem1;
- signed char *char2 = (signed char *) elem2;
- int i = 0;
- while(i < 50 && char1[i] == char2[i])
- i++;
- return char1[i] - char2[i];
-}
-
-
-/* pretty print a board in the specified hexagonal format */
-void pretty(signed char *b) {
- int i;
- for(i = 0; i < 50; i += 10) {
- printf("%c %c %c %c %c \n %c %c %c %c %c \n", b[i]+'0', b[i+1]+'0',
- b[i+2]+'0', b[i+3]+'0', b[i+4]+'0', b[i+5]+'0', b[i+6]+'0',
- b[i+7]+'0', b[i+8]+'0', b[i+9]+'0');
- }
- printf("\n");
-}
-
-int main(int argc, char **argv) {
- if(argc > 1)
- max_solutions = atoi(argv[1]);
- calc_pieces();
- calc_rows();
- solve(0, 0);
- printf("%d solutions found\n\n", solution_count);
- qsort(solutions, solution_count, 50 * sizeof(signed char), solution_sort);
- pretty(solutions[0]);
- pretty(solutions[solution_count-1]);
- return 0;
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/meteor-contest.go b/gcc/testsuite/go.test/test/bench/shootout/meteor-contest.go
deleted file mode 100644
index 34a4e23..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/meteor-contest.go
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by The Go Authors.
- * based on meteor-contest.c by Christian Vosteen
- */
-
-package main
-
-import (
- "flag"
- "fmt"
-)
-
-var max_solutions = flag.Int("n", 2100, "maximum number of solutions")
-
-func boolInt(b bool) int8 {
- if b {
- return 1
- }
- return 0
-}
-
-/* The board is a 50 cell hexagonal pattern. For . . . . .
- * maximum speed the board will be implemented as . . . . .
- * 50 bits, which will fit into a 64 bit long long . . . . .
- * int. . . . . .
- * . . . . .
- * I will represent 0's as empty cells and 1's . . . . .
- * as full cells. . . . . .
- * . . . . .
- * . . . . .
- * . . . . .
- */
-
-var board uint64 = 0xFFFC000000000000
-
-/* The puzzle pieces must be specified by the path followed
- * from one end to the other along 12 hexagonal directions.
- *
- * Piece 0 Piece 1 Piece 2 Piece 3 Piece 4
- *
- * O O O O O O O O O O O O O O O
- * O O O O O O O
- * O O O
- *
- * Piece 5 Piece 6 Piece 7 Piece 8 Piece 9
- *
- * O O O O O O O O O O O O O
- * O O O O O O O O O
- * O O O
- *
- * I had to make it 12 directions because I wanted all of the
- * piece definitions to fit into the same size arrays. It is
- * not possible to define piece 4 in terms of the 6 cardinal
- * directions in 4 moves.
- */
-
-const (
- E = iota
- ESE
- SE
- S
- SW
- WSW
- W
- WNW
- NW
- N
- NE
- ENE
- PIVOT
-)
-
-var piece_def = [10][4]int8{
- [4]int8{E, E, E, SE},
- [4]int8{SE, E, NE, E},
- [4]int8{E, E, SE, SW},
- [4]int8{E, E, SW, SE},
- [4]int8{SE, E, NE, S},
- [4]int8{E, E, SW, E},
- [4]int8{E, SE, SE, NE},
- [4]int8{E, SE, SE, W},
- [4]int8{E, SE, E, E},
- [4]int8{E, E, E, SW},
-}
-
-/* To minimize the amount of work done in the recursive solve function below,
- * I'm going to allocate enough space for all legal rotations of each piece
- * at each position on the board. That's 10 pieces x 50 board positions x
- * 12 rotations. However, not all 12 rotations will fit on every cell, so
- * I'll have to keep count of the actual number that do.
- * The pieces are going to be unsigned long long ints just like the board so
- * they can be bitwise-anded with the board to determine if they fit.
- * I'm also going to record the next possible open cell for each piece and
- * location to reduce the burden on the solve function.
- */
-var (
- pieces [10][50][12]uint64
- piece_counts [10][50]int
- next_cell [10][50][12]int8
-)
-
-/* Returns the direction rotated 60 degrees clockwise */
-func rotate(dir int8) int8 { return (dir + 2) % PIVOT }
-
-/* Returns the direction flipped on the horizontal axis */
-func flip(dir int8) int8 { return (PIVOT - dir) % PIVOT }
-
-/* Returns the new cell index from the specified cell in the
- * specified direction. The index is only valid if the
- * starting cell and direction have been checked by the
- * out_of_bounds function first.
- */
-func shift(cell, dir int8) int8 {
- switch dir {
- case E:
- return cell + 1
- case ESE:
- if ((cell / 5) % 2) != 0 {
- return cell + 7
- } else {
- return cell + 6
- }
- case SE:
- if ((cell / 5) % 2) != 0 {
- return cell + 6
- } else {
- return cell + 5
- }
- case S:
- return cell + 10
- case SW:
- if ((cell / 5) % 2) != 0 {
- return cell + 5
- } else {
- return cell + 4
- }
- case WSW:
- if ((cell / 5) % 2) != 0 {
- return cell + 4
- } else {
- return cell + 3
- }
- case W:
- return cell - 1
- case WNW:
- if ((cell / 5) % 2) != 0 {
- return cell - 6
- } else {
- return cell - 7
- }
- case NW:
- if ((cell / 5) % 2) != 0 {
- return cell - 5
- } else {
- return cell - 6
- }
- case N:
- return cell - 10
- case NE:
- if ((cell / 5) % 2) != 0 {
- return cell - 4
- } else {
- return cell - 5
- }
- case ENE:
- if ((cell / 5) % 2) != 0 {
- return cell - 3
- } else {
- return cell - 4
- }
- }
- return cell
-}
-
-/* Returns wether the specified cell and direction will land outside
- * of the board. Used to determine if a piece is at a legal board
- * location or not.
- */
-func out_of_bounds(cell, dir int8) bool {
- switch dir {
- case E:
- return cell%5 == 4
- case ESE:
- i := cell % 10
- return i == 4 || i == 8 || i == 9 || cell >= 45
- case SE:
- return cell%10 == 9 || cell >= 45
- case S:
- return cell >= 40
- case SW:
- return cell%10 == 0 || cell >= 45
- case WSW:
- i := cell % 10
- return i == 0 || i == 1 || i == 5 || cell >= 45
- case W:
- return cell%5 == 0
- case WNW:
- i := cell % 10
- return i == 0 || i == 1 || i == 5 || cell < 5
- case NW:
- return cell%10 == 0 || cell < 5
- case N:
- return cell < 10
- case NE:
- return cell%10 == 9 || cell < 5
- case ENE:
- i := cell % 10
- return i == 4 || i == 8 || i == 9 || cell < 5
- }
- return false
-}
-
-/* Rotate a piece 60 degrees clockwise */
-func rotate_piece(piece int) {
- for i := 0; i < 4; i++ {
- piece_def[piece][i] = rotate(piece_def[piece][i])
- }
-}
-
-/* Flip a piece along the horizontal axis */
-func flip_piece(piece int) {
- for i := 0; i < 4; i++ {
- piece_def[piece][i] = flip(piece_def[piece][i])
- }
-}
-
-/* Convenience function to quickly calculate all of the indices for a piece */
-func calc_cell_indices(cell []int8, piece int, index int8) {
- cell[0] = index
- for i := 1; i < 5; i++ {
- cell[i] = shift(cell[i-1], piece_def[piece][i-1])
- }
-}
-
-/* Convenience function to quickly calculate if a piece fits on the board */
-func cells_fit_on_board(cell []int8, piece int) bool {
- return !out_of_bounds(cell[0], piece_def[piece][0]) &&
- !out_of_bounds(cell[1], piece_def[piece][1]) &&
- !out_of_bounds(cell[2], piece_def[piece][2]) &&
- !out_of_bounds(cell[3], piece_def[piece][3])
-}
-
-/* Returns the lowest index of the cells of a piece.
- * I use the lowest index that a piece occupies as the index for looking up
- * the piece in the solve function.
- */
-func minimum_of_cells(cell []int8) int8 {
- minimum := cell[0]
- for i := 1; i < 5; i++ {
- if cell[i] < minimum {
- minimum = cell[i]
- }
- }
- return minimum
-}
-
-/* Calculate the lowest possible open cell if the piece is placed on the board.
- * Used to later reduce the amount of time searching for open cells in the
- * solve function.
- */
-func first_empty_cell(cell []int8, minimum int8) int8 {
- first_empty := minimum
- for first_empty == cell[0] || first_empty == cell[1] ||
- first_empty == cell[2] || first_empty == cell[3] ||
- first_empty == cell[4] {
- first_empty++
- }
- return first_empty
-}
-
-/* Generate the unsigned long long int that will later be anded with the
- * board to determine if it fits.
- */
-func bitmask_from_cells(cell []int8) uint64 {
- var piece_mask uint64
- for i := 0; i < 5; i++ {
- piece_mask |= 1 << uint(cell[i])
- }
- return piece_mask
-}
-
-/* Record the piece and other important information in arrays that will
- * later be used by the solve function.
- */
-func record_piece(piece int, minimum int8, first_empty int8, piece_mask uint64) {
- pieces[piece][minimum][piece_counts[piece][minimum]] = piece_mask
- next_cell[piece][minimum][piece_counts[piece][minimum]] = first_empty
- piece_counts[piece][minimum]++
-}
-
-/* Fill the entire board going cell by cell. If any cells are "trapped"
- * they will be left alone.
- */
-func fill_contiguous_space(board []int8, index int8) {
- if board[index] == 1 {
- return
- }
- board[index] = 1
- if !out_of_bounds(index, E) {
- fill_contiguous_space(board, shift(index, E))
- }
- if !out_of_bounds(index, SE) {
- fill_contiguous_space(board, shift(index, SE))
- }
- if !out_of_bounds(index, SW) {
- fill_contiguous_space(board, shift(index, SW))
- }
- if !out_of_bounds(index, W) {
- fill_contiguous_space(board, shift(index, W))
- }
- if !out_of_bounds(index, NW) {
- fill_contiguous_space(board, shift(index, NW))
- }
- if !out_of_bounds(index, NE) {
- fill_contiguous_space(board, shift(index, NE))
- }
-}
-
-/* To thin the number of pieces, I calculate if any of them trap any empty
- * cells at the edges. There are only a handful of exceptions where the
- * the board can be solved with the trapped cells. For example: piece 8 can
- * trap 5 cells in the corner, but piece 3 can fit in those cells, or piece 0
- * can split the board in half where both halves are viable.
- */
-func has_island(cell []int8, piece int) bool {
- temp_board := make([]int8, 50)
- var i int
- for i = 0; i < 5; i++ {
- temp_board[cell[i]] = 1
- }
- i = 49
- for temp_board[i] == 1 {
- i--
- }
- fill_contiguous_space(temp_board, int8(i))
- c := 0
- for i = 0; i < 50; i++ {
- if temp_board[i] == 0 {
- c++
- }
- }
- if c == 0 || (c == 5 && piece == 8) || (c == 40 && piece == 8) ||
- (c%5 == 0 && piece == 0) {
- return false
- }
- return true
-}
-
-/* Calculate all six rotations of the specified piece at the specified index.
- * We calculate only half of piece 3's rotations. This is because any solution
- * found has an identical solution rotated 180 degrees. Thus we can reduce the
- * number of attempted pieces in the solve algorithm by not including the 180-
- * degree-rotated pieces of ONE of the pieces. I chose piece 3 because it gave
- * me the best time ;)
- */
-func calc_six_rotations(piece, index int) {
- cell := make([]int8, 5)
- for rotation := 0; rotation < 6; rotation++ {
- if piece != 3 || rotation < 3 {
- calc_cell_indices(cell, piece, int8(index))
- if cells_fit_on_board(cell, piece) && !has_island(cell, piece) {
- minimum := minimum_of_cells(cell)
- first_empty := first_empty_cell(cell, minimum)
- piece_mask := bitmask_from_cells(cell)
- record_piece(piece, minimum, first_empty, piece_mask)
- }
- }
- rotate_piece(piece)
- }
-}
-
-/* Calculate every legal rotation for each piece at each board location. */
-func calc_pieces() {
- for piece := 0; piece < 10; piece++ {
- for index := 0; index < 50; index++ {
- calc_six_rotations(piece, index)
- flip_piece(piece)
- calc_six_rotations(piece, index)
- }
- }
-}
-
-/* Calculate all 32 possible states for a 5-bit row and all rows that will
- * create islands that follow any of the 32 possible rows. These pre-
- * calculated 5-bit rows will be used to find islands in a partially solved
- * board in the solve function.
- */
-const (
- ROW_MASK = 0x1F
- TRIPLE_MASK = 0x7FFF
-)
-
-var (
- all_rows = [32]int8{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, 29, 30, 31,
- }
- bad_even_rows [32][32]int8
- bad_odd_rows [32][32]int8
- bad_even_triple [32768]int8
- bad_odd_triple [32768]int8
-)
-
-func rows_bad(row1, row2 int8, even bool) int8 {
- /* even is referring to row1 */
- var row2_shift int8
- /* Test for blockages at same index and shifted index */
- if even {
- row2_shift = ((row2 << 1) & ROW_MASK) | 0x01
- } else {
- row2_shift = (row2 >> 1) | 0x10
- }
- block := ((row1 ^ row2) & row2) & ((row1 ^ row2_shift) & row2_shift)
- /* Test for groups of 0's */
- in_zeroes := false
- group_okay := false
- for i := uint8(0); i < 5; i++ {
- if row1&(1<<i) != 0 {
- if in_zeroes {
- if !group_okay {
- return 1
- }
- in_zeroes = false
- group_okay = false
- }
- } else {
- if !in_zeroes {
- in_zeroes = true
- }
- if (block & (1 << i)) == 0 {
- group_okay = true
- }
- }
- }
- if in_zeroes {
- return boolInt(!group_okay)
- }
- return 0
-}
-
-/* Check for cases where three rows checked sequentially cause a false
- * positive. One scenario is when 5 cells may be surrounded where piece 5
- * or 7 can fit. The other scenario is when piece 2 creates a hook shape.
- */
-func triple_is_okay(row1, row2, row3 int, even bool) bool {
- if even {
- /* There are four cases:
- * row1: 00011 00001 11001 10101
- * row2: 01011 00101 10001 10001
- * row3: 011?? 00110 ????? ?????
- */
- return ((row1 == 0x03) && (row2 == 0x0B) && ((row3 & 0x1C) == 0x0C)) ||
- ((row1 == 0x01) && (row2 == 0x05) && (row3 == 0x06)) ||
- ((row1 == 0x19) && (row2 == 0x11)) ||
- ((row1 == 0x15) && (row2 == 0x11))
- }
- /* There are two cases:
- * row1: 10011 10101
- * row2: 10001 10001
- * row3: ????? ?????
- */
- return ((row1 == 0x13) && (row2 == 0x11)) ||
- ((row1 == 0x15) && (row2 == 0x11))
-}
-
-func calc_rows() {
- for row1 := int8(0); row1 < 32; row1++ {
- for row2 := int8(0); row2 < 32; row2++ {
- bad_even_rows[row1][row2] = rows_bad(row1, row2, true)
- bad_odd_rows[row1][row2] = rows_bad(row1, row2, false)
- }
- }
- for row1 := 0; row1 < 32; row1++ {
- for row2 := 0; row2 < 32; row2++ {
- for row3 := 0; row3 < 32; row3++ {
- result1 := bad_even_rows[row1][row2]
- result2 := bad_odd_rows[row2][row3]
- if result1 == 0 && result2 != 0 && triple_is_okay(row1, row2, row3, true) {
- bad_even_triple[row1+(row2*32)+(row3*1024)] = 0
- } else {
- bad_even_triple[row1+(row2*32)+(row3*1024)] = boolInt(result1 != 0 || result2 != 0)
- }
-
- result1 = bad_odd_rows[row1][row2]
- result2 = bad_even_rows[row2][row3]
- if result1 == 0 && result2 != 0 && triple_is_okay(row1, row2, row3, false) {
- bad_odd_triple[row1+(row2*32)+(row3*1024)] = 0
- } else {
- bad_odd_triple[row1+(row2*32)+(row3*1024)] = boolInt(result1 != 0 || result2 != 0)
- }
- }
- }
- }
-}
-
-/* Calculate islands while solving the board.
- */
-func boardHasIslands(cell int8) int8 {
- /* Too low on board, don't bother checking */
- if cell >= 40 {
- return 0
- }
- current_triple := (board >> uint((cell/5)*5)) & TRIPLE_MASK
- if (cell/5)%2 != 0 {
- return bad_odd_triple[current_triple]
- }
- return bad_even_triple[current_triple]
-}
-
-/* The recursive solve algorithm. Try to place each permutation in the upper-
- * leftmost empty cell. Mark off available pieces as it goes along.
- * Because the board is a bit mask, the piece number and bit mask must be saved
- * at each successful piece placement. This data is used to create a 50 char
- * array if a solution is found.
- */
-var (
- avail uint16 = 0x03FF
- sol_nums [10]int8
- sol_masks [10]uint64
- solutions [2100][50]int8
- solution_count = 0
-)
-
-func record_solution() {
- for sol_no := 0; sol_no < 10; sol_no++ {
- sol_mask := sol_masks[sol_no]
- for index := 0; index < 50; index++ {
- if sol_mask&1 == 1 {
- solutions[solution_count][index] = sol_nums[sol_no]
- /* Board rotated 180 degrees is a solution too! */
- solutions[solution_count+1][49-index] = sol_nums[sol_no]
- }
- sol_mask = sol_mask >> 1
- }
- }
- solution_count += 2
-}
-
-func solve(depth, cell int8) {
- if solution_count >= *max_solutions {
- return
- }
-
- for board&(1<<uint(cell)) != 0 {
- cell++
- }
-
- for piece := int8(0); piece < 10; piece++ {
- var piece_no_mask uint16 = 1 << uint(piece)
- if avail&piece_no_mask == 0 {
- continue
- }
- avail ^= piece_no_mask
- max_rots := piece_counts[piece][cell]
- piece_mask := pieces[piece][cell]
- for rotation := 0; rotation < max_rots; rotation++ {
- if board&piece_mask[rotation] == 0 {
- sol_nums[depth] = piece
- sol_masks[depth] = piece_mask[rotation]
- if depth == 9 {
- /* Solution found!!!!!11!!ONE! */
- record_solution()
- avail ^= piece_no_mask
- return
- }
- board |= piece_mask[rotation]
- if boardHasIslands(next_cell[piece][cell][rotation]) == 0 {
- solve(depth+1, next_cell[piece][cell][rotation])
- }
- board ^= piece_mask[rotation]
- }
- }
- avail ^= piece_no_mask
- }
-}
-
-/* pretty print a board in the specified hexagonal format */
-func pretty(b *[50]int8) {
- for i := 0; i < 50; i += 10 {
- fmt.Printf("%c %c %c %c %c \n %c %c %c %c %c \n", b[i]+'0', b[i+1]+'0',
- b[i+2]+'0', b[i+3]+'0', b[i+4]+'0', b[i+5]+'0', b[i+6]+'0',
- b[i+7]+'0', b[i+8]+'0', b[i+9]+'0')
- }
- fmt.Printf("\n")
-}
-
-/* Find smallest and largest solutions */
-func smallest_largest() (smallest, largest *[50]int8) {
- smallest = &solutions[0]
- largest = &solutions[0]
- for i := 1; i < solution_count; i++ {
- candidate := &solutions[i]
- for j, s := range *smallest {
- c := candidate[j]
- if c == s {
- continue
- }
- if c < s {
- smallest = candidate
- }
- break
- }
- for j, s := range *largest {
- c := candidate[j]
- if c == s {
- continue
- }
- if c > s {
- largest = candidate
- }
- break
- }
- }
- return
-}
-
-func main() {
- flag.Parse()
- calc_pieces()
- calc_rows()
- solve(0, 0)
- fmt.Printf("%d solutions found\n\n", solution_count)
- smallest, largest := smallest_largest()
- pretty(smallest)
- pretty(largest)
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/meteor-contest.txt b/gcc/testsuite/go.test/test/bench/shootout/meteor-contest.txt
deleted file mode 100644
index 38d9783..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/meteor-contest.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-2098 solutions found
-
-0 0 0 0 1
- 2 2 2 0 1
-2 6 6 1 1
- 2 6 1 5 5
-8 6 5 5 5
- 8 6 3 3 3
-4 8 8 9 3
- 4 4 8 9 3
-4 7 4 7 9
- 7 7 7 9 9
-
-9 9 9 9 8
- 9 6 6 8 5
-6 6 8 8 5
- 6 8 2 5 5
-7 7 7 2 5
- 7 4 7 2 0
-1 4 2 2 0
- 1 4 4 0 3
-1 4 0 0 3
- 1 1 3 3 3
-
diff --git a/gcc/testsuite/go.test/test/bench/shootout/nbody.c b/gcc/testsuite/go.test/test/bench/shootout/nbody.c
deleted file mode 100644
index 3b95b05..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/nbody.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*
- * The Great Computer Language Shootout
- * http://shootout.alioth.debian.org/
- *
- * contributed by Christoph Bauer
- *
- */
-
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#define pi 3.141592653589793
-#define solar_mass (4 * pi * pi)
-#define days_per_year 365.24
-
-struct planet {
- double x, y, z;
- double vx, vy, vz;
- double mass;
-};
-
-void advance(int nbodies, struct planet * bodies, double dt)
-{
- int i, j;
-
- for (i = 0; i < nbodies; i++) {
- struct planet * b = &(bodies[i]);
- for (j = i + 1; j < nbodies; j++) {
- struct planet * b2 = &(bodies[j]);
- double dx = b->x - b2->x;
- double dy = b->y - b2->y;
- double dz = b->z - b2->z;
- double distance = sqrt(dx * dx + dy * dy + dz * dz);
- double mag = dt / (distance * distance * distance);
- b->vx -= dx * b2->mass * mag;
- b->vy -= dy * b2->mass * mag;
- b->vz -= dz * b2->mass * mag;
- b2->vx += dx * b->mass * mag;
- b2->vy += dy * b->mass * mag;
- b2->vz += dz * b->mass * mag;
- }
- }
- for (i = 0; i < nbodies; i++) {
- struct planet * b = &(bodies[i]);
- b->x += dt * b->vx;
- b->y += dt * b->vy;
- b->z += dt * b->vz;
- }
-}
-
-double energy(int nbodies, struct planet * bodies)
-{
- double e;
- int i, j;
-
- e = 0.0;
- for (i = 0; i < nbodies; i++) {
- struct planet * b = &(bodies[i]);
- e += 0.5 * b->mass * (b->vx * b->vx + b->vy * b->vy + b->vz * b->vz);
- for (j = i + 1; j < nbodies; j++) {
- struct planet * b2 = &(bodies[j]);
- double dx = b->x - b2->x;
- double dy = b->y - b2->y;
- double dz = b->z - b2->z;
- double distance = sqrt(dx * dx + dy * dy + dz * dz);
- e -= (b->mass * b2->mass) / distance;
- }
- }
- return e;
-}
-
-void offset_momentum(int nbodies, struct planet * bodies)
-{
- double px = 0.0, py = 0.0, pz = 0.0;
- int i;
- for (i = 0; i < nbodies; i++) {
- px += bodies[i].vx * bodies[i].mass;
- py += bodies[i].vy * bodies[i].mass;
- pz += bodies[i].vz * bodies[i].mass;
- }
- bodies[0].vx = - px / solar_mass;
- bodies[0].vy = - py / solar_mass;
- bodies[0].vz = - pz / solar_mass;
-}
-
-#define NBODIES 5
-struct planet bodies[NBODIES] = {
- { /* sun */
- 0, 0, 0, 0, 0, 0, solar_mass
- },
- { /* jupiter */
- 4.84143144246472090e+00,
- -1.16032004402742839e+00,
- -1.03622044471123109e-01,
- 1.66007664274403694e-03 * days_per_year,
- 7.69901118419740425e-03 * days_per_year,
- -6.90460016972063023e-05 * days_per_year,
- 9.54791938424326609e-04 * solar_mass
- },
- { /* saturn */
- 8.34336671824457987e+00,
- 4.12479856412430479e+00,
- -4.03523417114321381e-01,
- -2.76742510726862411e-03 * days_per_year,
- 4.99852801234917238e-03 * days_per_year,
- 2.30417297573763929e-05 * days_per_year,
- 2.85885980666130812e-04 * solar_mass
- },
- { /* uranus */
- 1.28943695621391310e+01,
- -1.51111514016986312e+01,
- -2.23307578892655734e-01,
- 2.96460137564761618e-03 * days_per_year,
- 2.37847173959480950e-03 * days_per_year,
- -2.96589568540237556e-05 * days_per_year,
- 4.36624404335156298e-05 * solar_mass
- },
- { /* neptune */
- 1.53796971148509165e+01,
- -2.59193146099879641e+01,
- 1.79258772950371181e-01,
- 2.68067772490389322e-03 * days_per_year,
- 1.62824170038242295e-03 * days_per_year,
- -9.51592254519715870e-05 * days_per_year,
- 5.15138902046611451e-05 * solar_mass
- }
-};
-
-int main(int argc, char ** argv)
-{
- int n = atoi(argv[1]);
- int i;
-
- offset_momentum(NBODIES, bodies);
- printf ("%.9f\n", energy(NBODIES, bodies));
- for (i = 1; i <= n; i++)
- advance(NBODIES, bodies, 0.01);
- printf ("%.9f\n", energy(NBODIES, bodies));
- return 0;
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/nbody.go b/gcc/testsuite/go.test/test/bench/shootout/nbody.go
deleted file mode 100644
index 988f3ba..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/nbody.go
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by The Go Authors.
- * based on C program by Christoph Bauer
- */
-
-package main
-
-import (
- "flag"
- "fmt"
- "math"
-)
-
-var n = flag.Int("n", 1000, "number of iterations")
-
-type Body struct {
- x, y, z, vx, vy, vz, mass float64
-}
-
-const (
- solarMass = 4 * math.Pi * math.Pi
- daysPerYear = 365.24
-)
-
-func (b *Body) offsetMomentum(px, py, pz float64) {
- b.vx = -px / solarMass
- b.vy = -py / solarMass
- b.vz = -pz / solarMass
-}
-
-type System []*Body
-
-func NewSystem(body []Body) System {
- n := make(System, len(body))
- for i := 0; i < len(body); i++ {
- n[i] = new(Body) // copy to avoid overwriting the inputs
- *n[i] = body[i]
- }
- var px, py, pz float64
- for _, body := range n {
- px += body.vx * body.mass
- py += body.vy * body.mass
- pz += body.vz * body.mass
- }
- n[0].offsetMomentum(px, py, pz)
- return n
-}
-
-func (sys System) energy() float64 {
- var e float64
- for i, body := range sys {
- e += 0.5 * body.mass *
- (body.vx*body.vx + body.vy*body.vy + body.vz*body.vz)
- for j := i + 1; j < len(sys); j++ {
- body2 := sys[j]
- dx := body.x - body2.x
- dy := body.y - body2.y
- dz := body.z - body2.z
- distance := math.Sqrt(dx*dx + dy*dy + dz*dz)
- e -= (body.mass * body2.mass) / distance
- }
- }
- return e
-}
-
-func (sys System) advance(dt float64) {
- for i, body := range sys {
- for j := i + 1; j < len(sys); j++ {
- body2 := sys[j]
- dx := body.x - body2.x
- dy := body.y - body2.y
- dz := body.z - body2.z
-
- dSquared := dx*dx + dy*dy + dz*dz
- distance := math.Sqrt(dSquared)
- mag := dt / (dSquared * distance)
-
- body.vx -= dx * body2.mass * mag
- body.vy -= dy * body2.mass * mag
- body.vz -= dz * body2.mass * mag
-
- body2.vx += dx * body.mass * mag
- body2.vy += dy * body.mass * mag
- body2.vz += dz * body.mass * mag
- }
- }
-
- for _, body := range sys {
- body.x += dt * body.vx
- body.y += dt * body.vy
- body.z += dt * body.vz
- }
-}
-
-var (
- jupiter = Body{
- x: 4.84143144246472090e+00,
- y: -1.16032004402742839e+00,
- z: -1.03622044471123109e-01,
- vx: 1.66007664274403694e-03 * daysPerYear,
- vy: 7.69901118419740425e-03 * daysPerYear,
- vz: -6.90460016972063023e-05 * daysPerYear,
- mass: 9.54791938424326609e-04 * solarMass,
- }
- saturn = Body{
- x: 8.34336671824457987e+00,
- y: 4.12479856412430479e+00,
- z: -4.03523417114321381e-01,
- vx: -2.76742510726862411e-03 * daysPerYear,
- vy: 4.99852801234917238e-03 * daysPerYear,
- vz: 2.30417297573763929e-05 * daysPerYear,
- mass: 2.85885980666130812e-04 * solarMass,
- }
- uranus = Body{
- x: 1.28943695621391310e+01,
- y: -1.51111514016986312e+01,
- z: -2.23307578892655734e-01,
- vx: 2.96460137564761618e-03 * daysPerYear,
- vy: 2.37847173959480950e-03 * daysPerYear,
- vz: -2.96589568540237556e-05 * daysPerYear,
- mass: 4.36624404335156298e-05 * solarMass,
- }
- neptune = Body{
- x: 1.53796971148509165e+01,
- y: -2.59193146099879641e+01,
- z: 1.79258772950371181e-01,
- vx: 2.68067772490389322e-03 * daysPerYear,
- vy: 1.62824170038242295e-03 * daysPerYear,
- vz: -9.51592254519715870e-05 * daysPerYear,
- mass: 5.15138902046611451e-05 * solarMass,
- }
- sun = Body{
- mass: solarMass,
- }
-)
-
-func main() {
- flag.Parse()
-
- system := NewSystem([]Body{sun, jupiter, saturn, uranus, neptune})
- fmt.Printf("%.9f\n", system.energy())
- for i := 0; i < *n; i++ {
- system.advance(0.01)
- }
- fmt.Printf("%.9f\n", system.energy())
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/nbody.txt b/gcc/testsuite/go.test/test/bench/shootout/nbody.txt
deleted file mode 100644
index 1731557..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/nbody.txt
+++ /dev/null
@@ -1,2 +0,0 @@
--0.169075164
--0.169087605
diff --git a/gcc/testsuite/go.test/test/bench/shootout/pidigits.c b/gcc/testsuite/go.test/test/bench/shootout/pidigits.c
deleted file mode 100644
index c064da0..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/pidigits.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- http://shootout.alioth.debian.org/
-
- contributed by Paolo Bonzini & Sean Bartlett
- modified by Michael Mellor
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <gmp.h>
-
-static mpz_t numer, accum, denom, tmp1, tmp2;
-
-static int extract_digit()
-{
- if (mpz_cmp(numer, accum) > 0)
- return -1;
-
- /* Compute (numer * 3 + accum) / denom */
- mpz_mul_2exp(tmp1, numer, 1);
- mpz_add(tmp1, tmp1, numer);
- mpz_add(tmp1, tmp1, accum);
- mpz_fdiv_qr(tmp1, tmp2, tmp1, denom);
-
- /* Now, if (numer * 4 + accum) % denom... */
- mpz_add(tmp2, tmp2, numer);
-
- /* ... is normalized, then the two divisions have the same result. */
- if (mpz_cmp(tmp2, denom) >= 0)
- return -1;
-
- return mpz_get_ui(tmp1);
-}
-
-static void next_term(unsigned int k)
-{
- unsigned int y2 = k*2 + 1;
-
- mpz_mul_2exp(tmp1, numer, 1);
- mpz_add(accum, accum, tmp1);
- mpz_mul_ui(accum, accum, y2);
- mpz_mul_ui(numer, numer, k);
- mpz_mul_ui(denom, denom, y2);
-}
-
-static void eliminate_digit(unsigned int d)
-{
- mpz_submul_ui(accum, denom, d);
- mpz_mul_ui(accum, accum, 10);
- mpz_mul_ui(numer, numer, 10);
-}
-
-static void pidigits(unsigned int n)
-{
- int d;
- unsigned int i = 0, k = 0, m;
- mpz_init(tmp1);
- mpz_init(tmp2);
- mpz_init_set_ui(numer, 1);
- mpz_init_set_ui(accum, 0);
- mpz_init_set_ui(denom, 1);
-
- for(;;)
- {
- do {
- k++;
- next_term(k);
- d = extract_digit();
- } while(d == -1);
-
- putchar(d + '0');
-
- i++;
- m = i%10;
- if(m == 0)
- printf("\t:%d\n", i);
- if(i >= n)
- break;
- eliminate_digit(d);
- }
-
- if(m) {
- m = 10 - m;
- while(m--)
- putchar(' ');
- printf("\t:%d\n", n);
- }
-}
-
-int main(int argc, char **argv)
-{
- pidigits(argc > 1 ? atoi(argv[1]) : 27);
- return 0;
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/pidigits.go b/gcc/testsuite/go.test/test/bench/shootout/pidigits.go
deleted file mode 100644
index a0f21a9..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/pidigits.go
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by The Go Authors.
- * based on pidigits.c (by Paolo Bonzini & Sean Bartlett,
- * modified by Michael Mellor)
- */
-
-package main
-
-import (
- "flag"
- "fmt"
- "math/big"
-)
-
-var n = flag.Int("n", 27, "number of digits")
-var silent = flag.Bool("s", false, "don't print result")
-
-var (
- tmp1 = big.NewInt(0)
- tmp2 = big.NewInt(0)
- tmp3 = big.NewInt(0)
- y2 = big.NewInt(0)
- bigk = big.NewInt(0)
- numer = big.NewInt(1)
- accum = big.NewInt(0)
- denom = big.NewInt(1)
- ten = big.NewInt(10)
-)
-
-func extract_digit() int64 {
- if numer.Cmp(accum) > 0 {
- return -1
- }
-
- // Compute (numer * 3 + accum) / denom
- tmp1.Lsh(numer, 1)
- tmp1.Add(tmp1, numer)
- tmp1.Add(tmp1, accum)
- tmp1.DivMod(tmp1, denom, tmp2)
-
- // Now, if (numer * 4 + accum) % denom...
- tmp2.Add(tmp2, numer)
-
- // ... is normalized, then the two divisions have the same result.
- if tmp2.Cmp(denom) >= 0 {
- return -1
- }
-
- return tmp1.Int64()
-}
-
-func next_term(k int64) {
- y2.SetInt64(k*2 + 1)
- bigk.SetInt64(k)
-
- tmp1.Lsh(numer, 1)
- accum.Add(accum, tmp1)
- accum.Mul(accum, y2)
- numer.Mul(numer, bigk)
- denom.Mul(denom, y2)
-}
-
-func eliminate_digit(d int64) {
- tmp3.SetInt64(d)
- accum.Sub(accum, tmp3.Mul(denom, tmp3))
- accum.Mul(accum, ten)
- numer.Mul(numer, ten)
-}
-
-func printf(s string, arg ...interface{}) {
- if !*silent {
- fmt.Printf(s, arg...)
- }
-}
-
-func main() {
- flag.Parse()
-
- var m int // 0 <= m < 10
- for i, k := 0, int64(0); ; {
- d := int64(-1)
- for d < 0 {
- k++
- next_term(k)
- d = extract_digit()
- }
-
- printf("%c", d+'0')
-
- i++
- m = i % 10
- if m == 0 {
- printf("\t:%d\n", i)
- }
- if i >= *n {
- break
- }
- eliminate_digit(d)
- }
-
- if m > 0 {
- printf("%s\t:%d\n", " "[m:10], *n)
- }
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/pidigits.txt b/gcc/testsuite/go.test/test/bench/shootout/pidigits.txt
deleted file mode 100644
index ad946a9..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/pidigits.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-3141592653 :10
-5897932384 :20
-6264338 :27
diff --git a/gcc/testsuite/go.test/test/bench/shootout/regex-dna-parallel.go b/gcc/testsuite/go.test/test/bench/shootout/regex-dna-parallel.go
deleted file mode 100644
index 9c6d421..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/regex-dna-parallel.go
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by The Go Authors.
- */
-
-package main
-
-import (
- "fmt"
- "io/ioutil"
- "os"
- "regexp"
- "runtime"
-)
-
-var variants = []string{
- "agggtaaa|tttaccct",
- "[cgt]gggtaaa|tttaccc[acg]",
- "a[act]ggtaaa|tttacc[agt]t",
- "ag[act]gtaaa|tttac[agt]ct",
- "agg[act]taaa|ttta[agt]cct",
- "aggg[acg]aaa|ttt[cgt]ccct",
- "agggt[cgt]aa|tt[acg]accct",
- "agggta[cgt]a|t[acg]taccct",
- "agggtaa[cgt]|[acg]ttaccct",
-}
-
-type Subst struct {
- pat, repl string
-}
-
-var substs = []Subst{
- Subst{"B", "(c|g|t)"},
- Subst{"D", "(a|g|t)"},
- Subst{"H", "(a|c|t)"},
- Subst{"K", "(g|t)"},
- Subst{"M", "(a|c)"},
- Subst{"N", "(a|c|g|t)"},
- Subst{"R", "(a|g)"},
- Subst{"S", "(c|g)"},
- Subst{"V", "(a|c|g)"},
- Subst{"W", "(a|t)"},
- Subst{"Y", "(c|t)"},
-}
-
-func countMatches(pat string, bytes []byte) int {
- re := regexp.MustCompile(pat)
- n := 0
- for {
- e := re.FindIndex(bytes)
- if e == nil {
- break
- }
- n++
- bytes = bytes[e[1]:]
- }
- return n
-}
-
-func main() {
- runtime.GOMAXPROCS(4)
- bytes, err := ioutil.ReadAll(os.Stdin)
- if err != nil {
- fmt.Fprintf(os.Stderr, "can't read input: %s\n", err)
- os.Exit(2)
- }
- ilen := len(bytes)
- // Delete the comment lines and newlines
- bytes = regexp.MustCompile("(>[^\n]+)?\n").ReplaceAll(bytes, []byte{})
- clen := len(bytes)
-
- mresults := make([]chan int, len(variants))
- for i, s := range variants {
- ch := make(chan int)
- mresults[i] = ch
- go func(ss string) {
- ch <- countMatches(ss, bytes)
- }(s)
- }
-
- lenresult := make(chan int)
- bb := bytes
- go func() {
- for _, sub := range substs {
- bb = regexp.MustCompile(sub.pat).ReplaceAll(bb, []byte(sub.repl))
- }
- lenresult <- len(bb)
- }()
-
- for i, s := range variants {
- fmt.Printf("%s %d\n", s, <-mresults[i])
- }
- fmt.Printf("\n%d\n%d\n%d\n", ilen, clen, <-lenresult)
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/regex-dna-parallel.txt b/gcc/testsuite/go.test/test/bench/shootout/regex-dna-parallel.txt
deleted file mode 100644
index e23e71f..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/regex-dna-parallel.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-agggtaaa|tttaccct 1
-[cgt]gggtaaa|tttaccc[acg] 0
-a[act]ggtaaa|tttacc[agt]t 0
-ag[act]gtaaa|tttac[agt]ct 0
-agg[act]taaa|ttta[agt]cct 1
-aggg[acg]aaa|ttt[cgt]ccct 0
-agggt[cgt]aa|tt[acg]accct 0
-agggta[cgt]a|t[acg]taccct 0
-agggtaa[cgt]|[acg]ttaccct 2
-
-10245
-10000
-13348
diff --git a/gcc/testsuite/go.test/test/bench/shootout/regex-dna.c b/gcc/testsuite/go.test/test/bench/shootout/regex-dna.c
deleted file mode 100644
index 134f821..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/regex-dna.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*
-** The Computer Language Shootout
-** http://shootout.alioth.debian.org/
-** contributed by Mike Pall
-**
-** regex-dna benchmark using PCRE
-**
-** compile with:
-** gcc -O3 -fomit-frame-pointer -o regexdna regexdna.c -lpcre
-*/
-
-#define __USE_STRING_INLINES
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <pcre.h>
-
-typedef struct fbuf {
- char *buf;
- size_t size, len;
-} fbuf_t;
-
-static void fb_init(fbuf_t *b)
-{
- b->buf = NULL;
- b->len = b->size = 0;
-}
-
-static char *fb_need(fbuf_t *b, size_t need)
-{
- need += b->len;
- if (need > b->size) {
- if (b->size == 0) b->size = need;
- else while (need > b->size) b->size += b->size;
- if (!(b->buf = realloc(b->buf, b->size))) exit(1);
- }
- return b->buf+b->len;
-}
-
-#define FB_MINREAD (3<<16)
-
-/* Read all of a stdio stream into dst buffer. */
-static size_t fb_readall(fbuf_t *dst, FILE *fp)
-{
- char *dp;
- int n;
- for (dp = fb_need(dst, FB_MINREAD);
- (n = fread(dp, 1, dst->size-dst->len, fp)) > 0;
- dp = fb_need(dst, FB_MINREAD)) dst->len += n;
- if (ferror(fp)) exit(1);
- return dst->len;
-}
-
-/* Substitute pattern p with replacement r, copying from src to dst buffer. */
-static size_t fb_subst(fbuf_t *dst, fbuf_t *src, const char *p, const char *r)
-{
- pcre *re;
- pcre_extra *re_ex;
- const char *re_e;
- char *dp;
- int re_eo, m[3], pos, rlen, clen;
- if (!(re = pcre_compile(p, PCRE_CASELESS, &re_e, &re_eo, NULL))) exit(1);
- re_ex = pcre_study(re, 0, &re_e);
- for (dst->len = 0, rlen = strlen(r), pos = 0;
- pcre_exec(re, re_ex, src->buf, src->len, pos, 0, m, 3) >= 0;
- pos = m[1]) {
- clen = m[0]-pos;
- dp = fb_need(dst, clen+rlen);
- dst->len += clen+rlen;
- memcpy(dp, src->buf+pos, clen);
- memcpy(dp+clen, r, rlen);
- }
- clen = src->len-pos;
- dp = fb_need(dst, clen);
- dst->len += clen;
- memcpy(dp, src->buf+pos, clen);
- return dst->len;
-}
-
-/* Count all matches with pattern p in src buffer. */
-static int fb_countmatches(fbuf_t *src, const char *p)
-{
- pcre *re;
- pcre_extra *re_ex;
- const char *re_e;
- int re_eo, m[3], pos, count;
- if (!(re = pcre_compile(p, PCRE_CASELESS, &re_e, &re_eo, NULL))) exit(1);
- re_ex = pcre_study(re, 0, &re_e);
- for (count = 0, pos = 0;
- pcre_exec(re, re_ex, src->buf, src->len, pos, 0, m, 3) >= 0;
- pos = m[1]) count++;
- return count;
-}
-
-static const char *variants[] = {
- "agggtaaa|tttaccct", "[cgt]gggtaaa|tttaccc[acg]",
- "a[act]ggtaaa|tttacc[agt]t", "ag[act]gtaaa|tttac[agt]ct",
- "agg[act]taaa|ttta[agt]cct", "aggg[acg]aaa|ttt[cgt]ccct",
- "agggt[cgt]aa|tt[acg]accct", "agggta[cgt]a|t[acg]taccct",
- "agggtaa[cgt]|[acg]ttaccct", NULL
-};
-
-static const char *subst[] = {
- "B", "(c|g|t)", "D", "(a|g|t)", "H", "(a|c|t)", "K", "(g|t)",
- "M", "(a|c)", "N", "(a|c|g|t)", "R", "(a|g)", "S", "(c|g)",
- "V", "(a|c|g)", "W", "(a|t)", "Y", "(c|t)", NULL
-};
-
-int main(int argc, char **argv)
-{
- fbuf_t seq[2];
- const char **pp;
- size_t ilen, clen, slen;
- int flip;
- fb_init(&seq[0]);
- fb_init(&seq[1]);
- ilen = fb_readall(&seq[0], stdin);
- clen = fb_subst(&seq[1], &seq[0], ">.*|\n", "");
- for (pp = variants; *pp; pp++)
- printf("%s %d\n", *pp, fb_countmatches(&seq[1], *pp));
- for (slen = 0, flip = 1, pp = subst; *pp; pp += 2, flip = 1-flip)
- slen = fb_subst(&seq[1-flip], &seq[flip], *pp, pp[1]);
- printf("\n%zu\n%zu\n%zu\n", ilen, clen, slen);
- return 0;
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/regex-dna.go b/gcc/testsuite/go.test/test/bench/shootout/regex-dna.go
deleted file mode 100644
index 042d7f2..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/regex-dna.go
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by The Go Authors.
- */
-
-package main
-
-import (
- "fmt"
- "io/ioutil"
- "os"
- "regexp"
-)
-
-var variants = []string{
- "agggtaaa|tttaccct",
- "[cgt]gggtaaa|tttaccc[acg]",
- "a[act]ggtaaa|tttacc[agt]t",
- "ag[act]gtaaa|tttac[agt]ct",
- "agg[act]taaa|ttta[agt]cct",
- "aggg[acg]aaa|ttt[cgt]ccct",
- "agggt[cgt]aa|tt[acg]accct",
- "agggta[cgt]a|t[acg]taccct",
- "agggtaa[cgt]|[acg]ttaccct",
-}
-
-type Subst struct {
- pat, repl string
-}
-
-var substs = []Subst{
- Subst{"B", "(c|g|t)"},
- Subst{"D", "(a|g|t)"},
- Subst{"H", "(a|c|t)"},
- Subst{"K", "(g|t)"},
- Subst{"M", "(a|c)"},
- Subst{"N", "(a|c|g|t)"},
- Subst{"R", "(a|g)"},
- Subst{"S", "(c|g)"},
- Subst{"V", "(a|c|g)"},
- Subst{"W", "(a|t)"},
- Subst{"Y", "(c|t)"},
-}
-
-func countMatches(pat string, bytes []byte) int {
- re := regexp.MustCompile(pat)
- n := 0
- for {
- e := re.FindIndex(bytes)
- if len(e) == 0 {
- break
- }
- n++
- bytes = bytes[e[1]:]
- }
- return n
-}
-
-func main() {
- bytes, err := ioutil.ReadAll(os.Stdin)
- if err != nil {
- fmt.Fprintf(os.Stderr, "can't read input: %s\n", err)
- os.Exit(2)
- }
- ilen := len(bytes)
- // Delete the comment lines and newlines
- bytes = regexp.MustCompile("(>[^\n]+)?\n").ReplaceAll(bytes, []byte{})
- clen := len(bytes)
- for _, s := range variants {
- fmt.Printf("%s %d\n", s, countMatches(s, bytes))
- }
- for _, sub := range substs {
- bytes = regexp.MustCompile(sub.pat).ReplaceAll(bytes, []byte(sub.repl))
- }
- fmt.Printf("\n%d\n%d\n%d\n", ilen, clen, len(bytes))
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/regex-dna.txt b/gcc/testsuite/go.test/test/bench/shootout/regex-dna.txt
deleted file mode 100644
index e23e71f..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/regex-dna.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-agggtaaa|tttaccct 1
-[cgt]gggtaaa|tttaccc[acg] 0
-a[act]ggtaaa|tttacc[agt]t 0
-ag[act]gtaaa|tttac[agt]ct 0
-agg[act]taaa|ttta[agt]cct 1
-aggg[acg]aaa|ttt[cgt]ccct 0
-agggt[cgt]aa|tt[acg]accct 0
-agggta[cgt]a|t[acg]taccct 0
-agggtaa[cgt]|[acg]ttaccct 2
-
-10245
-10000
-13348
diff --git a/gcc/testsuite/go.test/test/bench/shootout/reverse-complement.c b/gcc/testsuite/go.test/test/bench/shootout/reverse-complement.c
deleted file mode 100644
index b34c846..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/reverse-complement.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*
- * The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org
- *
- * contributed by Bob W
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#define JBFSIZE 82 // line input buffer size
-#define QBFSIZE 5200 // output buffer initial size
-#define Z16 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
-#define V32 "\0TVGH\0\0CD\0\0M\0KN\0\0\0YSA\0BW\0R\0\0\0\0\0\0"
-#define VALL Z16 Z16 Z16 Z16 V32 V32 Z16 Z16 Z16 Z16 Z16 Z16 Z16 Z16
-
-int errex(char *s, int n) { // error message+value, return 1
- fprintf(stderr,"\n*** Error: %s [%d]!\n", s, n);
- return 1;
-}
-
-int main () { // ***** main *****
- char *pj, *pq, *pr; // buffer pointers: inp,out,/out
- char *jjj = malloc(JBFSIZE); // allocate input line buffer
- char *qqq = malloc(QBFSIZE); // output buffer (dyn. size)
- char *pqstop = qqq+QBFSIZE; // end-of-buffer pointer
- char xtab[256] = VALL; // char conversion table
-
- if (!jjj || !qqq)
- return errex("Buffer allocation", !jjj + !qqq);
- pj = fgets(jjj,JBFSIZE,stdin); // fetch 1st line
- if (!pj)
- return errex("No input data",0);
- if (*jjj != '>')
- return errex("1st char not '>'", 0);
-
- while (pj) { // MAIN LOOP: process data
- fputs(jjj, stdout); // output ID line
-
- for (pq=qqq+1, pr=pqstop; ; pq++) { // LOOP: fill output buffer
- pj = fgets(jjj, JBFSIZE, stdin); // get line from stdin
- if (!pj || (*jjj=='>')) break; // EOF or new ID line
- if (pr <= (pq+61)) { // need to resize buffer
- char *newstop = pqstop + 12777888;
- char *newptr = realloc(qqq, newstop-qqq);
- if (!newptr)
- return errex("Out of memory", 0);
- if (newptr != qqq) { // new base: adj. pointers
- size_t x = newptr-qqq; // offset for pointer update
- pq+=x; pr+=x; qqq+=x;
- newstop+=x; pqstop+=x;
- }
- pr = __builtin_memmove(newstop-(pqstop-pr), pr, pqstop-pr);
- pqstop = newstop; // buffer resize complete
- }
- while (*pj) { // LOOP: conv. & revert line
- char c = xtab[(unsigned char)(*pj++)];
- if (c) // conversion valid
- *(--pr) = c;
- }
- }
-
- for (pq = qqq; pr<pqstop; ) { // LOOP: format output
- size_t x = (pqstop-pr)<60 ? pqstop-pr : 60;
- __builtin_memmove(pq,pr,x); // move line to free space
- pr+=x; pq+=x; *(pq++) = 0xA; // adjust pointers, add LF
- }
- fwrite(qqq, 1, pq-qqq, stdout); // output converted data
- }
- return 0;
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/reverse-complement.go b/gcc/testsuite/go.test/test/bench/shootout/reverse-complement.go
deleted file mode 100644
index baa30ff..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/reverse-complement.go
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by The Go Authors.
- */
-
-package main
-
-import (
- "bufio"
- "os"
-)
-
-const lineSize = 60
-
-var complement = [256]uint8{
- 'A': 'T', 'a': 'T',
- 'C': 'G', 'c': 'G',
- 'G': 'C', 'g': 'C',
- 'T': 'A', 't': 'A',
- 'U': 'A', 'u': 'A',
- 'M': 'K', 'm': 'K',
- 'R': 'Y', 'r': 'Y',
- 'W': 'W', 'w': 'W',
- 'S': 'S', 's': 'S',
- 'Y': 'R', 'y': 'R',
- 'K': 'M', 'k': 'M',
- 'V': 'B', 'v': 'B',
- 'H': 'D', 'h': 'D',
- 'D': 'H', 'd': 'H',
- 'B': 'V', 'b': 'V',
- 'N': 'N', 'n': 'N',
-}
-
-func main() {
- in := bufio.NewReader(os.Stdin)
- buf := make([]byte, 1024*1024)
- line, err := in.ReadSlice('\n')
- for err == nil {
- os.Stdout.Write(line)
-
- // Accumulate reversed complement in buf[w:]
- nchar := 0
- w := len(buf)
- for {
- line, err = in.ReadSlice('\n')
- if err != nil || line[0] == '>' {
- break
- }
- line = line[0 : len(line)-1]
- nchar += len(line)
- if len(line)+nchar/60+128 >= w {
- nbuf := make([]byte, len(buf)*5)
- copy(nbuf[len(nbuf)-len(buf):], buf)
- w += len(nbuf) - len(buf)
- buf = nbuf
- }
-
- // This loop is the bottleneck.
- for _, c := range line {
- w--
- buf[w] = complement[c]
- }
- }
-
- // Copy down to beginning of buffer, inserting newlines.
- // The loop left room for the newlines and 128 bytes of padding.
- i := 0
- for j := w; j < len(buf); j += 60 {
- n := copy(buf[i:i+60], buf[j:])
- buf[i+n] = '\n'
- i += n + 1
- }
- os.Stdout.Write(buf[0:i])
- }
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/reverse-complement.txt b/gcc/testsuite/go.test/test/bench/shootout/reverse-complement.txt
deleted file mode 100644
index 14d792a..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/reverse-complement.txt
+++ /dev/null
@@ -1,171 +0,0 @@
->ONE Homo sapiens alu
-CGGAGTCTCGCTCTGTCGCCCAGGCTGGAGTGCAGTGGCGCGATCTCGGCTCACTGCAAC
-CTCCGCCTCCCGGGTTCAAGCGATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGGATTACA
-GGCGCGCGCCACCACGCCCGGCTAATTTTTGTATTTTTAGTAGAGACGGGGTTTCACCAT
-GTTGGCCAGGCTGGTCTCGAACTCCTGACCTCAGGTGATCCGCCCGCCTCGGCCTCCCAA
-AGTGCTGGGATTACAGGCGTGAGCCACCGCGCCCGGCCTTTTTGAGACGGAGTCTCGCTC
-TGTCGCCCAGGCTGGAGTGCAGTGGCGCGATCTCGGCTCACTGCAACCTCCGCCTCCCGG
-GTTCAAGCGATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGGATTACAGGCGCGCGCCACC
-ACGCCCGGCTAATTTTTGTATTTTTAGTAGAGACGGGGTTTCACCATGTTGGCCAGGCTG
-GTCTCGAACTCCTGACCTCAGGTGATCCGCCCGCCTCGGCCTCCCAAAGTGCTGGGATTA
-CAGGCGTGAGCCACCGCGCCCGGCCTTTTTGAGACGGAGTCTCGCTCTGTCGCCCAGGCT
-GGAGTGCAGTGGCGCGATCTCGGCTCACTGCAACCTCCGCCTCCCGGGTTCAAGCGATTC
-TCCTGCCTCAGCCTCCCGAGTAGCTGGGATTACAGGCGCGCGCCACCACGCCCGGCTAAT
-TTTTGTATTTTTAGTAGAGACGGGGTTTCACCATGTTGGCCAGGCTGGTCTCGAACTCCT
-GACCTCAGGTGATCCGCCCGCCTCGGCCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCA
-CCGCGCCCGGCCTTTTTGAGACGGAGTCTCGCTCTGTCGCCCAGGCTGGAGTGCAGTGGC
-GCGATCTCGGCTCACTGCAACCTCCGCCTCCCGGGTTCAAGCGATTCTCCTGCCTCAGCC
-TCCCGAGTAGCTGGGATTACAGGCGCGCGCCACCACGCCCGGCTAATTTTTGTATTTTTA
-GTAGAGACGGGGTTTCACCATGTTGGCCAGGCTGGTCTCGAACTCCTGACCTCAGGTGAT
-CCGCCCGCCTCGGCCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCACCGCGCCCGGCCT
-TTTTGAGACGGAGTCTCGCTCTGTCGCCCAGGCTGGAGTGCAGTGGCGCGATCTCGGCTC
-ACTGCAACCTCCGCCTCCCGGGTTCAAGCGATTCTCCTGCCTCAGCCTCCCGAGTAGCTG
-GGATTACAGGCGCGCGCCACCACGCCCGGCTAATTTTTGTATTTTTAGTAGAGACGGGGT
-TTCACCATGTTGGCCAGGCTGGTCTCGAACTCCTGACCTCAGGTGATCCGCCCGCCTCGG
-CCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCACCGCGCCCGGCCTTTTTGAGACGGAG
-TCTCGCTCTGTCGCCCAGGCTGGAGTGCAGTGGCGCGATCTCGGCTCACTGCAACCTCCG
-CCTCCCGGGTTCAAGCGATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGGATTACAGGCGC
-GCGCCACCACGCCCGGCTAATTTTTGTATTTTTAGTAGAGACGGGGTTTCACCATGTTGG
-CCAGGCTGGTCTCGAACTCCTGACCTCAGGTGATCCGCCCGCCTCGGCCTCCCAAAGTGC
-TGGGATTACAGGCGTGAGCCACCGCGCCCGGCCTTTTTGAGACGGAGTCTCGCTCTGTCG
-CCCAGGCTGGAGTGCAGTGGCGCGATCTCGGCTCACTGCAACCTCCGCCTCCCGGGTTCA
-AGCGATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGGATTACAGGCGCGCGCCACCACGCC
-CGGCTAATTTTTGTATTTTTAGTAGAGACGGGGTTTCACCATGTTGGCCAGGCTGGTCTC
-GAACTCCTGACCTCAGGTGATCCGCCCGCCTCGGCCTCCCAAAGTGCTGGGATTACAGGC
-GTGAGCCACCGCGCCCGGCC
->TWO IUB ambiguity codes
-TAGGDHACHATCRGTRGVTGAGWTATGYTGCTGTCABACDWVTRTAAGAVVAGATTTNDA
-GASMTCTGCATBYTTCAAKTTACMTATTACTTCATARGGYACMRTGTTTTYTATACVAAT
-TTCTAKGDACKADACTATATNTANTCGTTCACGBCGYSCBHTANGGTGATCGTAAAGTAA
-CTATBAAAAGATSTGWATBCSGAKHTTABBAACGTSYCATGCAAVATKTSKTASCGGAAT
-WVATTTNTCCTTCTTCTTDDAGTGGTTGGATACVGTTAYMTMTBTACTTTHAGCTAGBAA
-AAGAGKAAGTTRATWATCAGATTMDDTTTAAAVAAATATTKTCYTAAATTVCNKTTRACG
-ADTATATTTATGATSADSCAATAWAGCGRTAGTGTAAGTGACVGRADYGTGCTACHVSDT
-CTVCARCSYTTAATATARAAAATTTAATTTACDAATTGBACAGTAYAABATBTGCAGBVG
-TGATGGDCAAAATBNMSTTABKATTGGSTCCTAGBTTACTTGTTTAGTTTATHCGATSTA
-AAGTCGAKAAASTGTTTTAWAKCAGATATACTTTTMTTTTGBATAGAGGAGCMATGATRA
-AAGGNCAYDCCDDGAAAGTHGBTAATCKYTBTACBGTBCTTTTTGDTAASSWTAAWAARA
-TTGGCTAAGWGRADTYACATAGCTCBTAGATAWAGCAATNGTATMATGTTKMMAGTAWTC
-CCNTSGAAWATWCAAAAMACTGAADNTYGATNAATCCGAYWNCTAACGTTAGAGDTTTTC
-ATCTGGKRTAVGAABVCTGWGBTCTDVGKATTBTCTAAGGVADAAAVWTCTAGGGGAGGG
-TTAGAACAATTAAHTAATNAAATGCATKATCTAAYRTDTCAGSAYTTYHGATRTTWAVTA
-BGNTCDACAGBCCRCAGWCRTCABTGMMAWGMCTCAACCGATRTGBCAVAATCGTDWDAA
-CAYAWAATWCTGGTAHCCCTAAGATAACSCTTAGTGSAACAWTBGTCDTTDGACWDBAAC
-HTTTNGSKTYYAAYGGATNTGATTTAARTTAMBAATCTAAGTBTCATYTAACTTADTGTT
-TCGATACGAAHGGCYATATACCWDTKYATDCSHTDTCAAAATGTGBACTGSCCVGATGTA
-TCMMAGCCTTDAAABAATGAAGAGTAACTHATMGVTTAATAACCCGGTTVSANTGCAATT
-GTGAGATTTAMGTTTAMAAYGCTGACAYAAAAAGGCACAMYTAAGVGGCTGGAABVTACG
-GATTSTYGTBVAKTATWACCGTGTKAGTDTGTATGTTTAAAGGAAAAAGTAACATARAAA
-GGTYCAMNYAAABTATAGNTSATANAGTCATCCTATWADKAACTRGTMSACDGTATSAYT
-AAHSHGTAABYGACTYTATADTGSTATAGAGAAATCGNTAAAGGAAATCAGTTGTNCYMV
-TNACDRTATBNATATASTAGAAMSCGGGANRCKKMCAAACATTNAGTCTRMAATBMTACC
-CGTACTTCTBGDSYAATWGAAAATGACADDCHAKAAAYATATTKTTTTCACANACWAGAA
-AKATCCTTATTAYKHKCTAAACARTATTTTDATBTVWCYGCAATACTAGGKAAASTTDGA
-MGGCHTTHAATVCAHDRYAGGRCTATACGTCMAGAGAGCTBTHGNACARTCCBDCTAAGA
-GCGGCTTTARTAAAGAATCCNAGTAWBTGACTTGAATTACWTVACAGAAABCAATNAAAC
-CGTNTRANTTGAYCMAWBADTANABRGGTKTHTWTAGTTVCTMBKTAGMTVKCCAGCANT
-TVAGSWTTAGCCGCRHTTTCCTTHNTATTAAGAAGAATAGGMTRAARTCTABGTACDTTT
-TATAAVDHAHTATAGATCCTAGTAAGYTWATDWCATGAGGGATAGTAAMDMNGBASTWAM
-TSTATRBAYDABATGTATATYCGCACTGTTTTAACMCWBTATAWAGTATBTSTATVTTAR
-CCTMTTAAKADATCAACTAATYTSVTAKGDATTATGCKTCAYCAKAATACTTKAANGAGT
-ATTSDAGATCGGAAATACTTAAYAAVGTATMCGCTTGTGTDCTAATYTATTTTATTTWAA
-CAGWRCTATGTAGMTGTTTGTTYKTNGTTKTCAGAACNTRACCTACKTGSRATGTGGGGG
-CTGTCATTAAGTAAATNGSTTABCCCCTCGCAGCTCWHTCGCGAAGCAVATGCKACGHCA
-ACAKTTAATAACASAAADATTWNYTGTAATTGTTCGTMHACHTWATGTGCWTTTTGAAHY
-ACTTTGTAYAMSAAACTTAADAAATATAGTABMATATYAATGSGGTAGTTTGTGTBYGGT
-TWSGSVGWMATTDMTCCWWCABTCSVACAGBAATGTTKATBGTCAATAATCTTCTTAAAC
-ARVAATHAGYBWCTRWCABGTWWAATCTAAGTCASTAAAKTAAGVKBAATTBGABACGTA
-AGGTTAAATAAAAACTRMDTWBCTTTTTAATAAAAGATMGCCTACKAKNTBAGYRASTGT
-ASSTCGTHCGAAKTTATTATATTYTTTGTAGAACATGTCAAAACTWTWTHGKTCCYAATA
-AAGTGGAYTMCYTAARCSTAAATWAKTGAATTTRAGTCTSSATACGACWAKAASATDAAA
-TGYYACTSAACAAHAKTSHYARGASTATTATTHAGGYGGASTTTBGAKGATSANAACACD
-TRGSTTRAAAAAAAACAAGARTCVTAGTAAGATAWATGVHAAKATWGAAAAGTYAHVTAC
-TCTGRTGTCAWGATRVAAKTCGCAAVCGASWGGTTRTCSAMCCTAACASGWKKAWDAATG
-ACRCBACTATGTGTCTTCAAAHGSCTATATTTCGTVWAGAAGTAYCKGARAKSGKAGTAN
-TTTCYACATWATGTCTAAAADMDTWCAATSTKDACAMAADADBSAAATAGGCTHAHAGTA
-CGACVGAATTATAAAGAHCCVAYHGHTTTACATSTTTATGNCCMTAGCATATGATAVAAG
->THREE Homo sapiens frequency
-ATATTTATCTTTTCACTTCCTACATTGGTCAGACCATTATTCGACACGTGGCGTCATTTT
-GTCATACCGGGTAATGTTGGAAACAAAACGTACTGATAAAATACTGAGTTGTAAACTCTA
-ATCAGATAACGCGCTTGGATATTAAGATTCACACAGGGGTTTCGGCTGTAAAAAAACTTG
-TGGAGCTGTTCTGGGACAGATAAGTTGTACCTCGTACTTAGCTAATTAATGAACCAACTG
-ATTACGATAGAACAATTCTGAGGCCGCCAGGACAGCCAAATTTTAATCTTATAAAGCTGG
-AAACAGCCGGTATTAGCTTCTCGCATACTTTGCCTGCATTGGTACCTTACAGATATCAGC
-GTAGTCATATACACCTCGGTCTCAGCTAAGCTTGTATCTCTTAGAGTAGTTCAAAGATAG
-TGGACAATACCTGTGGAATCGATTGCAGATATGGATTTATTTAACTACTGAGTCTCATTC
-ACAAGCTAAGCAAGGAGCACGTTTTGGTGCCGGCATACCGATTTGCTATCATGTCAGCAA
-ATTTGCGTTGTATTCCTAGTTGCACCCATTAAGGCCACACTCCGAACCTAATTATTACAT
-CGCAAAGACATGTACGAAGGACCCGATGTCGAATAGAAGGGAGGACTGTTCATTGGAAGC
-TAGACCAGAGGAATCGCAAAGATGCAACTCTTACAATAAAAATCTAATTTCAGTCAACAC
-GCAATTTCTATAAGGTTTCCGATAATAATGAACCGTCTTCCACAGGGGAATTTGCCATGC
-TCGTAAAAGTAGTTAATCCAAGTAGAAGAAATTTTGATAATGTTTTAAGTTGGCACGAAG
-GAATTCAGAGAGATCTTACCTAACAAAGGCATTAGTAGATGTTCCTTGGTTCACACTCGG
-TCAATCAGAGCACATACTACGGGCGATACCGGGAATGACACAACATCAATGAGATTGTTA
-AGTGAGGTAATTGACTTTAGAGGACTCGATCAGTATACTGTCACTATGAACATCGTATTA
-ATTGTTATCCGATATATACACCACCGATTTGCTTGTGCAAGGTTACAGACCCATTCGATA
-AATACAAACACGGAGCGATATTATTTAAGGAGTGCTGTCTTCAAAAGAATTATTCCCACA
-CCGACATAAGAACTTCGCTCCGTCATTCCAGATTTAAATAACATAACGTAACGCTTTGCT
-GATAACATAACATAACCGAGAATTTGCTTAGGAAATTTGGAGCAATATTGCATTGTTTCT
-CAGTCATCACAAGGCCCGCCAAAGAACTCTGAGAATCAGGATTCAACATGATTGGTAAGA
-CTCTATATATATAACTTAATTCTTGTGTCCGGAGATAGAAAGAGGACGAGAGATACTACG
-AAAGAAAGTGTACTTCGATGTATCAATTCAGACGCCTTCTCTATCATCAACATTATAGGT
-CTCGTATATGCTCGGCGCGATCTGCTTCTCTCCGCCAATAGCCCCATAGTGTATTTCAAG
-CGCAGTAACAGTGAAATCGTTACGAAGGTAGGGATGTTGCTTATAATTGTCGTAACTTAT
-CGCTTATGTATCTTTCAAGAATGAACGGCAGCATATACATACGTTCTACCTTTAGCTACA
-AAGCATCCATATACTCCCTCTCATGATTGAAACTCTTCCCTATTTTGTAGCCAATAGTGA
-AAGCGTATTAGTATAAATTCGTCGGTTTTTCACTCGCAACTGTTATACTCTGCAAACAAA
-CGAAAGCCTCATAGTACAAACCTAAAGCTACATACTTCATCATTGGCAGACCAGTGGCGG
-TATTTCTACGGAAGCATCACTATAGATATAAAGTTTCCCTTCATGTACGTCTGTTAACCA
-TATCACAAGAAACTGCTATCTCTGTCACGTAACAATTCACGCGCCTTATCGCCAAATGTT
-CATATATGCGCGGTATACGTATGAACGAATACTAATTAGTATAACGGAGGATTCACGGGA
-GGGATACTTGGGGCATTTATAAATCGTCTAAAAATTTTCTATCAGCACTTGCGGGTTATA
-GTGGATTACTAGGCAACATAATATTCTGTATTGGTCCAAATGACGCTATAGATAAATTAG
-CAAAATACATTGTTTCCATTTATGTAAGTCGAAACTCCAGGACTCCCGGGAACCAGTTAA
-ACCGTCTGGAAAAGACACATTGTGAGCGGGACTTCAATGATAGCTTTCAATGAGCTTCTC
-ATGCTTGGGGTCTGTACATATATGTTGGCGAAATTATCGTCTGTATTCTGTTATGCTTTG
-ATCATGGGTTATTAGTATAGTGTCCGGTTAAGTACCAATACCGCTAGAGACCCGACCTAA
-GTCGATAACTAACGATCATCGACGTAAGGATCGTCTCGATCAGTACTTCAGTCTAGATCT
-GGGAATAGTAACTCGTTAGTGAACTATGTCGTGTCATAACTCTAAAATGCAATCAAATCT
-TATTATTGAGTATTGATTATATAAAGCATCCGCTTAGCTTTACCCTCAAATGTTATATGC
-AATTTAAAGCGCTTGATATCGTCTACTCAAGTTCAGGTTTCACATGGCCGCAACGTGACG
-TTATTAGAGGTGGGTCATCATCTCTGAGGCTAGTGATGTTGAATACTCATTGAATGGGAA
-GTGGAATACCATGCTCGTAGGTAACAGCATGACCTATAAAATATACTATGGGTGTGTGGT
-AGATCAATATTGTTCAAGCATATCGTAACAATAACGGCTGAAATGTTACTGACATGAAAG
-AGGGAGTCCAAACCATTCTAACAGCTGATCAAGTCGTCTAAAAACGCCTGGTTCAGCCTT
-AAGAGTTATAAGCCAGACAAATTGTATCAATAGAGAATCCGTAAATTCCTCGGCCAACCT
-CTTGCAAAGACATCACTATCAATATACTACCGTGATCTTAATTAGTGAACTTATATAAAT
-ATCTACAACCAGATTCAACGGAAAAGCTTTAGTGGATTAGAAATTGCCAAGAATCACATT
-CATGTGGGTTCGAATGCTTTAGTAATACCATTTCGCCGAGTAGTCACTTCGCTGAACTGT
-CGTAAATTGCTATGACATAATCGAAAAGGATTGTCAAGAGTCGATTACTGCGGACTAATA
-ATCCCCACGGGGGTGGTCTCATGTCTCCCCAGGCGAGTGGGGACGGTTGATAAACACGCT
-GCATCGCGGACTGATGTTCCCAGTATTACATAGTCACATTGGATTGCGAGTAGTCTACCT
-ATTTATGAGCGAGAGATGCCTCTAACTACTTCGACTTTTAAAACCTTTCCACGCCAGTAT
-TCGGCGAAAGGGAAGTATTAAGGGTTGTCATAATTAAGCTGATACCACTTCAGACTTTGC
-TCTACTTCTGTCTTTCATTGGTTTAGTAAAGTCTGTCCATTCGTCGAGACCGTCTTTTGC
-AGCCTCATTCTACCAACTGCTCCGACTCTTAGTCTGCTTCTCCCAGCGTTATAACAAGAG
-GCATTTTGTCATCCTTAAAACAATAATAAAGAACTCGGAGCACTGATATAATGACTGAAT
-TAGAACCGCTTAAAAATACAACGAATAGATAAGACTATCGGATAAGATCTAATATGTAGT
-GATTAAGCCCTTTATTAATTAATAATAGTTACCCTTTCTGATGTAACGCGACATATTACG
-ATTTAGTGGCACGTCTGAATTGCAAAGCAGATCTCTACCCGATTTTTATTATAAATCCCG
-TATACATCTTGACTTGAGTAATTGTTCATCTTTTTATATCTCTTCGTACTACAAATAATT
-AATATCTCAACCCGTATTGTGTGATTCTAATTACCAACAGAATACGAGGAGGTTTTTGCT
-TAGGGCCATATATAATGAATCTATCTCGTTTATTCGCGGAACCCGAGATAACATTACGAT
-GTAACTATTTTAGAGAACTTAATACAAGAAACATTGCTGATTACTCATAACTAAATGCTT
-GGTAATATATCCTCAGTGCCCCTACCATCTTTTACGCAGGGATGTAATTACTTAGGATTC
-ATTGTGTAAGAATTACAATGAACGATGGATATGAAGGCATGTTGCGAGGTGTTCCTTGGT
-ATGTGAAGTTCGCAGGGCAACAAAAATTTCGCAGAATAGGCCTCAAAGTATTGGTAAAGA
-AGACAACTAATCATCACGAGCTTCTGATATCAATACGAACGAGTCCTGTGATGGATGAAA
-GAAAGTCGTATCGAAAATGTCAAGAGTCTGCCCAATGTAACTTACTTCAAAAAATAACGC
-TTCCGCCAAGTACGTTCGAATAAACGTAATTTTAAAAATACATAAGGGGTGTTAGAAAGT
-AAGCGACGGGATATAAGTTAGACTCAAGATTCCGCCGTAAAACGAGACTGATTCCGAAGA
-TTGTTCGTGGATCTGGTCATGACTTTCACTGAGTAAGGAGTTTCGACATATGTCAATAAA
-CACAAAAATAGAAGCTATTCGATCTGAAAAATATTAGGACAAGAAACTATCTCACGCTAG
-CCCAGAATATTCACTCACCCACGGGCGATACTAAAGCACTATATAGTCGCGTGATTACTA
-TACATATGGTACACATAAGAATCACGATCAGGTTCTCAATTTTCAACAATATATGTTTAT
-TTGCATAGGTAATATTAGGCCTTTAAGAGAAGGATGGGTGAGATACTCCGGGGATGGCGG
-CAATAAAGAAAAACACGATATGAGTAATAGGATCCTAATATCTTGGCGAGAGACTTAAGG
-TACGAATTTTGCGCAATCTATTTTTTACTTGGCCAGAATTCATGTATGGTATAAGTACGA
-ACTTTTTTGATCACTTTCATGGCTACCTGATTAGGATAGTTTGAGGAATTTCCCAAATAT
-ACCGATTTAATATACACTAGGGCTTGTCACTTTGAGTCAGAAAAAGAATATAATTACTTA
-GGGTAATGCTGCATACATATTCTTATATTGCAAAGGTTCTCTGGGTAATCTTGAGCCTTC
-ACGATACCTGGTGAAGTGTT
diff --git a/gcc/testsuite/go.test/test/bench/shootout/spectral-norm-parallel.go b/gcc/testsuite/go.test/test/bench/shootout/spectral-norm-parallel.go
deleted file mode 100644
index 2706f39..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/spectral-norm-parallel.go
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by The Go Authors.
- * Based on spectral-norm.c by Sebastien Loisel
- */
-
-package main
-
-import (
- "flag"
- "fmt"
- "math"
- "runtime"
-)
-
-var n = flag.Int("n", 2000, "count")
-var nCPU = flag.Int("ncpu", 4, "number of cpus")
-
-func evalA(i, j int) float64 { return 1 / float64(((i+j)*(i+j+1)/2 + i + 1)) }
-
-type Vec []float64
-
-func (v Vec) Times(i, n int, u Vec, c chan int) {
- for ; i < n; i++ {
- v[i] = 0
- for j := 0; j < len(u); j++ {
- v[i] += evalA(i, j) * u[j]
- }
- }
- c <- 1
-}
-
-func (v Vec) TimesTransp(i, n int, u Vec, c chan int) {
- for ; i < n; i++ {
- v[i] = 0
- for j := 0; j < len(u); j++ {
- v[i] += evalA(j, i) * u[j]
- }
- }
- c <- 1
-}
-
-func wait(c chan int) {
- for i := 0; i < *nCPU; i++ {
- <-c
- }
-}
-
-func (v Vec) ATimesTransp(u Vec) {
- x := make(Vec, len(u))
- c := make(chan int, *nCPU)
- for i := 0; i < *nCPU; i++ {
- go x.Times(i*len(v) / *nCPU, (i+1)*len(v) / *nCPU, u, c)
- }
- wait(c)
- for i := 0; i < *nCPU; i++ {
- go v.TimesTransp(i*len(v) / *nCPU, (i+1)*len(v) / *nCPU, x, c)
- }
- wait(c)
-}
-
-func main() {
- flag.Parse()
- runtime.GOMAXPROCS(*nCPU)
- N := *n
- u := make(Vec, N)
- for i := 0; i < N; i++ {
- u[i] = 1
- }
- v := make(Vec, N)
- for i := 0; i < 10; i++ {
- v.ATimesTransp(u)
- u.ATimesTransp(v)
- }
- var vBv, vv float64
- for i := 0; i < N; i++ {
- vBv += u[i] * v[i]
- vv += v[i] * v[i]
- }
- fmt.Printf("%0.9f\n", math.Sqrt(vBv/vv))
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/spectral-norm.c b/gcc/testsuite/go.test/test/bench/shootout/spectral-norm.c
deleted file mode 100644
index 832eb3d..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/spectral-norm.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* -*- mode: c -*-
- *
- * The Great Computer Language Shootout
- * http://shootout.alioth.debian.org/
- *
- * Contributed by Sebastien Loisel
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-
-double eval_A(int i, int j) { return 1.0/((i+j)*(i+j+1)/2+i+1); }
-
-void eval_A_times_u(int N, const double u[], double Au[])
-{
- int i,j;
- for(i=0;i<N;i++)
- {
- Au[i]=0;
- for(j=0;j<N;j++) Au[i]+=eval_A(i,j)*u[j];
- }
-}
-
-void eval_At_times_u(int N, const double u[], double Au[])
-{
- int i,j;
- for(i=0;i<N;i++)
- {
- Au[i]=0;
- for(j=0;j<N;j++) Au[i]+=eval_A(j,i)*u[j];
- }
-}
-
-void eval_AtA_times_u(int N, const double u[], double AtAu[])
-{ double v[N]; eval_A_times_u(N,u,v); eval_At_times_u(N,v,AtAu); }
-
-int main(int argc, char *argv[])
-{
- int i;
- int N = ((argc == 2) ? atoi(argv[1]) : 2000);
- double u[N],v[N],vBv,vv;
- for(i=0;i<N;i++) u[i]=1;
- for(i=0;i<10;i++)
- {
- eval_AtA_times_u(N,u,v);
- eval_AtA_times_u(N,v,u);
- }
- vBv=vv=0;
- for(i=0;i<N;i++) { vBv+=u[i]*v[i]; vv+=v[i]*v[i]; }
- printf("%0.9f\n",sqrt(vBv/vv));
- return 0;
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/spectral-norm.go b/gcc/testsuite/go.test/test/bench/shootout/spectral-norm.go
deleted file mode 100644
index 6667f3e..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/spectral-norm.go
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by The Go Authors.
- * Based on spectral-norm.c by Sebastien Loisel
- */
-
-package main
-
-import (
- "flag"
- "fmt"
- "math"
-)
-
-var n = flag.Int("n", 2000, "count")
-
-func evalA(i, j int) float64 { return 1 / float64(((i+j)*(i+j+1)/2 + i + 1)) }
-
-type Vec []float64
-
-func (v Vec) Times(u Vec) {
- for i := 0; i < len(v); i++ {
- v[i] = 0
- for j := 0; j < len(u); j++ {
- v[i] += evalA(i, j) * u[j]
- }
- }
-}
-
-func (v Vec) TimesTransp(u Vec) {
- for i := 0; i < len(v); i++ {
- v[i] = 0
- for j := 0; j < len(u); j++ {
- v[i] += evalA(j, i) * u[j]
- }
- }
-}
-
-func (v Vec) ATimesTransp(u Vec) {
- x := make(Vec, len(u))
- x.Times(u)
- v.TimesTransp(x)
-}
-
-func main() {
- flag.Parse()
- N := *n
- u := make(Vec, N)
- for i := 0; i < N; i++ {
- u[i] = 1
- }
- v := make(Vec, N)
- for i := 0; i < 10; i++ {
- v.ATimesTransp(u)
- u.ATimesTransp(v)
- }
- var vBv, vv float64
- for i := 0; i < N; i++ {
- vBv += u[i] * v[i]
- vv += v[i] * v[i]
- }
- fmt.Printf("%0.9f\n", math.Sqrt(vBv/vv))
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/spectral-norm.txt b/gcc/testsuite/go.test/test/bench/shootout/spectral-norm.txt
deleted file mode 100644
index b988598..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/spectral-norm.txt
+++ /dev/null
@@ -1 +0,0 @@
-1.274224152
diff --git a/gcc/testsuite/go.test/test/bench/shootout/threadring.c b/gcc/testsuite/go.test/test/bench/shootout/threadring.c
deleted file mode 100644
index a518134..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/threadring.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*
-* The Computer Language Benchmarks Game
-* http://shootout.alioth.debian.org/
-
-* contributed by Premysl Hruby
-*/
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <string.h>
-#include <limits.h>
-
-#define THREADS (503)
-
-
-struct stack {
- char x[PTHREAD_STACK_MIN];
-};
-
-
-/* staticaly initialize mutex[0] mutex */
-static pthread_mutex_t mutex[THREADS];
-static int data[THREADS];
-static struct stack stacks[THREADS];
-/* stacks must be defined staticaly, or my i386 box run of virtual memory for this
- * process while creating thread +- #400 */
-
-static void* thread(void *num)
-{
- int l = (int)(uintptr_t)num;
- int r = (l+1) % THREADS;
- int token;
-
- while(1) {
- pthread_mutex_lock(mutex + l);
- token = data[l];
- if (token) {
- data[r] = token - 1;
- pthread_mutex_unlock(mutex + r);
- }
- else {
- printf("%i\n", l+1);
- exit(0);
- }
- }
-}
-
-
-
-int main(int argc, char **argv)
-{
- int i;
- pthread_t cthread;
- pthread_attr_t stack_attr;
-
- if (argc != 2)
- exit(255);
- data[0] = atoi(argv[1]);
-
- pthread_attr_init(&stack_attr);
-
- for (i = 0; i < THREADS; i++) {
- pthread_mutex_init(mutex + i, NULL);
- pthread_mutex_lock(mutex + i);
-
- pthread_attr_setstack(&stack_attr, &stacks[i], sizeof(struct stack));
- pthread_create(&cthread, &stack_attr, thread, (void*)(uintptr_t)i);
- }
-
- pthread_mutex_unlock(mutex + 0);
- pthread_join(cthread, NULL);
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/threadring.go b/gcc/testsuite/go.test/test/bench/shootout/threadring.go
deleted file mode 100644
index e76dd0b..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/threadring.go
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of "The Computer Language Benchmarks Game" nor the
- name of "The Computer Language Shootout Benchmarks" nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* The Computer Language Benchmarks Game
- * http://shootout.alioth.debian.org/
- *
- * contributed by The Go Authors.
- */
-
-package main
-
-import (
- "flag"
- "fmt"
- "os"
-)
-
-var n = flag.Int("n", 1000, "how many passes")
-
-const Nthread = 503
-
-func f(i int, in <-chan int, out chan<- int) {
- for {
- n := <-in
- if n == 0 {
- fmt.Printf("%d\n", i)
- os.Exit(0)
- }
- out <- n - 1
- }
-}
-
-func main() {
- flag.Parse()
-
- one := make(chan int) // will be input to thread 1
- var in, out chan int = nil, one
- for i := 1; i <= Nthread-1; i++ {
- in, out = out, make(chan int)
- go f(i, in, out)
- }
- go f(Nthread, out, one)
- one <- *n
- <-make(chan int) // hang until ring completes
-}
diff --git a/gcc/testsuite/go.test/test/bench/shootout/threadring.txt b/gcc/testsuite/go.test/test/bench/shootout/threadring.txt
deleted file mode 100644
index f9aaa4d..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/threadring.txt
+++ /dev/null
@@ -1 +0,0 @@
-498
diff --git a/gcc/testsuite/go.test/test/bench/shootout/timing.log b/gcc/testsuite/go.test/test/bench/shootout/timing.log
deleted file mode 100644
index 4e7d17a..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/timing.log
+++ /dev/null
@@ -1,1254 +0,0 @@
-All tests on r45 or r70
-
-Aug 3 2009
-
-First version of fasta. Translation of fasta.c, fetched from
- http://shootout.alioth.debian.org/u32q/benchmark.php?test=fasta&lang=gpp&id=4
-
-fasta -n 25000000
- gcc -O2 fasta.c 5.98u 0.00s 6.01r
- gccgo -O2 fasta.go 8.82u 0.02s 8.85r
- 6g fasta.go 13.50u 0.02s 13.53r
- 6g -B fata.go 12.99u 0.02s 13.02r
-
-Aug 4 2009
-[added timing.sh]
-
-# myrandom:
-# hand-written optimization of integer division
-# use int32->float conversion
-fasta -n 25000000
- # probably I/O library inefficiencies
- gcc -O2 fasta.c 5.99u 0.00s 6.00r
- gccgo -O2 fasta.go 8.82u 0.02s 8.85r
- gc fasta 10.70u 0.00s 10.77r
- gc_B fasta 10.09u 0.03s 10.12r
-
-reverse-complement < output-of-fasta-25000000
- # we don't know - memory cache behavior?
- gcc -O2 reverse-complement.c 2.04u 0.94s 10.54r
- gccgo -O2 reverse-complement.go 6.54u 0.63s 7.17r
- gc reverse-complement 6.55u 0.70s 7.26r
- gc_B reverse-complement 6.32u 0.70s 7.10r
-
-nbody 50000000
- # math.Sqrt needs to be in assembly; inlining is probably the other 50%
- gcc -O2 nbody.c 21.61u 0.01s 24.80r
- gccgo -O2 nbody.go 118.55u 0.02s 120.32r
- gc nbody 100.84u 0.00s 100.85r
- gc_B nbody 103.33u 0.00s 103.39r
-[
-hacked Sqrt in assembler
- gc nbody 31.97u 0.00s 32.01r
-]
-
-binary-tree 15 # too slow to use 20
- # memory allocation and garbage collection
- gcc -O2 binary-tree.c -lm 0.86u 0.00s 0.87r
- gccgo -O2 binary-tree.go 1.69u 0.46s 2.15r
- gccgo -O2 binary-tree-freelist.go 8.48u 0.00s 8.48r
- gc binary-tree 9.60u 0.01s 9.62r
- gc binary-tree-freelist 0.48u 0.01s 0.50r
-
-August 5, 2009
-
-fannkuch 12
- # bounds checking is half the difference
- # rest might be registerization
- gcc -O2 fannkuch.c 60.09u 0.01s 60.32r
- gccgo -O2 fannkuch.go 64.89u 0.00s 64.92r
- gc fannkuch 124.59u 0.00s 124.67r
- gc_B fannkuch 91.14u 0.00s 91.16r
-
-regex-dna 100000
- # regexp code is slow on trivial regexp
- gcc -O2 regex-dna.c -lpcre 0.92u 0.00s 0.99r
- gc regexp-dna 26.94u 0.18s 28.75r
- gc_B regexp-dna 26.51u 0.09s 26.75r
-
-spectral-norm 5500
- gcc -O2 spectral-norm.c -lm 11.54u 0.00s 11.55r
- gccgo -O2 spectral-norm.go 12.20u 0.00s 12.23r
- gc spectral-norm 50.23u 0.00s 50.36r
- gc_B spectral-norm 49.69u 0.01s 49.83r
- gc spectral-norm-parallel 24.47u 0.03s 11.05r # has shift >>1 not div /2
- [using >>1 instead of /2 : gc gives 24.33u 0.00s 24.33r]
-
-August 6, 2009
-
-k-nucleotide 5000000
- # string maps are slower than glib string maps
- gcc -O2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include k-nucleotide.c -lglib-2.0 k-nucleotide.c: 10.72u 0.01s 10.74r
- gccgo -O2 k-nucleotide.go 21.64u 0.83s 22.78r
- gc k-nucleotide 16.08u 0.06s 16.50r
- gc_B k-nucleotide 17.32u 0.02s 17.37r
-
-mandelbrot 5500
- # floating point code generator should use more registers
- gcc -O2 mandelbrot.c 56.13u 0.02s 56.17r
- gccgo -O2 mandelbrot.go 57.49u 0.01s 57.51r
- gc mandelbrot 74.32u 0.00s 74.35r
- gc_B mandelbrot 74.28u 0.01s 74.31r
-
-meteor 2100
- # we don't know
- gcc -O2 meteor-contest.c 0.10u 0.00s 0.10r
- gccgo -O2 meteor-contest.go 0.12u 0.00s 0.14r
- gc meteor-contest 0.24u 0.00s 0.26r
- gc_B meteor-contest 0.23u 0.00s 0.24r
-
-pidigits 10000
- # bignum is slower than gmp
- gcc -O2 pidigits.c -lgmp 2.60u 0.00s 2.62r
- gc pidigits 77.69u 0.14s 78.18r
- gc_B pidigits 74.26u 0.18s 75.41r
- gc_B pidigits 68.48u 0.20s 69.31r # special case: no bounds checking in bignum
-
-August 7 2009
-
-# New gc does better division by powers of 2. Significant improvements:
-
-spectral-norm 5500
- # floating point code generator should use more registers; possibly inline evalA
- gcc -O2 spectral-norm.c -lm 11.50u 0.00s 11.50r
- gccgo -O2 spectral-norm.go 12.02u 0.00s 12.02r
- gc spectral-norm 23.98u 0.00s 24.00r # new time is 0.48 times old time, 52% faster
- gc_B spectral-norm 23.71u 0.01s 23.72r # ditto
- gc spectral-norm-parallel 24.04u 0.00s 6.26r # /2 put back. note: 4x faster (on r70, idle)
-
-k-nucleotide 1000000
- # string maps are slower than glib string maps
- gcc -O2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include k-nucleotide.c -lglib-2.0 10.82u 0.04s 10.87r
- gccgo -O2 k-nucleotide.go 22.73u 0.89s 23.63r
- gc k-nucleotide 15.97u 0.03s 16.04r
- gc_B k-nucleotide 15.86u 0.06s 15.93r # 8.5% faster, but probably due to weird cache effeccts in previous version
-
-pidigits 10000
- # bignum is slower than gmp
- gcc -O2 pidigits.c -lgmp 2.58u 0.00s 2.58r
- gc pidigits 71.24u 0.04s 71.28r # 8.5% faster
- gc_B pidigits 71.25u 0.03s 71.29r # 4% faster
-
-threadring 50000000
- gcc -O2 threadring.c -lpthread 35.51u 160.21s 199.50r
- gccgo -O2 threadring.go 90.33u 459.95s 448.03r
- gc threadring 33.11u 0.00s 33.14r
- GOMAXPROCS=4 gc threadring 114.48u 226.65s 371.59r
- # change wait code to do <-make(chan int) instead of time.Sleep
- gc threadring 28.41u 0.01s 29.35r
- GOMAXPROCS=4 gc threadring 112.59u 232.83s 384.72r
-
-chameneos 6000000
- gcc -O2 chameneosredux.c -lpthread 18.14u 276.52s 76.93r
- gc chameneosredux 20.19u 0.01s 20.23r
-
-Aug 10 2009
-
-# new 6g with better fp registers, fast div and mod of integers
-# complete set of timings listed. significant changes marked ***
-
-fasta -n 25000000
- # probably I/O library inefficiencies
- gcc -O2 fasta.c 5.96u 0.00s 5.97r
- gc fasta 10.59u 0.01s 10.61r
- gc_B fasta 9.92u 0.02s 9.95r
-
-reverse-complement < output-of-fasta-25000000
- # we don't know - memory cache behavior?
- gcc -O2 reverse-complement.c 1.96u 1.56s 16.23r
- gccgo -O2 reverse-complement.go 6.41u 0.62s 7.05r
- gc reverse-complement 6.46u 0.70s 7.17r
- gc_B reverse-complement 6.22u 0.72s 6.95r
-
-nbody 50000000
- # math.Sqrt needs to be in assembly; inlining is probably the other 50%
- gcc -O2 nbody.c 21.26u 0.01s 21.28r
- gccgo -O2 nbody.go 116.68u 0.07s 116.80r
- gc nbody 86.64u 0.01s 86.68r # -14%
- gc_B nbody 85.72u 0.02s 85.77r # *** -17%
-
-binary-tree 15 # too slow to use 20
- # memory allocation and garbage collection
- gcc -O2 binary-tree.c -lm 0.87u 0.00s 0.87r
- gccgo -O2 binary-tree.go 1.61u 0.47s 2.09r
- gccgo -O2 binary-tree-freelist.go 0.00u 0.00s 0.01r
- gc binary-tree 9.11u 0.01s 9.13r # *** -5%
- gc binary-tree-freelist 0.47u 0.01s 0.48r
-
-fannkuch 12
- # bounds checking is half the difference
- # rest might be registerization
- gcc -O2 fannkuch.c 59.92u 0.00s 59.94r
- gccgo -O2 fannkuch.go 65.54u 0.00s 65.58r
- gc fannkuch 123.98u 0.01s 124.04r
- gc_B fannkuch 90.75u 0.00s 90.78r
-
-regex-dna 100000
- # regexp code is slow on trivial regexp
- gcc -O2 regex-dna.c -lpcre 0.91u 0.00s 0.92r
- gc regex-dna 27.25u 0.02s 27.28r
- gc_B regex-dna 29.51u 0.03s 29.55r
-
-spectral-norm 5500
- # possibly inline evalA
- gcc -O2 spectral-norm.c -lm 11.57u 0.00s 11.57r
- gccgo -O2 spectral-norm.go 12.07u 0.01s 12.08r
- gc spectral-norm 23.99u 0.00s 24.00r
- gc_B spectral-norm 23.73u 0.00s 23.75r
-
-k-nucleotide 1000000
- # string maps are slower than glib string maps
- gcc -O2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include k-nucleotide.c -lglib-2.0 10.63u 0.02s 10.69r
- gccgo -O2 k-nucleotide.go 23.19u 0.91s 24.12r
- gc k-nucleotide 16.73u 0.04s 16.78r # *** +5% (but this one seems to vary by more than that)
- gc_B k-nucleotide 16.46u 0.04s 16.51r # *** +5%
-
-mandelbrot 16000
- gcc -O2 mandelbrot.c 56.16u 0.00s 56.16r
- gccgo -O2 mandelbrot.go 57.41u 0.01s 57.42r
- gc mandelbrot 64.05u 0.02s 64.08r # *** -14%
- gc_B mandelbrot 64.10u 0.02s 64.14r # *** -14%
-
-meteor 2100
- # we don't know
- gcc -O2 meteor-contest.c 0.10u 0.00s 0.10r
- gccgo -O2 meteor-contest.go 0.12u 0.00s 0.12r
- gc meteor-contest 0.18u 0.00s 0.20r # *** -25%
- gc_B meteor-contest 0.17u 0.00s 0.18r # *** -24%
-
-pidigits 10000
- # bignum is slower than gmp
- gcc -O2 pidigits.c -lgmp 2.57u 0.00s 2.57r
- gc pidigits 71.82u 0.04s 71.89r
- gc_B pidigits 71.84u 0.08s 71.98r
-
-threadring 50000000
- gcc -O2 threadring.c -lpthread 30.91u 164.33s 204.57r
- gccgo -O2 threadring.go 87.12u 460.04s 447.61r
- gc threadring 38.55u 0.00s 38.56r # *** +16%
-
-chameneos 6000000
- gcc -O2 chameneosredux.c -lpthread 17.93u 323.65s 88.47r
- gc chameneosredux 21.72u 0.00s 21.73r
-
-August 10 2009
-
-# In-place versions for some bignum operations.
-pidigits 10000
- gcc -O2 pidigits.c -lgmp 2.56u 0.00s 2.57r
- gc pidigits 55.22u 0.04s 55.29r # *** -23%
- gc_B pidigits 55.49u 0.02s 55.60r # *** -23%
-
-September 3 2009
-
-# New 6g inlines slices, has a few other tweaks.
-# Complete rerun. Significant changes marked.
-
-fasta -n 25000000
- # probably I/O library inefficiencies
- gcc -O2 fasta.c 5.96u 0.00s 5.96r
- gc fasta 10.63u 0.02s 10.66r
- gc_B fasta 9.92u 0.01s 9.94r
-
-reverse-complement < output-of-fasta-25000000
- # we don't know - memory cache behavior?
- gcc -O2 reverse-complement.c 1.92u 0.33s 2.93r
- gccgo -O2 reverse-complement.go 6.76u 0.72s 7.58r # +5%
- gc reverse-complement 6.59u 0.70s 7.29r # +2%
- gc_B reverse-complement 5.57u 0.80s 6.37r # -10%
-
-nbody 50000000
- # math.Sqrt needs to be in assembly; inlining is probably the other 50%
- # also loop alignment appears to be critical
- gcc -O2 nbody.c 21.28u 0.00s 21.28r
- gccgo -O2 nbody.go 119.21u 0.00s 119.22r # +2%
- gc nbody 109.72u 0.00s 109.78r # + 28% *****
- gc_B nbody 85.90u 0.00s 85.91r
-
-binary-tree 15 # too slow to use 20
- # memory allocation and garbage collection
- gcc -O2 binary-tree.c -lm 0.86u 0.00s 0.87r
- gccgo -O2 binary-tree.go 1.88u 0.54s 2.42r # +17%
- gccgo -O2 binary-tree-freelist.go 0.01u 0.01s 0.02r
- gc binary-tree 8.94u 0.01s 8.96r # -2%
- gc binary-tree-freelist 0.47u 0.01s 0.48r
-
-fannkuch 12
- # bounds checking is half the difference
- # rest might be registerization
- gcc -O2 fannkuch.c 60.12u 0.00s 60.12r
- gccgo -O2 fannkuch.go 92.62u 0.00s 92.66r # +41% ***
- gc fannkuch 123.90u 0.00s 123.92r
- gc_B fannkuch 89.71u 0.00s 89.74r # -1%
-
-regex-dna 100000
- # regexp code is slow on trivial regexp
- gcc -O2 regex-dna.c -lpcre 0.88u 0.00s 0.88r
- gc regex-dna 25.77u 0.01s 25.79r # -5%
- gc_B regex-dna 26.05u 0.02s 26.09r # -12% ***
-
-spectral-norm 5500
- # possibly inline evalA
- gcc -O2 spectral-norm.c -lm 11.51u 0.00s 11.51r
- gccgo -O2 spectral-norm.go 11.95u 0.00s 11.96r
- gc spectral-norm 24.23u 0.00s 24.23r
- gc_B spectral-norm 23.83u 0.00s 23.84r
-
-k-nucleotide 1000000
- # string maps are slower than glib string maps
- gcc -O2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include k-nucleotide.c -lglib-2.0 10.68u 0.04s 10.72r
- gccgo -O2 k-nucleotide.go 23.03u 0.88s 23.92r
- gc k-nucleotide 15.79u 0.05s 15.85r # -5% (but this one seems to vary by more than that)
- gc_B k-nucleotide 17.88u 0.05s 17.95r # +8% (ditto)
-
-mandelbrot 16000
- gcc -O2 mandelbrot.c 56.17u 0.02s 56.20r
- gccgo -O2 mandelbrot.go 56.74u 0.02s 56.79r # -1%
- gc mandelbrot 63.31u 0.01s 63.35r # -1%
- gc_B mandelbrot 63.29u 0.00s 63.31r # -1%
-
-meteor 2100
- # we don't know
- gcc -O2 meteor-contest.c 0.10u 0.00s 0.10r
- gccgo -O2 meteor-contest.go 0.11u 0.00s 0.12r
- gc meteor-contest 0.18u 0.00s 0.19r
- gc_B meteor-contest 0.17u 0.00s 0.18r
-
-pidigits 10000
- # bignum is slower than gmp
- gcc -O2 pidigits.c -lgmp 2.56u 0.00s 2.57r
- gc pidigits 55.87u 0.03s 55.91r
- gc_B pidigits 55.93u 0.03s 55.99r
-
-# these tests are compared using real time, since they run multiple processors
-# accuracy probably low
-threadring 50000000
- gcc -O2 threadring.c -lpthread 26.31u 164.69s 199.92r # -2%
- gccgo -O2 threadring.go 87.90u 487.26s 472.81r # +6%
- gc threadring 28.89u 0.00s 28.90r # -25% ***
-
-chameneos 6000000
- gcc -O2 chameneosredux.c -lpthread 16.41u 296.91s 81.17r # -8%
- gc chameneosredux 19.97u 0.00s 19.97r # -8%
-
-Sep 22, 2009
-
-# 6g inlines sliceslice in most cases.
-
-fasta -n 25000000
- # probably I/O library inefficiencies
- gc fasta 10.24u 0.00s 10.25r # -4%
- gc_B fasta 9.68u 0.01s 9.69r # -3%
-
-reverse-complement < output-of-fasta-25000000
- # we don't know - memory cache behavior?
- gc reverse-complement 6.67u 0.69s 7.37r # +1%
- gc_B reverse-complement 6.00u 0.64s 6.65r # +7%
-
-nbody -n 50000000
- # math.Sqrt needs to be in assembly; inlining is probably the other 50%
- # also loop alignment appears to be critical
- gc nbody 86.27u 0.00s 86.29r # -21%
- gc_B nbody 104.52u 0.00s 104.54r # +22%
-
-fannkuch 12
- # bounds checking is half the difference
- # rest might be registerization
- gc fannkuch 128.36u 0.00s 128.37r # +4%
- gc_B fannkuch 89.32u 0.00s 89.34r
-
-regex-dna 100000
- # regexp code is slow on trivial regexp
- gc regex-dna 24.82u 0.01s 24.86r # -4%
- gc_B regex-dna 24.55u 0.01s 24.57r # -6%
-
-spectral-norm 5500
- # possibly inline evalA
- gc spectral-norm 24.05u 0.00s 24.07r # -1%
- gc_B spectral-norm 23.60u 0.00s 23.65r # -1%
-
-k-nucleotide 1000000
- # string maps are slower than glib string maps
- gc k-nucleotide 17.84u 0.04s 17.89r # +13% but mysterious variation continues
- gc_B k-nucleotide 15.56u 0.08s 15.65r # -13% (ditto)
-
-mandelbrot 16000
- gc mandelbrot 64.08u 0.01s 64.11r # +1%
- gc_B mandelbrot 64.04u 0.00s 64.05r # +1%
-
-pidigits 10000
- # bignum is slower than gmp
- gc pidigits 58.68u 0.02s 58.72r # +5%
- gc_B pidigits 58.86u 0.05s 58.99r # +5%
-
-# these tests are compared using real time, since they run multiple processors
-# accuracy probably low
-threadring 50000000
- gc threadring 32.70u 0.02s 32.77r # +13%
-
-chameneos 6000000
- gc chameneosredux 26.62u 0.00s 26.63r # +13%
-
-Sep 24, 2009
-
-# Sqrt now in assembler for 6g.
-nbody -n 50000000
- # remember, at least for 6g, alignment of loops may be important
- gcc -O2 nbody.c 21.24u 0.00s 21.25r
- gccgo -O2 nbody.go 121.03u 0.00s 121.04r
- gc nbody 30.26u 0.00s 30.27r # -65% ***
- gc_B nbody 30.20u 0.02s 30.22r # -72% ***
-
-Nov 13 2009
-
-# fix bug in regexp; take performance hit. good regexps will come in time.
-regex-dna 100000
- gcc -O2 regex-dna.c -lpcre 0.92u 0.00s 0.94r
- gc regex-dna 29.78u 0.03s 29.83r
- gc_B regex-dna 32.63u 0.03s 32.74r
-
-Nov 24 2009
-
-# Roger Peppe's rewrite of the benchmark
-chameneos 6000000
- gcc -O2 chameneosredux.c -lpthread 18.00u 303.29s 83.64r
- gc chameneosredux 12.10u 0.00s 12.10r # 2.22X faster
-
-Jan 6, 2010
-
-# Long-overdue update. All numbers included in this complete run.
-# Some programs (e.g. reverse-complement) rewritten for speed.
-# Regular expressions much faster in common cases (although still far behind PCRE)
-# Bignum stuff improved
-# Better (but sometimes slower) locking in channels.
-
-fasta -n 25000000
- gcc -O2 fasta.c 5.99u 0.01s 6.00r
- gc fasta 9.11u 0.00s 9.12r # -11%
- gc_B fasta 8.60u 0.00s 8.62r # +12% ??
-
-reverse-complement < output-of-fasta-25000000
- gcc -O2 reverse-complement.c 2.00u 0.80s 9.54r
-# gccgo -O2 reverse-complement.go 4.57u 0.35s 4.94r # 33% faster
- gc reverse-complement 2.01u 0.38s 2.40r # 3.3X faster
- gc_B reverse-complement 1.88u 0.36s 2.24r # 3.2X faster
-GOGC=off
- gc reverse-complement 2.01u 0.35s 2.37r
- gc_B reverse-complement 1.86u 0.32s 2.19r
-
-nbody -n 50000000
- gcc -O2 nbody.c 21.28u 0.00s 21.31r
- gccgo -O2 nbody.go 80.02u 0.00s 80.05r # 33% faster
- gc nbody 30.13u 0.00s 30.13r
- gc_B nbody 29.89u 0.01s 29.91r
-
-binary-tree 15 # too slow to use 20
- gcc -O2 binary-tree.c -lm 0.86u 0.00s 0.87r
- gccgo -O2 binary-tree.go 4.82u 0.41s 5.24r # 2.5X slower
- gc binary-tree 7.23u 0.01s 7.25r # # -19%
- gc binary-tree-freelist 0.43u 0.00s 0.44r # -9%
-
-fannkuch 12
- gcc -O2 fannkuch.c 60.17u 0.00s 60.17r
- gccgo -O2 fannkuch.go 78.47u 0.01s 78.49r
- gc fannkuch 128.86u 0.00s 128.96r
- gc_B fannkuch 90.17u 0.00s 90.21r
-
-regex-dna 100000
- gcc -O2 regex-dna.c -lpcre 0.90u 0.00s 0.92r
- gc regex-dna 9.48u 0.01s 9.50r # 3.1X faster
- gc_B regex-dna 9.08u 0.00s 9.10r # 3.6X faster
-
-spectral-norm 5500
- gcc -O2 spectral-norm.c -lm 11.48u 0.00s 11.48r
- gccgo -O2 spectral-norm.go 11.68u 0.00s 11.70r
- gc spectral-norm 23.98u 0.00s 23.99r
- gc_B spectral-norm 23.68u 0.00s 23.69r
-
-k-nucleotide 1000000
- gcc -O2 k-nucleotide.c 10.85u 0.04s 10.90r
- gccgo -O2 k-nucleotide.go 25.26u 0.87s 26.14r
- gc k-nucleotide 15.28u 0.06s 15.37r # restored; mysterious variation continues
- gc_B k-nucleotide 15.97u 0.03s 16.00r
-
-mandelbrot 16000
- gcc -O2 mandelbrot.c 56.12u 0.01s 56.15r
- gccgo -O2 mandelbrot.go 56.86u 0.01s 56.89r
- gc mandelbrot 66.05u 0.00s 66.07r # -3%
- gc_B mandelbrot 66.06u 0.00s 66.07r # -3%
-
-meteor 2100
- gcc -O2 meteor-contest.c 0.10u 0.00s 0.10r
- gccgo -O2 meteor-contest.go 0.12u 0.00s 0.12r
- gc meteor-contest 0.17u 0.00s 0.17r
- gc_B meteor-contest 0.15u 0.00s 0.16r
-
-pidigits 10000
- gcc -O2 pidigits.c -lgmp 2.57u 0.00s 2.59r
- gc pidigits 38.27u 0.02s 38.30r # 1.5X faster
- gc_B pidigits 38.27u 0.02s 38.31r # 1.5X faster
-
-threadring 50000000
- gcc -O2 threadring.c 37.11u 170.59s 212.75r
- gccgo -O2 threadring.go 89.67u 447.56s 442.55r # -6.5%
- gc threadring 36.08u 0.04s 36.15r # +10%
-
-chameneos 6000000
- gcc -O2 chameneosredux.c -lpthread 19.02u 331.08s 90.79r
- gc chameneosredux 12.54u 0.00s 12.55r
-
-Oct 19, 2010
-
-# Another long-overdue update. Some of the code is new; parallel versions
-# of some are added. A few significant improvements.
-
-fasta -n 25000000
- gcc -O2 fasta.c 4.92u 0.00s 4.93r
- gccgo -O2 fasta.go 3.31u 0.00s 3.34r # new code
- gc fasta 3.68u 0.00s 3.69r # 2.5X faster with no code
- gc_B fasta 3.68u 0.00s 3.69r # 2.3X faster with no code
-
-reverse-complement < output-of-fasta-25000000
- gcc -O2 reverse-complement.c 1.93u 0.81s 11.24r
- gccgo -O2 reverse-complement.go 1.58u 0.43s 2.04r # first run with new code?
- gc reverse-complement 1.84u 0.34s 2.20r # 10% faster
- gc_B reverse-complement 1.85u 0.32s 2.18r
-
-nbody -n 50000000
- gcc -O2 nbody.c 21.35u 0.00s 21.36r
- gccgo -O2 nbody.go 21.62u 0.00s 21.66r # 3.7X faster - why??
- gc nbody 29.78u 0.00s 29.79r
- gc_B nbody 29.72u 0.00s 29.72r
-
-binary-tree 15 # too slow to use 20
- gcc -O2 binary-tree.c -lm 0.86u 0.00s 0.88r
- gccgo -O2 binary-tree.go 4.05u 0.02s 4.08r # 28% faster
- gccgo -O2 binary-tree-freelist 0.34u 0.08s 0.34r
- gc binary-tree 5.94u 0.00s 5.95r # 20% faster
- gc binary-tree-freelist 0.50u 0.01s 0.54r
-
-fannkuch 12
- gcc -O2 fannkuch.c 60.45u 0.00s 60.45r
- gccgo -O2 fannkuch.go 64.64u 0.00s 64.64r
- gccgo -O2 fannkuch-parallel.go 115.63u 0.00s 31.58r
- gc fannkuch 126.52u 0.04s 126.68r
- gc fannkuch-parallel 238.82u 0.10s 65.93r # GOMAXPROCS=4
- gc_B fannkuch 88.99u 0.00s 89.02r
-
-regex-dna 100000
- gcc -O2 regex-dna.c -lpcre 0.89u 0.00s 0.89r
- gc regex-dna 8.99u 0.02s 9.03r
- gc regex-dna-parallel 8.94u 0.02s 3.68r # GOMAXPROCS=4
- gc_B regex-dna 9.12u 0.00s 9.14r
-
-spectral-norm 5500
- gcc -O2 spectral-norm.c -lm 11.55u 0.00s 11.57r
- gccgo -O2 spectral-norm.go 11.73u 0.00s 11.75r
- gc spectral-norm 23.74u 0.00s 23.79r
- gc_B spectral-norm 24.49u 0.02s 24.54r
-
-k-nucleotide 1000000
- gcc -O2 k-nucleotide.c 11.44u 0.06s 11.50r
- gccgo -O2 k-nucleotide.go 8.65u 0.04s 8.71r
- gccgo -O2 k-nucleotide-parallel.go 8.75u 0.03s 2.97r # set GOMAXPROCS=4
- gc k-nucleotide 14.92u 0.05s 15.01r
- gc k-nucleotide-parallel 16.96u 0.06s 6.53r # set GOMAXPROCS=4
- gc_B k-nucleotide 15.97u 0.03s 16.08r
-
-mandelbrot 16000
- gcc -O2 mandelbrot.c 56.32u 0.00s 56.35r
- gccgo -O2 mandelbrot.go 55.62u 0.02s 55.77r
- gc mandelbrot 64.85u 0.01s 64.94r
- gc_B mandelbrot 65.02u 0.01s 65.14r
-
-meteor 2100
- gcc -O2 meteor-contest.c 0.10u 0.00s 0.10r
- gccgo -O2 meteor-contest.go 0.10u 0.00s 0.11r
- gc meteor-contest 0.17u 0.00s 0.18r
- gc_B meteor-contest 0.16u 0.00s 0.16r
-
-pidigits 10000
- gcc -O2 pidigits.c -lgmp 2.58u 0.00s 2.59r
- gccgo -O2 pidigits.go 14.06u 0.01s 14.09r # first run?
- gc pidigits 8.47u 0.05s 8.55r # 4.5X faster due to package big
- gc_B pidigits 8.33u 0.01s 8.36r # 4.5X faster due to package big
-
-threadring 50000000
- gcc -O2 threadring.c 28.18u 153.19s 186.47r
- gccgo -O2 threadring.go 110.10u 516.48s 515.25r
- gc threadring 40.39u 0.00s 40.40r
-
-chameneos 6000000
- gcc -O2 chameneosredux.c -lpthread 18.20u 301.55s 83.10r
- gccgo -O2 chameneosredux.go 52.22u 324.54s 201.21r
- gc chameneosredux 13.52u 0.00s 13.54r
-
-Dec 14, 2010
-
-# Improved regex code (same algorithm) gets ~30%.
-
-regex-dna 100000
- gcc -O2 regex-dna.c -lpcre 0.77u 0.01s 0.78r
- gc regex-dna 6.80u 0.00s 6.81r
- gc regex-dna-parallel 6.82u 0.01s 2.75r
- gc_B regex-dna 6.69u 0.02s 6.70r
-
-Feb 15, 2011
-
-# Improved GC, still single-threaded but more efficient
-
-fasta -n 25000000
- gcc -O2 fasta.c 3.40u 0.00s 3.40r
- gccgo -O2 fasta.go 3.51u 0.00s 3.50r
- gc fasta 3.66u 0.01s 3.66r
- gc_B fasta 3.66u 0.00s 3.66r
-
-reverse-complement < output-of-fasta-25000000
- gcc -O2 reverse-complement.c 1.86u 1.29s 4.93r
- gccgo -O2 reverse-complement.go 2.18u 0.41s 2.60r
- gc reverse-complement 1.67u 0.48s 2.15r
- gc_B reverse-complement 1.71u 0.45s 2.15r
-
-nbody -n 50000000
- gcc -O2 -lm nbody.c 21.64u 0.00s 21.64r
- gccgo -O2 nbody.go 21.46u 0.00s 21.45r
- gc nbody 29.07u 0.00s 29.06r
- gc_B nbody 31.61u 0.00s 31.61r
-
-binary-tree 15 # too slow to use 20
- gcc -O2 binary-tree.c -lm 0.88u 0.00s 0.87r
- gccgo -O2 binary-tree.go 2.74u 0.07s 2.81r
- gccgo -O2 binary-tree-freelist.go 0.01u 0.00s 0.00r
- gc binary-tree 4.22u 0.02s 4.24r
- gc binary-tree-freelist 0.54u 0.02s 0.55r
-
-fannkuch 12
- gcc -O2 fannkuch.c 57.64u 0.00s 57.64r
- gccgo -O2 fannkuch.go 65.79u 0.00s 65.82r
- gccgo -O2 fannkuch-parallel.go 160.91u 0.02s 43.90r
- gc fannkuch 126.36u 0.03s 126.53r
- gc fannkuch-parallel 175.23u 0.04s 45.49r
- gc_B fannkuch 89.23u 0.00s 89.24r
-
-regex-dna 100000
- gcc -O2 regex-dna.c -lpcre 0.77u 0.01s 0.80r
- gccgo -O2 regex-dna.go 12.38u 0.10s 12.52r
- gccgo -O2 regex-dna-parallel.go 43.96u 4.64s 15.11r
- gc regex-dna 7.03u 0.01s 7.05r
- gc regex-dna-parallel 6.85u 0.05s 2.70r
- gc_B regex-dna 6.87u 0.02s 6.89r
-
-spectral-norm 5500
- gcc -O2 spectral-norm.c -lm 12.29u 0.00s 12.28r
- gccgo -O2 spectral-norm.go 11.79u 0.00s 11.79r
- gc spectral-norm 24.00u 0.02s 24.05r
- gc_B spectral-norm 24.59u 0.01s 24.59r
-
-k-nucleotide 1000000
- gcc -O2 k-nucleotide.c 9.75u 0.07s 9.82r
- gccgo -O2 k-nucleotide.go 8.92u 0.06s 8.98r
- gccgo -O2 k-nucleotide-parallel.go 8.40u 0.04s 2.76r
- gc k-nucleotide 17.01u 0.03s 17.04r
- gc k-nucleotide-parallel 16.51u 0.08s 6.21r
- gc_B k-nucleotide 16.94u 0.08s 17.02r
-
-mandelbrot 16000
- gcc -O2 mandelbrot.c 54.60u 0.00s 54.66r
- gccgo -O2 mandelbrot.go 59.38u 0.00s 59.41r
- gc mandelbrot 64.93u 0.04s 65.08r
- gc_B mandelbrot 64.85u 0.03s 64.92r
-
-meteor 2098
- gcc -O2 meteor-contest.c 0.10u 0.01s 0.10r
- gccgo -O2 meteor-contest.go 0.11u 0.00s 0.11r
- gc meteor-contest 0.18u 0.00s 0.17r
- gc_B meteor-contest 0.17u 0.00s 0.16r
-
-pidigits 10000
- gcc -O2 pidigits.c -lgmp 2.24u 0.00s 2.23r
- gccgo -O2 pidigits.go 14.05u 0.00s 14.06r
- gc pidigits 6.34u 0.05s 6.38r
- gc_B pidigits 6.37u 0.02s 6.38r
-
-threadring 50000000
- gcc -O2 threadring.c 30.50u 258.05s 325.72r
- gccgo -O2 threadring.go 92.87u 748.39s 728.46r
- gc threadring 38.03u 0.01s 38.04r
-
-# Apr 15, 2011
-# Move to new machine, Intel Xeon E5520@2.27GHz.
-# (Was Opteron(tm) Processor 8214 HE)
-
-fasta -n 25000000
-OLD:
- gcc -O2 fasta.c 3.39u 0.04s 3.42r
- gccgo -O2 fasta.go 3.52u 0.00s 3.52r
- gc fasta 3.63u 0.04s 3.67r
- gc_B fasta 3.66u 0.00s 3.66r
-NEW:
- gcc -O2 fasta.c 1.45u 0.02s 1.47r
- gccgo -O2 fasta.go 1.51u 0.01s 1.51r
- gc fasta 2.04u 0.00s 2.04r
- gc_B fasta 2.05u 0.00s 2.04r
-
-reverse-complement < output-of-fasta-25000000
-OLD:
- gcc -O2 reverse-complement.c 1.87u 1.51s 7.02r
- gccgo -O2 reverse-complement.go 1.56u 0.54s 3.37r
- gc reverse-complement 1.73u 0.36s 2.08r
- gc_B reverse-complement 1.75u 0.37s 2.12r
-NEW:
- gcc -O2 reverse-complement.c 1.20u 0.47s 12.96r
- gccgo -O2 reverse-complement.go 0.88u 0.14s 1.01r
- gc reverse-complement 1.13u 0.17s 1.30r
- gc_B reverse-complement 1.11u 0.09s 1.20r
-
-nbody -n 50000000
-OLD:
- gcc -O2 -lm nbody.c 21.90u 0.00s 21.92r
- gccgo -O2 nbody.go 23.12u 0.03s 23.19r
- gc nbody 29.07u 0.00s 29.07r
- gc_B nbody 31.84u 0.00s 31.85r
-NEW:
- gcc -O2 -lm nbody.c 13.01u 0.00s 13.03r
- gccgo -O2 nbody.go 13.35u 0.00s 13.37r
- gc nbody 21.78u 0.00s 21.82r
- gc_B nbody 21.72u 0.00s 21.76r
-
-binary-tree 15 # too slow to use 20
-OLD:
- gcc -O2 binary-tree.c -lm 0.83u 0.02s 0.84r
- gccgo -O2 binary-tree.go 2.61u 0.02s 2.62r
- gccgo -O2 binary-tree-freelist.go 0.32u 0.01s 0.32r
- gc binary-tree 3.93u 0.04s 3.97r
- gc binary-tree-freelist 0.47u 0.03s 0.50r
-NEW:
- gcc -O2 binary-tree.c -lm 0.60u 0.00s 0.59r
- gccgo -O2 binary-tree.go 1.53u 0.00s 1.52r
- gccgo -O2 binary-tree-freelist.go 0.01u 0.00s 0.00r
- gc binary-tree 1.93u 0.02s 1.95r
- gc binary-tree-freelist 0.32u 0.01s 0.32r
-
-fannkuch 12
-OLD:
- gcc -O2 fannkuch.c 57.64u 0.00s 57.64r
- gccgo -O2 fannkuch.go 65.56u 0.01s 65.65r
- gccgo -O2 fannkuch-parallel.go 179.12u 0.00s 49.82r
- gc fannkuch 126.39u 0.00s 126.39r
- gc fannkuch-parallel 172.49u 0.02s 45.44r
- gc_B fannkuch 89.30u 0.00s 89.28r
-NEW:
- gcc -O2 fannkuch.c 45.17u 0.00s 45.26r
- gccgo -O2 fannkuch.go 53.63u 0.00s 53.73r
- gccgo -O2 fannkuch-parallel.go 216.72u 0.00s 58.42r
- gc fannkuch 108.21u 0.00s 108.44r
- gc fannkuch-parallel 227.20u 0.00s 57.27r
- gc_B fannkuch 56.14u 0.00s 56.26r
-
-regex-dna 100000
-OLD:
- gcc -O2 regex-dna.c -lpcre 0.77u 0.01s 0.78r
- gccgo -O2 regex-dna.go 10.15u 0.02s 10.23r
- gccgo -O2 regex-dna-parallel.go 33.81u 3.22s 11.62r
- gc regex-dna 6.52u 0.04s 6.56r
- gc regex-dna-parallel 6.84u 0.03s 2.70r
- gc_B regex-dna 6.83u 0.01s 6.84r
-NEW:
- gcc -O2 regex-dna.c -lpcre 0.47u 0.00s 0.47r
- gccgo -O2 regex-dna.go 6.00u 0.00s 6.00r
- gccgo -O2 regex-dna-parallel.go 44.54u 1.57s 6.51r
- gc regex-dna 5.41u 0.01s 5.42r
- gc regex-dna-parallel 5.62u 0.01s 2.20r
- gc_B regex-dna 5.50u 0.00s 5.50r
-
-spectral-norm 5500
-OLD:
- gcc -O2 spectral-norm.c -lm 12.29u 0.00s 12.28r
- gccgo -O2 spectral-norm.go 11.56u 0.00s 11.55r
- gc spectral-norm 23.98u 0.00s 24.00r
- gc_B spectral-norm 24.62u 0.00s 24.65r
-NEW:
- gcc -O2 spectral-norm.c -lm 15.79u 0.00s 15.82r
- gccgo -O2 spectral-norm.go 15.32u 0.00s 15.35r
- gc spectral-norm 19.62u 0.01s 19.67r
- gc_B spectral-norm 19.62u 0.00s 19.66r
-
-k-nucleotide 1000000
-OLD:
- gcc -O2 k-nucleotide.c 9.82u 0.06s 9.87r
- gccgo -O2 k-nucleotide.go 8.30u 0.02s 8.32r
- gccgo -O2 k-nucleotide-parallel.go 8.84u 0.05s 3.02r
- gc k-nucleotide 15.38u 0.07s 15.44r
- gc k-nucleotide-parallel 16.40u 0.03s 5.93r
- gc_B k-nucleotide 15.19u 0.05s 15.23r
-NEW:
- gcc -O2 -k-nucleotide.c 4.88u 0.03s 4.92r
- gccgo -O2 k-nucleotide.go 5.94u 0.01s 5.96r
- gccgo -O2 k-nucleotide-parallel.go 6.44u 0.03s 1.47r
- gc k-nucleotide 9.61u 0.01s 9.63r
- gc k-nucleotide-parallel 9.70u 0.00s 3.39r
- gc_B k-nucleotide 9.19u 0.03s 9.23r
-
-mandelbrot 16000
-OLD:
- gcc -O2 mandelbrot.c 54.54u 0.00s 54.56r
- gccgo -O2 mandelbrot.go 59.63u 0.03s 59.67r
- gc mandelbrot 64.82u 0.00s 64.83r
- gc_B mandelbrot 64.84u 0.00s 64.91r
-NEW:
- gcc -O2 mandelbrot.c 36.07u 0.01s 36.15r
- gccgo -O2 mandelbrot.go 43.57u 0.00s 43.66r
- gc mandelbrot 60.66u 0.00s 60.79r
- gc_B mandelbrot 60.90u 0.00s 61.03r
-
-meteor 2098
-OLD:
- gcc -O2 meteor-contest.c 0.11u 0.00s 0.10r
- gccgo -O2 meteor-contest.go 0.10u 0.01s 0.10r
- gc meteor-contest 0.18u 0.00s 0.17r
- gc_B meteor-contest 0.17u 0.00s 0.16r
-NEW:
- gcc -O2 meteor-contest.c 0.10u 0.00s 0.09r
- gccgo -O2 meteor-contest.go 0.10u 0.00s 0.09r
- gc meteor-contest 0.14u 0.00s 0.14r
- gc_B meteor-contest 0.13u 0.00s 0.13r
-
-pidigits 10000
-OLD:
- gcc -O2 pidigits.c -lgmp 2.22u 0.00s 2.21r
- gccgo -O2 pidigits.go 13.39u 0.00s 13.40r
- gc pidigits 6.42u 0.04s 6.45r
- gc_B pidigits 6.45u 0.02s 6.47r
-NEW:
- gcc -O2 pidigits.c -lgmp 2.27u 0.00s 2.29r
- gccgo -O2 pidigits.go 9.21u 0.00s 9.22r
- gc pidigits 3.60u 0.00s 3.60r
- gc_B pidigits 3.56u 0.02s 3.58r
-
-threadring 50000000
-OLD:
- gcc -O2 threadring.c -lpthread 34.51u 267.95s 336.12r
- gccgo -O2 threadring.go 103.51u 588.57s 627.16r
- gc threadring 54.68u 0.00s 54.73r
-NEW:
- gcc -O2 threadring.c 32.00u 259.39s 369.74r
- gccgo -O2 threadring.go 133.06u 546.02s 595.33r
- gc threadring 16.75u 0.02s 16.80r
-
-chameneos 6000000
-OLD:
- gcc -O2 chameneosredux.c -lpthread 12.65u 31.02s 13.33r
- gccgo -O2 chameneosredux.go 47.04u 302.84s 252.29r
- gc chameneosredux 14.14u 0.00s 14.14r
-NEW:
- gcc -O2 chameneosredux.c -lpthread 8.05u 63.43s 11.16r
- gccgo -O2 chameneosredux.go 82.95u 304.37s 207.64r
- gc chameneosredux 9.42u 0.00s 9.43r
-
-# May 13, 2011
-# after gc update to inline append when possible - 35% faster
-
-regex-dna 100000
- gc regex-dna 3.94u 0.00s 3.95r
- gc regex-dna-parallel 4.15u 0.01s 1.63r
- gc_B regex-dna 4.01u 0.01s 4.02r
-
-# Aug 4, 2011
-# After various updates to locking code and some runtime changes.
-# Slowdowns believed due to slower (but more correct) memmove.
-
-fannkuch 12
- gccgo -O2 fannkuch.go 51.59u 0.00s 51.69r # -4%
- gccgo -O2 fannkuch-parallel.go 253.17u 0.00s 64.67r # -11%
- gc fannkuch 103.14u 0.00s 103.36r # -5%
- gc fannkuch-parallel 189.63u 0.00s 49.37r # +9%
- gc_B fannkuch 49.19u 0.00s 49.29r # -14%
-
-regex-dna 100000
- gc regex-dna 3.78u 0.00s 3.78r # -43%
- gc regex-dna-parallel 3.84u 0.02s 1.48r # -49%
- gc_B regex-dna 3.62u 0.00s 3.63r # -52%
-
-k-nucleotide 1000000
- gc k-nucleotide 12.23u 0.02s 12.27r # +27%
- gc k-nucleotide-parallel 12.76u 0.02s 4.37r # +29%
- gc_B k-nucleotide 12.18u 0.01s 12.21r # +33%
-
-threadring 50000000
- gc threadring 17.49u 0.00s 17.53r # +4%
-
-chameneos 6000000
- gc chameneosredux 7.61u 0.00s 7.63r # -24%
-
-Aug 9, 2011
-# After custom algorithms for 1- 2- 4- 8-byte scalars.
-
-fannkuch 12
- gc fannkuch-parallel 157.17u 0.00s 41.08r # -17%
-
-k-nucleotide 1000000
- gc k-nucleotide 8.72u 0.03s 8.76r # -39%
- gc k-nucleotide-parallel 8.79u 0.01s 3.14r # -39%
- gc_B k-nucleotide 8.65u 0.03s 8.69r # -39%
-
-pidigits 10000
- gc pidigits 3.71u 0.02s 3.73r # +4%
- gc_B pidigits 3.73u 0.00s 3.73r # +4%
-
-threadring 50000000
- gc threadring 14.51u 0.00s 14.54r # -17%
-
-chameneos 6000000
- gc chameneosredux 7.41u 0.00s 7.42r # -3%
-
-# A complete run at the Go 1 release.
-# Significant changes:
-# - gccgo is now enabled for all tests (goroutines are cheap enough)
-# - threadring and chameneos are 14% faster, probably due to runtime changes
-# - regex-dna 36% faster
-# - fannkuch-parallel (only) slowed down 40%
-# - gccgo on binary-tree-freelist is still optimized to nothing
-# Other changes are modest.
-
-fasta -n 25000000
- gcc -O2 fasta.c 1.45u 0.02s 1.48r
- gccgo -O2 fasta.go 1.46u 0.00s 1.47r
- gc fasta 1.99u 0.01s 2.00r
- gc_B fasta 1.99u 0.01s 2.01r
-
-reverse-complement < output-of-fasta-25000000
- gcc -O2 reverse-complement.c 0.95u 0.48s 4.99r
- gccgo -O2 reverse-complement.go 0.93u 0.16s 1.09r
- gc reverse-complement 1.20u 0.19s 1.39r
- gc_B reverse-complement 1.04u 0.16s 1.20r
-
-nbody -n 50000000
- gcc -O2 -lm nbody.c 13.02u 0.00s 13.05r
- gccgo -O2 nbody.go 14.46u 0.00s 14.49r
- gc nbody 21.79u 0.00s 21.84r
- gc_B nbody 21.74u 0.00s 21.79r
-
-binary-tree 15 # too slow to use 20
- gcc -O2 binary-tree.c -lm 0.60u 0.01s 0.61r
- gccgo -O2 binary-tree.go 1.30u 0.01s 1.32r
- gccgo -O2 binary-tree-freelist.go 0.00u 0.00s 0.00r
- gc binary-tree 1.84u 0.01s 1.86r
- gc binary-tree-freelist 0.33u 0.00s 0.33r
-
-fannkuch 12
- gcc -O2 fannkuch.c 45.24u 0.00s 45.34r
- gccgo -O2 fannkuch.go 59.76u 0.01s 59.90r
- gccgo -O2 fannkuch-parallel.go 218.20u 0.01s 61.60r
- gc fannkuch 103.92u 0.00s 104.16r
- gc fannkuch-parallel 221.61u 0.00s 60.49r
- gc_B fannkuch 53.17u 0.00s 53.30r
-
-regex-dna 100000
- gcc -O2 regex-dna.c -lpcre 0.47u 0.00s 0.48r
- gccgo -O2 regex-dna.go 6.52u 0.00s 6.54r
- gccgo -O2 regex-dna-parallel.go 14.40u 0.73s 4.35r
- gc regex-dna 2.63u 0.02s 2.66r # -36%
- gc regex-dna-parallel 2.87u 0.01s 1.11r
- gc_B regex-dna 2.65u 0.00s 2.66r
-
-spectral-norm 5500
- gcc -O2 spectral-norm.c -lm 15.78u 0.00s 15.82r
- gccgo -O2 spectral-norm.go 15.79u 0.00s 15.83r
- gc spectral-norm 19.76u 0.00s 19.80r
- gc_B spectral-norm 19.73u 0.01s 19.78r
-
-k-nucleotide 1000000
- gcc -O2 k-nucleotide.c 5.59u 0.03s 5.63r
- gccgo -O2 k-nucleotide.go 4.09u 0.03s 4.13r
- gccgo -O2 k-nucleotide-parallel.go 4.50u 0.06s 1.63r
- gc k-nucleotide 9.23u 0.02s 9.27r
- gc k-nucleotide-parallel 9.87u 0.03s 3.55r
- gc_B k-nucleotide 9.20u 0.00s 9.22r
-
-mandelbrot 16000
- gcc -O2 mandelbrot.c 36.09u 0.00s 36.18r
- gccgo -O2 mandelbrot.go 41.69u 0.01s 41.80r
- gc mandelbrot 60.91u 0.02s 61.07r
- gc_B mandelbrot 60.90u 0.00s 61.04r
-
-meteor 2098
- gcc -O2 meteor-contest.c 0.09u 0.00s 0.09r
- gccgo -O2 meteor-contest.go 0.09u 0.00s 0.09r
- gc meteor-contest 0.14u 0.00s 0.15r
- gc_B meteor-contest 0.14u 0.00s 0.14r
-
-pidigits 10000
- gcc -O2 pidigits.c -lgmp 2.27u 0.00s 2.27r
- gccgo -O2 pidigits.go 8.65u 0.00s 8.67r
- gc pidigits 3.70u 0.04s 3.75r
- gc_B pidigits 3.72u 0.02s 3.75r
-
-threadring 50000000
- gcc -O2 threadring.c 40.91u 369.85s 323.31r
- gccgo -O2 threadring.go 26.97u 30.82s 57.93r
- gc threadring 12.81u 0.01s 12.85r # -13%
-
-chameneos 6000000
- gcc -O2 chameneosredux.c -lpthread 9.44u 72.90s 12.65r
- gccgo -O2 chameneosredux.go 7.73u 7.53s 15.30r
- gc chameneosredux 6.51u 0.00s 6.53r # - 14%
-
-# After http://codereview.appspot.com/6248049, moving panicindex
-# calls out of line (putting the likely code into a single path and shortening
-# loops). Significant changes since the last run (note: some are slower for
-# unrelated and as yet undiagnosed reasons):
-
-nbody -n 50000000
- gc nbody 19.10u 0.01s 19.19r # -12%
- gc_B nbody 19.19u 0.00s 19.23r # -12%
-
-binary-tree 15 # too slow to use 20
- gc binary-tree 1.49u 0.01s 1.51r # -19%
-
-fannkuch 12
- gc fannkuch 60.79u 0.00s 60.92r # -41%
- gc fannkuch-parallel 183.51u 0.01s 51.75r # -14%
- gc_B fannkuch 51.68u 0.00s 51.79r # -3%
-
-k-nucleotide 1000000
- gc k-nucleotide 9.74u 0.04s 9.80r # +6%
- gc k-nucleotide-parallel 9.89u 0.05s 3.59r # +1%
- gc_B k-nucleotide 9.39u 0.02s 9.43r # +2%
-
-mandelbrot (much slower, due to unrelated http://codereview.appspot.com/6209077)
- gc mandelbrot 100.98u 0.00s 101.20r # +65%
- gc_B mandelbrot 100.90u 0.01s 101.17r # +65%
-
-meteor 2098
- gc meteor-contest 0.13u 0.00s 0.13r # -13%
- gc_B meteor-contest 0.13u 0.00s 0.13r # -7%
-
-# May 30, 2012.
-# After http://codereview.appspot.com/6261051, restoring old code generated
-# for floating-point constants. Mandelbrot is back to its previous numbers.
-
-mandelbrot 16000
- gcc -O2 mandelbrot.c 36.07u 0.00s 36.16r
- gccgo -O2 mandelbrot.go 41.72u 0.01s 41.90r
- gc mandelbrot 60.62u 0.00s 60.76r
- gc_B mandelbrot 60.68u 0.00s 60.82r
-
-# May 30, 2012.
-# After http://codereview.appspot.com/6248068, better FP code
-# by avoiding MOVSD between registers.
-# Plus some other timing changes that have crept in from other speedups,
-# from garbage collection to Printf.
-
-fasta -n 25000000
- gc fasta 1.76u 0.00s 1.76r # -12%
- gc_B fasta 1.71u 0.00s 1.72r # -12%
-
-nbody -n 50000000
- gc nbody 17.56u 0.00s 17.60r # -8%
- gc_B nbody 17.30u 0.00s 17.34r # -10%
-
-fannkuch 12
- gc fannkuch-parallel 155.92u 0.01s 44.05r # -15%
-
-k-nucleotide 1000000
- gc k-nucleotide 9.22u 0.01s 9.26r # -5%
- gc k-nucleotide-parallel 9.23u 0.03s 3.26r # -9%
- gc_B k-nucleotide 9.22u 0.03s 9.28r # -2%
-
-mandelbrot 16000
- gc mandelbrot 44.80u 0.00s 44.90r # -27%
- gc_B mandelbrot 44.81u 0.00s 44.92r # -26%
-
-pidigits 10000
- gc pidigits 3.51u 0.00s 3.52r # -6%
- gc_B pidigits 3.51u 0.00s 3.52r # -6%
-
-# Aug 28, 2012
-# After some assembler work in package big.
-pidigits 10000
- gc pidigits 2.85u 0.02s 2.88r # -22%
- gc_B pidigits 2.88u 0.01s 2.90r # -21%
-
-# Sep 26, 2012
-# 64-bit ints, plus significantly better floating-point code.
-# Interesting details:
-# Generally something in the 0-10% slower range, some (binary tree) more
-# Floating-point noticeably faster:
-# nbody -25%
-# mandelbrot -37% relative to Go 1.
-# Other:
-# regex-dna +47%
-fasta -n 25000000
- gcc -O2 fasta.c 1.43u 0.03s 1.46r
- gccgo -O2 fasta.go 1.47u 0.00s 1.47r
- gc fasta 1.78u 0.01s 1.80r
- gc_B fasta 1.76u 0.00s 1.76r
-
-reverse-complement < output-of-fasta-25000000
- gcc -O2 reverse-complement.c 1.14u 0.39s 11.19r
- gccgo -O2 reverse-complement.go 0.91u 0.17s 1.09r
- gc reverse-complement 1.12u 0.18s 1.31r
- gc_B reverse-complement 1.12u 0.15s 1.28r
-
-nbody -n 50000000
- gcc -O2 nbody.c -lm 13.02u 0.00s 13.05r
- gccgo -O2 nbody.go 13.90u 0.00s 13.93r
- gc nbody 17.05u 0.00s 17.09r
- gc_B nbody 16.30u 0.00s 16.34r
-
-binary-tree 15 # too slow to use 20
- gcc -O2 binary-tree.c -lm 0.61u 0.00s 0.61r
- gccgo -O2 binary-tree.go 1.24u 0.04s 1.29r
- gccgo -O2 binary-tree-freelist.go 0.21u 0.01s 0.22r
- gc binary-tree 1.93u 0.02s 1.96r
- gc binary-tree-freelist 0.32u 0.00s 0.33r
-
-fannkuch 12
- gcc -O2 fannkuch.c 45.19u 0.00s 45.29r
- gccgo -O2 fannkuch.go 60.32u 0.00s 60.45r
- gccgo -O2 fannkuch-parallel.go 185.59u 0.00s 59.49r
- gc fannkuch 72.14u 0.00s 72.30r
- gc fannkuch-parallel 172.54u 0.00s 43.59r
- gc_B fannkuch 53.55u 0.00s 53.67r
-
-regex-dna 100000
- gcc -O2 regex-dna.c -lpcre 0.47u 0.00s 0.47r
- gccgo -O2 regex-dna.go 6.49u 0.05s 6.56r
- gccgo -O2 regex-dna-parallel.go 14.60u 0.67s 4.42r
- gc regex-dna 3.91u 0.00s 3.92r
- gc regex-dna-parallel 4.01u 0.03s 1.56r
- gc_B regex-dna 3.91u 0.00s 3.92r
-
-spectral-norm 5500
- gcc -O2 spectral-norm.c -lm 15.85u 0.00s 15.89r
- gccgo -O2 spectral-norm.go 15.86u 0.00s 15.89r
- gc spectral-norm 19.72u 0.00s 19.76r
- gc_B spectral-norm 19.68u 0.01s 19.74r
-
-k-nucleotide 1000000
- gcc -O2 k-nucleotide.c -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -lglib-2.0 4.90u 0.01s 4.93r
- gccgo -O2 k-nucleotide.go 4.78u 0.01s 4.80r
- gccgo -O2 k-nucleotide-parallel.go 6.49u 0.02s 2.18r
- gc k-nucleotide 9.05u 0.02s 9.09r
- gc k-nucleotide-parallel 9.27u 0.01s 3.29r
- gc_B k-nucleotide 8.95u 0.03s 9.00r
-
-mandelbrot 16000
- gcc -O2 mandelbrot.c 36.11u 0.00s 36.19r
- gccgo -O2 mandelbrot.go 43.67u 0.00s 43.77r
- gc mandelbrot 38.57u 0.00s 38.66r
- gc_B mandelbrot 38.59u 0.00s 38.68r
-
-meteor 2098
- gcc -O2 meteor-contest.c 0.09u 0.00s 0.09r
- gccgo -O2 meteor-contest.go 0.09u 0.00s 0.09r
- gc meteor-contest 0.13u 0.00s 0.14r
- gc_B meteor-contest 0.12u 0.00s 0.13r
-
-pidigits 10000
- gcc -O2 pidigits.c -lgmp 2.26u 0.00s 2.27r
- gccgo -O2 pidigits.go 9.05u 0.00s 9.07r
- gc pidigits 2.88u 0.02s 2.90r
- gc_B pidigits 2.89u 0.00s 2.90r
-
-threadring 50000000
- gcc -O2 threadring.c -lpthread 37.30u 327.81s 289.28r
- gccgo -O2 threadring.go 42.83u 26.15s 69.14r
- gc threadring 13.00u 0.00s 13.03r
-
-chameneos 6000000
- gcc -O2 chameneosredux.c -lpthread 8.80u 71.67s 12.19r
- gccgo -O2 chameneosredux.go 11.28u 6.68s 18.00r
- gc chameneosredux 6.94u 0.00s 6.96r
-
-# May 23, 2013
-# Go 1.1, which includes precise GC, new scheduler, faster maps.
-# 20%-ish speedups across many benchmarks.
-# gccgo showing significant improvement (even though it's not yet up to Go 1.1)
-#
-# Standouts:
-# fannkuch, regex-dna, k-nucleotide, threadring, chameneos
-
-fasta -n 25000000
- gcc -m64 -O2 fasta.c 1.54u 0.01s 1.55r
- gccgo -O2 fasta.go 1.42u 0.00s 1.43r
- gc fasta 1.50u 0.01s 1.52r # -16%
- gc_B fasta 1.46u 0.00s 1.46r # -17%
-
-reverse-complement < output-of-fasta-25000000
- gcc -m64 -O2 reverse-complement.c 0.87u 0.37s 4.36r
- gccgo -O2 reverse-complement.go 0.77u 0.15s 0.93r # -15%
- gc reverse-complement 0.99u 0.12s 1.12r # -15%
- gc_B reverse-complement 0.85u 0.17s 1.02r # -21%
-
-nbody -n 50000000
- gcc -m64 -O2 nbody.c -lm 13.50u 0.00s 13.53r
- gccgo -O2 nbody.go 13.98u 0.01s 14.02r
- gc nbody 16.63u 0.01s 16.67r
- gc_B nbody 15.74u 0.00s 15.76r
-
-binary-tree 15 # too slow to use 20
- gcc -m64 -O2 binary-tree.c -lm 0.61u 0.00s 0.61r
- gccgo -O2 binary-tree.go 1.11u 0.01s 1.12r # -13%
- gccgo -O2 binary-tree-freelist.go 0.22u 0.01s 0.23r
- gc binary-tree 1.83u 0.02s 1.83r # -7%
- gc binary-tree-freelist 0.32u 0.00s 0.32r
-
-fannkuch 12
- gcc -m64 -O2 fannkuch.c 45.56u 0.00s 45.67r
- gccgo -O2 fannkuch.go 57.71u 0.00s 57.85r # -4%
- gccgo -O2 fannkuch-parallel.go 146.31u 0.00s 37.50r #-37%
- gc fannkuch 70.06u 0.03s 70.17r # -3%
- gc fannkuch-parallel 131.88u 0.06s 33.59r # -23%
- gc_B fannkuch 45.55u 0.02s 45.63r # -15%
-
-regex-dna 100000
- gcc -m64 -O2 regex-dna.c -lpcre 0.44u 0.01s 0.45r
- gccgo -O2 regex-dna.go 5.59u 0.00s 5.61r # -14%
- gccgo -O2 regex-dna-parallel.go 10.85u 0.30s 3.34r # -24%
- gc regex-dna 2.23u 0.01s 2.25r # -43%
- gc regex-dna-parallel 2.35u 0.00s 0.93r # -40%
- gc_B regex-dna 2.24u 0.01s 2.25r # -43%
-
-spectral-norm 5500
- gcc -m64 -O2 spectral-norm.c -lm 14.84u 0.00s 14.88r
- gccgo -O2 spectral-norm.go 15.33u 0.00s 15.37r
- gc spectral-norm 16.75u 0.02s 16.79r # -15%
- gc_B spectral-norm 16.77u 0.01s 16.79r # -15%
-
-k-nucleotide 1000000
- gcc -O2 k-nucleotide.c -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lglib-2.0 4.50u 0.00s 4.52r
- gccgo -O2 k-nucleotide.go 3.72u 0.04s 3.77r # -21%
- gccgo -O2 k-nucleotide-parallel.go 3.88u 0.03s 1.42r # -35%
- gc k-nucleotide 6.32u 0.01s 6.33r # -31%
- gc k-nucleotide-parallel 6.47u 0.05s 2.13r # -33%
- gc_B k-nucleotide 6.45u 0.01s 6.47r # - 28%
-
-mandelbrot 16000
- gcc -m64 -O2 mandelbrot.c 36.03u 0.00s 36.11r
- gccgo -O2 mandelbrot.go 37.61u 0.00s 37.74r # -14%
- gc mandelbrot 38.19u 0.05s 38.29r
- gc_B mandelbrot 38.19u 0.03s 38.26r
-
-meteor 2098
- gcc -m64 -O2 meteor-contest.c 0.08u 0.00s 0.08r
- gccgo -O2 meteor-contest.go 0.09u 0.01s 0.10r
- gc meteor-contest 0.12u 0.00s 0.12r # -15% although perhaps just noise
- gc_B meteor-contest 0.11u 0.00s 0.12r # -8% although perhaps just noise
-
-pidigits 10000
- gcc -m64 -O2 pidigits.c -lgmp 2.27u 0.00s 2.28r
- gccgo -O2 pidigits.go 8.95u 0.02s 8.99r
- gc pidigits 2.88u 0.14s 2.91r
- gc_B pidigits 2.92u 0.10s 2.91r
-
-threadring 50000000
- gcc -m64 -O2 threadring.c -lpthread 14.75u 167.88s 212.23r
- gccgo -O2 threadring.go 36.72u 12.08s 48.91r # -29%
- gc threadring 10.93u 0.01s 10.95r # -16%
-
-chameneos 6000000
- gcc -m64 -O2 chameneosredux.c -lpthread 8.89u 56.62s 9.75r
- gccgo -O2 chameneosredux.go 9.48u 2.48s 11.99r # -33%
- gc chameneosredux 5.80u 0.00s 5.81r # -16%
-
diff --git a/gcc/testsuite/go.test/test/bench/shootout/timing.sh b/gcc/testsuite/go.test/test/bench/shootout/timing.sh
deleted file mode 100755
index 2db895c..0000000
--- a/gcc/testsuite/go.test/test/bench/shootout/timing.sh
+++ /dev/null
@@ -1,219 +0,0 @@
-#!/usr/bin/env bash
-# Copyright 2009 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.
-
-set -e
-
-eval $(go tool dist env)
-O=$GOCHAR
-GC="go tool ${O}g"
-LD="go tool ${O}l"
-
-gccm=""
-case "$O" in
-8)
- gccm=-m32;;
-6)
- gccm=-m64;;
-esac
-
-PATH=.:$PATH
-
-havegccgo=false
-if which gccgo >/dev/null 2>&1
-then
- havegccgo=true
-fi
-
-mode=run
-case X"$1" in
-X-test)
- mode=test
- shift
-esac
-
-gc() {
- $GC $1.go; $LD $1.$O
-}
-
-gc_B() {
- $GC -B $1.go; $LD $1.$O
-}
-
-runonly() {
- if [ $mode = run ]
- then
- "$@"
- fi
-}
-
-run() {
- if [ $mode = test ]
- then
- if echo $1 | grep -q '^gc '
- then
- $1 # compile the program
- program=$(echo $1 | sed 's/gc //')
- shift
- echo $program
- $1 <fasta-1000.out > /tmp/$$
- case $program in
- chameneosredux)
- # exact numbers may vary but non-numbers should match
- grep -v '[0-9]' /tmp/$$ > /tmp/$$x
- grep -v '[0-9]' chameneosredux.txt > /tmp/$$y
- cmp /tmp/$$x /tmp/$$y
- rm -f /tmp/$$ /tmp/$$x /tmp/$$y
- ;;
- *)
- cmp /tmp/$$ $program.txt
- rm -f /tmp/$$
- esac
- fi
- return
- fi
- if ! $havegccgo && echo $1 | grep -q '^gccgo '
- then
- return
- fi
- echo -n ' '$1' '
- $1
- shift
-
- echo $((time -p $* >/dev/null) 2>&1) | awk '{print $4 "u " $6 "s " $2 "r"}'
-}
-
-fasta() {
- runonly echo 'fasta -n 25000000'
- run "gcc $gccm -O2 fasta.c" a.out 25000000
- run 'gccgo -O2 fasta.go' a.out -n 25000000 #commented out until WriteString is in bufio
- run 'gc fasta' $O.out -n 25000000
- run 'gc_B fasta' $O.out -n 25000000
-}
-
-revcomp() {
- runonly gcc -O2 fasta.c
- runonly a.out 25000000 > x
- runonly echo 'reverse-complement < output-of-fasta-25000000'
- run "gcc $gccm -O2 reverse-complement.c" a.out < x
- run 'gccgo -O2 reverse-complement.go' a.out < x
- run 'gc reverse-complement' $O.out < x
- run 'gc_B reverse-complement' $O.out < x
- rm x
-}
-
-nbody() {
- runonly echo 'nbody -n 50000000'
- run "gcc $gccm -O2 nbody.c -lm" a.out 50000000
- run 'gccgo -O2 nbody.go' a.out -n 50000000
- run 'gc nbody' $O.out -n 50000000
- run 'gc_B nbody' $O.out -n 50000000
-}
-
-binarytree() {
- runonly echo 'binary-tree 15 # too slow to use 20'
- run "gcc $gccm -O2 binary-tree.c -lm" a.out 15
- run 'gccgo -O2 binary-tree.go' a.out -n 15
- run 'gccgo -O2 binary-tree-freelist.go' a.out -n 15
- run 'gc binary-tree' $O.out -n 15
- run 'gc binary-tree-freelist' $O.out -n 15
-}
-
-fannkuch() {
- runonly echo 'fannkuch 12'
- run "gcc $gccm -O2 fannkuch.c" a.out 12
- run 'gccgo -O2 fannkuch.go' a.out -n 12
- run 'gccgo -O2 fannkuch-parallel.go' a.out -n 12
- run 'gc fannkuch' $O.out -n 12
- run 'gc fannkuch-parallel' $O.out -n 12
- run 'gc_B fannkuch' $O.out -n 12
-}
-
-regexdna() {
- runonly gcc -O2 fasta.c
- runonly a.out 100000 > x
- runonly echo 'regex-dna 100000'
- run "gcc $gccm -O2 regex-dna.c -lpcre" a.out <x
- run 'gccgo -O2 regex-dna.go' a.out <x
- run 'gccgo -O2 regex-dna-parallel.go' a.out <x
- run 'gc regex-dna' $O.out <x
- run 'gc regex-dna-parallel' $O.out <x
- run 'gc_B regex-dna' $O.out <x
- rm x
-}
-
-spectralnorm() {
- runonly echo 'spectral-norm 5500'
- run "gcc $gccm -O2 spectral-norm.c -lm" a.out 5500
- run 'gccgo -O2 spectral-norm.go' a.out -n 5500
- run 'gc spectral-norm' $O.out -n 5500
- run 'gc_B spectral-norm' $O.out -n 5500
-}
-
-knucleotide() {
- runonly gcc -O2 fasta.c
- runonly a.out 1000000 > x # should be using 25000000
- runonly echo 'k-nucleotide 1000000'
- if [ $mode = run ]; then
- run "gcc -O2 k-nucleotide.c $(pkg-config glib-2.0 --cflags --libs)" a.out <x
- fi
- run 'gccgo -O2 k-nucleotide.go' a.out <x
- run 'gccgo -O2 k-nucleotide-parallel.go' a.out <x
- run 'gc k-nucleotide' $O.out <x
- run 'gc k-nucleotide-parallel' $O.out <x
- run 'gc_B k-nucleotide' $O.out <x
- rm x
-}
-
-mandelbrot() {
- runonly echo 'mandelbrot 16000'
- run "gcc $gccm -O2 mandelbrot.c" a.out 16000
- run 'gccgo -O2 mandelbrot.go' a.out -n 16000
- run 'gc mandelbrot' $O.out -n 16000
- run 'gc_B mandelbrot' $O.out -n 16000
-}
-
-meteor() {
- runonly echo 'meteor 2098'
- run "gcc $gccm -O2 meteor-contest.c" a.out 2098
- run 'gccgo -O2 meteor-contest.go' a.out -n 2098
- run 'gc meteor-contest' $O.out -n 2098
- run 'gc_B meteor-contest' $O.out -n 2098
-}
-
-pidigits() {
- runonly echo 'pidigits 10000'
- run "gcc $gccm -O2 pidigits.c -lgmp" a.out 10000
- run 'gccgo -O2 pidigits.go' a.out -n 10000
- run 'gc pidigits' $O.out -n 10000
- run 'gc_B pidigits' $O.out -n 10000
-}
-
-threadring() {
- runonly echo 'threadring 50000000'
- run "gcc $gccm -O2 threadring.c -lpthread" a.out 50000000
- run 'gccgo -O2 threadring.go' a.out -n 50000000
- run 'gc threadring' $O.out -n 50000000
-}
-
-chameneos() {
- runonly echo 'chameneos 6000000'
- run "gcc $gccm -O2 chameneosredux.c -lpthread" a.out 6000000
- run 'gccgo -O2 chameneosredux.go' a.out 6000000
- run 'gc chameneosredux' $O.out 6000000
-}
-
-case $# in
-0)
- run="fasta revcomp nbody binarytree fannkuch regexdna spectralnorm knucleotide mandelbrot meteor pidigits threadring chameneos"
- ;;
-*)
- run=$*
-esac
-
-for i in $run
-do
- $i
- runonly echo
-done
diff --git a/gcc/testsuite/go.test/test/blank1.go b/gcc/testsuite/go.test/test/blank1.go
index b60f9e1..70e01b1 100644
--- a/gcc/testsuite/go.test/test/blank1.go
+++ b/gcc/testsuite/go.test/test/blank1.go
@@ -4,7 +4,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Test that incorrect uses of the blank identifer are caught.
+// Test that incorrect uses of the blank identifier are caught.
// Does not compile.
package _ // ERROR "invalid package name"
@@ -13,6 +13,10 @@ var t struct {
_ int
}
+func (x int) _() { // ERROR "methods on non-local type"
+ println(x)
+}
+
type T struct {
_ []int
}
diff --git a/gcc/testsuite/go.test/test/bombad.go b/gcc/testsuite/go.test/test/bombad.go
index b894d9b..6b79a98 100644
--- a/gcc/testsuite/go.test/test/bombad.go
+++ b/gcc/testsuite/go.test/test/bombad.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/bounds.go b/gcc/testsuite/go.test/test/bounds.go
index 50f7ad7..aa1d51b 100644
--- a/gcc/testsuite/go.test/test/bounds.go
+++ b/gcc/testsuite/go.test/test/bounds.go
@@ -1,6 +1,6 @@
// errorcheck -0 -m -l
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
@@ -12,23 +12,23 @@ package foo
var (
s []int
- a1 [1]int
- a1k [1000]int
+ a1 [1]int
+ a1k [1000]int
a100k [100000]int
- p1 *[1]int
- p1k *[1000]int
+ p1 *[1]int
+ p1k *[1000]int
p100k *[100000]int
- i int
- ui uint
- i8 int8
- ui8 uint8
- i16 int16
+ i int
+ ui uint
+ i8 int8
+ ui8 uint8
+ i16 int16
ui16 uint16
- i32 int32
+ i32 int32
ui32 uint32
- i64 int64
+ i64 int64
ui64 uint64
)
@@ -61,11 +61,11 @@ func main() {
// Unsigned 8-bit numbers don't need checks for len >= 2⁸.
use(s[ui8])
use(a1[ui8])
- use(a1k[ui8]) // ERROR "index bounds check elided"
- use(a100k[ui8]) // ERROR "index bounds check elided"
+ use(a1k[ui8]) // ERROR "index bounds check elided"
+ use(a100k[ui8]) // ERROR "index bounds check elided"
use(p1[ui8])
- use(p1k[ui8]) // ERROR "index bounds check elided"
- use(p100k[ui8]) // ERROR "index bounds check elided"
+ use(p1k[ui8]) // ERROR "index bounds check elided"
+ use(p100k[ui8]) // ERROR "index bounds check elided"
use(s[i16])
use(a1[i16])
@@ -79,10 +79,10 @@ func main() {
use(s[ui16])
use(a1[ui16])
use(a1k[ui16])
- use(a100k[ui16]) // ERROR "index bounds check elided"
+ use(a100k[ui16]) // ERROR "index bounds check elided"
use(p1[ui16])
use(p1k[ui16])
- use(p100k[ui16]) // ERROR "index bounds check elided"
+ use(p100k[ui16]) // ERROR "index bounds check elided"
use(s[i32])
use(a1[i32])
@@ -128,11 +128,11 @@ func main() {
use(s[ui%999])
use(a1[ui%999])
- use(a1k[ui%999]) // ERROR "index bounds check elided"
- use(a100k[ui%999]) // ERROR "index bounds check elided"
+ use(a1k[ui%999]) // ERROR "index bounds check elided"
+ use(a100k[ui%999]) // ERROR "index bounds check elided"
use(p1[ui%999])
- use(p1k[ui%999]) // ERROR "index bounds check elided"
- use(p100k[ui%999]) // ERROR "index bounds check elided"
+ use(p1k[ui%999]) // ERROR "index bounds check elided"
+ use(p100k[ui%999]) // ERROR "index bounds check elided"
use(s[i%1000])
use(a1[i%1000])
@@ -144,11 +144,11 @@ func main() {
use(s[ui%1000])
use(a1[ui%1000])
- use(a1k[ui%1000]) // ERROR "index bounds check elided"
- use(a100k[ui%1000]) // ERROR "index bounds check elided"
+ use(a1k[ui%1000]) // ERROR "index bounds check elided"
+ use(a100k[ui%1000]) // ERROR "index bounds check elided"
use(p1[ui%1000])
- use(p1k[ui%1000]) // ERROR "index bounds check elided"
- use(p100k[ui%1000]) // ERROR "index bounds check elided"
+ use(p1k[ui%1000]) // ERROR "index bounds check elided"
+ use(p100k[ui%1000]) // ERROR "index bounds check elided"
use(s[i%1001])
use(a1[i%1001])
@@ -161,45 +161,59 @@ func main() {
use(s[ui%1001])
use(a1[ui%1001])
use(a1k[ui%1001])
- use(a100k[ui%1001]) // ERROR "index bounds check elided"
+ use(a100k[ui%1001]) // ERROR "index bounds check elided"
use(p1[ui%1001])
use(p1k[ui%1001])
- use(p100k[ui%1001]) // ERROR "index bounds check elided"
+ use(p100k[ui%1001]) // ERROR "index bounds check elided"
// Bitwise and truncates the maximum value to the mask value.
// The result (for a positive mask) cannot be negative, so elision
// applies to both signed and unsigned indexes.
use(s[i&999])
use(a1[i&999])
- use(a1k[i&999]) // ERROR "index bounds check elided"
- use(a100k[i&999]) // ERROR "index bounds check elided"
+ use(a1k[i&999]) // ERROR "index bounds check elided"
+ use(a100k[i&999]) // ERROR "index bounds check elided"
use(p1[i&999])
- use(p1k[i&999]) // ERROR "index bounds check elided"
- use(p100k[i&999]) // ERROR "index bounds check elided"
+ use(p1k[i&999]) // ERROR "index bounds check elided"
+ use(p100k[i&999]) // ERROR "index bounds check elided"
use(s[ui&999])
use(a1[ui&999])
- use(a1k[ui&999]) // ERROR "index bounds check elided"
- use(a100k[ui&999]) // ERROR "index bounds check elided"
+ use(a1k[ui&999]) // ERROR "index bounds check elided"
+ use(a100k[ui&999]) // ERROR "index bounds check elided"
use(p1[ui&999])
- use(p1k[ui&999]) // ERROR "index bounds check elided"
- use(p100k[ui&999]) // ERROR "index bounds check elided"
+ use(p1k[ui&999]) // ERROR "index bounds check elided"
+ use(p100k[ui&999]) // ERROR "index bounds check elided"
use(s[i&1000])
use(a1[i&1000])
use(a1k[i&1000])
- use(a100k[i&1000]) // ERROR "index bounds check elided"
+ use(a100k[i&1000]) // ERROR "index bounds check elided"
use(p1[i&1000])
use(p1k[i&1000])
- use(p100k[i&1000]) // ERROR "index bounds check elided"
+ use(p100k[i&1000]) // ERROR "index bounds check elided"
use(s[ui&1000])
use(a1[ui&1000])
use(a1k[ui&1000])
- use(a100k[ui&1000]) // ERROR "index bounds check elided"
+ use(a100k[ui&1000]) // ERROR "index bounds check elided"
use(p1[ui&1000])
use(p1k[ui&1000])
- use(p100k[ui&1000]) // ERROR "index bounds check elided"
+ use(p100k[ui&1000]) // ERROR "index bounds check elided"
+
+ use(a1[i&^-1]) // ERROR "index bounds check elided"
+ use(a1[i&^0])
+ use(a1[i&^-2])
+ use(a1[i&^1])
+ use(a1k[i&^-1]) // ERROR "index bounds check elided"
+ use(a1k[i&^0])
+ use(a1k[i&^-2]) // ERROR "index bounds check elided"
+ use(a1k[i&^1])
+ use(a1k[i8&^0])
+ use(a1k[i8&^-128]) // ERROR "index bounds check elided"
+ use(a1k[ui8&^1]) // ERROR "index bounds check elided"
+ use(a1k[ui16&^0xf000])
+ use(a1k[ui16&^0xff00]) // ERROR "index bounds check elided"
// Right shift cuts the effective number of bits in the index,
// but only for unsigned (signed stays negative).
@@ -214,10 +228,10 @@ func main() {
use(s[ui32>>22])
use(a1[ui32>>22])
use(a1k[ui32>>22])
- use(a100k[ui32>>22]) // ERROR "index bounds check elided"
+ use(a100k[ui32>>22]) // ERROR "index bounds check elided"
use(p1[ui32>>22])
use(p1k[ui32>>22])
- use(p100k[ui32>>22]) // ERROR "index bounds check elided"
+ use(p100k[ui32>>22]) // ERROR "index bounds check elided"
use(s[i32>>23])
use(a1[i32>>23])
@@ -229,11 +243,11 @@ func main() {
use(s[ui32>>23])
use(a1[ui32>>23])
- use(a1k[ui32>>23]) // ERROR "index bounds check elided"
- use(a100k[ui32>>23]) // ERROR "index bounds check elided"
+ use(a1k[ui32>>23]) // ERROR "index bounds check elided"
+ use(a100k[ui32>>23]) // ERROR "index bounds check elided"
use(p1[ui32>>23])
- use(p1k[ui32>>23]) // ERROR "index bounds check elided"
- use(p100k[ui32>>23]) // ERROR "index bounds check elided"
+ use(p1k[ui32>>23]) // ERROR "index bounds check elided"
+ use(p100k[ui32>>23]) // ERROR "index bounds check elided"
// Division cuts the range like right shift does.
use(s[i/1e6])
@@ -263,7 +277,7 @@ func main() {
use(p1[ui/1e7])
}
-var sum int
+var sum int
func use(x int) {
sum += x
diff --git a/gcc/testsuite/go.test/test/bugs/bug395.go b/gcc/testsuite/go.test/test/bugs/bug395.go
deleted file mode 100644
index 4632dcd..0000000
--- a/gcc/testsuite/go.test/test/bugs/bug395.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// echo bug395 is broken # takes 90+ seconds to break
-// # $G $D/$F.go || echo bug395
-
-// NOTE: This test is not run by 'run.go' and so not run by all.bash.
-// To run this test you must use the ./run shell script.
-
-// Copyright 2011 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.
-
-// Issue 1909
-// Would OOM due to exponential recursion on Foo's expanded methodset in nodefmt
-package test
-
-type Foo interface {
- Bar() interface {
- Foo
- }
- Baz() interface {
- Foo
- }
- Bug() interface {
- Foo
- }
-}
diff --git a/gcc/testsuite/go.test/test/bugs/placeholder b/gcc/testsuite/go.test/test/bugs/placeholder
deleted file mode 100644
index b816d34..0000000
--- a/gcc/testsuite/go.test/test/bugs/placeholder
+++ /dev/null
@@ -1,2 +0,0 @@
-This file keeps Mercurial from deleting the directory
-when there are no known bugs.
diff --git a/gcc/testsuite/go.test/test/chan/doubleselect.go b/gcc/testsuite/go.test/test/chan/doubleselect.go
index 6be3faf..ff69dbe 100644
--- a/gcc/testsuite/go.test/test/chan/doubleselect.go
+++ b/gcc/testsuite/go.test/test/chan/doubleselect.go
@@ -61,6 +61,7 @@ func recver(in <-chan int) {
func main() {
runtime.GOMAXPROCS(2)
+ flag.Parse()
c1 := make(chan int)
c2 := make(chan int)
c3 := make(chan int)
diff --git a/gcc/testsuite/go.test/test/chan/fifo.go b/gcc/testsuite/go.test/test/chan/fifo.go
index 70d20b3..0001bcf 100644
--- a/gcc/testsuite/go.test/test/chan/fifo.go
+++ b/gcc/testsuite/go.test/test/chan/fifo.go
@@ -54,4 +54,3 @@ func main() {
AsynchFifo()
SynchFifo()
}
-
diff --git a/gcc/testsuite/go.test/test/chan/perm.go b/gcc/testsuite/go.test/test/chan/perm.go
index 7e152c5..0c96d92 100644
--- a/gcc/testsuite/go.test/test/chan/perm.go
+++ b/gcc/testsuite/go.test/test/chan/perm.go
@@ -24,19 +24,23 @@ func main() {
cr = cs // ERROR "illegal types|incompatible|cannot"
cs = cr // ERROR "illegal types|incompatible|cannot"
- c <- 0 // ok
- <-c // ok
- x, ok := <-c // ok
+ var n int
+ <-n // ERROR "receive from non-chan|expected channel"
+ n <- 2 // ERROR "send to non-chan|must be channel"
+
+ c <- 0 // ok
+ <-c // ok
+ x, ok := <-c // ok
_, _ = x, ok
- cr <- 0 // ERROR "send"
- <-cr // ok
- x, ok = <-cr // ok
+ cr <- 0 // ERROR "send"
+ <-cr // ok
+ x, ok = <-cr // ok
_, _ = x, ok
- cs <- 0 // ok
- <-cs // ERROR "receive"
- x, ok = <-cs // ERROR "receive"
+ cs <- 0 // ok
+ <-cs // ERROR "receive"
+ x, ok = <-cs // ERROR "receive"
_, _ = x, ok
select {
@@ -53,10 +57,14 @@ func main() {
_ = x
}
- for _ = range cs {// ERROR "receive"
+ for _ = range cs { // ERROR "receive"
+ }
+
+ for range cs { // ERROR "receive"
}
close(c)
close(cs)
- close(cr) // ERROR "receive"
+ close(cr) // ERROR "receive"
+ close(n) // ERROR "invalid operation.*non-chan type|must be channel"
}
diff --git a/gcc/testsuite/go.test/test/chan/powser1.go b/gcc/testsuite/go.test/test/chan/powser1.go
index 6bf2a91..e999dde 100644
--- a/gcc/testsuite/go.test/test/chan/powser1.go
+++ b/gcc/testsuite/go.test/test/chan/powser1.go
@@ -11,18 +11,18 @@
// coefficients. A denominator of zero signifies the end.
// Original code in Newsqueak by Doug McIlroy.
// See Squinting at Power Series by Doug McIlroy,
-// http://www.cs.bell-labs.com/who/rsc/thread/squint.pdf
+// https://swtch.com/~rsc/thread/squint.pdf
package main
import "os"
-type rat struct {
- num, den int64 // numerator, denominator
+type rat struct {
+ num, den int64 // numerator, denominator
}
func (u rat) pr() {
- if u.den==1 {
+ if u.den == 1 {
print(u.num)
} else {
print(u.num, "/", u.den)
@@ -35,12 +35,12 @@ func (u rat) eq(c rat) bool {
}
type dch struct {
- req chan int
- dat chan rat
+ req chan int
+ dat chan rat
nam int
}
-type dch2 [2] *dch
+type dch2 [2]*dch
var chnames string
var chnameserial int
@@ -77,17 +77,17 @@ func mkdch2() *dch2 {
// a signal on the release-wait channel tells the next newer
// generation to begin servicing out[1].
-func dosplit(in *dch, out *dch2, wait chan int ) {
- both := false // do not service both channels
+func dosplit(in *dch, out *dch2, wait chan int) {
+ both := false // do not service both channels
select {
case <-out[0].req:
-
+
case <-wait:
both = true
select {
case <-out[0].req:
-
+
case <-out[1].req:
out[0], out[1] = out[1], out[0]
}
@@ -95,7 +95,7 @@ func dosplit(in *dch, out *dch2, wait chan int ) {
seqno++
in.req <- seqno
- release := make(chan int)
+ release := make(chan int)
go dosplit(in, out, release)
dat := <-in.dat
out[0].dat <- dat
@@ -128,17 +128,19 @@ func get(in *dch) rat {
func getn(in []*dch) []rat {
n := len(in)
- if n != 2 { panic("bad n in getn") }
- req := new([2] chan int)
- dat := new([2] chan rat)
+ if n != 2 {
+ panic("bad n in getn")
+ }
+ req := new([2]chan int)
+ dat := new([2]chan rat)
out := make([]rat, 2)
var i int
var it rat
- for i=0; i<n; i++ {
+ for i = 0; i < n; i++ {
req[i] = in[i].req
dat[i] = nil
}
- for n=2*n; n>0; n-- {
+ for n = 2 * n; n > 0; n-- {
seqno++
select {
@@ -178,8 +180,8 @@ func repeat(dat rat, out *dch) {
}
}
-type PS *dch // power series
-type PS2 *[2] PS // pair of power series
+type PS *dch // power series
+type PS2 *[2]PS // pair of power series
var Ones PS
var Twos PS
@@ -200,23 +202,27 @@ func mkPS2() *dch2 {
// Integer gcd; needed for rational arithmetic
-func gcd (u, v int64) int64 {
- if u < 0 { return gcd(-u, v) }
- if u == 0 { return v }
+func gcd(u, v int64) int64 {
+ if u < 0 {
+ return gcd(-u, v)
+ }
+ if u == 0 {
+ return v
+ }
return gcd(v%u, u)
}
// Make a rational from two ints and from one int
func i2tor(u, v int64) rat {
- g := gcd(u,v)
+ g := gcd(u, v)
var r rat
if v > 0 {
- r.num = u/g
- r.den = v/g
+ r.num = u / g
+ r.den = v / g
} else {
- r.num = -u/g
- r.den = -v/g
+ r.num = -u / g
+ r.den = -v / g
}
return r
}
@@ -228,29 +234,30 @@ func itor(u int64) rat {
var zero rat
var one rat
-
// End mark and end test
var finis rat
func end(u rat) int64 {
- if u.den==0 { return 1 }
+ if u.den == 0 {
+ return 1
+ }
return 0
}
// Operations on rationals
func add(u, v rat) rat {
- g := gcd(u.den,v.den)
- return i2tor(u.num*(v.den/g)+v.num*(u.den/g),u.den*(v.den/g))
+ g := gcd(u.den, v.den)
+ return i2tor(u.num*(v.den/g)+v.num*(u.den/g), u.den*(v.den/g))
}
func mul(u, v rat) rat {
- g1 := gcd(u.num,v.den)
- g2 := gcd(u.den,v.num)
+ g1 := gcd(u.num, v.den)
+ g2 := gcd(u.den, v.num)
var r rat
- r.num = (u.num/g1)*(v.num/g2)
- r.den = (u.den/g2)*(v.den/g1)
+ r.num = (u.num / g1) * (v.num / g2)
+ r.den = (u.den / g2) * (v.den / g1)
return r
}
@@ -262,23 +269,25 @@ func sub(u, v rat) rat {
return add(u, neg(v))
}
-func inv(u rat) rat { // invert a rat
- if u.num == 0 { panic("zero divide in inv") }
+func inv(u rat) rat { // invert a rat
+ if u.num == 0 {
+ panic("zero divide in inv")
+ }
return i2tor(u.den, u.num)
}
// print eval in floating point of PS at x=c to n terms
func evaln(c rat, U PS, n int) {
xn := float64(1)
- x := float64(c.num)/float64(c.den)
+ x := float64(c.num) / float64(c.den)
val := float64(0)
- for i:=0; i<n; i++ {
+ for i := 0; i < n; i++ {
u := get(U)
if end(u) != 0 {
break
}
- val = val + x * float64(u.num)/float64(u.den)
- xn = xn*x
+ val = val + x*float64(u.num)/float64(u.den)
+ xn = xn * x
}
print(val, "\n")
}
@@ -286,7 +295,7 @@ func evaln(c rat, U PS, n int) {
// Print n terms of a power series
func printn(U PS, n int) {
done := false
- for ; !done && n>0; n-- {
+ for ; !done && n > 0; n-- {
u := get(U)
if end(u) != 0 {
done = true
@@ -299,10 +308,14 @@ func printn(U PS, n int) {
// Evaluate n terms of power series U at x=c
func eval(c rat, U PS, n int) rat {
- if n==0 { return zero }
+ if n == 0 {
+ return zero
+ }
y := get(U)
- if end(y) != 0 { return zero }
- return add(y,mul(c,eval(c,U,n-1)))
+ if end(y) != 0 {
+ return zero
+ }
+ return add(y, mul(c, eval(c, U, n-1)))
}
// Power-series constructors return channels on which power
@@ -313,7 +326,7 @@ func eval(c rat, U PS, n int) rat {
func Split(U PS) *dch2 {
UU := mkdch2()
- go split(U,UU)
+ go split(U, UU)
return UU
}
@@ -324,16 +337,16 @@ func Add(U, V PS) PS {
var uv []rat
for {
<-Z.req
- uv = get2(U,V)
- switch end(uv[0])+2*end(uv[1]) {
+ uv = get2(U, V)
+ switch end(uv[0]) + 2*end(uv[1]) {
case 0:
Z.dat <- add(uv[0], uv[1])
case 1:
Z.dat <- uv[1]
- copy(V,Z)
+ copy(V, Z)
case 2:
Z.dat <- uv[0]
- copy(U,Z)
+ copy(U, Z)
case 3:
Z.dat <- finis
}
@@ -343,7 +356,7 @@ func Add(U, V PS) PS {
}
// Multiply a power series by a constant
-func Cmul(c rat,U PS) PS {
+func Cmul(c rat, U PS) PS {
Z := mkPS()
go func() {
done := false
@@ -353,7 +366,7 @@ func Cmul(c rat,U PS) PS {
if end(u) != 0 {
done = true
} else {
- Z.dat <- mul(c,u)
+ Z.dat <- mul(c, u)
}
}
Z.dat <- finis
@@ -372,8 +385,10 @@ func Sub(U, V PS) PS {
func Monmul(U PS, n int) PS {
Z := mkPS()
go func() {
- for ; n>0; n-- { put(zero,Z) }
- copy(U,Z)
+ for ; n > 0; n-- {
+ put(zero, Z)
+ }
+ copy(U, Z)
}()
return Z
}
@@ -381,25 +396,27 @@ func Monmul(U PS, n int) PS {
// Multiply by x
func Xmul(U PS) PS {
- return Monmul(U,1)
+ return Monmul(U, 1)
}
func Rep(c rat) PS {
Z := mkPS()
- go repeat(c,Z)
+ go repeat(c, Z)
return Z
}
// Monomial c*x^n
func Mon(c rat, n int) PS {
- Z:=mkPS()
+ Z := mkPS()
go func() {
- if(c.num!=0) {
- for ; n>0; n=n-1 { put(zero,Z) }
- put(c,Z)
+ if c.num != 0 {
+ for ; n > 0; n = n - 1 {
+ put(zero, Z)
+ }
+ put(c, Z)
}
- put(finis,Z)
+ put(finis, Z)
}()
return Z
}
@@ -407,8 +424,8 @@ func Mon(c rat, n int) PS {
func Shift(c rat, U PS) PS {
Z := mkPS()
go func() {
- put(c,Z)
- copy(U,Z)
+ put(c, Z)
+ copy(U, Z)
}()
return Z
}
@@ -440,20 +457,20 @@ func Poly(a []rat) PS {
// then UV = u*v + x*(u*VV+v*UU) + x*x*UU*VV
func Mul(U, V PS) PS {
- Z:=mkPS()
+ Z := mkPS()
go func() {
<-Z.req
- uv := get2(U,V)
- if end(uv[0])!=0 || end(uv[1]) != 0 {
+ uv := get2(U, V)
+ if end(uv[0]) != 0 || end(uv[1]) != 0 {
Z.dat <- finis
} else {
- Z.dat <- mul(uv[0],uv[1])
+ Z.dat <- mul(uv[0], uv[1])
UU := Split(U)
VV := Split(V)
- W := Add(Cmul(uv[0],VV[0]),Cmul(uv[1],UU[0]))
+ W := Add(Cmul(uv[0], VV[0]), Cmul(uv[1], UU[0]))
<-Z.req
Z.dat <- get(W)
- copy(Add(W,Mul(UU[1],VV[1])),Z)
+ copy(Add(W, Mul(UU[1], VV[1])), Z)
}
}()
return Z
@@ -462,18 +479,18 @@ func Mul(U, V PS) PS {
// Differentiate
func Diff(U PS) PS {
- Z:=mkPS()
+ Z := mkPS()
go func() {
<-Z.req
u := get(U)
if end(u) == 0 {
- done:=false
- for i:=1; !done; i++ {
+ done := false
+ for i := 1; !done; i++ {
u = get(U)
if end(u) != 0 {
done = true
} else {
- Z.dat <- mul(itor(int64(i)),u)
+ Z.dat <- mul(itor(int64(i)), u)
<-Z.req
}
}
@@ -484,16 +501,18 @@ func Diff(U PS) PS {
}
// Integrate, with const of integration
-func Integ(c rat,U PS) PS {
- Z:=mkPS()
+func Integ(c rat, U PS) PS {
+ Z := mkPS()
go func() {
- put(c,Z)
- done:=false
- for i:=1; !done; i++ {
+ put(c, Z)
+ done := false
+ for i := 1; !done; i++ {
<-Z.req
u := get(U)
- if end(u) != 0 { done= true }
- Z.dat <- mul(i2tor(1,int64(i)),u)
+ if end(u) != 0 {
+ done = true
+ }
+ Z.dat <- mul(i2tor(1, int64(i)), u)
}
Z.dat <- finis
}()
@@ -503,17 +522,17 @@ func Integ(c rat,U PS) PS {
// Binomial theorem (1+x)^c
func Binom(c rat) PS {
- Z:=mkPS()
+ Z := mkPS()
go func() {
n := 1
t := itor(1)
- for c.num!=0 {
- put(t,Z)
- t = mul(mul(t,c),i2tor(1,int64(n)))
- c = sub(c,one)
+ for c.num != 0 {
+ put(t, Z)
+ t = mul(mul(t, c), i2tor(1, int64(n)))
+ c = sub(c, one)
n++
}
- put(finis,Z)
+ put(finis, Z)
}()
return Z
}
@@ -527,14 +546,14 @@ func Binom(c rat) PS {
// ZZ = -UU*(z+x*ZZ)/u
func Recip(U PS) PS {
- Z:=mkPS()
+ Z := mkPS()
go func() {
- ZZ:=mkPS2()
+ ZZ := mkPS2()
<-Z.req
z := inv(get(U))
Z.dat <- z
- split(Mul(Cmul(neg(z),U),Shift(z,ZZ[0])),ZZ)
- copy(ZZ[1],Z)
+ split(Mul(Cmul(neg(z), U), Shift(z, ZZ[0])), ZZ)
+ copy(ZZ[1], Z)
}()
return Z
}
@@ -548,7 +567,7 @@ func Recip(U PS) PS {
func Exp(U PS) PS {
ZZ := mkPS2()
- split(Integ(one,Mul(ZZ[0],Diff(U))),ZZ)
+ split(Integ(one, Mul(ZZ[0], Diff(U))), ZZ)
return ZZ[1]
}
@@ -559,7 +578,7 @@ func Exp(U PS) PS {
// bug: a nonzero constant term is ignored
func Subst(U, V PS) PS {
- Z:= mkPS()
+ Z := mkPS()
go func() {
VV := Split(V)
<-Z.req
@@ -567,20 +586,20 @@ func Subst(U, V PS) PS {
Z.dat <- u
if end(u) == 0 {
if end(get(VV[0])) != 0 {
- put(finis,Z)
+ put(finis, Z)
} else {
- copy(Mul(VV[0],Subst(U,VV[1])),Z)
+ copy(Mul(VV[0], Subst(U, VV[1])), Z)
}
}
}()
return Z
}
-// Monomial Substition: U(c x^n)
+// Monomial Substitution: U(c x^n)
// Each Ui is multiplied by c^i and followed by n-1 zeros
func MonSubst(U PS, c0 rat, n int) PS {
- Z:= mkPS()
+ Z := mkPS()
go func() {
c := one
for {
@@ -601,14 +620,13 @@ func MonSubst(U PS, c0 rat, n int) PS {
return Z
}
-
func Init() {
chnameserial = -1
seqno = 0
chnames = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
zero = itor(0)
one = itor(1)
- finis = i2tor(1,0)
+ finis = i2tor(1, 0)
Ones = Rep(one)
Twos = Rep(itor(2))
}
@@ -627,7 +645,8 @@ func check(U PS, c rat, count int, str string) {
}
}
-const N=10
+const N = 10
+
func checka(U PS, a []rat, str string) {
for i := 0; i < N; i++ {
check(U, a[i], 1, str)
@@ -636,53 +655,64 @@ func checka(U PS, a []rat, str string) {
func main() {
Init()
- if len(os.Args) > 1 { // print
- print("Ones: "); printn(Ones, 10)
- print("Twos: "); printn(Twos, 10)
- print("Add: "); printn(Add(Ones, Twos), 10)
- print("Diff: "); printn(Diff(Ones), 10)
- print("Integ: "); printn(Integ(zero, Ones), 10)
- print("CMul: "); printn(Cmul(neg(one), Ones), 10)
- print("Sub: "); printn(Sub(Ones, Twos), 10)
- print("Mul: "); printn(Mul(Ones, Ones), 10)
- print("Exp: "); printn(Exp(Ones), 15)
- print("MonSubst: "); printn(MonSubst(Ones, neg(one), 2), 10)
- print("ATan: "); printn(Integ(zero, MonSubst(Ones, neg(one), 2)), 10)
- } else { // test
+ if len(os.Args) > 1 { // print
+ print("Ones: ")
+ printn(Ones, 10)
+ print("Twos: ")
+ printn(Twos, 10)
+ print("Add: ")
+ printn(Add(Ones, Twos), 10)
+ print("Diff: ")
+ printn(Diff(Ones), 10)
+ print("Integ: ")
+ printn(Integ(zero, Ones), 10)
+ print("CMul: ")
+ printn(Cmul(neg(one), Ones), 10)
+ print("Sub: ")
+ printn(Sub(Ones, Twos), 10)
+ print("Mul: ")
+ printn(Mul(Ones, Ones), 10)
+ print("Exp: ")
+ printn(Exp(Ones), 15)
+ print("MonSubst: ")
+ printn(MonSubst(Ones, neg(one), 2), 10)
+ print("ATan: ")
+ printn(Integ(zero, MonSubst(Ones, neg(one), 2)), 10)
+ } else { // test
check(Ones, one, 5, "Ones")
- check(Add(Ones, Ones), itor(2), 0, "Add Ones Ones") // 1 1 1 1 1
+ check(Add(Ones, Ones), itor(2), 0, "Add Ones Ones") // 1 1 1 1 1
check(Add(Ones, Twos), itor(3), 0, "Add Ones Twos") // 3 3 3 3 3
a := make([]rat, N)
d := Diff(Ones)
- for i:=0; i < N; i++ {
- a[i] = itor(int64(i+1))
+ for i := 0; i < N; i++ {
+ a[i] = itor(int64(i + 1))
}
- checka(d, a, "Diff") // 1 2 3 4 5
+ checka(d, a, "Diff") // 1 2 3 4 5
in := Integ(zero, Ones)
- a[0] = zero // integration constant
- for i:=1; i < N; i++ {
+ a[0] = zero // integration constant
+ for i := 1; i < N; i++ {
a[i] = i2tor(1, int64(i))
}
- checka(in, a, "Integ") // 0 1 1/2 1/3 1/4 1/5
- check(Cmul(neg(one), Twos), itor(-2), 10, "CMul") // -1 -1 -1 -1 -1
- check(Sub(Ones, Twos), itor(-1), 0, "Sub Ones Twos") // -1 -1 -1 -1 -1
+ checka(in, a, "Integ") // 0 1 1/2 1/3 1/4 1/5
+ check(Cmul(neg(one), Twos), itor(-2), 10, "CMul") // -1 -1 -1 -1 -1
+ check(Sub(Ones, Twos), itor(-1), 0, "Sub Ones Twos") // -1 -1 -1 -1 -1
m := Mul(Ones, Ones)
- for i:=0; i < N; i++ {
- a[i] = itor(int64(i+1))
+ for i := 0; i < N; i++ {
+ a[i] = itor(int64(i + 1))
}
- checka(m, a, "Mul") // 1 2 3 4 5
+ checka(m, a, "Mul") // 1 2 3 4 5
e := Exp(Ones)
a[0] = itor(1)
a[1] = itor(1)
- a[2] = i2tor(3,2)
- a[3] = i2tor(13,6)
- a[4] = i2tor(73,24)
- a[5] = i2tor(167,40)
- a[6] = i2tor(4051,720)
- a[7] = i2tor(37633,5040)
- a[8] = i2tor(43817,4480)
- a[9] = i2tor(4596553,362880)
- checka(e, a, "Exp") // 1 1 3/2 13/6 73/24
+ a[2] = i2tor(3, 2)
+ a[3] = i2tor(13, 6)
+ a[4] = i2tor(73, 24)
+ a[5] = i2tor(167, 40)
+ a[6] = i2tor(4051, 720)
+ a[7] = i2tor(37633, 5040)
+ a[8] = i2tor(43817, 4480)
+ a[9] = i2tor(4596553, 362880)
+ checka(e, a, "Exp") // 1 1 3/2 13/6 73/24
at := Integ(zero, MonSubst(Ones, neg(one), 2))
for c, i := 1, 0; i < N; i++ {
if i%2 == 0 {
@@ -692,20 +722,20 @@ func main() {
c *= -1
}
}
- checka(at, a, "ATan") // 0 -1 0 -1/3 0 -1/5
-/*
- t := Revert(Integ(zero, MonSubst(Ones, neg(one), 2)))
- a[0] = zero
- a[1] = itor(1)
- a[2] = zero
- a[3] = i2tor(1,3)
- a[4] = zero
- a[5] = i2tor(2,15)
- a[6] = zero
- a[7] = i2tor(17,315)
- a[8] = zero
- a[9] = i2tor(62,2835)
- checka(t, a, "Tan") // 0 1 0 1/3 0 2/15
-*/
+ checka(at, a, "ATan") // 0 -1 0 -1/3 0 -1/5
+ /*
+ t := Revert(Integ(zero, MonSubst(Ones, neg(one), 2)))
+ a[0] = zero
+ a[1] = itor(1)
+ a[2] = zero
+ a[3] = i2tor(1,3)
+ a[4] = zero
+ a[5] = i2tor(2,15)
+ a[6] = zero
+ a[7] = i2tor(17,315)
+ a[8] = zero
+ a[9] = i2tor(62,2835)
+ checka(t, a, "Tan") // 0 1 0 1/3 0 2/15
+ */
}
}
diff --git a/gcc/testsuite/go.test/test/chan/powser2.go b/gcc/testsuite/go.test/test/chan/powser2.go
index 33abd5c..72cbba8 100644
--- a/gcc/testsuite/go.test/test/chan/powser2.go
+++ b/gcc/testsuite/go.test/test/chan/powser2.go
@@ -15,14 +15,14 @@
// coefficients. A denominator of zero signifies the end.
// Original code in Newsqueak by Doug McIlroy.
// See Squinting at Power Series by Doug McIlroy,
-// http://www.cs.bell-labs.com/who/rsc/thread/squint.pdf
+// https://swtch.com/~rsc/thread/squint.pdf
package main
import "os"
-type rat struct {
- num, den int64 // numerator, denominator
+type rat struct {
+ num, den int64 // numerator, denominator
}
type item interface {
@@ -30,8 +30,8 @@ type item interface {
eq(c item) bool
}
-func (u *rat) pr(){
- if u.den==1 {
+func (u *rat) pr() {
+ if u.den == 1 {
print(u.num)
} else {
print(u.num, "/", u.den)
@@ -45,12 +45,12 @@ func (u *rat) eq(c item) bool {
}
type dch struct {
- req chan int
- dat chan item
+ req chan int
+ dat chan item
nam int
}
-type dch2 [2] *dch
+type dch2 [2]*dch
var chnames string
var chnameserial int
@@ -87,25 +87,25 @@ func mkdch2() *dch2 {
// a signal on the release-wait channel tells the next newer
// generation to begin servicing out[1].
-func dosplit(in *dch, out *dch2, wait chan int ){
- both := false // do not service both channels
+func dosplit(in *dch, out *dch2, wait chan int) {
+ both := false // do not service both channels
select {
case <-out[0].req:
-
+
case <-wait:
both = true
select {
case <-out[0].req:
-
+
case <-out[1].req:
- out[0],out[1] = out[1], out[0]
+ out[0], out[1] = out[1], out[0]
}
}
seqno++
in.req <- seqno
- release := make(chan int)
+ release := make(chan int)
go dosplit(in, out, release)
dat := <-in.dat
out[0].dat <- dat
@@ -117,13 +117,13 @@ func dosplit(in *dch, out *dch2, wait chan int ){
release <- 0
}
-func split(in *dch, out *dch2){
+func split(in *dch, out *dch2) {
release := make(chan int)
go dosplit(in, out, release)
release <- 0
}
-func put(dat item, out *dch){
+func put(dat item, out *dch) {
<-out.req
out.dat <- dat
}
@@ -137,21 +137,23 @@ func get(in *dch) *rat {
// Get one item from each of n demand channels
func getn(in []*dch) []item {
- n:=len(in)
- if n != 2 { panic("bad n in getn") }
- req := make([] chan int, 2)
- dat := make([] chan item, 2)
+ n := len(in)
+ if n != 2 {
+ panic("bad n in getn")
+ }
+ req := make([]chan int, 2)
+ dat := make([]chan item, 2)
out := make([]item, 2)
var i int
var it item
- for i=0; i<n; i++ {
+ for i = 0; i < n; i++ {
req[i] = in[i].req
dat[i] = nil
}
- for n=2*n; n>0; n-- {
+ for n = 2 * n; n > 0; n-- {
seqno++
- select{
+ select {
case req[0] <- seqno:
dat[0] = in[0].dat
req[0] = nil
@@ -171,25 +173,25 @@ func getn(in []*dch) []item {
// Get one item from each of 2 demand channels
-func get2(in0 *dch, in1 *dch) []item {
+func get2(in0 *dch, in1 *dch) []item {
return getn([]*dch{in0, in1})
}
-func copy(in *dch, out *dch){
+func copy(in *dch, out *dch) {
for {
<-out.req
out.dat <- get(in)
}
}
-func repeat(dat item, out *dch){
+func repeat(dat item, out *dch) {
for {
put(dat, out)
}
}
-type PS *dch // power series
-type PS2 *[2] PS // pair of power series
+type PS *dch // power series
+type PS2 *[2]PS // pair of power series
var Ones PS
var Twos PS
@@ -210,93 +212,100 @@ func mkPS2() *dch2 {
// Integer gcd; needed for rational arithmetic
-func gcd (u, v int64) int64{
- if u < 0 { return gcd(-u, v) }
- if u == 0 { return v }
+func gcd(u, v int64) int64 {
+ if u < 0 {
+ return gcd(-u, v)
+ }
+ if u == 0 {
+ return v
+ }
return gcd(v%u, u)
}
// Make a rational from two ints and from one int
-func i2tor(u, v int64) *rat{
- g := gcd(u,v)
+func i2tor(u, v int64) *rat {
+ g := gcd(u, v)
r := new(rat)
if v > 0 {
- r.num = u/g
- r.den = v/g
+ r.num = u / g
+ r.den = v / g
} else {
- r.num = -u/g
- r.den = -v/g
+ r.num = -u / g
+ r.den = -v / g
}
return r
}
-func itor(u int64) *rat{
+func itor(u int64) *rat {
return i2tor(u, 1)
}
var zero *rat
var one *rat
-
// End mark and end test
var finis *rat
func end(u *rat) int64 {
- if u.den==0 { return 1 }
+ if u.den == 0 {
+ return 1
+ }
return 0
}
// Operations on rationals
func add(u, v *rat) *rat {
- g := gcd(u.den,v.den)
- return i2tor(u.num*(v.den/g)+v.num*(u.den/g),u.den*(v.den/g))
+ g := gcd(u.den, v.den)
+ return i2tor(u.num*(v.den/g)+v.num*(u.den/g), u.den*(v.den/g))
}
-func mul(u, v *rat) *rat{
- g1 := gcd(u.num,v.den)
- g2 := gcd(u.den,v.num)
+func mul(u, v *rat) *rat {
+ g1 := gcd(u.num, v.den)
+ g2 := gcd(u.den, v.num)
r := new(rat)
- r.num =(u.num/g1)*(v.num/g2)
- r.den = (u.den/g2)*(v.den/g1)
+ r.num = (u.num / g1) * (v.num / g2)
+ r.den = (u.den / g2) * (v.den / g1)
return r
}
-func neg(u *rat) *rat{
+func neg(u *rat) *rat {
return i2tor(-u.num, u.den)
}
-func sub(u, v *rat) *rat{
+func sub(u, v *rat) *rat {
return add(u, neg(v))
}
-func inv(u *rat) *rat{ // invert a rat
- if u.num == 0 { panic("zero divide in inv") }
+func inv(u *rat) *rat { // invert a rat
+ if u.num == 0 {
+ panic("zero divide in inv")
+ }
return i2tor(u.den, u.num)
}
// print eval in floating point of PS at x=c to n terms
func Evaln(c *rat, U PS, n int) {
xn := float64(1)
- x := float64(c.num)/float64(c.den)
+ x := float64(c.num) / float64(c.den)
val := float64(0)
- for i:=0; i<n; i++ {
+ for i := 0; i < n; i++ {
u := get(U)
if end(u) != 0 {
break
}
- val = val + x * float64(u.num)/float64(u.den)
- xn = xn*x
+ val = val + x*float64(u.num)/float64(u.den)
+ xn = xn * x
}
print(val, "\n")
}
// Print n terms of a power series
-func Printn(U PS, n int){
+func Printn(U PS, n int) {
done := false
- for ; !done && n>0; n-- {
+ for ; !done && n > 0; n-- {
u := get(U)
if end(u) != 0 {
done = true
@@ -307,16 +316,20 @@ func Printn(U PS, n int){
print(("\n"))
}
-func Print(U PS){
- Printn(U,1000000000)
+func Print(U PS) {
+ Printn(U, 1000000000)
}
// Evaluate n terms of power series U at x=c
-func eval(c *rat, U PS, n int) *rat{
- if n==0 { return zero }
+func eval(c *rat, U PS, n int) *rat {
+ if n == 0 {
+ return zero
+ }
y := get(U)
- if end(y) != 0 { return zero }
- return add(y,mul(c,eval(c,U,n-1)))
+ if end(y) != 0 {
+ return zero
+ }
+ return add(y, mul(c, eval(c, U, n-1)))
}
// Power-series constructors return channels on which power
@@ -325,29 +338,29 @@ func eval(c *rat, U PS, n int) *rat{
// Make a pair of power series identical to a given power series
-func Split(U PS) *dch2{
+func Split(U PS) *dch2 {
UU := mkdch2()
- go split(U,UU)
+ go split(U, UU)
return UU
}
// Add two power series
-func Add(U, V PS) PS{
+func Add(U, V PS) PS {
Z := mkPS()
- go func(U, V, Z PS){
- var uv [] item
+ go func(U, V, Z PS) {
+ var uv []item
for {
<-Z.req
- uv = get2(U,V)
- switch end(uv[0].(*rat))+2*end(uv[1].(*rat)) {
+ uv = get2(U, V)
+ switch end(uv[0].(*rat)) + 2*end(uv[1].(*rat)) {
case 0:
Z.dat <- add(uv[0].(*rat), uv[1].(*rat))
case 1:
Z.dat <- uv[1]
- copy(V,Z)
+ copy(V, Z)
case 2:
Z.dat <- uv[0]
- copy(U,Z)
+ copy(U, Z)
case 3:
Z.dat <- finis
}
@@ -357,9 +370,9 @@ func Add(U, V PS) PS{
}
// Multiply a power series by a constant
-func Cmul(c *rat,U PS) PS{
+func Cmul(c *rat, U PS) PS {
Z := mkPS()
- go func(c *rat, U, Z PS){
+ go func(c *rat, U, Z PS) {
done := false
for !done {
<-Z.req
@@ -367,7 +380,7 @@ func Cmul(c *rat,U PS) PS{
if end(u) != 0 {
done = true
} else {
- Z.dat <- mul(c,u)
+ Z.dat <- mul(c, u)
}
}
Z.dat <- finis
@@ -377,52 +390,56 @@ func Cmul(c *rat,U PS) PS{
// Subtract
-func Sub(U, V PS) PS{
+func Sub(U, V PS) PS {
return Add(U, Cmul(neg(one), V))
}
// Multiply a power series by the monomial x^n
-func Monmul(U PS, n int) PS{
+func Monmul(U PS, n int) PS {
Z := mkPS()
- go func(n int, U PS, Z PS){
- for ; n>0; n-- { put(zero,Z) }
- copy(U,Z)
+ go func(n int, U PS, Z PS) {
+ for ; n > 0; n-- {
+ put(zero, Z)
+ }
+ copy(U, Z)
}(n, U, Z)
return Z
}
// Multiply by x
-func Xmul(U PS) PS{
- return Monmul(U,1)
+func Xmul(U PS) PS {
+ return Monmul(U, 1)
}
-func Rep(c *rat) PS{
+func Rep(c *rat) PS {
Z := mkPS()
- go repeat(c,Z)
+ go repeat(c, Z)
return Z
}
// Monomial c*x^n
-func Mon(c *rat, n int) PS{
- Z:=mkPS()
- go func(c *rat, n int, Z PS){
- if(c.num!=0) {
- for ; n>0; n=n-1 { put(zero,Z) }
- put(c,Z)
+func Mon(c *rat, n int) PS {
+ Z := mkPS()
+ go func(c *rat, n int, Z PS) {
+ if c.num != 0 {
+ for ; n > 0; n = n - 1 {
+ put(zero, Z)
+ }
+ put(c, Z)
}
- put(finis,Z)
+ put(finis, Z)
}(c, n, Z)
return Z
}
-func Shift(c *rat, U PS) PS{
+func Shift(c *rat, U PS) PS {
Z := mkPS()
- go func(c *rat, U, Z PS){
- put(c,Z)
- copy(U,Z)
+ go func(c *rat, U, Z PS) {
+ put(c, Z)
+ copy(U, Z)
}(c, U, Z)
return Z
}
@@ -453,21 +470,21 @@ func Poly(a [] *rat) PS{
// let V = v + x*VV
// then UV = u*v + x*(u*VV+v*UU) + x*x*UU*VV
-func Mul(U, V PS) PS{
- Z:=mkPS()
- go func(U, V, Z PS){
+func Mul(U, V PS) PS {
+ Z := mkPS()
+ go func(U, V, Z PS) {
<-Z.req
- uv := get2(U,V)
- if end(uv[0].(*rat))!=0 || end(uv[1].(*rat)) != 0 {
+ uv := get2(U, V)
+ if end(uv[0].(*rat)) != 0 || end(uv[1].(*rat)) != 0 {
Z.dat <- finis
} else {
- Z.dat <- mul(uv[0].(*rat),uv[1].(*rat))
+ Z.dat <- mul(uv[0].(*rat), uv[1].(*rat))
UU := Split(U)
VV := Split(V)
- W := Add(Cmul(uv[0].(*rat),VV[0]),Cmul(uv[1].(*rat),UU[0]))
+ W := Add(Cmul(uv[0].(*rat), VV[0]), Cmul(uv[1].(*rat), UU[0]))
<-Z.req
Z.dat <- get(W)
- copy(Add(W,Mul(UU[1],VV[1])),Z)
+ copy(Add(W, Mul(UU[1], VV[1])), Z)
}
}(U, V, Z)
return Z
@@ -475,19 +492,19 @@ func Mul(U, V PS) PS{
// Differentiate
-func Diff(U PS) PS{
- Z:=mkPS()
- go func(U, Z PS){
+func Diff(U PS) PS {
+ Z := mkPS()
+ go func(U, Z PS) {
<-Z.req
u := get(U)
if end(u) == 0 {
- done:=false
- for i:=1; !done; i++ {
+ done := false
+ for i := 1; !done; i++ {
u = get(U)
if end(u) != 0 {
- done=true
+ done = true
} else {
- Z.dat <- mul(itor(int64(i)),u)
+ Z.dat <- mul(itor(int64(i)), u)
<-Z.req
}
}
@@ -498,16 +515,18 @@ func Diff(U PS) PS{
}
// Integrate, with const of integration
-func Integ(c *rat,U PS) PS{
- Z:=mkPS()
- go func(c *rat, U, Z PS){
- put(c,Z)
- done:=false
- for i:=1; !done; i++ {
+func Integ(c *rat, U PS) PS {
+ Z := mkPS()
+ go func(c *rat, U, Z PS) {
+ put(c, Z)
+ done := false
+ for i := 1; !done; i++ {
<-Z.req
u := get(U)
- if end(u) != 0 { done= true }
- Z.dat <- mul(i2tor(1,int64(i)),u)
+ if end(u) != 0 {
+ done = true
+ }
+ Z.dat <- mul(i2tor(1, int64(i)), u)
}
Z.dat <- finis
}(c, U, Z)
@@ -516,18 +535,18 @@ func Integ(c *rat,U PS) PS{
// Binomial theorem (1+x)^c
-func Binom(c *rat) PS{
- Z:=mkPS()
- go func(c *rat, Z PS){
+func Binom(c *rat) PS {
+ Z := mkPS()
+ go func(c *rat, Z PS) {
n := 1
t := itor(1)
- for c.num!=0 {
- put(t,Z)
- t = mul(mul(t,c),i2tor(1,int64(n)))
- c = sub(c,one)
+ for c.num != 0 {
+ put(t, Z)
+ t = mul(mul(t, c), i2tor(1, int64(n)))
+ c = sub(c, one)
n++
}
- put(finis,Z)
+ put(finis, Z)
}(c, Z)
return Z
}
@@ -540,15 +559,15 @@ func Binom(c *rat) PS{
// u*ZZ + z*UU +x*UU*ZZ = 0
// ZZ = -UU*(z+x*ZZ)/u
-func Recip(U PS) PS{
- Z:=mkPS()
- go func(U, Z PS){
- ZZ:=mkPS2()
+func Recip(U PS) PS {
+ Z := mkPS()
+ go func(U, Z PS) {
+ ZZ := mkPS2()
<-Z.req
z := inv(get(U))
Z.dat <- z
- split(Mul(Cmul(neg(z),U),Shift(z,ZZ[0])),ZZ)
- copy(ZZ[1],Z)
+ split(Mul(Cmul(neg(z), U), Shift(z, ZZ[0])), ZZ)
+ copy(ZZ[1], Z)
}(U, Z)
return Z
}
@@ -560,9 +579,9 @@ func Recip(U PS) PS{
// DZ = Z*DU
// integrate to get Z
-func Exp(U PS) PS{
+func Exp(U PS) PS {
ZZ := mkPS2()
- split(Integ(one,Mul(ZZ[0],Diff(U))),ZZ)
+ split(Integ(one, Mul(ZZ[0], Diff(U))), ZZ)
return ZZ[1]
}
@@ -573,7 +592,7 @@ func Exp(U PS) PS{
// bug: a nonzero constant term is ignored
func Subst(U, V PS) PS {
- Z:= mkPS()
+ Z := mkPS()
go func(U, V, Z PS) {
VV := Split(V)
<-Z.req
@@ -581,20 +600,20 @@ func Subst(U, V PS) PS {
Z.dat <- u
if end(u) == 0 {
if end(get(VV[0])) != 0 {
- put(finis,Z)
+ put(finis, Z)
} else {
- copy(Mul(VV[0],Subst(U,VV[1])),Z)
+ copy(Mul(VV[0], Subst(U, VV[1])), Z)
}
}
}(U, V, Z)
return Z
}
-// Monomial Substition: U(c x^n)
+// Monomial Substitution: U(c x^n)
// Each Ui is multiplied by c^i and followed by n-1 zeros
func MonSubst(U PS, c0 *rat, n int) PS {
- Z:= mkPS()
+ Z := mkPS()
go func(U, Z PS, c0 *rat, n int) {
c := one
for {
@@ -615,14 +634,13 @@ func MonSubst(U PS, c0 *rat, n int) PS {
return Z
}
-
func Init() {
chnameserial = -1
seqno = 0
chnames = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
zero = itor(0)
one = itor(1)
- finis = i2tor(1,0)
+ finis = i2tor(1, 0)
Ones = Rep(one)
Twos = Rep(itor(2))
}
@@ -641,7 +659,8 @@ func check(U PS, c *rat, count int, str string) {
}
}
-const N=10
+const N = 10
+
func checka(U PS, a []*rat, str string) {
for i := 0; i < N; i++ {
check(U, a[i], 1, str)
@@ -650,53 +669,64 @@ func checka(U PS, a []*rat, str string) {
func main() {
Init()
- if len(os.Args) > 1 { // print
- print("Ones: "); Printn(Ones, 10)
- print("Twos: "); Printn(Twos, 10)
- print("Add: "); Printn(Add(Ones, Twos), 10)
- print("Diff: "); Printn(Diff(Ones), 10)
- print("Integ: "); Printn(Integ(zero, Ones), 10)
- print("CMul: "); Printn(Cmul(neg(one), Ones), 10)
- print("Sub: "); Printn(Sub(Ones, Twos), 10)
- print("Mul: "); Printn(Mul(Ones, Ones), 10)
- print("Exp: "); Printn(Exp(Ones), 15)
- print("MonSubst: "); Printn(MonSubst(Ones, neg(one), 2), 10)
- print("ATan: "); Printn(Integ(zero, MonSubst(Ones, neg(one), 2)), 10)
- } else { // test
+ if len(os.Args) > 1 { // print
+ print("Ones: ")
+ Printn(Ones, 10)
+ print("Twos: ")
+ Printn(Twos, 10)
+ print("Add: ")
+ Printn(Add(Ones, Twos), 10)
+ print("Diff: ")
+ Printn(Diff(Ones), 10)
+ print("Integ: ")
+ Printn(Integ(zero, Ones), 10)
+ print("CMul: ")
+ Printn(Cmul(neg(one), Ones), 10)
+ print("Sub: ")
+ Printn(Sub(Ones, Twos), 10)
+ print("Mul: ")
+ Printn(Mul(Ones, Ones), 10)
+ print("Exp: ")
+ Printn(Exp(Ones), 15)
+ print("MonSubst: ")
+ Printn(MonSubst(Ones, neg(one), 2), 10)
+ print("ATan: ")
+ Printn(Integ(zero, MonSubst(Ones, neg(one), 2)), 10)
+ } else { // test
check(Ones, one, 5, "Ones")
- check(Add(Ones, Ones), itor(2), 0, "Add Ones Ones") // 1 1 1 1 1
+ check(Add(Ones, Ones), itor(2), 0, "Add Ones Ones") // 1 1 1 1 1
check(Add(Ones, Twos), itor(3), 0, "Add Ones Twos") // 3 3 3 3 3
a := make([]*rat, N)
d := Diff(Ones)
- for i:=0; i < N; i++ {
- a[i] = itor(int64(i+1))
+ for i := 0; i < N; i++ {
+ a[i] = itor(int64(i + 1))
}
- checka(d, a, "Diff") // 1 2 3 4 5
+ checka(d, a, "Diff") // 1 2 3 4 5
in := Integ(zero, Ones)
- a[0] = zero // integration constant
- for i:=1; i < N; i++ {
+ a[0] = zero // integration constant
+ for i := 1; i < N; i++ {
a[i] = i2tor(1, int64(i))
}
- checka(in, a, "Integ") // 0 1 1/2 1/3 1/4 1/5
- check(Cmul(neg(one), Twos), itor(-2), 10, "CMul") // -1 -1 -1 -1 -1
- check(Sub(Ones, Twos), itor(-1), 0, "Sub Ones Twos") // -1 -1 -1 -1 -1
+ checka(in, a, "Integ") // 0 1 1/2 1/3 1/4 1/5
+ check(Cmul(neg(one), Twos), itor(-2), 10, "CMul") // -1 -1 -1 -1 -1
+ check(Sub(Ones, Twos), itor(-1), 0, "Sub Ones Twos") // -1 -1 -1 -1 -1
m := Mul(Ones, Ones)
- for i:=0; i < N; i++ {
- a[i] = itor(int64(i+1))
+ for i := 0; i < N; i++ {
+ a[i] = itor(int64(i + 1))
}
- checka(m, a, "Mul") // 1 2 3 4 5
+ checka(m, a, "Mul") // 1 2 3 4 5
e := Exp(Ones)
a[0] = itor(1)
a[1] = itor(1)
- a[2] = i2tor(3,2)
- a[3] = i2tor(13,6)
- a[4] = i2tor(73,24)
- a[5] = i2tor(167,40)
- a[6] = i2tor(4051,720)
- a[7] = i2tor(37633,5040)
- a[8] = i2tor(43817,4480)
- a[9] = i2tor(4596553,362880)
- checka(e, a, "Exp") // 1 1 3/2 13/6 73/24
+ a[2] = i2tor(3, 2)
+ a[3] = i2tor(13, 6)
+ a[4] = i2tor(73, 24)
+ a[5] = i2tor(167, 40)
+ a[6] = i2tor(4051, 720)
+ a[7] = i2tor(37633, 5040)
+ a[8] = i2tor(43817, 4480)
+ a[9] = i2tor(4596553, 362880)
+ checka(e, a, "Exp") // 1 1 3/2 13/6 73/24
at := Integ(zero, MonSubst(Ones, neg(one), 2))
for c, i := 1, 0; i < N; i++ {
if i%2 == 0 {
@@ -706,20 +736,20 @@ func main() {
c *= -1
}
}
- checka(at, a, "ATan"); // 0 -1 0 -1/3 0 -1/5
-/*
- t := Revert(Integ(zero, MonSubst(Ones, neg(one), 2)))
- a[0] = zero
- a[1] = itor(1)
- a[2] = zero
- a[3] = i2tor(1,3)
- a[4] = zero
- a[5] = i2tor(2,15)
- a[6] = zero
- a[7] = i2tor(17,315)
- a[8] = zero
- a[9] = i2tor(62,2835)
- checka(t, a, "Tan") // 0 1 0 1/3 0 2/15
-*/
+ checka(at, a, "ATan") // 0 -1 0 -1/3 0 -1/5
+ /*
+ t := Revert(Integ(zero, MonSubst(Ones, neg(one), 2)))
+ a[0] = zero
+ a[1] = itor(1)
+ a[2] = zero
+ a[3] = i2tor(1,3)
+ a[4] = zero
+ a[5] = i2tor(2,15)
+ a[6] = zero
+ a[7] = i2tor(17,315)
+ a[8] = zero
+ a[9] = i2tor(62,2835)
+ checka(t, a, "Tan") // 0 1 0 1/3 0 2/15
+ */
}
}
diff --git a/gcc/testsuite/go.test/test/chan/select2.go b/gcc/testsuite/go.test/test/chan/select2.go
index ccf9dab..31e27d7 100644
--- a/gcc/testsuite/go.test/test/chan/select2.go
+++ b/gcc/testsuite/go.test/test/chan/select2.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/chan/select3.go b/gcc/testsuite/go.test/test/chan/select3.go
index 847d8ed..dd14c73 100644
--- a/gcc/testsuite/go.test/test/chan/select3.go
+++ b/gcc/testsuite/go.test/test/chan/select3.go
@@ -14,12 +14,10 @@ import "time"
const always = "function did not"
const never = "function did"
-
func unreachable() {
panic("control flow shouldn't reach here")
}
-
// Calls f and verifies that f always/never panics depending on signal.
func testPanic(signal string, f func()) {
defer func() {
@@ -34,7 +32,6 @@ func testPanic(signal string, f func()) {
f()
}
-
// Calls f and empirically verifies that f always/never blocks depending on signal.
func testBlock(signal string, f func()) {
c := make(chan string)
@@ -43,15 +40,21 @@ func testBlock(signal string, f func()) {
c <- never // f didn't block
}()
go func() {
- time.Sleep(1e8) // 0.1s seems plenty long
- c <- always // f blocked always
+ if signal == never {
+ // Wait a long time to make sure that we don't miss our window by accident on a slow machine.
+ time.Sleep(10 * time.Second)
+ } else {
+ // Wait as short a time as we can without false negatives.
+ // 10ms should be long enough to catch most failures.
+ time.Sleep(10 * time.Millisecond)
+ }
+ c <- always // f blocked always
}()
if <-c != signal {
panic(signal + " block")
}
}
-
func main() {
const async = 1 // asynchronous channels
var nilch chan int
@@ -114,8 +117,7 @@ func main() {
// empty selects always block
testBlock(always, func() {
- select {
- }
+ select {}
})
// selects with only nil channels always block
diff --git a/gcc/testsuite/go.test/test/chan/select5.go b/gcc/testsuite/go.test/test/chan/select5.go
index f72cfe4..8b98c3a 100644
--- a/gcc/testsuite/go.test/test/chan/select5.go
+++ b/gcc/testsuite/go.test/test/chan/select5.go
@@ -1,6 +1,6 @@
// runoutput
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -27,16 +27,16 @@ func main() {
fmt.Fprintln(out, header)
a := new(arg)
- // Generate each kind of test as a separate function to avoid
- // hitting the 6g optimizer with one enormous function.
+ // Generate each test as a separate function to avoid
+ // hitting the gc optimizer with one enormous function.
// If we name all the functions init we don't have to
// maintain a list of which ones to run.
do := func(t *template.Template) {
- fmt.Fprintln(out, `func init() {`)
for ; next(); a.reset() {
+ fmt.Fprintln(out, `func init() {`)
run(t, a, out)
+ fmt.Fprintln(out, `}`)
}
- fmt.Fprintln(out, `}`)
}
do(recv)
diff --git a/gcc/testsuite/go.test/test/chan/select6.go b/gcc/testsuite/go.test/test/chan/select6.go
index af470a0..6e8129f 100644
--- a/gcc/testsuite/go.test/test/chan/select6.go
+++ b/gcc/testsuite/go.test/test/chan/select6.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/chan/select7.go b/gcc/testsuite/go.test/test/chan/select7.go
index 20456a9..f7222ca 100644
--- a/gcc/testsuite/go.test/test/chan/select7.go
+++ b/gcc/testsuite/go.test/test/chan/select7.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/chan/select8.go b/gcc/testsuite/go.test/test/chan/select8.go
new file mode 100644
index 0000000..20bca3a
--- /dev/null
+++ b/gcc/testsuite/go.test/test/chan/select8.go
@@ -0,0 +1,55 @@
+// run
+
+// 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.
+
+// Test break statements in a select.
+// Gccgo had a bug in handling this.
+// Test 1,2,3-case selects, so it covers both the general
+// code path and the specialized optimizations for one-
+// and two-case selects.
+
+package main
+
+var ch = make(chan int)
+
+func main() {
+ go func() {
+ for {
+ ch <- 5
+ }
+ }()
+
+ select {
+ case <-ch:
+ break
+ panic("unreachable")
+ }
+
+ select {
+ default:
+ break
+ panic("unreachable")
+ }
+
+ select {
+ case <-ch:
+ break
+ panic("unreachable")
+ default:
+ break
+ panic("unreachable")
+ }
+
+ select {
+ case <-ch:
+ break
+ panic("unreachable")
+ case ch <- 10:
+ panic("unreachable")
+ default:
+ break
+ panic("unreachable")
+ }
+}
diff --git a/gcc/testsuite/go.test/test/chan/sendstmt.go b/gcc/testsuite/go.test/test/chan/sendstmt.go
index a92c4f6..d296a55 100644
--- a/gcc/testsuite/go.test/test/chan/sendstmt.go
+++ b/gcc/testsuite/go.test/test/chan/sendstmt.go
@@ -1,11 +1,11 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
// Test various parsing cases that are a little
-// different now that send is a statement, not a expression.
+// different now that send is a statement, not an expression.
package main
@@ -30,7 +30,7 @@ func chanchan() {
func sendprec() {
c := make(chan bool, 1)
- c <- false || true // not a syntax error: same as c <- (false || true)
+ c <- false || true // not a syntax error: same as c <- (false || true)
if !<-c {
panic("sent false")
}
diff --git a/gcc/testsuite/go.test/test/chancap.go b/gcc/testsuite/go.test/test/chancap.go
index b3e4023..8dce924 100644
--- a/gcc/testsuite/go.test/test/chancap.go
+++ b/gcc/testsuite/go.test/test/chancap.go
@@ -8,8 +8,17 @@
package main
+import (
+ "strings"
+ "unsafe"
+)
+
+type T chan int
+
+const ptrSize = unsafe.Sizeof((*byte)(nil))
+
func main() {
- c := make(chan int, 10)
+ c := make(T, 10)
if len(c) != 0 || cap(c) != 10 {
println("chan len/cap ", len(c), cap(c), " want 0 10")
panic("fail")
@@ -23,9 +32,40 @@ func main() {
panic("fail")
}
- c = make(chan int)
+ c = make(T)
if len(c) != 0 || cap(c) != 0 {
println("chan len/cap ", len(c), cap(c), " want 0 0")
panic("fail")
}
+
+ n := -1
+ shouldPanic("makechan: size out of range", func() { _ = make(T, n) })
+ shouldPanic("makechan: size out of range", func() { _ = make(T, int64(n)) })
+ if ptrSize == 8 {
+ // Test mem > maxAlloc
+ var n2 int64 = 1 << 59
+ shouldPanic("makechan: size out of range", func() { _ = make(T, int(n2)) })
+ // Test elem.size*cap overflow
+ n2 = 1<<63 - 1
+ shouldPanic("makechan: size out of range", func() { _ = make(T, int(n2)) })
+ } else {
+ n = 1<<31 - 1
+ shouldPanic("makechan: size out of range", func() { _ = make(T, n) })
+ shouldPanic("makechan: size out of range", func() { _ = make(T, int64(n)) })
+ }
+}
+
+func shouldPanic(str string, f func()) {
+ defer func() {
+ err := recover()
+ if err == nil {
+ panic("did not panic")
+ }
+ s := err.(error).Error()
+ if !strings.Contains(s, str) {
+ panic("got panic " + s + ", want " + str)
+ }
+ }()
+
+ f()
}
diff --git a/gcc/testsuite/go.test/test/cmp.go b/gcc/testsuite/go.test/test/cmp.go
index 73de502..6db9ce5 100644
--- a/gcc/testsuite/go.test/test/cmp.go
+++ b/gcc/testsuite/go.test/test/cmp.go
@@ -35,6 +35,10 @@ func istrue(b bool) {
type T *int
+type X int
+
+func (X) x() {}
+
func main() {
var a []int
var b map[string]int
@@ -111,7 +115,7 @@ func main() {
isfalse(ic != d)
isfalse(ie != e)
- // 6g used to let this go through as true.
+ // gc used to let this go through as true.
var g uint64 = 123
var h int64 = 123
var ig interface{} = g
@@ -129,6 +133,44 @@ func main() {
panic("bad m[c]")
}
+ // interface comparisons (issue 7207)
+ {
+ type I1 interface {
+ x()
+ }
+ type I2 interface {
+ x()
+ }
+ a1 := I1(X(0))
+ b1 := I1(X(1))
+ a2 := I2(X(0))
+ b2 := I2(X(1))
+ a3 := I1(a2)
+ a4 := I2(a1)
+ var e interface{} = X(0)
+ a5 := e.(I1)
+ a6 := e.(I2)
+ isfalse(a1 == b1)
+ isfalse(a1 == b2)
+ isfalse(a2 == b1)
+ isfalse(a2 == b2)
+ istrue(a1 == a2)
+ istrue(a1 == a3)
+ istrue(a1 == a4)
+ istrue(a1 == a5)
+ istrue(a1 == a6)
+ istrue(a2 == a3)
+ istrue(a2 == a4)
+ istrue(a2 == a5)
+ istrue(a2 == a6)
+ istrue(a3 == a4)
+ istrue(a3 == a5)
+ istrue(a3 == a6)
+ istrue(a4 == a5)
+ istrue(a4 == a6)
+ istrue(a5 == a6)
+ }
+
// non-interface comparisons
{
c := make(chan int)
@@ -387,6 +429,23 @@ func main() {
isfalse(iz != x)
}
+ // named booleans
+ {
+ type mybool bool
+ var b mybool
+
+ type T struct{ data [20]byte }
+ var x, y T
+ b = x == y
+ istrue(x == y)
+ istrue(bool(b))
+
+ m := make(map[string][10]interface{})
+ b = m["x"] == m["y"]
+ istrue(m["x"] == m["y"])
+ istrue(bool(b))
+ }
+
shouldPanic(p1)
shouldPanic(p2)
shouldPanic(p3)
diff --git a/gcc/testsuite/go.test/test/cmp6.go b/gcc/testsuite/go.test/test/cmp6.go
index 839c274..7cf7604 100644
--- a/gcc/testsuite/go.test/test/cmp6.go
+++ b/gcc/testsuite/go.test/test/cmp6.go
@@ -18,7 +18,10 @@ type T3 struct{ z []int }
var t3 T3
-type T4 struct { _ []int; a float64 }
+type T4 struct {
+ _ []int
+ a float64
+}
var t4 T4
@@ -51,6 +54,14 @@ func main() {
use(p3 == p1)
use(p3 == p2)
+ // Arrays are comparable if and only if their element type is comparable.
+ var a1 [1]int
+ var a2 [1]func()
+ var a3 [0]func()
+ use(a1 == a1)
+ use(a2 == a2) // ERROR "invalid operation|invalid comparison"
+ use(a3 == a3) // ERROR "invalid operation|invalid comparison"
+
// Comparison of structs should have a good message
use(t3 == t3) // ERROR "struct|expected"
use(t4 == t4) // ERROR "cannot be compared|non-comparable"
diff --git a/gcc/testsuite/go.test/test/cmplx.go b/gcc/testsuite/go.test/test/cmplx.go
index 2d8a622..d63c7eb 100644
--- a/gcc/testsuite/go.test/test/cmplx.go
+++ b/gcc/testsuite/go.test/test/cmplx.go
@@ -28,6 +28,14 @@ var (
C128 Complex128
)
+func F1() int {
+ return 1
+}
+
+func F3() (int, int, int) {
+ return 1, 2, 3
+}
+
func main() {
// ok
c64 = complex(f32, f32)
@@ -41,6 +49,11 @@ func main() {
_ = complex(f64, F64) // ERROR "complex"
_ = complex(F64, f64) // ERROR "complex"
+ _ = complex(F1()) // ERROR "not enough arguments"
+ _ = complex(F3()) // ERROR "too many arguments"
+
+ _ = complex() // ERROR "not enough arguments"
+
c128 = complex(f32, f32) // ERROR "cannot use"
c64 = complex(f64, f64) // ERROR "cannot use"
@@ -51,4 +64,5 @@ func main() {
C64 = complex(f32, f32) // ERROR "cannot use"
C128 = complex(f64, f64) // ERROR "cannot use"
+
}
diff --git a/gcc/testsuite/go.test/test/cmplxdivide.c b/gcc/testsuite/go.test/test/cmplxdivide.c
index 12dc4f1..89a2868 100644
--- a/gcc/testsuite/go.test/test/cmplxdivide.c
+++ b/gcc/testsuite/go.test/test/cmplxdivide.c
@@ -1,8 +1,19 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// gcc '-std=c99' cmplxdivide.c && a.out >cmplxdivide1.go
+// This C program generates the file cmplxdivide1.go. It uses the
+// output of the operations by C99 as the reference to check
+// the implementation of complex numbers in Go.
+// The generated file, cmplxdivide1.go, is compiled along
+// with the driver cmplxdivide.go (the names are confusing
+// and unimaginative) to run the actual test. This is done by
+// the usual test runner.
+//
+// The file cmplxdivide1.go is checked in to the repository, but
+// if it needs to be regenerated, compile and run this C program
+// like this:
+// gcc '-std=c99' cmplxdivide.c && a.out >cmplxdivide1.go
#include <complex.h>
#include <math.h>
@@ -12,50 +23,63 @@
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
double f[] = {
- 0,
- 1,
- -1,
- 2,
+ 0.0,
+ -0.0,
+ 1.0,
+ -1.0,
+ 2.0,
NAN,
INFINITY,
-INFINITY,
};
-char*
-fmt(double g)
-{
+char* fmt(double g) {
static char buf[10][30];
static int n;
char *p;
-
+
p = buf[n++];
- if(n == 10)
+ if(n == 10) {
n = 0;
+ }
+
sprintf(p, "%g", g);
- if(strcmp(p, "-0") == 0)
- strcpy(p, "negzero");
- return p;
-}
-int
-iscnan(double complex d)
-{
- return !isinf(creal(d)) && !isinf(cimag(d)) && (isnan(creal(d)) || isnan(cimag(d)));
-}
+ if(strcmp(p, "0") == 0) {
+ strcpy(p, "zero");
+ return p;
+ }
+
+ if(strcmp(p, "-0") == 0) {
+ strcpy(p, "-zero");
+ return p;
+ }
-double complex zero; // attempt to hide zero division from gcc
+ return p;
+}
-int
-main(void)
-{
+int main(void) {
int i, j, k, l;
double complex n, d, q;
-
+
printf("// skip\n");
printf("// # generated by cmplxdivide.c\n");
printf("\n");
printf("package main\n");
- printf("var tests = []Test{\n");
+ printf("\n");
+ printf("import \"math\"\n");
+ printf("\n");
+ printf("var (\n");
+ printf("\tnan = math.NaN()\n");
+ printf("\tinf = math.Inf(1)\n");
+ printf("\tzero = 0.0\n");
+ printf(")\n");
+ printf("\n");
+ printf("var tests = []struct {\n");
+ printf("\tf, g complex128\n");
+ printf("\tout complex128\n");
+ printf("}{\n");
+
for(i=0; i<nelem(f); i++)
for(j=0; j<nelem(f); j++)
for(k=0; k<nelem(f); k++)
@@ -63,17 +87,8 @@ main(void)
n = f[i] + f[j]*I;
d = f[k] + f[l]*I;
q = n/d;
-
- // BUG FIX.
- // Gcc gets the wrong answer for NaN/0 unless both sides are NaN.
- // That is, it treats (NaN+NaN*I)/0 = NaN+NaN*I (a complex NaN)
- // but it then computes (1+NaN*I)/0 = Inf+NaN*I (a complex infinity).
- // Since both numerators are complex NaNs, it seems that the
- // results should agree in kind. Override the gcc computation in this case.
- if(iscnan(n) && d == 0)
- q = (NAN+NAN*I) / zero;
- printf("\tTest{complex(%s, %s), complex(%s, %s), complex(%s, %s)},\n",
+ printf("\t{complex(%s, %s), complex(%s, %s), complex(%s, %s)},\n",
fmt(creal(n)), fmt(cimag(n)),
fmt(creal(d)), fmt(cimag(d)),
fmt(creal(q)), fmt(cimag(q)));
diff --git a/gcc/testsuite/go.test/test/cmplxdivide.go b/gcc/testsuite/go.test/test/cmplxdivide.go
index 40c8448..49cd5bf 100644
--- a/gcc/testsuite/go.test/test/cmplxdivide.go
+++ b/gcc/testsuite/go.test/test/cmplxdivide.go
@@ -1,36 +1,29 @@
// run cmplxdivide1.go
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Driver for complex division table defined in cmplxdivide1.go
+// For details, see the comment at the top of cmplxdivide.c.
package main
import (
"fmt"
"math"
- "math/cmplx"
)
-type Test struct {
- f, g complex128
- out complex128
-}
-
-var nan = math.NaN()
-var inf = math.Inf(1)
-var negzero = math.Copysign(0, -1)
-
func calike(a, b complex128) bool {
- switch {
- case cmplx.IsInf(a) && cmplx.IsInf(b):
- return true
- case cmplx.IsNaN(a) && cmplx.IsNaN(b):
- return true
+ if imag(a) != imag(b) && !(math.IsNaN(imag(a)) && math.IsNaN(imag(b))) {
+ return false
}
- return a == b
+
+ if real(a) != real(b) && !(math.IsNaN(real(a)) && math.IsNaN(real(b))) {
+ return false
+ }
+
+ return true
}
func main() {
diff --git a/gcc/testsuite/go.test/test/cmplxdivide1.go b/gcc/testsuite/go.test/test/cmplxdivide1.go
index e9031dd..a52fb6f 100644
--- a/gcc/testsuite/go.test/test/cmplxdivide1.go
+++ b/gcc/testsuite/go.test/test/cmplxdivide1.go
@@ -2,2406 +2,4113 @@
// # generated by cmplxdivide.c
package main
-var tests = []Test{
- Test{complex(0, 0), complex(0, 0), complex(-nan, -nan)},
- Test{complex(0, 0), complex(0, 1), complex(0, 0)},
- Test{complex(0, 0), complex(0, -1), complex(negzero, 0)},
- Test{complex(0, 0), complex(0, 2), complex(0, 0)},
- Test{complex(0, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 0), complex(1, 0), complex(0, 0)},
- Test{complex(0, 0), complex(1, 1), complex(0, 0)},
- Test{complex(0, 0), complex(1, -1), complex(0, 0)},
- Test{complex(0, 0), complex(1, 2), complex(0, 0)},
- Test{complex(0, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 0), complex(-1, 0), complex(negzero, negzero)},
- Test{complex(0, 0), complex(-1, 1), complex(negzero, negzero)},
- Test{complex(0, 0), complex(-1, -1), complex(negzero, negzero)},
- Test{complex(0, 0), complex(-1, 2), complex(0, negzero)},
- Test{complex(0, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 0), complex(2, 0), complex(0, 0)},
- Test{complex(0, 0), complex(2, 1), complex(0, 0)},
- Test{complex(0, 0), complex(2, -1), complex(0, 0)},
- Test{complex(0, 0), complex(2, 2), complex(0, 0)},
- Test{complex(0, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 0), complex(nan, 0), complex(nan, nan)},
- Test{complex(0, 0), complex(nan, 1), complex(nan, nan)},
- Test{complex(0, 0), complex(nan, -1), complex(nan, nan)},
- Test{complex(0, 0), complex(nan, 2), complex(nan, nan)},
- Test{complex(0, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 0), complex(inf, 0), complex(0, 0)},
- Test{complex(0, 0), complex(inf, 1), complex(0, 0)},
- Test{complex(0, 0), complex(inf, -1), complex(0, 0)},
- Test{complex(0, 0), complex(inf, 2), complex(0, 0)},
- Test{complex(0, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 0), complex(-inf, 0), complex(negzero, negzero)},
- Test{complex(0, 0), complex(-inf, 1), complex(negzero, negzero)},
- Test{complex(0, 0), complex(-inf, -1), complex(negzero, negzero)},
- Test{complex(0, 0), complex(-inf, 2), complex(negzero, negzero)},
- Test{complex(0, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 1), complex(0, 0), complex(-nan, inf)},
- Test{complex(0, 1), complex(0, 1), complex(1, 0)},
- Test{complex(0, 1), complex(0, -1), complex(-1, 0)},
- Test{complex(0, 1), complex(0, 2), complex(0.5, 0)},
- Test{complex(0, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 1), complex(1, 0), complex(0, 1)},
- Test{complex(0, 1), complex(1, 1), complex(0.5, 0.5)},
- Test{complex(0, 1), complex(1, -1), complex(-0.5, 0.5)},
- Test{complex(0, 1), complex(1, 2), complex(0.4, 0.2)},
- Test{complex(0, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 1), complex(-1, 0), complex(negzero, -1)},
- Test{complex(0, 1), complex(-1, 1), complex(0.5, -0.5)},
- Test{complex(0, 1), complex(-1, -1), complex(-0.5, -0.5)},
- Test{complex(0, 1), complex(-1, 2), complex(0.4, -0.2)},
- Test{complex(0, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 1), complex(2, 0), complex(0, 0.5)},
- Test{complex(0, 1), complex(2, 1), complex(0.2, 0.4)},
- Test{complex(0, 1), complex(2, -1), complex(-0.2, 0.4)},
- Test{complex(0, 1), complex(2, 2), complex(0.25, 0.25)},
- Test{complex(0, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 1), complex(nan, 0), complex(nan, nan)},
- Test{complex(0, 1), complex(nan, 1), complex(nan, nan)},
- Test{complex(0, 1), complex(nan, -1), complex(nan, nan)},
- Test{complex(0, 1), complex(nan, 2), complex(nan, nan)},
- Test{complex(0, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 1), complex(inf, 0), complex(0, 0)},
- Test{complex(0, 1), complex(inf, 1), complex(0, 0)},
- Test{complex(0, 1), complex(inf, -1), complex(0, 0)},
- Test{complex(0, 1), complex(inf, 2), complex(0, 0)},
- Test{complex(0, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 1), complex(-inf, 0), complex(negzero, negzero)},
- Test{complex(0, 1), complex(-inf, 1), complex(negzero, negzero)},
- Test{complex(0, 1), complex(-inf, -1), complex(negzero, negzero)},
- Test{complex(0, 1), complex(-inf, 2), complex(negzero, negzero)},
- Test{complex(0, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, -1), complex(0, 0), complex(-nan, -inf)},
- Test{complex(0, -1), complex(0, 1), complex(-1, negzero)},
- Test{complex(0, -1), complex(0, -1), complex(1, negzero)},
- Test{complex(0, -1), complex(0, 2), complex(-0.5, negzero)},
- Test{complex(0, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, -1), complex(-nan, inf), complex(negzero, 0)},
- Test{complex(0, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(0, -1), complex(1, 0), complex(0, -1)},
- Test{complex(0, -1), complex(1, 1), complex(-0.5, -0.5)},
- Test{complex(0, -1), complex(1, -1), complex(0.5, -0.5)},
- Test{complex(0, -1), complex(1, 2), complex(-0.4, -0.2)},
- Test{complex(0, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, -1), complex(-nan, inf), complex(negzero, 0)},
- Test{complex(0, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(0, -1), complex(-1, 0), complex(negzero, 1)},
- Test{complex(0, -1), complex(-1, 1), complex(-0.5, 0.5)},
- Test{complex(0, -1), complex(-1, -1), complex(0.5, 0.5)},
- Test{complex(0, -1), complex(-1, 2), complex(-0.4, 0.2)},
- Test{complex(0, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, -1), complex(-nan, inf), complex(negzero, 0)},
- Test{complex(0, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(0, -1), complex(2, 0), complex(0, -0.5)},
- Test{complex(0, -1), complex(2, 1), complex(-0.2, -0.4)},
- Test{complex(0, -1), complex(2, -1), complex(0.2, -0.4)},
- Test{complex(0, -1), complex(2, 2), complex(-0.25, -0.25)},
- Test{complex(0, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, -1), complex(-nan, inf), complex(negzero, 0)},
- Test{complex(0, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(0, -1), complex(nan, 0), complex(nan, nan)},
- Test{complex(0, -1), complex(nan, 1), complex(nan, nan)},
- Test{complex(0, -1), complex(nan, -1), complex(nan, nan)},
- Test{complex(0, -1), complex(nan, 2), complex(nan, nan)},
- Test{complex(0, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, -1), complex(-nan, inf), complex(negzero, 0)},
- Test{complex(0, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(0, -1), complex(inf, 0), complex(0, negzero)},
- Test{complex(0, -1), complex(inf, 1), complex(0, negzero)},
- Test{complex(0, -1), complex(inf, -1), complex(0, negzero)},
- Test{complex(0, -1), complex(inf, 2), complex(0, negzero)},
- Test{complex(0, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, -1), complex(-nan, inf), complex(negzero, 0)},
- Test{complex(0, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(0, -1), complex(-inf, 0), complex(negzero, 0)},
- Test{complex(0, -1), complex(-inf, 1), complex(negzero, 0)},
- Test{complex(0, -1), complex(-inf, -1), complex(negzero, 0)},
- Test{complex(0, -1), complex(-inf, 2), complex(negzero, 0)},
- Test{complex(0, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, -1), complex(-nan, inf), complex(negzero, 0)},
- Test{complex(0, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(0, 2), complex(0, 0), complex(-nan, inf)},
- Test{complex(0, 2), complex(0, 1), complex(2, 0)},
- Test{complex(0, 2), complex(0, -1), complex(-2, 0)},
- Test{complex(0, 2), complex(0, 2), complex(1, 0)},
- Test{complex(0, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 2), complex(1, 0), complex(0, 2)},
- Test{complex(0, 2), complex(1, 1), complex(1, 1)},
- Test{complex(0, 2), complex(1, -1), complex(-1, 1)},
- Test{complex(0, 2), complex(1, 2), complex(0.8, 0.4)},
- Test{complex(0, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 2), complex(-1, 0), complex(negzero, -2)},
- Test{complex(0, 2), complex(-1, 1), complex(1, -1)},
- Test{complex(0, 2), complex(-1, -1), complex(-1, -1)},
- Test{complex(0, 2), complex(-1, 2), complex(0.8, -0.4)},
- Test{complex(0, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 2), complex(2, 0), complex(0, 1)},
- Test{complex(0, 2), complex(2, 1), complex(0.4, 0.8)},
- Test{complex(0, 2), complex(2, -1), complex(-0.4, 0.8)},
- Test{complex(0, 2), complex(2, 2), complex(0.5, 0.5)},
- Test{complex(0, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 2), complex(nan, 0), complex(nan, nan)},
- Test{complex(0, 2), complex(nan, 1), complex(nan, nan)},
- Test{complex(0, 2), complex(nan, -1), complex(nan, nan)},
- Test{complex(0, 2), complex(nan, 2), complex(nan, nan)},
- Test{complex(0, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 2), complex(inf, 0), complex(0, 0)},
- Test{complex(0, 2), complex(inf, 1), complex(0, 0)},
- Test{complex(0, 2), complex(inf, -1), complex(0, 0)},
- Test{complex(0, 2), complex(inf, 2), complex(0, 0)},
- Test{complex(0, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(0, 2), complex(-inf, 0), complex(negzero, negzero)},
- Test{complex(0, 2), complex(-inf, 1), complex(negzero, negzero)},
- Test{complex(0, 2), complex(-inf, -1), complex(negzero, negzero)},
- Test{complex(0, 2), complex(-inf, 2), complex(negzero, negzero)},
- Test{complex(0, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(0, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(0, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(nan, nan), complex(0, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(-nan, inf), complex(0, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(0, 1), complex(inf, -nan)},
- Test{complex(-nan, inf), complex(0, -1), complex(-inf, -nan)},
- Test{complex(-nan, inf), complex(0, 2), complex(inf, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(1, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(1, 1), complex(inf, inf)},
- Test{complex(-nan, inf), complex(1, -1), complex(-inf, inf)},
- Test{complex(-nan, inf), complex(1, 2), complex(inf, inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-1, 0), complex(-nan, -inf)},
- Test{complex(-nan, inf), complex(-1, 1), complex(inf, -inf)},
- Test{complex(-nan, inf), complex(-1, -1), complex(-inf, -inf)},
- Test{complex(-nan, inf), complex(-1, 2), complex(inf, -inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(2, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(2, 1), complex(inf, inf)},
- Test{complex(-nan, inf), complex(2, -1), complex(-inf, inf)},
- Test{complex(-nan, inf), complex(2, 2), complex(inf, inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, 0), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, 1), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, -1), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, 2), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(0, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(0, 1), complex(-inf, -nan)},
- Test{complex(-nan, -inf), complex(0, -1), complex(inf, -nan)},
- Test{complex(-nan, -inf), complex(0, 2), complex(-inf, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(1, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(1, 1), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(1, -1), complex(inf, -inf)},
- Test{complex(-nan, -inf), complex(1, 2), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-1, 0), complex(-nan, inf)},
- Test{complex(-nan, -inf), complex(-1, 1), complex(-inf, inf)},
- Test{complex(-nan, -inf), complex(-1, -1), complex(inf, inf)},
- Test{complex(-nan, -inf), complex(-1, 2), complex(-inf, inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(2, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(2, 1), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(2, -1), complex(inf, -inf)},
- Test{complex(-nan, -inf), complex(2, 2), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, 0), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, 1), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, -1), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, 2), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(1, 0), complex(0, 0), complex(inf, -nan)},
- Test{complex(1, 0), complex(0, 1), complex(0, -1)},
- Test{complex(1, 0), complex(0, -1), complex(negzero, 1)},
- Test{complex(1, 0), complex(0, 2), complex(0, -0.5)},
- Test{complex(1, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 0), complex(1, 0), complex(1, 0)},
- Test{complex(1, 0), complex(1, 1), complex(0.5, -0.5)},
- Test{complex(1, 0), complex(1, -1), complex(0.5, 0.5)},
- Test{complex(1, 0), complex(1, 2), complex(0.2, -0.4)},
- Test{complex(1, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 0), complex(-1, 0), complex(-1, negzero)},
- Test{complex(1, 0), complex(-1, 1), complex(-0.5, -0.5)},
- Test{complex(1, 0), complex(-1, -1), complex(-0.5, 0.5)},
- Test{complex(1, 0), complex(-1, 2), complex(-0.2, -0.4)},
- Test{complex(1, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 0), complex(2, 0), complex(0.5, 0)},
- Test{complex(1, 0), complex(2, 1), complex(0.4, -0.2)},
- Test{complex(1, 0), complex(2, -1), complex(0.4, 0.2)},
- Test{complex(1, 0), complex(2, 2), complex(0.25, -0.25)},
- Test{complex(1, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 0), complex(nan, 0), complex(nan, nan)},
- Test{complex(1, 0), complex(nan, 1), complex(nan, nan)},
- Test{complex(1, 0), complex(nan, -1), complex(nan, nan)},
- Test{complex(1, 0), complex(nan, 2), complex(nan, nan)},
- Test{complex(1, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 0), complex(inf, 0), complex(0, 0)},
- Test{complex(1, 0), complex(inf, 1), complex(0, 0)},
- Test{complex(1, 0), complex(inf, -1), complex(0, 0)},
- Test{complex(1, 0), complex(inf, 2), complex(0, 0)},
- Test{complex(1, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 0), complex(-inf, 0), complex(negzero, negzero)},
- Test{complex(1, 0), complex(-inf, 1), complex(negzero, negzero)},
- Test{complex(1, 0), complex(-inf, -1), complex(negzero, negzero)},
- Test{complex(1, 0), complex(-inf, 2), complex(negzero, negzero)},
- Test{complex(1, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 1), complex(0, 0), complex(inf, inf)},
- Test{complex(1, 1), complex(0, 1), complex(1, -1)},
- Test{complex(1, 1), complex(0, -1), complex(-1, 1)},
- Test{complex(1, 1), complex(0, 2), complex(0.5, -0.5)},
- Test{complex(1, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 1), complex(1, 0), complex(1, 1)},
- Test{complex(1, 1), complex(1, 1), complex(1, 0)},
- Test{complex(1, 1), complex(1, -1), complex(0, 1)},
- Test{complex(1, 1), complex(1, 2), complex(0.6, -0.2)},
- Test{complex(1, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 1), complex(-1, 0), complex(-1, -1)},
- Test{complex(1, 1), complex(-1, 1), complex(negzero, -1)},
- Test{complex(1, 1), complex(-1, -1), complex(-1, negzero)},
- Test{complex(1, 1), complex(-1, 2), complex(0.2, -0.6)},
- Test{complex(1, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 1), complex(2, 0), complex(0.5, 0.5)},
- Test{complex(1, 1), complex(2, 1), complex(0.6, 0.2)},
- Test{complex(1, 1), complex(2, -1), complex(0.2, 0.6)},
- Test{complex(1, 1), complex(2, 2), complex(0.5, 0)},
- Test{complex(1, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 1), complex(nan, 0), complex(nan, nan)},
- Test{complex(1, 1), complex(nan, 1), complex(nan, nan)},
- Test{complex(1, 1), complex(nan, -1), complex(nan, nan)},
- Test{complex(1, 1), complex(nan, 2), complex(nan, nan)},
- Test{complex(1, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 1), complex(inf, 0), complex(0, 0)},
- Test{complex(1, 1), complex(inf, 1), complex(0, 0)},
- Test{complex(1, 1), complex(inf, -1), complex(0, 0)},
- Test{complex(1, 1), complex(inf, 2), complex(0, 0)},
- Test{complex(1, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 1), complex(-inf, 0), complex(negzero, negzero)},
- Test{complex(1, 1), complex(-inf, 1), complex(negzero, negzero)},
- Test{complex(1, 1), complex(-inf, -1), complex(negzero, negzero)},
- Test{complex(1, 1), complex(-inf, 2), complex(negzero, negzero)},
- Test{complex(1, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, -1), complex(0, 0), complex(inf, -inf)},
- Test{complex(1, -1), complex(0, 1), complex(-1, -1)},
- Test{complex(1, -1), complex(0, -1), complex(1, 1)},
- Test{complex(1, -1), complex(0, 2), complex(-0.5, -0.5)},
- Test{complex(1, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, -1), complex(-nan, inf), complex(negzero, negzero)},
- Test{complex(1, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(1, -1), complex(1, 0), complex(1, -1)},
- Test{complex(1, -1), complex(1, 1), complex(0, -1)},
- Test{complex(1, -1), complex(1, -1), complex(1, 0)},
- Test{complex(1, -1), complex(1, 2), complex(-0.2, -0.6)},
- Test{complex(1, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, -1), complex(-nan, inf), complex(negzero, negzero)},
- Test{complex(1, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(1, -1), complex(-1, 0), complex(-1, 1)},
- Test{complex(1, -1), complex(-1, 1), complex(-1, negzero)},
- Test{complex(1, -1), complex(-1, -1), complex(negzero, 1)},
- Test{complex(1, -1), complex(-1, 2), complex(-0.6, -0.2)},
- Test{complex(1, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, -1), complex(-nan, inf), complex(negzero, negzero)},
- Test{complex(1, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(1, -1), complex(2, 0), complex(0.5, -0.5)},
- Test{complex(1, -1), complex(2, 1), complex(0.2, -0.6)},
- Test{complex(1, -1), complex(2, -1), complex(0.6, -0.2)},
- Test{complex(1, -1), complex(2, 2), complex(0, -0.5)},
- Test{complex(1, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, -1), complex(-nan, inf), complex(negzero, negzero)},
- Test{complex(1, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(1, -1), complex(nan, 0), complex(nan, nan)},
- Test{complex(1, -1), complex(nan, 1), complex(nan, nan)},
- Test{complex(1, -1), complex(nan, -1), complex(nan, nan)},
- Test{complex(1, -1), complex(nan, 2), complex(nan, nan)},
- Test{complex(1, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, -1), complex(-nan, inf), complex(negzero, negzero)},
- Test{complex(1, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(1, -1), complex(inf, 0), complex(0, negzero)},
- Test{complex(1, -1), complex(inf, 1), complex(0, negzero)},
- Test{complex(1, -1), complex(inf, -1), complex(0, negzero)},
- Test{complex(1, -1), complex(inf, 2), complex(0, negzero)},
- Test{complex(1, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, -1), complex(-nan, inf), complex(negzero, negzero)},
- Test{complex(1, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(1, -1), complex(-inf, 0), complex(negzero, 0)},
- Test{complex(1, -1), complex(-inf, 1), complex(negzero, 0)},
- Test{complex(1, -1), complex(-inf, -1), complex(negzero, 0)},
- Test{complex(1, -1), complex(-inf, 2), complex(negzero, 0)},
- Test{complex(1, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, -1), complex(-nan, inf), complex(negzero, negzero)},
- Test{complex(1, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(1, 2), complex(0, 0), complex(inf, inf)},
- Test{complex(1, 2), complex(0, 1), complex(2, -1)},
- Test{complex(1, 2), complex(0, -1), complex(-2, 1)},
- Test{complex(1, 2), complex(0, 2), complex(1, -0.5)},
- Test{complex(1, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 2), complex(1, 0), complex(1, 2)},
- Test{complex(1, 2), complex(1, 1), complex(1.5, 0.5)},
- Test{complex(1, 2), complex(1, -1), complex(-0.5, 1.5)},
- Test{complex(1, 2), complex(1, 2), complex(1, 0)},
- Test{complex(1, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 2), complex(-1, 0), complex(-1, -2)},
- Test{complex(1, 2), complex(-1, 1), complex(0.5, -1.5)},
- Test{complex(1, 2), complex(-1, -1), complex(-1.5, -0.5)},
- Test{complex(1, 2), complex(-1, 2), complex(0.6, -0.8)},
- Test{complex(1, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 2), complex(2, 0), complex(0.5, 1)},
- Test{complex(1, 2), complex(2, 1), complex(0.8, 0.6)},
- Test{complex(1, 2), complex(2, -1), complex(0, 1)},
- Test{complex(1, 2), complex(2, 2), complex(0.75, 0.25)},
- Test{complex(1, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 2), complex(nan, 0), complex(nan, nan)},
- Test{complex(1, 2), complex(nan, 1), complex(nan, nan)},
- Test{complex(1, 2), complex(nan, -1), complex(nan, nan)},
- Test{complex(1, 2), complex(nan, 2), complex(nan, nan)},
- Test{complex(1, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 2), complex(inf, 0), complex(0, 0)},
- Test{complex(1, 2), complex(inf, 1), complex(0, 0)},
- Test{complex(1, 2), complex(inf, -1), complex(0, 0)},
- Test{complex(1, 2), complex(inf, 2), complex(0, 0)},
- Test{complex(1, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(1, 2), complex(-inf, 0), complex(negzero, negzero)},
- Test{complex(1, 2), complex(-inf, 1), complex(negzero, negzero)},
- Test{complex(1, 2), complex(-inf, -1), complex(negzero, negzero)},
- Test{complex(1, 2), complex(-inf, 2), complex(negzero, negzero)},
- Test{complex(1, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(1, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(1, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(nan, nan), complex(0, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(-nan, inf), complex(0, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(0, 1), complex(inf, -nan)},
- Test{complex(-nan, inf), complex(0, -1), complex(-inf, -nan)},
- Test{complex(-nan, inf), complex(0, 2), complex(inf, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(1, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(1, 1), complex(inf, inf)},
- Test{complex(-nan, inf), complex(1, -1), complex(-inf, inf)},
- Test{complex(-nan, inf), complex(1, 2), complex(inf, inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-1, 0), complex(-nan, -inf)},
- Test{complex(-nan, inf), complex(-1, 1), complex(inf, -inf)},
- Test{complex(-nan, inf), complex(-1, -1), complex(-inf, -inf)},
- Test{complex(-nan, inf), complex(-1, 2), complex(inf, -inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(2, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(2, 1), complex(inf, inf)},
- Test{complex(-nan, inf), complex(2, -1), complex(-inf, inf)},
- Test{complex(-nan, inf), complex(2, 2), complex(inf, inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, 0), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, 1), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, -1), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, 2), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(0, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(0, 1), complex(-inf, -nan)},
- Test{complex(-nan, -inf), complex(0, -1), complex(inf, -nan)},
- Test{complex(-nan, -inf), complex(0, 2), complex(-inf, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(1, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(1, 1), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(1, -1), complex(inf, -inf)},
- Test{complex(-nan, -inf), complex(1, 2), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-1, 0), complex(-nan, inf)},
- Test{complex(-nan, -inf), complex(-1, 1), complex(-inf, inf)},
- Test{complex(-nan, -inf), complex(-1, -1), complex(inf, inf)},
- Test{complex(-nan, -inf), complex(-1, 2), complex(-inf, inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(2, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(2, 1), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(2, -1), complex(inf, -inf)},
- Test{complex(-nan, -inf), complex(2, 2), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, 0), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, 1), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, -1), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, 2), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-1, 0), complex(0, 0), complex(-inf, -nan)},
- Test{complex(-1, 0), complex(0, 1), complex(0, 1)},
- Test{complex(-1, 0), complex(0, -1), complex(negzero, -1)},
- Test{complex(-1, 0), complex(0, 2), complex(0, 0.5)},
- Test{complex(-1, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 0), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 0), complex(-nan, -inf), complex(0, negzero)},
- Test{complex(-1, 0), complex(1, 0), complex(-1, 0)},
- Test{complex(-1, 0), complex(1, 1), complex(-0.5, 0.5)},
- Test{complex(-1, 0), complex(1, -1), complex(-0.5, -0.5)},
- Test{complex(-1, 0), complex(1, 2), complex(-0.2, 0.4)},
- Test{complex(-1, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 0), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 0), complex(-nan, -inf), complex(0, negzero)},
- Test{complex(-1, 0), complex(-1, 0), complex(1, negzero)},
- Test{complex(-1, 0), complex(-1, 1), complex(0.5, 0.5)},
- Test{complex(-1, 0), complex(-1, -1), complex(0.5, -0.5)},
- Test{complex(-1, 0), complex(-1, 2), complex(0.2, 0.4)},
- Test{complex(-1, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 0), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 0), complex(-nan, -inf), complex(0, negzero)},
- Test{complex(-1, 0), complex(2, 0), complex(-0.5, 0)},
- Test{complex(-1, 0), complex(2, 1), complex(-0.4, 0.2)},
- Test{complex(-1, 0), complex(2, -1), complex(-0.4, -0.2)},
- Test{complex(-1, 0), complex(2, 2), complex(-0.25, 0.25)},
- Test{complex(-1, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 0), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 0), complex(-nan, -inf), complex(0, negzero)},
- Test{complex(-1, 0), complex(nan, 0), complex(nan, nan)},
- Test{complex(-1, 0), complex(nan, 1), complex(nan, nan)},
- Test{complex(-1, 0), complex(nan, -1), complex(nan, nan)},
- Test{complex(-1, 0), complex(nan, 2), complex(nan, nan)},
- Test{complex(-1, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 0), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 0), complex(-nan, -inf), complex(0, negzero)},
- Test{complex(-1, 0), complex(inf, 0), complex(negzero, 0)},
- Test{complex(-1, 0), complex(inf, 1), complex(negzero, 0)},
- Test{complex(-1, 0), complex(inf, -1), complex(negzero, 0)},
- Test{complex(-1, 0), complex(inf, 2), complex(negzero, 0)},
- Test{complex(-1, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 0), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 0), complex(-nan, -inf), complex(0, negzero)},
- Test{complex(-1, 0), complex(-inf, 0), complex(0, negzero)},
- Test{complex(-1, 0), complex(-inf, 1), complex(0, negzero)},
- Test{complex(-1, 0), complex(-inf, -1), complex(0, negzero)},
- Test{complex(-1, 0), complex(-inf, 2), complex(0, negzero)},
- Test{complex(-1, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 0), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 0), complex(-nan, -inf), complex(0, negzero)},
- Test{complex(-1, 1), complex(0, 0), complex(-inf, inf)},
- Test{complex(-1, 1), complex(0, 1), complex(1, 1)},
- Test{complex(-1, 1), complex(0, -1), complex(-1, -1)},
- Test{complex(-1, 1), complex(0, 2), complex(0.5, 0.5)},
- Test{complex(-1, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 1), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 1), complex(-nan, -inf), complex(negzero, negzero)},
- Test{complex(-1, 1), complex(1, 0), complex(-1, 1)},
- Test{complex(-1, 1), complex(1, 1), complex(0, 1)},
- Test{complex(-1, 1), complex(1, -1), complex(-1, 0)},
- Test{complex(-1, 1), complex(1, 2), complex(0.2, 0.6)},
- Test{complex(-1, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 1), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 1), complex(-nan, -inf), complex(negzero, negzero)},
- Test{complex(-1, 1), complex(-1, 0), complex(1, -1)},
- Test{complex(-1, 1), complex(-1, 1), complex(1, negzero)},
- Test{complex(-1, 1), complex(-1, -1), complex(negzero, -1)},
- Test{complex(-1, 1), complex(-1, 2), complex(0.6, 0.2)},
- Test{complex(-1, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 1), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 1), complex(-nan, -inf), complex(negzero, negzero)},
- Test{complex(-1, 1), complex(2, 0), complex(-0.5, 0.5)},
- Test{complex(-1, 1), complex(2, 1), complex(-0.2, 0.6)},
- Test{complex(-1, 1), complex(2, -1), complex(-0.6, 0.2)},
- Test{complex(-1, 1), complex(2, 2), complex(0, 0.5)},
- Test{complex(-1, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 1), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 1), complex(-nan, -inf), complex(negzero, negzero)},
- Test{complex(-1, 1), complex(nan, 0), complex(nan, nan)},
- Test{complex(-1, 1), complex(nan, 1), complex(nan, nan)},
- Test{complex(-1, 1), complex(nan, -1), complex(nan, nan)},
- Test{complex(-1, 1), complex(nan, 2), complex(nan, nan)},
- Test{complex(-1, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 1), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 1), complex(-nan, -inf), complex(negzero, negzero)},
- Test{complex(-1, 1), complex(inf, 0), complex(negzero, 0)},
- Test{complex(-1, 1), complex(inf, 1), complex(negzero, 0)},
- Test{complex(-1, 1), complex(inf, -1), complex(negzero, 0)},
- Test{complex(-1, 1), complex(inf, 2), complex(negzero, 0)},
- Test{complex(-1, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 1), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 1), complex(-nan, -inf), complex(negzero, negzero)},
- Test{complex(-1, 1), complex(-inf, 0), complex(0, negzero)},
- Test{complex(-1, 1), complex(-inf, 1), complex(0, negzero)},
- Test{complex(-1, 1), complex(-inf, -1), complex(0, negzero)},
- Test{complex(-1, 1), complex(-inf, 2), complex(0, negzero)},
- Test{complex(-1, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 1), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 1), complex(-nan, -inf), complex(negzero, negzero)},
- Test{complex(-1, -1), complex(0, 0), complex(-inf, -inf)},
- Test{complex(-1, -1), complex(0, 1), complex(-1, 1)},
- Test{complex(-1, -1), complex(0, -1), complex(1, -1)},
- Test{complex(-1, -1), complex(0, 2), complex(-0.5, 0.5)},
- Test{complex(-1, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, -1), complex(-nan, inf), complex(negzero, 0)},
- Test{complex(-1, -1), complex(-nan, -inf), complex(0, negzero)},
- Test{complex(-1, -1), complex(1, 0), complex(-1, -1)},
- Test{complex(-1, -1), complex(1, 1), complex(-1, 0)},
- Test{complex(-1, -1), complex(1, -1), complex(0, -1)},
- Test{complex(-1, -1), complex(1, 2), complex(-0.6, 0.2)},
- Test{complex(-1, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, -1), complex(-nan, inf), complex(negzero, 0)},
- Test{complex(-1, -1), complex(-nan, -inf), complex(0, negzero)},
- Test{complex(-1, -1), complex(-1, 0), complex(1, 1)},
- Test{complex(-1, -1), complex(-1, 1), complex(negzero, 1)},
- Test{complex(-1, -1), complex(-1, -1), complex(1, negzero)},
- Test{complex(-1, -1), complex(-1, 2), complex(-0.2, 0.6)},
- Test{complex(-1, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, -1), complex(-nan, inf), complex(negzero, 0)},
- Test{complex(-1, -1), complex(-nan, -inf), complex(0, negzero)},
- Test{complex(-1, -1), complex(2, 0), complex(-0.5, -0.5)},
- Test{complex(-1, -1), complex(2, 1), complex(-0.6, -0.2)},
- Test{complex(-1, -1), complex(2, -1), complex(-0.2, -0.6)},
- Test{complex(-1, -1), complex(2, 2), complex(-0.5, 0)},
- Test{complex(-1, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, -1), complex(-nan, inf), complex(negzero, 0)},
- Test{complex(-1, -1), complex(-nan, -inf), complex(0, negzero)},
- Test{complex(-1, -1), complex(nan, 0), complex(nan, nan)},
- Test{complex(-1, -1), complex(nan, 1), complex(nan, nan)},
- Test{complex(-1, -1), complex(nan, -1), complex(nan, nan)},
- Test{complex(-1, -1), complex(nan, 2), complex(nan, nan)},
- Test{complex(-1, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, -1), complex(-nan, inf), complex(negzero, 0)},
- Test{complex(-1, -1), complex(-nan, -inf), complex(0, negzero)},
- Test{complex(-1, -1), complex(inf, 0), complex(negzero, negzero)},
- Test{complex(-1, -1), complex(inf, 1), complex(negzero, negzero)},
- Test{complex(-1, -1), complex(inf, -1), complex(negzero, negzero)},
- Test{complex(-1, -1), complex(inf, 2), complex(negzero, negzero)},
- Test{complex(-1, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, -1), complex(-nan, inf), complex(negzero, 0)},
- Test{complex(-1, -1), complex(-nan, -inf), complex(0, negzero)},
- Test{complex(-1, -1), complex(-inf, 0), complex(0, 0)},
- Test{complex(-1, -1), complex(-inf, 1), complex(0, 0)},
- Test{complex(-1, -1), complex(-inf, -1), complex(0, 0)},
- Test{complex(-1, -1), complex(-inf, 2), complex(0, 0)},
- Test{complex(-1, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, -1), complex(-nan, inf), complex(negzero, 0)},
- Test{complex(-1, -1), complex(-nan, -inf), complex(0, negzero)},
- Test{complex(-1, 2), complex(0, 0), complex(-inf, inf)},
- Test{complex(-1, 2), complex(0, 1), complex(2, 1)},
- Test{complex(-1, 2), complex(0, -1), complex(-2, -1)},
- Test{complex(-1, 2), complex(0, 2), complex(1, 0.5)},
- Test{complex(-1, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 2), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 2), complex(-nan, -inf), complex(negzero, negzero)},
- Test{complex(-1, 2), complex(1, 0), complex(-1, 2)},
- Test{complex(-1, 2), complex(1, 1), complex(0.5, 1.5)},
- Test{complex(-1, 2), complex(1, -1), complex(-1.5, 0.5)},
- Test{complex(-1, 2), complex(1, 2), complex(0.6, 0.8)},
- Test{complex(-1, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 2), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 2), complex(-nan, -inf), complex(negzero, negzero)},
- Test{complex(-1, 2), complex(-1, 0), complex(1, -2)},
- Test{complex(-1, 2), complex(-1, 1), complex(1.5, -0.5)},
- Test{complex(-1, 2), complex(-1, -1), complex(-0.5, -1.5)},
- Test{complex(-1, 2), complex(-1, 2), complex(1, 0)},
- Test{complex(-1, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 2), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 2), complex(-nan, -inf), complex(negzero, negzero)},
- Test{complex(-1, 2), complex(2, 0), complex(-0.5, 1)},
- Test{complex(-1, 2), complex(2, 1), complex(0, 1)},
- Test{complex(-1, 2), complex(2, -1), complex(-0.8, 0.6)},
- Test{complex(-1, 2), complex(2, 2), complex(0.25, 0.75)},
- Test{complex(-1, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 2), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 2), complex(-nan, -inf), complex(negzero, negzero)},
- Test{complex(-1, 2), complex(nan, 0), complex(nan, nan)},
- Test{complex(-1, 2), complex(nan, 1), complex(nan, nan)},
- Test{complex(-1, 2), complex(nan, -1), complex(nan, nan)},
- Test{complex(-1, 2), complex(nan, 2), complex(nan, nan)},
- Test{complex(-1, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 2), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 2), complex(-nan, -inf), complex(negzero, negzero)},
- Test{complex(-1, 2), complex(inf, 0), complex(negzero, 0)},
- Test{complex(-1, 2), complex(inf, 1), complex(negzero, 0)},
- Test{complex(-1, 2), complex(inf, -1), complex(negzero, 0)},
- Test{complex(-1, 2), complex(inf, 2), complex(negzero, 0)},
- Test{complex(-1, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 2), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 2), complex(-nan, -inf), complex(negzero, negzero)},
- Test{complex(-1, 2), complex(-inf, 0), complex(0, negzero)},
- Test{complex(-1, 2), complex(-inf, 1), complex(0, negzero)},
- Test{complex(-1, 2), complex(-inf, -1), complex(0, negzero)},
- Test{complex(-1, 2), complex(-inf, 2), complex(0, negzero)},
- Test{complex(-1, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(-1, 2), complex(-nan, inf), complex(0, 0)},
- Test{complex(-1, 2), complex(-nan, -inf), complex(negzero, negzero)},
- Test{complex(nan, nan), complex(0, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(-nan, inf), complex(0, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(0, 1), complex(inf, -nan)},
- Test{complex(-nan, inf), complex(0, -1), complex(-inf, -nan)},
- Test{complex(-nan, inf), complex(0, 2), complex(inf, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(1, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(1, 1), complex(inf, inf)},
- Test{complex(-nan, inf), complex(1, -1), complex(-inf, inf)},
- Test{complex(-nan, inf), complex(1, 2), complex(inf, inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-1, 0), complex(-nan, -inf)},
- Test{complex(-nan, inf), complex(-1, 1), complex(inf, -inf)},
- Test{complex(-nan, inf), complex(-1, -1), complex(-inf, -inf)},
- Test{complex(-nan, inf), complex(-1, 2), complex(inf, -inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(2, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(2, 1), complex(inf, inf)},
- Test{complex(-nan, inf), complex(2, -1), complex(-inf, inf)},
- Test{complex(-nan, inf), complex(2, 2), complex(inf, inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, 0), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, 1), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, -1), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, 2), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(0, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(0, 1), complex(-inf, -nan)},
- Test{complex(-nan, -inf), complex(0, -1), complex(inf, -nan)},
- Test{complex(-nan, -inf), complex(0, 2), complex(-inf, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(1, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(1, 1), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(1, -1), complex(inf, -inf)},
- Test{complex(-nan, -inf), complex(1, 2), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-1, 0), complex(-nan, inf)},
- Test{complex(-nan, -inf), complex(-1, 1), complex(-inf, inf)},
- Test{complex(-nan, -inf), complex(-1, -1), complex(inf, inf)},
- Test{complex(-nan, -inf), complex(-1, 2), complex(-inf, inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(2, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(2, 1), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(2, -1), complex(inf, -inf)},
- Test{complex(-nan, -inf), complex(2, 2), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, 0), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, 1), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, -1), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, 2), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(2, 0), complex(0, 0), complex(inf, -nan)},
- Test{complex(2, 0), complex(0, 1), complex(0, -2)},
- Test{complex(2, 0), complex(0, -1), complex(negzero, 2)},
- Test{complex(2, 0), complex(0, 2), complex(0, -1)},
- Test{complex(2, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 0), complex(1, 0), complex(2, 0)},
- Test{complex(2, 0), complex(1, 1), complex(1, -1)},
- Test{complex(2, 0), complex(1, -1), complex(1, 1)},
- Test{complex(2, 0), complex(1, 2), complex(0.4, -0.8)},
- Test{complex(2, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 0), complex(-1, 0), complex(-2, negzero)},
- Test{complex(2, 0), complex(-1, 1), complex(-1, -1)},
- Test{complex(2, 0), complex(-1, -1), complex(-1, 1)},
- Test{complex(2, 0), complex(-1, 2), complex(-0.4, -0.8)},
- Test{complex(2, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 0), complex(2, 0), complex(1, 0)},
- Test{complex(2, 0), complex(2, 1), complex(0.8, -0.4)},
- Test{complex(2, 0), complex(2, -1), complex(0.8, 0.4)},
- Test{complex(2, 0), complex(2, 2), complex(0.5, -0.5)},
- Test{complex(2, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 0), complex(nan, 0), complex(nan, nan)},
- Test{complex(2, 0), complex(nan, 1), complex(nan, nan)},
- Test{complex(2, 0), complex(nan, -1), complex(nan, nan)},
- Test{complex(2, 0), complex(nan, 2), complex(nan, nan)},
- Test{complex(2, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 0), complex(inf, 0), complex(0, 0)},
- Test{complex(2, 0), complex(inf, 1), complex(0, 0)},
- Test{complex(2, 0), complex(inf, -1), complex(0, 0)},
- Test{complex(2, 0), complex(inf, 2), complex(0, 0)},
- Test{complex(2, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 0), complex(-inf, 0), complex(negzero, negzero)},
- Test{complex(2, 0), complex(-inf, 1), complex(negzero, negzero)},
- Test{complex(2, 0), complex(-inf, -1), complex(negzero, negzero)},
- Test{complex(2, 0), complex(-inf, 2), complex(negzero, negzero)},
- Test{complex(2, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 0), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 0), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 1), complex(0, 0), complex(inf, inf)},
- Test{complex(2, 1), complex(0, 1), complex(1, -2)},
- Test{complex(2, 1), complex(0, -1), complex(-1, 2)},
- Test{complex(2, 1), complex(0, 2), complex(0.5, -1)},
- Test{complex(2, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 1), complex(1, 0), complex(2, 1)},
- Test{complex(2, 1), complex(1, 1), complex(1.5, -0.5)},
- Test{complex(2, 1), complex(1, -1), complex(0.5, 1.5)},
- Test{complex(2, 1), complex(1, 2), complex(0.8, -0.6)},
- Test{complex(2, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 1), complex(-1, 0), complex(-2, -1)},
- Test{complex(2, 1), complex(-1, 1), complex(-0.5, -1.5)},
- Test{complex(2, 1), complex(-1, -1), complex(-1.5, 0.5)},
- Test{complex(2, 1), complex(-1, 2), complex(0, -1)},
- Test{complex(2, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 1), complex(2, 0), complex(1, 0.5)},
- Test{complex(2, 1), complex(2, 1), complex(1, 0)},
- Test{complex(2, 1), complex(2, -1), complex(0.6, 0.8)},
- Test{complex(2, 1), complex(2, 2), complex(0.75, -0.25)},
- Test{complex(2, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 1), complex(nan, 0), complex(nan, nan)},
- Test{complex(2, 1), complex(nan, 1), complex(nan, nan)},
- Test{complex(2, 1), complex(nan, -1), complex(nan, nan)},
- Test{complex(2, 1), complex(nan, 2), complex(nan, nan)},
- Test{complex(2, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 1), complex(inf, 0), complex(0, 0)},
- Test{complex(2, 1), complex(inf, 1), complex(0, 0)},
- Test{complex(2, 1), complex(inf, -1), complex(0, 0)},
- Test{complex(2, 1), complex(inf, 2), complex(0, 0)},
- Test{complex(2, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 1), complex(-inf, 0), complex(negzero, negzero)},
- Test{complex(2, 1), complex(-inf, 1), complex(negzero, negzero)},
- Test{complex(2, 1), complex(-inf, -1), complex(negzero, negzero)},
- Test{complex(2, 1), complex(-inf, 2), complex(negzero, negzero)},
- Test{complex(2, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 1), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 1), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, -1), complex(0, 0), complex(inf, -inf)},
- Test{complex(2, -1), complex(0, 1), complex(-1, -2)},
- Test{complex(2, -1), complex(0, -1), complex(1, 2)},
- Test{complex(2, -1), complex(0, 2), complex(-0.5, -1)},
- Test{complex(2, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, -1), complex(-nan, inf), complex(negzero, negzero)},
- Test{complex(2, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(2, -1), complex(1, 0), complex(2, -1)},
- Test{complex(2, -1), complex(1, 1), complex(0.5, -1.5)},
- Test{complex(2, -1), complex(1, -1), complex(1.5, 0.5)},
- Test{complex(2, -1), complex(1, 2), complex(0, -1)},
- Test{complex(2, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, -1), complex(-nan, inf), complex(negzero, negzero)},
- Test{complex(2, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(2, -1), complex(-1, 0), complex(-2, 1)},
- Test{complex(2, -1), complex(-1, 1), complex(-1.5, -0.5)},
- Test{complex(2, -1), complex(-1, -1), complex(-0.5, 1.5)},
- Test{complex(2, -1), complex(-1, 2), complex(-0.8, -0.6)},
- Test{complex(2, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, -1), complex(-nan, inf), complex(negzero, negzero)},
- Test{complex(2, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(2, -1), complex(2, 0), complex(1, -0.5)},
- Test{complex(2, -1), complex(2, 1), complex(0.6, -0.8)},
- Test{complex(2, -1), complex(2, -1), complex(1, 0)},
- Test{complex(2, -1), complex(2, 2), complex(0.25, -0.75)},
- Test{complex(2, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, -1), complex(-nan, inf), complex(negzero, negzero)},
- Test{complex(2, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(2, -1), complex(nan, 0), complex(nan, nan)},
- Test{complex(2, -1), complex(nan, 1), complex(nan, nan)},
- Test{complex(2, -1), complex(nan, -1), complex(nan, nan)},
- Test{complex(2, -1), complex(nan, 2), complex(nan, nan)},
- Test{complex(2, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, -1), complex(-nan, inf), complex(negzero, negzero)},
- Test{complex(2, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(2, -1), complex(inf, 0), complex(0, negzero)},
- Test{complex(2, -1), complex(inf, 1), complex(0, negzero)},
- Test{complex(2, -1), complex(inf, -1), complex(0, negzero)},
- Test{complex(2, -1), complex(inf, 2), complex(0, negzero)},
- Test{complex(2, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, -1), complex(-nan, inf), complex(negzero, negzero)},
- Test{complex(2, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(2, -1), complex(-inf, 0), complex(negzero, 0)},
- Test{complex(2, -1), complex(-inf, 1), complex(negzero, 0)},
- Test{complex(2, -1), complex(-inf, -1), complex(negzero, 0)},
- Test{complex(2, -1), complex(-inf, 2), complex(negzero, 0)},
- Test{complex(2, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, -1), complex(-nan, inf), complex(negzero, negzero)},
- Test{complex(2, -1), complex(-nan, -inf), complex(0, 0)},
- Test{complex(2, 2), complex(0, 0), complex(inf, inf)},
- Test{complex(2, 2), complex(0, 1), complex(2, -2)},
- Test{complex(2, 2), complex(0, -1), complex(-2, 2)},
- Test{complex(2, 2), complex(0, 2), complex(1, -1)},
- Test{complex(2, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 2), complex(1, 0), complex(2, 2)},
- Test{complex(2, 2), complex(1, 1), complex(2, 0)},
- Test{complex(2, 2), complex(1, -1), complex(0, 2)},
- Test{complex(2, 2), complex(1, 2), complex(1.2, -0.4)},
- Test{complex(2, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 2), complex(-1, 0), complex(-2, -2)},
- Test{complex(2, 2), complex(-1, 1), complex(negzero, -2)},
- Test{complex(2, 2), complex(-1, -1), complex(-2, negzero)},
- Test{complex(2, 2), complex(-1, 2), complex(0.4, -1.2)},
- Test{complex(2, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 2), complex(2, 0), complex(1, 1)},
- Test{complex(2, 2), complex(2, 1), complex(1.2, 0.4)},
- Test{complex(2, 2), complex(2, -1), complex(0.4, 1.2)},
- Test{complex(2, 2), complex(2, 2), complex(1, 0)},
- Test{complex(2, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 2), complex(nan, 0), complex(nan, nan)},
- Test{complex(2, 2), complex(nan, 1), complex(nan, nan)},
- Test{complex(2, 2), complex(nan, -1), complex(nan, nan)},
- Test{complex(2, 2), complex(nan, 2), complex(nan, nan)},
- Test{complex(2, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 2), complex(inf, 0), complex(0, 0)},
- Test{complex(2, 2), complex(inf, 1), complex(0, 0)},
- Test{complex(2, 2), complex(inf, -1), complex(0, 0)},
- Test{complex(2, 2), complex(inf, 2), complex(0, 0)},
- Test{complex(2, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(2, 2), complex(-inf, 0), complex(negzero, negzero)},
- Test{complex(2, 2), complex(-inf, 1), complex(negzero, negzero)},
- Test{complex(2, 2), complex(-inf, -1), complex(negzero, negzero)},
- Test{complex(2, 2), complex(-inf, 2), complex(negzero, negzero)},
- Test{complex(2, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(2, 2), complex(-nan, inf), complex(0, negzero)},
- Test{complex(2, 2), complex(-nan, -inf), complex(negzero, 0)},
- Test{complex(nan, nan), complex(0, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(-nan, inf), complex(0, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(0, 1), complex(inf, -nan)},
- Test{complex(-nan, inf), complex(0, -1), complex(-inf, -nan)},
- Test{complex(-nan, inf), complex(0, 2), complex(inf, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(1, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(1, 1), complex(inf, inf)},
- Test{complex(-nan, inf), complex(1, -1), complex(-inf, inf)},
- Test{complex(-nan, inf), complex(1, 2), complex(inf, inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-1, 0), complex(-nan, -inf)},
- Test{complex(-nan, inf), complex(-1, 1), complex(inf, -inf)},
- Test{complex(-nan, inf), complex(-1, -1), complex(-inf, -inf)},
- Test{complex(-nan, inf), complex(-1, 2), complex(inf, -inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(2, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(2, 1), complex(inf, inf)},
- Test{complex(-nan, inf), complex(2, -1), complex(-inf, inf)},
- Test{complex(-nan, inf), complex(2, 2), complex(inf, inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, 0), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, 1), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, -1), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, 2), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(0, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(0, 1), complex(-inf, -nan)},
- Test{complex(-nan, -inf), complex(0, -1), complex(inf, -nan)},
- Test{complex(-nan, -inf), complex(0, 2), complex(-inf, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(1, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(1, 1), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(1, -1), complex(inf, -inf)},
- Test{complex(-nan, -inf), complex(1, 2), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-1, 0), complex(-nan, inf)},
- Test{complex(-nan, -inf), complex(-1, 1), complex(-inf, inf)},
- Test{complex(-nan, -inf), complex(-1, -1), complex(inf, inf)},
- Test{complex(-nan, -inf), complex(-1, 2), complex(-inf, inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(2, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(2, 1), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(2, -1), complex(inf, -inf)},
- Test{complex(-nan, -inf), complex(2, 2), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, 0), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, 1), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, -1), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, 2), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 0), complex(0, 0), complex(nan, nan)},
- Test{complex(nan, 0), complex(0, 1), complex(nan, nan)},
- Test{complex(nan, 0), complex(0, -1), complex(nan, nan)},
- Test{complex(nan, 0), complex(0, 2), complex(nan, nan)},
- Test{complex(nan, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 0), complex(1, 0), complex(nan, nan)},
- Test{complex(nan, 0), complex(1, 1), complex(nan, nan)},
- Test{complex(nan, 0), complex(1, -1), complex(nan, nan)},
- Test{complex(nan, 0), complex(1, 2), complex(nan, nan)},
- Test{complex(nan, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 0), complex(-1, 0), complex(nan, nan)},
- Test{complex(nan, 0), complex(-1, 1), complex(nan, nan)},
- Test{complex(nan, 0), complex(-1, -1), complex(nan, nan)},
- Test{complex(nan, 0), complex(-1, 2), complex(nan, nan)},
- Test{complex(nan, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 0), complex(2, 0), complex(nan, nan)},
- Test{complex(nan, 0), complex(2, 1), complex(nan, nan)},
- Test{complex(nan, 0), complex(2, -1), complex(nan, nan)},
- Test{complex(nan, 0), complex(2, 2), complex(nan, nan)},
- Test{complex(nan, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 0), complex(nan, 0), complex(nan, nan)},
- Test{complex(nan, 0), complex(nan, 1), complex(nan, nan)},
- Test{complex(nan, 0), complex(nan, -1), complex(nan, nan)},
- Test{complex(nan, 0), complex(nan, 2), complex(nan, nan)},
- Test{complex(nan, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 0), complex(inf, 0), complex(nan, nan)},
- Test{complex(nan, 0), complex(inf, 1), complex(nan, nan)},
- Test{complex(nan, 0), complex(inf, -1), complex(nan, nan)},
- Test{complex(nan, 0), complex(inf, 2), complex(nan, nan)},
- Test{complex(nan, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 0), complex(-inf, 0), complex(nan, nan)},
- Test{complex(nan, 0), complex(-inf, 1), complex(nan, nan)},
- Test{complex(nan, 0), complex(-inf, -1), complex(nan, nan)},
- Test{complex(nan, 0), complex(-inf, 2), complex(nan, nan)},
- Test{complex(nan, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 1), complex(0, 0), complex(nan, nan)},
- Test{complex(nan, 1), complex(0, 1), complex(nan, nan)},
- Test{complex(nan, 1), complex(0, -1), complex(nan, nan)},
- Test{complex(nan, 1), complex(0, 2), complex(nan, nan)},
- Test{complex(nan, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 1), complex(1, 0), complex(nan, nan)},
- Test{complex(nan, 1), complex(1, 1), complex(nan, nan)},
- Test{complex(nan, 1), complex(1, -1), complex(nan, nan)},
- Test{complex(nan, 1), complex(1, 2), complex(nan, nan)},
- Test{complex(nan, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 1), complex(-1, 0), complex(nan, nan)},
- Test{complex(nan, 1), complex(-1, 1), complex(nan, nan)},
- Test{complex(nan, 1), complex(-1, -1), complex(nan, nan)},
- Test{complex(nan, 1), complex(-1, 2), complex(nan, nan)},
- Test{complex(nan, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 1), complex(2, 0), complex(nan, nan)},
- Test{complex(nan, 1), complex(2, 1), complex(nan, nan)},
- Test{complex(nan, 1), complex(2, -1), complex(nan, nan)},
- Test{complex(nan, 1), complex(2, 2), complex(nan, nan)},
- Test{complex(nan, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 1), complex(nan, 0), complex(nan, nan)},
- Test{complex(nan, 1), complex(nan, 1), complex(nan, nan)},
- Test{complex(nan, 1), complex(nan, -1), complex(nan, nan)},
- Test{complex(nan, 1), complex(nan, 2), complex(nan, nan)},
- Test{complex(nan, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 1), complex(inf, 0), complex(nan, nan)},
- Test{complex(nan, 1), complex(inf, 1), complex(nan, nan)},
- Test{complex(nan, 1), complex(inf, -1), complex(nan, nan)},
- Test{complex(nan, 1), complex(inf, 2), complex(nan, nan)},
- Test{complex(nan, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 1), complex(-inf, 0), complex(nan, nan)},
- Test{complex(nan, 1), complex(-inf, 1), complex(nan, nan)},
- Test{complex(nan, 1), complex(-inf, -1), complex(nan, nan)},
- Test{complex(nan, 1), complex(-inf, 2), complex(nan, nan)},
- Test{complex(nan, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, -1), complex(0, 0), complex(nan, nan)},
- Test{complex(nan, -1), complex(0, 1), complex(nan, nan)},
- Test{complex(nan, -1), complex(0, -1), complex(nan, nan)},
- Test{complex(nan, -1), complex(0, 2), complex(nan, nan)},
- Test{complex(nan, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, -1), complex(1, 0), complex(nan, nan)},
- Test{complex(nan, -1), complex(1, 1), complex(nan, nan)},
- Test{complex(nan, -1), complex(1, -1), complex(nan, nan)},
- Test{complex(nan, -1), complex(1, 2), complex(nan, nan)},
- Test{complex(nan, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, -1), complex(-1, 0), complex(nan, nan)},
- Test{complex(nan, -1), complex(-1, 1), complex(nan, nan)},
- Test{complex(nan, -1), complex(-1, -1), complex(nan, nan)},
- Test{complex(nan, -1), complex(-1, 2), complex(nan, nan)},
- Test{complex(nan, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, -1), complex(2, 0), complex(nan, nan)},
- Test{complex(nan, -1), complex(2, 1), complex(nan, nan)},
- Test{complex(nan, -1), complex(2, -1), complex(nan, nan)},
- Test{complex(nan, -1), complex(2, 2), complex(nan, nan)},
- Test{complex(nan, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, -1), complex(nan, 0), complex(nan, nan)},
- Test{complex(nan, -1), complex(nan, 1), complex(nan, nan)},
- Test{complex(nan, -1), complex(nan, -1), complex(nan, nan)},
- Test{complex(nan, -1), complex(nan, 2), complex(nan, nan)},
- Test{complex(nan, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, -1), complex(inf, 0), complex(nan, nan)},
- Test{complex(nan, -1), complex(inf, 1), complex(nan, nan)},
- Test{complex(nan, -1), complex(inf, -1), complex(nan, nan)},
- Test{complex(nan, -1), complex(inf, 2), complex(nan, nan)},
- Test{complex(nan, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, -1), complex(-inf, 0), complex(nan, nan)},
- Test{complex(nan, -1), complex(-inf, 1), complex(nan, nan)},
- Test{complex(nan, -1), complex(-inf, -1), complex(nan, nan)},
- Test{complex(nan, -1), complex(-inf, 2), complex(nan, nan)},
- Test{complex(nan, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 2), complex(0, 0), complex(nan, nan)},
- Test{complex(nan, 2), complex(0, 1), complex(nan, nan)},
- Test{complex(nan, 2), complex(0, -1), complex(nan, nan)},
- Test{complex(nan, 2), complex(0, 2), complex(nan, nan)},
- Test{complex(nan, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 2), complex(1, 0), complex(nan, nan)},
- Test{complex(nan, 2), complex(1, 1), complex(nan, nan)},
- Test{complex(nan, 2), complex(1, -1), complex(nan, nan)},
- Test{complex(nan, 2), complex(1, 2), complex(nan, nan)},
- Test{complex(nan, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 2), complex(-1, 0), complex(nan, nan)},
- Test{complex(nan, 2), complex(-1, 1), complex(nan, nan)},
- Test{complex(nan, 2), complex(-1, -1), complex(nan, nan)},
- Test{complex(nan, 2), complex(-1, 2), complex(nan, nan)},
- Test{complex(nan, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 2), complex(2, 0), complex(nan, nan)},
- Test{complex(nan, 2), complex(2, 1), complex(nan, nan)},
- Test{complex(nan, 2), complex(2, -1), complex(nan, nan)},
- Test{complex(nan, 2), complex(2, 2), complex(nan, nan)},
- Test{complex(nan, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 2), complex(nan, 0), complex(nan, nan)},
- Test{complex(nan, 2), complex(nan, 1), complex(nan, nan)},
- Test{complex(nan, 2), complex(nan, -1), complex(nan, nan)},
- Test{complex(nan, 2), complex(nan, 2), complex(nan, nan)},
- Test{complex(nan, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 2), complex(inf, 0), complex(nan, nan)},
- Test{complex(nan, 2), complex(inf, 1), complex(nan, nan)},
- Test{complex(nan, 2), complex(inf, -1), complex(nan, nan)},
- Test{complex(nan, 2), complex(inf, 2), complex(nan, nan)},
- Test{complex(nan, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, 2), complex(-inf, 0), complex(nan, nan)},
- Test{complex(nan, 2), complex(-inf, 1), complex(nan, nan)},
- Test{complex(nan, 2), complex(-inf, -1), complex(nan, nan)},
- Test{complex(nan, 2), complex(-inf, 2), complex(nan, nan)},
- Test{complex(nan, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(nan, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, nan), complex(0, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(-nan, inf), complex(0, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(0, 1), complex(inf, -nan)},
- Test{complex(-nan, inf), complex(0, -1), complex(-inf, -nan)},
- Test{complex(-nan, inf), complex(0, 2), complex(inf, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(1, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(1, 1), complex(inf, inf)},
- Test{complex(-nan, inf), complex(1, -1), complex(-inf, inf)},
- Test{complex(-nan, inf), complex(1, 2), complex(inf, inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-1, 0), complex(-nan, -inf)},
- Test{complex(-nan, inf), complex(-1, 1), complex(inf, -inf)},
- Test{complex(-nan, inf), complex(-1, -1), complex(-inf, -inf)},
- Test{complex(-nan, inf), complex(-1, 2), complex(inf, -inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(2, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(2, 1), complex(inf, inf)},
- Test{complex(-nan, inf), complex(2, -1), complex(-inf, inf)},
- Test{complex(-nan, inf), complex(2, 2), complex(inf, inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, 0), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, 1), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, -1), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, 2), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(0, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(0, 1), complex(-inf, -nan)},
- Test{complex(-nan, -inf), complex(0, -1), complex(inf, -nan)},
- Test{complex(-nan, -inf), complex(0, 2), complex(-inf, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(1, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(1, 1), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(1, -1), complex(inf, -inf)},
- Test{complex(-nan, -inf), complex(1, 2), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-1, 0), complex(-nan, inf)},
- Test{complex(-nan, -inf), complex(-1, 1), complex(-inf, inf)},
- Test{complex(-nan, -inf), complex(-1, -1), complex(inf, inf)},
- Test{complex(-nan, -inf), complex(-1, 2), complex(-inf, inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(2, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(2, 1), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(2, -1), complex(inf, -inf)},
- Test{complex(-nan, -inf), complex(2, 2), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, 0), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, 1), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, -1), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, 2), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(0, 0), complex(inf, -nan)},
- Test{complex(inf, 0), complex(0, 1), complex(-nan, -inf)},
- Test{complex(inf, 0), complex(0, -1), complex(-nan, inf)},
- Test{complex(inf, 0), complex(0, 2), complex(-nan, -inf)},
- Test{complex(inf, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(1, 0), complex(inf, -nan)},
- Test{complex(inf, 0), complex(1, 1), complex(inf, -inf)},
- Test{complex(inf, 0), complex(1, -1), complex(inf, inf)},
- Test{complex(inf, 0), complex(1, 2), complex(inf, -inf)},
- Test{complex(inf, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(-1, 0), complex(-inf, -nan)},
- Test{complex(inf, 0), complex(-1, 1), complex(-inf, -inf)},
- Test{complex(inf, 0), complex(-1, -1), complex(-inf, inf)},
- Test{complex(inf, 0), complex(-1, 2), complex(-inf, -inf)},
- Test{complex(inf, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(2, 0), complex(inf, -nan)},
- Test{complex(inf, 0), complex(2, 1), complex(inf, -inf)},
- Test{complex(inf, 0), complex(2, -1), complex(inf, inf)},
- Test{complex(inf, 0), complex(2, 2), complex(inf, -inf)},
- Test{complex(inf, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(nan, 0), complex(nan, nan)},
- Test{complex(inf, 0), complex(nan, 1), complex(nan, nan)},
- Test{complex(inf, 0), complex(nan, -1), complex(nan, nan)},
- Test{complex(inf, 0), complex(nan, 2), complex(nan, nan)},
- Test{complex(inf, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(0, 0), complex(inf, inf)},
- Test{complex(inf, 1), complex(0, 1), complex(-nan, -inf)},
- Test{complex(inf, 1), complex(0, -1), complex(-nan, inf)},
- Test{complex(inf, 1), complex(0, 2), complex(-nan, -inf)},
- Test{complex(inf, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(1, 0), complex(inf, -nan)},
- Test{complex(inf, 1), complex(1, 1), complex(inf, -inf)},
- Test{complex(inf, 1), complex(1, -1), complex(inf, inf)},
- Test{complex(inf, 1), complex(1, 2), complex(inf, -inf)},
- Test{complex(inf, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(-1, 0), complex(-inf, -nan)},
- Test{complex(inf, 1), complex(-1, 1), complex(-inf, -inf)},
- Test{complex(inf, 1), complex(-1, -1), complex(-inf, inf)},
- Test{complex(inf, 1), complex(-1, 2), complex(-inf, -inf)},
- Test{complex(inf, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(2, 0), complex(inf, -nan)},
- Test{complex(inf, 1), complex(2, 1), complex(inf, -inf)},
- Test{complex(inf, 1), complex(2, -1), complex(inf, inf)},
- Test{complex(inf, 1), complex(2, 2), complex(inf, -inf)},
- Test{complex(inf, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(nan, 0), complex(nan, nan)},
- Test{complex(inf, 1), complex(nan, 1), complex(nan, nan)},
- Test{complex(inf, 1), complex(nan, -1), complex(nan, nan)},
- Test{complex(inf, 1), complex(nan, 2), complex(nan, nan)},
- Test{complex(inf, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(0, 0), complex(inf, -inf)},
- Test{complex(inf, -1), complex(0, 1), complex(-nan, -inf)},
- Test{complex(inf, -1), complex(0, -1), complex(-nan, inf)},
- Test{complex(inf, -1), complex(0, 2), complex(-nan, -inf)},
- Test{complex(inf, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(1, 0), complex(inf, -nan)},
- Test{complex(inf, -1), complex(1, 1), complex(inf, -inf)},
- Test{complex(inf, -1), complex(1, -1), complex(inf, inf)},
- Test{complex(inf, -1), complex(1, 2), complex(inf, -inf)},
- Test{complex(inf, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(-1, 0), complex(-inf, -nan)},
- Test{complex(inf, -1), complex(-1, 1), complex(-inf, -inf)},
- Test{complex(inf, -1), complex(-1, -1), complex(-inf, inf)},
- Test{complex(inf, -1), complex(-1, 2), complex(-inf, -inf)},
- Test{complex(inf, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(2, 0), complex(inf, -nan)},
- Test{complex(inf, -1), complex(2, 1), complex(inf, -inf)},
- Test{complex(inf, -1), complex(2, -1), complex(inf, inf)},
- Test{complex(inf, -1), complex(2, 2), complex(inf, -inf)},
- Test{complex(inf, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(nan, 0), complex(nan, nan)},
- Test{complex(inf, -1), complex(nan, 1), complex(nan, nan)},
- Test{complex(inf, -1), complex(nan, -1), complex(nan, nan)},
- Test{complex(inf, -1), complex(nan, 2), complex(nan, nan)},
- Test{complex(inf, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(0, 0), complex(inf, inf)},
- Test{complex(inf, 2), complex(0, 1), complex(-nan, -inf)},
- Test{complex(inf, 2), complex(0, -1), complex(-nan, inf)},
- Test{complex(inf, 2), complex(0, 2), complex(-nan, -inf)},
- Test{complex(inf, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(1, 0), complex(inf, -nan)},
- Test{complex(inf, 2), complex(1, 1), complex(inf, -inf)},
- Test{complex(inf, 2), complex(1, -1), complex(inf, inf)},
- Test{complex(inf, 2), complex(1, 2), complex(inf, -inf)},
- Test{complex(inf, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(-1, 0), complex(-inf, -nan)},
- Test{complex(inf, 2), complex(-1, 1), complex(-inf, -inf)},
- Test{complex(inf, 2), complex(-1, -1), complex(-inf, inf)},
- Test{complex(inf, 2), complex(-1, 2), complex(-inf, -inf)},
- Test{complex(inf, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(2, 0), complex(inf, -nan)},
- Test{complex(inf, 2), complex(2, 1), complex(inf, -inf)},
- Test{complex(inf, 2), complex(2, -1), complex(inf, inf)},
- Test{complex(inf, 2), complex(2, 2), complex(inf, -inf)},
- Test{complex(inf, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(nan, 0), complex(nan, nan)},
- Test{complex(inf, 2), complex(nan, 1), complex(nan, nan)},
- Test{complex(inf, 2), complex(nan, -1), complex(nan, nan)},
- Test{complex(inf, 2), complex(nan, 2), complex(nan, nan)},
- Test{complex(inf, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(inf, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(inf, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, nan), complex(0, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(-nan, inf), complex(0, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(0, 1), complex(inf, -nan)},
- Test{complex(-nan, inf), complex(0, -1), complex(-inf, -nan)},
- Test{complex(-nan, inf), complex(0, 2), complex(inf, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(1, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(1, 1), complex(inf, inf)},
- Test{complex(-nan, inf), complex(1, -1), complex(-inf, inf)},
- Test{complex(-nan, inf), complex(1, 2), complex(inf, inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-1, 0), complex(-nan, -inf)},
- Test{complex(-nan, inf), complex(-1, 1), complex(inf, -inf)},
- Test{complex(-nan, inf), complex(-1, -1), complex(-inf, -inf)},
- Test{complex(-nan, inf), complex(-1, 2), complex(inf, -inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(2, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(2, 1), complex(inf, inf)},
- Test{complex(-nan, inf), complex(2, -1), complex(-inf, inf)},
- Test{complex(-nan, inf), complex(2, 2), complex(inf, inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, 0), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, 1), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, -1), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, 2), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(0, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(0, 1), complex(-inf, -nan)},
- Test{complex(-nan, -inf), complex(0, -1), complex(inf, -nan)},
- Test{complex(-nan, -inf), complex(0, 2), complex(-inf, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(1, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(1, 1), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(1, -1), complex(inf, -inf)},
- Test{complex(-nan, -inf), complex(1, 2), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-1, 0), complex(-nan, inf)},
- Test{complex(-nan, -inf), complex(-1, 1), complex(-inf, inf)},
- Test{complex(-nan, -inf), complex(-1, -1), complex(inf, inf)},
- Test{complex(-nan, -inf), complex(-1, 2), complex(-inf, inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(2, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(2, 1), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(2, -1), complex(inf, -inf)},
- Test{complex(-nan, -inf), complex(2, 2), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, 0), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, 1), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, -1), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, 2), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(0, 0), complex(-inf, -nan)},
- Test{complex(-inf, 0), complex(0, 1), complex(-nan, inf)},
- Test{complex(-inf, 0), complex(0, -1), complex(-nan, -inf)},
- Test{complex(-inf, 0), complex(0, 2), complex(-nan, inf)},
- Test{complex(-inf, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(1, 0), complex(-inf, -nan)},
- Test{complex(-inf, 0), complex(1, 1), complex(-inf, inf)},
- Test{complex(-inf, 0), complex(1, -1), complex(-inf, -inf)},
- Test{complex(-inf, 0), complex(1, 2), complex(-inf, inf)},
- Test{complex(-inf, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(-1, 0), complex(inf, -nan)},
- Test{complex(-inf, 0), complex(-1, 1), complex(inf, inf)},
- Test{complex(-inf, 0), complex(-1, -1), complex(inf, -inf)},
- Test{complex(-inf, 0), complex(-1, 2), complex(inf, inf)},
- Test{complex(-inf, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(2, 0), complex(-inf, -nan)},
- Test{complex(-inf, 0), complex(2, 1), complex(-inf, inf)},
- Test{complex(-inf, 0), complex(2, -1), complex(-inf, -inf)},
- Test{complex(-inf, 0), complex(2, 2), complex(-inf, inf)},
- Test{complex(-inf, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(nan, 0), complex(nan, nan)},
- Test{complex(-inf, 0), complex(nan, 1), complex(nan, nan)},
- Test{complex(-inf, 0), complex(nan, -1), complex(nan, nan)},
- Test{complex(-inf, 0), complex(nan, 2), complex(nan, nan)},
- Test{complex(-inf, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 0), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 0), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(0, 0), complex(-inf, inf)},
- Test{complex(-inf, 1), complex(0, 1), complex(-nan, inf)},
- Test{complex(-inf, 1), complex(0, -1), complex(-nan, -inf)},
- Test{complex(-inf, 1), complex(0, 2), complex(-nan, inf)},
- Test{complex(-inf, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(1, 0), complex(-inf, -nan)},
- Test{complex(-inf, 1), complex(1, 1), complex(-inf, inf)},
- Test{complex(-inf, 1), complex(1, -1), complex(-inf, -inf)},
- Test{complex(-inf, 1), complex(1, 2), complex(-inf, inf)},
- Test{complex(-inf, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(-1, 0), complex(inf, -nan)},
- Test{complex(-inf, 1), complex(-1, 1), complex(inf, inf)},
- Test{complex(-inf, 1), complex(-1, -1), complex(inf, -inf)},
- Test{complex(-inf, 1), complex(-1, 2), complex(inf, inf)},
- Test{complex(-inf, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(2, 0), complex(-inf, -nan)},
- Test{complex(-inf, 1), complex(2, 1), complex(-inf, inf)},
- Test{complex(-inf, 1), complex(2, -1), complex(-inf, -inf)},
- Test{complex(-inf, 1), complex(2, 2), complex(-inf, inf)},
- Test{complex(-inf, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(nan, 0), complex(nan, nan)},
- Test{complex(-inf, 1), complex(nan, 1), complex(nan, nan)},
- Test{complex(-inf, 1), complex(nan, -1), complex(nan, nan)},
- Test{complex(-inf, 1), complex(nan, 2), complex(nan, nan)},
- Test{complex(-inf, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(0, 0), complex(-inf, -inf)},
- Test{complex(-inf, -1), complex(0, 1), complex(-nan, inf)},
- Test{complex(-inf, -1), complex(0, -1), complex(-nan, -inf)},
- Test{complex(-inf, -1), complex(0, 2), complex(-nan, inf)},
- Test{complex(-inf, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(1, 0), complex(-inf, -nan)},
- Test{complex(-inf, -1), complex(1, 1), complex(-inf, inf)},
- Test{complex(-inf, -1), complex(1, -1), complex(-inf, -inf)},
- Test{complex(-inf, -1), complex(1, 2), complex(-inf, inf)},
- Test{complex(-inf, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(-1, 0), complex(inf, -nan)},
- Test{complex(-inf, -1), complex(-1, 1), complex(inf, inf)},
- Test{complex(-inf, -1), complex(-1, -1), complex(inf, -inf)},
- Test{complex(-inf, -1), complex(-1, 2), complex(inf, inf)},
- Test{complex(-inf, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(2, 0), complex(-inf, -nan)},
- Test{complex(-inf, -1), complex(2, 1), complex(-inf, inf)},
- Test{complex(-inf, -1), complex(2, -1), complex(-inf, -inf)},
- Test{complex(-inf, -1), complex(2, 2), complex(-inf, inf)},
- Test{complex(-inf, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(nan, 0), complex(nan, nan)},
- Test{complex(-inf, -1), complex(nan, 1), complex(nan, nan)},
- Test{complex(-inf, -1), complex(nan, -1), complex(nan, nan)},
- Test{complex(-inf, -1), complex(nan, 2), complex(nan, nan)},
- Test{complex(-inf, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, -1), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, -1), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(0, 0), complex(-inf, inf)},
- Test{complex(-inf, 2), complex(0, 1), complex(-nan, inf)},
- Test{complex(-inf, 2), complex(0, -1), complex(-nan, -inf)},
- Test{complex(-inf, 2), complex(0, 2), complex(-nan, inf)},
- Test{complex(-inf, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(1, 0), complex(-inf, -nan)},
- Test{complex(-inf, 2), complex(1, 1), complex(-inf, inf)},
- Test{complex(-inf, 2), complex(1, -1), complex(-inf, -inf)},
- Test{complex(-inf, 2), complex(1, 2), complex(-inf, inf)},
- Test{complex(-inf, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(-1, 0), complex(inf, -nan)},
- Test{complex(-inf, 2), complex(-1, 1), complex(inf, inf)},
- Test{complex(-inf, 2), complex(-1, -1), complex(inf, -inf)},
- Test{complex(-inf, 2), complex(-1, 2), complex(inf, inf)},
- Test{complex(-inf, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(2, 0), complex(-inf, -nan)},
- Test{complex(-inf, 2), complex(2, 1), complex(-inf, inf)},
- Test{complex(-inf, 2), complex(2, -1), complex(-inf, -inf)},
- Test{complex(-inf, 2), complex(2, 2), complex(-inf, inf)},
- Test{complex(-inf, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(nan, 0), complex(nan, nan)},
- Test{complex(-inf, 2), complex(nan, 1), complex(nan, nan)},
- Test{complex(-inf, 2), complex(nan, -1), complex(nan, nan)},
- Test{complex(-inf, 2), complex(nan, 2), complex(nan, nan)},
- Test{complex(-inf, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(nan, nan), complex(nan, nan)},
- Test{complex(-inf, 2), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-inf, 2), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(nan, nan), complex(0, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(0, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(1, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-1, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(2, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(inf, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 0), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, -1), complex(nan, nan)},
- Test{complex(nan, nan), complex(-inf, 2), complex(nan, nan)},
- Test{complex(nan, nan), complex(nan, nan), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, inf), complex(nan, nan)},
- Test{complex(nan, nan), complex(-nan, -inf), complex(nan, nan)},
- Test{complex(-nan, inf), complex(0, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(0, 1), complex(inf, -nan)},
- Test{complex(-nan, inf), complex(0, -1), complex(-inf, -nan)},
- Test{complex(-nan, inf), complex(0, 2), complex(inf, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(1, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(1, 1), complex(inf, inf)},
- Test{complex(-nan, inf), complex(1, -1), complex(-inf, inf)},
- Test{complex(-nan, inf), complex(1, 2), complex(inf, inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-1, 0), complex(-nan, -inf)},
- Test{complex(-nan, inf), complex(-1, 1), complex(inf, -inf)},
- Test{complex(-nan, inf), complex(-1, -1), complex(-inf, -inf)},
- Test{complex(-nan, inf), complex(-1, 2), complex(inf, -inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(2, 0), complex(-nan, inf)},
- Test{complex(-nan, inf), complex(2, 1), complex(inf, inf)},
- Test{complex(-nan, inf), complex(2, -1), complex(-inf, inf)},
- Test{complex(-nan, inf), complex(2, 2), complex(inf, inf)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, 0), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, 1), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, -1), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, 2), complex(nan, nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(0, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(0, 1), complex(-inf, -nan)},
- Test{complex(-nan, -inf), complex(0, -1), complex(inf, -nan)},
- Test{complex(-nan, -inf), complex(0, 2), complex(-inf, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(1, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(1, 1), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(1, -1), complex(inf, -inf)},
- Test{complex(-nan, -inf), complex(1, 2), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-1, 0), complex(-nan, inf)},
- Test{complex(-nan, -inf), complex(-1, 1), complex(-inf, inf)},
- Test{complex(-nan, -inf), complex(-1, -1), complex(inf, inf)},
- Test{complex(-nan, -inf), complex(-1, 2), complex(-inf, inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(2, 0), complex(-nan, -inf)},
- Test{complex(-nan, -inf), complex(2, 1), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(2, -1), complex(inf, -inf)},
- Test{complex(-nan, -inf), complex(2, 2), complex(-inf, -inf)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, 0), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, 1), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, -1), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, 2), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 0), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, -1), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-inf, 2), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(nan, nan), complex(nan, nan)},
- Test{complex(-nan, -inf), complex(-nan, inf), complex(-nan, -nan)},
- Test{complex(-nan, -inf), complex(-nan, -inf), complex(-nan, -nan)},
+
+import "math"
+
+var (
+ nan = math.NaN()
+ inf = math.Inf(1)
+ zero = 0.0
+)
+
+var tests = []struct {
+ f, g complex128
+ out complex128
+}{
+ {complex(zero, zero), complex(zero, zero), complex(nan, nan)},
+ {complex(zero, zero), complex(zero, -zero), complex(nan, nan)},
+ {complex(zero, zero), complex(zero, 1), complex(zero, zero)},
+ {complex(zero, zero), complex(zero, -1), complex(-zero, zero)},
+ {complex(zero, zero), complex(zero, 2), complex(zero, zero)},
+ {complex(zero, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, zero), complex(zero, zero), complex(nan, nan)},
+ {complex(zero, zero), complex(-zero, -zero), complex(nan, nan)},
+ {complex(zero, zero), complex(zero, 1), complex(zero, zero)},
+ {complex(zero, zero), complex(-zero, -1), complex(-zero, -zero)},
+ {complex(zero, zero), complex(zero, 2), complex(zero, zero)},
+ {complex(zero, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, zero), complex(1, zero), complex(zero, zero)},
+ {complex(zero, zero), complex(1, -zero), complex(zero, zero)},
+ {complex(zero, zero), complex(1, 1), complex(zero, zero)},
+ {complex(zero, zero), complex(1, -1), complex(zero, zero)},
+ {complex(zero, zero), complex(1, 2), complex(zero, zero)},
+ {complex(zero, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, zero), complex(-1, zero), complex(-zero, -zero)},
+ {complex(zero, zero), complex(-1, -zero), complex(-zero, -zero)},
+ {complex(zero, zero), complex(-1, 1), complex(-zero, -zero)},
+ {complex(zero, zero), complex(-1, -1), complex(-zero, -zero)},
+ {complex(zero, zero), complex(-1, 2), complex(zero, -zero)},
+ {complex(zero, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, zero), complex(2, zero), complex(zero, zero)},
+ {complex(zero, zero), complex(2, -zero), complex(zero, zero)},
+ {complex(zero, zero), complex(2, 1), complex(zero, zero)},
+ {complex(zero, zero), complex(2, -1), complex(zero, zero)},
+ {complex(zero, zero), complex(2, 2), complex(zero, zero)},
+ {complex(zero, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, zero), complex(nan, zero), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, -zero), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, 1), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, -1), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, 2), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, zero), complex(inf, zero), complex(zero, zero)},
+ {complex(zero, zero), complex(inf, -zero), complex(zero, zero)},
+ {complex(zero, zero), complex(inf, 1), complex(zero, zero)},
+ {complex(zero, zero), complex(inf, -1), complex(zero, zero)},
+ {complex(zero, zero), complex(inf, 2), complex(zero, zero)},
+ {complex(zero, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, zero), complex(-inf, zero), complex(-zero, -zero)},
+ {complex(zero, zero), complex(-inf, -zero), complex(-zero, -zero)},
+ {complex(zero, zero), complex(-inf, 1), complex(-zero, -zero)},
+ {complex(zero, zero), complex(-inf, -1), complex(-zero, -zero)},
+ {complex(zero, zero), complex(-inf, 2), complex(-zero, -zero)},
+ {complex(zero, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, -zero), complex(zero, zero), complex(nan, nan)},
+ {complex(zero, -zero), complex(zero, -zero), complex(nan, nan)},
+ {complex(zero, -zero), complex(zero, 1), complex(zero, -zero)},
+ {complex(zero, -zero), complex(zero, -1), complex(zero, -zero)},
+ {complex(zero, -zero), complex(zero, 2), complex(zero, -zero)},
+ {complex(zero, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, -zero), complex(nan, inf), complex(-zero, zero)},
+ {complex(zero, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(zero, -zero), complex(zero, zero), complex(nan, nan)},
+ {complex(zero, -zero), complex(-zero, -zero), complex(nan, nan)},
+ {complex(zero, -zero), complex(zero, 1), complex(zero, -zero)},
+ {complex(zero, -zero), complex(-zero, -1), complex(-zero, zero)},
+ {complex(zero, -zero), complex(zero, 2), complex(zero, -zero)},
+ {complex(zero, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, -zero), complex(nan, inf), complex(-zero, zero)},
+ {complex(zero, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(zero, -zero), complex(1, zero), complex(zero, -zero)},
+ {complex(zero, -zero), complex(1, -zero), complex(zero, zero)},
+ {complex(zero, -zero), complex(1, 1), complex(zero, -zero)},
+ {complex(zero, -zero), complex(1, -1), complex(zero, zero)},
+ {complex(zero, -zero), complex(1, 2), complex(zero, -zero)},
+ {complex(zero, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, -zero), complex(nan, inf), complex(-zero, zero)},
+ {complex(zero, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(zero, -zero), complex(-1, zero), complex(-zero, -zero)},
+ {complex(zero, -zero), complex(-1, -zero), complex(-zero, zero)},
+ {complex(zero, -zero), complex(-1, 1), complex(-zero, -zero)},
+ {complex(zero, -zero), complex(-1, -1), complex(-zero, zero)},
+ {complex(zero, -zero), complex(-1, 2), complex(-zero, zero)},
+ {complex(zero, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, -zero), complex(nan, inf), complex(-zero, zero)},
+ {complex(zero, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(zero, -zero), complex(2, zero), complex(zero, -zero)},
+ {complex(zero, -zero), complex(2, -zero), complex(zero, zero)},
+ {complex(zero, -zero), complex(2, 1), complex(zero, -zero)},
+ {complex(zero, -zero), complex(2, -1), complex(zero, zero)},
+ {complex(zero, -zero), complex(2, 2), complex(zero, -zero)},
+ {complex(zero, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, -zero), complex(nan, inf), complex(-zero, zero)},
+ {complex(zero, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(zero, -zero), complex(nan, zero), complex(nan, nan)},
+ {complex(zero, -zero), complex(nan, -zero), complex(nan, nan)},
+ {complex(zero, -zero), complex(nan, 1), complex(nan, nan)},
+ {complex(zero, -zero), complex(nan, -1), complex(nan, nan)},
+ {complex(zero, -zero), complex(nan, 2), complex(nan, nan)},
+ {complex(zero, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, -zero), complex(nan, inf), complex(-zero, zero)},
+ {complex(zero, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(zero, -zero), complex(inf, zero), complex(zero, -zero)},
+ {complex(zero, -zero), complex(inf, -zero), complex(zero, zero)},
+ {complex(zero, -zero), complex(inf, 1), complex(zero, -zero)},
+ {complex(zero, -zero), complex(inf, -1), complex(zero, zero)},
+ {complex(zero, -zero), complex(inf, 2), complex(zero, -zero)},
+ {complex(zero, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, -zero), complex(nan, inf), complex(-zero, zero)},
+ {complex(zero, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(zero, -zero), complex(-inf, zero), complex(-zero, -zero)},
+ {complex(zero, -zero), complex(-inf, -zero), complex(-zero, zero)},
+ {complex(zero, -zero), complex(-inf, 1), complex(-zero, -zero)},
+ {complex(zero, -zero), complex(-inf, -1), complex(-zero, zero)},
+ {complex(zero, -zero), complex(-inf, 2), complex(-zero, -zero)},
+ {complex(zero, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, -zero), complex(nan, inf), complex(-zero, zero)},
+ {complex(zero, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(zero, 1), complex(zero, zero), complex(nan, inf)},
+ {complex(zero, 1), complex(zero, -zero), complex(nan, inf)},
+ {complex(zero, 1), complex(zero, 1), complex(1, zero)},
+ {complex(zero, 1), complex(zero, -1), complex(-1, zero)},
+ {complex(zero, 1), complex(zero, 2), complex(0.5, zero)},
+ {complex(zero, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 1), complex(zero, zero), complex(nan, inf)},
+ {complex(zero, 1), complex(-zero, -zero), complex(nan, -inf)},
+ {complex(zero, 1), complex(zero, 1), complex(1, zero)},
+ {complex(zero, 1), complex(-zero, -1), complex(-1, -zero)},
+ {complex(zero, 1), complex(zero, 2), complex(0.5, zero)},
+ {complex(zero, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 1), complex(1, zero), complex(zero, 1)},
+ {complex(zero, 1), complex(1, -zero), complex(zero, 1)},
+ {complex(zero, 1), complex(1, 1), complex(0.5, 0.5)},
+ {complex(zero, 1), complex(1, -1), complex(-0.5, 0.5)},
+ {complex(zero, 1), complex(1, 2), complex(0.4, 0.2)},
+ {complex(zero, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 1), complex(-1, zero), complex(-zero, -1)},
+ {complex(zero, 1), complex(-1, -zero), complex(-zero, -1)},
+ {complex(zero, 1), complex(-1, 1), complex(0.5, -0.5)},
+ {complex(zero, 1), complex(-1, -1), complex(-0.5, -0.5)},
+ {complex(zero, 1), complex(-1, 2), complex(0.4, -0.2)},
+ {complex(zero, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 1), complex(2, zero), complex(zero, 0.5)},
+ {complex(zero, 1), complex(2, -zero), complex(zero, 0.5)},
+ {complex(zero, 1), complex(2, 1), complex(0.2, 0.4)},
+ {complex(zero, 1), complex(2, -1), complex(-0.2, 0.4)},
+ {complex(zero, 1), complex(2, 2), complex(0.25, 0.25)},
+ {complex(zero, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 1), complex(nan, zero), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, -zero), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, 1), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, -1), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, 2), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 1), complex(inf, zero), complex(zero, zero)},
+ {complex(zero, 1), complex(inf, -zero), complex(zero, zero)},
+ {complex(zero, 1), complex(inf, 1), complex(zero, zero)},
+ {complex(zero, 1), complex(inf, -1), complex(zero, zero)},
+ {complex(zero, 1), complex(inf, 2), complex(zero, zero)},
+ {complex(zero, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 1), complex(-inf, zero), complex(-zero, -zero)},
+ {complex(zero, 1), complex(-inf, -zero), complex(-zero, -zero)},
+ {complex(zero, 1), complex(-inf, 1), complex(-zero, -zero)},
+ {complex(zero, 1), complex(-inf, -1), complex(-zero, -zero)},
+ {complex(zero, 1), complex(-inf, 2), complex(-zero, -zero)},
+ {complex(zero, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, -1), complex(zero, zero), complex(nan, -inf)},
+ {complex(zero, -1), complex(zero, -zero), complex(nan, -inf)},
+ {complex(zero, -1), complex(zero, 1), complex(-1, -zero)},
+ {complex(zero, -1), complex(zero, -1), complex(1, -zero)},
+ {complex(zero, -1), complex(zero, 2), complex(-0.5, -zero)},
+ {complex(zero, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(zero, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(zero, -1), complex(zero, zero), complex(nan, -inf)},
+ {complex(zero, -1), complex(-zero, -zero), complex(nan, inf)},
+ {complex(zero, -1), complex(zero, 1), complex(-1, -zero)},
+ {complex(zero, -1), complex(-zero, -1), complex(1, zero)},
+ {complex(zero, -1), complex(zero, 2), complex(-0.5, -zero)},
+ {complex(zero, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(zero, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(zero, -1), complex(1, zero), complex(zero, -1)},
+ {complex(zero, -1), complex(1, -zero), complex(zero, -1)},
+ {complex(zero, -1), complex(1, 1), complex(-0.5, -0.5)},
+ {complex(zero, -1), complex(1, -1), complex(0.5, -0.5)},
+ {complex(zero, -1), complex(1, 2), complex(-0.4, -0.2)},
+ {complex(zero, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(zero, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(zero, -1), complex(-1, zero), complex(-zero, 1)},
+ {complex(zero, -1), complex(-1, -zero), complex(-zero, 1)},
+ {complex(zero, -1), complex(-1, 1), complex(-0.5, 0.5)},
+ {complex(zero, -1), complex(-1, -1), complex(0.5, 0.5)},
+ {complex(zero, -1), complex(-1, 2), complex(-0.4, 0.2)},
+ {complex(zero, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(zero, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(zero, -1), complex(2, zero), complex(zero, -0.5)},
+ {complex(zero, -1), complex(2, -zero), complex(zero, -0.5)},
+ {complex(zero, -1), complex(2, 1), complex(-0.2, -0.4)},
+ {complex(zero, -1), complex(2, -1), complex(0.2, -0.4)},
+ {complex(zero, -1), complex(2, 2), complex(-0.25, -0.25)},
+ {complex(zero, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(zero, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(zero, -1), complex(nan, zero), complex(nan, nan)},
+ {complex(zero, -1), complex(nan, -zero), complex(nan, nan)},
+ {complex(zero, -1), complex(nan, 1), complex(nan, nan)},
+ {complex(zero, -1), complex(nan, -1), complex(nan, nan)},
+ {complex(zero, -1), complex(nan, 2), complex(nan, nan)},
+ {complex(zero, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(zero, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(zero, -1), complex(inf, zero), complex(zero, -zero)},
+ {complex(zero, -1), complex(inf, -zero), complex(zero, -zero)},
+ {complex(zero, -1), complex(inf, 1), complex(zero, -zero)},
+ {complex(zero, -1), complex(inf, -1), complex(zero, -zero)},
+ {complex(zero, -1), complex(inf, 2), complex(zero, -zero)},
+ {complex(zero, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(zero, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(zero, -1), complex(-inf, zero), complex(-zero, zero)},
+ {complex(zero, -1), complex(-inf, -zero), complex(-zero, zero)},
+ {complex(zero, -1), complex(-inf, 1), complex(-zero, zero)},
+ {complex(zero, -1), complex(-inf, -1), complex(-zero, zero)},
+ {complex(zero, -1), complex(-inf, 2), complex(-zero, zero)},
+ {complex(zero, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(zero, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(zero, 2), complex(zero, zero), complex(nan, inf)},
+ {complex(zero, 2), complex(zero, -zero), complex(nan, inf)},
+ {complex(zero, 2), complex(zero, 1), complex(2, zero)},
+ {complex(zero, 2), complex(zero, -1), complex(-2, zero)},
+ {complex(zero, 2), complex(zero, 2), complex(1, zero)},
+ {complex(zero, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 2), complex(zero, zero), complex(nan, inf)},
+ {complex(zero, 2), complex(-zero, -zero), complex(nan, -inf)},
+ {complex(zero, 2), complex(zero, 1), complex(2, zero)},
+ {complex(zero, 2), complex(-zero, -1), complex(-2, -zero)},
+ {complex(zero, 2), complex(zero, 2), complex(1, zero)},
+ {complex(zero, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 2), complex(1, zero), complex(zero, 2)},
+ {complex(zero, 2), complex(1, -zero), complex(zero, 2)},
+ {complex(zero, 2), complex(1, 1), complex(1, 1)},
+ {complex(zero, 2), complex(1, -1), complex(-1, 1)},
+ {complex(zero, 2), complex(1, 2), complex(0.8, 0.4)},
+ {complex(zero, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 2), complex(-1, zero), complex(-zero, -2)},
+ {complex(zero, 2), complex(-1, -zero), complex(-zero, -2)},
+ {complex(zero, 2), complex(-1, 1), complex(1, -1)},
+ {complex(zero, 2), complex(-1, -1), complex(-1, -1)},
+ {complex(zero, 2), complex(-1, 2), complex(0.8, -0.4)},
+ {complex(zero, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 2), complex(2, zero), complex(zero, 1)},
+ {complex(zero, 2), complex(2, -zero), complex(zero, 1)},
+ {complex(zero, 2), complex(2, 1), complex(0.4, 0.8)},
+ {complex(zero, 2), complex(2, -1), complex(-0.4, 0.8)},
+ {complex(zero, 2), complex(2, 2), complex(0.5, 0.5)},
+ {complex(zero, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 2), complex(nan, zero), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, -zero), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, 1), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, -1), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, 2), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 2), complex(inf, zero), complex(zero, zero)},
+ {complex(zero, 2), complex(inf, -zero), complex(zero, zero)},
+ {complex(zero, 2), complex(inf, 1), complex(zero, zero)},
+ {complex(zero, 2), complex(inf, -1), complex(zero, zero)},
+ {complex(zero, 2), complex(inf, 2), complex(zero, zero)},
+ {complex(zero, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 2), complex(-inf, zero), complex(-zero, -zero)},
+ {complex(zero, 2), complex(-inf, -zero), complex(-zero, -zero)},
+ {complex(zero, 2), complex(-inf, 1), complex(-zero, -zero)},
+ {complex(zero, 2), complex(-inf, -1), complex(-zero, -zero)},
+ {complex(zero, 2), complex(-inf, 2), complex(-zero, -zero)},
+ {complex(zero, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(nan, nan), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-zero, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-zero, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(1, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(1, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(1, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(1, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(1, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(2, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(2, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(2, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(2, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(2, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(zero, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(zero, 1), complex(inf, nan)},
+ {complex(nan, inf), complex(zero, -1), complex(-inf, nan)},
+ {complex(nan, inf), complex(zero, 2), complex(inf, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(-zero, -zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(zero, 1), complex(inf, nan)},
+ {complex(nan, inf), complex(-zero, -1), complex(-inf, nan)},
+ {complex(nan, inf), complex(zero, 2), complex(inf, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(1, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(1, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(1, 1), complex(inf, inf)},
+ {complex(nan, inf), complex(1, -1), complex(-inf, inf)},
+ {complex(nan, inf), complex(1, 2), complex(inf, inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(-1, zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(-1, -zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(-1, 1), complex(inf, -inf)},
+ {complex(nan, inf), complex(-1, -1), complex(-inf, -inf)},
+ {complex(nan, inf), complex(-1, 2), complex(inf, -inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(2, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(2, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(2, 1), complex(inf, inf)},
+ {complex(nan, inf), complex(2, -1), complex(-inf, inf)},
+ {complex(nan, inf), complex(2, 2), complex(inf, inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(zero, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(zero, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(zero, 1), complex(-inf, nan)},
+ {complex(nan, -inf), complex(zero, -1), complex(inf, nan)},
+ {complex(nan, -inf), complex(zero, 2), complex(-inf, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(zero, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(-zero, -zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(zero, 1), complex(-inf, nan)},
+ {complex(nan, -inf), complex(-zero, -1), complex(inf, nan)},
+ {complex(nan, -inf), complex(zero, 2), complex(-inf, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(1, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(1, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(1, 1), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(1, -1), complex(inf, -inf)},
+ {complex(nan, -inf), complex(1, 2), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(-1, zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(-1, -zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(-1, 1), complex(-inf, inf)},
+ {complex(nan, -inf), complex(-1, -1), complex(inf, inf)},
+ {complex(nan, -inf), complex(-1, 2), complex(-inf, inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(2, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(2, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(2, 1), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(2, -1), complex(inf, -inf)},
+ {complex(nan, -inf), complex(2, 2), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(zero, zero), complex(zero, zero), complex(nan, nan)},
+ {complex(zero, zero), complex(zero, -zero), complex(nan, nan)},
+ {complex(zero, zero), complex(zero, 1), complex(zero, zero)},
+ {complex(zero, zero), complex(zero, -1), complex(-zero, zero)},
+ {complex(zero, zero), complex(zero, 2), complex(zero, zero)},
+ {complex(zero, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, zero), complex(zero, zero), complex(nan, nan)},
+ {complex(zero, zero), complex(-zero, -zero), complex(nan, nan)},
+ {complex(zero, zero), complex(zero, 1), complex(zero, zero)},
+ {complex(zero, zero), complex(-zero, -1), complex(-zero, -zero)},
+ {complex(zero, zero), complex(zero, 2), complex(zero, zero)},
+ {complex(zero, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, zero), complex(1, zero), complex(zero, zero)},
+ {complex(zero, zero), complex(1, -zero), complex(zero, zero)},
+ {complex(zero, zero), complex(1, 1), complex(zero, zero)},
+ {complex(zero, zero), complex(1, -1), complex(zero, zero)},
+ {complex(zero, zero), complex(1, 2), complex(zero, zero)},
+ {complex(zero, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, zero), complex(-1, zero), complex(-zero, -zero)},
+ {complex(zero, zero), complex(-1, -zero), complex(-zero, -zero)},
+ {complex(zero, zero), complex(-1, 1), complex(-zero, -zero)},
+ {complex(zero, zero), complex(-1, -1), complex(-zero, -zero)},
+ {complex(zero, zero), complex(-1, 2), complex(zero, -zero)},
+ {complex(zero, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, zero), complex(2, zero), complex(zero, zero)},
+ {complex(zero, zero), complex(2, -zero), complex(zero, zero)},
+ {complex(zero, zero), complex(2, 1), complex(zero, zero)},
+ {complex(zero, zero), complex(2, -1), complex(zero, zero)},
+ {complex(zero, zero), complex(2, 2), complex(zero, zero)},
+ {complex(zero, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, zero), complex(nan, zero), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, -zero), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, 1), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, -1), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, 2), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, zero), complex(inf, zero), complex(zero, zero)},
+ {complex(zero, zero), complex(inf, -zero), complex(zero, zero)},
+ {complex(zero, zero), complex(inf, 1), complex(zero, zero)},
+ {complex(zero, zero), complex(inf, -1), complex(zero, zero)},
+ {complex(zero, zero), complex(inf, 2), complex(zero, zero)},
+ {complex(zero, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, zero), complex(-inf, zero), complex(-zero, -zero)},
+ {complex(zero, zero), complex(-inf, -zero), complex(-zero, -zero)},
+ {complex(zero, zero), complex(-inf, 1), complex(-zero, -zero)},
+ {complex(zero, zero), complex(-inf, -1), complex(-zero, -zero)},
+ {complex(zero, zero), complex(-inf, 2), complex(-zero, -zero)},
+ {complex(zero, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(zero, zero), complex(nan, nan)},
+ {complex(-zero, -zero), complex(zero, -zero), complex(nan, nan)},
+ {complex(-zero, -zero), complex(zero, 1), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(zero, -1), complex(-zero, -zero)},
+ {complex(-zero, -zero), complex(zero, 2), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-zero, -zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-zero, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(-zero, -zero), complex(zero, zero), complex(nan, nan)},
+ {complex(-zero, -zero), complex(-zero, -zero), complex(nan, nan)},
+ {complex(-zero, -zero), complex(zero, 1), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(-zero, -1), complex(zero, -zero)},
+ {complex(-zero, -zero), complex(zero, 2), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-zero, -zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-zero, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(-zero, -zero), complex(1, zero), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(1, -zero), complex(zero, -zero)},
+ {complex(-zero, -zero), complex(1, 1), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(1, -1), complex(zero, -zero)},
+ {complex(-zero, -zero), complex(1, 2), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-zero, -zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-zero, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(-zero, -zero), complex(-1, zero), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(-1, -zero), complex(zero, -zero)},
+ {complex(-zero, -zero), complex(-1, 1), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(-1, -1), complex(zero, -zero)},
+ {complex(-zero, -zero), complex(-1, 2), complex(zero, zero)},
+ {complex(-zero, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-zero, -zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-zero, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(-zero, -zero), complex(2, zero), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(2, -zero), complex(zero, -zero)},
+ {complex(-zero, -zero), complex(2, 1), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(2, -1), complex(zero, -zero)},
+ {complex(-zero, -zero), complex(2, 2), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-zero, -zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-zero, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(-zero, -zero), complex(nan, zero), complex(nan, nan)},
+ {complex(-zero, -zero), complex(nan, -zero), complex(nan, nan)},
+ {complex(-zero, -zero), complex(nan, 1), complex(nan, nan)},
+ {complex(-zero, -zero), complex(nan, -1), complex(nan, nan)},
+ {complex(-zero, -zero), complex(nan, 2), complex(nan, nan)},
+ {complex(-zero, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-zero, -zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-zero, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(-zero, -zero), complex(inf, zero), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(inf, -zero), complex(zero, -zero)},
+ {complex(-zero, -zero), complex(inf, 1), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(inf, -1), complex(zero, -zero)},
+ {complex(-zero, -zero), complex(inf, 2), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-zero, -zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-zero, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(-zero, -zero), complex(-inf, zero), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(-inf, -zero), complex(zero, -zero)},
+ {complex(-zero, -zero), complex(-inf, 1), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(-inf, -1), complex(zero, -zero)},
+ {complex(-zero, -zero), complex(-inf, 2), complex(-zero, zero)},
+ {complex(-zero, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-zero, -zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-zero, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(zero, 1), complex(zero, zero), complex(nan, inf)},
+ {complex(zero, 1), complex(zero, -zero), complex(nan, inf)},
+ {complex(zero, 1), complex(zero, 1), complex(1, zero)},
+ {complex(zero, 1), complex(zero, -1), complex(-1, zero)},
+ {complex(zero, 1), complex(zero, 2), complex(0.5, zero)},
+ {complex(zero, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 1), complex(zero, zero), complex(nan, inf)},
+ {complex(zero, 1), complex(-zero, -zero), complex(nan, -inf)},
+ {complex(zero, 1), complex(zero, 1), complex(1, zero)},
+ {complex(zero, 1), complex(-zero, -1), complex(-1, -zero)},
+ {complex(zero, 1), complex(zero, 2), complex(0.5, zero)},
+ {complex(zero, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 1), complex(1, zero), complex(zero, 1)},
+ {complex(zero, 1), complex(1, -zero), complex(zero, 1)},
+ {complex(zero, 1), complex(1, 1), complex(0.5, 0.5)},
+ {complex(zero, 1), complex(1, -1), complex(-0.5, 0.5)},
+ {complex(zero, 1), complex(1, 2), complex(0.4, 0.2)},
+ {complex(zero, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 1), complex(-1, zero), complex(-zero, -1)},
+ {complex(zero, 1), complex(-1, -zero), complex(-zero, -1)},
+ {complex(zero, 1), complex(-1, 1), complex(0.5, -0.5)},
+ {complex(zero, 1), complex(-1, -1), complex(-0.5, -0.5)},
+ {complex(zero, 1), complex(-1, 2), complex(0.4, -0.2)},
+ {complex(zero, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 1), complex(2, zero), complex(zero, 0.5)},
+ {complex(zero, 1), complex(2, -zero), complex(zero, 0.5)},
+ {complex(zero, 1), complex(2, 1), complex(0.2, 0.4)},
+ {complex(zero, 1), complex(2, -1), complex(-0.2, 0.4)},
+ {complex(zero, 1), complex(2, 2), complex(0.25, 0.25)},
+ {complex(zero, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 1), complex(nan, zero), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, -zero), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, 1), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, -1), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, 2), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 1), complex(inf, zero), complex(zero, zero)},
+ {complex(zero, 1), complex(inf, -zero), complex(zero, zero)},
+ {complex(zero, 1), complex(inf, 1), complex(zero, zero)},
+ {complex(zero, 1), complex(inf, -1), complex(zero, zero)},
+ {complex(zero, 1), complex(inf, 2), complex(zero, zero)},
+ {complex(zero, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 1), complex(-inf, zero), complex(-zero, -zero)},
+ {complex(zero, 1), complex(-inf, -zero), complex(-zero, -zero)},
+ {complex(zero, 1), complex(-inf, 1), complex(-zero, -zero)},
+ {complex(zero, 1), complex(-inf, -1), complex(-zero, -zero)},
+ {complex(zero, 1), complex(-inf, 2), complex(-zero, -zero)},
+ {complex(zero, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(-zero, -1), complex(zero, zero), complex(nan, -inf)},
+ {complex(-zero, -1), complex(zero, -zero), complex(nan, -inf)},
+ {complex(-zero, -1), complex(zero, 1), complex(-1, zero)},
+ {complex(-zero, -1), complex(zero, -1), complex(1, -zero)},
+ {complex(-zero, -1), complex(zero, 2), complex(-0.5, zero)},
+ {complex(-zero, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-zero, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(-zero, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(-zero, -1), complex(zero, zero), complex(nan, -inf)},
+ {complex(-zero, -1), complex(-zero, -zero), complex(nan, inf)},
+ {complex(-zero, -1), complex(zero, 1), complex(-1, zero)},
+ {complex(-zero, -1), complex(-zero, -1), complex(1, -zero)},
+ {complex(-zero, -1), complex(zero, 2), complex(-0.5, zero)},
+ {complex(-zero, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-zero, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(-zero, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(-zero, -1), complex(1, zero), complex(-zero, -1)},
+ {complex(-zero, -1), complex(1, -zero), complex(zero, -1)},
+ {complex(-zero, -1), complex(1, 1), complex(-0.5, -0.5)},
+ {complex(-zero, -1), complex(1, -1), complex(0.5, -0.5)},
+ {complex(-zero, -1), complex(1, 2), complex(-0.4, -0.2)},
+ {complex(-zero, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-zero, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(-zero, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(-zero, -1), complex(-1, zero), complex(-zero, 1)},
+ {complex(-zero, -1), complex(-1, -zero), complex(zero, 1)},
+ {complex(-zero, -1), complex(-1, 1), complex(-0.5, 0.5)},
+ {complex(-zero, -1), complex(-1, -1), complex(0.5, 0.5)},
+ {complex(-zero, -1), complex(-1, 2), complex(-0.4, 0.2)},
+ {complex(-zero, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-zero, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(-zero, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(-zero, -1), complex(2, zero), complex(-zero, -0.5)},
+ {complex(-zero, -1), complex(2, -zero), complex(zero, -0.5)},
+ {complex(-zero, -1), complex(2, 1), complex(-0.2, -0.4)},
+ {complex(-zero, -1), complex(2, -1), complex(0.2, -0.4)},
+ {complex(-zero, -1), complex(2, 2), complex(-0.25, -0.25)},
+ {complex(-zero, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-zero, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(-zero, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(-zero, -1), complex(nan, zero), complex(nan, nan)},
+ {complex(-zero, -1), complex(nan, -zero), complex(nan, nan)},
+ {complex(-zero, -1), complex(nan, 1), complex(nan, nan)},
+ {complex(-zero, -1), complex(nan, -1), complex(nan, nan)},
+ {complex(-zero, -1), complex(nan, 2), complex(nan, nan)},
+ {complex(-zero, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-zero, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(-zero, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(-zero, -1), complex(inf, zero), complex(-zero, -zero)},
+ {complex(-zero, -1), complex(inf, -zero), complex(zero, -zero)},
+ {complex(-zero, -1), complex(inf, 1), complex(-zero, -zero)},
+ {complex(-zero, -1), complex(inf, -1), complex(zero, -zero)},
+ {complex(-zero, -1), complex(inf, 2), complex(-zero, -zero)},
+ {complex(-zero, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-zero, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(-zero, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(-zero, -1), complex(-inf, zero), complex(-zero, zero)},
+ {complex(-zero, -1), complex(-inf, -zero), complex(zero, zero)},
+ {complex(-zero, -1), complex(-inf, 1), complex(-zero, zero)},
+ {complex(-zero, -1), complex(-inf, -1), complex(zero, zero)},
+ {complex(-zero, -1), complex(-inf, 2), complex(-zero, zero)},
+ {complex(-zero, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-zero, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(-zero, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(zero, 2), complex(zero, zero), complex(nan, inf)},
+ {complex(zero, 2), complex(zero, -zero), complex(nan, inf)},
+ {complex(zero, 2), complex(zero, 1), complex(2, zero)},
+ {complex(zero, 2), complex(zero, -1), complex(-2, zero)},
+ {complex(zero, 2), complex(zero, 2), complex(1, zero)},
+ {complex(zero, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 2), complex(zero, zero), complex(nan, inf)},
+ {complex(zero, 2), complex(-zero, -zero), complex(nan, -inf)},
+ {complex(zero, 2), complex(zero, 1), complex(2, zero)},
+ {complex(zero, 2), complex(-zero, -1), complex(-2, -zero)},
+ {complex(zero, 2), complex(zero, 2), complex(1, zero)},
+ {complex(zero, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 2), complex(1, zero), complex(zero, 2)},
+ {complex(zero, 2), complex(1, -zero), complex(zero, 2)},
+ {complex(zero, 2), complex(1, 1), complex(1, 1)},
+ {complex(zero, 2), complex(1, -1), complex(-1, 1)},
+ {complex(zero, 2), complex(1, 2), complex(0.8, 0.4)},
+ {complex(zero, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 2), complex(-1, zero), complex(-zero, -2)},
+ {complex(zero, 2), complex(-1, -zero), complex(-zero, -2)},
+ {complex(zero, 2), complex(-1, 1), complex(1, -1)},
+ {complex(zero, 2), complex(-1, -1), complex(-1, -1)},
+ {complex(zero, 2), complex(-1, 2), complex(0.8, -0.4)},
+ {complex(zero, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 2), complex(2, zero), complex(zero, 1)},
+ {complex(zero, 2), complex(2, -zero), complex(zero, 1)},
+ {complex(zero, 2), complex(2, 1), complex(0.4, 0.8)},
+ {complex(zero, 2), complex(2, -1), complex(-0.4, 0.8)},
+ {complex(zero, 2), complex(2, 2), complex(0.5, 0.5)},
+ {complex(zero, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 2), complex(nan, zero), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, -zero), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, 1), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, -1), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, 2), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 2), complex(inf, zero), complex(zero, zero)},
+ {complex(zero, 2), complex(inf, -zero), complex(zero, zero)},
+ {complex(zero, 2), complex(inf, 1), complex(zero, zero)},
+ {complex(zero, 2), complex(inf, -1), complex(zero, zero)},
+ {complex(zero, 2), complex(inf, 2), complex(zero, zero)},
+ {complex(zero, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(zero, 2), complex(-inf, zero), complex(-zero, -zero)},
+ {complex(zero, 2), complex(-inf, -zero), complex(-zero, -zero)},
+ {complex(zero, 2), complex(-inf, 1), complex(-zero, -zero)},
+ {complex(zero, 2), complex(-inf, -1), complex(-zero, -zero)},
+ {complex(zero, 2), complex(-inf, 2), complex(-zero, -zero)},
+ {complex(zero, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(zero, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(zero, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(nan, nan), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-zero, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-zero, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(1, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(1, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(1, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(1, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(1, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(2, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(2, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(2, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(2, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(2, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(zero, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(zero, 1), complex(inf, nan)},
+ {complex(nan, inf), complex(zero, -1), complex(-inf, nan)},
+ {complex(nan, inf), complex(zero, 2), complex(inf, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(-zero, -zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(zero, 1), complex(inf, nan)},
+ {complex(nan, inf), complex(-zero, -1), complex(-inf, nan)},
+ {complex(nan, inf), complex(zero, 2), complex(inf, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(1, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(1, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(1, 1), complex(inf, inf)},
+ {complex(nan, inf), complex(1, -1), complex(-inf, inf)},
+ {complex(nan, inf), complex(1, 2), complex(inf, inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(-1, zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(-1, -zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(-1, 1), complex(inf, -inf)},
+ {complex(nan, inf), complex(-1, -1), complex(-inf, -inf)},
+ {complex(nan, inf), complex(-1, 2), complex(inf, -inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(2, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(2, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(2, 1), complex(inf, inf)},
+ {complex(nan, inf), complex(2, -1), complex(-inf, inf)},
+ {complex(nan, inf), complex(2, 2), complex(inf, inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(zero, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(zero, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(zero, 1), complex(-inf, nan)},
+ {complex(nan, -inf), complex(zero, -1), complex(inf, nan)},
+ {complex(nan, -inf), complex(zero, 2), complex(-inf, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(zero, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(-zero, -zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(zero, 1), complex(-inf, nan)},
+ {complex(nan, -inf), complex(-zero, -1), complex(inf, nan)},
+ {complex(nan, -inf), complex(zero, 2), complex(-inf, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(1, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(1, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(1, 1), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(1, -1), complex(inf, -inf)},
+ {complex(nan, -inf), complex(1, 2), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(-1, zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(-1, -zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(-1, 1), complex(-inf, inf)},
+ {complex(nan, -inf), complex(-1, -1), complex(inf, inf)},
+ {complex(nan, -inf), complex(-1, 2), complex(-inf, inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(2, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(2, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(2, 1), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(2, -1), complex(inf, -inf)},
+ {complex(nan, -inf), complex(2, 2), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(1, zero), complex(zero, zero), complex(inf, nan)},
+ {complex(1, zero), complex(zero, -zero), complex(inf, nan)},
+ {complex(1, zero), complex(zero, 1), complex(zero, -1)},
+ {complex(1, zero), complex(zero, -1), complex(-zero, 1)},
+ {complex(1, zero), complex(zero, 2), complex(zero, -0.5)},
+ {complex(1, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(1, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, zero), complex(zero, zero), complex(inf, nan)},
+ {complex(1, zero), complex(-zero, -zero), complex(-inf, nan)},
+ {complex(1, zero), complex(zero, 1), complex(zero, -1)},
+ {complex(1, zero), complex(-zero, -1), complex(-zero, 1)},
+ {complex(1, zero), complex(zero, 2), complex(zero, -0.5)},
+ {complex(1, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(1, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, zero), complex(1, zero), complex(1, zero)},
+ {complex(1, zero), complex(1, -zero), complex(1, zero)},
+ {complex(1, zero), complex(1, 1), complex(0.5, -0.5)},
+ {complex(1, zero), complex(1, -1), complex(0.5, 0.5)},
+ {complex(1, zero), complex(1, 2), complex(0.2, -0.4)},
+ {complex(1, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(1, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, zero), complex(-1, zero), complex(-1, -zero)},
+ {complex(1, zero), complex(-1, -zero), complex(-1, -zero)},
+ {complex(1, zero), complex(-1, 1), complex(-0.5, -0.5)},
+ {complex(1, zero), complex(-1, -1), complex(-0.5, 0.5)},
+ {complex(1, zero), complex(-1, 2), complex(-0.2, -0.4)},
+ {complex(1, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(1, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, zero), complex(2, zero), complex(0.5, zero)},
+ {complex(1, zero), complex(2, -zero), complex(0.5, zero)},
+ {complex(1, zero), complex(2, 1), complex(0.4, -0.2)},
+ {complex(1, zero), complex(2, -1), complex(0.4, 0.2)},
+ {complex(1, zero), complex(2, 2), complex(0.25, -0.25)},
+ {complex(1, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(1, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, zero), complex(nan, zero), complex(nan, nan)},
+ {complex(1, zero), complex(nan, -zero), complex(nan, nan)},
+ {complex(1, zero), complex(nan, 1), complex(nan, nan)},
+ {complex(1, zero), complex(nan, -1), complex(nan, nan)},
+ {complex(1, zero), complex(nan, 2), complex(nan, nan)},
+ {complex(1, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(1, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, zero), complex(inf, zero), complex(zero, zero)},
+ {complex(1, zero), complex(inf, -zero), complex(zero, zero)},
+ {complex(1, zero), complex(inf, 1), complex(zero, zero)},
+ {complex(1, zero), complex(inf, -1), complex(zero, zero)},
+ {complex(1, zero), complex(inf, 2), complex(zero, zero)},
+ {complex(1, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(1, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, zero), complex(-inf, zero), complex(-zero, -zero)},
+ {complex(1, zero), complex(-inf, -zero), complex(-zero, -zero)},
+ {complex(1, zero), complex(-inf, 1), complex(-zero, -zero)},
+ {complex(1, zero), complex(-inf, -1), complex(-zero, -zero)},
+ {complex(1, zero), complex(-inf, 2), complex(-zero, -zero)},
+ {complex(1, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(1, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, -zero), complex(zero, zero), complex(inf, nan)},
+ {complex(1, -zero), complex(zero, -zero), complex(inf, nan)},
+ {complex(1, -zero), complex(zero, 1), complex(zero, -1)},
+ {complex(1, -zero), complex(zero, -1), complex(zero, 1)},
+ {complex(1, -zero), complex(zero, 2), complex(zero, -0.5)},
+ {complex(1, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(1, -zero), complex(nan, inf), complex(-zero, -zero)},
+ {complex(1, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(1, -zero), complex(zero, zero), complex(inf, nan)},
+ {complex(1, -zero), complex(-zero, -zero), complex(-inf, nan)},
+ {complex(1, -zero), complex(zero, 1), complex(zero, -1)},
+ {complex(1, -zero), complex(-zero, -1), complex(-zero, 1)},
+ {complex(1, -zero), complex(zero, 2), complex(zero, -0.5)},
+ {complex(1, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(1, -zero), complex(nan, inf), complex(-zero, -zero)},
+ {complex(1, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(1, -zero), complex(1, zero), complex(1, -zero)},
+ {complex(1, -zero), complex(1, -zero), complex(1, zero)},
+ {complex(1, -zero), complex(1, 1), complex(0.5, -0.5)},
+ {complex(1, -zero), complex(1, -1), complex(0.5, 0.5)},
+ {complex(1, -zero), complex(1, 2), complex(0.2, -0.4)},
+ {complex(1, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(1, -zero), complex(nan, inf), complex(-zero, -zero)},
+ {complex(1, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(1, -zero), complex(-1, zero), complex(-1, -zero)},
+ {complex(1, -zero), complex(-1, -zero), complex(-1, zero)},
+ {complex(1, -zero), complex(-1, 1), complex(-0.5, -0.5)},
+ {complex(1, -zero), complex(-1, -1), complex(-0.5, 0.5)},
+ {complex(1, -zero), complex(-1, 2), complex(-0.2, -0.4)},
+ {complex(1, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(1, -zero), complex(nan, inf), complex(-zero, -zero)},
+ {complex(1, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(1, -zero), complex(2, zero), complex(0.5, -zero)},
+ {complex(1, -zero), complex(2, -zero), complex(0.5, zero)},
+ {complex(1, -zero), complex(2, 1), complex(0.4, -0.2)},
+ {complex(1, -zero), complex(2, -1), complex(0.4, 0.2)},
+ {complex(1, -zero), complex(2, 2), complex(0.25, -0.25)},
+ {complex(1, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(1, -zero), complex(nan, inf), complex(-zero, -zero)},
+ {complex(1, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(1, -zero), complex(nan, zero), complex(nan, nan)},
+ {complex(1, -zero), complex(nan, -zero), complex(nan, nan)},
+ {complex(1, -zero), complex(nan, 1), complex(nan, nan)},
+ {complex(1, -zero), complex(nan, -1), complex(nan, nan)},
+ {complex(1, -zero), complex(nan, 2), complex(nan, nan)},
+ {complex(1, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(1, -zero), complex(nan, inf), complex(-zero, -zero)},
+ {complex(1, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(1, -zero), complex(inf, zero), complex(zero, -zero)},
+ {complex(1, -zero), complex(inf, -zero), complex(zero, zero)},
+ {complex(1, -zero), complex(inf, 1), complex(zero, -zero)},
+ {complex(1, -zero), complex(inf, -1), complex(zero, zero)},
+ {complex(1, -zero), complex(inf, 2), complex(zero, -zero)},
+ {complex(1, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(1, -zero), complex(nan, inf), complex(-zero, -zero)},
+ {complex(1, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(1, -zero), complex(-inf, zero), complex(-zero, -zero)},
+ {complex(1, -zero), complex(-inf, -zero), complex(-zero, zero)},
+ {complex(1, -zero), complex(-inf, 1), complex(-zero, -zero)},
+ {complex(1, -zero), complex(-inf, -1), complex(-zero, zero)},
+ {complex(1, -zero), complex(-inf, 2), complex(-zero, -zero)},
+ {complex(1, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(1, -zero), complex(nan, inf), complex(-zero, -zero)},
+ {complex(1, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(1, 1), complex(zero, zero), complex(inf, inf)},
+ {complex(1, 1), complex(zero, -zero), complex(inf, inf)},
+ {complex(1, 1), complex(zero, 1), complex(1, -1)},
+ {complex(1, 1), complex(zero, -1), complex(-1, 1)},
+ {complex(1, 1), complex(zero, 2), complex(0.5, -0.5)},
+ {complex(1, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(1, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, 1), complex(zero, zero), complex(inf, inf)},
+ {complex(1, 1), complex(-zero, -zero), complex(-inf, -inf)},
+ {complex(1, 1), complex(zero, 1), complex(1, -1)},
+ {complex(1, 1), complex(-zero, -1), complex(-1, 1)},
+ {complex(1, 1), complex(zero, 2), complex(0.5, -0.5)},
+ {complex(1, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(1, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, 1), complex(1, zero), complex(1, 1)},
+ {complex(1, 1), complex(1, -zero), complex(1, 1)},
+ {complex(1, 1), complex(1, 1), complex(1, zero)},
+ {complex(1, 1), complex(1, -1), complex(zero, 1)},
+ {complex(1, 1), complex(1, 2), complex(0.6, -0.2)},
+ {complex(1, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(1, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, 1), complex(-1, zero), complex(-1, -1)},
+ {complex(1, 1), complex(-1, -zero), complex(-1, -1)},
+ {complex(1, 1), complex(-1, 1), complex(-zero, -1)},
+ {complex(1, 1), complex(-1, -1), complex(-1, -zero)},
+ {complex(1, 1), complex(-1, 2), complex(0.2, -0.6)},
+ {complex(1, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(1, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, 1), complex(2, zero), complex(0.5, 0.5)},
+ {complex(1, 1), complex(2, -zero), complex(0.5, 0.5)},
+ {complex(1, 1), complex(2, 1), complex(0.6, 0.2)},
+ {complex(1, 1), complex(2, -1), complex(0.2, 0.6)},
+ {complex(1, 1), complex(2, 2), complex(0.5, zero)},
+ {complex(1, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(1, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, 1), complex(nan, zero), complex(nan, nan)},
+ {complex(1, 1), complex(nan, -zero), complex(nan, nan)},
+ {complex(1, 1), complex(nan, 1), complex(nan, nan)},
+ {complex(1, 1), complex(nan, -1), complex(nan, nan)},
+ {complex(1, 1), complex(nan, 2), complex(nan, nan)},
+ {complex(1, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(1, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, 1), complex(inf, zero), complex(zero, zero)},
+ {complex(1, 1), complex(inf, -zero), complex(zero, zero)},
+ {complex(1, 1), complex(inf, 1), complex(zero, zero)},
+ {complex(1, 1), complex(inf, -1), complex(zero, zero)},
+ {complex(1, 1), complex(inf, 2), complex(zero, zero)},
+ {complex(1, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(1, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, 1), complex(-inf, zero), complex(-zero, -zero)},
+ {complex(1, 1), complex(-inf, -zero), complex(-zero, -zero)},
+ {complex(1, 1), complex(-inf, 1), complex(-zero, -zero)},
+ {complex(1, 1), complex(-inf, -1), complex(-zero, -zero)},
+ {complex(1, 1), complex(-inf, 2), complex(-zero, -zero)},
+ {complex(1, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(1, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, -1), complex(zero, zero), complex(inf, -inf)},
+ {complex(1, -1), complex(zero, -zero), complex(inf, -inf)},
+ {complex(1, -1), complex(zero, 1), complex(-1, -1)},
+ {complex(1, -1), complex(zero, -1), complex(1, 1)},
+ {complex(1, -1), complex(zero, 2), complex(-0.5, -0.5)},
+ {complex(1, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(1, -1), complex(nan, inf), complex(-zero, -zero)},
+ {complex(1, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(1, -1), complex(zero, zero), complex(inf, -inf)},
+ {complex(1, -1), complex(-zero, -zero), complex(-inf, inf)},
+ {complex(1, -1), complex(zero, 1), complex(-1, -1)},
+ {complex(1, -1), complex(-zero, -1), complex(1, 1)},
+ {complex(1, -1), complex(zero, 2), complex(-0.5, -0.5)},
+ {complex(1, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(1, -1), complex(nan, inf), complex(-zero, -zero)},
+ {complex(1, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(1, -1), complex(1, zero), complex(1, -1)},
+ {complex(1, -1), complex(1, -zero), complex(1, -1)},
+ {complex(1, -1), complex(1, 1), complex(zero, -1)},
+ {complex(1, -1), complex(1, -1), complex(1, zero)},
+ {complex(1, -1), complex(1, 2), complex(-0.2, -0.6)},
+ {complex(1, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(1, -1), complex(nan, inf), complex(-zero, -zero)},
+ {complex(1, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(1, -1), complex(-1, zero), complex(-1, 1)},
+ {complex(1, -1), complex(-1, -zero), complex(-1, 1)},
+ {complex(1, -1), complex(-1, 1), complex(-1, -zero)},
+ {complex(1, -1), complex(-1, -1), complex(-zero, 1)},
+ {complex(1, -1), complex(-1, 2), complex(-0.6, -0.2)},
+ {complex(1, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(1, -1), complex(nan, inf), complex(-zero, -zero)},
+ {complex(1, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(1, -1), complex(2, zero), complex(0.5, -0.5)},
+ {complex(1, -1), complex(2, -zero), complex(0.5, -0.5)},
+ {complex(1, -1), complex(2, 1), complex(0.2, -0.6)},
+ {complex(1, -1), complex(2, -1), complex(0.6, -0.2)},
+ {complex(1, -1), complex(2, 2), complex(zero, -0.5)},
+ {complex(1, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(1, -1), complex(nan, inf), complex(-zero, -zero)},
+ {complex(1, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(1, -1), complex(nan, zero), complex(nan, nan)},
+ {complex(1, -1), complex(nan, -zero), complex(nan, nan)},
+ {complex(1, -1), complex(nan, 1), complex(nan, nan)},
+ {complex(1, -1), complex(nan, -1), complex(nan, nan)},
+ {complex(1, -1), complex(nan, 2), complex(nan, nan)},
+ {complex(1, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(1, -1), complex(nan, inf), complex(-zero, -zero)},
+ {complex(1, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(1, -1), complex(inf, zero), complex(zero, -zero)},
+ {complex(1, -1), complex(inf, -zero), complex(zero, -zero)},
+ {complex(1, -1), complex(inf, 1), complex(zero, -zero)},
+ {complex(1, -1), complex(inf, -1), complex(zero, -zero)},
+ {complex(1, -1), complex(inf, 2), complex(zero, -zero)},
+ {complex(1, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(1, -1), complex(nan, inf), complex(-zero, -zero)},
+ {complex(1, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(1, -1), complex(-inf, zero), complex(-zero, zero)},
+ {complex(1, -1), complex(-inf, -zero), complex(-zero, zero)},
+ {complex(1, -1), complex(-inf, 1), complex(-zero, zero)},
+ {complex(1, -1), complex(-inf, -1), complex(-zero, zero)},
+ {complex(1, -1), complex(-inf, 2), complex(-zero, zero)},
+ {complex(1, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(1, -1), complex(nan, inf), complex(-zero, -zero)},
+ {complex(1, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(1, 2), complex(zero, zero), complex(inf, inf)},
+ {complex(1, 2), complex(zero, -zero), complex(inf, inf)},
+ {complex(1, 2), complex(zero, 1), complex(2, -1)},
+ {complex(1, 2), complex(zero, -1), complex(-2, 1)},
+ {complex(1, 2), complex(zero, 2), complex(1, -0.5)},
+ {complex(1, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(1, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, 2), complex(zero, zero), complex(inf, inf)},
+ {complex(1, 2), complex(-zero, -zero), complex(-inf, -inf)},
+ {complex(1, 2), complex(zero, 1), complex(2, -1)},
+ {complex(1, 2), complex(-zero, -1), complex(-2, 1)},
+ {complex(1, 2), complex(zero, 2), complex(1, -0.5)},
+ {complex(1, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(1, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, 2), complex(1, zero), complex(1, 2)},
+ {complex(1, 2), complex(1, -zero), complex(1, 2)},
+ {complex(1, 2), complex(1, 1), complex(1.5, 0.5)},
+ {complex(1, 2), complex(1, -1), complex(-0.5, 1.5)},
+ {complex(1, 2), complex(1, 2), complex(1, zero)},
+ {complex(1, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(1, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, 2), complex(-1, zero), complex(-1, -2)},
+ {complex(1, 2), complex(-1, -zero), complex(-1, -2)},
+ {complex(1, 2), complex(-1, 1), complex(0.5, -1.5)},
+ {complex(1, 2), complex(-1, -1), complex(-1.5, -0.5)},
+ {complex(1, 2), complex(-1, 2), complex(0.6, -0.8)},
+ {complex(1, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(1, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, 2), complex(2, zero), complex(0.5, 1)},
+ {complex(1, 2), complex(2, -zero), complex(0.5, 1)},
+ {complex(1, 2), complex(2, 1), complex(0.8, 0.6)},
+ {complex(1, 2), complex(2, -1), complex(zero, 1)},
+ {complex(1, 2), complex(2, 2), complex(0.75, 0.25)},
+ {complex(1, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(1, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, 2), complex(nan, zero), complex(nan, nan)},
+ {complex(1, 2), complex(nan, -zero), complex(nan, nan)},
+ {complex(1, 2), complex(nan, 1), complex(nan, nan)},
+ {complex(1, 2), complex(nan, -1), complex(nan, nan)},
+ {complex(1, 2), complex(nan, 2), complex(nan, nan)},
+ {complex(1, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(1, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, 2), complex(inf, zero), complex(zero, zero)},
+ {complex(1, 2), complex(inf, -zero), complex(zero, zero)},
+ {complex(1, 2), complex(inf, 1), complex(zero, zero)},
+ {complex(1, 2), complex(inf, -1), complex(zero, zero)},
+ {complex(1, 2), complex(inf, 2), complex(zero, zero)},
+ {complex(1, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(1, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(1, 2), complex(-inf, zero), complex(-zero, -zero)},
+ {complex(1, 2), complex(-inf, -zero), complex(-zero, -zero)},
+ {complex(1, 2), complex(-inf, 1), complex(-zero, -zero)},
+ {complex(1, 2), complex(-inf, -1), complex(-zero, -zero)},
+ {complex(1, 2), complex(-inf, 2), complex(-zero, -zero)},
+ {complex(1, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(1, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(1, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(nan, nan), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-zero, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-zero, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(1, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(1, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(1, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(1, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(1, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(2, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(2, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(2, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(2, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(2, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(zero, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(zero, 1), complex(inf, nan)},
+ {complex(nan, inf), complex(zero, -1), complex(-inf, nan)},
+ {complex(nan, inf), complex(zero, 2), complex(inf, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(-zero, -zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(zero, 1), complex(inf, nan)},
+ {complex(nan, inf), complex(-zero, -1), complex(-inf, nan)},
+ {complex(nan, inf), complex(zero, 2), complex(inf, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(1, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(1, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(1, 1), complex(inf, inf)},
+ {complex(nan, inf), complex(1, -1), complex(-inf, inf)},
+ {complex(nan, inf), complex(1, 2), complex(inf, inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(-1, zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(-1, -zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(-1, 1), complex(inf, -inf)},
+ {complex(nan, inf), complex(-1, -1), complex(-inf, -inf)},
+ {complex(nan, inf), complex(-1, 2), complex(inf, -inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(2, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(2, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(2, 1), complex(inf, inf)},
+ {complex(nan, inf), complex(2, -1), complex(-inf, inf)},
+ {complex(nan, inf), complex(2, 2), complex(inf, inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(zero, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(zero, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(zero, 1), complex(-inf, nan)},
+ {complex(nan, -inf), complex(zero, -1), complex(inf, nan)},
+ {complex(nan, -inf), complex(zero, 2), complex(-inf, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(zero, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(-zero, -zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(zero, 1), complex(-inf, nan)},
+ {complex(nan, -inf), complex(-zero, -1), complex(inf, nan)},
+ {complex(nan, -inf), complex(zero, 2), complex(-inf, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(1, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(1, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(1, 1), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(1, -1), complex(inf, -inf)},
+ {complex(nan, -inf), complex(1, 2), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(-1, zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(-1, -zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(-1, 1), complex(-inf, inf)},
+ {complex(nan, -inf), complex(-1, -1), complex(inf, inf)},
+ {complex(nan, -inf), complex(-1, 2), complex(-inf, inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(2, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(2, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(2, 1), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(2, -1), complex(inf, -inf)},
+ {complex(nan, -inf), complex(2, 2), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(-1, zero), complex(zero, zero), complex(-inf, nan)},
+ {complex(-1, zero), complex(zero, -zero), complex(-inf, nan)},
+ {complex(-1, zero), complex(zero, 1), complex(zero, 1)},
+ {complex(-1, zero), complex(zero, -1), complex(-zero, -1)},
+ {complex(-1, zero), complex(zero, 2), complex(zero, 0.5)},
+ {complex(-1, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, zero), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, zero), complex(zero, zero), complex(-inf, nan)},
+ {complex(-1, zero), complex(-zero, -zero), complex(inf, nan)},
+ {complex(-1, zero), complex(zero, 1), complex(zero, 1)},
+ {complex(-1, zero), complex(-zero, -1), complex(-zero, -1)},
+ {complex(-1, zero), complex(zero, 2), complex(zero, 0.5)},
+ {complex(-1, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, zero), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, zero), complex(1, zero), complex(-1, zero)},
+ {complex(-1, zero), complex(1, -zero), complex(-1, zero)},
+ {complex(-1, zero), complex(1, 1), complex(-0.5, 0.5)},
+ {complex(-1, zero), complex(1, -1), complex(-0.5, -0.5)},
+ {complex(-1, zero), complex(1, 2), complex(-0.2, 0.4)},
+ {complex(-1, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, zero), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, zero), complex(-1, zero), complex(1, -zero)},
+ {complex(-1, zero), complex(-1, -zero), complex(1, -zero)},
+ {complex(-1, zero), complex(-1, 1), complex(0.5, 0.5)},
+ {complex(-1, zero), complex(-1, -1), complex(0.5, -0.5)},
+ {complex(-1, zero), complex(-1, 2), complex(0.2, 0.4)},
+ {complex(-1, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, zero), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, zero), complex(2, zero), complex(-0.5, zero)},
+ {complex(-1, zero), complex(2, -zero), complex(-0.5, zero)},
+ {complex(-1, zero), complex(2, 1), complex(-0.4, 0.2)},
+ {complex(-1, zero), complex(2, -1), complex(-0.4, -0.2)},
+ {complex(-1, zero), complex(2, 2), complex(-0.25, 0.25)},
+ {complex(-1, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, zero), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, zero), complex(nan, zero), complex(nan, nan)},
+ {complex(-1, zero), complex(nan, -zero), complex(nan, nan)},
+ {complex(-1, zero), complex(nan, 1), complex(nan, nan)},
+ {complex(-1, zero), complex(nan, -1), complex(nan, nan)},
+ {complex(-1, zero), complex(nan, 2), complex(nan, nan)},
+ {complex(-1, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, zero), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, zero), complex(inf, zero), complex(-zero, zero)},
+ {complex(-1, zero), complex(inf, -zero), complex(-zero, zero)},
+ {complex(-1, zero), complex(inf, 1), complex(-zero, zero)},
+ {complex(-1, zero), complex(inf, -1), complex(-zero, zero)},
+ {complex(-1, zero), complex(inf, 2), complex(-zero, zero)},
+ {complex(-1, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, zero), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, zero), complex(-inf, zero), complex(zero, -zero)},
+ {complex(-1, zero), complex(-inf, -zero), complex(zero, -zero)},
+ {complex(-1, zero), complex(-inf, 1), complex(zero, -zero)},
+ {complex(-1, zero), complex(-inf, -1), complex(zero, -zero)},
+ {complex(-1, zero), complex(-inf, 2), complex(zero, -zero)},
+ {complex(-1, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, zero), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, -zero), complex(zero, zero), complex(-inf, nan)},
+ {complex(-1, -zero), complex(zero, -zero), complex(-inf, nan)},
+ {complex(-1, -zero), complex(zero, 1), complex(-zero, 1)},
+ {complex(-1, -zero), complex(zero, -1), complex(-zero, -1)},
+ {complex(-1, -zero), complex(zero, 2), complex(-zero, 0.5)},
+ {complex(-1, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, -zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, -zero), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, -zero), complex(zero, zero), complex(-inf, nan)},
+ {complex(-1, -zero), complex(-zero, -zero), complex(inf, nan)},
+ {complex(-1, -zero), complex(zero, 1), complex(-zero, 1)},
+ {complex(-1, -zero), complex(-zero, -1), complex(zero, -1)},
+ {complex(-1, -zero), complex(zero, 2), complex(-zero, 0.5)},
+ {complex(-1, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, -zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, -zero), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, -zero), complex(1, zero), complex(-1, zero)},
+ {complex(-1, -zero), complex(1, -zero), complex(-1, -zero)},
+ {complex(-1, -zero), complex(1, 1), complex(-0.5, 0.5)},
+ {complex(-1, -zero), complex(1, -1), complex(-0.5, -0.5)},
+ {complex(-1, -zero), complex(1, 2), complex(-0.2, 0.4)},
+ {complex(-1, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, -zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, -zero), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, -zero), complex(-1, zero), complex(1, zero)},
+ {complex(-1, -zero), complex(-1, -zero), complex(1, -zero)},
+ {complex(-1, -zero), complex(-1, 1), complex(0.5, 0.5)},
+ {complex(-1, -zero), complex(-1, -1), complex(0.5, -0.5)},
+ {complex(-1, -zero), complex(-1, 2), complex(0.2, 0.4)},
+ {complex(-1, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, -zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, -zero), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, -zero), complex(2, zero), complex(-0.5, zero)},
+ {complex(-1, -zero), complex(2, -zero), complex(-0.5, -zero)},
+ {complex(-1, -zero), complex(2, 1), complex(-0.4, 0.2)},
+ {complex(-1, -zero), complex(2, -1), complex(-0.4, -0.2)},
+ {complex(-1, -zero), complex(2, 2), complex(-0.25, 0.25)},
+ {complex(-1, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, -zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, -zero), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, -zero), complex(nan, zero), complex(nan, nan)},
+ {complex(-1, -zero), complex(nan, -zero), complex(nan, nan)},
+ {complex(-1, -zero), complex(nan, 1), complex(nan, nan)},
+ {complex(-1, -zero), complex(nan, -1), complex(nan, nan)},
+ {complex(-1, -zero), complex(nan, 2), complex(nan, nan)},
+ {complex(-1, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, -zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, -zero), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, -zero), complex(inf, zero), complex(-zero, zero)},
+ {complex(-1, -zero), complex(inf, -zero), complex(-zero, -zero)},
+ {complex(-1, -zero), complex(inf, 1), complex(-zero, zero)},
+ {complex(-1, -zero), complex(inf, -1), complex(-zero, -zero)},
+ {complex(-1, -zero), complex(inf, 2), complex(-zero, zero)},
+ {complex(-1, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, -zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, -zero), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, -zero), complex(-inf, zero), complex(zero, zero)},
+ {complex(-1, -zero), complex(-inf, -zero), complex(zero, -zero)},
+ {complex(-1, -zero), complex(-inf, 1), complex(zero, zero)},
+ {complex(-1, -zero), complex(-inf, -1), complex(zero, -zero)},
+ {complex(-1, -zero), complex(-inf, 2), complex(zero, zero)},
+ {complex(-1, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, -zero), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, -zero), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, 1), complex(zero, zero), complex(-inf, inf)},
+ {complex(-1, 1), complex(zero, -zero), complex(-inf, inf)},
+ {complex(-1, 1), complex(zero, 1), complex(1, 1)},
+ {complex(-1, 1), complex(zero, -1), complex(-1, -1)},
+ {complex(-1, 1), complex(zero, 2), complex(0.5, 0.5)},
+ {complex(-1, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, 1), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, 1), complex(nan, -inf), complex(-zero, -zero)},
+ {complex(-1, 1), complex(zero, zero), complex(-inf, inf)},
+ {complex(-1, 1), complex(-zero, -zero), complex(inf, -inf)},
+ {complex(-1, 1), complex(zero, 1), complex(1, 1)},
+ {complex(-1, 1), complex(-zero, -1), complex(-1, -1)},
+ {complex(-1, 1), complex(zero, 2), complex(0.5, 0.5)},
+ {complex(-1, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, 1), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, 1), complex(nan, -inf), complex(-zero, -zero)},
+ {complex(-1, 1), complex(1, zero), complex(-1, 1)},
+ {complex(-1, 1), complex(1, -zero), complex(-1, 1)},
+ {complex(-1, 1), complex(1, 1), complex(zero, 1)},
+ {complex(-1, 1), complex(1, -1), complex(-1, zero)},
+ {complex(-1, 1), complex(1, 2), complex(0.2, 0.6)},
+ {complex(-1, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, 1), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, 1), complex(nan, -inf), complex(-zero, -zero)},
+ {complex(-1, 1), complex(-1, zero), complex(1, -1)},
+ {complex(-1, 1), complex(-1, -zero), complex(1, -1)},
+ {complex(-1, 1), complex(-1, 1), complex(1, -zero)},
+ {complex(-1, 1), complex(-1, -1), complex(-zero, -1)},
+ {complex(-1, 1), complex(-1, 2), complex(0.6, 0.2)},
+ {complex(-1, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, 1), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, 1), complex(nan, -inf), complex(-zero, -zero)},
+ {complex(-1, 1), complex(2, zero), complex(-0.5, 0.5)},
+ {complex(-1, 1), complex(2, -zero), complex(-0.5, 0.5)},
+ {complex(-1, 1), complex(2, 1), complex(-0.2, 0.6)},
+ {complex(-1, 1), complex(2, -1), complex(-0.6, 0.2)},
+ {complex(-1, 1), complex(2, 2), complex(zero, 0.5)},
+ {complex(-1, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, 1), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, 1), complex(nan, -inf), complex(-zero, -zero)},
+ {complex(-1, 1), complex(nan, zero), complex(nan, nan)},
+ {complex(-1, 1), complex(nan, -zero), complex(nan, nan)},
+ {complex(-1, 1), complex(nan, 1), complex(nan, nan)},
+ {complex(-1, 1), complex(nan, -1), complex(nan, nan)},
+ {complex(-1, 1), complex(nan, 2), complex(nan, nan)},
+ {complex(-1, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, 1), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, 1), complex(nan, -inf), complex(-zero, -zero)},
+ {complex(-1, 1), complex(inf, zero), complex(-zero, zero)},
+ {complex(-1, 1), complex(inf, -zero), complex(-zero, zero)},
+ {complex(-1, 1), complex(inf, 1), complex(-zero, zero)},
+ {complex(-1, 1), complex(inf, -1), complex(-zero, zero)},
+ {complex(-1, 1), complex(inf, 2), complex(-zero, zero)},
+ {complex(-1, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, 1), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, 1), complex(nan, -inf), complex(-zero, -zero)},
+ {complex(-1, 1), complex(-inf, zero), complex(zero, -zero)},
+ {complex(-1, 1), complex(-inf, -zero), complex(zero, -zero)},
+ {complex(-1, 1), complex(-inf, 1), complex(zero, -zero)},
+ {complex(-1, 1), complex(-inf, -1), complex(zero, -zero)},
+ {complex(-1, 1), complex(-inf, 2), complex(zero, -zero)},
+ {complex(-1, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, 1), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, 1), complex(nan, -inf), complex(-zero, -zero)},
+ {complex(-1, -1), complex(zero, zero), complex(-inf, -inf)},
+ {complex(-1, -1), complex(zero, -zero), complex(-inf, -inf)},
+ {complex(-1, -1), complex(zero, 1), complex(-1, 1)},
+ {complex(-1, -1), complex(zero, -1), complex(1, -1)},
+ {complex(-1, -1), complex(zero, 2), complex(-0.5, 0.5)},
+ {complex(-1, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(-1, -1), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, -1), complex(zero, zero), complex(-inf, -inf)},
+ {complex(-1, -1), complex(-zero, -zero), complex(inf, inf)},
+ {complex(-1, -1), complex(zero, 1), complex(-1, 1)},
+ {complex(-1, -1), complex(-zero, -1), complex(1, -1)},
+ {complex(-1, -1), complex(zero, 2), complex(-0.5, 0.5)},
+ {complex(-1, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(-1, -1), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, -1), complex(1, zero), complex(-1, -1)},
+ {complex(-1, -1), complex(1, -zero), complex(-1, -1)},
+ {complex(-1, -1), complex(1, 1), complex(-1, zero)},
+ {complex(-1, -1), complex(1, -1), complex(zero, -1)},
+ {complex(-1, -1), complex(1, 2), complex(-0.6, 0.2)},
+ {complex(-1, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(-1, -1), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, -1), complex(-1, zero), complex(1, 1)},
+ {complex(-1, -1), complex(-1, -zero), complex(1, 1)},
+ {complex(-1, -1), complex(-1, 1), complex(-zero, 1)},
+ {complex(-1, -1), complex(-1, -1), complex(1, -zero)},
+ {complex(-1, -1), complex(-1, 2), complex(-0.2, 0.6)},
+ {complex(-1, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(-1, -1), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, -1), complex(2, zero), complex(-0.5, -0.5)},
+ {complex(-1, -1), complex(2, -zero), complex(-0.5, -0.5)},
+ {complex(-1, -1), complex(2, 1), complex(-0.6, -0.2)},
+ {complex(-1, -1), complex(2, -1), complex(-0.2, -0.6)},
+ {complex(-1, -1), complex(2, 2), complex(-0.5, zero)},
+ {complex(-1, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(-1, -1), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, -1), complex(nan, zero), complex(nan, nan)},
+ {complex(-1, -1), complex(nan, -zero), complex(nan, nan)},
+ {complex(-1, -1), complex(nan, 1), complex(nan, nan)},
+ {complex(-1, -1), complex(nan, -1), complex(nan, nan)},
+ {complex(-1, -1), complex(nan, 2), complex(nan, nan)},
+ {complex(-1, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(-1, -1), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, -1), complex(inf, zero), complex(-zero, -zero)},
+ {complex(-1, -1), complex(inf, -zero), complex(-zero, -zero)},
+ {complex(-1, -1), complex(inf, 1), complex(-zero, -zero)},
+ {complex(-1, -1), complex(inf, -1), complex(-zero, -zero)},
+ {complex(-1, -1), complex(inf, 2), complex(-zero, -zero)},
+ {complex(-1, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(-1, -1), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, -1), complex(-inf, zero), complex(zero, zero)},
+ {complex(-1, -1), complex(-inf, -zero), complex(zero, zero)},
+ {complex(-1, -1), complex(-inf, 1), complex(zero, zero)},
+ {complex(-1, -1), complex(-inf, -1), complex(zero, zero)},
+ {complex(-1, -1), complex(-inf, 2), complex(zero, zero)},
+ {complex(-1, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, -1), complex(nan, inf), complex(-zero, zero)},
+ {complex(-1, -1), complex(nan, -inf), complex(zero, -zero)},
+ {complex(-1, 2), complex(zero, zero), complex(-inf, inf)},
+ {complex(-1, 2), complex(zero, -zero), complex(-inf, inf)},
+ {complex(-1, 2), complex(zero, 1), complex(2, 1)},
+ {complex(-1, 2), complex(zero, -1), complex(-2, -1)},
+ {complex(-1, 2), complex(zero, 2), complex(1, 0.5)},
+ {complex(-1, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, 2), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, 2), complex(nan, -inf), complex(-zero, -zero)},
+ {complex(-1, 2), complex(zero, zero), complex(-inf, inf)},
+ {complex(-1, 2), complex(-zero, -zero), complex(inf, -inf)},
+ {complex(-1, 2), complex(zero, 1), complex(2, 1)},
+ {complex(-1, 2), complex(-zero, -1), complex(-2, -1)},
+ {complex(-1, 2), complex(zero, 2), complex(1, 0.5)},
+ {complex(-1, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, 2), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, 2), complex(nan, -inf), complex(-zero, -zero)},
+ {complex(-1, 2), complex(1, zero), complex(-1, 2)},
+ {complex(-1, 2), complex(1, -zero), complex(-1, 2)},
+ {complex(-1, 2), complex(1, 1), complex(0.5, 1.5)},
+ {complex(-1, 2), complex(1, -1), complex(-1.5, 0.5)},
+ {complex(-1, 2), complex(1, 2), complex(0.6, 0.8)},
+ {complex(-1, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, 2), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, 2), complex(nan, -inf), complex(-zero, -zero)},
+ {complex(-1, 2), complex(-1, zero), complex(1, -2)},
+ {complex(-1, 2), complex(-1, -zero), complex(1, -2)},
+ {complex(-1, 2), complex(-1, 1), complex(1.5, -0.5)},
+ {complex(-1, 2), complex(-1, -1), complex(-0.5, -1.5)},
+ {complex(-1, 2), complex(-1, 2), complex(1, zero)},
+ {complex(-1, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, 2), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, 2), complex(nan, -inf), complex(-zero, -zero)},
+ {complex(-1, 2), complex(2, zero), complex(-0.5, 1)},
+ {complex(-1, 2), complex(2, -zero), complex(-0.5, 1)},
+ {complex(-1, 2), complex(2, 1), complex(zero, 1)},
+ {complex(-1, 2), complex(2, -1), complex(-0.8, 0.6)},
+ {complex(-1, 2), complex(2, 2), complex(0.25, 0.75)},
+ {complex(-1, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, 2), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, 2), complex(nan, -inf), complex(-zero, -zero)},
+ {complex(-1, 2), complex(nan, zero), complex(nan, nan)},
+ {complex(-1, 2), complex(nan, -zero), complex(nan, nan)},
+ {complex(-1, 2), complex(nan, 1), complex(nan, nan)},
+ {complex(-1, 2), complex(nan, -1), complex(nan, nan)},
+ {complex(-1, 2), complex(nan, 2), complex(nan, nan)},
+ {complex(-1, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, 2), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, 2), complex(nan, -inf), complex(-zero, -zero)},
+ {complex(-1, 2), complex(inf, zero), complex(-zero, zero)},
+ {complex(-1, 2), complex(inf, -zero), complex(-zero, zero)},
+ {complex(-1, 2), complex(inf, 1), complex(-zero, zero)},
+ {complex(-1, 2), complex(inf, -1), complex(-zero, zero)},
+ {complex(-1, 2), complex(inf, 2), complex(-zero, zero)},
+ {complex(-1, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, 2), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, 2), complex(nan, -inf), complex(-zero, -zero)},
+ {complex(-1, 2), complex(-inf, zero), complex(zero, -zero)},
+ {complex(-1, 2), complex(-inf, -zero), complex(zero, -zero)},
+ {complex(-1, 2), complex(-inf, 1), complex(zero, -zero)},
+ {complex(-1, 2), complex(-inf, -1), complex(zero, -zero)},
+ {complex(-1, 2), complex(-inf, 2), complex(zero, -zero)},
+ {complex(-1, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(-1, 2), complex(nan, inf), complex(zero, zero)},
+ {complex(-1, 2), complex(nan, -inf), complex(-zero, -zero)},
+ {complex(nan, nan), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-zero, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-zero, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(1, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(1, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(1, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(1, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(1, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(2, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(2, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(2, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(2, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(2, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(zero, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(zero, 1), complex(inf, nan)},
+ {complex(nan, inf), complex(zero, -1), complex(-inf, nan)},
+ {complex(nan, inf), complex(zero, 2), complex(inf, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(-zero, -zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(zero, 1), complex(inf, nan)},
+ {complex(nan, inf), complex(-zero, -1), complex(-inf, nan)},
+ {complex(nan, inf), complex(zero, 2), complex(inf, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(1, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(1, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(1, 1), complex(inf, inf)},
+ {complex(nan, inf), complex(1, -1), complex(-inf, inf)},
+ {complex(nan, inf), complex(1, 2), complex(inf, inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(-1, zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(-1, -zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(-1, 1), complex(inf, -inf)},
+ {complex(nan, inf), complex(-1, -1), complex(-inf, -inf)},
+ {complex(nan, inf), complex(-1, 2), complex(inf, -inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(2, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(2, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(2, 1), complex(inf, inf)},
+ {complex(nan, inf), complex(2, -1), complex(-inf, inf)},
+ {complex(nan, inf), complex(2, 2), complex(inf, inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(zero, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(zero, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(zero, 1), complex(-inf, nan)},
+ {complex(nan, -inf), complex(zero, -1), complex(inf, nan)},
+ {complex(nan, -inf), complex(zero, 2), complex(-inf, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(zero, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(-zero, -zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(zero, 1), complex(-inf, nan)},
+ {complex(nan, -inf), complex(-zero, -1), complex(inf, nan)},
+ {complex(nan, -inf), complex(zero, 2), complex(-inf, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(1, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(1, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(1, 1), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(1, -1), complex(inf, -inf)},
+ {complex(nan, -inf), complex(1, 2), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(-1, zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(-1, -zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(-1, 1), complex(-inf, inf)},
+ {complex(nan, -inf), complex(-1, -1), complex(inf, inf)},
+ {complex(nan, -inf), complex(-1, 2), complex(-inf, inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(2, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(2, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(2, 1), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(2, -1), complex(inf, -inf)},
+ {complex(nan, -inf), complex(2, 2), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(2, zero), complex(zero, zero), complex(inf, nan)},
+ {complex(2, zero), complex(zero, -zero), complex(inf, nan)},
+ {complex(2, zero), complex(zero, 1), complex(zero, -2)},
+ {complex(2, zero), complex(zero, -1), complex(-zero, 2)},
+ {complex(2, zero), complex(zero, 2), complex(zero, -1)},
+ {complex(2, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(2, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, zero), complex(zero, zero), complex(inf, nan)},
+ {complex(2, zero), complex(-zero, -zero), complex(-inf, nan)},
+ {complex(2, zero), complex(zero, 1), complex(zero, -2)},
+ {complex(2, zero), complex(-zero, -1), complex(-zero, 2)},
+ {complex(2, zero), complex(zero, 2), complex(zero, -1)},
+ {complex(2, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(2, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, zero), complex(1, zero), complex(2, zero)},
+ {complex(2, zero), complex(1, -zero), complex(2, zero)},
+ {complex(2, zero), complex(1, 1), complex(1, -1)},
+ {complex(2, zero), complex(1, -1), complex(1, 1)},
+ {complex(2, zero), complex(1, 2), complex(0.4, -0.8)},
+ {complex(2, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(2, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, zero), complex(-1, zero), complex(-2, -zero)},
+ {complex(2, zero), complex(-1, -zero), complex(-2, -zero)},
+ {complex(2, zero), complex(-1, 1), complex(-1, -1)},
+ {complex(2, zero), complex(-1, -1), complex(-1, 1)},
+ {complex(2, zero), complex(-1, 2), complex(-0.4, -0.8)},
+ {complex(2, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(2, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, zero), complex(2, zero), complex(1, zero)},
+ {complex(2, zero), complex(2, -zero), complex(1, zero)},
+ {complex(2, zero), complex(2, 1), complex(0.8, -0.4)},
+ {complex(2, zero), complex(2, -1), complex(0.8, 0.4)},
+ {complex(2, zero), complex(2, 2), complex(0.5, -0.5)},
+ {complex(2, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(2, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, zero), complex(nan, zero), complex(nan, nan)},
+ {complex(2, zero), complex(nan, -zero), complex(nan, nan)},
+ {complex(2, zero), complex(nan, 1), complex(nan, nan)},
+ {complex(2, zero), complex(nan, -1), complex(nan, nan)},
+ {complex(2, zero), complex(nan, 2), complex(nan, nan)},
+ {complex(2, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(2, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, zero), complex(inf, zero), complex(zero, zero)},
+ {complex(2, zero), complex(inf, -zero), complex(zero, zero)},
+ {complex(2, zero), complex(inf, 1), complex(zero, zero)},
+ {complex(2, zero), complex(inf, -1), complex(zero, zero)},
+ {complex(2, zero), complex(inf, 2), complex(zero, zero)},
+ {complex(2, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(2, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, zero), complex(-inf, zero), complex(-zero, -zero)},
+ {complex(2, zero), complex(-inf, -zero), complex(-zero, -zero)},
+ {complex(2, zero), complex(-inf, 1), complex(-zero, -zero)},
+ {complex(2, zero), complex(-inf, -1), complex(-zero, -zero)},
+ {complex(2, zero), complex(-inf, 2), complex(-zero, -zero)},
+ {complex(2, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(2, zero), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, zero), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, -zero), complex(zero, zero), complex(inf, nan)},
+ {complex(2, -zero), complex(zero, -zero), complex(inf, nan)},
+ {complex(2, -zero), complex(zero, 1), complex(zero, -2)},
+ {complex(2, -zero), complex(zero, -1), complex(zero, 2)},
+ {complex(2, -zero), complex(zero, 2), complex(zero, -1)},
+ {complex(2, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(2, -zero), complex(nan, inf), complex(-zero, -zero)},
+ {complex(2, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(2, -zero), complex(zero, zero), complex(inf, nan)},
+ {complex(2, -zero), complex(-zero, -zero), complex(-inf, nan)},
+ {complex(2, -zero), complex(zero, 1), complex(zero, -2)},
+ {complex(2, -zero), complex(-zero, -1), complex(-zero, 2)},
+ {complex(2, -zero), complex(zero, 2), complex(zero, -1)},
+ {complex(2, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(2, -zero), complex(nan, inf), complex(-zero, -zero)},
+ {complex(2, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(2, -zero), complex(1, zero), complex(2, -zero)},
+ {complex(2, -zero), complex(1, -zero), complex(2, zero)},
+ {complex(2, -zero), complex(1, 1), complex(1, -1)},
+ {complex(2, -zero), complex(1, -1), complex(1, 1)},
+ {complex(2, -zero), complex(1, 2), complex(0.4, -0.8)},
+ {complex(2, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(2, -zero), complex(nan, inf), complex(-zero, -zero)},
+ {complex(2, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(2, -zero), complex(-1, zero), complex(-2, -zero)},
+ {complex(2, -zero), complex(-1, -zero), complex(-2, zero)},
+ {complex(2, -zero), complex(-1, 1), complex(-1, -1)},
+ {complex(2, -zero), complex(-1, -1), complex(-1, 1)},
+ {complex(2, -zero), complex(-1, 2), complex(-0.4, -0.8)},
+ {complex(2, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(2, -zero), complex(nan, inf), complex(-zero, -zero)},
+ {complex(2, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(2, -zero), complex(2, zero), complex(1, -zero)},
+ {complex(2, -zero), complex(2, -zero), complex(1, zero)},
+ {complex(2, -zero), complex(2, 1), complex(0.8, -0.4)},
+ {complex(2, -zero), complex(2, -1), complex(0.8, 0.4)},
+ {complex(2, -zero), complex(2, 2), complex(0.5, -0.5)},
+ {complex(2, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(2, -zero), complex(nan, inf), complex(-zero, -zero)},
+ {complex(2, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(2, -zero), complex(nan, zero), complex(nan, nan)},
+ {complex(2, -zero), complex(nan, -zero), complex(nan, nan)},
+ {complex(2, -zero), complex(nan, 1), complex(nan, nan)},
+ {complex(2, -zero), complex(nan, -1), complex(nan, nan)},
+ {complex(2, -zero), complex(nan, 2), complex(nan, nan)},
+ {complex(2, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(2, -zero), complex(nan, inf), complex(-zero, -zero)},
+ {complex(2, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(2, -zero), complex(inf, zero), complex(zero, -zero)},
+ {complex(2, -zero), complex(inf, -zero), complex(zero, zero)},
+ {complex(2, -zero), complex(inf, 1), complex(zero, -zero)},
+ {complex(2, -zero), complex(inf, -1), complex(zero, zero)},
+ {complex(2, -zero), complex(inf, 2), complex(zero, -zero)},
+ {complex(2, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(2, -zero), complex(nan, inf), complex(-zero, -zero)},
+ {complex(2, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(2, -zero), complex(-inf, zero), complex(-zero, -zero)},
+ {complex(2, -zero), complex(-inf, -zero), complex(-zero, zero)},
+ {complex(2, -zero), complex(-inf, 1), complex(-zero, -zero)},
+ {complex(2, -zero), complex(-inf, -1), complex(-zero, zero)},
+ {complex(2, -zero), complex(-inf, 2), complex(-zero, -zero)},
+ {complex(2, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(2, -zero), complex(nan, inf), complex(-zero, -zero)},
+ {complex(2, -zero), complex(nan, -inf), complex(zero, zero)},
+ {complex(2, 1), complex(zero, zero), complex(inf, inf)},
+ {complex(2, 1), complex(zero, -zero), complex(inf, inf)},
+ {complex(2, 1), complex(zero, 1), complex(1, -2)},
+ {complex(2, 1), complex(zero, -1), complex(-1, 2)},
+ {complex(2, 1), complex(zero, 2), complex(0.5, -1)},
+ {complex(2, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(2, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, 1), complex(zero, zero), complex(inf, inf)},
+ {complex(2, 1), complex(-zero, -zero), complex(-inf, -inf)},
+ {complex(2, 1), complex(zero, 1), complex(1, -2)},
+ {complex(2, 1), complex(-zero, -1), complex(-1, 2)},
+ {complex(2, 1), complex(zero, 2), complex(0.5, -1)},
+ {complex(2, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(2, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, 1), complex(1, zero), complex(2, 1)},
+ {complex(2, 1), complex(1, -zero), complex(2, 1)},
+ {complex(2, 1), complex(1, 1), complex(1.5, -0.5)},
+ {complex(2, 1), complex(1, -1), complex(0.5, 1.5)},
+ {complex(2, 1), complex(1, 2), complex(0.8, -0.6)},
+ {complex(2, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(2, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, 1), complex(-1, zero), complex(-2, -1)},
+ {complex(2, 1), complex(-1, -zero), complex(-2, -1)},
+ {complex(2, 1), complex(-1, 1), complex(-0.5, -1.5)},
+ {complex(2, 1), complex(-1, -1), complex(-1.5, 0.5)},
+ {complex(2, 1), complex(-1, 2), complex(zero, -1)},
+ {complex(2, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(2, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, 1), complex(2, zero), complex(1, 0.5)},
+ {complex(2, 1), complex(2, -zero), complex(1, 0.5)},
+ {complex(2, 1), complex(2, 1), complex(1, zero)},
+ {complex(2, 1), complex(2, -1), complex(0.6, 0.8)},
+ {complex(2, 1), complex(2, 2), complex(0.75, -0.25)},
+ {complex(2, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(2, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, 1), complex(nan, zero), complex(nan, nan)},
+ {complex(2, 1), complex(nan, -zero), complex(nan, nan)},
+ {complex(2, 1), complex(nan, 1), complex(nan, nan)},
+ {complex(2, 1), complex(nan, -1), complex(nan, nan)},
+ {complex(2, 1), complex(nan, 2), complex(nan, nan)},
+ {complex(2, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(2, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, 1), complex(inf, zero), complex(zero, zero)},
+ {complex(2, 1), complex(inf, -zero), complex(zero, zero)},
+ {complex(2, 1), complex(inf, 1), complex(zero, zero)},
+ {complex(2, 1), complex(inf, -1), complex(zero, zero)},
+ {complex(2, 1), complex(inf, 2), complex(zero, zero)},
+ {complex(2, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(2, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, 1), complex(-inf, zero), complex(-zero, -zero)},
+ {complex(2, 1), complex(-inf, -zero), complex(-zero, -zero)},
+ {complex(2, 1), complex(-inf, 1), complex(-zero, -zero)},
+ {complex(2, 1), complex(-inf, -1), complex(-zero, -zero)},
+ {complex(2, 1), complex(-inf, 2), complex(-zero, -zero)},
+ {complex(2, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(2, 1), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, 1), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, -1), complex(zero, zero), complex(inf, -inf)},
+ {complex(2, -1), complex(zero, -zero), complex(inf, -inf)},
+ {complex(2, -1), complex(zero, 1), complex(-1, -2)},
+ {complex(2, -1), complex(zero, -1), complex(1, 2)},
+ {complex(2, -1), complex(zero, 2), complex(-0.5, -1)},
+ {complex(2, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(2, -1), complex(nan, inf), complex(-zero, -zero)},
+ {complex(2, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(2, -1), complex(zero, zero), complex(inf, -inf)},
+ {complex(2, -1), complex(-zero, -zero), complex(-inf, inf)},
+ {complex(2, -1), complex(zero, 1), complex(-1, -2)},
+ {complex(2, -1), complex(-zero, -1), complex(1, 2)},
+ {complex(2, -1), complex(zero, 2), complex(-0.5, -1)},
+ {complex(2, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(2, -1), complex(nan, inf), complex(-zero, -zero)},
+ {complex(2, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(2, -1), complex(1, zero), complex(2, -1)},
+ {complex(2, -1), complex(1, -zero), complex(2, -1)},
+ {complex(2, -1), complex(1, 1), complex(0.5, -1.5)},
+ {complex(2, -1), complex(1, -1), complex(1.5, 0.5)},
+ {complex(2, -1), complex(1, 2), complex(zero, -1)},
+ {complex(2, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(2, -1), complex(nan, inf), complex(-zero, -zero)},
+ {complex(2, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(2, -1), complex(-1, zero), complex(-2, 1)},
+ {complex(2, -1), complex(-1, -zero), complex(-2, 1)},
+ {complex(2, -1), complex(-1, 1), complex(-1.5, -0.5)},
+ {complex(2, -1), complex(-1, -1), complex(-0.5, 1.5)},
+ {complex(2, -1), complex(-1, 2), complex(-0.8, -0.6)},
+ {complex(2, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(2, -1), complex(nan, inf), complex(-zero, -zero)},
+ {complex(2, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(2, -1), complex(2, zero), complex(1, -0.5)},
+ {complex(2, -1), complex(2, -zero), complex(1, -0.5)},
+ {complex(2, -1), complex(2, 1), complex(0.6, -0.8)},
+ {complex(2, -1), complex(2, -1), complex(1, zero)},
+ {complex(2, -1), complex(2, 2), complex(0.25, -0.75)},
+ {complex(2, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(2, -1), complex(nan, inf), complex(-zero, -zero)},
+ {complex(2, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(2, -1), complex(nan, zero), complex(nan, nan)},
+ {complex(2, -1), complex(nan, -zero), complex(nan, nan)},
+ {complex(2, -1), complex(nan, 1), complex(nan, nan)},
+ {complex(2, -1), complex(nan, -1), complex(nan, nan)},
+ {complex(2, -1), complex(nan, 2), complex(nan, nan)},
+ {complex(2, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(2, -1), complex(nan, inf), complex(-zero, -zero)},
+ {complex(2, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(2, -1), complex(inf, zero), complex(zero, -zero)},
+ {complex(2, -1), complex(inf, -zero), complex(zero, -zero)},
+ {complex(2, -1), complex(inf, 1), complex(zero, -zero)},
+ {complex(2, -1), complex(inf, -1), complex(zero, -zero)},
+ {complex(2, -1), complex(inf, 2), complex(zero, -zero)},
+ {complex(2, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(2, -1), complex(nan, inf), complex(-zero, -zero)},
+ {complex(2, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(2, -1), complex(-inf, zero), complex(-zero, zero)},
+ {complex(2, -1), complex(-inf, -zero), complex(-zero, zero)},
+ {complex(2, -1), complex(-inf, 1), complex(-zero, zero)},
+ {complex(2, -1), complex(-inf, -1), complex(-zero, zero)},
+ {complex(2, -1), complex(-inf, 2), complex(-zero, zero)},
+ {complex(2, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(2, -1), complex(nan, inf), complex(-zero, -zero)},
+ {complex(2, -1), complex(nan, -inf), complex(zero, zero)},
+ {complex(2, 2), complex(zero, zero), complex(inf, inf)},
+ {complex(2, 2), complex(zero, -zero), complex(inf, inf)},
+ {complex(2, 2), complex(zero, 1), complex(2, -2)},
+ {complex(2, 2), complex(zero, -1), complex(-2, 2)},
+ {complex(2, 2), complex(zero, 2), complex(1, -1)},
+ {complex(2, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(2, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, 2), complex(zero, zero), complex(inf, inf)},
+ {complex(2, 2), complex(-zero, -zero), complex(-inf, -inf)},
+ {complex(2, 2), complex(zero, 1), complex(2, -2)},
+ {complex(2, 2), complex(-zero, -1), complex(-2, 2)},
+ {complex(2, 2), complex(zero, 2), complex(1, -1)},
+ {complex(2, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(2, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, 2), complex(1, zero), complex(2, 2)},
+ {complex(2, 2), complex(1, -zero), complex(2, 2)},
+ {complex(2, 2), complex(1, 1), complex(2, zero)},
+ {complex(2, 2), complex(1, -1), complex(zero, 2)},
+ {complex(2, 2), complex(1, 2), complex(1.2, -0.4)},
+ {complex(2, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(2, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, 2), complex(-1, zero), complex(-2, -2)},
+ {complex(2, 2), complex(-1, -zero), complex(-2, -2)},
+ {complex(2, 2), complex(-1, 1), complex(-zero, -2)},
+ {complex(2, 2), complex(-1, -1), complex(-2, -zero)},
+ {complex(2, 2), complex(-1, 2), complex(0.4, -1.2)},
+ {complex(2, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(2, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, 2), complex(2, zero), complex(1, 1)},
+ {complex(2, 2), complex(2, -zero), complex(1, 1)},
+ {complex(2, 2), complex(2, 1), complex(1.2, 0.4)},
+ {complex(2, 2), complex(2, -1), complex(0.4, 1.2)},
+ {complex(2, 2), complex(2, 2), complex(1, zero)},
+ {complex(2, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(2, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, 2), complex(nan, zero), complex(nan, nan)},
+ {complex(2, 2), complex(nan, -zero), complex(nan, nan)},
+ {complex(2, 2), complex(nan, 1), complex(nan, nan)},
+ {complex(2, 2), complex(nan, -1), complex(nan, nan)},
+ {complex(2, 2), complex(nan, 2), complex(nan, nan)},
+ {complex(2, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(2, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, 2), complex(inf, zero), complex(zero, zero)},
+ {complex(2, 2), complex(inf, -zero), complex(zero, zero)},
+ {complex(2, 2), complex(inf, 1), complex(zero, zero)},
+ {complex(2, 2), complex(inf, -1), complex(zero, zero)},
+ {complex(2, 2), complex(inf, 2), complex(zero, zero)},
+ {complex(2, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(2, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(2, 2), complex(-inf, zero), complex(-zero, -zero)},
+ {complex(2, 2), complex(-inf, -zero), complex(-zero, -zero)},
+ {complex(2, 2), complex(-inf, 1), complex(-zero, -zero)},
+ {complex(2, 2), complex(-inf, -1), complex(-zero, -zero)},
+ {complex(2, 2), complex(-inf, 2), complex(-zero, -zero)},
+ {complex(2, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(2, 2), complex(nan, inf), complex(zero, -zero)},
+ {complex(2, 2), complex(nan, -inf), complex(-zero, zero)},
+ {complex(nan, nan), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-zero, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-zero, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(1, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(1, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(1, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(1, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(1, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(2, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(2, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(2, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(2, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(2, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(zero, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(zero, 1), complex(inf, nan)},
+ {complex(nan, inf), complex(zero, -1), complex(-inf, nan)},
+ {complex(nan, inf), complex(zero, 2), complex(inf, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(-zero, -zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(zero, 1), complex(inf, nan)},
+ {complex(nan, inf), complex(-zero, -1), complex(-inf, nan)},
+ {complex(nan, inf), complex(zero, 2), complex(inf, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(1, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(1, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(1, 1), complex(inf, inf)},
+ {complex(nan, inf), complex(1, -1), complex(-inf, inf)},
+ {complex(nan, inf), complex(1, 2), complex(inf, inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(-1, zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(-1, -zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(-1, 1), complex(inf, -inf)},
+ {complex(nan, inf), complex(-1, -1), complex(-inf, -inf)},
+ {complex(nan, inf), complex(-1, 2), complex(inf, -inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(2, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(2, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(2, 1), complex(inf, inf)},
+ {complex(nan, inf), complex(2, -1), complex(-inf, inf)},
+ {complex(nan, inf), complex(2, 2), complex(inf, inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(zero, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(zero, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(zero, 1), complex(-inf, nan)},
+ {complex(nan, -inf), complex(zero, -1), complex(inf, nan)},
+ {complex(nan, -inf), complex(zero, 2), complex(-inf, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(zero, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(-zero, -zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(zero, 1), complex(-inf, nan)},
+ {complex(nan, -inf), complex(-zero, -1), complex(inf, nan)},
+ {complex(nan, -inf), complex(zero, 2), complex(-inf, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(1, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(1, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(1, 1), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(1, -1), complex(inf, -inf)},
+ {complex(nan, -inf), complex(1, 2), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(-1, zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(-1, -zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(-1, 1), complex(-inf, inf)},
+ {complex(nan, -inf), complex(-1, -1), complex(inf, inf)},
+ {complex(nan, -inf), complex(-1, 2), complex(-inf, inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(2, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(2, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(2, 1), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(2, -1), complex(inf, -inf)},
+ {complex(nan, -inf), complex(2, 2), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, zero), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, zero), complex(zero, -zero), complex(nan, nan)},
+ {complex(nan, zero), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, zero), complex(zero, -1), complex(nan, nan)},
+ {complex(nan, zero), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, zero), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, zero), complex(-zero, -zero), complex(nan, nan)},
+ {complex(nan, zero), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, zero), complex(-zero, -1), complex(nan, nan)},
+ {complex(nan, zero), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, zero), complex(1, zero), complex(nan, nan)},
+ {complex(nan, zero), complex(1, -zero), complex(nan, nan)},
+ {complex(nan, zero), complex(1, 1), complex(nan, nan)},
+ {complex(nan, zero), complex(1, -1), complex(nan, nan)},
+ {complex(nan, zero), complex(1, 2), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, zero), complex(-1, zero), complex(nan, nan)},
+ {complex(nan, zero), complex(-1, -zero), complex(nan, nan)},
+ {complex(nan, zero), complex(-1, 1), complex(nan, nan)},
+ {complex(nan, zero), complex(-1, -1), complex(nan, nan)},
+ {complex(nan, zero), complex(-1, 2), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, zero), complex(2, zero), complex(nan, nan)},
+ {complex(nan, zero), complex(2, -zero), complex(nan, nan)},
+ {complex(nan, zero), complex(2, 1), complex(nan, nan)},
+ {complex(nan, zero), complex(2, -1), complex(nan, nan)},
+ {complex(nan, zero), complex(2, 2), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, zero), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, zero), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, zero), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, zero), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, zero), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, zero), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, zero), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, zero), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, zero), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, zero), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -zero), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, -zero), complex(zero, -zero), complex(nan, nan)},
+ {complex(nan, -zero), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, -zero), complex(zero, -1), complex(nan, nan)},
+ {complex(nan, -zero), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -zero), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, -zero), complex(-zero, -zero), complex(nan, nan)},
+ {complex(nan, -zero), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, -zero), complex(-zero, -1), complex(nan, nan)},
+ {complex(nan, -zero), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -zero), complex(1, zero), complex(nan, nan)},
+ {complex(nan, -zero), complex(1, -zero), complex(nan, nan)},
+ {complex(nan, -zero), complex(1, 1), complex(nan, nan)},
+ {complex(nan, -zero), complex(1, -1), complex(nan, nan)},
+ {complex(nan, -zero), complex(1, 2), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -zero), complex(-1, zero), complex(nan, nan)},
+ {complex(nan, -zero), complex(-1, -zero), complex(nan, nan)},
+ {complex(nan, -zero), complex(-1, 1), complex(nan, nan)},
+ {complex(nan, -zero), complex(-1, -1), complex(nan, nan)},
+ {complex(nan, -zero), complex(-1, 2), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -zero), complex(2, zero), complex(nan, nan)},
+ {complex(nan, -zero), complex(2, -zero), complex(nan, nan)},
+ {complex(nan, -zero), complex(2, 1), complex(nan, nan)},
+ {complex(nan, -zero), complex(2, -1), complex(nan, nan)},
+ {complex(nan, -zero), complex(2, 2), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -zero), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, -zero), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, -zero), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, -zero), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, -zero), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -zero), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, -zero), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, -zero), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, -zero), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, -zero), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, 1), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, 1), complex(zero, -zero), complex(nan, inf)},
+ {complex(nan, 1), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, 1), complex(zero, -1), complex(nan, nan)},
+ {complex(nan, 1), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, 1), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, 1), complex(-zero, -zero), complex(nan, -inf)},
+ {complex(nan, 1), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, 1), complex(-zero, -1), complex(nan, nan)},
+ {complex(nan, 1), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, 1), complex(1, zero), complex(nan, nan)},
+ {complex(nan, 1), complex(1, -zero), complex(nan, nan)},
+ {complex(nan, 1), complex(1, 1), complex(nan, nan)},
+ {complex(nan, 1), complex(1, -1), complex(nan, nan)},
+ {complex(nan, 1), complex(1, 2), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, 1), complex(-1, zero), complex(nan, nan)},
+ {complex(nan, 1), complex(-1, -zero), complex(nan, nan)},
+ {complex(nan, 1), complex(-1, 1), complex(nan, nan)},
+ {complex(nan, 1), complex(-1, -1), complex(nan, nan)},
+ {complex(nan, 1), complex(-1, 2), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, 1), complex(2, zero), complex(nan, nan)},
+ {complex(nan, 1), complex(2, -zero), complex(nan, nan)},
+ {complex(nan, 1), complex(2, 1), complex(nan, nan)},
+ {complex(nan, 1), complex(2, -1), complex(nan, nan)},
+ {complex(nan, 1), complex(2, 2), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, 1), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, 1), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, 1), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, 1), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, 1), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, 1), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, 1), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, 1), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, 1), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, 1), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -1), complex(zero, zero), complex(nan, -inf)},
+ {complex(nan, -1), complex(zero, -zero), complex(nan, -inf)},
+ {complex(nan, -1), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, -1), complex(zero, -1), complex(nan, nan)},
+ {complex(nan, -1), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -1), complex(zero, zero), complex(nan, -inf)},
+ {complex(nan, -1), complex(-zero, -zero), complex(nan, inf)},
+ {complex(nan, -1), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, -1), complex(-zero, -1), complex(nan, nan)},
+ {complex(nan, -1), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -1), complex(1, zero), complex(nan, nan)},
+ {complex(nan, -1), complex(1, -zero), complex(nan, nan)},
+ {complex(nan, -1), complex(1, 1), complex(nan, nan)},
+ {complex(nan, -1), complex(1, -1), complex(nan, nan)},
+ {complex(nan, -1), complex(1, 2), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -1), complex(-1, zero), complex(nan, nan)},
+ {complex(nan, -1), complex(-1, -zero), complex(nan, nan)},
+ {complex(nan, -1), complex(-1, 1), complex(nan, nan)},
+ {complex(nan, -1), complex(-1, -1), complex(nan, nan)},
+ {complex(nan, -1), complex(-1, 2), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -1), complex(2, zero), complex(nan, nan)},
+ {complex(nan, -1), complex(2, -zero), complex(nan, nan)},
+ {complex(nan, -1), complex(2, 1), complex(nan, nan)},
+ {complex(nan, -1), complex(2, -1), complex(nan, nan)},
+ {complex(nan, -1), complex(2, 2), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -1), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, -1), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, -1), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, -1), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, -1), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -1), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, -1), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, -1), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, -1), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, -1), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, 2), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, 2), complex(zero, -zero), complex(nan, inf)},
+ {complex(nan, 2), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, 2), complex(zero, -1), complex(nan, nan)},
+ {complex(nan, 2), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, 2), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, 2), complex(-zero, -zero), complex(nan, -inf)},
+ {complex(nan, 2), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, 2), complex(-zero, -1), complex(nan, nan)},
+ {complex(nan, 2), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, 2), complex(1, zero), complex(nan, nan)},
+ {complex(nan, 2), complex(1, -zero), complex(nan, nan)},
+ {complex(nan, 2), complex(1, 1), complex(nan, nan)},
+ {complex(nan, 2), complex(1, -1), complex(nan, nan)},
+ {complex(nan, 2), complex(1, 2), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, 2), complex(-1, zero), complex(nan, nan)},
+ {complex(nan, 2), complex(-1, -zero), complex(nan, nan)},
+ {complex(nan, 2), complex(-1, 1), complex(nan, nan)},
+ {complex(nan, 2), complex(-1, -1), complex(nan, nan)},
+ {complex(nan, 2), complex(-1, 2), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, 2), complex(2, zero), complex(nan, nan)},
+ {complex(nan, 2), complex(2, -zero), complex(nan, nan)},
+ {complex(nan, 2), complex(2, 1), complex(nan, nan)},
+ {complex(nan, 2), complex(2, -1), complex(nan, nan)},
+ {complex(nan, 2), complex(2, 2), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, 2), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, 2), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, 2), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, 2), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, 2), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, 2), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, 2), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, 2), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, 2), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, 2), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-zero, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-zero, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(1, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(1, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(1, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(1, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(1, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(2, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(2, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(2, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(2, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(2, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(zero, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(zero, 1), complex(inf, nan)},
+ {complex(nan, inf), complex(zero, -1), complex(-inf, nan)},
+ {complex(nan, inf), complex(zero, 2), complex(inf, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(-zero, -zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(zero, 1), complex(inf, nan)},
+ {complex(nan, inf), complex(-zero, -1), complex(-inf, nan)},
+ {complex(nan, inf), complex(zero, 2), complex(inf, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(1, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(1, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(1, 1), complex(inf, inf)},
+ {complex(nan, inf), complex(1, -1), complex(-inf, inf)},
+ {complex(nan, inf), complex(1, 2), complex(inf, inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(-1, zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(-1, -zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(-1, 1), complex(inf, -inf)},
+ {complex(nan, inf), complex(-1, -1), complex(-inf, -inf)},
+ {complex(nan, inf), complex(-1, 2), complex(inf, -inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(2, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(2, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(2, 1), complex(inf, inf)},
+ {complex(nan, inf), complex(2, -1), complex(-inf, inf)},
+ {complex(nan, inf), complex(2, 2), complex(inf, inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(zero, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(zero, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(zero, 1), complex(-inf, nan)},
+ {complex(nan, -inf), complex(zero, -1), complex(inf, nan)},
+ {complex(nan, -inf), complex(zero, 2), complex(-inf, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(zero, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(-zero, -zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(zero, 1), complex(-inf, nan)},
+ {complex(nan, -inf), complex(-zero, -1), complex(inf, nan)},
+ {complex(nan, -inf), complex(zero, 2), complex(-inf, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(1, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(1, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(1, 1), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(1, -1), complex(inf, -inf)},
+ {complex(nan, -inf), complex(1, 2), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(-1, zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(-1, -zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(-1, 1), complex(-inf, inf)},
+ {complex(nan, -inf), complex(-1, -1), complex(inf, inf)},
+ {complex(nan, -inf), complex(-1, 2), complex(-inf, inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(2, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(2, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(2, 1), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(2, -1), complex(inf, -inf)},
+ {complex(nan, -inf), complex(2, 2), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, zero), complex(zero, zero), complex(inf, nan)},
+ {complex(inf, zero), complex(zero, -zero), complex(inf, nan)},
+ {complex(inf, zero), complex(zero, 1), complex(nan, -inf)},
+ {complex(inf, zero), complex(zero, -1), complex(nan, inf)},
+ {complex(inf, zero), complex(zero, 2), complex(nan, -inf)},
+ {complex(inf, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, zero), complex(zero, zero), complex(inf, nan)},
+ {complex(inf, zero), complex(-zero, -zero), complex(-inf, nan)},
+ {complex(inf, zero), complex(zero, 1), complex(nan, -inf)},
+ {complex(inf, zero), complex(-zero, -1), complex(nan, inf)},
+ {complex(inf, zero), complex(zero, 2), complex(nan, -inf)},
+ {complex(inf, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, zero), complex(1, zero), complex(inf, nan)},
+ {complex(inf, zero), complex(1, -zero), complex(inf, nan)},
+ {complex(inf, zero), complex(1, 1), complex(inf, -inf)},
+ {complex(inf, zero), complex(1, -1), complex(inf, inf)},
+ {complex(inf, zero), complex(1, 2), complex(inf, -inf)},
+ {complex(inf, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, zero), complex(-1, zero), complex(-inf, nan)},
+ {complex(inf, zero), complex(-1, -zero), complex(-inf, nan)},
+ {complex(inf, zero), complex(-1, 1), complex(-inf, -inf)},
+ {complex(inf, zero), complex(-1, -1), complex(-inf, inf)},
+ {complex(inf, zero), complex(-1, 2), complex(-inf, -inf)},
+ {complex(inf, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, zero), complex(2, zero), complex(inf, nan)},
+ {complex(inf, zero), complex(2, -zero), complex(inf, nan)},
+ {complex(inf, zero), complex(2, 1), complex(inf, -inf)},
+ {complex(inf, zero), complex(2, -1), complex(inf, inf)},
+ {complex(inf, zero), complex(2, 2), complex(inf, -inf)},
+ {complex(inf, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, zero), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, -zero), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, 1), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, -1), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, 2), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, zero), complex(inf, zero), complex(nan, nan)},
+ {complex(inf, zero), complex(inf, -zero), complex(nan, nan)},
+ {complex(inf, zero), complex(inf, 1), complex(nan, nan)},
+ {complex(inf, zero), complex(inf, -1), complex(nan, nan)},
+ {complex(inf, zero), complex(inf, 2), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, zero), complex(-inf, zero), complex(nan, nan)},
+ {complex(inf, zero), complex(-inf, -zero), complex(nan, nan)},
+ {complex(inf, zero), complex(-inf, 1), complex(nan, nan)},
+ {complex(inf, zero), complex(-inf, -1), complex(nan, nan)},
+ {complex(inf, zero), complex(-inf, 2), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, -zero), complex(zero, zero), complex(inf, nan)},
+ {complex(inf, -zero), complex(zero, -zero), complex(inf, nan)},
+ {complex(inf, -zero), complex(zero, 1), complex(nan, -inf)},
+ {complex(inf, -zero), complex(zero, -1), complex(nan, inf)},
+ {complex(inf, -zero), complex(zero, 2), complex(nan, -inf)},
+ {complex(inf, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, -zero), complex(zero, zero), complex(inf, nan)},
+ {complex(inf, -zero), complex(-zero, -zero), complex(-inf, nan)},
+ {complex(inf, -zero), complex(zero, 1), complex(nan, -inf)},
+ {complex(inf, -zero), complex(-zero, -1), complex(nan, inf)},
+ {complex(inf, -zero), complex(zero, 2), complex(nan, -inf)},
+ {complex(inf, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, -zero), complex(1, zero), complex(inf, nan)},
+ {complex(inf, -zero), complex(1, -zero), complex(inf, nan)},
+ {complex(inf, -zero), complex(1, 1), complex(inf, -inf)},
+ {complex(inf, -zero), complex(1, -1), complex(inf, inf)},
+ {complex(inf, -zero), complex(1, 2), complex(inf, -inf)},
+ {complex(inf, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, -zero), complex(-1, zero), complex(-inf, nan)},
+ {complex(inf, -zero), complex(-1, -zero), complex(-inf, nan)},
+ {complex(inf, -zero), complex(-1, 1), complex(-inf, -inf)},
+ {complex(inf, -zero), complex(-1, -1), complex(-inf, inf)},
+ {complex(inf, -zero), complex(-1, 2), complex(-inf, -inf)},
+ {complex(inf, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, -zero), complex(2, zero), complex(inf, nan)},
+ {complex(inf, -zero), complex(2, -zero), complex(inf, nan)},
+ {complex(inf, -zero), complex(2, 1), complex(inf, -inf)},
+ {complex(inf, -zero), complex(2, -1), complex(inf, inf)},
+ {complex(inf, -zero), complex(2, 2), complex(inf, -inf)},
+ {complex(inf, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, zero), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, -zero), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, 1), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, -1), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, 2), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, -zero), complex(inf, zero), complex(nan, nan)},
+ {complex(inf, -zero), complex(inf, -zero), complex(nan, nan)},
+ {complex(inf, -zero), complex(inf, 1), complex(nan, nan)},
+ {complex(inf, -zero), complex(inf, -1), complex(nan, nan)},
+ {complex(inf, -zero), complex(inf, 2), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, -zero), complex(-inf, zero), complex(nan, nan)},
+ {complex(inf, -zero), complex(-inf, -zero), complex(nan, nan)},
+ {complex(inf, -zero), complex(-inf, 1), complex(nan, nan)},
+ {complex(inf, -zero), complex(-inf, -1), complex(nan, nan)},
+ {complex(inf, -zero), complex(-inf, 2), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, 1), complex(zero, zero), complex(inf, inf)},
+ {complex(inf, 1), complex(zero, -zero), complex(inf, inf)},
+ {complex(inf, 1), complex(zero, 1), complex(nan, -inf)},
+ {complex(inf, 1), complex(zero, -1), complex(nan, inf)},
+ {complex(inf, 1), complex(zero, 2), complex(nan, -inf)},
+ {complex(inf, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, 1), complex(zero, zero), complex(inf, inf)},
+ {complex(inf, 1), complex(-zero, -zero), complex(-inf, -inf)},
+ {complex(inf, 1), complex(zero, 1), complex(nan, -inf)},
+ {complex(inf, 1), complex(-zero, -1), complex(nan, inf)},
+ {complex(inf, 1), complex(zero, 2), complex(nan, -inf)},
+ {complex(inf, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, 1), complex(1, zero), complex(inf, nan)},
+ {complex(inf, 1), complex(1, -zero), complex(inf, nan)},
+ {complex(inf, 1), complex(1, 1), complex(inf, -inf)},
+ {complex(inf, 1), complex(1, -1), complex(inf, inf)},
+ {complex(inf, 1), complex(1, 2), complex(inf, -inf)},
+ {complex(inf, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, 1), complex(-1, zero), complex(-inf, nan)},
+ {complex(inf, 1), complex(-1, -zero), complex(-inf, nan)},
+ {complex(inf, 1), complex(-1, 1), complex(-inf, -inf)},
+ {complex(inf, 1), complex(-1, -1), complex(-inf, inf)},
+ {complex(inf, 1), complex(-1, 2), complex(-inf, -inf)},
+ {complex(inf, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, 1), complex(2, zero), complex(inf, nan)},
+ {complex(inf, 1), complex(2, -zero), complex(inf, nan)},
+ {complex(inf, 1), complex(2, 1), complex(inf, -inf)},
+ {complex(inf, 1), complex(2, -1), complex(inf, inf)},
+ {complex(inf, 1), complex(2, 2), complex(inf, -inf)},
+ {complex(inf, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, zero), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, -zero), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, 1), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, -1), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, 2), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, 1), complex(inf, zero), complex(nan, nan)},
+ {complex(inf, 1), complex(inf, -zero), complex(nan, nan)},
+ {complex(inf, 1), complex(inf, 1), complex(nan, nan)},
+ {complex(inf, 1), complex(inf, -1), complex(nan, nan)},
+ {complex(inf, 1), complex(inf, 2), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, 1), complex(-inf, zero), complex(nan, nan)},
+ {complex(inf, 1), complex(-inf, -zero), complex(nan, nan)},
+ {complex(inf, 1), complex(-inf, 1), complex(nan, nan)},
+ {complex(inf, 1), complex(-inf, -1), complex(nan, nan)},
+ {complex(inf, 1), complex(-inf, 2), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, -1), complex(zero, zero), complex(inf, -inf)},
+ {complex(inf, -1), complex(zero, -zero), complex(inf, -inf)},
+ {complex(inf, -1), complex(zero, 1), complex(nan, -inf)},
+ {complex(inf, -1), complex(zero, -1), complex(nan, inf)},
+ {complex(inf, -1), complex(zero, 2), complex(nan, -inf)},
+ {complex(inf, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, -1), complex(zero, zero), complex(inf, -inf)},
+ {complex(inf, -1), complex(-zero, -zero), complex(-inf, inf)},
+ {complex(inf, -1), complex(zero, 1), complex(nan, -inf)},
+ {complex(inf, -1), complex(-zero, -1), complex(nan, inf)},
+ {complex(inf, -1), complex(zero, 2), complex(nan, -inf)},
+ {complex(inf, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, -1), complex(1, zero), complex(inf, nan)},
+ {complex(inf, -1), complex(1, -zero), complex(inf, nan)},
+ {complex(inf, -1), complex(1, 1), complex(inf, -inf)},
+ {complex(inf, -1), complex(1, -1), complex(inf, inf)},
+ {complex(inf, -1), complex(1, 2), complex(inf, -inf)},
+ {complex(inf, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, -1), complex(-1, zero), complex(-inf, nan)},
+ {complex(inf, -1), complex(-1, -zero), complex(-inf, nan)},
+ {complex(inf, -1), complex(-1, 1), complex(-inf, -inf)},
+ {complex(inf, -1), complex(-1, -1), complex(-inf, inf)},
+ {complex(inf, -1), complex(-1, 2), complex(-inf, -inf)},
+ {complex(inf, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, -1), complex(2, zero), complex(inf, nan)},
+ {complex(inf, -1), complex(2, -zero), complex(inf, nan)},
+ {complex(inf, -1), complex(2, 1), complex(inf, -inf)},
+ {complex(inf, -1), complex(2, -1), complex(inf, inf)},
+ {complex(inf, -1), complex(2, 2), complex(inf, -inf)},
+ {complex(inf, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, zero), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, -zero), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, 1), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, -1), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, 2), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, -1), complex(inf, zero), complex(nan, nan)},
+ {complex(inf, -1), complex(inf, -zero), complex(nan, nan)},
+ {complex(inf, -1), complex(inf, 1), complex(nan, nan)},
+ {complex(inf, -1), complex(inf, -1), complex(nan, nan)},
+ {complex(inf, -1), complex(inf, 2), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, -1), complex(-inf, zero), complex(nan, nan)},
+ {complex(inf, -1), complex(-inf, -zero), complex(nan, nan)},
+ {complex(inf, -1), complex(-inf, 1), complex(nan, nan)},
+ {complex(inf, -1), complex(-inf, -1), complex(nan, nan)},
+ {complex(inf, -1), complex(-inf, 2), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, 2), complex(zero, zero), complex(inf, inf)},
+ {complex(inf, 2), complex(zero, -zero), complex(inf, inf)},
+ {complex(inf, 2), complex(zero, 1), complex(nan, -inf)},
+ {complex(inf, 2), complex(zero, -1), complex(nan, inf)},
+ {complex(inf, 2), complex(zero, 2), complex(nan, -inf)},
+ {complex(inf, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, 2), complex(zero, zero), complex(inf, inf)},
+ {complex(inf, 2), complex(-zero, -zero), complex(-inf, -inf)},
+ {complex(inf, 2), complex(zero, 1), complex(nan, -inf)},
+ {complex(inf, 2), complex(-zero, -1), complex(nan, inf)},
+ {complex(inf, 2), complex(zero, 2), complex(nan, -inf)},
+ {complex(inf, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, 2), complex(1, zero), complex(inf, nan)},
+ {complex(inf, 2), complex(1, -zero), complex(inf, nan)},
+ {complex(inf, 2), complex(1, 1), complex(inf, -inf)},
+ {complex(inf, 2), complex(1, -1), complex(inf, inf)},
+ {complex(inf, 2), complex(1, 2), complex(inf, -inf)},
+ {complex(inf, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, 2), complex(-1, zero), complex(-inf, nan)},
+ {complex(inf, 2), complex(-1, -zero), complex(-inf, nan)},
+ {complex(inf, 2), complex(-1, 1), complex(-inf, -inf)},
+ {complex(inf, 2), complex(-1, -1), complex(-inf, inf)},
+ {complex(inf, 2), complex(-1, 2), complex(-inf, -inf)},
+ {complex(inf, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, 2), complex(2, zero), complex(inf, nan)},
+ {complex(inf, 2), complex(2, -zero), complex(inf, nan)},
+ {complex(inf, 2), complex(2, 1), complex(inf, -inf)},
+ {complex(inf, 2), complex(2, -1), complex(inf, inf)},
+ {complex(inf, 2), complex(2, 2), complex(inf, -inf)},
+ {complex(inf, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, zero), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, -zero), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, 1), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, -1), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, 2), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, 2), complex(inf, zero), complex(nan, nan)},
+ {complex(inf, 2), complex(inf, -zero), complex(nan, nan)},
+ {complex(inf, 2), complex(inf, 1), complex(nan, nan)},
+ {complex(inf, 2), complex(inf, -1), complex(nan, nan)},
+ {complex(inf, 2), complex(inf, 2), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(inf, 2), complex(-inf, zero), complex(nan, nan)},
+ {complex(inf, 2), complex(-inf, -zero), complex(nan, nan)},
+ {complex(inf, 2), complex(-inf, 1), complex(nan, nan)},
+ {complex(inf, 2), complex(-inf, -1), complex(nan, nan)},
+ {complex(inf, 2), complex(-inf, 2), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(inf, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-zero, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-zero, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(1, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(1, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(1, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(1, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(1, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(2, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(2, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(2, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(2, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(2, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(zero, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(zero, 1), complex(inf, nan)},
+ {complex(nan, inf), complex(zero, -1), complex(-inf, nan)},
+ {complex(nan, inf), complex(zero, 2), complex(inf, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(-zero, -zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(zero, 1), complex(inf, nan)},
+ {complex(nan, inf), complex(-zero, -1), complex(-inf, nan)},
+ {complex(nan, inf), complex(zero, 2), complex(inf, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(1, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(1, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(1, 1), complex(inf, inf)},
+ {complex(nan, inf), complex(1, -1), complex(-inf, inf)},
+ {complex(nan, inf), complex(1, 2), complex(inf, inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(-1, zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(-1, -zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(-1, 1), complex(inf, -inf)},
+ {complex(nan, inf), complex(-1, -1), complex(-inf, -inf)},
+ {complex(nan, inf), complex(-1, 2), complex(inf, -inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(2, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(2, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(2, 1), complex(inf, inf)},
+ {complex(nan, inf), complex(2, -1), complex(-inf, inf)},
+ {complex(nan, inf), complex(2, 2), complex(inf, inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(zero, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(zero, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(zero, 1), complex(-inf, nan)},
+ {complex(nan, -inf), complex(zero, -1), complex(inf, nan)},
+ {complex(nan, -inf), complex(zero, 2), complex(-inf, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(zero, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(-zero, -zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(zero, 1), complex(-inf, nan)},
+ {complex(nan, -inf), complex(-zero, -1), complex(inf, nan)},
+ {complex(nan, -inf), complex(zero, 2), complex(-inf, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(1, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(1, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(1, 1), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(1, -1), complex(inf, -inf)},
+ {complex(nan, -inf), complex(1, 2), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(-1, zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(-1, -zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(-1, 1), complex(-inf, inf)},
+ {complex(nan, -inf), complex(-1, -1), complex(inf, inf)},
+ {complex(nan, -inf), complex(-1, 2), complex(-inf, inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(2, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(2, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(2, 1), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(2, -1), complex(inf, -inf)},
+ {complex(nan, -inf), complex(2, 2), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, zero), complex(zero, zero), complex(-inf, nan)},
+ {complex(-inf, zero), complex(zero, -zero), complex(-inf, nan)},
+ {complex(-inf, zero), complex(zero, 1), complex(nan, inf)},
+ {complex(-inf, zero), complex(zero, -1), complex(nan, -inf)},
+ {complex(-inf, zero), complex(zero, 2), complex(nan, inf)},
+ {complex(-inf, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, zero), complex(zero, zero), complex(-inf, nan)},
+ {complex(-inf, zero), complex(-zero, -zero), complex(inf, nan)},
+ {complex(-inf, zero), complex(zero, 1), complex(nan, inf)},
+ {complex(-inf, zero), complex(-zero, -1), complex(nan, -inf)},
+ {complex(-inf, zero), complex(zero, 2), complex(nan, inf)},
+ {complex(-inf, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, zero), complex(1, zero), complex(-inf, nan)},
+ {complex(-inf, zero), complex(1, -zero), complex(-inf, nan)},
+ {complex(-inf, zero), complex(1, 1), complex(-inf, inf)},
+ {complex(-inf, zero), complex(1, -1), complex(-inf, -inf)},
+ {complex(-inf, zero), complex(1, 2), complex(-inf, inf)},
+ {complex(-inf, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, zero), complex(-1, zero), complex(inf, nan)},
+ {complex(-inf, zero), complex(-1, -zero), complex(inf, nan)},
+ {complex(-inf, zero), complex(-1, 1), complex(inf, inf)},
+ {complex(-inf, zero), complex(-1, -1), complex(inf, -inf)},
+ {complex(-inf, zero), complex(-1, 2), complex(inf, inf)},
+ {complex(-inf, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, zero), complex(2, zero), complex(-inf, nan)},
+ {complex(-inf, zero), complex(2, -zero), complex(-inf, nan)},
+ {complex(-inf, zero), complex(2, 1), complex(-inf, inf)},
+ {complex(-inf, zero), complex(2, -1), complex(-inf, -inf)},
+ {complex(-inf, zero), complex(2, 2), complex(-inf, inf)},
+ {complex(-inf, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, zero), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, -zero), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, 1), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, -1), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, 2), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, zero), complex(inf, zero), complex(nan, nan)},
+ {complex(-inf, zero), complex(inf, -zero), complex(nan, nan)},
+ {complex(-inf, zero), complex(inf, 1), complex(nan, nan)},
+ {complex(-inf, zero), complex(inf, -1), complex(nan, nan)},
+ {complex(-inf, zero), complex(inf, 2), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, zero), complex(-inf, zero), complex(nan, nan)},
+ {complex(-inf, zero), complex(-inf, -zero), complex(nan, nan)},
+ {complex(-inf, zero), complex(-inf, 1), complex(nan, nan)},
+ {complex(-inf, zero), complex(-inf, -1), complex(nan, nan)},
+ {complex(-inf, zero), complex(-inf, 2), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, -zero), complex(zero, zero), complex(-inf, nan)},
+ {complex(-inf, -zero), complex(zero, -zero), complex(-inf, nan)},
+ {complex(-inf, -zero), complex(zero, 1), complex(nan, inf)},
+ {complex(-inf, -zero), complex(zero, -1), complex(nan, -inf)},
+ {complex(-inf, -zero), complex(zero, 2), complex(nan, inf)},
+ {complex(-inf, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, -zero), complex(zero, zero), complex(-inf, nan)},
+ {complex(-inf, -zero), complex(-zero, -zero), complex(inf, nan)},
+ {complex(-inf, -zero), complex(zero, 1), complex(nan, inf)},
+ {complex(-inf, -zero), complex(-zero, -1), complex(nan, -inf)},
+ {complex(-inf, -zero), complex(zero, 2), complex(nan, inf)},
+ {complex(-inf, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, -zero), complex(1, zero), complex(-inf, nan)},
+ {complex(-inf, -zero), complex(1, -zero), complex(-inf, nan)},
+ {complex(-inf, -zero), complex(1, 1), complex(-inf, inf)},
+ {complex(-inf, -zero), complex(1, -1), complex(-inf, -inf)},
+ {complex(-inf, -zero), complex(1, 2), complex(-inf, inf)},
+ {complex(-inf, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, -zero), complex(-1, zero), complex(inf, nan)},
+ {complex(-inf, -zero), complex(-1, -zero), complex(inf, nan)},
+ {complex(-inf, -zero), complex(-1, 1), complex(inf, inf)},
+ {complex(-inf, -zero), complex(-1, -1), complex(inf, -inf)},
+ {complex(-inf, -zero), complex(-1, 2), complex(inf, inf)},
+ {complex(-inf, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, -zero), complex(2, zero), complex(-inf, nan)},
+ {complex(-inf, -zero), complex(2, -zero), complex(-inf, nan)},
+ {complex(-inf, -zero), complex(2, 1), complex(-inf, inf)},
+ {complex(-inf, -zero), complex(2, -1), complex(-inf, -inf)},
+ {complex(-inf, -zero), complex(2, 2), complex(-inf, inf)},
+ {complex(-inf, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, zero), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, -zero), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, 1), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, -1), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, 2), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, -zero), complex(inf, zero), complex(nan, nan)},
+ {complex(-inf, -zero), complex(inf, -zero), complex(nan, nan)},
+ {complex(-inf, -zero), complex(inf, 1), complex(nan, nan)},
+ {complex(-inf, -zero), complex(inf, -1), complex(nan, nan)},
+ {complex(-inf, -zero), complex(inf, 2), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, -zero), complex(-inf, zero), complex(nan, nan)},
+ {complex(-inf, -zero), complex(-inf, -zero), complex(nan, nan)},
+ {complex(-inf, -zero), complex(-inf, 1), complex(nan, nan)},
+ {complex(-inf, -zero), complex(-inf, -1), complex(nan, nan)},
+ {complex(-inf, -zero), complex(-inf, 2), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, -zero), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, 1), complex(zero, zero), complex(-inf, inf)},
+ {complex(-inf, 1), complex(zero, -zero), complex(-inf, inf)},
+ {complex(-inf, 1), complex(zero, 1), complex(nan, inf)},
+ {complex(-inf, 1), complex(zero, -1), complex(nan, -inf)},
+ {complex(-inf, 1), complex(zero, 2), complex(nan, inf)},
+ {complex(-inf, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, 1), complex(zero, zero), complex(-inf, inf)},
+ {complex(-inf, 1), complex(-zero, -zero), complex(inf, -inf)},
+ {complex(-inf, 1), complex(zero, 1), complex(nan, inf)},
+ {complex(-inf, 1), complex(-zero, -1), complex(nan, -inf)},
+ {complex(-inf, 1), complex(zero, 2), complex(nan, inf)},
+ {complex(-inf, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, 1), complex(1, zero), complex(-inf, nan)},
+ {complex(-inf, 1), complex(1, -zero), complex(-inf, nan)},
+ {complex(-inf, 1), complex(1, 1), complex(-inf, inf)},
+ {complex(-inf, 1), complex(1, -1), complex(-inf, -inf)},
+ {complex(-inf, 1), complex(1, 2), complex(-inf, inf)},
+ {complex(-inf, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, 1), complex(-1, zero), complex(inf, nan)},
+ {complex(-inf, 1), complex(-1, -zero), complex(inf, nan)},
+ {complex(-inf, 1), complex(-1, 1), complex(inf, inf)},
+ {complex(-inf, 1), complex(-1, -1), complex(inf, -inf)},
+ {complex(-inf, 1), complex(-1, 2), complex(inf, inf)},
+ {complex(-inf, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, 1), complex(2, zero), complex(-inf, nan)},
+ {complex(-inf, 1), complex(2, -zero), complex(-inf, nan)},
+ {complex(-inf, 1), complex(2, 1), complex(-inf, inf)},
+ {complex(-inf, 1), complex(2, -1), complex(-inf, -inf)},
+ {complex(-inf, 1), complex(2, 2), complex(-inf, inf)},
+ {complex(-inf, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, zero), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, -zero), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, 1), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, -1), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, 2), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, 1), complex(inf, zero), complex(nan, nan)},
+ {complex(-inf, 1), complex(inf, -zero), complex(nan, nan)},
+ {complex(-inf, 1), complex(inf, 1), complex(nan, nan)},
+ {complex(-inf, 1), complex(inf, -1), complex(nan, nan)},
+ {complex(-inf, 1), complex(inf, 2), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, 1), complex(-inf, zero), complex(nan, nan)},
+ {complex(-inf, 1), complex(-inf, -zero), complex(nan, nan)},
+ {complex(-inf, 1), complex(-inf, 1), complex(nan, nan)},
+ {complex(-inf, 1), complex(-inf, -1), complex(nan, nan)},
+ {complex(-inf, 1), complex(-inf, 2), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, 1), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, -1), complex(zero, zero), complex(-inf, -inf)},
+ {complex(-inf, -1), complex(zero, -zero), complex(-inf, -inf)},
+ {complex(-inf, -1), complex(zero, 1), complex(nan, inf)},
+ {complex(-inf, -1), complex(zero, -1), complex(nan, -inf)},
+ {complex(-inf, -1), complex(zero, 2), complex(nan, inf)},
+ {complex(-inf, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, -1), complex(zero, zero), complex(-inf, -inf)},
+ {complex(-inf, -1), complex(-zero, -zero), complex(inf, inf)},
+ {complex(-inf, -1), complex(zero, 1), complex(nan, inf)},
+ {complex(-inf, -1), complex(-zero, -1), complex(nan, -inf)},
+ {complex(-inf, -1), complex(zero, 2), complex(nan, inf)},
+ {complex(-inf, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, -1), complex(1, zero), complex(-inf, nan)},
+ {complex(-inf, -1), complex(1, -zero), complex(-inf, nan)},
+ {complex(-inf, -1), complex(1, 1), complex(-inf, inf)},
+ {complex(-inf, -1), complex(1, -1), complex(-inf, -inf)},
+ {complex(-inf, -1), complex(1, 2), complex(-inf, inf)},
+ {complex(-inf, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, -1), complex(-1, zero), complex(inf, nan)},
+ {complex(-inf, -1), complex(-1, -zero), complex(inf, nan)},
+ {complex(-inf, -1), complex(-1, 1), complex(inf, inf)},
+ {complex(-inf, -1), complex(-1, -1), complex(inf, -inf)},
+ {complex(-inf, -1), complex(-1, 2), complex(inf, inf)},
+ {complex(-inf, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, -1), complex(2, zero), complex(-inf, nan)},
+ {complex(-inf, -1), complex(2, -zero), complex(-inf, nan)},
+ {complex(-inf, -1), complex(2, 1), complex(-inf, inf)},
+ {complex(-inf, -1), complex(2, -1), complex(-inf, -inf)},
+ {complex(-inf, -1), complex(2, 2), complex(-inf, inf)},
+ {complex(-inf, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, zero), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, -zero), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, 1), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, -1), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, 2), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, -1), complex(inf, zero), complex(nan, nan)},
+ {complex(-inf, -1), complex(inf, -zero), complex(nan, nan)},
+ {complex(-inf, -1), complex(inf, 1), complex(nan, nan)},
+ {complex(-inf, -1), complex(inf, -1), complex(nan, nan)},
+ {complex(-inf, -1), complex(inf, 2), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, -1), complex(-inf, zero), complex(nan, nan)},
+ {complex(-inf, -1), complex(-inf, -zero), complex(nan, nan)},
+ {complex(-inf, -1), complex(-inf, 1), complex(nan, nan)},
+ {complex(-inf, -1), complex(-inf, -1), complex(nan, nan)},
+ {complex(-inf, -1), complex(-inf, 2), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, -1), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, 2), complex(zero, zero), complex(-inf, inf)},
+ {complex(-inf, 2), complex(zero, -zero), complex(-inf, inf)},
+ {complex(-inf, 2), complex(zero, 1), complex(nan, inf)},
+ {complex(-inf, 2), complex(zero, -1), complex(nan, -inf)},
+ {complex(-inf, 2), complex(zero, 2), complex(nan, inf)},
+ {complex(-inf, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, 2), complex(zero, zero), complex(-inf, inf)},
+ {complex(-inf, 2), complex(-zero, -zero), complex(inf, -inf)},
+ {complex(-inf, 2), complex(zero, 1), complex(nan, inf)},
+ {complex(-inf, 2), complex(-zero, -1), complex(nan, -inf)},
+ {complex(-inf, 2), complex(zero, 2), complex(nan, inf)},
+ {complex(-inf, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, 2), complex(1, zero), complex(-inf, nan)},
+ {complex(-inf, 2), complex(1, -zero), complex(-inf, nan)},
+ {complex(-inf, 2), complex(1, 1), complex(-inf, inf)},
+ {complex(-inf, 2), complex(1, -1), complex(-inf, -inf)},
+ {complex(-inf, 2), complex(1, 2), complex(-inf, inf)},
+ {complex(-inf, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, 2), complex(-1, zero), complex(inf, nan)},
+ {complex(-inf, 2), complex(-1, -zero), complex(inf, nan)},
+ {complex(-inf, 2), complex(-1, 1), complex(inf, inf)},
+ {complex(-inf, 2), complex(-1, -1), complex(inf, -inf)},
+ {complex(-inf, 2), complex(-1, 2), complex(inf, inf)},
+ {complex(-inf, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, 2), complex(2, zero), complex(-inf, nan)},
+ {complex(-inf, 2), complex(2, -zero), complex(-inf, nan)},
+ {complex(-inf, 2), complex(2, 1), complex(-inf, inf)},
+ {complex(-inf, 2), complex(2, -1), complex(-inf, -inf)},
+ {complex(-inf, 2), complex(2, 2), complex(-inf, inf)},
+ {complex(-inf, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, zero), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, -zero), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, 1), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, -1), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, 2), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, 2), complex(inf, zero), complex(nan, nan)},
+ {complex(-inf, 2), complex(inf, -zero), complex(nan, nan)},
+ {complex(-inf, 2), complex(inf, 1), complex(nan, nan)},
+ {complex(-inf, 2), complex(inf, -1), complex(nan, nan)},
+ {complex(-inf, 2), complex(inf, 2), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(-inf, 2), complex(-inf, zero), complex(nan, nan)},
+ {complex(-inf, 2), complex(-inf, -zero), complex(nan, nan)},
+ {complex(-inf, 2), complex(-inf, 1), complex(nan, nan)},
+ {complex(-inf, 2), complex(-inf, -1), complex(nan, nan)},
+ {complex(-inf, 2), complex(-inf, 2), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, nan), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, inf), complex(nan, nan)},
+ {complex(-inf, 2), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-zero, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-zero, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(zero, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(1, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(1, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(1, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(1, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(1, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(-1, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(2, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(2, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(2, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(2, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(2, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, nan), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, nan), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(zero, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(zero, 1), complex(inf, nan)},
+ {complex(nan, inf), complex(zero, -1), complex(-inf, nan)},
+ {complex(nan, inf), complex(zero, 2), complex(inf, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(zero, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(-zero, -zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(zero, 1), complex(inf, nan)},
+ {complex(nan, inf), complex(-zero, -1), complex(-inf, nan)},
+ {complex(nan, inf), complex(zero, 2), complex(inf, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(1, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(1, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(1, 1), complex(inf, inf)},
+ {complex(nan, inf), complex(1, -1), complex(-inf, inf)},
+ {complex(nan, inf), complex(1, 2), complex(inf, inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(-1, zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(-1, -zero), complex(nan, -inf)},
+ {complex(nan, inf), complex(-1, 1), complex(inf, -inf)},
+ {complex(nan, inf), complex(-1, -1), complex(-inf, -inf)},
+ {complex(nan, inf), complex(-1, 2), complex(inf, -inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(2, zero), complex(nan, inf)},
+ {complex(nan, inf), complex(2, -zero), complex(nan, inf)},
+ {complex(nan, inf), complex(2, 1), complex(inf, inf)},
+ {complex(nan, inf), complex(2, -1), complex(-inf, inf)},
+ {complex(nan, inf), complex(2, 2), complex(inf, inf)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, inf), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(zero, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(zero, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(zero, 1), complex(-inf, nan)},
+ {complex(nan, -inf), complex(zero, -1), complex(inf, nan)},
+ {complex(nan, -inf), complex(zero, 2), complex(-inf, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(zero, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(-zero, -zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(zero, 1), complex(-inf, nan)},
+ {complex(nan, -inf), complex(-zero, -1), complex(inf, nan)},
+ {complex(nan, -inf), complex(zero, 2), complex(-inf, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(1, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(1, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(1, 1), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(1, -1), complex(inf, -inf)},
+ {complex(nan, -inf), complex(1, 2), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(-1, zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(-1, -zero), complex(nan, inf)},
+ {complex(nan, -inf), complex(-1, 1), complex(-inf, inf)},
+ {complex(nan, -inf), complex(-1, -1), complex(inf, inf)},
+ {complex(nan, -inf), complex(-1, 2), complex(-inf, inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(2, zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(2, -zero), complex(nan, -inf)},
+ {complex(nan, -inf), complex(2, 1), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(2, -1), complex(inf, -inf)},
+ {complex(nan, -inf), complex(2, 2), complex(-inf, -inf)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(inf, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, -zero), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, 1), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, -1), complex(nan, nan)},
+ {complex(nan, -inf), complex(-inf, 2), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, nan), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, inf), complex(nan, nan)},
+ {complex(nan, -inf), complex(nan, -inf), complex(nan, nan)},
}
diff --git a/gcc/testsuite/go.test/test/complit1.go b/gcc/testsuite/go.test/test/complit1.go
index 521401d..7c2a4e2 100644
--- a/gcc/testsuite/go.test/test/complit1.go
+++ b/gcc/testsuite/go.test/test/complit1.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -22,6 +22,10 @@ var (
_ = m[0][:] // ERROR "slice of unaddressable value"
_ = f()[:] // ERROR "slice of unaddressable value"
+ _ = 301[:] // ERROR "cannot slice|attempt to slice object that is not"
+ _ = 3.1[:] // ERROR "cannot slice|attempt to slice object that is not"
+ _ = true[:] // ERROR "cannot slice|attempt to slice object that is not"
+
// these are okay because they are slicing a pointer to an array
_ = (&[3]int{1, 2, 3})[:]
_ = mp[0][:]
@@ -35,8 +39,27 @@ type T struct {
next *T
}
+type TP *T
+type Ti int
+
var (
_ = &T{0, 0, "", nil} // ok
_ = &T{i: 0, f: 0, s: "", next: {}} // ERROR "missing type in composite literal|omit types within composite literal"
_ = &T{0, 0, "", {}} // ERROR "missing type in composite literal|omit types within composite literal"
+ _ = TP{i: 0, f: 0, s: "", next: {}} // ERROR "invalid composite literal type TP|omit types within composite literal"
+ _ = &Ti{} // ERROR "invalid composite literal type Ti|expected.*type for composite literal"
+)
+
+type M map[T]T
+
+var (
+ _ = M{{i:1}: {i:2}}
+ _ = M{T{i:1}: {i:2}}
+ _ = M{{i:1}: T{i:2}}
+ _ = M{T{i:1}: T{i:2}}
)
+
+type S struct { s [1]*M1 }
+type M1 map[S]int
+var _ = M1{{s:[1]*M1{&M1{{}:1}}}:2}
+
diff --git a/gcc/testsuite/go.test/test/compos.go b/gcc/testsuite/go.test/test/compos.go
index de688b3..e6375f2 100644
--- a/gcc/testsuite/go.test/test/compos.go
+++ b/gcc/testsuite/go.test/test/compos.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/const.go b/gcc/testsuite/go.test/test/const.go
index d583659..f8aa1dd 100644
--- a/gcc/testsuite/go.test/test/const.go
+++ b/gcc/testsuite/go.test/test/const.go
@@ -19,8 +19,15 @@ const (
c3div2 = 3 / 2
c1e3 = 1e3
+ rsh1 = 1e100 >> 1000
+ rsh2 = 1e302 >> 1000
+
ctrue = true
cfalse = !ctrue
+
+ // Issue #34563
+ _ = string(int(123))
+ _ = string(rune(456))
)
const (
@@ -48,6 +55,8 @@ func ints() {
assert(c3div2 == 1, "3/2")
assert(c1e3 == 1000, "c1e3 int")
assert(c1e3 == 1e3, "c1e3 float")
+ assert(rsh1 == 0, "rsh1")
+ assert(rsh2 == 9, "rsh2")
// verify that all (in range) are assignable as ints
var i int
@@ -118,9 +127,83 @@ func floats() {
assert(f == f1e3, "f == f1e3")
}
+func interfaces() {
+ var (
+ nilN interface{}
+ nilI *int
+ five = 5
+
+ _ = nil == interface{}(nil)
+ _ = interface{}(nil) == nil
+ )
+ ii := func(i1 interface{}, i2 interface{}) bool { return i1 == i2 }
+ ni := func(n interface{}, i int) bool { return n == i }
+ in := func(i int, n interface{}) bool { return i == n }
+ pi := func(p *int, i interface{}) bool { return p == i }
+ ip := func(i interface{}, p *int) bool { return i == p }
+
+ assert((interface{}(nil) == interface{}(nil)) == ii(nilN, nilN),
+ "for interface{}==interface{} compiler == runtime")
+
+ assert(((*int)(nil) == interface{}(nil)) == pi(nilI, nilN),
+ "for *int==interface{} compiler == runtime")
+ assert((interface{}(nil) == (*int)(nil)) == ip(nilN, nilI),
+ "for interface{}==*int compiler == runtime")
+
+ assert((&five == interface{}(nil)) == pi(&five, nilN),
+ "for interface{}==*int compiler == runtime")
+ assert((interface{}(nil) == &five) == ip(nilN, &five),
+ "for interface{}==*int compiler == runtime")
+
+ assert((5 == interface{}(5)) == ni(five, five),
+ "for int==interface{} compiler == runtime")
+ assert((interface{}(5) == 5) == in(five, five),
+ "for interface{}==int comipiler == runtime")
+}
+
+// Test that typed floating-point and complex arithmetic
+// is computed with correct precision.
+func truncate() {
+ const (
+ x30 = 1 << 30
+ x60 = 1 << 60
+
+ staticF32 = float32(x30) + 1 - x30
+ staticF64 = float64(x60) + 1 - x60
+ staticC64 = complex64(x30) + 1 - x30
+ staticC128 = complex128(x60) + 1 - x60
+ )
+ dynamicF32 := float32(x30)
+ dynamicF32 += 1
+ dynamicF32 -= x30
+
+ dynamicF64 := float64(x60)
+ dynamicF64 += 1
+ dynamicF64 -= x60
+
+ dynamicC64 := complex64(x30)
+ dynamicC64 += 1
+ dynamicC64 -= x30
+
+ dynamicC128 := complex128(x60)
+ dynamicC128 += 1
+ dynamicC128 -= x60
+
+ assert(staticF32 == 0, "staticF32 == 0")
+ assert(staticF64 == 0, "staticF64 == 0")
+ assert(dynamicF32 == 0, "dynamicF32 == 0")
+ assert(dynamicF64 == 0, "dynamicF64 == 0")
+ assert(staticC64 == 0, "staticC64 == 0")
+ assert(staticC128 == 0, "staticC128 == 0")
+ assert(dynamicC64 == 0, "dynamicC64 == 0")
+ assert(dynamicC128 == 0, "dynamicC128 == 0")
+}
+
func main() {
ints()
floats()
+ interfaces()
+ truncate()
assert(ctrue == true, "ctrue == true")
assert(cfalse == false, "cfalse == false")
diff --git a/gcc/testsuite/go.test/test/const1.go b/gcc/testsuite/go.test/test/const1.go
index 58bddee..3fd5b55 100644
--- a/gcc/testsuite/go.test/test/const1.go
+++ b/gcc/testsuite/go.test/test/const1.go
@@ -68,7 +68,7 @@ var (
c3 float64 = float64(Big) * Big // ERROR "overflow"
c4 = Big * Big // ERROR "overflow"
c5 = Big / 0 // ERROR "division by zero"
- c6 = 1000 % 1e3 // ERROR "floating-point % operation|expected integer type"
+ c6 = 1000 % 1e3 // ERROR "invalid operation|expected integer type"
)
func f(int)
@@ -90,5 +90,5 @@ func main() {
const ptr = nil // ERROR "const.*nil"
const _ = string([]byte(nil)) // ERROR "is not a? ?constant"
const _ = uintptr(unsafe.Pointer((*int)(nil))) // ERROR "is not a? ?constant"
-const _ = unsafe.Pointer((*int)(nil)) // ERROR "cannot be nil|invalid constant type"
-const _ = (*int)(nil) // ERROR "cannot be nil|invalid constant type"
+const _ = unsafe.Pointer((*int)(nil)) // ERROR "cannot be nil|invalid constant type|is not a constant"
+const _ = (*int)(nil) // ERROR "cannot be nil|invalid constant type|is not a constant"
diff --git a/gcc/testsuite/go.test/test/const4.go b/gcc/testsuite/go.test/test/const4.go
index 2fb2d06..785e1ec 100644
--- a/gcc/testsuite/go.test/test/const4.go
+++ b/gcc/testsuite/go.test/test/const4.go
@@ -4,7 +4,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Test len constants and non-constants, http://golang.org/issue/3244.
+// Test len constants and non-constants, https://golang.org/issue/3244.
package main
diff --git a/gcc/testsuite/go.test/test/const5.go b/gcc/testsuite/go.test/test/const5.go
index 87fe33a..51e46cb 100644
--- a/gcc/testsuite/go.test/test/const5.go
+++ b/gcc/testsuite/go.test/test/const5.go
@@ -4,7 +4,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Test that len non-constants are not constants, http://golang.org/issue/3244.
+// Test that len non-constants are not constants, https://golang.org/issue/3244.
package p
@@ -18,6 +18,7 @@ var s [][30]int
func f() *[40]int
var c chan *[50]int
+var z complex128
const (
n1 = len(b.a)
@@ -29,5 +30,8 @@ const (
n6 = cap(f()) // ERROR "is not a constant|is not constant"
n7 = cap(<-c) // ERROR "is not a constant|is not constant"
+ n8 = real(z) // ERROR "is not a constant|is not constant"
+ n9 = len([4]float64{real(z)}) // ERROR "is not a constant|is not constant"
+
)
diff --git a/gcc/testsuite/go.test/test/const6.go b/gcc/testsuite/go.test/test/const6.go
index c005ac3..b340e58 100644
--- a/gcc/testsuite/go.test/test/const6.go
+++ b/gcc/testsuite/go.test/test/const6.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/convert1.go b/gcc/testsuite/go.test/test/convert1.go
index 0f417a3..afb63cd 100644
--- a/gcc/testsuite/go.test/test/convert1.go
+++ b/gcc/testsuite/go.test/test/convert1.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/convlit.go b/gcc/testsuite/go.test/test/convlit.go
index 8a6145d..1c66c89 100644
--- a/gcc/testsuite/go.test/test/convlit.go
+++ b/gcc/testsuite/go.test/test/convlit.go
@@ -9,6 +9,8 @@
package main
+import "unsafe"
+
// explicit conversion of constants
var x1 = string(1)
var x2 string = string(1)
@@ -18,11 +20,16 @@ var x5 = "a" + string(1)
var x6 = int(1e100) // ERROR "overflow"
var x7 = float32(1e1000) // ERROR "overflow"
+// unsafe.Pointer can only convert to/from uintptr
+var _ = string(unsafe.Pointer(uintptr(65))) // ERROR "convert|conversion"
+var _ = float64(unsafe.Pointer(uintptr(65))) // ERROR "convert|conversion"
+var _ = int(unsafe.Pointer(uintptr(65))) // ERROR "convert|conversion"
+
// implicit conversions merit scrutiny
var s string
var bad1 string = 1 // ERROR "conver|incompatible|invalid|cannot"
-var bad2 = s + 1 // ERROR "conver|incompatible|invalid"
-var bad3 = s + 'a' // ERROR "conver|incompatible|invalid"
+var bad2 = s + 1 // ERROR "conver|incompatible|invalid|cannot"
+var bad3 = s + 'a' // ERROR "conver|incompatible|invalid|cannot"
var bad4 = "a" + 1 // ERROR "literals|incompatible|convert|invalid"
var bad5 = "a" + 'a' // ERROR "literals|incompatible|convert|invalid"
diff --git a/gcc/testsuite/go.test/test/ddd.go b/gcc/testsuite/go.test/test/ddd.go
index 01768b8..84503f7 100644
--- a/gcc/testsuite/go.test/test/ddd.go
+++ b/gcc/testsuite/go.test/test/ddd.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/ddd1.go b/gcc/testsuite/go.test/test/ddd1.go
index 07981af..01b9c0e 100644
--- a/gcc/testsuite/go.test/test/ddd1.go
+++ b/gcc/testsuite/go.test/test/ddd1.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -18,8 +18,8 @@ var (
_ = sum()
_ = sum(1.0, 2.0)
_ = sum(1.5) // ERROR "integer"
- _ = sum("hello") // ERROR ".hello. .type string. as type int|incompatible"
- _ = sum([]int{1}) // ERROR "\[\]int literal.*as type int|incompatible"
+ _ = sum("hello") // ERROR ".hello. .type untyped string. as type int|incompatible"
+ _ = sum([]int{1}) // ERROR "\[\]int{...}.*as type int|incompatible"
)
func sum3(int, int, int) int { return 0 }
@@ -27,9 +27,9 @@ func tuple() (int, int, int) { return 1, 2, 3 }
var (
_ = sum(tuple())
- _ = sum(tuple()...) // ERROR "multiple-value|[.][.][.]"
+ _ = sum(tuple()...) // ERROR "multiple-value"
_ = sum3(tuple())
- _ = sum3(tuple()...) // ERROR "multiple-value|[.][.][.]" "not enough"
+ _ = sum3(tuple()...) // ERROR "multiple-value"
)
type T []T
@@ -42,6 +42,8 @@ var (
_ = funny([]T{}) // ok because []T{} is a T; passes []T{[]T{}}
)
+func Foo(n int) {}
+
func bad(args ...int) {
print(1, 2, args...) // ERROR "[.][.][.]"
println(args...) // ERROR "[.][.][.]"
@@ -51,12 +53,12 @@ func bad(args ...int) {
_ = new(int...) // ERROR "[.][.][.]"
n := 10
_ = make([]byte, n...) // ERROR "[.][.][.]"
- // TODO(rsc): enable after gofmt bug is fixed
- // _ = make([]byte, 10 ...) // error "[.][.][.]"
+ _ = make([]byte, 10 ...) // ERROR "[.][.][.]"
var x int
_ = unsafe.Pointer(&x...) // ERROR "[.][.][.]"
_ = unsafe.Sizeof(x...) // ERROR "[.][.][.]"
_ = [...]byte("foo") // ERROR "[.][.][.]"
_ = [...][...]int{{1,2,3},{4,5,6}} // ERROR "[.][.][.]"
-}
+ Foo(x...) // ERROR "invalid use of .*[.][.][.]"
+}
diff --git a/gcc/testsuite/go.test/test/ddd2.dir/ddd2.go b/gcc/testsuite/go.test/test/ddd2.dir/ddd2.go
index c9a2675..f3f863c 100644
--- a/gcc/testsuite/go.test/test/ddd2.dir/ddd2.go
+++ b/gcc/testsuite/go.test/test/ddd2.dir/ddd2.go
@@ -1,4 +1,4 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/ddd2.dir/ddd3.go b/gcc/testsuite/go.test/test/ddd2.dir/ddd3.go
index 5486fe8..608091d 100644
--- a/gcc/testsuite/go.test/test/ddd2.dir/ddd3.go
+++ b/gcc/testsuite/go.test/test/ddd2.dir/ddd3.go
@@ -1,4 +1,4 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/ddd2.go b/gcc/testsuite/go.test/test/ddd2.go
index 0d9f634..612ba29 100644
--- a/gcc/testsuite/go.test/test/ddd2.go
+++ b/gcc/testsuite/go.test/test/ddd2.go
@@ -1,6 +1,6 @@
// rundir
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/deferprint.go b/gcc/testsuite/go.test/test/deferprint.go
index 72c98b1..b74677a 100644
--- a/gcc/testsuite/go.test/test/deferprint.go
+++ b/gcc/testsuite/go.test/test/deferprint.go
@@ -1,6 +1,6 @@
-// cmpout
+// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/divide.go b/gcc/testsuite/go.test/test/divide.go
index b20f106..b557041 100644
--- a/gcc/testsuite/go.test/test/divide.go
+++ b/gcc/testsuite/go.test/test/divide.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/divmod.go b/gcc/testsuite/go.test/test/divmod.go
index 49fed02..ab85b7f 100644
--- a/gcc/testsuite/go.test/test/divmod.go
+++ b/gcc/testsuite/go.test/test/divmod.go
@@ -1,12 +1,12 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Test division of variables. Generate many test cases,
// compute correct answer using shift and subtract,
-// and then compare against results from divison and
+// and then compare against results from division and
// modulus operators.
//
// Primarily useful for testing software div/mod.
diff --git a/gcc/testsuite/go.test/test/eof.go b/gcc/testsuite/go.test/test/eof.go
index 06c7790..d051f33 100644
--- a/gcc/testsuite/go.test/test/eof.go
+++ b/gcc/testsuite/go.test/test/eof.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/eof1.go b/gcc/testsuite/go.test/test/eof1.go
index 2105b89..90792ca 100644
--- a/gcc/testsuite/go.test/test/eof1.go
+++ b/gcc/testsuite/go.test/test/eof1.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/errchk b/gcc/testsuite/go.test/test/errchk
deleted file mode 100755
index de0c4fd..0000000
--- a/gcc/testsuite/go.test/test/errchk
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/usr/bin/env perl
-# Copyright 2009 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.
-
-# This script checks that the compilers emit the errors which we expect.
-# Usage: errchk COMPILER [OPTS] SOURCEFILES. This will run the command
-# COMPILER [OPTS] SOURCEFILES. The compilation is expected to fail; if
-# it succeeds, this script will report an error. The stderr output of
-# the compiler will be matched against comments in SOURCEFILES. For each
-# line of the source files which should generate an error, there should
-# be a comment of the form // ERROR "regexp". If the compiler generates
-# an error for a line which has no such comment, this script will report
-# an error. Likewise if the compiler does not generate an error for a
-# line which has a comment, or if the error message does not match the
-# <regexp>. The <regexp> syntax is Perl but its best to stick to egrep.
-
-use POSIX;
-
-my $exitcode = 1;
-
-if(@ARGV >= 1 && $ARGV[0] eq "-0") {
- $exitcode = 0;
- shift;
-}
-
-if(@ARGV < 1) {
- print STDERR "Usage: errchk COMPILER [OPTS] SOURCEFILES\n";
- exit 1;
-}
-
-# Grab SOURCEFILES
-foreach(reverse 0 .. @ARGV-1) {
- unless($ARGV[$_] =~ /\.(go|s)$/) {
- @file = @ARGV[$_+1 .. @ARGV-1];
- last;
- }
-}
-
-foreach $file (@file) {
- open(SRC, $file) || die "BUG: errchk: open $file: $!";
- $src{$file} = [<SRC>];
- close(SRC);
-}
-
-# Run command
-$cmd = join(' ', @ARGV);
-open(CMD, "exec $cmd </dev/null 2>&1 |") || die "BUG: errchk: run $cmd: $!";
-
-# 6g error messages continue onto additional lines with leading tabs.
-# Split the output at the beginning of each line that doesn't begin with a tab.
-$out = join('', <CMD>);
-@out = split(/^(?!\t)/m, $out);
-
-close CMD;
-
-if($exitcode != 0 && $? == 0) {
- print STDERR "BUG: errchk: command succeeded unexpectedly\n";
- print STDERR @out;
- exit 0;
-}
-
-if($exitcode == 0 && $? != 0) {
- print STDERR "BUG: errchk: command failed unexpectedly\n";
- print STDERR @out;
- exit 0;
-}
-
-if(!WIFEXITED($?)) {
- print STDERR "BUG: errchk: compiler crashed\n";
- print STDERR @out, "\n";
- exit 0;
-}
-
-sub bug() {
- if(!$bug++) {
- print STDERR "BUG: ";
- }
-}
-
-sub chk {
- my $file = shift;
- my $line = 0;
- my $regexp;
- my @errmsg;
- my @match;
- foreach my $src (@{$src{$file}}) {
- $line++;
- next if $src =~ m|////|; # double comment disables ERROR
- next unless $src =~ m|// (GC_)?ERROR (.*)|;
- my $all = $2;
- if($all !~ /^"([^"]*)"/) {
- print STDERR "$file:$line: malformed regexp\n";
- next;
- }
- @errmsg = grep { /$file:$line[:[]/ } @out;
- @out = grep { !/$file:$line[:[]/ } @out;
- if(@errmsg == 0) {
- bug();
- print STDERR "errchk: $file:$line: missing expected error: '$all'\n";
- next;
- }
- foreach my $regexp ($all =~ /"([^"]*)"/g) {
- # Turn relative line number in message into absolute line number.
- if($regexp =~ /LINE(([+-])([0-9]+))?/) {
- my $n = $line;
- if(defined($1)) {
- if($2 eq "+") {
- $n += int($3);
- } else {
- $n -= int($3);
- }
- }
- $regexp = "$`$file:$n$'";
- }
-
- @match = grep { /$regexp/ } @errmsg;
- if(@match == 0) {
- bug();
- print STDERR "errchk: $file:$line: error messages do not match '$regexp'\n";
- next;
- }
- @errmsg = grep { !/$regexp/ } @errmsg;
- }
- if(@errmsg != 0) {
- bug();
- print STDERR "errchk: $file:$line: unmatched error messages:\n";
- foreach my $l (@errmsg) {
- print STDERR "> $l";
- }
- }
- }
-}
-
-foreach $file (@file) {
- chk($file)
-}
-
-if(@out != 0) {
- bug();
- print STDERR "errchk: unmatched error messages:\n";
- print STDERR "==================================================\n";
- print STDERR @out;
- print STDERR "==================================================\n";
-}
-
-exit 0;
diff --git a/gcc/testsuite/go.test/test/escape2.go b/gcc/testsuite/go.test/test/escape2.go
index be89c2d..5c6eb55 100644
--- a/gcc/testsuite/go.test/test/escape2.go
+++ b/gcc/testsuite/go.test/test/escape2.go
@@ -1,12 +1,14 @@
// errorcheck -0 -m -l
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Test, using compiler diagnostic flags, that the escape analysis is working.
// Compiles but does not run. Inlining is disabled.
+// escape2n.go contains all the same tests but compiles with -N.
+
package foo
import (
@@ -16,94 +18,94 @@ import (
var gxx *int
-func foo1(x int) { // ERROR "moved to heap: x"
- gxx = &x // ERROR "&x escapes to heap"
+func foo1(x int) { // ERROR "moved to heap: x$"
+ gxx = &x
}
-func foo2(yy *int) { // ERROR "leaking param: yy"
+func foo2(yy *int) { // ERROR "leaking param: yy$"
gxx = yy
}
-func foo3(x int) *int { // ERROR "moved to heap: x"
- return &x // ERROR "&x escapes to heap"
+func foo3(x int) *int { // ERROR "moved to heap: x$"
+ return &x
}
type T *T
-func foo3b(t T) { // ERROR "leaking param: t"
+func foo3b(t T) { // ERROR "leaking param: t$"
*t = t
}
// xx isn't going anywhere, so use of yy is ok
-func foo4(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape"
+func foo4(xx, yy *int) { // ERROR "xx does not escape$" "yy does not escape$"
xx = yy
}
// xx isn't going anywhere, so taking address of yy is ok
-func foo5(xx **int, yy *int) { // ERROR "xx does not escape" "yy does not escape"
- xx = &yy // ERROR "&yy does not escape"
+func foo5(xx **int, yy *int) { // ERROR "xx does not escape$" "yy does not escape$"
+ xx = &yy
}
-func foo6(xx **int, yy *int) { // ERROR "xx does not escape" "leaking param: yy"
+func foo6(xx **int, yy *int) { // ERROR "xx does not escape$" "leaking param: yy$"
*xx = yy
}
-func foo7(xx **int, yy *int) { // ERROR "xx does not escape" "yy does not escape"
+func foo7(xx **int, yy *int) { // ERROR "xx does not escape$" "yy does not escape$"
**xx = *yy
}
-func foo8(xx, yy *int) int { // ERROR "xx does not escape" "yy does not escape"
+func foo8(xx, yy *int) int { // ERROR "xx does not escape$" "yy does not escape$"
xx = yy
return *xx
}
-func foo9(xx, yy *int) *int { // ERROR "leaking param: xx" "leaking param: yy"
+func foo9(xx, yy *int) *int { // ERROR "leaking param: xx to result ~r2 level=0$" "leaking param: yy to result ~r2 level=0$"
xx = yy
return xx
}
-func foo10(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape"
+func foo10(xx, yy *int) { // ERROR "xx does not escape$" "yy does not escape$"
*xx = *yy
}
func foo11() int {
x, y := 0, 42
- xx := &x // ERROR "&x does not escape"
- yy := &y // ERROR "&y does not escape"
+ xx := &x
+ yy := &y
*xx = *yy
return x
}
var xxx **int
-func foo12(yyy **int) { // ERROR "leaking param: yyy"
+func foo12(yyy **int) { // ERROR "leaking param: yyy$"
xxx = yyy
}
-// Must treat yyy as leaking because *yyy leaks, and the escape analysis
+// Must treat yyy as leaking because *yyy leaks, and the escape analysis
// summaries in exported metadata do not distinguish these two cases.
-func foo13(yyy **int) { // ERROR "leaking param: yyy"
+func foo13(yyy **int) { // ERROR "leaking param content: yyy$"
*xxx = *yyy
}
-func foo14(yyy **int) { // ERROR "yyy does not escape"
+func foo14(yyy **int) { // ERROR "yyy does not escape$"
**xxx = **yyy
}
-func foo15(yy *int) { // ERROR "moved to heap: yy"
- xxx = &yy // ERROR "&yy escapes to heap"
+func foo15(yy *int) { // ERROR "moved to heap: yy$"
+ xxx = &yy
}
-func foo16(yy *int) { // ERROR "leaking param: yy"
+func foo16(yy *int) { // ERROR "leaking param: yy$"
*xxx = yy
}
-func foo17(yy *int) { // ERROR "yy does not escape"
+func foo17(yy *int) { // ERROR "yy does not escape$"
**xxx = *yy
}
-func foo18(y int) { // ERROR "moved to heap: "y"
- *xxx = &y // ERROR "&y escapes to heap"
+func foo18(y int) { // ERROR "moved to heap: y$"
+ *xxx = &y
}
func foo19(y int) {
@@ -116,52 +118,52 @@ type Bar struct {
}
func NewBar() *Bar {
- return &Bar{42, nil} // ERROR "&Bar literal escapes to heap"
+ return &Bar{42, nil} // ERROR "&Bar{...} escapes to heap$"
}
-func NewBarp(x *int) *Bar { // ERROR "leaking param: x"
- return &Bar{42, x} // ERROR "&Bar literal escapes to heap"
+func NewBarp(x *int) *Bar { // ERROR "leaking param: x$"
+ return &Bar{42, x} // ERROR "&Bar{...} escapes to heap$"
}
-func NewBarp2(x *int) *Bar { // ERROR "x does not escape"
- return &Bar{*x, nil} // ERROR "&Bar literal escapes to heap"
+func NewBarp2(x *int) *Bar { // ERROR "x does not escape$"
+ return &Bar{*x, nil} // ERROR "&Bar{...} escapes to heap$"
}
-func (b *Bar) NoLeak() int { // ERROR "b does not escape"
+func (b *Bar) NoLeak() int { // ERROR "b does not escape$"
return *(b.ii)
}
-func (b *Bar) Leak() *int { // ERROR "leaking param: b"
- return &b.i // ERROR "&b.i escapes to heap"
+func (b *Bar) Leak() *int { // ERROR "leaking param: b to result ~r0 level=0$"
+ return &b.i
}
-func (b *Bar) AlsoNoLeak() *int { // ERROR "b does not escape"
+func (b *Bar) AlsoNoLeak() *int { // ERROR "leaking param: b to result ~r0 level=1$"
return b.ii
}
-func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b"
+func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b to result ~r0 level=0$"
return b.ii
}
-func (b Bar) LeaksToo() *int { // ERROR "leaking param: b"
- v := 0 // ERROR "moved to heap: v"
- b.ii = &v // ERROR "&v escapes"
+func (b Bar) LeaksToo() *int { // ERROR "leaking param: b to result ~r0 level=0$"
+ v := 0 // ERROR "moved to heap: v$"
+ b.ii = &v
return b.ii
}
-func (b *Bar) LeaksABit() *int { // ERROR "b does not escape"
- v := 0 // ERROR "moved to heap: v"
- b.ii = &v // ERROR "&v escapes"
+func (b *Bar) LeaksABit() *int { // ERROR "leaking param: b to result ~r0 level=1$"
+ v := 0 // ERROR "moved to heap: v$"
+ b.ii = &v
return b.ii
}
-func (b Bar) StillNoLeak() int { // ERROR "b does not escape"
+func (b Bar) StillNoLeak() int { // ERROR "b does not escape$"
v := 0
- b.ii = &v // ERROR "&v does not escape"
+ b.ii = &v
return b.i
}
-func goLeak(b *Bar) { // ERROR "leaking param: b"
+func goLeak(b *Bar) { // ERROR "leaking param: b$"
go b.NoLeak()
}
@@ -171,90 +173,105 @@ type Bar2 struct {
}
func NewBar2() *Bar2 {
- return &Bar2{[12]int{42}, nil} // ERROR "&Bar2 literal escapes to heap"
+ return &Bar2{[12]int{42}, nil} // ERROR "&Bar2{...} escapes to heap$"
}
-func (b *Bar2) NoLeak() int { // ERROR "b does not escape"
+func (b *Bar2) NoLeak() int { // ERROR "b does not escape$"
return b.i[0]
}
-func (b *Bar2) Leak() []int { // ERROR "leaking param: b"
- return b.i[:] // ERROR "b.i escapes to heap"
+func (b *Bar2) Leak() []int { // ERROR "leaking param: b to result ~r0 level=0$"
+ return b.i[:]
}
-func (b *Bar2) AlsoNoLeak() []int { // ERROR "b does not escape"
+func (b *Bar2) AlsoNoLeak() []int { // ERROR "leaking param: b to result ~r0 level=1$"
return b.ii[0:1]
}
-func (b Bar2) AgainNoLeak() [12]int { // ERROR "b does not escape"
+func (b Bar2) AgainNoLeak() [12]int { // ERROR "b does not escape$"
return b.i
}
-func (b *Bar2) LeakSelf() { // ERROR "leaking param: b"
- b.ii = b.i[0:4] // ERROR "b.i escapes to heap"
+func (b *Bar2) LeakSelf() { // ERROR "leaking param: b$"
+ b.ii = b.i[0:4]
}
-func (b *Bar2) LeakSelf2() { // ERROR "leaking param: b"
+func (b *Bar2) LeakSelf2() { // ERROR "leaking param: b$"
var buf []int
- buf = b.i[0:] // ERROR "b.i escapes to heap"
+ buf = b.i[0:]
b.ii = buf
}
func foo21() func() int {
- x := 42 // ERROR "moved to heap: x"
- return func() int { // ERROR "func literal escapes to heap"
- return x // ERROR "&x escapes to heap"
+ x := 42
+ return func() int { // ERROR "func literal escapes to heap$"
+ return x
+ }
+}
+
+func foo21a() func() int {
+ x := 42 // ERROR "moved to heap: x$"
+ return func() int { // ERROR "func literal escapes to heap$"
+ x++
+ return x
}
}
func foo22() int {
x := 42
- return func() int { // ERROR "func literal does not escape"
+ return func() int { // ERROR "func literal does not escape$"
return x
}()
}
-func foo23(x int) func() int { // ERROR "moved to heap: x"
- return func() int { // ERROR "func literal escapes to heap"
- return x // ERROR "&x escapes to heap"
+func foo23(x int) func() int {
+ return func() int { // ERROR "func literal escapes to heap$"
+ return x
}
}
-func foo23a(x int) func() int { // ERROR "moved to heap: x"
- f := func() int { // ERROR "func literal escapes to heap"
- return x // ERROR "&x escapes to heap"
+func foo23a(x int) func() int {
+ f := func() int { // ERROR "func literal escapes to heap$"
+ return x
}
return f
}
-func foo23b(x int) *(func() int) { // ERROR "moved to heap: x"
- f := func() int { return x } // ERROR "moved to heap: f" "func literal escapes to heap" "&x escapes to heap"
- return &f // ERROR "&f escapes to heap"
+func foo23b(x int) *(func() int) {
+ f := func() int { return x } // ERROR "func literal escapes to heap$" "moved to heap: f$"
+ return &f
+}
+
+func foo23c(x int) func() int { // ERROR "moved to heap: x$"
+ return func() int { // ERROR "func literal escapes to heap$"
+ x++
+ return x
+ }
}
func foo24(x int) int {
- return func() int { // ERROR "func literal does not escape"
+ return func() int { // ERROR "func literal does not escape$"
return x
}()
}
var x *int
-func fooleak(xx *int) int { // ERROR "leaking param: xx"
+func fooleak(xx *int) int { // ERROR "leaking param: xx$"
x = xx
return *x
}
-func foonoleak(xx *int) int { // ERROR "xx does not escape"
+func foonoleak(xx *int) int { // ERROR "xx does not escape$"
return *x + *xx
}
-func foo31(x int) int { // ERROR "moved to heap: x"
- return fooleak(&x) // ERROR "&x escapes to heap"
+func foo31(x int) int { // ERROR "moved to heap: x$"
+ return fooleak(&x)
}
func foo32(x int) int {
- return foonoleak(&x) // ERROR "&x does not escape"
+ return foonoleak(&x)
}
type Foo struct {
@@ -265,114 +282,114 @@ type Foo struct {
var F Foo
var pf *Foo
-func (f *Foo) fooleak() { // ERROR "leaking param: f"
+func (f *Foo) fooleak() { // ERROR "leaking param: f$"
pf = f
}
-func (f *Foo) foonoleak() { // ERROR "f does not escape"
+func (f *Foo) foonoleak() { // ERROR "f does not escape$"
F.x = f.x
}
-func (f *Foo) Leak() { // ERROR "leaking param: f"
+func (f *Foo) Leak() { // ERROR "leaking param: f$"
f.fooleak()
}
-func (f *Foo) NoLeak() { // ERROR "f does not escape"
+func (f *Foo) NoLeak() { // ERROR "f does not escape$"
f.foonoleak()
}
-func foo41(x int) { // ERROR "moved to heap: x"
- F.xx = &x // ERROR "&x escapes to heap"
+func foo41(x int) { // ERROR "moved to heap: x$"
+ F.xx = &x
}
-func (f *Foo) foo42(x int) { // ERROR "f does not escape" "moved to heap: x"
- f.xx = &x // ERROR "&x escapes to heap"
+func (f *Foo) foo42(x int) { // ERROR "f does not escape$" "moved to heap: x$"
+ f.xx = &x
}
-func foo43(f *Foo, x int) { // ERROR "f does not escape" "moved to heap: x"
- f.xx = &x // ERROR "&x escapes to heap"
+func foo43(f *Foo, x int) { // ERROR "f does not escape$" "moved to heap: x$"
+ f.xx = &x
}
-func foo44(yy *int) { // ERROR "leaking param: yy"
+func foo44(yy *int) { // ERROR "leaking param: yy$"
F.xx = yy
}
-func (f *Foo) foo45() { // ERROR "f does not escape"
+func (f *Foo) foo45() { // ERROR "f does not escape$"
F.x = f.x
}
// See foo13 above for explanation of why f leaks.
-func (f *Foo) foo46() { // ERROR "leaking param: f"
+func (f *Foo) foo46() { // ERROR "leaking param content: f$"
F.xx = f.xx
}
-func (f *Foo) foo47() { // ERROR "leaking param: f"
- f.xx = &f.x // ERROR "&f.x escapes to heap"
+func (f *Foo) foo47() { // ERROR "leaking param: f$"
+ f.xx = &f.x
}
var ptrSlice []*int
-func foo50(i *int) { // ERROR "leaking param: i"
+func foo50(i *int) { // ERROR "leaking param: i$"
ptrSlice[0] = i
}
var ptrMap map[*int]*int
-func foo51(i *int) { // ERROR "leaking param: i"
+func foo51(i *int) { // ERROR "leaking param: i$"
ptrMap[i] = i
}
-func indaddr1(x int) *int { // ERROR "moved to heap: x"
- return &x // ERROR "&x escapes to heap"
+func indaddr1(x int) *int { // ERROR "moved to heap: x$"
+ return &x
}
-func indaddr2(x *int) *int { // ERROR "leaking param: x"
- return *&x // ERROR "&x does not escape"
+func indaddr2(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
+ return *&x
}
-func indaddr3(x *int32) *int { // ERROR "leaking param: x"
- return *(**int)(unsafe.Pointer(&x)) // ERROR "&x does not escape"
+func indaddr3(x *int32) *int { // ERROR "leaking param: x to result ~r1 level=0$"
+ return *(**int)(unsafe.Pointer(&x))
}
// From package math:
func Float32bits(f float32) uint32 {
- return *(*uint32)(unsafe.Pointer(&f)) // ERROR "&f does not escape"
+ return *(*uint32)(unsafe.Pointer(&f))
}
func Float32frombits(b uint32) float32 {
- return *(*float32)(unsafe.Pointer(&b)) // ERROR "&b does not escape"
+ return *(*float32)(unsafe.Pointer(&b))
}
func Float64bits(f float64) uint64 {
- return *(*uint64)(unsafe.Pointer(&f)) // ERROR "&f does not escape"
+ return *(*uint64)(unsafe.Pointer(&f))
}
func Float64frombits(b uint64) float64 {
- return *(*float64)(unsafe.Pointer(&b)) // ERROR "&b does not escape"
+ return *(*float64)(unsafe.Pointer(&b))
}
// contrast with
-func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: f"
- return (*uint64)(unsafe.Pointer(&f)) // ERROR "&f escapes to heap"
+func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: f$"
+ return (*uint64)(unsafe.Pointer(&f))
}
-func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f"
+func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f to result ~r1 level=0$"
return (*uint64)(unsafe.Pointer(f))
}
-func typesw(i interface{}) *int { // ERROR "leaking param: i"
+func typesw(i interface{}) *int { // ERROR "leaking param: i to result ~r1 level=0$"
switch val := i.(type) {
case *int:
return val
case *int8:
- v := int(*val) // ERROR "moved to heap: v"
- return &v // ERROR "&v escapes to heap"
+ v := int(*val) // ERROR "moved to heap: v$"
+ return &v
}
return nil
}
-func exprsw(i *int) *int { // ERROR "leaking param: i"
+func exprsw(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
switch j := i; *j + 110 {
case 12:
return j
@@ -384,20 +401,20 @@ func exprsw(i *int) *int { // ERROR "leaking param: i"
}
// assigning to an array element is like assigning to the array
-func foo60(i *int) *int { // ERROR "leaking param: i"
+func foo60(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
var a [12]*int
a[0] = i
return a[1]
}
-func foo60a(i *int) *int { // ERROR "i does not escape"
+func foo60a(i *int) *int { // ERROR "i does not escape$"
var a [12]*int
a[0] = i
return nil
}
// assigning to a struct field is like assigning to the struct
-func foo61(i *int) *int { // ERROR "leaking param: i"
+func foo61(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
type S struct {
a, b *int
}
@@ -406,7 +423,7 @@ func foo61(i *int) *int { // ERROR "leaking param: i"
return s.b
}
-func foo61a(i *int) *int { // ERROR "i does not escape"
+func foo61a(i *int) *int { // ERROR "i does not escape$"
type S struct {
a, b *int
}
@@ -418,11 +435,11 @@ func foo61a(i *int) *int { // ERROR "i does not escape"
// assigning to a struct field is like assigning to the struct but
// here this subtlety is lost, since s.a counts as an assignment to a
// track-losing dereference.
-func foo62(i *int) *int { // ERROR "leaking param: i"
+func foo62(i *int) *int { // ERROR "leaking param: i$"
type S struct {
a, b *int
}
- s := new(S) // ERROR "new[(]S[)] does not escape"
+ s := new(S) // ERROR "new\(S\) does not escape$"
s.a = i
return nil // s.b
}
@@ -431,14 +448,14 @@ type M interface {
M()
}
-func foo63(m M) { // ERROR "m does not escape"
+func foo63(m M) { // ERROR "m does not escape$"
}
-func foo64(m M) { // ERROR "leaking param: m"
+func foo64(m M) { // ERROR "leaking param: m$"
m.M()
}
-func foo64b(m M) { // ERROR "leaking param: m"
+func foo64b(m M) { // ERROR "leaking param: m$"
defer m.M()
}
@@ -448,55 +465,56 @@ func (MV) M() {}
func foo65() {
var mv MV
- foo63(&mv) // ERROR "&mv does not escape"
+ foo63(&mv)
}
func foo66() {
- var mv MV // ERROR "moved to heap: mv"
- foo64(&mv) // ERROR "&mv escapes to heap"
+ var mv MV // ERROR "moved to heap: mv$"
+ foo64(&mv)
}
func foo67() {
var mv MV
- foo63(mv)
+ foo63(mv) // ERROR "mv does not escape$"
}
func foo68() {
var mv MV
- foo64(mv) // escapes but it's an int so irrelevant
+ // escapes but it's an int so irrelevant
+ foo64(mv) // ERROR "mv escapes to heap$"
}
-func foo69(m M) { // ERROR "leaking param: m"
+func foo69(m M) { // ERROR "leaking param: m$"
foo64(m)
}
-func foo70(mv1 *MV, m M) { // ERROR "leaking param: mv1" "leaking param: m"
+func foo70(mv1 *MV, m M) { // ERROR "leaking param: m$" "leaking param: mv1$"
m = mv1
foo64(m)
}
-func foo71(x *int) []*int { // ERROR "leaking param: x"
+func foo71(x *int) []*int { // ERROR "leaking param: x$"
var y []*int
y = append(y, x)
return y
}
-func foo71a(x int) []*int { // ERROR "moved to heap: x"
+func foo71a(x int) []*int { // ERROR "moved to heap: x$"
var y []*int
- y = append(y, &x) // ERROR "&x escapes to heap"
+ y = append(y, &x)
return y
}
func foo72() {
var x int
var y [1]*int
- y[0] = &x // ERROR "&x does not escape"
+ y[0] = &x
}
func foo72aa() [10]*int {
- var x int // ERROR "moved to heap: x"
+ var x int // ERROR "moved to heap: x$"
var y [10]*int
- y[0] = &x // ERROR "&x escapes to heap"
+ y[0] = &x
return y
}
@@ -504,8 +522,8 @@ func foo72a() {
var y [10]*int
for i := 0; i < 10; i++ {
// escapes its scope
- x := i // ERROR "moved to heap: x"
- y[i] = &x // ERROR "&x escapes to heap"
+ x := i // ERROR "moved to heap: x$"
+ y[i] = &x
}
return
}
@@ -513,31 +531,56 @@ func foo72a() {
func foo72b() [10]*int {
var y [10]*int
for i := 0; i < 10; i++ {
- x := i // ERROR "moved to heap: x"
- y[i] = &x // ERROR "&x escapes to heap"
+ x := i // ERROR "moved to heap: x$"
+ y[i] = &x
}
return y
}
// issue 2145
func foo73() {
- s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
+ s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
for _, v := range s {
- vv := v // ERROR "moved to heap: vv"
+ vv := v
// actually just escapes its scope
- defer func() { // ERROR "func literal escapes to heap"
- println(vv) // ERROR "&vv escapes to heap"
+ defer func() { // ERROR "func literal escapes to heap$"
+ println(vv)
+ }()
+ }
+}
+
+func foo731() {
+ s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
+ for _, v := range s {
+ vv := v // ERROR "moved to heap: vv$"
+ // actually just escapes its scope
+ defer func() { // ERROR "func literal escapes to heap$"
+ vv = 42
+ println(vv)
}()
}
}
func foo74() {
- s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
+ s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
for _, v := range s {
- vv := v // ERROR "moved to heap: vv"
+ vv := v
// actually just escapes its scope
- fn := func() { // ERROR "func literal escapes to heap"
- println(vv) // ERROR "&vv escapes to heap"
+ fn := func() { // ERROR "func literal escapes to heap$"
+ println(vv)
+ }
+ defer fn()
+ }
+}
+
+func foo74a() {
+ s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
+ for _, v := range s {
+ vv := v // ERROR "moved to heap: vv$"
+ // actually just escapes its scope
+ fn := func() { // ERROR "func literal escapes to heap$"
+ vv += 1
+ println(vv)
}
defer fn()
}
@@ -546,110 +589,138 @@ func foo74() {
// issue 3975
func foo74b() {
var array [3]func()
- s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
+ s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
+ for i, v := range s {
+ vv := v
+ // actually just escapes its scope
+ array[i] = func() { // ERROR "func literal escapes to heap$"
+ println(vv)
+ }
+ }
+}
+
+func foo74c() {
+ var array [3]func()
+ s := []int{3, 2, 1} // ERROR "\[\]int{...} does not escape$"
for i, v := range s {
- vv := v // ERROR "moved to heap: vv"
+ vv := v // ERROR "moved to heap: vv$"
// actually just escapes its scope
- array[i] = func() { // ERROR "func literal escapes to heap"
- println(vv) // ERROR "&vv escapes to heap"
+ array[i] = func() { // ERROR "func literal escapes to heap$"
+ println(&vv)
}
}
}
-func myprint(y *int, x ...interface{}) *int { // ERROR "x does not escape" "leaking param: y"
+func myprint(y *int, x ...interface{}) *int { // ERROR "leaking param: y to result ~r2 level=0$" "x does not escape$"
return y
}
-func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "y does not escape" "leaking param: x"
- return &x[0] // ERROR "&x.0. escapes to heap"
+func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "leaking param: x to result ~r2 level=0$" "y does not escape$"
+ return &x[0]
}
-func foo75(z *int) { // ERROR "z does not escape"
- myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+func foo75(z *int) { // ERROR "z does not escape$"
+ myprint(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
}
-func foo75a(z *int) { // ERROR "z does not escape"
- myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+func foo75a(z *int) { // ERROR "z does not escape$"
+ myprint1(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
}
-func foo75esc(z *int) { // ERROR "leaking param: z"
- gxx = myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+func foo75esc(z *int) { // ERROR "leaking param: z$"
+ gxx = myprint(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
}
-func foo75aesc(z *int) { // ERROR "z does not escape"
+func foo75aesc(z *int) { // ERROR "z does not escape$"
var ppi **interface{} // assignments to pointer dereferences lose track
- *ppi = myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
+ *ppi = myprint1(z, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
+}
+
+func foo75aesc1(z *int) { // ERROR "z does not escape$"
+ sink = myprint1(z, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
}
-func foo76(z *int) { // ERROR "leaking param: z"
- myprint(nil, z) // ERROR "[.][.][.] argument does not escape"
+func foo76(z *int) { // ERROR "z does not escape"
+ myprint(nil, z) // ERROR "... argument does not escape$"
}
-func foo76a(z *int) { // ERROR "leaking param: z"
- myprint1(nil, z) // ERROR "[.][.][.] argument does not escape"
+func foo76a(z *int) { // ERROR "z does not escape"
+ myprint1(nil, z) // ERROR "... argument does not escape$"
}
func foo76b() {
- myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+ myprint(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
}
func foo76c() {
- myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+ myprint1(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
}
func foo76d() {
- defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+ defer myprint(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
}
func foo76e() {
- defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+ defer myprint1(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "... argument does not escape$"
}
func foo76f() {
for {
// TODO: This one really only escapes its scope, but we don't distinguish yet.
- defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
+ defer myprint(nil, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
}
}
func foo76g() {
for {
- defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
+ defer myprint1(nil, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
}
}
-func foo77(z []interface{}) { // ERROR "z does not escape"
+func foo77(z []interface{}) { // ERROR "z does not escape$"
myprint(nil, z...) // z does not escape
}
-func foo77a(z []interface{}) { // ERROR "z does not escape"
+func foo77a(z []interface{}) { // ERROR "z does not escape$"
myprint1(nil, z...)
}
-func foo77b(z []interface{}) { // ERROR "leaking param: z"
+func foo77b(z []interface{}) { // ERROR "leaking param: z$"
var ppi **interface{}
*ppi = myprint1(nil, z...)
}
-func foo78(z int) *int { // ERROR "moved to heap: z"
- return &z // ERROR "&z escapes to heap"
+func foo77c(z []interface{}) { // ERROR "leaking param: z$"
+ sink = myprint1(nil, z...)
+}
+
+func dotdotdot() {
+ i := 0
+ myprint(nil, &i) // ERROR "... argument does not escape$"
+
+ j := 0
+ myprint1(nil, &j) // ERROR "... argument does not escape$"
}
-func foo78a(z int) *int { // ERROR "moved to heap: z"
- y := &z // ERROR "&z escapes to heap"
- x := &y // ERROR "&y does not escape"
+func foo78(z int) *int { // ERROR "moved to heap: z$"
+ return &z
+}
+
+func foo78a(z int) *int { // ERROR "moved to heap: z$"
+ y := &z
+ x := &y
return *x // really return y
}
func foo79() *int {
- return new(int) // ERROR "new[(]int[)] escapes to heap"
+ return new(int) // ERROR "new\(int\) escapes to heap$"
}
func foo80() *int {
var z *int
for {
// Really just escapes its scope but we don't distinguish
- z = new(int) // ERROR "new[(]int[)] escapes to heap"
+ z = new(int) // ERROR "new\(int\) escapes to heap$"
}
_ = z
return nil
@@ -657,24 +728,24 @@ func foo80() *int {
func foo81() *int {
for {
- z := new(int) // ERROR "new[(]int[)] does not escape"
+ z := new(int) // ERROR "new\(int\) does not escape$"
_ = z
}
return nil
}
-func tee(p *int) (x, y *int) { return p, p } // ERROR "leaking param"
+func tee(p *int) (x, y *int) { return p, p } // ERROR "leaking param: p to result x level=0$" "leaking param: p to result y level=0$"
-func noop(x, y *int) {} // ERROR "does not escape"
+func noop(x, y *int) {} // ERROR "x does not escape$" "y does not escape$"
func foo82() {
- var x, y, z int // ERROR "moved to heap"
- go noop(tee(&z)) // ERROR "&z escapes to heap"
- go noop(&x, &y) // ERROR "escapes to heap"
+ var x, y, z int // ERROR "moved to heap: x$" "moved to heap: y$" "moved to heap: z$"
+ go noop(tee(&z))
+ go noop(&x, &y)
for {
- var u, v, w int // ERROR "moved to heap"
- defer noop(tee(&u)) // ERROR "&u escapes to heap"
- defer noop(&v, &w) // ERROR "escapes to heap"
+ var u, v, w int // ERROR "moved to heap: u$" "moved to heap: v$" "moved to heap: w$"
+ defer noop(tee(&u))
+ defer noop(&v, &w)
}
}
@@ -687,24 +758,24 @@ type LimitedFooer struct {
N int64
}
-func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r"
- return &LimitedFooer{r, n} // ERROR "&LimitedFooer literal escapes to heap"
+func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r$"
+ return &LimitedFooer{r, n} // ERROR "&LimitedFooer{...} escapes to heap$"
}
-func foo90(x *int) map[*int]*int { // ERROR "leaking param: x"
- return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap"
+func foo90(x *int) map[*int]*int { // ERROR "leaking param: x$"
+ return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
}
-func foo91(x *int) map[*int]*int { // ERROR "leaking param: x"
- return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap"
+func foo91(x *int) map[*int]*int { // ERROR "leaking param: x$"
+ return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
}
-func foo92(x *int) [2]*int { // ERROR "leaking param: x"
+func foo92(x *int) [2]*int { // ERROR "leaking param: x to result ~r1 level=0$"
return [2]*int{x, nil}
}
// does not leak c
-func foo93(c chan *int) *int { // ERROR "c does not escape"
+func foo93(c chan *int) *int { // ERROR "c does not escape$"
for v := range c {
return v
}
@@ -712,7 +783,7 @@ func foo93(c chan *int) *int { // ERROR "c does not escape"
}
// does not leak m
-func foo94(m map[*int]*int, b bool) *int { // ERROR "m does not escape"
+func foo94(m map[*int]*int, b bool) *int { // ERROR "leaking param: m to result ~r2 level=1"
for k, v := range m {
if b {
return k
@@ -723,32 +794,32 @@ func foo94(m map[*int]*int, b bool) *int { // ERROR "m does not escape"
}
// does leak x
-func foo95(m map[*int]*int, x *int) { // ERROR "m does not escape" "leaking param: x"
+func foo95(m map[*int]*int, x *int) { // ERROR "m does not escape$" "leaking param: x$"
m[x] = x
}
-// does not leak m
-func foo96(m []*int) *int { // ERROR "m does not escape"
+// does not leak m but does leak content
+func foo96(m []*int) *int { // ERROR "leaking param: m to result ~r1 level=1"
return m[0]
}
// does leak m
-func foo97(m [1]*int) *int { // ERROR "leaking param: m"
+func foo97(m [1]*int) *int { // ERROR "leaking param: m to result ~r1 level=0$"
return m[0]
}
// does not leak m
-func foo98(m map[int]*int) *int { // ERROR "m does not escape"
+func foo98(m map[int]*int) *int { // ERROR "m does not escape$"
return m[0]
}
// does leak m
-func foo99(m *[1]*int) []*int { // ERROR "leaking param: m"
+func foo99(m *[1]*int) []*int { // ERROR "leaking param: m to result ~r1 level=0$"
return m[:]
}
// does not leak m
-func foo100(m []*int) *int { // ERROR "m does not escape"
+func foo100(m []*int) *int { // ERROR "leaking param: m to result ~r1 level=1"
for _, v := range m {
return v
}
@@ -756,7 +827,7 @@ func foo100(m []*int) *int { // ERROR "m does not escape"
}
// does leak m
-func foo101(m [1]*int) *int { // ERROR "leaking param: m"
+func foo101(m [1]*int) *int { // ERROR "leaking param: m to result ~r1 level=0$"
for _, v := range m {
return v
}
@@ -764,109 +835,109 @@ func foo101(m [1]*int) *int { // ERROR "leaking param: m"
}
// does not leak m
-func foo101a(m [1]*int) *int { // ERROR "m does not escape"
- for i := range m { // ERROR "moved to heap: i"
- return &i // ERROR "&i escapes to heap"
+func foo101a(m [1]*int) *int { // ERROR "m does not escape$"
+ for i := range m { // ERROR "moved to heap: i$"
+ return &i
}
return nil
}
// does leak x
-func foo102(m []*int, x *int) { // ERROR "m does not escape" "leaking param: x"
+func foo102(m []*int, x *int) { // ERROR "m does not escape$" "leaking param: x$"
m[0] = x
}
// does not leak x
-func foo103(m [1]*int, x *int) { // ERROR "m does not escape" "x does not escape"
+func foo103(m [1]*int, x *int) { // ERROR "m does not escape$" "x does not escape$"
m[0] = x
}
var y []*int
-// does not leak x
-func foo104(x []*int) { // ERROR "x does not escape"
+// does not leak x but does leak content
+func foo104(x []*int) { // ERROR "leaking param content: x"
copy(y, x)
}
-// does not leak x
-func foo105(x []*int) { // ERROR "x does not escape"
+// does not leak x but does leak content
+func foo105(x []*int) { // ERROR "leaking param content: x"
_ = append(y, x...)
}
// does leak x
-func foo106(x *int) { // ERROR "leaking param: x"
+func foo106(x *int) { // ERROR "leaking param: x$"
_ = append(y, x)
}
-func foo107(x *int) map[*int]*int { // ERROR "leaking param: x"
- return map[*int]*int{x: nil} // ERROR "map.* literal escapes to heap"
+func foo107(x *int) map[*int]*int { // ERROR "leaking param: x$"
+ return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
}
-func foo108(x *int) map[*int]*int { // ERROR "leaking param: x"
- return map[*int]*int{nil: x} // ERROR "map.* literal escapes to heap"
+func foo108(x *int) map[*int]*int { // ERROR "leaking param: x$"
+ return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int{...} escapes to heap$"
}
-func foo109(x *int) *int { // ERROR "leaking param: x"
- m := map[*int]*int{x: nil} // ERROR "map.* literal does not escape"
+func foo109(x *int) *int { // ERROR "leaking param: x$"
+ m := map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int{...} does not escape$"
for k, _ := range m {
return k
}
return nil
}
-func foo110(x *int) *int { // ERROR "leaking param: x"
- m := map[*int]*int{nil: x} // ERROR "map.* literal does not escape"
+func foo110(x *int) *int { // ERROR "leaking param: x$"
+ m := map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int{...} does not escape$"
return m[nil]
}
-func foo111(x *int) *int { // ERROR "leaking param: x"
- m := []*int{x} // ERROR "\[\]\*int literal does not escape"
+func foo111(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0"
+ m := []*int{x} // ERROR "\[\]\*int{...} does not escape$"
return m[0]
}
-func foo112(x *int) *int { // ERROR "leaking param: x"
+func foo112(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
m := [1]*int{x}
return m[0]
}
-func foo113(x *int) *int { // ERROR "leaking param: x"
+func foo113(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
m := Bar{ii: x}
return m.ii
}
-func foo114(x *int) *int { // ERROR "leaking param: x"
- m := &Bar{ii: x} // ERROR "&Bar literal does not escape"
+func foo114(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
+ m := &Bar{ii: x} // ERROR "&Bar{...} does not escape$"
return m.ii
}
-func foo115(x *int) *int { // ERROR "leaking param: x"
+func foo115(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
return (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(x)) + 1))
}
func foo116(b bool) *int {
if b {
- x := 1 // ERROR "moved to heap: x"
- return &x // ERROR "&x escapes to heap"
+ x := 1 // ERROR "moved to heap: x$"
+ return &x
} else {
- y := 1 // ERROR "moved to heap: y"
- return &y // ERROR "&y escapes to heap"
+ y := 1 // ERROR "moved to heap: y$"
+ return &y
}
return nil
}
-func foo117(unknown func(interface{})) { // ERROR "unknown does not escape"
- x := 1 // ERROR "moved to heap: x"
- unknown(&x) // ERROR "&x escapes to heap"
+func foo117(unknown func(interface{})) { // ERROR "unknown does not escape$"
+ x := 1 // ERROR "moved to heap: x$"
+ unknown(&x)
}
-func foo118(unknown func(*int)) { // ERROR "unknown does not escape"
- x := 1 // ERROR "moved to heap: x"
- unknown(&x) // ERROR "&x escapes to heap"
+func foo118(unknown func(*int)) { // ERROR "unknown does not escape$"
+ x := 1 // ERROR "moved to heap: x$"
+ unknown(&x)
}
func external(*int)
-func foo119(x *int) { // ERROR "leaking param: x"
+func foo119(x *int) { // ERROR "leaking param: x$"
external(x)
}
@@ -1077,16 +1148,16 @@ L100:
func foo121() {
for i := 0; i < 10; i++ {
- defer myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap"
- go myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap"
+ defer myprint(nil, i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
+ go myprint(nil, i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
}
}
// same as foo121 but check across import
func foo121b() {
for i := 0; i < 10; i++ {
- defer fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap"
- go fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap"
+ defer fmt.Printf("%d", i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
+ go fmt.Printf("%d", i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
}
}
@@ -1096,7 +1167,7 @@ func foo122() {
goto L1
L1:
- i = new(int) // ERROR "new.int. does not escape"
+ i = new(int) // ERROR "new\(int\) does not escape$"
_ = i
}
@@ -1105,25 +1176,25 @@ func foo123() {
var i *int
L1:
- i = new(int) // ERROR "new.int. escapes to heap"
+ i = new(int) // ERROR "new\(int\) escapes to heap$"
goto L1
_ = i
}
-func foo124(x **int) { // ERROR "x does not escape"
- var i int // ERROR "moved to heap: i"
- p := &i // ERROR "&i escapes"
- func() { // ERROR "func literal does not escape"
- *x = p // ERROR "leaking closure reference p"
+func foo124(x **int) { // ERROR "x does not escape$"
+ var i int // ERROR "moved to heap: i$"
+ p := &i
+ func() { // ERROR "func literal does not escape$"
+ *x = p
}()
}
-func foo125(ch chan *int) { // ERROR "does not escape"
- var i int // ERROR "moved to heap"
- p := &i // ERROR "&i escapes to heap"
- func() { // ERROR "func literal does not escape"
- ch <- p // ERROR "leaking closure reference p"
+func foo125(ch chan *int) { // ERROR "ch does not escape$"
+ var i int // ERROR "moved to heap: i$"
+ p := &i
+ func() { // ERROR "func literal does not escape$"
+ ch <- p
}()
}
@@ -1131,9 +1202,9 @@ func foo126() {
var px *int // loopdepth 0
for {
// loopdepth 1
- var i int // ERROR "moved to heap"
- func() { // ERROR "func literal does not escape"
- px = &i // ERROR "&i escapes"
+ var i int // ERROR "moved to heap: i$"
+ func() { // ERROR "func literal does not escape$"
+ px = &i
}()
}
_ = px
@@ -1142,26 +1213,26 @@ func foo126() {
var px *int
func foo127() {
- var i int // ERROR "moved to heap: i"
- p := &i // ERROR "&i escapes to heap"
+ var i int // ERROR "moved to heap: i$"
+ p := &i
q := p
px = q
}
func foo128() {
var i int
- p := &i // ERROR "&i does not escape"
+ p := &i
q := p
_ = q
}
func foo129() {
- var i int // ERROR "moved to heap: i"
- p := &i // ERROR "&i escapes to heap"
- func() { // ERROR "func literal does not escape"
- q := p // ERROR "leaking closure reference p"
- func() { // ERROR "func literal does not escape"
- r := q // ERROR "leaking closure reference q"
+ var i int // ERROR "moved to heap: i$"
+ p := &i
+ func() { // ERROR "func literal does not escape$"
+ q := p
+ func() { // ERROR "func literal does not escape$"
+ r := q
px = r
}()
}()
@@ -1169,40 +1240,40 @@ func foo129() {
func foo130() {
for {
- var i int // ERROR "moved to heap"
- func() { // ERROR "func literal does not escape"
- px = &i // ERROR "&i escapes" "leaking closure reference i"
+ var i int // ERROR "moved to heap: i$"
+ func() { // ERROR "func literal does not escape$"
+ px = &i
}()
}
}
func foo131() {
- var i int // ERROR "moved to heap"
- func() { // ERROR "func literal does not escape"
- px = &i // ERROR "&i escapes" "leaking closure reference i"
+ var i int // ERROR "moved to heap: i$"
+ func() { // ERROR "func literal does not escape$"
+ px = &i
}()
}
func foo132() {
- var i int // ERROR "moved to heap"
- go func() { // ERROR "func literal escapes to heap"
- px = &i // ERROR "&i escapes" "leaking closure reference i"
+ var i int // ERROR "moved to heap: i$"
+ go func() { // ERROR "func literal escapes to heap$"
+ px = &i
}()
}
func foo133() {
- var i int // ERROR "moved to heap"
- defer func() { // ERROR "func literal does not escape"
- px = &i // ERROR "&i escapes" "leaking closure reference i"
+ var i int // ERROR "moved to heap: i$"
+ defer func() { // ERROR "func literal does not escape$"
+ px = &i
}()
}
func foo134() {
var i int
- p := &i // ERROR "&i does not escape"
- func() { // ERROR "func literal does not escape"
+ p := &i
+ func() { // ERROR "func literal does not escape$"
q := p
- func() { // ERROR "func literal does not escape"
+ func() { // ERROR "func literal does not escape$"
r := q
_ = r
}()
@@ -1210,11 +1281,11 @@ func foo134() {
}
func foo135() {
- var i int // ERROR "moved to heap: i"
- p := &i // ERROR "&i escapes to heap" "moved to heap: p"
- go func() { // ERROR "func literal escapes to heap"
- q := p // ERROR "&p escapes to heap"
- func() { // ERROR "func literal does not escape"
+ var i int // ERROR "moved to heap: i$"
+ p := &i
+ go func() { // ERROR "func literal escapes to heap$"
+ q := p
+ func() { // ERROR "func literal does not escape$"
r := q
_ = r
}()
@@ -1222,24 +1293,24 @@ func foo135() {
}
func foo136() {
- var i int // ERROR "moved to heap: i"
- p := &i // ERROR "&i escapes to heap" "moved to heap: p"
- go func() { // ERROR "func literal escapes to heap"
- q := p // ERROR "&p escapes to heap" "leaking closure reference p"
- func() { // ERROR "func literal does not escape"
- r := q // ERROR "leaking closure reference q"
+ var i int // ERROR "moved to heap: i$"
+ p := &i
+ go func() { // ERROR "func literal escapes to heap$"
+ q := p
+ func() { // ERROR "func literal does not escape$"
+ r := q
px = r
}()
}()
}
func foo137() {
- var i int // ERROR "moved to heap: i"
- p := &i // ERROR "&i escapes to heap"
- func() { // ERROR "func literal does not escape"
- q := p // ERROR "leaking closure reference p" "moved to heap: q"
- go func() { // ERROR "func literal escapes to heap"
- r := q // ERROR "&q escapes to heap"
+ var i int // ERROR "moved to heap: i$"
+ p := &i
+ func() { // ERROR "func literal does not escape$"
+ q := p
+ go func() { // ERROR "func literal escapes to heap$"
+ r := q
_ = r
}()
}()
@@ -1249,8 +1320,8 @@ func foo138() *byte {
type T struct {
x [1]byte
}
- t := new(T) // ERROR "new.T. escapes to heap"
- return &t.x[0] // ERROR "&t.x.0. escapes to heap"
+ t := new(T) // ERROR "new\(T\) escapes to heap$"
+ return &t.x[0]
}
func foo139() *byte {
@@ -1259,8 +1330,8 @@ func foo139() *byte {
y byte
}
}
- t := new(T) // ERROR "new.T. escapes to heap"
- return &t.x.y // ERROR "&t.x.y escapes to heap"
+ t := new(T) // ERROR "new\(T\) escapes to heap$"
+ return &t.x.y
}
// issue 4751
@@ -1272,8 +1343,8 @@ func foo140() interface{} {
X string
T *T
}
- t := &T{} // ERROR "&T literal escapes to heap"
- return U{
+ t := &T{} // ERROR "&T{} escapes to heap$"
+ return U{ // ERROR "U{...} escapes to heap$"
X: t.X,
T: t,
}
@@ -1287,53 +1358,53 @@ func F2([]byte)
//go:noescape
-func F3(x []byte) // ERROR "F3 x does not escape"
+func F3(x []byte) // ERROR "x does not escape$"
-func F4(x []byte)
+func F4(x []byte) // ERROR "leaking param: x$"
func G() {
var buf1 [10]byte
- F1(buf1[:]) // ERROR "buf1 does not escape"
-
- var buf2 [10]byte // ERROR "moved to heap: buf2"
- F2(buf2[:]) // ERROR "buf2 escapes to heap"
+ F1(buf1[:])
+
+ var buf2 [10]byte // ERROR "moved to heap: buf2$"
+ F2(buf2[:])
var buf3 [10]byte
- F3(buf3[:]) // ERROR "buf3 does not escape"
-
- var buf4 [10]byte // ERROR "moved to heap: buf4"
- F4(buf4[:]) // ERROR "buf4 escapes to heap"
+ F3(buf3[:])
+
+ var buf4 [10]byte // ERROR "moved to heap: buf4$"
+ F4(buf4[:])
}
type Tm struct {
x int
}
-func (t *Tm) M() { // ERROR "t does not escape"
+func (t *Tm) M() { // ERROR "t does not escape$"
}
func foo141() {
var f func()
-
- t := new(Tm) // ERROR "escapes to heap"
- f = t.M // ERROR "t.M does not escape"
+
+ t := new(Tm) // ERROR "new\(Tm\) does not escape$"
+ f = t.M // ERROR "t.M does not escape$"
_ = f
}
var gf func()
func foo142() {
- t := new(Tm) // ERROR "escapes to heap"
- gf = t.M // ERROR "t.M escapes to heap"
+ t := new(Tm) // ERROR "new\(Tm\) escapes to heap$"
+ gf = t.M // ERROR "t.M escapes to heap$"
}
// issue 3888.
func foo143() {
for i := 0; i < 1000; i++ {
- func() { // ERROR "func literal does not escape"
+ func() { // ERROR "func literal does not escape$"
for i := 0; i < 1; i++ {
var t Tm
- t.M() // ERROR "t does not escape"
+ t.M()
}
}()
}
@@ -1349,11 +1420,427 @@ func foo144a(*int)
func foo144() {
var x int
- foo144a(&x) // ERROR "&x does not escape"
+ foo144a(&x)
var y int
- foo144b(&y) // ERROR "&y does not escape"
+ foo144b(&y)
}
//go:noescape
func foo144b(*int)
+
+// issue 7313: for loop init should not be treated as "in loop"
+
+type List struct {
+ Next *List
+}
+
+func foo145(l List) { // ERROR "l does not escape$"
+ var p *List
+ for p = &l; p.Next != nil; p = p.Next {
+ }
+}
+
+func foo146(l List) { // ERROR "l does not escape$"
+ var p *List
+ p = &l
+ for ; p.Next != nil; p = p.Next {
+ }
+}
+
+func foo147(l List) { // ERROR "l does not escape$"
+ var p *List
+ p = &l
+ for p.Next != nil {
+ p = p.Next
+ }
+}
+
+func foo148(l List) { // ERROR "l does not escape$"
+ for p := &l; p.Next != nil; p = p.Next {
+ }
+}
+
+// related: address of variable should have depth of variable, not of loop
+
+func foo149(l List) { // ERROR "l does not escape$"
+ var p *List
+ for {
+ for p = &l; p.Next != nil; p = p.Next {
+ }
+ }
+}
+
+// issue 7934: missed ... if element type had no pointers
+
+var save150 []byte
+
+func foo150(x ...byte) { // ERROR "leaking param: x$"
+ save150 = x
+}
+
+func bar150() {
+ foo150(1, 2, 3) // ERROR "... argument escapes to heap$"
+}
+
+// issue 7931: bad handling of slice of array
+
+var save151 *int
+
+func foo151(x *int) { // ERROR "leaking param: x$"
+ save151 = x
+}
+
+func bar151() {
+ var a [64]int // ERROR "moved to heap: a$"
+ a[4] = 101
+ foo151(&(&a)[4:8][0])
+}
+
+func bar151b() {
+ var a [10]int // ERROR "moved to heap: a$"
+ b := a[:]
+ foo151(&b[4:8][0])
+}
+
+func bar151c() {
+ var a [64]int // ERROR "moved to heap: a$"
+ a[4] = 101
+ foo151(&(&a)[4:8:8][0])
+}
+
+func bar151d() {
+ var a [10]int // ERROR "moved to heap: a$"
+ b := a[:]
+ foo151(&b[4:8:8][0])
+}
+
+// issue 8120
+
+type U struct {
+ s *string
+}
+
+func (u *U) String() *string { // ERROR "leaking param: u to result ~r0 level=1$"
+ return u.s
+}
+
+type V struct {
+ s *string
+}
+
+func NewV(u U) *V { // ERROR "leaking param: u$"
+ return &V{u.String()} // ERROR "&V{...} escapes to heap$"
+}
+
+func foo152() {
+ a := "a" // ERROR "moved to heap: a$"
+ u := U{&a}
+ v := NewV(u)
+ println(v)
+}
+
+// issue 8176 - &x in type switch body not marked as escaping
+
+func foo153(v interface{}) *int { // ERROR "v does not escape"
+ switch x := v.(type) {
+ case int: // ERROR "moved to heap: x$"
+ return &x
+ }
+ panic(0)
+}
+
+// issue 8185 - &result escaping into result
+
+func f() (x int, y *int) { // ERROR "moved to heap: x$"
+ y = &x
+ return
+}
+
+func g() (x interface{}) { // ERROR "moved to heap: x$"
+ x = &x
+ return
+}
+
+var sink interface{}
+
+type Lit struct {
+ p *int
+}
+
+func ptrlitNoescape() {
+ // Both literal and element do not escape.
+ i := 0
+ x := &Lit{&i} // ERROR "&Lit{...} does not escape$"
+ _ = x
+}
+
+func ptrlitNoEscape2() {
+ // Literal does not escape, but element does.
+ i := 0 // ERROR "moved to heap: i$"
+ x := &Lit{&i} // ERROR "&Lit{...} does not escape$"
+ sink = *x
+}
+
+func ptrlitEscape() {
+ // Both literal and element escape.
+ i := 0 // ERROR "moved to heap: i$"
+ x := &Lit{&i} // ERROR "&Lit{...} escapes to heap$"
+ sink = x
+}
+
+// self-assignments
+
+type Buffer struct {
+ arr [64]byte
+ arrPtr *[64]byte
+ buf1 []byte
+ buf2 []byte
+ str1 string
+ str2 string
+}
+
+func (b *Buffer) foo() { // ERROR "b does not escape$"
+ b.buf1 = b.buf1[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf1\[1:2\]$"
+ b.buf1 = b.buf1[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf1\[1:2:3\]$"
+ b.buf1 = b.buf2[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf2\[1:2\]$"
+ b.buf1 = b.buf2[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment in b.buf1 = b.buf2\[1:2:3\]$"
+}
+
+func (b *Buffer) bar() { // ERROR "leaking param: b$"
+ b.buf1 = b.arr[1:2]
+}
+
+func (b *Buffer) arrayPtr() { // ERROR "b does not escape"
+ b.buf1 = b.arrPtr[1:2] // ERROR "\(\*Buffer\).arrayPtr ignoring self-assignment in b.buf1 = b.arrPtr\[1:2\]$"
+ b.buf1 = b.arrPtr[1:2:3] // ERROR "\(\*Buffer\).arrayPtr ignoring self-assignment in b.buf1 = b.arrPtr\[1:2:3\]$"
+}
+
+func (b *Buffer) baz() { // ERROR "b does not escape$"
+ b.str1 = b.str1[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment in b.str1 = b.str1\[1:2\]$"
+ b.str1 = b.str2[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment in b.str1 = b.str2\[1:2\]$"
+}
+
+func (b *Buffer) bat() { // ERROR "leaking param content: b$"
+ o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap$"
+ o.buf1 = b.buf1[1:2]
+ sink = o
+}
+
+func quux(sp *string, bp *[]byte) { // ERROR "bp does not escape$" "sp does not escape$"
+ *sp = (*sp)[1:2] // ERROR "quux ignoring self-assignment in \*sp = \(\*sp\)\[1:2\]$"
+ *bp = (*bp)[1:2] // ERROR "quux ignoring self-assignment in \*bp = \(\*bp\)\[1:2\]$"
+}
+
+type StructWithString struct {
+ p *int
+ s string
+}
+
+// This is escape analysis false negative.
+// We assign the pointer to x.p but leak x.s. Escape analysis coarsens flows
+// to just x, and thus &i looks escaping.
+func fieldFlowTracking() {
+ var x StructWithString
+ i := 0 // ERROR "moved to heap: i$"
+ x.p = &i
+ sink = x.s // ERROR "x.s escapes to heap$"
+}
+
+// String operations.
+
+func slicebytetostring0() {
+ b := make([]byte, 20) // ERROR "make\(\[\]byte, 20\) does not escape$"
+ s := string(b) // ERROR "string\(b\) does not escape$"
+ _ = s
+}
+
+func slicebytetostring1() {
+ b := make([]byte, 20) // ERROR "make\(\[\]byte, 20\) does not escape$"
+ s := string(b) // ERROR "string\(b\) does not escape$"
+ s1 := s[0:1]
+ _ = s1
+}
+
+func slicebytetostring2() {
+ b := make([]byte, 20) // ERROR "make\(\[\]byte, 20\) does not escape$"
+ s := string(b) // ERROR "string\(b\) escapes to heap$"
+ s1 := s[0:1] // ERROR "moved to heap: s1$"
+ sink = &s1
+}
+
+func slicebytetostring3() {
+ b := make([]byte, 20) // ERROR "make\(\[\]byte, 20\) does not escape$"
+ s := string(b) // ERROR "string\(b\) escapes to heap$"
+ s1 := s[0:1]
+ sink = s1 // ERROR "s1 escapes to heap$"
+}
+
+func addstr0() {
+ s0 := "a"
+ s1 := "b"
+ s := s0 + s1 // ERROR "s0 \+ s1 does not escape$"
+ _ = s
+}
+
+func addstr1() {
+ s0 := "a"
+ s1 := "b"
+ s := "c"
+ s += s0 + s1 // ERROR "s0 \+ s1 does not escape$"
+ _ = s
+}
+
+func addstr2() {
+ b := make([]byte, 20) // ERROR "make\(\[\]byte, 20\) does not escape$"
+ s0 := "a"
+ s := string(b) + s0 // ERROR "string\(b\) \+ s0 does not escape$" "string\(b\) does not escape$"
+ _ = s
+}
+
+func addstr3() {
+ s0 := "a"
+ s1 := "b"
+ s := s0 + s1 // ERROR "s0 \+ s1 escapes to heap$"
+ s2 := s[0:1]
+ sink = s2 // ERROR "s2 escapes to heap$"
+}
+
+func intstring0() bool {
+ // string does not escape
+ x := '0'
+ s := string(x) // ERROR "string\(x\) does not escape$"
+ return s == "0"
+}
+
+func intstring1() string {
+ // string does not escape, but the buffer does
+ x := '0'
+ s := string(x) // ERROR "string\(x\) escapes to heap$"
+ return s
+}
+
+func intstring2() {
+ // string escapes to heap
+ x := '0'
+ s := string(x) // ERROR "moved to heap: s$" "string\(x\) escapes to heap$"
+ sink = &s
+}
+
+func stringtoslicebyte0() {
+ s := "foo"
+ x := []byte(s) // ERROR "\(\[\]byte\)\(s\) does not escape$"
+ _ = x
+}
+
+func stringtoslicebyte1() []byte {
+ s := "foo"
+ return []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$"
+}
+
+func stringtoslicebyte2() {
+ s := "foo"
+ sink = []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$"
+}
+
+func stringtoslicerune0() {
+ s := "foo"
+ x := []rune(s) // ERROR "\(\[\]rune\)\(s\) does not escape$"
+ _ = x
+}
+
+func stringtoslicerune1() []rune {
+ s := "foo"
+ return []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$"
+}
+
+func stringtoslicerune2() {
+ s := "foo"
+ sink = []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$"
+}
+
+func slicerunetostring0() {
+ r := []rune{1, 2, 3} // ERROR "\[\]rune{...} does not escape$"
+ s := string(r) // ERROR "string\(r\) does not escape$"
+ _ = s
+}
+
+func slicerunetostring1() string {
+ r := []rune{1, 2, 3} // ERROR "\[\]rune{...} does not escape$"
+ return string(r) // ERROR "string\(r\) escapes to heap$"
+}
+
+func slicerunetostring2() {
+ r := []rune{1, 2, 3} // ERROR "\[\]rune{...} does not escape$"
+ sink = string(r) // ERROR "string\(r\) escapes to heap$"
+}
+
+func makemap0() {
+ m := make(map[int]int) // ERROR "make\(map\[int\]int\) does not escape$"
+ m[0] = 0
+ m[1]++
+ delete(m, 1)
+ sink = m[0] // ERROR "m\[0\] escapes to heap$"
+}
+
+func makemap1() map[int]int {
+ return make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$"
+}
+
+func makemap2() {
+ m := make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$"
+ sink = m
+}
+
+func nonescapingEface(m map[interface{}]bool) bool { // ERROR "m does not escape$"
+ return m["foo"] // ERROR ".foo. does not escape$"
+}
+
+func nonescapingIface(m map[M]bool) bool { // ERROR "m does not escape$"
+ return m[MV(0)] // ERROR "MV\(0\) does not escape$"
+}
+
+func issue10353() {
+ x := new(int) // ERROR "new\(int\) escapes to heap$"
+ issue10353a(x)()
+}
+
+func issue10353a(x *int) func() { // ERROR "leaking param: x$"
+ return func() { // ERROR "func literal escapes to heap$"
+ println(*x)
+ }
+}
+
+func issue10353b() {
+ var f func()
+ for {
+ x := new(int) // ERROR "new\(int\) escapes to heap$"
+ f = func() { // ERROR "func literal escapes to heap$"
+ println(*x)
+ }
+ }
+ _ = f
+}
+
+func issue11387(x int) func() int {
+ f := func() int { return x } // ERROR "func literal escapes to heap"
+ slice1 := []func() int{f} // ERROR "\[\].* does not escape"
+ slice2 := make([]func() int, 1) // ERROR "make\(.*\) does not escape"
+ copy(slice2, slice1)
+ return slice2[0]
+}
+
+func issue12397(x, y int) { // ERROR "moved to heap: y$"
+ // x does not escape below, because all relevant code is dead.
+ if false {
+ gxx = &x
+ } else {
+ gxx = &y
+ }
+
+ if true {
+ gxx = &y
+ } else {
+ gxx = &x
+ }
+}
diff --git a/gcc/testsuite/go.test/test/escape3.go b/gcc/testsuite/go.test/test/escape3.go
index 4c19891..f1131a2 100644
--- a/gcc/testsuite/go.test/test/escape3.go
+++ b/gcc/testsuite/go.test/test/escape3.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/escape4.go b/gcc/testsuite/go.test/test/escape4.go
index 83bc8eb..a4a9c14 100644
--- a/gcc/testsuite/go.test/test/escape4.go
+++ b/gcc/testsuite/go.test/test/escape4.go
@@ -1,6 +1,6 @@
// errorcheck -0 -m
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -12,38 +12,38 @@ package foo
var p *int
func alloc(x int) *int { // ERROR "can inline alloc" "moved to heap: x"
- return &x // ERROR "&x escapes to heap"
+ return &x
}
var f func()
func f1() {
- p = alloc(2) // ERROR "inlining call to alloc" "&x escapes to heap" "moved to heap: x"
+ p = alloc(2) // ERROR "inlining call to alloc" "moved to heap: x"
// Escape analysis used to miss inlined code in closures.
- func() { // ERROR "func literal does not escape"
- p = alloc(3) // ERROR "inlining call to alloc" "&x escapes to heap" "moved to heap: x"
- }()
+ func() { // ERROR "can inline f1.func1"
+ p = alloc(3) // ERROR "inlining call to alloc"
+ }() // ERROR "inlining call to f1.func1" "inlining call to alloc" "moved to heap: x"
- f = func() { // ERROR "func literal escapes to heap"
- p = alloc(3) // ERROR "inlining call to alloc" "&x escapes to heap" "moved to heap: x"
+ f = func() { // ERROR "func literal escapes to heap" "can inline f1.func2"
+ p = alloc(3) // ERROR "inlining call to alloc" "moved to heap: x"
}
f()
}
func f2() {} // ERROR "can inline f2"
-// No inline for panic, recover.
-func f3() { panic(1) }
+// No inline for recover; panic now allowed to inline.
+func f3() { panic(1) } // ERROR "can inline f3"
func f4() { recover() }
func f5() *byte {
type T struct {
x [1]byte
}
- t := new(T) // ERROR "new.T. escapes to heap"
- return &t.x[0] // ERROR "&t.x.0. escapes to heap"
+ t := new(T) // ERROR "new.T. escapes to heap"
+ return &t.x[0]
}
func f6() *byte {
@@ -52,6 +52,6 @@ func f6() *byte {
y byte
}
}
- t := new(T) // ERROR "new.T. escapes to heap"
- return &t.x.y // ERROR "&t.x.y escapes to heap"
+ t := new(T) // ERROR "new.T. escapes to heap"
+ return &t.x.y
}
diff --git a/gcc/testsuite/go.test/test/escape5.go b/gcc/testsuite/go.test/test/escape5.go
index c964687..2ed2023 100644
--- a/gcc/testsuite/go.test/test/escape5.go
+++ b/gcc/testsuite/go.test/test/escape5.go
@@ -1,6 +1,6 @@
// errorcheck -0 -m -l
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
@@ -9,6 +9,11 @@
package foo
+import (
+ "runtime"
+ "unsafe"
+)
+
func noleak(p *int) int { // ERROR "p does not escape"
return *p
}
@@ -17,19 +22,19 @@ func leaktoret(p *int) *int { // ERROR "leaking param: p to result"
return p
}
-func leaktoret2(p *int) (*int, *int) { // ERROR "leaking param: p to result .anon1" "leaking param: p to result .anon2"
+func leaktoret2(p *int) (*int, *int) { // ERROR "leaking param: p to result ~r1" "leaking param: p to result ~r2"
return p, p
}
-func leaktoret22(p, q *int) (*int, *int) { // ERROR "leaking param: p to result .anon2" "leaking param: q to result .anon3"
+func leaktoret22(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r2" "leaking param: q to result ~r3"
return p, q
}
-func leaktoret22b(p, q *int) (*int, *int) { // ERROR "leaking param: p to result .anon3" "leaking param: q to result .anon2"
+func leaktoret22b(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r3" "leaking param: q to result ~r2"
return leaktoret22(q, p)
}
-func leaktoret22c(p, q *int) (*int, *int) { // ERROR "leaking param: p to result .anon3" "leaking param: q to result .anon2"
+func leaktoret22c(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r3" "leaking param: q to result ~r2"
r, s := leaktoret22(q, p)
return r, s
}
@@ -58,37 +63,37 @@ func leaktosink(p *int) *int { // ERROR "leaking param: p"
func f1() {
var x int
- p := noleak(&x) // ERROR "&x does not escape"
+ p := noleak(&x)
_ = p
}
func f2() {
var x int
- p := leaktoret(&x) // ERROR "&x does not escape"
+ p := leaktoret(&x)
_ = p
}
func f3() {
- var x int // ERROR "moved to heap: x"
- p := leaktoret(&x) // ERROR "&x escapes to heap"
+ var x int // ERROR "moved to heap: x"
+ p := leaktoret(&x)
gp = p
}
func f4() {
- var x int // ERROR "moved to heap: x"
- p, q := leaktoret2(&x) // ERROR "&x escapes to heap"
+ var x int // ERROR "moved to heap: x"
+ p, q := leaktoret2(&x)
gp = p
gp = q
}
func f5() {
var x int
- leaktoret22(leaktoret2(&x)) // ERROR "&x does not escape"
+ leaktoret22(leaktoret2(&x))
}
func f6() {
- var x int // ERROR "moved to heap: x"
- px1, px2 := leaktoret22(leaktoret2(&x)) // ERROR "&x escapes to heap"
+ var x int // ERROR "moved to heap: x"
+ px1, px2 := leaktoret22(leaktoret2(&x))
gp = px1
_ = px2
}
@@ -117,7 +122,6 @@ func leakrecursive2(p, q *int) (*int, *int) { // ERROR "leaking param: p" "leaki
return p, q
}
-
var global interface{}
type T1 struct {
@@ -128,24 +132,140 @@ type T2 struct {
Y *T1
}
-func f8(p *T1) (k T2) { // ERROR "leaking param: p to result k" "leaking param: p"
+func f8(p *T1) (k T2) { // ERROR "leaking param: p$"
if p == nil {
k = T2{}
return
}
- global = p // should make p leak always
+ // should make p leak always
+ global = p
return T2{p}
}
func f9() {
var j T1 // ERROR "moved to heap: j"
- f8(&j) // ERROR "&j escapes to heap"
+ f8(&j)
}
func f10() {
// These don't escape but are too big for the stack
- var x [1<<30]byte // ERROR "moved to heap: x"
- var y = make([]byte, 1<<30) // ERROR "does not escape"
+ var x [1 << 30]byte // ERROR "moved to heap: x"
+ var y = make([]byte, 1<<30) // ERROR "make\(\[\]byte, 1 << 30\) escapes to heap"
_ = x[0] + y[0]
}
+
+// Test for issue 19687 (passing to unnamed parameters does not escape).
+func f11(**int) {
+}
+func f12(_ **int) {
+}
+func f13() {
+ var x *int
+ f11(&x)
+ f12(&x)
+ runtime.KeepAlive(&x)
+}
+
+// Test for issue 24305 (passing to unnamed receivers does not escape).
+type U int
+
+func (*U) M() {}
+func (_ *U) N() {}
+
+func _() {
+ var u U
+ u.M()
+ u.N()
+}
+
+func fbad24305() {
+ // BAD u should not be heap allocated
+ var u U // ERROR "moved to heap: u"
+ (*U).M(&u)
+ (*U).N(&u)
+}
+
+// Issue 24730: taking address in a loop causes unnecessary escape
+type T24730 struct {
+ x [64]byte
+}
+
+func (t *T24730) g() { // ERROR "t does not escape"
+ y := t.x[:]
+ for i := range t.x[:] {
+ y = t.x[:]
+ y[i] = 1
+ }
+
+ var z *byte
+ for i := range t.x[:] {
+ z = &t.x[i]
+ *z = 2
+ }
+}
+
+// Issue 15730: copy causes unnecessary escape
+
+var sink []byte
+var sink2 []int
+var sink3 []*int
+
+func f15730a(args ...interface{}) { // ERROR "args does not escape"
+ for _, arg := range args {
+ switch a := arg.(type) {
+ case string:
+ copy(sink, a)
+ }
+ }
+}
+
+func f15730b(args ...interface{}) { // ERROR "args does not escape"
+ for _, arg := range args {
+ switch a := arg.(type) {
+ case []int:
+ copy(sink2, a)
+ }
+ }
+}
+
+func f15730c(args ...interface{}) { // ERROR "leaking param content: args"
+ for _, arg := range args {
+ switch a := arg.(type) {
+ case []*int:
+ // copy pointerful data should cause escape
+ copy(sink3, a)
+ }
+ }
+}
+
+// Issue 29000: unnamed parameter is not handled correctly
+
+var sink4 interface{}
+var alwaysFalse = false
+
+func f29000(_ int, x interface{}) { // ERROR "leaking param: x"
+ sink4 = x
+ if alwaysFalse {
+ g29000()
+ }
+}
+
+func g29000() {
+ x := 1
+ f29000(2, x) // ERROR "x escapes to heap"
+}
+
+// Issue 28369: taking an address of a parameter and converting it into a uintptr causes an
+// unnecessary escape.
+
+var sink28369 uintptr
+
+func f28369(n int) int {
+ if n == 0 {
+ sink28369 = uintptr(unsafe.Pointer(&n))
+ return n
+ }
+
+ return 1 + f28369(n-1)
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug083.dir/bug0.go b/gcc/testsuite/go.test/test/fixedbugs/bug083.dir/bug0.go
index e312256..2f59d81 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug083.dir/bug0.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug083.dir/bug0.go
@@ -1,4 +1,4 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug083.dir/bug1.go b/gcc/testsuite/go.test/test/fixedbugs/bug083.dir/bug1.go
index 486fe76..ea5bcfe 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug083.dir/bug1.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug083.dir/bug1.go
@@ -1,4 +1,4 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug088.dir/bug0.go b/gcc/testsuite/go.test/test/fixedbugs/bug088.dir/bug0.go
index af9d991..7a6e347 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug088.dir/bug0.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug088.dir/bug0.go
@@ -1,4 +1,4 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug088.dir/bug1.go b/gcc/testsuite/go.test/test/fixedbugs/bug088.dir/bug1.go
index cadf0e6..2568e37 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug088.dir/bug1.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug088.dir/bug1.go
@@ -1,4 +1,4 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug106.dir/bug0.go b/gcc/testsuite/go.test/test/fixedbugs/bug106.dir/bug0.go
index d9c26a0..7494c58 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug106.dir/bug0.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug106.dir/bug0.go
@@ -1,4 +1,4 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug106.dir/bug1.go b/gcc/testsuite/go.test/test/fixedbugs/bug106.dir/bug1.go
index 0f1d20e..eff0d36 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug106.dir/bug1.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug106.dir/bug1.go
@@ -1,4 +1,4 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug108.go b/gcc/testsuite/go.test/test/fixedbugs/bug108.go
index 9f2a27e..cfec4c9 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug108.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug108.go
@@ -6,6 +6,6 @@
package main
func f() {
- v := 1 << 1025; // ERROR "overflow|stupid shift"
+ v := 1 << 1025; // ERROR "overflow|shift count too large"
_ = v
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug121.go b/gcc/testsuite/go.test/test/fixedbugs/bug121.go
index 5adf982..22c7181 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug121.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug121.go
@@ -15,4 +15,3 @@ type I interface {
type J interface {
h T; // ERROR "syntax|signature"
}
-
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug133.dir/bug0.go b/gcc/testsuite/go.test/test/fixedbugs/bug133.dir/bug0.go
index 48cd104..19a2bfb 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug133.dir/bug0.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug133.dir/bug0.go
@@ -1,4 +1,4 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug133.dir/bug1.go b/gcc/testsuite/go.test/test/fixedbugs/bug133.dir/bug1.go
index 7562147..dd59b2f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug133.dir/bug1.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug133.dir/bug1.go
@@ -1,4 +1,4 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug133.dir/bug2.go b/gcc/testsuite/go.test/test/fixedbugs/bug133.dir/bug2.go
index e531001..b6184c2 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug133.dir/bug2.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug133.dir/bug2.go
@@ -1,4 +1,4 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug1515.go b/gcc/testsuite/go.test/test/fixedbugs/bug1515.go
index a4baccd..5fef5ad 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug1515.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug1515.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug160.dir/x.go b/gcc/testsuite/go.test/test/fixedbugs/bug160.dir/x.go
index bd52c6c..2673552 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug160.dir/x.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug160.dir/x.go
@@ -1,4 +1,4 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug160.dir/y.go b/gcc/testsuite/go.test/test/fixedbugs/bug160.dir/y.go
index 27e2f35..428808d 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug160.dir/y.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug160.dir/y.go
@@ -1,4 +1,4 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug169.go b/gcc/testsuite/go.test/test/fixedbugs/bug169.go
index f63c2f3..62ab7c2 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug169.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug169.go
@@ -5,6 +5,6 @@
// license that can be found in the LICENSE file.
package main
-var x = '''; // ERROR "char"
+var x = '''; // ERROR "char|rune"
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug173.go b/gcc/testsuite/go.test/test/fixedbugs/bug173.go
index 6479bb2..3515c64 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug173.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug173.go
@@ -18,4 +18,6 @@ func main() {
}
for _ = range t {
}
+ for range t {
+ }
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug176.go b/gcc/testsuite/go.test/test/fixedbugs/bug176.go
index 82f8dba..7001dd0 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug176.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug176.go
@@ -9,6 +9,6 @@ package main
var x int
var a = []int{ x: 1} // ERROR "constant"
-var b = [...]int{ x : 1} // ERROR "constant"
+var b = [...]int{x: 1} // GCCGO_ERROR "constant"
var c = map[int]int{ x: 1}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug195.go b/gcc/testsuite/go.test/test/fixedbugs/bug195.go
index 85367cb..aef7bd2 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug195.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug195.go
@@ -6,22 +6,22 @@
package main
-type I1 interface { I2 } // ERROR "interface"
+type I1 interface{ I2 } // ERROR "interface"
type I2 int
-type I3 interface { int } // ERROR "interface"
+type I3 interface{ int } // ERROR "interface"
type S struct {
- x interface{ S } // ERROR "interface"
+ x interface{ S } // ERROR "interface"
}
-type I4 interface {
- I4 // ERROR "interface"
+type I4 interface { // GC_ERROR "invalid recursive type I4\n\tLINE: I4 refers to\n\tLINE: I4$"
+ I4 // GCCGO_ERROR "interface"
}
-type I5 interface {
- I6 // GCCGO_ERROR "interface"
+type I5 interface { // GC_ERROR "invalid recursive type I5\n\tLINE: I5 refers to\n\tLINE+4: I6 refers to\n\tLINE: I5$"
+ I6 // GCCGO_ERROR "interface"
}
type I6 interface {
- I5 // ERROR "interface"
+ I5 // GCCGO_ERROR "interface"
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug203.go b/gcc/testsuite/go.test/test/fixedbugs/bug203.go
index 2fb084b..68647ec 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug203.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug203.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug206.go b/gcc/testsuite/go.test/test/fixedbugs/bug206.go
index c2382ac..91efa3f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug206.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug206.go
@@ -1,4 +1,4 @@
-// cmpout
+// run
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug214.go b/gcc/testsuite/go.test/test/fixedbugs/bug214.go
index 5420058..f3c25e7 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug214.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug214.go
@@ -5,7 +5,7 @@
// license that can be found in the LICENSE file.
// Used to crash the compiler.
-// http://code.google.com/p/go/issues/detail?id=88
+// https://golang.org/issue/88
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug215.go b/gcc/testsuite/go.test/test/fixedbugs/bug215.go
index 08ed662..b27cc7d 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug215.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug215.go
@@ -5,7 +5,7 @@
// license that can be found in the LICENSE file.
// Used to crash the compiler.
-// http://code.google.com/p/go/issues/detail?id=158
+// https://golang.org/issue/158
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug216.go b/gcc/testsuite/go.test/test/fixedbugs/bug216.go
index c83a522..470369a 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug216.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug216.go
@@ -5,7 +5,7 @@
// license that can be found in the LICENSE file.
// Used to be rejected
-// http://code.google.com/p/go/issues/detail?id=188
+// https://golang.org/issue/188
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug217.go b/gcc/testsuite/go.test/test/fixedbugs/bug217.go
index ec93c25..ea836b9 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug217.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug217.go
@@ -5,7 +5,7 @@
// license that can be found in the LICENSE file.
// Used to crash
-// http://code.google.com/p/go/issues/detail?id=204
+// https://golang.org/issue/204
package main
@@ -13,3 +13,5 @@ func () x() // ERROR "no receiver"
func (a b, c d) x() // ERROR "multiple receiver"
+type b int
+
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug218.go b/gcc/testsuite/go.test/test/fixedbugs/bug218.go
index 0e008db..f159f05 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug218.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug218.go
@@ -5,7 +5,7 @@
// license that can be found in the LICENSE file.
// Crashes 6g, 8g
-// http://code.google.com/p/go/issues/detail?id=238
+// https://golang.org/issue/238
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug221.go b/gcc/testsuite/go.test/test/fixedbugs/bug221.go
index 86fda20..4275474 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug221.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug221.go
@@ -7,7 +7,7 @@
// function call arg reordering was picking out 1 call that
// didn't need to be in a temporary, but it was picking
// out the first call instead of the last call.
-// http://code.google.com/p/go/issues/detail?id=370
+// https://golang.org/issue/370
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug227.go b/gcc/testsuite/go.test/test/fixedbugs/bug227.go
index ea8d02d..afbdd97 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug227.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug227.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug228.go b/gcc/testsuite/go.test/test/fixedbugs/bug228.go
index 3fccd17..f7ac670 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug228.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug228.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug229.go b/gcc/testsuite/go.test/test/fixedbugs/bug229.go
index 1977688..a30202f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug229.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug229.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
@@ -10,11 +10,11 @@ import "testing"
func main() {
var t testing.T
-
+
// make sure error mentions that
// name is unexported, not just "name not found".
- t.name = nil // ERROR "unexported"
-
- println(testing.anyLowercaseName("asdf")) // ERROR "unexported" "undefined: testing.anyLowercaseName"
+ t.common.name = nil // ERROR "unexported"
+
+ println(testing.anyLowercaseName("asdf")) // ERROR "unexported"
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug230.go b/gcc/testsuite/go.test/test/fixedbugs/bug230.go
index 210acc4..e5eead5 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug230.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug230.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug231.go b/gcc/testsuite/go.test/test/fixedbugs/bug231.go
index a9d409b..f64ddc3 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug231.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug231.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug232.go b/gcc/testsuite/go.test/test/fixedbugs/bug232.go
index d18727e..10b0c52 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug232.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug232.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug233.go b/gcc/testsuite/go.test/test/fixedbugs/bug233.go
index 63f8ee2..d4e1e07 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug233.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug233.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug234.go b/gcc/testsuite/go.test/test/fixedbugs/bug234.go
index 9f503f0..0d37ce2 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug234.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug234.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug235.go b/gcc/testsuite/go.test/test/fixedbugs/bug235.go
index d12d9e7..a33092b 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug235.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug235.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug236.go b/gcc/testsuite/go.test/test/fixedbugs/bug236.go
index 6c24556..de7e8e3 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug236.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug236.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug237.go b/gcc/testsuite/go.test/test/fixedbugs/bug237.go
index 58996ca..75d6132 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug237.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug237.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug243.go b/gcc/testsuite/go.test/test/fixedbugs/bug243.go
index 4870c36..5b6bb75 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug243.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug243.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug245.go b/gcc/testsuite/go.test/test/fixedbugs/bug245.go
index c607a6d..adf62f9 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug245.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug245.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug247.go b/gcc/testsuite/go.test/test/fixedbugs/bug247.go
index b6851e1..6550bd8 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug247.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug247.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug248.dir/bug1.go b/gcc/testsuite/go.test/test/fixedbugs/bug248.dir/bug1.go
index 78433f5..f1db77d 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug248.dir/bug1.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug248.dir/bug1.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file
-package p
+package q
type T struct {
X, Y int
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug248.dir/bug2.go b/gcc/testsuite/go.test/test/fixedbugs/bug248.dir/bug2.go
index ba547d6..c0fdecf 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug248.dir/bug2.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug248.dir/bug2.go
@@ -2,19 +2,20 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file
-package main
+package s
import (
p0 "./bug0"
p1 "./bug1"
-
- "reflect"
- "strings"
)
+// both p0.T and p1.T are struct { X, Y int }.
+
var v0 p0.T
var v1 p1.T
+// interfaces involving the two
+
type I0 interface {
M(p0.T)
}
@@ -23,83 +24,50 @@ type I1 interface {
M(p1.T)
}
+// t0 satisfies I0 and p0.I
type t0 int
func (t0) M(p0.T) {}
+// t1 satisfies I1 and p1.I
type t1 float64
func (t1) M(p1.T) {}
+// check static interface assignments
var i0 I0 = t0(0) // ok
var i1 I1 = t1(0) // ok
+var i2 I0 = t1(0) // ERROR "does not implement|incompatible"
+var i3 I1 = t0(0) // ERROR "does not implement|incompatible"
+
var p0i p0.I = t0(0) // ok
var p1i p1.I = t1(0) // ok
-func main() {
- // check that reflect paths are correct,
- // meaning that reflect data for v0, v1 didn't get confused.
-
- // path is full (rooted) path name. check suffix for gc, prefix for gccgo
- if s := reflect.TypeOf(v0).PkgPath(); !strings.HasSuffix(s, "/bug0") && !strings.HasPrefix(s, "bug0") {
- println("bad v0 path", len(s), s)
- panic("fail")
- }
- if s := reflect.TypeOf(v1).PkgPath(); !strings.HasSuffix(s, "/bug1") && !strings.HasPrefix(s, "bug1") {
- println("bad v1 path", s)
- panic("fail")
- }
-
- // check that dynamic interface check doesn't get confused
- var i interface{} = t0(0)
- if _, ok := i.(I1); ok {
- println("used t0 as i1")
- panic("fail")
- }
- if _, ok := i.(p1.I); ok {
- println("used t0 as p1.I")
- panic("fail")
- }
-
- i = t1(1)
- if _, ok := i.(I0); ok {
- println("used t1 as i0")
- panic("fail")
- }
- if _, ok := i.(p0.I); ok {
- println("used t1 as p0.I")
- panic("fail")
- }
-
- // check that type switch works.
- // the worry is that if p0.T and p1.T have the same hash,
- // the binary search will handle one of them incorrectly.
- for j := 0; j < 3; j++ {
- switch j {
- case 0:
- i = p0.T{}
- case 1:
- i = p1.T{}
- case 2:
- i = 3.14
- }
- switch i.(type) {
- case p0.T:
- if j != 0 {
- println("type switch p0.T")
- panic("fail")
- }
- case p1.T:
- if j != 1 {
- println("type switch p1.T")
- panic("fail")
- }
- default:
- if j != 2 {
- println("type switch default", j)
- panic("fail")
- }
- }
- }
+var p0i1 p0.I = t1(0) // ERROR "does not implement|incompatible"
+var p0i2 p1.I = t0(0) // ERROR "does not implement|incompatible"
+
+func foobar() {
+ // check that cannot assign one to the other,
+ // but can convert.
+ v0 = v1 // ERROR "assign"
+ v1 = v0 // ERROR "assign"
+
+ v0 = p0.T(v1)
+ v1 = p1.T(v0)
+
+ i0 = i1 // ERROR "cannot use|incompatible"
+ i1 = i0 // ERROR "cannot use|incompatible"
+ p0i = i1 // ERROR "cannot use|incompatible"
+ p1i = i0 // ERROR "cannot use|incompatible"
+ i0 = p1i // ERROR "cannot use|incompatible"
+ i1 = p0i // ERROR "cannot use|incompatible"
+ p0i = p1i // ERROR "cannot use|incompatible"
+ p1i = p0i // ERROR "cannot use|incompatible"
+
+ i0 = p0i
+ p0i = i0
+
+ i1 = p1i
+ p1i = i1
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug248.dir/bug3.go b/gcc/testsuite/go.test/test/fixedbugs/bug248.dir/bug3.go
index 4a56c5c..ba547d6 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug248.dir/bug3.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug248.dir/bug3.go
@@ -7,15 +7,14 @@ package main
import (
p0 "./bug0"
p1 "./bug1"
-)
-// both p0.T and p1.T are struct { X, Y int }.
+ "reflect"
+ "strings"
+)
var v0 p0.T
var v1 p1.T
-// interfaces involving the two
-
type I0 interface {
M(p0.T)
}
@@ -24,50 +23,83 @@ type I1 interface {
M(p1.T)
}
-// t0 satisfies I0 and p0.I
type t0 int
func (t0) M(p0.T) {}
-// t1 satisfies I1 and p1.I
type t1 float64
func (t1) M(p1.T) {}
-// check static interface assignments
var i0 I0 = t0(0) // ok
var i1 I1 = t1(0) // ok
-var i2 I0 = t1(0) // ERROR "does not implement|incompatible"
-var i3 I1 = t0(0) // ERROR "does not implement|incompatible"
-
var p0i p0.I = t0(0) // ok
var p1i p1.I = t1(0) // ok
-var p0i1 p0.I = t1(0) // ERROR "does not implement|incompatible"
-var p0i2 p1.I = t0(0) // ERROR "does not implement|incompatible"
-
func main() {
- // check that cannot assign one to the other,
- // but can convert.
- v0 = v1 // ERROR "assign"
- v1 = v0 // ERROR "assign"
-
- v0 = p0.T(v1)
- v1 = p1.T(v0)
-
- i0 = i1 // ERROR "cannot use|incompatible"
- i1 = i0 // ERROR "cannot use|incompatible"
- p0i = i1 // ERROR "cannot use|incompatible"
- p1i = i0 // ERROR "cannot use|incompatible"
- i0 = p1i // ERROR "cannot use|incompatible"
- i1 = p0i // ERROR "cannot use|incompatible"
- p0i = p1i // ERROR "cannot use|incompatible"
- p1i = p0i // ERROR "cannot use|incompatible"
-
- i0 = p0i
- p0i = i0
-
- i1 = p1i
- p1i = i1
+ // check that reflect paths are correct,
+ // meaning that reflect data for v0, v1 didn't get confused.
+
+ // path is full (rooted) path name. check suffix for gc, prefix for gccgo
+ if s := reflect.TypeOf(v0).PkgPath(); !strings.HasSuffix(s, "/bug0") && !strings.HasPrefix(s, "bug0") {
+ println("bad v0 path", len(s), s)
+ panic("fail")
+ }
+ if s := reflect.TypeOf(v1).PkgPath(); !strings.HasSuffix(s, "/bug1") && !strings.HasPrefix(s, "bug1") {
+ println("bad v1 path", s)
+ panic("fail")
+ }
+
+ // check that dynamic interface check doesn't get confused
+ var i interface{} = t0(0)
+ if _, ok := i.(I1); ok {
+ println("used t0 as i1")
+ panic("fail")
+ }
+ if _, ok := i.(p1.I); ok {
+ println("used t0 as p1.I")
+ panic("fail")
+ }
+
+ i = t1(1)
+ if _, ok := i.(I0); ok {
+ println("used t1 as i0")
+ panic("fail")
+ }
+ if _, ok := i.(p0.I); ok {
+ println("used t1 as p0.I")
+ panic("fail")
+ }
+
+ // check that type switch works.
+ // the worry is that if p0.T and p1.T have the same hash,
+ // the binary search will handle one of them incorrectly.
+ for j := 0; j < 3; j++ {
+ switch j {
+ case 0:
+ i = p0.T{}
+ case 1:
+ i = p1.T{}
+ case 2:
+ i = 3.14
+ }
+ switch i.(type) {
+ case p0.T:
+ if j != 0 {
+ println("type switch p0.T")
+ panic("fail")
+ }
+ case p1.T:
+ if j != 1 {
+ println("type switch p1.T")
+ panic("fail")
+ }
+ default:
+ if j != 2 {
+ println("type switch default", j)
+ panic("fail")
+ }
+ }
+ }
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug248.go b/gcc/testsuite/go.test/test/fixedbugs/bug248.go
index 98cda35..93d2fdb 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug248.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug248.go
@@ -1,15 +1,12 @@
-// $G $D/$F.dir/bug0.go &&
-// $G $D/$F.dir/bug1.go &&
-// $G $D/$F.dir/bug2.go &&
-// errchk $G -e $D/$F.dir/bug3.go &&
-// $L bug2.$A &&
-// ./$A.out || echo BUG: failed to compile
-
-// NOTE: This test is not run by 'run.go' and so not run by all.bash.
-// To run this test you must use the ./run shell script.
+// +build !nacl,!js,!plan9
+// errorcheckandrundir -1
// Copyright 2009 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.
-ignored
+package ignored
+
+// Compile: bug0.go, bug1.go
+// Compile and errorCheck: bug2.go
+// Link and run: bug3.go
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug249.go b/gcc/testsuite/go.test/test/fixedbugs/bug249.go
index dc92245..ec9699a 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug249.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug249.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug250.go b/gcc/testsuite/go.test/test/fixedbugs/bug250.go
index 5140f3e..9fb34c3 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug250.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug250.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug252.go b/gcc/testsuite/go.test/test/fixedbugs/bug252.go
index 6f007fb..f678925 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug252.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug252.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug253.go b/gcc/testsuite/go.test/test/fixedbugs/bug253.go
index f6ab712..933f3f1 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug253.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug253.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug254.go b/gcc/testsuite/go.test/test/fixedbugs/bug254.go
index 9b1c819..3902cd5 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug254.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug254.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug255.go b/gcc/testsuite/go.test/test/fixedbugs/bug255.go
index acf4f23..458fb97 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug255.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug255.go
@@ -1,15 +1,20 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
-var a [10]int // ok
-var b [1e1]int // ok
-var c [1.5]int // ERROR "truncated"
-var d ["abc"]int // ERROR "invalid array bound|not numeric"
-var e [nil]int // ERROR "invalid array bound|not numeric"
-var f [e]int // ERROR "invalid array bound|not constant"
-var g [1<<65]int // ERROR "array bound is too large|overflows"
+var a [10]int // ok
+var b [1e1]int // ok
+var c [1.5]int // ERROR "truncated"
+var d ["abc"]int // ERROR "invalid array bound|not numeric"
+var e [nil]int // ERROR "use of untyped nil|invalid array bound|not numeric"
+var f [e]int // ok: error already reported for e
+var g [1 << 65]int // ERROR "array bound is too large|overflows"
+var h [len(a)]int // ok
+
+func ff() string
+
+var i [len([1]string{ff()})]int // ERROR "non-constant array bound|not constant"
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug256.go b/gcc/testsuite/go.test/test/fixedbugs/bug256.go
index 0498a40..705a032 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug256.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug256.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug257.go b/gcc/testsuite/go.test/test/fixedbugs/bug257.go
index 003f3ff..b05c37a 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug257.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug257.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug258.go b/gcc/testsuite/go.test/test/fixedbugs/bug258.go
index d362e5a..075da87 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug258.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug258.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug259.go b/gcc/testsuite/go.test/test/fixedbugs/bug259.go
index e4dcaeb2f..857b442 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug259.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug259.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug261.go b/gcc/testsuite/go.test/test/fixedbugs/bug261.go
index f7879b0..abe6431 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug261.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug261.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug264.go b/gcc/testsuite/go.test/test/fixedbugs/bug264.go
index fcf373c..2f320def 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug264.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug264.go
@@ -4,7 +4,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Test case for http://code.google.com/p/go/issues/detail?id=692
+// Test case for https://golang.org/issue/692
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug265.go b/gcc/testsuite/go.test/test/fixedbugs/bug265.go
index 7f06fce..5e05166 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug265.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug265.go
@@ -4,7 +4,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Test case for http://code.google.com/p/go/issues/detail?id=700
+// Test case for https://golang.org/issue/700
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug266.go b/gcc/testsuite/go.test/test/fixedbugs/bug266.go
index d4da891..5d2334c 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug266.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug266.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug269.go b/gcc/testsuite/go.test/test/fixedbugs/bug269.go
index c13eb26..ec0dbc6 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug269.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug269.go
@@ -1,10 +1,10 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// http://code.google.com/p/go/issues/detail?id=749
+// https://golang.org/issue/749
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug271.go b/gcc/testsuite/go.test/test/fixedbugs/bug271.go
index 88add70..a6abbfe 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug271.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug271.go
@@ -1,10 +1,10 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// http://code.google.com/p/go/issues/detail?id=662
+// https://golang.org/issue/662
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug272.go b/gcc/testsuite/go.test/test/fixedbugs/bug272.go
index c27f7ee..6b8862f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug272.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug272.go
@@ -1,10 +1,10 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// http://code.google.com/p/go/issues/detail?id=589
+// https://golang.org/issue/589
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug273.go b/gcc/testsuite/go.test/test/fixedbugs/bug273.go
index 7305c60..2af8800 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug273.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug273.go
@@ -14,7 +14,7 @@ var bug = false
var minus1 = -1
var five = 5
-var big int64 = 10 | 1<<40
+var big int64 = 10 | 1<<46
type block [1 << 19]byte
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug274.go b/gcc/testsuite/go.test/test/fixedbugs/bug274.go
index beb2d61..e93f30e 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug274.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug274.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -13,7 +13,7 @@
// Both gccgo and gofmt correctly refuse this program as is and accept it
// when the semicolons are present.
-// This is a test case for issue 777 ( http://code.google.com/p/go/issues/detail?id=777 ).
+// This is a test case for issue 777 ( https://golang.org/issue/777 ).
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug275.go b/gcc/testsuite/go.test/test/fixedbugs/bug275.go
index f5f6b14..d3be754 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug275.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug275.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug278.go b/gcc/testsuite/go.test/test/fixedbugs/bug278.go
index 68a3d81..4817ebf 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug278.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug278.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug279.go b/gcc/testsuite/go.test/test/fixedbugs/bug279.go
index e5ec594..3b1df3b 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug279.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug279.go
@@ -1,10 +1,10 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// http://code.google.com/p/go/issues/detail?id=799
+// https://golang.org/issue/799
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug280.go b/gcc/testsuite/go.test/test/fixedbugs/bug280.go
index ba594a2..afec57f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug280.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug280.go
@@ -1,10 +1,10 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// http://code.google.com/p/go/issues/detail?id=808
+// https://golang.org/issue/808
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug281.go b/gcc/testsuite/go.test/test/fixedbugs/bug281.go
index 24d6fdc..c65530f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug281.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug281.go
@@ -1,10 +1,10 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// http://code.google.com/p/go/issues/detail?id=807
+// https://golang.org/issue/807
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug282.dir/p1.go b/gcc/testsuite/go.test/test/fixedbugs/bug282.dir/p1.go
index b562755..0f7422c 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug282.dir/p1.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug282.dir/p1.go
@@ -1,4 +1,4 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug282.dir/p2.go b/gcc/testsuite/go.test/test/fixedbugs/bug282.dir/p2.go
index 3f8bd9d..f614507 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug282.dir/p2.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug282.dir/p2.go
@@ -1,4 +1,4 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug283.go b/gcc/testsuite/go.test/test/fixedbugs/bug283.go
index eefed03..ef1953b 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug283.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug283.go
@@ -1,10 +1,10 @@
// compile
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// http://code.google.com/p/go/issues/detail?id=806
+// https://golang.org/issue/806
// triggered out of registers on 8g
package bug283
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug285.go b/gcc/testsuite/go.test/test/fixedbugs/bug285.go
index 0a8a0f0..0632ab4 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug285.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug285.go
@@ -1,12 +1,12 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Test for issue 778: Map key values that are assignment
// compatible with the map key type must be accepted according
-// to the spec: http://golang.org/doc/go_spec.html#Indexes .
+// to the spec: https://golang.org/doc/go_spec.html#Indexes .
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug286.go b/gcc/testsuite/go.test/test/fixedbugs/bug286.go
index 44f0515..b1271f4 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug286.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug286.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug287.go b/gcc/testsuite/go.test/test/fixedbugs/bug287.go
index 2ed81c5..94582a8 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug287.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug287.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug288.go b/gcc/testsuite/go.test/test/fixedbugs/bug288.go
index d2461e6..0a53d32 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug288.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug288.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug289.go b/gcc/testsuite/go.test/test/fixedbugs/bug289.go
index 3c6b687..3fc7fb2 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug289.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug289.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -9,14 +9,14 @@
package main
func f1() {
- a, b := f() // ERROR "mismatch|does not match"
+ a, b := f() // ERROR "assignment mismatch|does not match"
_ = a
_ = b
}
func f2() {
var a, b int
- a, b = f() // ERROR "mismatch|does not match"
+ a, b = f() // ERROR "assignment mismatch|does not match"
_ = a
_ = b
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug290.go b/gcc/testsuite/go.test/test/fixedbugs/bug290.go
index c8ff0bc..4eee285 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug290.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug290.go
@@ -1,10 +1,10 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// http://code.google.com/p/go/issues/detail?id=920
+// https://golang.org/issue/920
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug291.go b/gcc/testsuite/go.test/test/fixedbugs/bug291.go
index 17a5483..ac84a7e 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug291.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug291.go
@@ -1,10 +1,10 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// http://code.google.com/p/go/issues/detail?id=915
+// https://golang.org/issue/915
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug292.go b/gcc/testsuite/go.test/test/fixedbugs/bug292.go
index 07051dd..1130a28 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug292.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug292.go
@@ -1,10 +1,10 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// http://code.google.com/p/go/issues/detail?id=843
+// https://golang.org/issue/843
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug293.go b/gcc/testsuite/go.test/test/fixedbugs/bug293.go
index bf926f5..ae7cc1f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug293.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug293.go
@@ -1,10 +1,10 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// http://code.google.com/p/go/issues/detail?id=846
+// https://golang.org/issue/846
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug294.go b/gcc/testsuite/go.test/test/fixedbugs/bug294.go
index 0f3e380..b35b771 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug294.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug294.go
@@ -1,10 +1,10 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// http://code.google.com/p/go/issues/detail?id=800
+// https://golang.org/issue/800
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug295.go b/gcc/testsuite/go.test/test/fixedbugs/bug295.go
index 63a12a3..d1c961c 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug295.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug295.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug296.go b/gcc/testsuite/go.test/test/fixedbugs/bug296.go
index a7c4e0c..2ef4e66 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug296.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug296.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug297.go b/gcc/testsuite/go.test/test/fixedbugs/bug297.go
index ee2ff92..c2bd253 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug297.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug297.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -11,5 +11,5 @@ package main
type ByteSize float64
const (
_ = iota; // ignore first value by assigning to blank identifier
- KB ByteSize = 1<<(10*X) // ERROR "undefined" "is not a constant|as type ByteSize"
+ KB ByteSize = 1<<(10*X) // ERROR "undefined"
)
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug298.go b/gcc/testsuite/go.test/test/fixedbugs/bug298.go
index bd362ac..0aed032 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug298.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug298.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug299.go b/gcc/testsuite/go.test/test/fixedbugs/bug299.go
index 1067fd1..cf11bcc 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug299.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug299.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug300.go b/gcc/testsuite/go.test/test/fixedbugs/bug300.go
index 1ef43a0..1695a96 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug300.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug300.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug301.go b/gcc/testsuite/go.test/test/fixedbugs/bug301.go
index 572668f..2be62b8 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug301.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug301.go
@@ -1,10 +1,10 @@
// compile
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// http://code.google.com/p/go/issues/detail?id=990
+// https://golang.org/issue/990
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug302.dir/main.go b/gcc/testsuite/go.test/test/fixedbugs/bug302.dir/main.go
index 9f874d0..52c054f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug302.dir/main.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug302.dir/main.go
@@ -1,12 +1,12 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
// Check that the export information is correct in p.6.
-import _ "./p"
+import _ "p"
// Check that it's still correct in pp.a (which contains p.6).
-import _ "./pp"
+import _ "pp"
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug302.dir/p.go b/gcc/testsuite/go.test/test/fixedbugs/bug302.dir/p.go
index 7c54b90..0be521b 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug302.dir/p.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug302.dir/p.go
@@ -1,4 +1,4 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug302.go b/gcc/testsuite/go.test/test/fixedbugs/bug302.go
index dc7637f..87f9d4e 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug302.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug302.go
@@ -1,9 +1,45 @@
-// $G $D/bug302.dir/p.go && pack grc pp.a p.$A && $G $D/bug302.dir/main.go
+// +build !nacl,!js
+// run
-// NOTE: This test is not run by 'run.go' and so not run by all.bash.
-// To run this test you must use the ./run shell script.
-
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+package main
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+)
+
+var tmpDir string
+
+func main() {
+ fb, err := filepath.Abs("fixedbugs")
+ if err == nil {
+ tmpDir, err = ioutil.TempDir("", "bug302")
+ }
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ defer os.RemoveAll(tmpDir)
+
+ run("go", "tool", "compile", filepath.Join(fb, "bug302.dir", "p.go"))
+ run("go", "tool", "pack", "grc", "pp.a", "p.o")
+ run("go", "tool", "compile", "-I", ".", filepath.Join(fb, "bug302.dir", "main.go"))
+}
+
+func run(cmd string, args ...string) {
+ c := exec.Command(cmd, args...)
+ c.Dir = tmpDir
+ out, err := c.CombinedOutput()
+ if err != nil {
+ fmt.Println(string(out))
+ fmt.Println(err)
+ os.Exit(1)
+ }
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug303.go b/gcc/testsuite/go.test/test/fixedbugs/bug303.go
index 94ca07e..aef8b22 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug303.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug303.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug304.go b/gcc/testsuite/go.test/test/fixedbugs/bug304.go
index ad71b20..4073073 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug304.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug304.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug305.go b/gcc/testsuite/go.test/test/fixedbugs/bug305.go
index d0a4b24..0c34b1a 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug305.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug305.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug306.dir/p1.go b/gcc/testsuite/go.test/test/fixedbugs/bug306.dir/p1.go
index bf87ea1..b285518 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug306.dir/p1.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug306.dir/p1.go
@@ -1,4 +1,4 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug306.dir/p2.go b/gcc/testsuite/go.test/test/fixedbugs/bug306.dir/p2.go
index 3f8bd9d..f614507 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug306.dir/p2.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug306.dir/p2.go
@@ -1,4 +1,4 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug308.go b/gcc/testsuite/go.test/test/fixedbugs/bug308.go
index 5bea517..a23903c 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug308.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug308.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug309.go b/gcc/testsuite/go.test/test/fixedbugs/bug309.go
index 948ca5c..d707aa3 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug309.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug309.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug311.go b/gcc/testsuite/go.test/test/fixedbugs/bug311.go
index edcd975..f5cab44 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug311.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug311.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug312.go b/gcc/testsuite/go.test/test/fixedbugs/bug312.go
index c7c17e1..af423e5b 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug312.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug312.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug313.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/bug313.dir/a.go
index cb4ca72..335f84d 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug313.dir/a.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug313.dir/a.go
@@ -1,4 +1,4 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug313.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/bug313.dir/b.go
index 7eda72b..26e6413 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug313.dir/b.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug313.dir/b.go
@@ -1,4 +1,4 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug313.go b/gcc/testsuite/go.test/test/fixedbugs/bug313.go
index a7c1d36..f7e0238 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug313.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug313.go
@@ -1,6 +1,6 @@
// errorcheckdir
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug317.go b/gcc/testsuite/go.test/test/fixedbugs/bug317.go
index 3ff4dc4..4cd9ec28 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug317.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug317.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug319.go b/gcc/testsuite/go.test/test/fixedbugs/bug319.go
index f8e959a..b93106d 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug319.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug319.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug320.go b/gcc/testsuite/go.test/test/fixedbugs/bug320.go
index c2dd31b..0406b96 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug320.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug320.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug321.go b/gcc/testsuite/go.test/test/fixedbugs/bug321.go
index 7d01827..19970af 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug321.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug321.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug323.go b/gcc/testsuite/go.test/test/fixedbugs/bug323.go
index 9730ae5..3cb8eaa 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug323.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug323.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug325.go b/gcc/testsuite/go.test/test/fixedbugs/bug325.go
index 6ccd0e3..e6528ae 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug325.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug325.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug326.go b/gcc/testsuite/go.test/test/fixedbugs/bug326.go
index 57f6471..75d620c 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug326.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug326.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug327.go b/gcc/testsuite/go.test/test/fixedbugs/bug327.go
index 0598d95..ecb5d22 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug327.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug327.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug328.go b/gcc/testsuite/go.test/test/fixedbugs/bug328.go
index 73ab46d..57043f3 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug328.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug328.go
@@ -1,6 +1,6 @@
-// cmpout
+// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug329.go b/gcc/testsuite/go.test/test/fixedbugs/bug329.go
index 74fc781..37c93d0 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug329.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug329.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug330.go b/gcc/testsuite/go.test/test/fixedbugs/bug330.go
index ef6a077..2f33feb 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug330.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug330.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug331.go b/gcc/testsuite/go.test/test/fixedbugs/bug331.go
index fac0e36..9eb57cd 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug331.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug331.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug332.go b/gcc/testsuite/go.test/test/fixedbugs/bug332.go
index 702779b..159c8b4 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug332.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug332.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -13,5 +13,5 @@ func main() {}
// issue 1474
// important: no newline on end of next line.
-// 6g used to print <epoch> instead of bug332.go:111
-func (t *T) F() {} // ERROR "bug332" \ No newline at end of file
+// 6g used to print <epoch> instead of bug332.go:111
+func (t *T) F() {} // ERROR "undefined.*T" \ No newline at end of file
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug333.go b/gcc/testsuite/go.test/test/fixedbugs/bug333.go
index bb690f0..149843a 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug333.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug333.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug334.go b/gcc/testsuite/go.test/test/fixedbugs/bug334.go
index bd671696..9558c06 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug334.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug334.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug335.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/bug335.dir/a.go
index 256c110..6ecc5c4 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug335.dir/a.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug335.dir/a.go
@@ -1,4 +1,4 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug335.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/bug335.dir/b.go
index 1474470..a7735a8 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug335.dir/b.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug335.dir/b.go
@@ -1,4 +1,4 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug335.go b/gcc/testsuite/go.test/test/fixedbugs/bug335.go
index 37c97d7..fda9eb8 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug335.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug335.go
@@ -1,6 +1,6 @@
// compiledir
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug336.go b/gcc/testsuite/go.test/test/fixedbugs/bug336.go
index fbf2320..fbcd3a5 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug336.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug336.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug337.go b/gcc/testsuite/go.test/test/fixedbugs/bug337.go
index 38dc665..1a0616f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug337.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug337.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug338.go b/gcc/testsuite/go.test/test/fixedbugs/bug338.go
index c2193fc..a4537a4 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug338.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug338.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug339.go b/gcc/testsuite/go.test/test/fixedbugs/bug339.go
index 59921d4..36be761 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug339.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug339.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug340.go b/gcc/testsuite/go.test/test/fixedbugs/bug340.go
index d996ab6..8c543c9 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug340.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug340.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -12,6 +12,6 @@ func main() {
var x interface{}
switch t := x.(type) {
case 0: // ERROR "type"
- t.x = 1 // ERROR "type interface \{\}|reference to undefined field or method"
+ t.x = 1 // ERROR "type interface \{\}|reference to undefined field or method|interface with no methods"
}
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug341.go b/gcc/testsuite/go.test/test/fixedbugs/bug341.go
index db1af3e..baab282 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug341.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug341.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug342.go b/gcc/testsuite/go.test/test/fixedbugs/bug342.go
index ffcb668..f90f6f3 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug342.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug342.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug343.go b/gcc/testsuite/go.test/test/fixedbugs/bug343.go
index 8220108..fd8bd76 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug343.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug343.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug344.go b/gcc/testsuite/go.test/test/fixedbugs/bug344.go
index 4a92624..b53abd2 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug344.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug344.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug345.dir/io.go b/gcc/testsuite/go.test/test/fixedbugs/bug345.dir/io.go
index 1d695c3..ca7a509 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug345.dir/io.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug345.dir/io.go
@@ -1,4 +1,4 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug345.dir/main.go b/gcc/testsuite/go.test/test/fixedbugs/bug345.dir/main.go
index ddba8da..b77a2fa 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug345.dir/main.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug345.dir/main.go
@@ -1,4 +1,4 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -6,8 +6,9 @@ package main
import (
"bufio"
- "./io"
goio "io"
+
+ "./io"
)
func main() {
@@ -22,7 +23,7 @@ func main() {
// main.go:27: cannot use &x (type *"io".SectionReader) as type *"/Users/rsc/g/go/test/fixedbugs/bug345.dir/io".SectionReader in function argument
var w io.Writer
- bufio.NewWriter(w) // ERROR "test/io|has incompatible type"
+ bufio.NewWriter(w) // ERROR "[\w.]+[^.]/io|has incompatible type"
var x goio.SectionReader
- io.SR(&x) // ERROR "test/io|has incompatible type"
+ io.SR(&x) // ERROR "[\w.]+[^.]/io|has incompatible type"
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug345.go b/gcc/testsuite/go.test/test/fixedbugs/bug345.go
index e3705f6..b974a61 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug345.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug345.go
@@ -1,10 +1,10 @@
-// $G $D/$F.dir/io.go && errchk $G -e $D/$F.dir/main.go
+// +build !windows
+// errorcheckdir -n
-// NOTE: This test is not run by 'run.go' and so not run by all.bash.
-// To run this test you must use the ./run shell script.
-
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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 ignored
+
+// TODO(ysmolsky): Fix golang.org/issue/25693 to enable on Windows.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug346.go b/gcc/testsuite/go.test/test/fixedbugs/bug346.go
index d9203aa..f69b58d 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug346.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug346.go
@@ -9,11 +9,28 @@ package main
import "os"
func main() {
- x := 4
- a, b, c, d := func(i int) (p int, q int, r int, s int) { return 1, i, 3, x }(2)
+ // Test unclosed closure.
+ {
+ x := 4
+ a, b, c, d := func(i int) (p int, q int, r int, s int) { return 1, i, 3, x }(2)
- if a != 1 || b != 2 || c != 3 || d != 4 {
- println("abcd: expected 1 2 3 4 got", a, b, c, d)
- os.Exit(1)
+ if a != 1 || b != 2 || c != 3 || d != 4 {
+ println("1# abcd: expected 1 2 3 4 got", a, b, c, d)
+ os.Exit(1)
+ }
+ }
+ // Test real closure.
+ {
+ x := 4
+ gf = func(i int) (p int, q int, r int, s int) { return 1, i, 3, x }
+
+ a, b, c, d := gf(2)
+
+ if a != 1 || b != 2 || c != 3 || d != 4 {
+ println("2# abcd: expected 1 2 3 4 got", a, b, c, d)
+ os.Exit(1)
+ }
}
}
+
+var gf func(int) (int, int, int, int)
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug347.go b/gcc/testsuite/go.test/test/fixedbugs/bug347.go
index 08edf0f..92afb2e 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug347.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug347.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug348.go b/gcc/testsuite/go.test/test/fixedbugs/bug348.go
index 54a289a..c7f1346 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug348.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug348.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug349.go b/gcc/testsuite/go.test/test/fixedbugs/bug349.go
index a3e6bd1..a6e8386 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug349.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug349.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug350.go b/gcc/testsuite/go.test/test/fixedbugs/bug350.go
index 5ce8996..cdce1cf 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug350.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug350.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug351.go b/gcc/testsuite/go.test/test/fixedbugs/bug351.go
index 4c5c7c3..8fd63e3 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug351.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug351.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug352.go b/gcc/testsuite/go.test/test/fixedbugs/bug352.go
index 1ae2d61..464ad7b 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug352.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug352.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug353.go b/gcc/testsuite/go.test/test/fixedbugs/bug353.go
index 2a532c4..4a65f77 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug353.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug353.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug354.go b/gcc/testsuite/go.test/test/fixedbugs/bug354.go
index 1245d91..293180f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug354.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug354.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug355.go b/gcc/testsuite/go.test/test/fixedbugs/bug355.go
index fcf859b..880353a 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug355.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug355.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug356.go b/gcc/testsuite/go.test/test/fixedbugs/bug356.go
index 273c5b8..6d93860 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug356.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug356.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug357.go b/gcc/testsuite/go.test/test/fixedbugs/bug357.go
index ceb2009..e9db50e 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug357.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug357.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug358.go b/gcc/testsuite/go.test/test/fixedbugs/bug358.go
index 063c2e0..5ca0be1 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug358.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug358.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -10,13 +10,14 @@
package main
import (
- "io/ioutil" // GCCGO_ERROR "imported and not used"
+ // avoid imported and not used errors
+ // "io/ioutil"
"net/http"
- "os" // GCCGO_ERROR "imported and not used"
+ // "os"
)
func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
- return func(w http.ResponseWriter, r *http.Request) // ERROR "syntax error|invalid use of type"
+ return func(w http.ResponseWriter, r *http.Request) // ERROR "syntax error|not an expression|invalid use of type"
}
type Page struct {
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug361.go b/gcc/testsuite/go.test/test/fixedbugs/bug361.go
index 3e3b7c1..8e28243 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug361.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug361.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug362.go b/gcc/testsuite/go.test/test/fixedbugs/bug362.go
index b888ccb..771d13d 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug362.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug362.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug363.go b/gcc/testsuite/go.test/test/fixedbugs/bug363.go
index 615c668..1bd14009 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug363.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug363.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug365.go b/gcc/testsuite/go.test/test/fixedbugs/bug365.go
index 795323b..985b6de 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug365.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug365.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug366.go b/gcc/testsuite/go.test/test/fixedbugs/bug366.go
index 33a1a5a..3af5bea 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug366.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug366.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug368.go b/gcc/testsuite/go.test/test/fixedbugs/bug368.go
index c38cc7f..353ea5a 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug368.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug368.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug369.dir/pkg.go b/gcc/testsuite/go.test/test/fixedbugs/bug369.dir/pkg.go
index cf57041..9964347 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug369.dir/pkg.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug369.dir/pkg.go
@@ -1,4 +1,4 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug369.go b/gcc/testsuite/go.test/test/fixedbugs/bug369.go
index 7c9583a..9316f7a 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug369.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug369.go
@@ -1,11 +1,7 @@
-// $G -N -o slow.$A $D/bug369.dir/pkg.go &&
-// $G -o fast.$A $D/bug369.dir/pkg.go &&
+// +build !nacl,!js,!windows
// run
-// NOTE: This test is not run by 'run.go' and so not run by all.bash.
-// To run this test you must use the ./run shell script.
-
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -14,50 +10,45 @@
package main
import (
- "flag"
+ "fmt"
+ "io/ioutil"
"os"
- "runtime"
- "testing"
-
- fast "./fast"
- slow "./slow"
+ "os/exec"
+ "path/filepath"
)
-var buf = make([]byte, 1048576)
+func main() {
+ err := os.Chdir(filepath.Join(".", "fixedbugs", "bug369.dir"))
+ check(err)
+
+ tmpDir, err := ioutil.TempDir("", "bug369")
+ check(err)
+ defer os.RemoveAll(tmpDir)
-func BenchmarkFastNonASCII(b *testing.B) {
- for i := 0; i < b.N; i++ {
- fast.NonASCII(buf, 0)
+ tmp := func(name string) string {
+ return filepath.Join(tmpDir, name)
}
+
+ run("go", "tool", "compile", "-N", "-o", tmp("slow.o"), "pkg.go")
+ run("go", "tool", "compile", "-o", tmp("fast.o"), "pkg.go")
+ run("go", "tool", "compile", "-D", tmpDir, "-o", tmp("main.o"), "main.go")
+ run("go", "tool", "link", "-o", tmp("a.exe"), tmp("main.o"))
+ run(tmp("a.exe"))
}
-func BenchmarkSlowNonASCII(b *testing.B) {
- for i := 0; i < b.N; i++ {
- slow.NonASCII(buf, 0)
+func run(name string, args ...string) {
+ cmd := exec.Command(name, args...)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ fmt.Println(string(out))
+ fmt.Println(err)
+ os.Exit(1)
}
}
-func main() {
- testing.Init()
- os.Args = []string{os.Args[0], "-test.benchtime=100ms"}
- flag.Parse()
-
- rslow := testing.Benchmark(BenchmarkSlowNonASCII)
- rfast := testing.Benchmark(BenchmarkFastNonASCII)
- tslow := rslow.NsPerOp()
- tfast := rfast.NsPerOp()
-
- // Optimization should be good for at least 2x, but be forgiving.
- // On the ARM simulator we see closer to 1.5x.
- speedup := float64(tslow)/float64(tfast)
- want := 1.8
- if runtime.GOARCH == "arm" {
- want = 1.3
- }
- if speedup < want {
- // TODO(rsc): doesn't work on linux-amd64 or darwin-amd64 builders, nor on
- // a Lenovo x200 (linux-amd64) laptop.
- //println("fast:", tfast, "slow:", tslow, "speedup:", speedup, "want:", want)
- //println("not fast enough")
+func check(err error) {
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
}
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug370.go b/gcc/testsuite/go.test/test/fixedbugs/bug370.go
index 246bc7c..c5165c5 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug370.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug370.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug371.go b/gcc/testsuite/go.test/test/fixedbugs/bug371.go
index 86c73bf..3a626e5 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug371.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug371.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug372.go b/gcc/testsuite/go.test/test/fixedbugs/bug372.go
index 3457856..5fba131d 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug372.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug372.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug373.go b/gcc/testsuite/go.test/test/fixedbugs/bug373.go
index e91f26d..6b7a312 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug373.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug373.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -9,7 +9,7 @@
package foo
func f(x interface{}) {
- switch t := x.(type) { // ERROR "declared and not used"
+ switch t := x.(type) { // ERROR "declared but not used"
case int:
}
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug374.go b/gcc/testsuite/go.test/test/fixedbugs/bug374.go
index 4f0b721..2d604cb 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug374.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug374.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug375.go b/gcc/testsuite/go.test/test/fixedbugs/bug375.go
index cb159b0..08d5afc 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug375.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug375.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug376.go b/gcc/testsuite/go.test/test/fixedbugs/bug376.go
index 5fbbc9c..cd70012 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug376.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug376.go
@@ -1,11 +1,10 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
// issue 1951
package foo
import "unsafe"
-var v = unsafe.Sizeof // ERROR "must be called"
-
+var v = unsafe.Sizeof // ERROR "not in function call|must be called"
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug378.go b/gcc/testsuite/go.test/test/fixedbugs/bug378.go
index f3346c6..c7b0dac 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug378.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug378.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug379.go b/gcc/testsuite/go.test/test/fixedbugs/bug379.go
index 14abe46..5638123 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug379.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug379.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug380.go b/gcc/testsuite/go.test/test/fixedbugs/bug380.go
index 96e1ede..0cb3487 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug380.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug380.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug381.go b/gcc/testsuite/go.test/test/fixedbugs/bug381.go
index 0253e14..a0a1c8a 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug381.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug381.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug382.dir/pkg.go b/gcc/testsuite/go.test/test/fixedbugs/bug382.dir/pkg.go
index f8d75d4..92fe4e3 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug382.dir/pkg.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug382.dir/pkg.go
@@ -1,4 +1,4 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug383.go b/gcc/testsuite/go.test/test/fixedbugs/bug383.go
index 503779c..dc2ecd6 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug383.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug383.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug384.go b/gcc/testsuite/go.test/test/fixedbugs/bug384.go
index 0233c19..d02352b 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug384.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug384.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug385_32.go b/gcc/testsuite/go.test/test/fixedbugs/bug385_32.go
index 4c3cad7..73a1311 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug385_32.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug385_32.go
@@ -1,7 +1,7 @@
-// +build 386 arm
+// +build 386 amd64p32 arm
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug385_64.go b/gcc/testsuite/go.test/test/fixedbugs/bug385_64.go
index 6789c0a..0f941ca 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug385_64.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug385_64.go
@@ -1,7 +1,7 @@
// +build amd64
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug386.go b/gcc/testsuite/go.test/test/fixedbugs/bug386.go
index ec358bd..889c8b0 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug386.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug386.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug387.go b/gcc/testsuite/go.test/test/fixedbugs/bug387.go
index 59d5ef9..d885445 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug387.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug387.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug388.go b/gcc/testsuite/go.test/test/fixedbugs/bug388.go
index d41f9ea..2d50850 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug388.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug388.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -9,12 +9,12 @@
package main
import "runtime"
-func foo(runtime.UintType, i int) { // ERROR "cannot declare name runtime.UintType|named/anonymous mix|undefined identifier"
+func foo(runtime.UintType, i int) { // ERROR "cannot declare name runtime.UintType|mixed named and unnamed|undefined identifier"
println(i, runtime.UintType) // GCCGO_ERROR "undefined identifier"
}
func bar(i int) {
- runtime.UintType := i // ERROR "cannot declare name runtime.UintType|non-name on left side|undefined identifier"
+ runtime.UintType := i // ERROR "non-name runtime.UintType|non-name on left side|undefined identifier"
println(runtime.UintType) // GCCGO_ERROR "invalid use of type|undefined identifier"
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug389.go b/gcc/testsuite/go.test/test/fixedbugs/bug389.go
index 55a02e0..14804c8 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug389.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug389.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug391.go b/gcc/testsuite/go.test/test/fixedbugs/bug391.go
index 07d129d..9211b1c 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug391.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug391.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug392.dir/one.go b/gcc/testsuite/go.test/test/fixedbugs/bug392.dir/one.go
index 8242f28..aba8649 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug392.dir/one.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug392.dir/one.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug392.dir/pkg2.go b/gcc/testsuite/go.test/test/fixedbugs/bug392.dir/pkg2.go
index 8320b2f..2ee41f0 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug392.dir/pkg2.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug392.dir/pkg2.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug392.dir/pkg3.go b/gcc/testsuite/go.test/test/fixedbugs/bug392.dir/pkg3.go
index 402c3b0..1403798 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug392.dir/pkg3.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug392.dir/pkg3.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug393.go b/gcc/testsuite/go.test/test/fixedbugs/bug393.go
index f8a9c65..61af578 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug393.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug393.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug394.go b/gcc/testsuite/go.test/test/fixedbugs/bug394.go
index 2d77156..08bac18 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug394.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug394.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug396.dir/one.go b/gcc/testsuite/go.test/test/fixedbugs/bug396.dir/one.go
index 96a1dd7..66eba63f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug396.dir/one.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug396.dir/one.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug396.dir/two.go b/gcc/testsuite/go.test/test/fixedbugs/bug396.dir/two.go
index 9b32508..9152bec 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug396.dir/two.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug396.dir/two.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug397.go b/gcc/testsuite/go.test/test/fixedbugs/bug397.go
index 56cc7cd..6188e3e 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug397.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug397.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug398.go b/gcc/testsuite/go.test/test/fixedbugs/bug398.go
index 1dd3fa4..a1583bd 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug398.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug398.go
@@ -1,23 +1,43 @@
// compile
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
// Used to crash compiler in interface type equality check.
+// (This test used to have problems - see #15596.)
package p
+// exported interfaces
+
type I1 interface {
F() interface{I1}
}
type I2 interface {
F() interface{I2}
-}
+}
+
+var V1 I1
+var V2 I2
+
+func F() bool {
+ return V1 == V2
+}
+
+// non-exported interfaces
+
+type i1 interface {
+ F() interface{i1}
+}
+
+type i2 interface {
+ F() interface{i2}
+}
-var v1 I1
-var v2 I2
+var v1 i1
+var v2 i2
func f() bool {
return v1 == v2
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug399.go b/gcc/testsuite/go.test/test/fixedbugs/bug399.go
index 94852c9..e460d81 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug399.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug399.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug401.go b/gcc/testsuite/go.test/test/fixedbugs/bug401.go
index 5589b5b..215498e 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug401.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug401.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -9,9 +9,8 @@ package main
type T struct{}
+//go:noinline
func (T) cplx() complex128 {
- for false {
- } // avoid inlining
return complex(1, 0)
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug402.go b/gcc/testsuite/go.test/test/fixedbugs/bug402.go
index db3f3da..f9f554d 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug402.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug402.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug403.go b/gcc/testsuite/go.test/test/fixedbugs/bug403.go
index ed7b49a..aa3c1ea 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug403.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug403.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug404.dir/one.go b/gcc/testsuite/go.test/test/fixedbugs/bug404.dir/one.go
index 2024eb0..9fc4770 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug404.dir/one.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug404.dir/one.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug404.dir/two.go b/gcc/testsuite/go.test/test/fixedbugs/bug404.dir/two.go
index 162eae7..0c70a23 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug404.dir/two.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug404.dir/two.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug406.go b/gcc/testsuite/go.test/test/fixedbugs/bug406.go
index c6f8534..32cf3e3 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug406.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug406.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
@@ -14,6 +14,8 @@ type matrix struct {
func (a matrix) equal() bool {
for _ = range a.e {
}
+ for range a.e {
+ }
return true
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug407.dir/one.go b/gcc/testsuite/go.test/test/fixedbugs/bug407.dir/one.go
index a91d904..c85b077 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug407.dir/one.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug407.dir/one.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug407.dir/two.go b/gcc/testsuite/go.test/test/fixedbugs/bug407.dir/two.go
index 67e1852..640305c6 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug407.dir/two.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug407.dir/two.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug409.go b/gcc/testsuite/go.test/test/fixedbugs/bug409.go
index 1dca43b..e854636 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug409.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug409.go
@@ -1,6 +1,6 @@
-// cmpout
+// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug410.go b/gcc/testsuite/go.test/test/fixedbugs/bug410.go
index 430ddcb..a4eef64 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug410.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug410.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug411.go b/gcc/testsuite/go.test/test/fixedbugs/bug411.go
index 3b90db8..a1c36f6 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug411.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug411.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug412.go b/gcc/testsuite/go.test/test/fixedbugs/bug412.go
index c7ddc0c..183fb7e 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug412.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug412.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug413.go b/gcc/testsuite/go.test/test/fixedbugs/bug413.go
index ba80464..819bd1a 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug413.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug413.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug414.dir/p1.go b/gcc/testsuite/go.test/test/fixedbugs/bug414.dir/p1.go
index 2463834..143e600 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug414.dir/p1.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug414.dir/p1.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug414.dir/prog.go b/gcc/testsuite/go.test/test/fixedbugs/bug414.dir/prog.go
index f55d946..8945d65 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug414.dir/prog.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug414.dir/prog.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug414.go b/gcc/testsuite/go.test/test/fixedbugs/bug414.go
index 35e19be..5b435b4 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug414.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug414.go
@@ -1,6 +1,6 @@
// rundir
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug415.dir/p.go b/gcc/testsuite/go.test/test/fixedbugs/bug415.dir/p.go
index b4152d6..e86a697 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug415.dir/p.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug415.dir/p.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug415.dir/prog.go b/gcc/testsuite/go.test/test/fixedbugs/bug415.dir/prog.go
index b894453..1ffde18 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug415.dir/prog.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug415.dir/prog.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug415.go b/gcc/testsuite/go.test/test/fixedbugs/bug415.go
index 8cd4c49..daf4f0c 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug415.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug415.go
@@ -1,6 +1,6 @@
// compiledir
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug416.go b/gcc/testsuite/go.test/test/fixedbugs/bug416.go
index 1d24fa9..9fc3532 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug416.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug416.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug424.dir/lib.go b/gcc/testsuite/go.test/test/fixedbugs/bug424.dir/lib.go
index 97054da..31df8c6 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug424.dir/lib.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug424.dir/lib.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug424.dir/main.go b/gcc/testsuite/go.test/test/fixedbugs/bug424.dir/main.go
index c2fe146..28b41e6 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug424.dir/main.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug424.dir/main.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug424.go b/gcc/testsuite/go.test/test/fixedbugs/bug424.go
index 59c2cd3..9c59abe 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug424.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug424.go
@@ -1,6 +1,6 @@
// rundir
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug425.go b/gcc/testsuite/go.test/test/fixedbugs/bug425.go
index 5546bd9..c3035f6 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug425.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug425.go
@@ -4,7 +4,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// http://code.google.com/p/go/issues/detail?id=3119
+// https://golang.org/issue/3119
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug427.go b/gcc/testsuite/go.test/test/fixedbugs/bug427.go
index 1239e7a..c13bb81 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug427.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug427.go
@@ -4,7 +4,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// http://code.google.com/p/go/issues/detail?id=3351
+// https://golang.org/issue/3351
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug428.go b/gcc/testsuite/go.test/test/fixedbugs/bug428.go
index 298c455..d9ad276 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug428.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug428.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug429.go b/gcc/testsuite/go.test/test/fixedbugs/bug429.go
index 794d293..2c31f32 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug429.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug429.go
@@ -1,13 +1,11 @@
-// $G $D/$F.go && $L $F.$A && ! ./$A.out || echo BUG: bug429
+// skip
-// NOTE: This test is not run by 'run.go' and so not run by all.bash.
-// To run this test you must use the ./run shell script.
-
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
// Should print deadlock message, not hang.
+// This test is run by bug429_run.go.
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug435.go b/gcc/testsuite/go.test/test/fixedbugs/bug435.go
index 45323d8..692a492 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug435.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug435.go
@@ -1,13 +1,13 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
// Test that a syntax error caused by an unexpected EOF
// gives an error message with the correct line number.
//
-// https://code.google.com/p/go/issues/detail?id=3392
+// https://golang.org/issue/3392
package main
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug437.dir/one.go b/gcc/testsuite/go.test/test/fixedbugs/bug437.dir/one.go
index 8d3caad..633573e 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug437.dir/one.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug437.dir/one.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug437.dir/two.go b/gcc/testsuite/go.test/test/fixedbugs/bug437.dir/two.go
index 406dd59..61da121 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug437.dir/two.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug437.dir/two.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug437.dir/x.go b/gcc/testsuite/go.test/test/fixedbugs/bug437.dir/x.go
index 364d017..585b480 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug437.dir/x.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug437.dir/x.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug437.go b/gcc/testsuite/go.test/test/fixedbugs/bug437.go
index 5c4a2ad..98adce7 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug437.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug437.go
@@ -1,6 +1,6 @@
// rundir
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug441.go b/gcc/testsuite/go.test/test/fixedbugs/bug441.go
index 8562bfe..b67125b 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug441.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug441.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug442.go b/gcc/testsuite/go.test/test/fixedbugs/bug442.go
index 1d1a948..684d54f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug442.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug442.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug443.go b/gcc/testsuite/go.test/test/fixedbugs/bug443.go
index b67bd8c..9abd254 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug443.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug443.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug444.go b/gcc/testsuite/go.test/test/fixedbugs/bug444.go
index b54fb4f5..29a60f5 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug444.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug444.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug445.go b/gcc/testsuite/go.test/test/fixedbugs/bug445.go
index 497ecd3..45c3290 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug445.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug445.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug447.go b/gcc/testsuite/go.test/test/fixedbugs/bug447.go
index a4c871b..8358f00 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug447.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug447.go
@@ -1,6 +1,6 @@
// runoutput
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug448.dir/pkg1.go b/gcc/testsuite/go.test/test/fixedbugs/bug448.dir/pkg1.go
index 032e5d9..291903c 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug448.dir/pkg1.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug448.dir/pkg1.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug448.dir/pkg2.go b/gcc/testsuite/go.test/test/fixedbugs/bug448.dir/pkg2.go
index 5c78c7d..20d8509 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug448.dir/pkg2.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug448.dir/pkg2.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug448.go b/gcc/testsuite/go.test/test/fixedbugs/bug448.go
index 242f599..481acda 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug448.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug448.go
@@ -1,6 +1,6 @@
// compiledir
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug450.go b/gcc/testsuite/go.test/test/fixedbugs/bug450.go
index 3f13de1..af27b72 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug450.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug450.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug452.go b/gcc/testsuite/go.test/test/fixedbugs/bug452.go
index d2e4a0b..f1f8b08 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug452.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug452.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug453.go b/gcc/testsuite/go.test/test/fixedbugs/bug453.go
index 136abef..1f4f3ea 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug453.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug453.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug454.go b/gcc/testsuite/go.test/test/fixedbugs/bug454.go
index a10abba..9e3344d 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug454.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug454.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug455.go b/gcc/testsuite/go.test/test/fixedbugs/bug455.go
index 8e3c770..9f6974d 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug455.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug455.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug456.go b/gcc/testsuite/go.test/test/fixedbugs/bug456.go
index 064e1aa..c77a76d 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug456.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug456.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug457.go b/gcc/testsuite/go.test/test/fixedbugs/bug457.go
index ee70489..84f8db4 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug457.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug457.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug458.go b/gcc/testsuite/go.test/test/fixedbugs/bug458.go
index ddc97bd..6332697 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug458.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug458.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug459.go b/gcc/testsuite/go.test/test/fixedbugs/bug459.go
index 014f2ef..c71cb1b 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug459.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug459.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug460.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/bug460.dir/a.go
index 29049d9..51c6836 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug460.dir/a.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug460.dir/a.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug460.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/bug460.dir/b.go
index 5c0a0c4..ef64694 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug460.dir/b.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug460.dir/b.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug460.go b/gcc/testsuite/go.test/test/fixedbugs/bug460.go
index 79234a3..a1b6f47 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug460.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug460.go
@@ -1,6 +1,6 @@
// errorcheckdir
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug461.go b/gcc/testsuite/go.test/test/fixedbugs/bug461.go
index f0f7b0e..d7fe802 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug461.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug461.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug462.go b/gcc/testsuite/go.test/test/fixedbugs/bug462.go
index 1a23ad0..3df63b0 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug462.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug462.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug463.go b/gcc/testsuite/go.test/test/fixedbugs/bug463.go
index 3e7a184..c7f9237 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug463.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug463.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug464.go b/gcc/testsuite/go.test/test/fixedbugs/bug464.go
index 5821939..3e2c18a 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug464.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug464.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug465.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/bug465.dir/a.go
index a9a8614..3e5d012 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug465.dir/a.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug465.dir/a.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug465.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/bug465.dir/b.go
index c84c683..db7f731 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug465.dir/b.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug465.dir/b.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug465.go b/gcc/testsuite/go.test/test/fixedbugs/bug465.go
index a6ef587..84ff07b 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug465.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug465.go
@@ -1,6 +1,6 @@
// rundir
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug466.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/bug466.dir/a.go
index b9de63e..e27699c 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug466.dir/a.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug466.dir/a.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug466.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/bug466.dir/b.go
index 82d66ea..04e3626 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug466.dir/b.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug466.dir/b.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug466.go b/gcc/testsuite/go.test/test/fixedbugs/bug466.go
index 6b65b33..dc909d4 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug466.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug466.go
@@ -1,6 +1,6 @@
// rundir
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug467.go b/gcc/testsuite/go.test/test/fixedbugs/bug467.go
index d73adba..4126f92 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug467.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug467.go
@@ -1,6 +1,6 @@
// compiledir
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug468.dir/p1.go b/gcc/testsuite/go.test/test/fixedbugs/bug468.dir/p1.go
index ca17577..cdda735 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug468.dir/p1.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug468.dir/p1.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug468.dir/p2.go b/gcc/testsuite/go.test/test/fixedbugs/bug468.dir/p2.go
index 1793c0e..dbb4693 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug468.dir/p2.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug468.dir/p2.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug468.go b/gcc/testsuite/go.test/test/fixedbugs/bug468.go
index 12e4997..77941ce 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug468.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug468.go
@@ -1,6 +1,6 @@
// rundir
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug470.go b/gcc/testsuite/go.test/test/fixedbugs/bug470.go
index 0a35918..c21663f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug470.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug470.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug471.go b/gcc/testsuite/go.test/test/fixedbugs/bug471.go
index e454259..343661f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug471.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug471.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug472.dir/p1.go b/gcc/testsuite/go.test/test/fixedbugs/bug472.dir/p1.go
index 9d47fd8..cda1aa7 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug472.dir/p1.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug472.dir/p1.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug472.dir/p2.go b/gcc/testsuite/go.test/test/fixedbugs/bug472.dir/p2.go
index 34a3f04..581ec40 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug472.dir/p2.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug472.dir/p2.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug472.dir/z.go b/gcc/testsuite/go.test/test/fixedbugs/bug472.dir/z.go
index 6c29dd0..eb791bf 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug472.dir/z.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug472.dir/z.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug472.go b/gcc/testsuite/go.test/test/fixedbugs/bug472.go
index c79c64c..6939e64 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug472.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug472.go
@@ -1,6 +1,6 @@
// rundir
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug473.go b/gcc/testsuite/go.test/test/fixedbugs/bug473.go
index 49ce7d7..7649b6b 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug473.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug473.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug474.go b/gcc/testsuite/go.test/test/fixedbugs/bug474.go
index b826487..1efabe4 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug474.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug474.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug475.go b/gcc/testsuite/go.test/test/fixedbugs/bug475.go
index 1bd6fa3..0145aab 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug475.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug475.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug476.go b/gcc/testsuite/go.test/test/fixedbugs/bug476.go
index 4ea2174..8695f95 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug476.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug476.go
@@ -1,11 +1,11 @@
// compile
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Logical operation on named boolean type returns the same type,
-// supporting an implicit convertion to an interface type. This used
+// supporting an implicit conversion to an interface type. This used
// to crash gccgo.
package p
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug477.go b/gcc/testsuite/go.test/test/fixedbugs/bug477.go
index 86289af..f1fbffa 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug477.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug477.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug478.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/bug478.dir/a.go
index a40e454..b5a2dbc 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug478.dir/a.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug478.dir/a.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug478.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/bug478.dir/b.go
index c0fdf11..cfd1d27 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug478.dir/b.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug478.dir/b.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug478.go b/gcc/testsuite/go.test/test/fixedbugs/bug478.go
index 5e339e8..8757f46 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug478.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug478.go
@@ -1,6 +1,6 @@
// compiledir
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug479.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/bug479.dir/a.go
index 5ff3bef..eddb4cf 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug479.dir/a.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug479.dir/a.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug479.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/bug479.dir/b.go
index a1b27b3..9f3f5e8 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug479.dir/b.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug479.dir/b.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug479.go b/gcc/testsuite/go.test/test/fixedbugs/bug479.go
index f8a0f93..80012ba 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug479.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug479.go
@@ -1,6 +1,6 @@
// rundir
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug480.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/bug480.dir/a.go
index 6dff515..26a8d11 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug480.dir/a.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug480.dir/a.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug480.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/bug480.dir/b.go
index 6207365..5bd40f6 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug480.dir/b.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug480.dir/b.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug480.go b/gcc/testsuite/go.test/test/fixedbugs/bug480.go
index 5b44af4..ad2f73c 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug480.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug480.go
@@ -1,6 +1,6 @@
// compiledir
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug481.go b/gcc/testsuite/go.test/test/fixedbugs/bug481.go
index d0922a5..13a5339 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug481.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug481.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug482.go b/gcc/testsuite/go.test/test/fixedbugs/bug482.go
index 10c4828..0e5417d 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug482.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug482.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug487.go b/gcc/testsuite/go.test/test/fixedbugs/bug487.go
new file mode 100644
index 0000000..e60af6c
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug487.go
@@ -0,0 +1,24 @@
+// errorcheck
+
+// Copyright 2014 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.
+
+// The gccgo compiler did not reliably report mismatches between the
+// number of function results and the number of expected results.
+
+package p
+
+func G() (int, int, int) {
+ return 0, 0, 0
+}
+
+func F() {
+ a, b := G() // ERROR "mismatch"
+ a, b = G() // ERROR "mismatch"
+ _, _ = a, b
+}
+
+func H() (int, int) {
+ return G() // ERROR "too many|mismatch"
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug488.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/bug488.dir/a.go
new file mode 100644
index 0000000..fc49420
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug488.dir/a.go
@@ -0,0 +1,7 @@
+// Copyright 2014 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 a
+
+var p2 = Printf // ERROR "undefined"
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug488.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/bug488.dir/b.go
new file mode 100644
index 0000000..f93328c
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug488.dir/b.go
@@ -0,0 +1,9 @@
+// Copyright 2014 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 a
+
+import . "fmt"
+
+var p1 = Print
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug488.go b/gcc/testsuite/go.test/test/fixedbugs/bug488.go
new file mode 100644
index 0000000..3912deb
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug488.go
@@ -0,0 +1,12 @@
+// errorcheckdir
+
+// Copyright 2014 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.
+
+// The gccgo compiler had a bug: if one file in a package did a dot
+// import, then an earlier file in the package would incorrectly
+// resolve to the imported names rather than reporting undefined
+// errors.
+
+package ignored
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug489.go b/gcc/testsuite/go.test/test/fixedbugs/bug489.go
new file mode 100644
index 0000000..34250cd
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug489.go
@@ -0,0 +1,22 @@
+// compile
+
+// Copyright 2014 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.
+
+// The gccgo compiler had a bug: mentioning a function type in an
+// expression in a function literal messed up the list of variables
+// referenced in enclosing functions.
+
+package main
+
+func main() {
+ v1, v2 := 0, 0
+ f := func() {
+ a := v1
+ g := (func())(nil)
+ b := v2
+ _, _, _ = a, g, b
+ }
+ _, _, _ = v1, v2, f
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug492.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/bug492.dir/a.go
new file mode 100644
index 0000000..90917e5
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug492.dir/a.go
@@ -0,0 +1,16 @@
+// Copyright 2014 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 a
+
+type s struct {
+ s string
+}
+
+func F1(s s) {
+}
+
+func F2() s {
+ return s{""}
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug492.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/bug492.dir/b.go
new file mode 100644
index 0000000..5b8c4f2
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug492.dir/b.go
@@ -0,0 +1,11 @@
+// Copyright 2014 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 main
+
+import "./a"
+
+func main() {
+ defer a.F1(a.F2())
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug492.go b/gcc/testsuite/go.test/test/fixedbugs/bug492.go
new file mode 100644
index 0000000..050a9e5
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug492.go
@@ -0,0 +1,9 @@
+// rundir
+
+// Copyright 2014 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.
+
+// Test case that gccgo failed to link.
+
+package ignored
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug493.go b/gcc/testsuite/go.test/test/fixedbugs/bug493.go
new file mode 100644
index 0000000..643e9af
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug493.go
@@ -0,0 +1,15 @@
+// compile
+
+// Copyright 2014 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.
+
+// Test case that gccgo failed to compile.
+
+package p
+
+func F() []string {
+ return []string{""}
+}
+
+var V = append(F())
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug494.go b/gcc/testsuite/go.test/test/fixedbugs/bug494.go
new file mode 100644
index 0000000..42f1879
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug494.go
@@ -0,0 +1,51 @@
+// run
+
+// Copyright 2014 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.
+
+// Gccgo incorrectly executed functions multiple times when they
+// appeared in a composite literal that required a conversion between
+// different interface types.
+
+package main
+
+type MyInt int
+
+var c MyInt
+
+func (c *MyInt) S(i int) {
+ *c = MyInt(i)
+}
+
+func (c *MyInt) V() int {
+ return int(*c)
+}
+
+type i1 interface {
+ S(int)
+ V() int
+}
+
+type i2 interface {
+ V() int
+}
+
+type s struct {
+ i i2
+}
+
+func f() i1 {
+ c++
+ return &c
+}
+
+func main() {
+ p := &s{f()}
+ if v := p.i.V(); v != 1 {
+ panic(v)
+ }
+ if c != 1 {
+ panic(c)
+ }
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug496.go b/gcc/testsuite/go.test/test/fixedbugs/bug496.go
new file mode 100644
index 0000000..4307c75
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug496.go
@@ -0,0 +1,29 @@
+// compile
+
+// Copyright 2015 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.
+
+// Gccgo used to give an error:
+// <built-in>: error: redefinition of ‘s$F$hash’
+// <built-in>: note: previous definition of ‘s$F$hash’ was here
+// <built-in>: error: redefinition of ‘s$F$equal’
+// <built-in>: note: previous definition of ‘s$F$equal’ was here
+
+package p
+
+type T1 int
+
+func (t T1) F() {
+ type s struct {
+ f string
+ }
+}
+
+type T2 int
+
+func (t T2) F() {
+ type s struct {
+ f string
+ }
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug497.go b/gcc/testsuite/go.test/test/fixedbugs/bug497.go
new file mode 100644
index 0000000..7081b1c
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug497.go
@@ -0,0 +1,28 @@
+// run
+
+// Copyright 2015 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.
+
+// Gccgo used to miscompile passing a global variable with a
+// zero-sized type to a function.
+
+package main
+
+type T struct {
+ field s
+}
+
+type s struct{}
+
+var X T
+
+func F(_ T, c interface{}) int {
+ return len(c.(string))
+}
+
+func main() {
+ if v := F(X, "hi"); v != 2 {
+ panic(v)
+ }
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug499.go b/gcc/testsuite/go.test/test/fixedbugs/bug499.go
new file mode 100644
index 0000000..e4142e93
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug499.go
@@ -0,0 +1,15 @@
+// run
+
+// Copyright 2016 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.
+
+// Gccgo got confused when a type was used both for a map bucket type
+// and for a map key type.
+
+package main
+
+func main() {
+ _ = make(map[byte]byte)
+ _ = make(map[[8]byte]chan struct{})
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug500.go b/gcc/testsuite/go.test/test/fixedbugs/bug500.go
new file mode 100644
index 0000000..2dd5df1
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug500.go
@@ -0,0 +1,41 @@
+// run
+
+// Copyright 2016 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.
+
+// Gccgo generated incorrect GC info when a global variable was
+// initialized to a slice of a value containing pointers. The initial
+// backing array for the slice was allocated in the .data section,
+// which is fine, but the backing array was not registered as a GC
+// root.
+
+package main
+
+import (
+ "runtime"
+)
+
+type s struct {
+ str string
+}
+
+var a = []struct {
+ str string
+}{
+ {""},
+}
+
+var b = "b"
+var c = "c"
+
+func init() {
+ a[0].str = b + c
+}
+
+func main() {
+ runtime.GC()
+ if a[0].str != b + c {
+ panic(a[0].str)
+ }
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug501.go b/gcc/testsuite/go.test/test/fixedbugs/bug501.go
new file mode 100644
index 0000000..8e951b1
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug501.go
@@ -0,0 +1,24 @@
+// run
+
+// Copyright 2016 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.
+
+// Gccgo got a compiler crash compiling the addition of more than five
+// strings with mixed constants and variables.
+
+package main
+
+func F(s string) (string, error) {
+ return s, nil
+}
+
+func G(a, b, c string) (string, error) {
+ return F("a" + a + "b" + b + "c" + c)
+}
+
+func main() {
+ if got, _ := G("x", "y", "z"); got != "axbycz" {
+ panic(got)
+ }
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug502.go b/gcc/testsuite/go.test/test/fixedbugs/bug502.go
new file mode 100644
index 0000000..cff73e7
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug502.go
@@ -0,0 +1,28 @@
+// build
+
+// Copyright 2017 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.
+
+// Linking this with gccgo got an undefined symbol reference,
+// because the private method in testing.TB led gccgo to assume that
+// the interface method table would be defined in the testing package.
+
+package main
+
+import "testing"
+
+type I interface {
+ testing.TB
+ Parallel()
+}
+
+func F(i I) {
+ i.Log("F")
+}
+
+var t testing.T
+
+func main() {
+ F(&t)
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug503.go b/gcc/testsuite/go.test/test/fixedbugs/bug503.go
new file mode 100644
index 0000000..7bbc798
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug503.go
@@ -0,0 +1,16 @@
+// compile
+
+// Copyright 2017 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.
+
+// gccgo crashed compiling this file, due to failing to correctly emit
+// the type descriptor for a named alias.
+
+package p
+
+type entry = struct {
+ a, b, c int
+}
+
+var V entry
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug504.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/bug504.dir/a.go
new file mode 100644
index 0000000..ac0be93
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug504.dir/a.go
@@ -0,0 +1,7 @@
+// Copyright 2017 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 a
+
+type MyInt = int
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug504.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/bug504.dir/b.go
new file mode 100644
index 0000000..e8f8da9
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug504.dir/b.go
@@ -0,0 +1,11 @@
+// Copyright 2017 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 b
+
+import "./a"
+
+func F() a.MyInt {
+ return 0
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug504.dir/c.go b/gcc/testsuite/go.test/test/fixedbugs/bug504.dir/c.go
new file mode 100644
index 0000000..5a6e889
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug504.dir/c.go
@@ -0,0 +1,9 @@
+// Copyright 2017 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 c
+
+import "./b"
+
+var V = b.F()
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug504.dir/main.go b/gcc/testsuite/go.test/test/fixedbugs/bug504.dir/main.go
new file mode 100644
index 0000000..bdbd95c
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug504.dir/main.go
@@ -0,0 +1,11 @@
+// Copyright 2017 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 main
+
+import "./c"
+
+func main() {
+ println(c.V)
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug504.go b/gcc/testsuite/go.test/test/fixedbugs/bug504.go
new file mode 100644
index 0000000..ae1f2e5
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug504.go
@@ -0,0 +1,10 @@
+// compiledir
+
+// Copyright 2017 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.
+
+// Gccgo mishandled a reference to a type alias in a package that was
+// not directly imported.
+
+package ignored
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug505.go b/gcc/testsuite/go.test/test/fixedbugs/bug505.go
new file mode 100644
index 0000000..062a087
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug505.go
@@ -0,0 +1,20 @@
+// compile
+
+// Copyright 2017 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.
+
+// gccgo crashed compiling this file with a failed conversion to the
+// alias type when constructing the composite literal.
+
+package p
+
+type I interface{ M() }
+type A = I
+type S struct {
+ f A
+}
+
+func F(i I) S {
+ return S{f: i}
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug506.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/bug506.dir/a.go
new file mode 100644
index 0000000..8e8a200
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug506.dir/a.go
@@ -0,0 +1,16 @@
+// Copyright 2018 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 a
+
+type internal struct {
+ f1 string
+ f2 float64
+}
+
+type S struct {
+ F struct {
+ I internal
+ }
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug506.dir/main.go b/gcc/testsuite/go.test/test/fixedbugs/bug506.dir/main.go
new file mode 100644
index 0000000..1b60e40
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug506.dir/main.go
@@ -0,0 +1,20 @@
+// Copyright 2018 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 main
+
+import (
+ "fmt"
+
+ "./a"
+)
+
+var v = a.S{}
+
+func main() {
+ want := "{{ 0}}"
+ if got := fmt.Sprint(v.F); got != want {
+ panic(got)
+ }
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug506.go b/gcc/testsuite/go.test/test/fixedbugs/bug506.go
new file mode 100644
index 0000000..7c8ccc6
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug506.go
@@ -0,0 +1,10 @@
+// rundir
+
+// Copyright 2018 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.
+
+// Gccgo caused an undefined symbol reference building hash functions
+// for an imported struct with unexported fields.
+
+package ignored
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug507.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/bug507.dir/a.go
new file mode 100644
index 0000000..0929adc
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug507.dir/a.go
@@ -0,0 +1,13 @@
+// Copyright 2020 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 a
+
+type I interface {
+ M()
+}
+
+type S struct {
+ I I
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug507.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/bug507.dir/b.go
new file mode 100644
index 0000000..bddce2d
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug507.dir/b.go
@@ -0,0 +1,9 @@
+// Copyright 2020 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 b
+
+import . "./a"
+
+var V2 I
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug507.dir/c.go b/gcc/testsuite/go.test/test/fixedbugs/bug507.dir/c.go
new file mode 100644
index 0000000..e67f0fd
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug507.dir/c.go
@@ -0,0 +1,9 @@
+// Copyright 2020 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 b
+
+import "./a"
+
+var V1 = a.S{I: nil}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug507.go b/gcc/testsuite/go.test/test/fixedbugs/bug507.go
new file mode 100644
index 0000000..2d7aa59
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug507.go
@@ -0,0 +1,9 @@
+// compiledir
+
+// Copyright 2020 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.
+
+// Gccgo mishandled a combination of normal import and dot import.
+
+package ignored
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug508.go b/gcc/testsuite/go.test/test/fixedbugs/bug508.go
new file mode 100644
index 0000000..69b1ada
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug508.go
@@ -0,0 +1,14 @@
+// compile
+
+// Copyright 2020 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.
+
+// Gccgo mishandles composite literals of map with type bool.
+
+package p
+
+var M = map[bool]uint8{
+ false: 0,
+ true: 1,
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug509.go b/gcc/testsuite/go.test/test/fixedbugs/bug509.go
new file mode 100644
index 0000000..df6ed61
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug509.go
@@ -0,0 +1,30 @@
+// compile
+
+// Copyright 2020 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.
+
+// Gccgo mishandles a couple of alias cases.
+
+package p
+
+type S struct{}
+
+func (*S) M() {}
+
+type I interface {
+ M()
+}
+
+type A = *S
+
+var V1 I
+var _ = V1.(*S)
+var _ = V1.(A)
+
+func F() {
+ var v I
+ v = (*S)(nil)
+ v = A(nil)
+ _ = v
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/gcc67968.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/gcc67968.dir/a.go
new file mode 100644
index 0000000..9f51a7a
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/gcc67968.dir/a.go
@@ -0,0 +1,12 @@
+// Copyright 2015 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 a
+
+type T int
+
+func (a *T) Foo() [1]string {
+ var r [1]string
+ return r
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/gcc67968.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/gcc67968.dir/b.go
new file mode 100644
index 0000000..41b62d2
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/gcc67968.dir/b.go
@@ -0,0 +1,12 @@
+// Copyright 2015 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 b
+
+import "./a"
+
+func F() (interface{}) {
+ var v *a.T
+ return v.Foo()
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/gcc67968.go b/gcc/testsuite/go.test/test/fixedbugs/gcc67968.go
new file mode 100644
index 0000000..8db3dd8
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/gcc67968.go
@@ -0,0 +1,14 @@
+// compiledir
+
+// Copyright 2015 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.
+
+// https://gcc.gnu.org/PR67968
+
+// gccgo compiler crash building the equality and hash functions for a
+// type when a return statement requires a conversion to interface
+// type of a call of function defined in a different package that
+// returns an unnamed type.
+
+package ignored
diff --git a/gcc/testsuite/go.test/test/fixedbugs/gcc78763.go b/gcc/testsuite/go.test/test/fixedbugs/gcc78763.go
new file mode 100644
index 0000000..3e34127
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/gcc78763.go
@@ -0,0 +1,19 @@
+// compile
+
+// Copyright 2016 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.
+
+// The gccgo compiler crashed while compiling this code.
+// https://gcc.gnu.org/PR78763.
+
+package p
+
+import "unsafe"
+
+func F() int {
+ if unsafe.Sizeof(0) == 8 {
+ return 8
+ }
+ return 0
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/gcc80226.go b/gcc/testsuite/go.test/test/fixedbugs/gcc80226.go
new file mode 100644
index 0000000..530b397
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/gcc80226.go
@@ -0,0 +1,17 @@
+// compile
+
+// Copyright 2017 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.
+
+// The gccgo compiler crashed while compiling a function that returned
+// multiple zero-sized structs.
+// https://gcc.gnu.org/PR80226.
+
+package p
+
+type S struct{}
+
+func F() (S, S) {
+ return S{}, S{}
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/gcc89321.go b/gcc/testsuite/go.test/test/fixedbugs/gcc89321.go
new file mode 100644
index 0000000..93ca6b4
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/gcc89321.go
@@ -0,0 +1,17 @@
+// compile
+
+// 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.
+
+// https://gcc.gnu.org/PR89321
+// gccgo compiler crash building map literals with a zero-sized value type.
+
+package p
+
+type M map[byte]struct{}
+
+var (
+ M1 = M{1: {}, 2: {}, 3: {}}
+ M2 = M{1: {}, 2: {}}
+)
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue12621.go b/gcc/testsuite/go.test/test/fixedbugs/issue12621.go
new file mode 100644
index 0000000..379a362
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue12621.go
@@ -0,0 +1,20 @@
+// run
+
+// Copyright 2018 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.
+
+// Issues 12576 and 12621: Negative untyped floating point constants
+// with small magnitude round to 0, not negative zero.
+
+package main
+
+import "math"
+
+var m = -1e-10000
+
+func main() {
+ if math.Signbit(m) {
+ panic(m)
+ }
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue14540.go b/gcc/testsuite/go.test/test/fixedbugs/issue14540.go
new file mode 100644
index 0000000..62b17a0
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue14540.go
@@ -0,0 +1,20 @@
+// errorcheck
+
+// Copyright 2017 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 p
+
+func f(x int) {
+ switch x {
+ case 0:
+ fallthrough
+ ; // ok
+ case 1:
+ fallthrough // ERROR "fallthrough statement out of place"
+ {}
+ case 2:
+ fallthrough // ERROR "cannot fallthrough"
+ }
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue15002.go b/gcc/testsuite/go.test/test/fixedbugs/issue15002.go
new file mode 100644
index 0000000..936105e
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue15002.go
@@ -0,0 +1,132 @@
+// run
+// +build amd64
+// +build linux darwin
+
+// Copyright 2016 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 main
+
+import (
+ "fmt"
+ "syscall"
+)
+
+// Use global variables so the compiler
+// doesn't know that they are constants.
+var p = syscall.Getpagesize()
+var zero = 0
+var one = 1
+
+func main() {
+ // Allocate 2 pages of memory.
+ b, err := syscall.Mmap(-1, 0, 2*p, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_ANON|syscall.MAP_PRIVATE)
+ if err != nil {
+ panic(err)
+ }
+ // Mark the second page as faulting.
+ err = syscall.Mprotect(b[p:], syscall.PROT_NONE)
+ if err != nil {
+ panic(err)
+ }
+ // Get a slice pointing to the last byte of the good page.
+ x := b[p-one : p]
+
+ test16(x)
+ test16i(x, 0)
+ test32(x)
+ test32i(x, 0)
+ test64(x)
+ test64i(x, 0)
+}
+
+func test16(x []byte) uint16 {
+ defer func() {
+ r := recover()
+ if r == nil {
+ panic("no fault or bounds check failure happened")
+ }
+ s := fmt.Sprintf("%s", r)
+ if s != "runtime error: index out of range [1] with length 1" {
+ panic("bad panic: " + s)
+ }
+ }()
+ // Try to read 2 bytes from x.
+ return uint16(x[0]) | uint16(x[1])<<8
+
+ // We expect to get an "index out of range" error from x[1].
+ // If we promote the first load to a 2-byte load, it will segfault, which we don't want.
+}
+
+func test16i(x []byte, i int) uint16 {
+ defer func() {
+ r := recover()
+ if r == nil {
+ panic("no fault or bounds check failure happened")
+ }
+ s := fmt.Sprintf("%s", r)
+ if s != "runtime error: index out of range [1] with length 1" {
+ panic("bad panic: " + s)
+ }
+ }()
+ return uint16(x[i]) | uint16(x[i+1])<<8
+}
+
+func test32(x []byte) uint32 {
+ defer func() {
+ r := recover()
+ if r == nil {
+ panic("no fault or bounds check failure happened")
+ }
+ s := fmt.Sprintf("%s", r)
+ if s != "runtime error: index out of range [1] with length 1" {
+ panic("bad panic: " + s)
+ }
+ }()
+ return uint32(x[0]) | uint32(x[1])<<8 | uint32(x[2])<<16 | uint32(x[3])<<24
+}
+
+func test32i(x []byte, i int) uint32 {
+ defer func() {
+ r := recover()
+ if r == nil {
+ panic("no fault or bounds check failure happened")
+ }
+ s := fmt.Sprintf("%s", r)
+ if s != "runtime error: index out of range [1] with length 1" {
+ panic("bad panic: " + s)
+ }
+ }()
+ return uint32(x[i]) | uint32(x[i+1])<<8 | uint32(x[i+2])<<16 | uint32(x[i+3])<<24
+}
+
+func test64(x []byte) uint64 {
+ defer func() {
+ r := recover()
+ if r == nil {
+ panic("no fault or bounds check failure happened")
+ }
+ s := fmt.Sprintf("%s", r)
+ if s != "runtime error: index out of range [1] with length 1" {
+ panic("bad panic: " + s)
+ }
+ }()
+ return uint64(x[0]) | uint64(x[1])<<8 | uint64(x[2])<<16 | uint64(x[3])<<24 |
+ uint64(x[4])<<32 | uint64(x[5])<<40 | uint64(x[6])<<48 | uint64(x[7])<<56
+}
+
+func test64i(x []byte, i int) uint64 {
+ defer func() {
+ r := recover()
+ if r == nil {
+ panic("no fault or bounds check failure happened")
+ }
+ s := fmt.Sprintf("%s", r)
+ if s != "runtime error: index out of range [1] with length 1" {
+ panic("bad panic: " + s)
+ }
+ }()
+ return uint64(x[i+0]) | uint64(x[i+1])<<8 | uint64(x[i+2])<<16 | uint64(x[i+3])<<24 |
+ uint64(x[i+4])<<32 | uint64(x[i+5])<<40 | uint64(x[i+6])<<48 | uint64(x[i+7])<<56
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue16949.go b/gcc/testsuite/go.test/test/fixedbugs/issue16949.go
new file mode 100644
index 0000000..9ee3387
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue16949.go
@@ -0,0 +1,30 @@
+// errorcheck
+
+// Copyright 2016 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.
+
+// Ensure that typed non-integer len and cap make arguments are not accepted.
+
+package main
+
+var sink []byte
+
+func main() {
+ sink = make([]byte, 1.0)
+ sink = make([]byte, float32(1.0)) // ERROR "non-integer.*len"
+ sink = make([]byte, float64(1.0)) // ERROR "non-integer.*len"
+
+ sink = make([]byte, 0, 1.0)
+ sink = make([]byte, 0, float32(1.0)) // ERROR "non-integer.*cap"
+ sink = make([]byte, 0, float64(1.0)) // ERROR "non-integer.*cap"
+
+ sink = make([]byte, 1+0i)
+ sink = make([]byte, complex64(1+0i)) // ERROR "non-integer.*len"
+ sink = make([]byte, complex128(1+0i)) // ERROR "non-integer.*len"
+
+ sink = make([]byte, 0, 1+0i)
+ sink = make([]byte, 0, complex64(1+0i)) // ERROR "non-integer.*cap"
+ sink = make([]byte, 0, complex128(1+0i)) // ERROR "non-integer.*cap"
+
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue19113.go b/gcc/testsuite/go.test/test/fixedbugs/issue19113.go
new file mode 100644
index 0000000..5e01dde
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue19113.go
@@ -0,0 +1,108 @@
+// run
+
+// 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 main
+
+import "reflect"
+
+var tests = []interface{}{
+ func(x int, s int) int {
+ return x << s
+ },
+ func(x int, s int64) int {
+ return x << s
+ },
+ func(x int, s int32) int {
+ return x << s
+ },
+ func(x int, s int16) int {
+ return x << s
+ },
+ func(x int, s int8) int {
+ return x << s
+ },
+ func(x int, s int) int {
+ return x >> s
+ },
+ func(x int, s int64) int {
+ return x >> s
+ },
+ func(x int, s int32) int {
+ return x >> s
+ },
+ func(x int, s int16) int {
+ return x >> s
+ },
+ func(x int, s int8) int {
+ return x >> s
+ },
+ func(x uint, s int) uint {
+ return x << s
+ },
+ func(x uint, s int64) uint {
+ return x << s
+ },
+ func(x uint, s int32) uint {
+ return x << s
+ },
+ func(x uint, s int16) uint {
+ return x << s
+ },
+ func(x uint, s int8) uint {
+ return x << s
+ },
+ func(x uint, s int) uint {
+ return x >> s
+ },
+ func(x uint, s int64) uint {
+ return x >> s
+ },
+ func(x uint, s int32) uint {
+ return x >> s
+ },
+ func(x uint, s int16) uint {
+ return x >> s
+ },
+ func(x uint, s int8) uint {
+ return x >> s
+ },
+}
+
+func main() {
+ for _, t := range tests {
+ runTest(reflect.ValueOf(t))
+ }
+}
+
+func runTest(f reflect.Value) {
+ xt := f.Type().In(0)
+ st := f.Type().In(1)
+
+ for _, x := range []int{1, 0, -1} {
+ for _, s := range []int{-99, -64, -63, -32, -31, -16, -15, -8, -7, -1, 0, 1, 7, 8, 15, 16, 31, 32, 63, 64, 99} {
+ args := []reflect.Value{
+ reflect.ValueOf(x).Convert(xt),
+ reflect.ValueOf(s).Convert(st),
+ }
+ if s < 0 {
+ shouldPanic(func() {
+ f.Call(args)
+ })
+ } else {
+ f.Call(args) // should not panic
+ }
+ }
+ }
+}
+
+func shouldPanic(f func()) {
+ defer func() {
+ if recover() == nil {
+ panic("did not panic")
+ }
+ }()
+ f()
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue20923.go b/gcc/testsuite/go.test/test/fixedbugs/issue20923.go
new file mode 100644
index 0000000..5fd1ad8
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue20923.go
@@ -0,0 +1,19 @@
+// compile
+
+// Copyright 2018 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.
+
+// Issue 20923: gccgo failed to compile parenthesized select case expressions.
+
+package p
+
+func F(c chan bool) {
+ select {
+ case (<-c):
+ case _ = (<-c):
+ case _, _ = (<-c):
+ case (c) <- true:
+ default:
+ }
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue21253.go b/gcc/testsuite/go.test/test/fixedbugs/issue21253.go
new file mode 100644
index 0000000..3531b2b
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue21253.go
@@ -0,0 +1,27 @@
+// compile
+
+// Copyright 2017 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.
+
+// Gccgo crashed compiling this code due to failing to finalize
+// interfaces in the right order.
+
+package p
+
+type s1 struct {
+ f m
+ I
+}
+
+type m interface {
+ Mm(*s2)
+}
+
+type s2 struct {
+ *s1
+}
+
+type I interface {
+ MI()
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue22305.go b/gcc/testsuite/go.test/test/fixedbugs/issue22305.go
new file mode 100644
index 0000000..ec432f9
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue22305.go
@@ -0,0 +1,15 @@
+// compile
+
+// Copyright 2017 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.
+
+// Issue 22305: gccgo failed to compile this file.
+
+package main
+
+var F func() [0]func()
+var i = 2
+var B = F()[i]
+
+func main() {}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue23188.go b/gcc/testsuite/go.test/test/fixedbugs/issue23188.go
new file mode 100644
index 0000000..c224340
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue23188.go
@@ -0,0 +1,32 @@
+// run
+
+// Copyright 2018 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.
+
+// Test order of evaluation of index operations.
+
+package main
+
+func main() {
+ arr := []int{1, 2}
+
+ // The spec says that in an assignment statement the operands
+ // of all index expressions and pointer indirections on the
+ // left, and the expressions on the right, are evaluated in
+ // the usual order. The usual order means function calls and
+ // channel operations are done first. Then the assignments are
+ // carried out one at a time. The operands of an index
+ // expression include both the array and the index. So this
+ // evaluates as
+ // tmp1 := arr
+ // tmp2 := len(arr) - 1
+ // tmp3 := len(arr)
+ // arr = arr[:tmp3-1]
+ // tmp1[tmp2] = 3
+ arr, arr[len(arr)-1] = arr[:len(arr)-1], 3
+
+ if len(arr) != 1 || arr[0] != 1 || arr[:2][1] != 3 {
+ panic(arr)
+ }
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue23489.go b/gcc/testsuite/go.test/test/fixedbugs/issue23489.go
new file mode 100644
index 0000000..1e64af1
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue23489.go
@@ -0,0 +1,20 @@
+// run
+
+// Copyright 2017 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.
+
+// Caused gccgo to issue a spurious compilation error.
+
+package main
+
+type T struct{}
+
+func (*T) Foo() {}
+
+type P = *T
+
+func main() {
+ var p P
+ p.Foo()
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue23912.go b/gcc/testsuite/go.test/test/fixedbugs/issue23912.go
new file mode 100644
index 0000000..05ffd6b
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue23912.go
@@ -0,0 +1,30 @@
+// compile
+
+// Copyright 2018 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.
+
+// A couple of aliases cases that gccgo incorrectly gave errors for.
+
+package p
+
+func F1() {
+ type E = struct{}
+ type X struct{}
+ var x X
+ var y E = x
+ _ = y
+}
+
+func F2() {
+ type E = struct{}
+ type S []E
+ type T []struct{}
+ type X struct{}
+ var x X
+ s := S{E{}}
+ t := T{struct{}{}}
+ _ = append(s, x)
+ _ = append(s, t[0])
+ _ = append(s, t...)
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue2615.go b/gcc/testsuite/go.test/test/fixedbugs/issue2615.go
index 686e1e1..831110e 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue2615.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue2615.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue26335.go b/gcc/testsuite/go.test/test/fixedbugs/issue26335.go
new file mode 100644
index 0000000..a97b4b6
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue26335.go
@@ -0,0 +1,32 @@
+// run
+
+// Copyright 2018 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.
+
+// gccgo mishandled passing a struct with an empty field through
+// reflect.Value.Call.
+
+package main
+
+import (
+ "reflect"
+)
+
+type Empty struct {
+ f1, f2 *byte
+ empty struct{}
+}
+
+func F(e Empty, s []string) {
+ if len(s) != 1 || s[0] != "hi" {
+ panic("bad slice")
+ }
+}
+
+func main() {
+ reflect.ValueOf(F).Call([]reflect.Value{
+ reflect.ValueOf(Empty{}),
+ reflect.ValueOf([]string{"hi"}),
+ })
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue26340.go b/gcc/testsuite/go.test/test/fixedbugs/issue26340.go
new file mode 100644
index 0000000..f973ce2
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue26340.go
@@ -0,0 +1,21 @@
+// compile
+
+// Copyright 2018 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.
+
+// gccgo did not permit omitting the type of a composite literal
+// element when one of the middle omitted types was a pointer type.
+
+package p
+
+type S []T
+type T struct { x int }
+
+var _ = map[string]*S{
+ "a": {
+ { 1 },
+ },
+}
+
+var _ = [1]*S{ { {1}, } }
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue28601.go b/gcc/testsuite/go.test/test/fixedbugs/issue28601.go
new file mode 100644
index 0000000..ec367e9
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue28601.go
@@ -0,0 +1,15 @@
+// compile
+
+// Copyright 2018 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.
+
+// Failed to compile with gccgo.
+
+package p
+
+import "unsafe"
+
+const w int = int(unsafe.Sizeof(0))
+
+var a [w]byte
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue30116.go b/gcc/testsuite/go.test/test/fixedbugs/issue30116.go
new file mode 100644
index 0000000..452a6e3
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue30116.go
@@ -0,0 +1,112 @@
+// run
+
+// 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.
+
+// This test makes sure the text output for bounds check failures is as expected.
+
+package main
+
+import (
+ "fmt"
+ "os"
+ "runtime"
+ "text/tabwriter"
+)
+
+// Testing with length 3 slices, arrays, and strings.
+// Large (>1<<32) values are included to test 32-bit platforms.
+var indexes = []int64{-9876543210, -1, 0, 2, 3, 9876543210}
+var slices = []int64{-9876543210, -1, 0, 3, 4, 9876543210}
+
+var w *tabwriter.Writer
+
+func main() {
+ w = tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', tabwriter.AlignRight)
+ defer w.Flush()
+ doIndex()
+ doSlice()
+ doSlice3()
+}
+func doIndex() {
+ a := []int{1, 2, 3}
+ for _, i := range indexes {
+ printPanic(fmt.Sprintf("slice[%d]", i), func() {
+ _ = a[i]
+ })
+ }
+ b := [3]int{1, 2, 3}
+ for _, i := range indexes {
+ printPanic(fmt.Sprintf("array[%d]", i), func() {
+ _ = b[i]
+ })
+ }
+ c := "123"
+ for _, i := range indexes {
+ printPanic(fmt.Sprintf("string[%d]", i), func() {
+ _ = c[i]
+ })
+ }
+}
+
+func doSlice() {
+ a := []int{1, 2, 3}
+ for _, i := range slices {
+ for _, j := range slices {
+ printPanic(fmt.Sprintf("slice[%d:%d]", i, j), func() {
+ _ = a[i:j]
+ })
+ }
+ }
+ b := [3]int{1, 2, 3}
+ for _, i := range slices {
+ for _, j := range slices {
+ printPanic(fmt.Sprintf("array[%d:%d]", i, j), func() {
+ _ = b[i:j]
+ })
+ }
+ }
+ c := "123"
+ for _, i := range slices {
+ for _, j := range slices {
+ printPanic(fmt.Sprintf("string[%d:%d]", i, j), func() {
+ _ = c[i:j]
+ })
+ }
+ }
+}
+
+func doSlice3() {
+ a := []int{1, 2, 3}
+ for _, i := range slices {
+ for _, j := range slices {
+ for _, k := range slices {
+ printPanic(fmt.Sprintf("slice[%d:%d:%d]", i, j, k), func() {
+ _ = a[i:j:k]
+ })
+ }
+ }
+ }
+ b := [3]int{1, 2, 3}
+ for _, i := range slices {
+ for _, j := range slices {
+ for _, k := range slices {
+ printPanic(fmt.Sprintf("array[%d:%d:%d]", i, j, k), func() {
+ _ = b[i:j:k]
+ })
+ }
+ }
+ }
+}
+
+func printPanic(msg string, f func()) {
+ defer func() {
+ res := "no panic"
+ if e := recover(); e != nil {
+ res = e.(runtime.Error).Error()
+ }
+ fmt.Fprintf(w, "%s\t %s\n", msg, res)
+ }()
+ f()
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue30116.out b/gcc/testsuite/go.test/test/fixedbugs/issue30116.out
new file mode 100644
index 0000000..bde134d
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue30116.out
@@ -0,0 +1,558 @@
+ slice[-9876543210] runtime error: index out of range [-9876543210]
+ slice[-1] runtime error: index out of range [-1]
+ slice[0] no panic
+ slice[2] no panic
+ slice[3] runtime error: index out of range [3] with length 3
+ slice[9876543210] runtime error: index out of range [9876543210] with length 3
+ array[-9876543210] runtime error: index out of range [-9876543210]
+ array[-1] runtime error: index out of range [-1]
+ array[0] no panic
+ array[2] no panic
+ array[3] runtime error: index out of range [3] with length 3
+ array[9876543210] runtime error: index out of range [9876543210] with length 3
+ string[-9876543210] runtime error: index out of range [-9876543210]
+ string[-1] runtime error: index out of range [-1]
+ string[0] no panic
+ string[2] no panic
+ string[3] runtime error: index out of range [3] with length 3
+ string[9876543210] runtime error: index out of range [9876543210] with length 3
+ slice[-9876543210:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+ slice[-9876543210:-1] runtime error: slice bounds out of range [:-1]
+ slice[-9876543210:0] runtime error: slice bounds out of range [-9876543210:]
+ slice[-9876543210:3] runtime error: slice bounds out of range [-9876543210:]
+ slice[-9876543210:4] runtime error: slice bounds out of range [:4] with capacity 3
+ slice[-9876543210:9876543210] runtime error: slice bounds out of range [:9876543210] with capacity 3
+ slice[-1:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+ slice[-1:-1] runtime error: slice bounds out of range [:-1]
+ slice[-1:0] runtime error: slice bounds out of range [-1:]
+ slice[-1:3] runtime error: slice bounds out of range [-1:]
+ slice[-1:4] runtime error: slice bounds out of range [:4] with capacity 3
+ slice[-1:9876543210] runtime error: slice bounds out of range [:9876543210] with capacity 3
+ slice[0:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+ slice[0:-1] runtime error: slice bounds out of range [:-1]
+ slice[0:0] no panic
+ slice[0:3] no panic
+ slice[0:4] runtime error: slice bounds out of range [:4] with capacity 3
+ slice[0:9876543210] runtime error: slice bounds out of range [:9876543210] with capacity 3
+ slice[3:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+ slice[3:-1] runtime error: slice bounds out of range [:-1]
+ slice[3:0] runtime error: slice bounds out of range [3:0]
+ slice[3:3] no panic
+ slice[3:4] runtime error: slice bounds out of range [:4] with capacity 3
+ slice[3:9876543210] runtime error: slice bounds out of range [:9876543210] with capacity 3
+ slice[4:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+ slice[4:-1] runtime error: slice bounds out of range [:-1]
+ slice[4:0] runtime error: slice bounds out of range [4:0]
+ slice[4:3] runtime error: slice bounds out of range [4:3]
+ slice[4:4] runtime error: slice bounds out of range [:4] with capacity 3
+ slice[4:9876543210] runtime error: slice bounds out of range [:9876543210] with capacity 3
+ slice[9876543210:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+ slice[9876543210:-1] runtime error: slice bounds out of range [:-1]
+ slice[9876543210:0] runtime error: slice bounds out of range [9876543210:0]
+ slice[9876543210:3] runtime error: slice bounds out of range [9876543210:3]
+ slice[9876543210:4] runtime error: slice bounds out of range [:4] with capacity 3
+ slice[9876543210:9876543210] runtime error: slice bounds out of range [:9876543210] with capacity 3
+ array[-9876543210:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+ array[-9876543210:-1] runtime error: slice bounds out of range [:-1]
+ array[-9876543210:0] runtime error: slice bounds out of range [-9876543210:]
+ array[-9876543210:3] runtime error: slice bounds out of range [-9876543210:]
+ array[-9876543210:4] runtime error: slice bounds out of range [:4] with length 3
+ array[-9876543210:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+ array[-1:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+ array[-1:-1] runtime error: slice bounds out of range [:-1]
+ array[-1:0] runtime error: slice bounds out of range [-1:]
+ array[-1:3] runtime error: slice bounds out of range [-1:]
+ array[-1:4] runtime error: slice bounds out of range [:4] with length 3
+ array[-1:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+ array[0:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+ array[0:-1] runtime error: slice bounds out of range [:-1]
+ array[0:0] no panic
+ array[0:3] no panic
+ array[0:4] runtime error: slice bounds out of range [:4] with length 3
+ array[0:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+ array[3:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+ array[3:-1] runtime error: slice bounds out of range [:-1]
+ array[3:0] runtime error: slice bounds out of range [3:0]
+ array[3:3] no panic
+ array[3:4] runtime error: slice bounds out of range [:4] with length 3
+ array[3:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+ array[4:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+ array[4:-1] runtime error: slice bounds out of range [:-1]
+ array[4:0] runtime error: slice bounds out of range [4:0]
+ array[4:3] runtime error: slice bounds out of range [4:3]
+ array[4:4] runtime error: slice bounds out of range [:4] with length 3
+ array[4:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+ array[9876543210:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+ array[9876543210:-1] runtime error: slice bounds out of range [:-1]
+ array[9876543210:0] runtime error: slice bounds out of range [9876543210:0]
+ array[9876543210:3] runtime error: slice bounds out of range [9876543210:3]
+ array[9876543210:4] runtime error: slice bounds out of range [:4] with length 3
+ array[9876543210:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+ string[-9876543210:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+ string[-9876543210:-1] runtime error: slice bounds out of range [:-1]
+ string[-9876543210:0] runtime error: slice bounds out of range [-9876543210:]
+ string[-9876543210:3] runtime error: slice bounds out of range [-9876543210:]
+ string[-9876543210:4] runtime error: slice bounds out of range [:4] with length 3
+ string[-9876543210:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+ string[-1:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+ string[-1:-1] runtime error: slice bounds out of range [:-1]
+ string[-1:0] runtime error: slice bounds out of range [-1:]
+ string[-1:3] runtime error: slice bounds out of range [-1:]
+ string[-1:4] runtime error: slice bounds out of range [:4] with length 3
+ string[-1:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+ string[0:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+ string[0:-1] runtime error: slice bounds out of range [:-1]
+ string[0:0] no panic
+ string[0:3] no panic
+ string[0:4] runtime error: slice bounds out of range [:4] with length 3
+ string[0:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+ string[3:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+ string[3:-1] runtime error: slice bounds out of range [:-1]
+ string[3:0] runtime error: slice bounds out of range [3:0]
+ string[3:3] no panic
+ string[3:4] runtime error: slice bounds out of range [:4] with length 3
+ string[3:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+ string[4:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+ string[4:-1] runtime error: slice bounds out of range [:-1]
+ string[4:0] runtime error: slice bounds out of range [4:0]
+ string[4:3] runtime error: slice bounds out of range [4:3]
+ string[4:4] runtime error: slice bounds out of range [:4] with length 3
+ string[4:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+ string[9876543210:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+ string[9876543210:-1] runtime error: slice bounds out of range [:-1]
+ string[9876543210:0] runtime error: slice bounds out of range [9876543210:0]
+ string[9876543210:3] runtime error: slice bounds out of range [9876543210:3]
+ string[9876543210:4] runtime error: slice bounds out of range [:4] with length 3
+ string[9876543210:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+ slice[-9876543210:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[-9876543210:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+ slice[-9876543210:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+ slice[-9876543210:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+ slice[-9876543210:-9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[-9876543210:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[-9876543210:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[-9876543210:-1:-1] runtime error: slice bounds out of range [::-1]
+ slice[-9876543210:-1:0] runtime error: slice bounds out of range [:-1:]
+ slice[-9876543210:-1:3] runtime error: slice bounds out of range [:-1:]
+ slice[-9876543210:-1:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[-9876543210:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[-9876543210:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[-9876543210:0:-1] runtime error: slice bounds out of range [::-1]
+ slice[-9876543210:0:0] runtime error: slice bounds out of range [-9876543210::]
+ slice[-9876543210:0:3] runtime error: slice bounds out of range [-9876543210::]
+ slice[-9876543210:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[-9876543210:0:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[-9876543210:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[-9876543210:3:-1] runtime error: slice bounds out of range [::-1]
+ slice[-9876543210:3:0] runtime error: slice bounds out of range [:3:0]
+ slice[-9876543210:3:3] runtime error: slice bounds out of range [-9876543210::]
+ slice[-9876543210:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[-9876543210:3:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[-9876543210:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[-9876543210:4:-1] runtime error: slice bounds out of range [::-1]
+ slice[-9876543210:4:0] runtime error: slice bounds out of range [:4:0]
+ slice[-9876543210:4:3] runtime error: slice bounds out of range [:4:3]
+ slice[-9876543210:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[-9876543210:4:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[-9876543210:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[-9876543210:9876543210:-1] runtime error: slice bounds out of range [::-1]
+ slice[-9876543210:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+ slice[-9876543210:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+ slice[-9876543210:9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[-9876543210:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[-1:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[-1:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+ slice[-1:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+ slice[-1:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+ slice[-1:-9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[-1:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[-1:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[-1:-1:-1] runtime error: slice bounds out of range [::-1]
+ slice[-1:-1:0] runtime error: slice bounds out of range [:-1:]
+ slice[-1:-1:3] runtime error: slice bounds out of range [:-1:]
+ slice[-1:-1:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[-1:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[-1:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[-1:0:-1] runtime error: slice bounds out of range [::-1]
+ slice[-1:0:0] runtime error: slice bounds out of range [-1::]
+ slice[-1:0:3] runtime error: slice bounds out of range [-1::]
+ slice[-1:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[-1:0:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[-1:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[-1:3:-1] runtime error: slice bounds out of range [::-1]
+ slice[-1:3:0] runtime error: slice bounds out of range [:3:0]
+ slice[-1:3:3] runtime error: slice bounds out of range [-1::]
+ slice[-1:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[-1:3:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[-1:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[-1:4:-1] runtime error: slice bounds out of range [::-1]
+ slice[-1:4:0] runtime error: slice bounds out of range [:4:0]
+ slice[-1:4:3] runtime error: slice bounds out of range [:4:3]
+ slice[-1:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[-1:4:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[-1:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[-1:9876543210:-1] runtime error: slice bounds out of range [::-1]
+ slice[-1:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+ slice[-1:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+ slice[-1:9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[-1:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[0:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[0:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+ slice[0:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+ slice[0:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+ slice[0:-9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[0:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[0:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[0:-1:-1] runtime error: slice bounds out of range [::-1]
+ slice[0:-1:0] runtime error: slice bounds out of range [:-1:]
+ slice[0:-1:3] runtime error: slice bounds out of range [:-1:]
+ slice[0:-1:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[0:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[0:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[0:0:-1] runtime error: slice bounds out of range [::-1]
+ slice[0:0:0] no panic
+ slice[0:0:3] no panic
+ slice[0:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[0:0:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[0:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[0:3:-1] runtime error: slice bounds out of range [::-1]
+ slice[0:3:0] runtime error: slice bounds out of range [:3:0]
+ slice[0:3:3] no panic
+ slice[0:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[0:3:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[0:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[0:4:-1] runtime error: slice bounds out of range [::-1]
+ slice[0:4:0] runtime error: slice bounds out of range [:4:0]
+ slice[0:4:3] runtime error: slice bounds out of range [:4:3]
+ slice[0:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[0:4:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[0:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[0:9876543210:-1] runtime error: slice bounds out of range [::-1]
+ slice[0:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+ slice[0:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+ slice[0:9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[0:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[3:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[3:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+ slice[3:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+ slice[3:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+ slice[3:-9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[3:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[3:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[3:-1:-1] runtime error: slice bounds out of range [::-1]
+ slice[3:-1:0] runtime error: slice bounds out of range [:-1:]
+ slice[3:-1:3] runtime error: slice bounds out of range [:-1:]
+ slice[3:-1:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[3:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[3:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[3:0:-1] runtime error: slice bounds out of range [::-1]
+ slice[3:0:0] runtime error: slice bounds out of range [3:0:]
+ slice[3:0:3] runtime error: slice bounds out of range [3:0:]
+ slice[3:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[3:0:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[3:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[3:3:-1] runtime error: slice bounds out of range [::-1]
+ slice[3:3:0] runtime error: slice bounds out of range [:3:0]
+ slice[3:3:3] no panic
+ slice[3:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[3:3:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[3:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[3:4:-1] runtime error: slice bounds out of range [::-1]
+ slice[3:4:0] runtime error: slice bounds out of range [:4:0]
+ slice[3:4:3] runtime error: slice bounds out of range [:4:3]
+ slice[3:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[3:4:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[3:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[3:9876543210:-1] runtime error: slice bounds out of range [::-1]
+ slice[3:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+ slice[3:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+ slice[3:9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[3:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[4:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[4:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+ slice[4:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+ slice[4:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+ slice[4:-9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[4:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[4:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[4:-1:-1] runtime error: slice bounds out of range [::-1]
+ slice[4:-1:0] runtime error: slice bounds out of range [:-1:]
+ slice[4:-1:3] runtime error: slice bounds out of range [:-1:]
+ slice[4:-1:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[4:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[4:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[4:0:-1] runtime error: slice bounds out of range [::-1]
+ slice[4:0:0] runtime error: slice bounds out of range [4:0:]
+ slice[4:0:3] runtime error: slice bounds out of range [4:0:]
+ slice[4:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[4:0:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[4:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[4:3:-1] runtime error: slice bounds out of range [::-1]
+ slice[4:3:0] runtime error: slice bounds out of range [:3:0]
+ slice[4:3:3] runtime error: slice bounds out of range [4:3:]
+ slice[4:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[4:3:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[4:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[4:4:-1] runtime error: slice bounds out of range [::-1]
+ slice[4:4:0] runtime error: slice bounds out of range [:4:0]
+ slice[4:4:3] runtime error: slice bounds out of range [:4:3]
+ slice[4:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[4:4:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[4:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[4:9876543210:-1] runtime error: slice bounds out of range [::-1]
+ slice[4:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+ slice[4:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+ slice[4:9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[4:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[9876543210:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[9876543210:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+ slice[9876543210:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+ slice[9876543210:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+ slice[9876543210:-9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[9876543210:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[9876543210:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[9876543210:-1:-1] runtime error: slice bounds out of range [::-1]
+ slice[9876543210:-1:0] runtime error: slice bounds out of range [:-1:]
+ slice[9876543210:-1:3] runtime error: slice bounds out of range [:-1:]
+ slice[9876543210:-1:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[9876543210:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[9876543210:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[9876543210:0:-1] runtime error: slice bounds out of range [::-1]
+ slice[9876543210:0:0] runtime error: slice bounds out of range [9876543210:0:]
+ slice[9876543210:0:3] runtime error: slice bounds out of range [9876543210:0:]
+ slice[9876543210:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[9876543210:0:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[9876543210:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[9876543210:3:-1] runtime error: slice bounds out of range [::-1]
+ slice[9876543210:3:0] runtime error: slice bounds out of range [:3:0]
+ slice[9876543210:3:3] runtime error: slice bounds out of range [9876543210:3:]
+ slice[9876543210:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[9876543210:3:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[9876543210:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[9876543210:4:-1] runtime error: slice bounds out of range [::-1]
+ slice[9876543210:4:0] runtime error: slice bounds out of range [:4:0]
+ slice[9876543210:4:3] runtime error: slice bounds out of range [:4:3]
+ slice[9876543210:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[9876543210:4:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ slice[9876543210:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ slice[9876543210:9876543210:-1] runtime error: slice bounds out of range [::-1]
+ slice[9876543210:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+ slice[9876543210:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+ slice[9876543210:9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[9876543210:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ array[-9876543210:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[-9876543210:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+ array[-9876543210:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+ array[-9876543210:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+ array[-9876543210:-9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+ array[-9876543210:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[-9876543210:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[-9876543210:-1:-1] runtime error: slice bounds out of range [::-1]
+ array[-9876543210:-1:0] runtime error: slice bounds out of range [:-1:]
+ array[-9876543210:-1:3] runtime error: slice bounds out of range [:-1:]
+ array[-9876543210:-1:4] runtime error: slice bounds out of range [::4] with length 3
+ array[-9876543210:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[-9876543210:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[-9876543210:0:-1] runtime error: slice bounds out of range [::-1]
+ array[-9876543210:0:0] runtime error: slice bounds out of range [-9876543210::]
+ array[-9876543210:0:3] runtime error: slice bounds out of range [-9876543210::]
+ array[-9876543210:0:4] runtime error: slice bounds out of range [::4] with length 3
+ array[-9876543210:0:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[-9876543210:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[-9876543210:3:-1] runtime error: slice bounds out of range [::-1]
+ array[-9876543210:3:0] runtime error: slice bounds out of range [:3:0]
+ array[-9876543210:3:3] runtime error: slice bounds out of range [-9876543210::]
+ array[-9876543210:3:4] runtime error: slice bounds out of range [::4] with length 3
+ array[-9876543210:3:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[-9876543210:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[-9876543210:4:-1] runtime error: slice bounds out of range [::-1]
+ array[-9876543210:4:0] runtime error: slice bounds out of range [:4:0]
+ array[-9876543210:4:3] runtime error: slice bounds out of range [:4:3]
+ array[-9876543210:4:4] runtime error: slice bounds out of range [::4] with length 3
+ array[-9876543210:4:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[-9876543210:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[-9876543210:9876543210:-1] runtime error: slice bounds out of range [::-1]
+ array[-9876543210:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+ array[-9876543210:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+ array[-9876543210:9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+ array[-9876543210:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[-1:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[-1:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+ array[-1:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+ array[-1:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+ array[-1:-9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+ array[-1:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[-1:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[-1:-1:-1] runtime error: slice bounds out of range [::-1]
+ array[-1:-1:0] runtime error: slice bounds out of range [:-1:]
+ array[-1:-1:3] runtime error: slice bounds out of range [:-1:]
+ array[-1:-1:4] runtime error: slice bounds out of range [::4] with length 3
+ array[-1:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[-1:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[-1:0:-1] runtime error: slice bounds out of range [::-1]
+ array[-1:0:0] runtime error: slice bounds out of range [-1::]
+ array[-1:0:3] runtime error: slice bounds out of range [-1::]
+ array[-1:0:4] runtime error: slice bounds out of range [::4] with length 3
+ array[-1:0:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[-1:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[-1:3:-1] runtime error: slice bounds out of range [::-1]
+ array[-1:3:0] runtime error: slice bounds out of range [:3:0]
+ array[-1:3:3] runtime error: slice bounds out of range [-1::]
+ array[-1:3:4] runtime error: slice bounds out of range [::4] with length 3
+ array[-1:3:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[-1:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[-1:4:-1] runtime error: slice bounds out of range [::-1]
+ array[-1:4:0] runtime error: slice bounds out of range [:4:0]
+ array[-1:4:3] runtime error: slice bounds out of range [:4:3]
+ array[-1:4:4] runtime error: slice bounds out of range [::4] with length 3
+ array[-1:4:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[-1:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[-1:9876543210:-1] runtime error: slice bounds out of range [::-1]
+ array[-1:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+ array[-1:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+ array[-1:9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+ array[-1:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[0:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[0:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+ array[0:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+ array[0:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+ array[0:-9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+ array[0:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[0:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[0:-1:-1] runtime error: slice bounds out of range [::-1]
+ array[0:-1:0] runtime error: slice bounds out of range [:-1:]
+ array[0:-1:3] runtime error: slice bounds out of range [:-1:]
+ array[0:-1:4] runtime error: slice bounds out of range [::4] with length 3
+ array[0:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[0:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[0:0:-1] runtime error: slice bounds out of range [::-1]
+ array[0:0:0] no panic
+ array[0:0:3] no panic
+ array[0:0:4] runtime error: slice bounds out of range [::4] with length 3
+ array[0:0:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[0:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[0:3:-1] runtime error: slice bounds out of range [::-1]
+ array[0:3:0] runtime error: slice bounds out of range [:3:0]
+ array[0:3:3] no panic
+ array[0:3:4] runtime error: slice bounds out of range [::4] with length 3
+ array[0:3:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[0:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[0:4:-1] runtime error: slice bounds out of range [::-1]
+ array[0:4:0] runtime error: slice bounds out of range [:4:0]
+ array[0:4:3] runtime error: slice bounds out of range [:4:3]
+ array[0:4:4] runtime error: slice bounds out of range [::4] with length 3
+ array[0:4:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[0:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[0:9876543210:-1] runtime error: slice bounds out of range [::-1]
+ array[0:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+ array[0:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+ array[0:9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+ array[0:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[3:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[3:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+ array[3:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+ array[3:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+ array[3:-9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+ array[3:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[3:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[3:-1:-1] runtime error: slice bounds out of range [::-1]
+ array[3:-1:0] runtime error: slice bounds out of range [:-1:]
+ array[3:-1:3] runtime error: slice bounds out of range [:-1:]
+ array[3:-1:4] runtime error: slice bounds out of range [::4] with length 3
+ array[3:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[3:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[3:0:-1] runtime error: slice bounds out of range [::-1]
+ array[3:0:0] runtime error: slice bounds out of range [3:0:]
+ array[3:0:3] runtime error: slice bounds out of range [3:0:]
+ array[3:0:4] runtime error: slice bounds out of range [::4] with length 3
+ array[3:0:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[3:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[3:3:-1] runtime error: slice bounds out of range [::-1]
+ array[3:3:0] runtime error: slice bounds out of range [:3:0]
+ array[3:3:3] no panic
+ array[3:3:4] runtime error: slice bounds out of range [::4] with length 3
+ array[3:3:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[3:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[3:4:-1] runtime error: slice bounds out of range [::-1]
+ array[3:4:0] runtime error: slice bounds out of range [:4:0]
+ array[3:4:3] runtime error: slice bounds out of range [:4:3]
+ array[3:4:4] runtime error: slice bounds out of range [::4] with length 3
+ array[3:4:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[3:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[3:9876543210:-1] runtime error: slice bounds out of range [::-1]
+ array[3:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+ array[3:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+ array[3:9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+ array[3:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[4:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[4:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+ array[4:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+ array[4:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+ array[4:-9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+ array[4:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[4:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[4:-1:-1] runtime error: slice bounds out of range [::-1]
+ array[4:-1:0] runtime error: slice bounds out of range [:-1:]
+ array[4:-1:3] runtime error: slice bounds out of range [:-1:]
+ array[4:-1:4] runtime error: slice bounds out of range [::4] with length 3
+ array[4:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[4:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[4:0:-1] runtime error: slice bounds out of range [::-1]
+ array[4:0:0] runtime error: slice bounds out of range [4:0:]
+ array[4:0:3] runtime error: slice bounds out of range [4:0:]
+ array[4:0:4] runtime error: slice bounds out of range [::4] with length 3
+ array[4:0:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[4:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[4:3:-1] runtime error: slice bounds out of range [::-1]
+ array[4:3:0] runtime error: slice bounds out of range [:3:0]
+ array[4:3:3] runtime error: slice bounds out of range [4:3:]
+ array[4:3:4] runtime error: slice bounds out of range [::4] with length 3
+ array[4:3:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[4:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[4:4:-1] runtime error: slice bounds out of range [::-1]
+ array[4:4:0] runtime error: slice bounds out of range [:4:0]
+ array[4:4:3] runtime error: slice bounds out of range [:4:3]
+ array[4:4:4] runtime error: slice bounds out of range [::4] with length 3
+ array[4:4:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[4:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[4:9876543210:-1] runtime error: slice bounds out of range [::-1]
+ array[4:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+ array[4:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+ array[4:9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+ array[4:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[9876543210:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[9876543210:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+ array[9876543210:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+ array[9876543210:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+ array[9876543210:-9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+ array[9876543210:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[9876543210:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[9876543210:-1:-1] runtime error: slice bounds out of range [::-1]
+ array[9876543210:-1:0] runtime error: slice bounds out of range [:-1:]
+ array[9876543210:-1:3] runtime error: slice bounds out of range [:-1:]
+ array[9876543210:-1:4] runtime error: slice bounds out of range [::4] with length 3
+ array[9876543210:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[9876543210:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[9876543210:0:-1] runtime error: slice bounds out of range [::-1]
+ array[9876543210:0:0] runtime error: slice bounds out of range [9876543210:0:]
+ array[9876543210:0:3] runtime error: slice bounds out of range [9876543210:0:]
+ array[9876543210:0:4] runtime error: slice bounds out of range [::4] with length 3
+ array[9876543210:0:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[9876543210:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[9876543210:3:-1] runtime error: slice bounds out of range [::-1]
+ array[9876543210:3:0] runtime error: slice bounds out of range [:3:0]
+ array[9876543210:3:3] runtime error: slice bounds out of range [9876543210:3:]
+ array[9876543210:3:4] runtime error: slice bounds out of range [::4] with length 3
+ array[9876543210:3:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[9876543210:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[9876543210:4:-1] runtime error: slice bounds out of range [::-1]
+ array[9876543210:4:0] runtime error: slice bounds out of range [:4:0]
+ array[9876543210:4:3] runtime error: slice bounds out of range [:4:3]
+ array[9876543210:4:4] runtime error: slice bounds out of range [::4] with length 3
+ array[9876543210:4:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+ array[9876543210:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+ array[9876543210:9876543210:-1] runtime error: slice bounds out of range [::-1]
+ array[9876543210:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+ array[9876543210:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+ array[9876543210:9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+ array[9876543210:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue30116u.go b/gcc/testsuite/go.test/test/fixedbugs/issue30116u.go
new file mode 100644
index 0000000..7c2aea2
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue30116u.go
@@ -0,0 +1,112 @@
+// run
+
+// 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.
+
+// This test makes sure the text output for bounds check failures is as expected.
+
+package main
+
+import (
+ "fmt"
+ "os"
+ "runtime"
+ "text/tabwriter"
+)
+
+// Testing with length 3 slices, arrays, and strings.
+// A large (>1<<32) value is included to test 32-bit platforms.
+var indexes = []uint64{0, 2, 3, 1<<32 - 1, 1<<64 - 1}
+var slices = []uint64{0, 3, 4, 1<<32 - 1, 1<<64 - 1}
+
+var w *tabwriter.Writer
+
+func main() {
+ w = tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', tabwriter.AlignRight)
+ defer w.Flush()
+ doIndex()
+ doSlice()
+ doSlice3()
+}
+func doIndex() {
+ a := []int{1, 2, 3}
+ for _, i := range indexes {
+ printPanic(fmt.Sprintf("slice[%d]", i), func() {
+ _ = a[i]
+ })
+ }
+ b := [3]int{1, 2, 3}
+ for _, i := range indexes {
+ printPanic(fmt.Sprintf("array[%d]", i), func() {
+ _ = b[i]
+ })
+ }
+ c := "123"
+ for _, i := range indexes {
+ printPanic(fmt.Sprintf("string[%d]", i), func() {
+ _ = c[i]
+ })
+ }
+}
+
+func doSlice() {
+ a := []int{1, 2, 3}
+ for _, i := range slices {
+ for _, j := range slices {
+ printPanic(fmt.Sprintf("slice[%d:%d]", i, j), func() {
+ _ = a[i:j]
+ })
+ }
+ }
+ b := [3]int{1, 2, 3}
+ for _, i := range slices {
+ for _, j := range slices {
+ printPanic(fmt.Sprintf("array[%d:%d]", i, j), func() {
+ _ = b[i:j]
+ })
+ }
+ }
+ c := "123"
+ for _, i := range slices {
+ for _, j := range slices {
+ printPanic(fmt.Sprintf("string[%d:%d]", i, j), func() {
+ _ = c[i:j]
+ })
+ }
+ }
+}
+
+func doSlice3() {
+ a := []int{1, 2, 3}
+ for _, i := range slices {
+ for _, j := range slices {
+ for _, k := range slices {
+ printPanic(fmt.Sprintf("slice[%d:%d:%d]", i, j, k), func() {
+ _ = a[i:j:k]
+ })
+ }
+ }
+ }
+ b := [3]int{1, 2, 3}
+ for _, i := range slices {
+ for _, j := range slices {
+ for _, k := range slices {
+ printPanic(fmt.Sprintf("array[%d:%d:%d]", i, j, k), func() {
+ _ = b[i:j:k]
+ })
+ }
+ }
+ }
+}
+
+func printPanic(msg string, f func()) {
+ defer func() {
+ res := "no panic"
+ if e := recover(); e != nil {
+ res = e.(runtime.Error).Error()
+ }
+ fmt.Fprintf(w, "%s\t %s\n", msg, res)
+ }()
+ f()
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue30116u.out b/gcc/testsuite/go.test/test/fixedbugs/issue30116u.out
new file mode 100644
index 0000000..ee19192
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue30116u.out
@@ -0,0 +1,340 @@
+ slice[0] no panic
+ slice[2] no panic
+ slice[3] runtime error: index out of range [3] with length 3
+ slice[4294967295] runtime error: index out of range [4294967295] with length 3
+ slice[18446744073709551615] runtime error: index out of range [18446744073709551615] with length 3
+ array[0] no panic
+ array[2] no panic
+ array[3] runtime error: index out of range [3] with length 3
+ array[4294967295] runtime error: index out of range [4294967295] with length 3
+ array[18446744073709551615] runtime error: index out of range [18446744073709551615] with length 3
+ string[0] no panic
+ string[2] no panic
+ string[3] runtime error: index out of range [3] with length 3
+ string[4294967295] runtime error: index out of range [4294967295] with length 3
+ string[18446744073709551615] runtime error: index out of range [18446744073709551615] with length 3
+ slice[0:0] no panic
+ slice[0:3] no panic
+ slice[0:4] runtime error: slice bounds out of range [:4] with capacity 3
+ slice[0:4294967295] runtime error: slice bounds out of range [:4294967295] with capacity 3
+ slice[0:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with capacity 3
+ slice[3:0] runtime error: slice bounds out of range [3:0]
+ slice[3:3] no panic
+ slice[3:4] runtime error: slice bounds out of range [:4] with capacity 3
+ slice[3:4294967295] runtime error: slice bounds out of range [:4294967295] with capacity 3
+ slice[3:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with capacity 3
+ slice[4:0] runtime error: slice bounds out of range [4:0]
+ slice[4:3] runtime error: slice bounds out of range [4:3]
+ slice[4:4] runtime error: slice bounds out of range [:4] with capacity 3
+ slice[4:4294967295] runtime error: slice bounds out of range [:4294967295] with capacity 3
+ slice[4:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with capacity 3
+ slice[4294967295:0] runtime error: slice bounds out of range [4294967295:0]
+ slice[4294967295:3] runtime error: slice bounds out of range [4294967295:3]
+ slice[4294967295:4] runtime error: slice bounds out of range [:4] with capacity 3
+ slice[4294967295:4294967295] runtime error: slice bounds out of range [:4294967295] with capacity 3
+ slice[4294967295:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with capacity 3
+ slice[18446744073709551615:0] runtime error: slice bounds out of range [18446744073709551615:0]
+ slice[18446744073709551615:3] runtime error: slice bounds out of range [18446744073709551615:3]
+ slice[18446744073709551615:4] runtime error: slice bounds out of range [:4] with capacity 3
+ slice[18446744073709551615:4294967295] runtime error: slice bounds out of range [:4294967295] with capacity 3
+ slice[18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with capacity 3
+ array[0:0] no panic
+ array[0:3] no panic
+ array[0:4] runtime error: slice bounds out of range [:4] with length 3
+ array[0:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+ array[0:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+ array[3:0] runtime error: slice bounds out of range [3:0]
+ array[3:3] no panic
+ array[3:4] runtime error: slice bounds out of range [:4] with length 3
+ array[3:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+ array[3:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+ array[4:0] runtime error: slice bounds out of range [4:0]
+ array[4:3] runtime error: slice bounds out of range [4:3]
+ array[4:4] runtime error: slice bounds out of range [:4] with length 3
+ array[4:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+ array[4:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+ array[4294967295:0] runtime error: slice bounds out of range [4294967295:0]
+ array[4294967295:3] runtime error: slice bounds out of range [4294967295:3]
+ array[4294967295:4] runtime error: slice bounds out of range [:4] with length 3
+ array[4294967295:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+ array[4294967295:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+ array[18446744073709551615:0] runtime error: slice bounds out of range [18446744073709551615:0]
+ array[18446744073709551615:3] runtime error: slice bounds out of range [18446744073709551615:3]
+ array[18446744073709551615:4] runtime error: slice bounds out of range [:4] with length 3
+ array[18446744073709551615:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+ array[18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+ string[0:0] no panic
+ string[0:3] no panic
+ string[0:4] runtime error: slice bounds out of range [:4] with length 3
+ string[0:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+ string[0:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+ string[3:0] runtime error: slice bounds out of range [3:0]
+ string[3:3] no panic
+ string[3:4] runtime error: slice bounds out of range [:4] with length 3
+ string[3:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+ string[3:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+ string[4:0] runtime error: slice bounds out of range [4:0]
+ string[4:3] runtime error: slice bounds out of range [4:3]
+ string[4:4] runtime error: slice bounds out of range [:4] with length 3
+ string[4:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+ string[4:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+ string[4294967295:0] runtime error: slice bounds out of range [4294967295:0]
+ string[4294967295:3] runtime error: slice bounds out of range [4294967295:3]
+ string[4294967295:4] runtime error: slice bounds out of range [:4] with length 3
+ string[4294967295:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+ string[4294967295:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+ string[18446744073709551615:0] runtime error: slice bounds out of range [18446744073709551615:0]
+ string[18446744073709551615:3] runtime error: slice bounds out of range [18446744073709551615:3]
+ string[18446744073709551615:4] runtime error: slice bounds out of range [:4] with length 3
+ string[18446744073709551615:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+ string[18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+ slice[0:0:0] no panic
+ slice[0:0:3] no panic
+ slice[0:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[0:0:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[0:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[0:3:0] runtime error: slice bounds out of range [:3:0]
+ slice[0:3:3] no panic
+ slice[0:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[0:3:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[0:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[0:4:0] runtime error: slice bounds out of range [:4:0]
+ slice[0:4:3] runtime error: slice bounds out of range [:4:3]
+ slice[0:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[0:4:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[0:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[0:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+ slice[0:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+ slice[0:4294967295:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[0:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[0:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[0:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+ slice[0:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+ slice[0:18446744073709551615:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[0:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[0:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[3:0:0] runtime error: slice bounds out of range [3:0:]
+ slice[3:0:3] runtime error: slice bounds out of range [3:0:]
+ slice[3:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[3:0:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[3:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[3:3:0] runtime error: slice bounds out of range [:3:0]
+ slice[3:3:3] no panic
+ slice[3:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[3:3:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[3:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[3:4:0] runtime error: slice bounds out of range [:4:0]
+ slice[3:4:3] runtime error: slice bounds out of range [:4:3]
+ slice[3:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[3:4:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[3:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[3:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+ slice[3:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+ slice[3:4294967295:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[3:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[3:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[3:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+ slice[3:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+ slice[3:18446744073709551615:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[3:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[3:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[4:0:0] runtime error: slice bounds out of range [4:0:]
+ slice[4:0:3] runtime error: slice bounds out of range [4:0:]
+ slice[4:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[4:0:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[4:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[4:3:0] runtime error: slice bounds out of range [:3:0]
+ slice[4:3:3] runtime error: slice bounds out of range [4:3:]
+ slice[4:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[4:3:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[4:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[4:4:0] runtime error: slice bounds out of range [:4:0]
+ slice[4:4:3] runtime error: slice bounds out of range [:4:3]
+ slice[4:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[4:4:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[4:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[4:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+ slice[4:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+ slice[4:4294967295:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[4:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[4:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[4:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+ slice[4:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+ slice[4:18446744073709551615:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[4:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[4:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[4294967295:0:0] runtime error: slice bounds out of range [4294967295:0:]
+ slice[4294967295:0:3] runtime error: slice bounds out of range [4294967295:0:]
+ slice[4294967295:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[4294967295:0:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[4294967295:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[4294967295:3:0] runtime error: slice bounds out of range [:3:0]
+ slice[4294967295:3:3] runtime error: slice bounds out of range [4294967295:3:]
+ slice[4294967295:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[4294967295:3:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[4294967295:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[4294967295:4:0] runtime error: slice bounds out of range [:4:0]
+ slice[4294967295:4:3] runtime error: slice bounds out of range [:4:3]
+ slice[4294967295:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[4294967295:4:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[4294967295:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[4294967295:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+ slice[4294967295:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+ slice[4294967295:4294967295:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[4294967295:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[4294967295:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[4294967295:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+ slice[4294967295:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+ slice[4294967295:18446744073709551615:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[4294967295:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[4294967295:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[18446744073709551615:0:0] runtime error: slice bounds out of range [18446744073709551615:0:]
+ slice[18446744073709551615:0:3] runtime error: slice bounds out of range [18446744073709551615:0:]
+ slice[18446744073709551615:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[18446744073709551615:0:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[18446744073709551615:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[18446744073709551615:3:0] runtime error: slice bounds out of range [:3:0]
+ slice[18446744073709551615:3:3] runtime error: slice bounds out of range [18446744073709551615:3:]
+ slice[18446744073709551615:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[18446744073709551615:3:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[18446744073709551615:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[18446744073709551615:4:0] runtime error: slice bounds out of range [:4:0]
+ slice[18446744073709551615:4:3] runtime error: slice bounds out of range [:4:3]
+ slice[18446744073709551615:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[18446744073709551615:4:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[18446744073709551615:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[18446744073709551615:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+ slice[18446744073709551615:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+ slice[18446744073709551615:4294967295:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[18446744073709551615:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[18446744073709551615:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ slice[18446744073709551615:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+ slice[18446744073709551615:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+ slice[18446744073709551615:18446744073709551615:4] runtime error: slice bounds out of range [::4] with capacity 3
+ slice[18446744073709551615:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[18446744073709551615:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+ array[0:0:0] no panic
+ array[0:0:3] no panic
+ array[0:0:4] runtime error: slice bounds out of range [::4] with length 3
+ array[0:0:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[0:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[0:3:0] runtime error: slice bounds out of range [:3:0]
+ array[0:3:3] no panic
+ array[0:3:4] runtime error: slice bounds out of range [::4] with length 3
+ array[0:3:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[0:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[0:4:0] runtime error: slice bounds out of range [:4:0]
+ array[0:4:3] runtime error: slice bounds out of range [:4:3]
+ array[0:4:4] runtime error: slice bounds out of range [::4] with length 3
+ array[0:4:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[0:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[0:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+ array[0:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+ array[0:4294967295:4] runtime error: slice bounds out of range [::4] with length 3
+ array[0:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[0:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[0:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+ array[0:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+ array[0:18446744073709551615:4] runtime error: slice bounds out of range [::4] with length 3
+ array[0:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[0:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[3:0:0] runtime error: slice bounds out of range [3:0:]
+ array[3:0:3] runtime error: slice bounds out of range [3:0:]
+ array[3:0:4] runtime error: slice bounds out of range [::4] with length 3
+ array[3:0:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[3:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[3:3:0] runtime error: slice bounds out of range [:3:0]
+ array[3:3:3] no panic
+ array[3:3:4] runtime error: slice bounds out of range [::4] with length 3
+ array[3:3:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[3:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[3:4:0] runtime error: slice bounds out of range [:4:0]
+ array[3:4:3] runtime error: slice bounds out of range [:4:3]
+ array[3:4:4] runtime error: slice bounds out of range [::4] with length 3
+ array[3:4:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[3:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[3:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+ array[3:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+ array[3:4294967295:4] runtime error: slice bounds out of range [::4] with length 3
+ array[3:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[3:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[3:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+ array[3:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+ array[3:18446744073709551615:4] runtime error: slice bounds out of range [::4] with length 3
+ array[3:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[3:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[4:0:0] runtime error: slice bounds out of range [4:0:]
+ array[4:0:3] runtime error: slice bounds out of range [4:0:]
+ array[4:0:4] runtime error: slice bounds out of range [::4] with length 3
+ array[4:0:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[4:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[4:3:0] runtime error: slice bounds out of range [:3:0]
+ array[4:3:3] runtime error: slice bounds out of range [4:3:]
+ array[4:3:4] runtime error: slice bounds out of range [::4] with length 3
+ array[4:3:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[4:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[4:4:0] runtime error: slice bounds out of range [:4:0]
+ array[4:4:3] runtime error: slice bounds out of range [:4:3]
+ array[4:4:4] runtime error: slice bounds out of range [::4] with length 3
+ array[4:4:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[4:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[4:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+ array[4:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+ array[4:4294967295:4] runtime error: slice bounds out of range [::4] with length 3
+ array[4:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[4:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[4:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+ array[4:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+ array[4:18446744073709551615:4] runtime error: slice bounds out of range [::4] with length 3
+ array[4:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[4:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[4294967295:0:0] runtime error: slice bounds out of range [4294967295:0:]
+ array[4294967295:0:3] runtime error: slice bounds out of range [4294967295:0:]
+ array[4294967295:0:4] runtime error: slice bounds out of range [::4] with length 3
+ array[4294967295:0:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[4294967295:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[4294967295:3:0] runtime error: slice bounds out of range [:3:0]
+ array[4294967295:3:3] runtime error: slice bounds out of range [4294967295:3:]
+ array[4294967295:3:4] runtime error: slice bounds out of range [::4] with length 3
+ array[4294967295:3:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[4294967295:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[4294967295:4:0] runtime error: slice bounds out of range [:4:0]
+ array[4294967295:4:3] runtime error: slice bounds out of range [:4:3]
+ array[4294967295:4:4] runtime error: slice bounds out of range [::4] with length 3
+ array[4294967295:4:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[4294967295:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[4294967295:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+ array[4294967295:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+ array[4294967295:4294967295:4] runtime error: slice bounds out of range [::4] with length 3
+ array[4294967295:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[4294967295:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[4294967295:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+ array[4294967295:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+ array[4294967295:18446744073709551615:4] runtime error: slice bounds out of range [::4] with length 3
+ array[4294967295:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[4294967295:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[18446744073709551615:0:0] runtime error: slice bounds out of range [18446744073709551615:0:]
+ array[18446744073709551615:0:3] runtime error: slice bounds out of range [18446744073709551615:0:]
+ array[18446744073709551615:0:4] runtime error: slice bounds out of range [::4] with length 3
+ array[18446744073709551615:0:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[18446744073709551615:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[18446744073709551615:3:0] runtime error: slice bounds out of range [:3:0]
+ array[18446744073709551615:3:3] runtime error: slice bounds out of range [18446744073709551615:3:]
+ array[18446744073709551615:3:4] runtime error: slice bounds out of range [::4] with length 3
+ array[18446744073709551615:3:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[18446744073709551615:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[18446744073709551615:4:0] runtime error: slice bounds out of range [:4:0]
+ array[18446744073709551615:4:3] runtime error: slice bounds out of range [:4:3]
+ array[18446744073709551615:4:4] runtime error: slice bounds out of range [::4] with length 3
+ array[18446744073709551615:4:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[18446744073709551615:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[18446744073709551615:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+ array[18446744073709551615:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+ array[18446744073709551615:4294967295:4] runtime error: slice bounds out of range [::4] with length 3
+ array[18446744073709551615:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[18446744073709551615:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+ array[18446744073709551615:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+ array[18446744073709551615:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+ array[18446744073709551615:18446744073709551615:4] runtime error: slice bounds out of range [::4] with length 3
+ array[18446744073709551615:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[18446744073709551615:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue30659.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/issue30659.dir/a.go
new file mode 100644
index 0000000..3837e02
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue30659.dir/a.go
@@ -0,0 +1,19 @@
+// 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 a
+
+type I interface {
+ I2
+}
+type I2 interface {
+ M()
+}
+type S struct{}
+
+func (*S) M() {}
+
+func New() I {
+ return &S{}
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue30659.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/issue30659.dir/b.go
new file mode 100644
index 0000000..272e520
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue30659.dir/b.go
@@ -0,0 +1,13 @@
+// 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 b
+
+import (
+ "./a"
+)
+
+func B(p1 a.I, p2 a.I2) int {
+ return 42
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue30659.go b/gcc/testsuite/go.test/test/fixedbugs/issue30659.go
new file mode 100644
index 0000000..973ae1d
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue30659.go
@@ -0,0 +1,7 @@
+// compiledir
+
+// 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 ignored
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue32901.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/issue32901.dir/a.go
new file mode 100644
index 0000000..54ed771
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue32901.dir/a.go
@@ -0,0 +1,15 @@
+// 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 a
+
+type T struct { x int }
+
+func F() interface{} {
+ return [2]T{}
+}
+
+func P() interface{} {
+ return &[2]T{}
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue32901.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/issue32901.dir/b.go
new file mode 100644
index 0000000..932d7b0
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue32901.dir/b.go
@@ -0,0 +1,15 @@
+// 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 b
+
+import "./a"
+
+func F() interface{} {
+ return a.F()
+}
+
+func P() interface{} {
+ return a.P()
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue32901.dir/c.go b/gcc/testsuite/go.test/test/fixedbugs/issue32901.dir/c.go
new file mode 100644
index 0000000..5f31c7f
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue32901.dir/c.go
@@ -0,0 +1,17 @@
+// 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 c
+
+import "./b"
+
+func F() interface{} {
+ go func(){}() // make it non-inlineable
+ return b.F()
+}
+
+func P() interface{} {
+ go func(){}() // make it non-inlineable
+ return b.P()
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue32901.dir/main.go b/gcc/testsuite/go.test/test/fixedbugs/issue32901.dir/main.go
new file mode 100644
index 0000000..28bb8cd
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue32901.dir/main.go
@@ -0,0 +1,18 @@
+// 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 main
+
+import "./c"
+import "reflect"
+
+func main() {
+ x := c.F()
+ p := c.P()
+ t := reflect.PtrTo(reflect.TypeOf(x))
+ tp := reflect.TypeOf(p)
+ if t != tp {
+ panic("FAIL")
+ }
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue32901.go b/gcc/testsuite/go.test/test/fixedbugs/issue32901.go
new file mode 100644
index 0000000..004c3da
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue32901.go
@@ -0,0 +1,9 @@
+// rundir
+
+// 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.
+
+// Issue 32901: type descriptor equality bug in gccgo.
+
+package ignored
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue32922.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/issue32922.dir/a.go
new file mode 100644
index 0000000..b13c4b4
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue32922.dir/a.go
@@ -0,0 +1,18 @@
+// 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 a
+
+func A() int {
+ return p("count")
+}
+
+func p(which string, args ...string) int {
+ switch which {
+ case "count", "something":
+ return 1
+ default:
+ return 2
+ }
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue32922.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/issue32922.dir/b.go
new file mode 100644
index 0000000..fdaf42d
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue32922.dir/b.go
@@ -0,0 +1,11 @@
+// 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 b
+
+import "./a"
+
+func B() int {
+ return 99 + a.A()
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue32922.go b/gcc/testsuite/go.test/test/fixedbugs/issue32922.go
new file mode 100644
index 0000000..005c8e6
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue32922.go
@@ -0,0 +1,11 @@
+// compiledir
+
+// 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.
+
+// This directory contains a pair of packages that triggers a compiler
+// error in gccgo (problem with the way inlinable call expressions are
+// imported). See issue 32922 for details.
+
+package ignored
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33013.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/issue33013.dir/a.go
new file mode 100644
index 0000000..056be88
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33013.dir/a.go
@@ -0,0 +1,9 @@
+// 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 a
+
+type G interface {
+ UsesEmpty(p interface{}) int
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33013.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/issue33013.dir/b.go
new file mode 100644
index 0000000..5694b58
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33013.dir/b.go
@@ -0,0 +1,24 @@
+// 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 b
+
+import "a"
+
+type Service uint64
+type ServiceDesc struct {
+ X int
+ uc
+}
+
+type uc interface {
+ f() a.G
+}
+
+var q int
+
+func RS(svcd *ServiceDesc, server interface{}, qq uint8) *Service {
+ defer func() { q += int(qq) }()
+ return nil
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33013.dir/c.go b/gcc/testsuite/go.test/test/fixedbugs/issue33013.dir/c.go
new file mode 100644
index 0000000..bfdc0b5
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33013.dir/c.go
@@ -0,0 +1,19 @@
+// 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 c
+
+import (
+ "a"
+ "b"
+)
+
+type BI interface {
+ Something(s int64) int64
+ Another(pxp a.G) int32
+}
+
+func BRS(sd *b.ServiceDesc, server BI, xyz int) *b.Service {
+ return b.RS(sd, server, 7)
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33013.dir/d.go b/gcc/testsuite/go.test/test/fixedbugs/issue33013.dir/d.go
new file mode 100644
index 0000000..f4fff4a
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33013.dir/d.go
@@ -0,0 +1,16 @@
+// 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 d
+
+import (
+ "b"
+ "c"
+)
+
+var GA b.Service
+
+func C() {
+ c.BRS(nil, nil, 22)
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33013.go b/gcc/testsuite/go.test/test/fixedbugs/issue33013.go
new file mode 100644
index 0000000..e363cf5
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33013.go
@@ -0,0 +1,9 @@
+// compiledir
+
+// 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.
+
+// Issue 33013: gccgo compiler error with inlinable function
+
+package ignored
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33020.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/issue33020.dir/a.go
new file mode 100644
index 0000000..948f4fd
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33020.dir/a.go
@@ -0,0 +1,16 @@
+// 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 a
+
+var G1 int
+var G2 int
+var G3 int
+var G4 int
+var G5 int
+var G6 int
+var G7 int
+var G8 int
+var G9 int
+var G10 int
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33020.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/issue33020.dir/b.go
new file mode 100644
index 0000000..354ab3e
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33020.dir/b.go
@@ -0,0 +1,22 @@
+// 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 b
+
+import "a"
+
+var N n
+
+type n struct{}
+
+func (r n) M1() int { return a.G1 }
+func (r n) M2() int { return a.G2 }
+func (r n) M3() int { return a.G3 }
+func (r n) M4() int { return a.G4 }
+func (r n) M5() int { return a.G5 }
+func (r n) M6() int { return a.G6 }
+func (r n) M7() int { return a.G7 }
+func (r n) M8() int { return a.G8 }
+func (r n) M9() int { return a.G9 }
+func (r n) M10() int { return a.G10 }
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33020.go b/gcc/testsuite/go.test/test/fixedbugs/issue33020.go
new file mode 100644
index 0000000..ccdf187
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33020.go
@@ -0,0 +1,9 @@
+// compiledir
+
+// 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.
+
+// Issue 33020: gccgo undefined behavior with inlinable function
+
+package ignored
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33062.go b/gcc/testsuite/go.test/test/fixedbugs/issue33062.go
new file mode 100644
index 0000000..5e6a358
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33062.go
@@ -0,0 +1,33 @@
+// run
+
+// 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.
+
+// Issue 33062: gccgo generates incorrect type equality
+// functions.
+
+package main
+
+type simpleStruct struct {
+ int
+ string
+}
+
+type complexStruct struct {
+ int
+ simpleStruct
+}
+
+func main() {
+ x := complexStruct{1, simpleStruct{2, "xxx"}}
+ ix := interface{}(x)
+ y := complexStruct{1, simpleStruct{2, "yyy"}}
+ iy := interface{}(y)
+ if ix != ix {
+ panic("FAIL")
+ }
+ if ix == iy {
+ panic("FAIL")
+ }
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33158.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/issue33158.dir/a.go
new file mode 100644
index 0000000..28714e0
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33158.dir/a.go
@@ -0,0 +1,25 @@
+// 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 a
+
+var GS string
+
+func M() string {
+ if s := getname("Fred"); s != "" {
+ return s
+ }
+ if s := getname("Joe"); s != "" {
+ return s
+ }
+
+ return string("Alex")
+}
+
+// getname can be any function returning a string, just has to be non-inlinable.
+
+//go:noinline
+func getname(s string) string {
+ return s + "foo"
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33158.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/issue33158.dir/b.go
new file mode 100644
index 0000000..a16f0da
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33158.dir/b.go
@@ -0,0 +1,11 @@
+// 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 b
+
+import "a"
+
+func B() string {
+ return a.M()
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33158.go b/gcc/testsuite/go.test/test/fixedbugs/issue33158.go
new file mode 100644
index 0000000..1bba8f2
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33158.go
@@ -0,0 +1,9 @@
+// compiledir
+
+// 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.
+
+// Issue 33158: gccgo duplicate def error from importing inlinable function
+
+package ignored
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33219.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/issue33219.dir/a.go
new file mode 100644
index 0000000..2d96301
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33219.dir/a.go
@@ -0,0 +1,17 @@
+// 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 a
+
+type A interface {
+ M(i interface{}) interface{}
+}
+
+var a1 A
+var a2 A
+
+func V(p A, k, v interface{}) A {
+ defer func() { a1, a2 = a2, a1 }()
+ return a1
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33219.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/issue33219.dir/b.go
new file mode 100644
index 0000000..2a8f518
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33219.dir/b.go
@@ -0,0 +1,25 @@
+// 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 b
+
+import "./a"
+
+type Service uint64
+
+var q *Service
+var r *Service
+
+type f struct{}
+
+var fk f
+
+func No(s a.A, qq uint8) *Service {
+ defer func() { q, r = r, q }()
+ return q
+}
+
+func Yes(s a.A, p *uint64) a.A {
+ return a.V(s, fk, p)
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33219.dir/c.go b/gcc/testsuite/go.test/test/fixedbugs/issue33219.dir/c.go
new file mode 100644
index 0000000..ece48d7
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33219.dir/c.go
@@ -0,0 +1,20 @@
+// 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 c
+
+import (
+ "a"
+ "b"
+)
+
+type BI interface {
+ Another(pxp a.A) int32
+}
+
+//go:noinline
+func BRS(sd a.A, xyz int) *b.Service {
+ x := b.Yes(sd, nil)
+ return b.No(x, 1)
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33219.go b/gcc/testsuite/go.test/test/fixedbugs/issue33219.go
new file mode 100644
index 0000000..45edc8b
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33219.go
@@ -0,0 +1,9 @@
+// compiledir
+
+// 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.
+
+// Issue 33219: gccgo assert in "implements_interface()"
+
+package ignored
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33739.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/issue33739.dir/a.go
new file mode 100644
index 0000000..7eb5b92
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33739.dir/a.go
@@ -0,0 +1,11 @@
+// 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 a
+
+func F() func() {
+ return f
+}
+
+func f() {}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33739.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/issue33739.dir/b.go
new file mode 100644
index 0000000..caca1ec
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33739.dir/b.go
@@ -0,0 +1,11 @@
+// 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 main
+
+import "a"
+
+func main() {
+ a.F()()
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue33739.go b/gcc/testsuite/go.test/test/fixedbugs/issue33739.go
new file mode 100644
index 0000000..b770782
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue33739.go
@@ -0,0 +1,9 @@
+// rundir
+
+// 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.
+
+// Issue 33739: gccgo undefined symbol with cross-package inlining
+
+package ignored
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue34503.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/issue34503.dir/a.go
new file mode 100644
index 0000000..2c14913
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue34503.dir/a.go
@@ -0,0 +1,15 @@
+// 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 a
+
+import "unsafe"
+
+type HookFunc func(x uint64)
+
+var HookV unsafe.Pointer
+
+func Hook(x uint64) {
+ (*(*HookFunc)(HookV))(x)
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue34503.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/issue34503.dir/b.go
new file mode 100644
index 0000000..21bdfcc
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue34503.dir/b.go
@@ -0,0 +1,11 @@
+// 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 b
+
+import "a"
+
+func Bfunc() {
+ a.Hook(101)
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue34503.go b/gcc/testsuite/go.test/test/fixedbugs/issue34503.go
new file mode 100644
index 0000000..d843df7
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue34503.go
@@ -0,0 +1,9 @@
+// compiledir
+
+// 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.
+
+// Issue 34503: gccgo compiler error importing inlinable function
+
+package ignored
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue34577.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/issue34577.dir/a.go
new file mode 100644
index 0000000..b6af555
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue34577.dir/a.go
@@ -0,0 +1,27 @@
+// 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 a
+
+type A struct {
+ x int
+}
+
+type AI interface {
+ bar()
+}
+
+type AC int
+
+func (ab AC) bar() {
+}
+
+const (
+ ACC = AC(101)
+)
+
+//go:noinline
+func W(a A, k, v interface{}) A {
+ return A{3}
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue34577.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/issue34577.dir/b.go
new file mode 100644
index 0000000..bbcd1af
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue34577.dir/b.go
@@ -0,0 +1,23 @@
+// 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 b
+
+import "a"
+
+type B struct {
+ s string
+}
+
+func (b B) Func(x a.A) a.A {
+ return a.W(x, k, b)
+}
+
+type ktype int
+
+const k ktype = 0
+
+func Func2() a.AI {
+ return a.ACC
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue34577.go b/gcc/testsuite/go.test/test/fixedbugs/issue34577.go
new file mode 100644
index 0000000..b4caaeb
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue34577.go
@@ -0,0 +1,9 @@
+// compiledir
+
+// 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.
+
+// Issue 34577: gccgo compiler error emitting export data
+
+package ignored
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue3552.dir/one.go b/gcc/testsuite/go.test/test/fixedbugs/issue3552.dir/one.go
index 491ada1..e594db7 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue3552.dir/one.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue3552.dir/one.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue3552.dir/two.go b/gcc/testsuite/go.test/test/fixedbugs/issue3552.dir/two.go
index 1366d24..2f330bf 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue3552.dir/two.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue3552.dir/two.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue35739.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/issue35739.dir/a.go
new file mode 100644
index 0000000..b79503e
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue35739.dir/a.go
@@ -0,0 +1,15 @@
+// Copyright 2020 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 a
+
+type myError string
+
+func (e myError) Error() string { return string(e) }
+
+const myErrorVal myError = "error"
+
+func IsMyError(err error) bool {
+ return err == error(myErrorVal)
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue35739.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/issue35739.dir/b.go
new file mode 100644
index 0000000..8d22aac
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue35739.dir/b.go
@@ -0,0 +1,11 @@
+// Copyright 2020 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 b
+
+import "./a"
+
+func F(err error) bool {
+ return a.IsMyError(err)
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue35739.go b/gcc/testsuite/go.test/test/fixedbugs/issue35739.go
new file mode 100644
index 0000000..26f09d8
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue35739.go
@@ -0,0 +1,9 @@
+// compiledir
+
+// Copyright 2020 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.
+
+// Issue 35739: gccgo inlining error with constant with method.
+
+package ignored
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue3705.go b/gcc/testsuite/go.test/test/fixedbugs/issue3705.go
index 64ef38b..ed0a193 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue3705.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue3705.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue3783.go b/gcc/testsuite/go.test/test/fixedbugs/issue3783.go
index d7a4a2e..7db06d1 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue3783.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue3783.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue38125.go b/gcc/testsuite/go.test/test/fixedbugs/issue38125.go
new file mode 100644
index 0000000..1207aec
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue38125.go
@@ -0,0 +1,22 @@
+// compile
+
+// Copyright 2020 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.
+
+// gccgo mishandled embedded methods of type aliases.
+
+package p
+
+type I int
+
+func (I) M() {}
+
+type T = struct {
+ I
+}
+
+func F() {
+ _ = T.M
+ _ = struct { I }.M
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue3924.go b/gcc/testsuite/go.test/test/fixedbugs/issue3924.go
deleted file mode 100644
index eb7a665..0000000
--- a/gcc/testsuite/go.test/test/fixedbugs/issue3924.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// compile
-
-// Copyright 2012 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 foo
-
-type mybool bool
-
-var x, y = 1, 2
-var _ mybool = x < y && x < y
-var _ mybool = x < y || x < y
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue3925.go b/gcc/testsuite/go.test/test/fixedbugs/issue3925.go
index a62d439..628c2226 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue3925.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue3925.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue40152.go b/gcc/testsuite/go.test/test/fixedbugs/issue40152.go
new file mode 100644
index 0000000..1cb68e9
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue40152.go
@@ -0,0 +1,21 @@
+// run
+
+// Copyright 2020 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.
+
+// Gccgo mishandles converting an untyped boolean to an interface type.
+
+package main
+
+func t(args ...interface{}) bool {
+ x := true
+ return x == args[0]
+}
+
+func main() {
+ r := t("x" == "x" && "y" == "y")
+ if !r {
+ panic(r)
+ }
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue40252.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/issue40252.dir/a.go
new file mode 100644
index 0000000..5519e93
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue40252.dir/a.go
@@ -0,0 +1,14 @@
+// Copyright 2020 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 a
+
+type I interface {
+ Func()
+}
+
+func Call() {
+ f := I.Func
+ f(nil)
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue40252.dir/main.go b/gcc/testsuite/go.test/test/fixedbugs/issue40252.dir/main.go
new file mode 100644
index 0000000..93f5b70
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue40252.dir/main.go
@@ -0,0 +1,16 @@
+// Copyright 2020 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 main
+
+import "./a"
+
+func main() {
+ defer func() {
+ if recover() == nil {
+ panic("expected nil pointer dereference")
+ }
+ }()
+ a.Call()
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue40252.go b/gcc/testsuite/go.test/test/fixedbugs/issue40252.go
new file mode 100644
index 0000000..9be4e66
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue40252.go
@@ -0,0 +1,8 @@
+// rundir
+
+// Copyright 2020 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.
+
+// gccgo got an undefined symbol reference when inlining a method expression.
+package ignored
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4085a.go b/gcc/testsuite/go.test/test/fixedbugs/issue4085a.go
index 089637d..200290a 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4085a.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4085a.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4085b.go b/gcc/testsuite/go.test/test/fixedbugs/issue4085b.go
index 6304ce0..cf27512 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4085b.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4085b.go
@@ -19,29 +19,36 @@ func main() {
shouldPanic("cap out of range", func() { _ = make(T, 0, n) })
shouldPanic("len out of range", func() { _ = make(T, int64(n)) })
shouldPanic("cap out of range", func() { _ = make(T, 0, int64(n)) })
+ testMakeInAppend(n)
+
var t *byte
if unsafe.Sizeof(t) == 8 {
// Test mem > maxAlloc
var n2 int64 = 1 << 59
shouldPanic("len out of range", func() { _ = make(T, int(n2)) })
shouldPanic("cap out of range", func() { _ = make(T, 0, int(n2)) })
+ testMakeInAppend(int(n2))
// Test elem.size*cap overflow
n2 = 1<<63 - 1
shouldPanic("len out of range", func() { _ = make(T, int(n2)) })
shouldPanic("cap out of range", func() { _ = make(T, 0, int(n2)) })
+ testMakeInAppend(int(n2))
+ var x uint64 = 1<<64 - 1
+ shouldPanic("len out of range", func() { _ = make([]byte, x) })
+ shouldPanic("cap out of range", func() { _ = make(T, 0, x) })
+ testMakeInAppend(int(x))
} else {
n = 1<<31 - 1
shouldPanic("len out of range", func() { _ = make(T, n) })
shouldPanic("cap out of range", func() { _ = make(T, 0, n) })
shouldPanic("len out of range", func() { _ = make(T, int64(n)) })
shouldPanic("cap out of range", func() { _ = make(T, 0, int64(n)) })
+ testMakeInAppend(n)
+ var x uint64 = 1<<32 - 1
+ shouldPanic("len out of range", func() { _ = make([]byte, x) })
+ shouldPanic("cap out of range", func() { _ = make(T, 0, x) })
+ testMakeInAppend(int(x))
}
-
- // Test make in append panics since the gc compiler optimizes makes in appends.
- shouldPanic("len out of range", func() { _ = append(T{}, make(T, n)...) })
- shouldPanic("cap out of range", func() { _ = append(T{}, make(T, 0, n)...) })
- shouldPanic("len out of range", func() { _ = append(T{}, make(T, int64(n))...) })
- shouldPanic("cap out of range", func() { _ = append(T{}, make(T, 0, int64(n))...) })
}
func shouldPanic(str string, f func()) {
@@ -58,3 +65,21 @@ func shouldPanic(str string, f func()) {
f()
}
+
+// Test make in append panics since the gc compiler optimizes makes in appends.
+func testMakeInAppend(n int) {
+ lengths := []int{0, 1}
+ for _, length := range lengths {
+ t := make(T, length)
+ shouldPanic("len out of range", func() { _ = append(t, make(T, n)...) })
+ shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, n)...) })
+ shouldPanic("len out of range", func() { _ = append(t, make(T, int64(n))...) })
+ shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, int64(n))...) })
+ shouldPanic("len out of range", func() { _ = append(t, make(T, uint64(n))...) })
+ shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, uint64(n))...) })
+ shouldPanic("len out of range", func() { _ = append(t, make(T, int(n))...) })
+ shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, int(n))...) })
+ shouldPanic("len out of range", func() { _ = append(t, make(T, uint(n))...) })
+ shouldPanic("cap out of range", func() { _ = append(t, make(T, 0, uint(n))...) })
+ }
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4097.go b/gcc/testsuite/go.test/test/fixedbugs/issue4097.go
index c2b7d9b..30b65bc 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4097.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4097.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4099.go b/gcc/testsuite/go.test/test/fixedbugs/issue4099.go
index 89392bf..5a4ea7c 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4099.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4099.go
@@ -1,6 +1,6 @@
// errorcheck -0 -m
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -19,8 +19,8 @@ func F2([]byte)
func G() {
var buf1 [10]byte
- F1(buf1[:]) // ERROR "buf1 does not escape"
+ F1(buf1[:])
var buf2 [10]byte // ERROR "moved to heap: buf2"
- F2(buf2[:]) // ERROR "buf2 escapes to heap"
+ F2(buf2[:])
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4162.go b/gcc/testsuite/go.test/test/fixedbugs/issue4162.go
index c2a8338..f236bd0 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4162.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4162.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4167.go b/gcc/testsuite/go.test/test/fixedbugs/issue4167.go
index 4e35331..86a636f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4167.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4167.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4232.go b/gcc/testsuite/go.test/test/fixedbugs/issue4232.go
index e5daa65..30d1326 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4232.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4232.go
@@ -1,9 +1,12 @@
// errorcheck
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+// issue 4232
+// issue 7200
+
package p
func f() {
@@ -12,22 +15,42 @@ func f() {
_ = a[-1:] // ERROR "invalid slice index -1|index out of bounds"
_ = a[:-1] // ERROR "invalid slice index -1|index out of bounds"
_ = a[10] // ERROR "invalid array index 10|index out of bounds"
+ _ = a[9:10]
+ _ = a[10:10]
+ _ = a[9:12] // ERROR "invalid slice index 12|index out of bounds"
+ _ = a[11:12] // ERROR "invalid slice index 11|index out of bounds"
+ _ = a[1<<100 : 1<<110] // ERROR "overflows int|integer constant overflow" "invalid slice index 1 << 100|index out of bounds"
var s []int
_ = s[-1] // ERROR "invalid slice index -1|index out of bounds"
_ = s[-1:] // ERROR "invalid slice index -1|index out of bounds"
_ = s[:-1] // ERROR "invalid slice index -1|index out of bounds"
_ = s[10]
+ _ = s[9:10]
+ _ = s[10:10]
+ _ = s[9:12]
+ _ = s[11:12]
+ _ = s[1<<100 : 1<<110] // ERROR "overflows int|integer constant overflow" "invalid slice index 1 << 100|index out of bounds"
- const c = "foo"
+ const c = "foofoofoof"
_ = c[-1] // ERROR "invalid string index -1|index out of bounds"
_ = c[-1:] // ERROR "invalid slice index -1|index out of bounds"
_ = c[:-1] // ERROR "invalid slice index -1|index out of bounds"
- _ = c[3] // ERROR "invalid string index 3|index out of bounds"
+ _ = c[10] // ERROR "invalid string index 10|index out of bounds"
+ _ = c[9:10]
+ _ = c[10:10]
+ _ = c[9:12] // ERROR "invalid slice index 12|index out of bounds"
+ _ = c[11:12] // ERROR "invalid slice index 11|index out of bounds"
+ _ = c[1<<100 : 1<<110] // ERROR "overflows int|integer constant overflow" "invalid slice index 1 << 100|index out of bounds"
var t string
_ = t[-1] // ERROR "invalid string index -1|index out of bounds"
_ = t[-1:] // ERROR "invalid slice index -1|index out of bounds"
_ = t[:-1] // ERROR "invalid slice index -1|index out of bounds"
- _ = t[3]
+ _ = t[10]
+ _ = t[9:10]
+ _ = t[10:10]
+ _ = t[9:12]
+ _ = t[11:12]
+ _ = t[1<<100 : 1<<110] // ERROR "overflows int|integer constant overflow" "invalid slice index 1 << 100|index out of bounds"
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4251.go b/gcc/testsuite/go.test/test/fixedbugs/issue4251.go
index 3668d4c..d11ce51 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4251.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4251.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4252.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/issue4252.dir/a.go
index 089b6f2..a587e28 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4252.dir/a.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4252.dir/a.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4252.dir/main.go b/gcc/testsuite/go.test/test/fixedbugs/issue4252.dir/main.go
index 28e4342..02d9836 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4252.dir/main.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4252.dir/main.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4252.go b/gcc/testsuite/go.test/test/fixedbugs/issue4252.go
index 1b0e5b2..01bcbc4 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4252.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4252.go
@@ -1,6 +1,6 @@
// rundir
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue42790.go b/gcc/testsuite/go.test/test/fixedbugs/issue42790.go
new file mode 100644
index 0000000..d83a022
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue42790.go
@@ -0,0 +1,9 @@
+// compile
+
+// Copyright 2020 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 p
+
+const _ = -uint(len(string(1<<32)) - len("\uFFFD"))
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4283.go b/gcc/testsuite/go.test/test/fixedbugs/issue4283.go
index 128c872..fa5629b 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4283.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4283.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4313.go b/gcc/testsuite/go.test/test/fixedbugs/issue4313.go
index b2f69db..2494b83 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4313.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4313.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4316.go b/gcc/testsuite/go.test/test/fixedbugs/issue4316.go
index bb18a08..de9a61b 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4316.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4316.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4323.go b/gcc/testsuite/go.test/test/fixedbugs/issue4323.go
index 6bb78f4..f082a1f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4323.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4323.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4326.go b/gcc/testsuite/go.test/test/fixedbugs/issue4326.go
index 5ce2eea..6a510f9 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4326.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4326.go
@@ -1,6 +1,6 @@
// compiledir
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4348.go b/gcc/testsuite/go.test/test/fixedbugs/issue4348.go
index 3dac8f7..8b1a56c 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4348.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4348.go
@@ -1,12 +1,14 @@
-// compile
+// skip
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
// Issue 4348. After switch to 64-bit ints the compiler generates
// illegal instructions when using large array bounds or indexes.
+// Skip. We reject symbols larger that 2GB (Issue #9862).
+
package main
// 1<<32 on a 64-bit machine, 1 otherwise.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4353.go b/gcc/testsuite/go.test/test/fixedbugs/issue4353.go
index defe7c3..6a17c46 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4353.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4353.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4359.go b/gcc/testsuite/go.test/test/fixedbugs/issue4359.go
index b5adb40..c79e9e2 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4359.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4359.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4370.dir/p1.go b/gcc/testsuite/go.test/test/fixedbugs/issue4370.dir/p1.go
index d732c8b..d010e93 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4370.dir/p1.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4370.dir/p1.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4370.dir/p2.go b/gcc/testsuite/go.test/test/fixedbugs/issue4370.dir/p2.go
index 33370d0..0d3e236 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4370.dir/p2.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4370.dir/p2.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4370.dir/p3.go b/gcc/testsuite/go.test/test/fixedbugs/issue4370.dir/p3.go
index 13c996b..c275c6e 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4370.dir/p3.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4370.dir/p3.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4370.go b/gcc/testsuite/go.test/test/fixedbugs/issue4370.go
index 76b47e1..b1d0364 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4370.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4370.go
@@ -1,6 +1,6 @@
// compiledir
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4396a.go b/gcc/testsuite/go.test/test/fixedbugs/issue4396a.go
index 11ae1f7..38dd4b8 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4396a.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4396a.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4396b.go b/gcc/testsuite/go.test/test/fixedbugs/issue4396b.go
index d0bf28f..1284870 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4396b.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4396b.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4399.go b/gcc/testsuite/go.test/test/fixedbugs/issue4399.go
index 6674db9..3dc2126 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4399.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4399.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4405.go b/gcc/testsuite/go.test/test/fixedbugs/issue4405.go
index b8458d7..5ba3e10 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4405.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4405.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4429.go b/gcc/testsuite/go.test/test/fixedbugs/issue4429.go
index 6822760..9eb2e0f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4429.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4429.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4448.go b/gcc/testsuite/go.test/test/fixedbugs/issue4448.go
index fa1d9fe..f5e4715 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4448.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4448.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4452.go b/gcc/testsuite/go.test/test/fixedbugs/issue4452.go
index 54dd214..f91bd2c 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4452.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4452.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4458.go b/gcc/testsuite/go.test/test/fixedbugs/issue4458.go
index 82b104a..59cfa9f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4458.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4458.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
@@ -16,5 +16,5 @@ func (T) foo() {}
func main() {
av := T{}
pav := &av
- (**T).foo(&pav) // ERROR "no method|requires named type or pointer to named"
+ (**T).foo(&pav) // ERROR "no method .*foo|requires named type or pointer to named"
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4463.go b/gcc/testsuite/go.test/test/fixedbugs/issue4463.go
index 70977ce..6ad1952 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4463.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4463.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4468.go b/gcc/testsuite/go.test/test/fixedbugs/issue4468.go
index ef0b46b..d26725e 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4468.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4468.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
@@ -19,8 +19,12 @@ type S struct {
}
func F() {
- go (F()) // ERROR "must be function call"
- defer (F()) // ERROR "must be function call"
+ go F // ERROR "must be function call"
+ defer F // ERROR "must be function call"
+ go (F) // ERROR "must be function call|must not be parenthesized"
+ defer (F) // ERROR "must be function call|must not be parenthesized"
+ go (F()) // ERROR "must be function call|must not be parenthesized"
+ defer (F()) // ERROR "must be function call|must not be parenthesized"
var s S
(&s.t).F()
go (&s.t).F()
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4470.go b/gcc/testsuite/go.test/test/fixedbugs/issue4470.go
index 5ed09ca..d922478 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4470.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4470.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4495.go b/gcc/testsuite/go.test/test/fixedbugs/issue4495.go
index 7ec1134..308acc2 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4495.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4495.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4517a.go b/gcc/testsuite/go.test/test/fixedbugs/issue4517a.go
index a1b6b57..83d42e7 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4517a.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4517a.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4517b.go b/gcc/testsuite/go.test/test/fixedbugs/issue4517b.go
index f04103f..34fa98f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4517b.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4517b.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4517c.go b/gcc/testsuite/go.test/test/fixedbugs/issue4517c.go
index 47b21cf..9023e0a 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4517c.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4517c.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4517d.go b/gcc/testsuite/go.test/test/fixedbugs/issue4517d.go
index 3d727d4..197c225 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4517d.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4517d.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4518.go b/gcc/testsuite/go.test/test/fixedbugs/issue4518.go
index e64b069..c482b0f 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4518.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4518.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
@@ -10,15 +10,13 @@
package main
-func DontInline() {}
-
+//go:noinline
func F(e interface{}) (int, int) {
- DontInline()
return 3, 7
}
+//go:noinline
func G() (int, int) {
- DontInline()
return 3, 7
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4529.go b/gcc/testsuite/go.test/test/fixedbugs/issue4529.go
index 4f37e7c..66b96c7 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4529.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4529.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4545.go b/gcc/testsuite/go.test/test/fixedbugs/issue4545.go
index c37ccef..534ba71 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4545.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4545.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4562.go b/gcc/testsuite/go.test/test/fixedbugs/issue4562.go
index 29d98b0..8c958f5 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4562.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4562.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4585.go b/gcc/testsuite/go.test/test/fixedbugs/issue4585.go
index ad1242d..9191ec5 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4585.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4585.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4590.dir/pkg1.go b/gcc/testsuite/go.test/test/fixedbugs/issue4590.dir/pkg1.go
index c447371..96cac0a 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4590.dir/pkg1.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4590.dir/pkg1.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4590.dir/pkg2.go b/gcc/testsuite/go.test/test/fixedbugs/issue4590.dir/pkg2.go
index 61c01d7..98bc2a5 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4590.dir/pkg2.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4590.dir/pkg2.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4590.dir/prog.go b/gcc/testsuite/go.test/test/fixedbugs/issue4590.dir/prog.go
index 3220e85..32055b2 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4590.dir/prog.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4590.dir/prog.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4614.go b/gcc/testsuite/go.test/test/fixedbugs/issue4614.go
index 1aa318c..ad378d8 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4614.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4614.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4618.go b/gcc/testsuite/go.test/test/fixedbugs/issue4618.go
index fe875b3..0ba9523 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4618.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4618.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4620.go b/gcc/testsuite/go.test/test/fixedbugs/issue4620.go
index 7b4ebf9..5aa2908 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4620.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4620.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4654.go b/gcc/testsuite/go.test/test/fixedbugs/issue4654.go
index d3f582b..76aff76 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4654.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4654.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4663.go b/gcc/testsuite/go.test/test/fixedbugs/issue4663.go
index edaee93..971290d 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4663.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4663.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4667.go b/gcc/testsuite/go.test/test/fixedbugs/issue4667.go
index 18d773c..31b3284 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4667.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4667.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4734.go b/gcc/testsuite/go.test/test/fixedbugs/issue4734.go
index 69f66f2..45e609d 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4734.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4734.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4748.go b/gcc/testsuite/go.test/test/fixedbugs/issue4748.go
index 73c7539..f7c77cf 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4748.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4748.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4752.go b/gcc/testsuite/go.test/test/fixedbugs/issue4752.go
index d6781e3..af7bb92 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4752.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4752.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4776.go b/gcc/testsuite/go.test/test/fixedbugs/issue4776.go
index 13781af..a1009ad 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4776.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4776.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4785.go b/gcc/testsuite/go.test/test/fixedbugs/issue4785.go
index c3dd629..d0bcd56 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4785.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4785.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4909a.go b/gcc/testsuite/go.test/test/fixedbugs/issue4909a.go
index aefe2d6..09e1b85 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4909a.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4909a.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue4964.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/issue4964.dir/a.go
index 2b9e44e..216f352 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue4964.dir/a.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue4964.dir/a.go
@@ -10,16 +10,14 @@ type T struct {
Pointer *int
}
-func dontinline() {}
-
+//go:noinline
func Store(t *T) {
global = t.Pointer
- dontinline()
}
+//go:noinline
func Store2(t *T) {
global2 = t.Pointer
- dontinline()
}
func Get() *int {
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue5002.go b/gcc/testsuite/go.test/test/fixedbugs/issue5002.go
index 1e74fa1..5ac119a 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue5002.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue5002.go
@@ -1,6 +1,6 @@
// build
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue5056.go b/gcc/testsuite/go.test/test/fixedbugs/issue5056.go
index a2cde2a..6fb444a 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue5056.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue5056.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue5172.go b/gcc/testsuite/go.test/test/fixedbugs/issue5172.go
index a6acbd3..ed92ac6 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue5172.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue5172.go
@@ -12,8 +12,15 @@ type foo struct {
x bar // ERROR "undefined"
}
+type T struct{}
+
+func (t T) Bar() {}
+
func main() {
var f foo
- go f.bar() // GCCGO_ERROR "undefined"
- defer f.bar() // GCCGO_ERROR "undefined"
+ go f.bar() // ERROR "undefined"
+ defer f.bar() // ERROR "undefined"
+
+ t := T{1} // ERROR "too many"
+ go t.Bar()
}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue5231.go b/gcc/testsuite/go.test/test/fixedbugs/issue5231.go
index 4039913..6bc8826 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue5231.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue5231.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue5358.go b/gcc/testsuite/go.test/test/fixedbugs/issue5358.go
index c2b1da9..25f1e52 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue5358.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue5358.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue5581.go b/gcc/testsuite/go.test/test/fixedbugs/issue5581.go
index 36a4ad6..8834b44 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue5581.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue5581.go
@@ -3,7 +3,7 @@
// Used to emit a spurious "invalid recursive type" error.
// See golang.org/issue/5581.
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue5698.go b/gcc/testsuite/go.test/test/fixedbugs/issue5698.go
index 035bbd3..081541c 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue5698.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue5698.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue5704.go b/gcc/testsuite/go.test/test/fixedbugs/issue5704.go
index 1dfa072..11b9a93 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue5704.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue5704.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue5809.go b/gcc/testsuite/go.test/test/fixedbugs/issue5809.go
index ca060b55..fc8eeef 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue5809.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue5809.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue5820.go b/gcc/testsuite/go.test/test/fixedbugs/issue5820.go
index 94de06d..1046d66 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue5820.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue5820.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue5841.go b/gcc/testsuite/go.test/test/fixedbugs/issue5841.go
index cfc4a50..2be1aee 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue5841.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue5841.go
@@ -1,6 +1,6 @@
// build
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue5856.go b/gcc/testsuite/go.test/test/fixedbugs/issue5856.go
index 35cadf8..f132588 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue5856.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue5856.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue5963.go b/gcc/testsuite/go.test/test/fixedbugs/issue5963.go
index 190e8f4..f828303 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue5963.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue5963.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue6004.go b/gcc/testsuite/go.test/test/fixedbugs/issue6004.go
index 45aaffd..2b3dcd9 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue6004.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue6004.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue6036.go b/gcc/testsuite/go.test/test/fixedbugs/issue6036.go
index 5f787c5..8ebef5a 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue6036.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue6036.go
@@ -1,7 +1,7 @@
-// +build amd64
+// +build !386,!arm,!mips,!mipsle,!amd64p32
// compile
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue6055.go b/gcc/testsuite/go.test/test/fixedbugs/issue6055.go
index 698f62a..4594348 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue6055.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue6055.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue6131.go b/gcc/testsuite/go.test/test/fixedbugs/issue6131.go
index 817e4a8..61548a2 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue6131.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue6131.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue6140.go b/gcc/testsuite/go.test/test/fixedbugs/issue6140.go
index d494933..dde7921 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue6140.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue6140.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue6247.go b/gcc/testsuite/go.test/test/fixedbugs/issue6247.go
index eea8f9c..2786786 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue6247.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue6247.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue6269.go b/gcc/testsuite/go.test/test/fixedbugs/issue6269.go
index af5feb7..2930f52 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue6269.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue6269.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue6298.go b/gcc/testsuite/go.test/test/fixedbugs/issue6298.go
index 6303dbe..ab3bfcd 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue6298.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue6298.go
@@ -3,7 +3,7 @@
// golang.org/issue/6298.
// Used to cause "internal error: typename ideal bool"
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue6513.dir/a.go b/gcc/testsuite/go.test/test/fixedbugs/issue6513.dir/a.go
index da90ca3..e5536fe 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue6513.dir/a.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue6513.dir/a.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue6513.dir/b.go b/gcc/testsuite/go.test/test/fixedbugs/issue6513.dir/b.go
index 3b35b2d..ce3d52e 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue6513.dir/b.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue6513.dir/b.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue6513.dir/main.go b/gcc/testsuite/go.test/test/fixedbugs/issue6513.dir/main.go
index f09b727..8d8c02b 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue6513.dir/main.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue6513.dir/main.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue6899.go b/gcc/testsuite/go.test/test/fixedbugs/issue6899.go
index a693bf2..d7f8578 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue6899.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue6899.go
@@ -1,6 +1,6 @@
-// cmpout
+// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue6977.go b/gcc/testsuite/go.test/test/fixedbugs/issue6977.go
new file mode 100644
index 0000000..4525e40
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue6977.go
@@ -0,0 +1,40 @@
+// errorcheck
+
+// 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 p
+
+import "io"
+
+// Alan's initial report.
+
+type I interface { f(); String() string }
+type J interface { g(); String() string }
+
+type IJ1 = interface { I; J }
+type IJ2 = interface { f(); g(); String() string }
+
+var _ = (*IJ1)(nil) == (*IJ2)(nil) // static assert that IJ1 and IJ2 are identical types
+
+// The canonical example.
+
+type ReadWriteCloser interface { io.ReadCloser; io.WriteCloser }
+
+// Some more cases.
+
+type M interface { m() }
+type M32 interface { m() int32 }
+type M64 interface { m() int64 }
+
+type U1 interface { m() }
+type U2 interface { m(); M }
+type U3 interface { M; m() }
+type U4 interface { M; M; M }
+type U5 interface { U1; U2; U3; U4 }
+
+type U6 interface { m(); m() } // ERROR "duplicate method .*m"
+type U7 interface { M32; m() } // ERROR "duplicate method .*m"
+type U8 interface { m(); M32 } // ERROR "duplicate method .*m"
+type U9 interface { M32; M64 } // ERROR "duplicate method .*m"
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue8042.go b/gcc/testsuite/go.test/test/fixedbugs/issue8042.go
new file mode 100644
index 0000000..5639f97
--- /dev/null
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue8042.go
@@ -0,0 +1,66 @@
+// compile
+
+// Copyright 2017 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.
+
+// Verify that gotos across non-variable declarations
+// are accepted.
+
+package p
+
+func _() {
+ goto L1
+ const x = 0
+L1:
+ goto L2
+ type T int
+L2:
+}
+
+func _() {
+ {
+ goto L1
+ }
+ const x = 0
+L1:
+ {
+ goto L2
+ }
+ type T int
+L2:
+}
+
+func _(d int) {
+ if d > 0 {
+ goto L1
+ } else {
+ goto L2
+ }
+ const x = 0
+L1:
+ switch d {
+ case 1:
+ goto L3
+ case 2:
+ default:
+ goto L4
+ }
+ type T1 int
+L2:
+ const y = 1
+L3:
+ for d > 0 {
+ if d < 10 {
+ goto L4
+ }
+ }
+ type T2 int
+L4:
+ select {
+ default:
+ goto L5
+ }
+ type T3 int
+L5:
+}
diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue887.go b/gcc/testsuite/go.test/test/fixedbugs/issue887.go
index 5bc193b..b68ba69 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue887.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue887.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/func6.go b/gcc/testsuite/go.test/test/func6.go
index 456cb49..5b2f9f2 100644
--- a/gcc/testsuite/go.test/test/func6.go
+++ b/gcc/testsuite/go.test/test/func6.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -9,7 +9,7 @@
package main
func main() {
- if func() bool { return true }() {} // 6g used to say this was a syntax error
+ if func() bool { return true }() {} // gc used to say this was a syntax error
if (func() bool { return true })() {}
if (func() bool { return true }()) {}
}
diff --git a/gcc/testsuite/go.test/test/func7.go b/gcc/testsuite/go.test/test/func7.go
index 2d646b6..3b22199 100644
--- a/gcc/testsuite/go.test/test/func7.go
+++ b/gcc/testsuite/go.test/test/func7.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -23,7 +23,7 @@ func g() int {
}
func main() {
- // 6g, 8g, 5g all used to evaluate g() before f().
+ // gc used to evaluate g() before f().
if f() < g() {
panic("wrong answer")
}
diff --git a/gcc/testsuite/go.test/test/func8.go b/gcc/testsuite/go.test/test/func8.go
index 1305180..9de01d4 100644
--- a/gcc/testsuite/go.test/test/func8.go
+++ b/gcc/testsuite/go.test/test/func8.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -21,16 +21,14 @@ func g() int {
var xy string
+//go:noinline
func x() bool {
- for false {
- } // no inlining
xy += "x"
return false
}
+//go:noinline
func y() string {
- for false {
- } // no inlining
xy += "y"
return "abc"
}
diff --git a/gcc/testsuite/go.test/test/funcdup.go b/gcc/testsuite/go.test/test/funcdup.go
index d15d685..7b05d12 100644
--- a/gcc/testsuite/go.test/test/funcdup.go
+++ b/gcc/testsuite/go.test/test/funcdup.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/funcdup2.go b/gcc/testsuite/go.test/test/funcdup2.go
index 1db1a39..9513ef4 100644
--- a/gcc/testsuite/go.test/test/funcdup2.go
+++ b/gcc/testsuite/go.test/test/funcdup2.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/gc2.go b/gcc/testsuite/go.test/test/gc2.go
index de52a4f..2f8eb9b 100644
--- a/gcc/testsuite/go.test/test/gc2.go
+++ b/gcc/testsuite/go.test/test/gc2.go
@@ -1,6 +1,7 @@
+// +build !nacl,!js
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -36,7 +37,7 @@ func main() {
}
runtime.ReadMemStats(memstats)
- obj := memstats.HeapObjects - st.HeapObjects
+ obj := int64(memstats.HeapObjects - st.HeapObjects)
if obj > N/5 {
fmt.Println("too many objects left:", obj)
os.Exit(1)
diff --git a/gcc/testsuite/go.test/test/golden.out b/gcc/testsuite/go.test/test/golden.out
deleted file mode 100644
index 742a5d3..0000000
--- a/gcc/testsuite/go.test/test/golden.out
+++ /dev/null
@@ -1,24 +0,0 @@
-
-== ./
-
-== ken/
-
-== chan/
-
-== interface/
-
-== syntax/
-
-== dwarf/
-
-== safe/
-
-== fixedbugs/
-
-=========== fixedbugs/bug429.go
-fatal error: all goroutines are asleep - deadlock!
-
-== bugs/
-
-=========== bugs/bug395.go
-bug395 is broken
diff --git a/gcc/testsuite/go.test/test/goprint.go b/gcc/testsuite/go.test/test/goprint.go
index cdaccf4..d44b259 100644
--- a/gcc/testsuite/go.test/test/goprint.go
+++ b/gcc/testsuite/go.test/test/goprint.go
@@ -1,6 +1,6 @@
-// cmpout
+// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -8,9 +8,25 @@
package main
-import "time"
+import (
+ "log"
+ "runtime"
+ "time"
+)
func main() {
+ numg0 := runtime.NumGoroutine()
+ deadline := time.Now().Add(10 * time.Second)
go println(42, true, false, true, 1.5, "world", (chan int)(nil), []int(nil), (map[string]int)(nil), (func())(nil), byte(255))
- time.Sleep(100*time.Millisecond)
+ for {
+ numg := runtime.NumGoroutine()
+ if numg > numg0 {
+ if time.Now().After(deadline) {
+ log.Fatalf("%d goroutines > initial %d after deadline", numg, numg0)
+ }
+ runtime.Gosched()
+ continue
+ }
+ break
+ }
}
diff --git a/gcc/testsuite/go.test/test/goto.go b/gcc/testsuite/go.test/test/goto.go
index ca477b3..d660c9c 100644
--- a/gcc/testsuite/go.test/test/goto.go
+++ b/gcc/testsuite/go.test/test/goto.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -40,7 +40,7 @@ L:
// goto across declaration not okay
func _() {
goto L // ERROR "goto L jumps over declaration of x at LINE+1|goto jumps over declaration"
- x := 1 // GCCGO_ERROR "defined here"
+ x := 1 // GCCGO_ERROR "defined here"
_ = x
L:
}
@@ -62,7 +62,7 @@ func _() {
x := 1
_ = x
}
- x := 1 // GCCGO_ERROR "defined here"
+ x := 1 // GCCGO_ERROR "defined here"
_ = x
L:
}
@@ -77,8 +77,8 @@ L:
// error shows first offending variable
func _() {
- goto L // ERROR "goto L jumps over declaration of x at LINE+1|goto jumps over declaration"
- x := 1 // GCCGO_ERROR "defined here"
+ goto L // ERROR "goto L jumps over declaration of y at LINE+3|goto jumps over declaration"
+ x := 1 // GCCGO_ERROR "defined here"
_ = x
y := 1
_ = y
@@ -87,8 +87,8 @@ L:
// goto not okay even if code path is dead
func _() {
- goto L // ERROR "goto L jumps over declaration of x at LINE+1|goto jumps over declaration"
- x := 1 // GCCGO_ERROR "defined here"
+ goto L // ERROR "goto L jumps over declaration of y at LINE+3|goto jumps over declaration"
+ x := 1 // GCCGO_ERROR "defined here"
_ = x
y := 1
_ = y
@@ -115,14 +115,14 @@ L:
// goto into inner block not okay
func _() {
goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
- { // GCCGO_ERROR "block starts here"
+ { // GCCGO_ERROR "block starts here"
L:
}
}
// goto backward into inner block still not okay
func _() {
- { // GCCGO_ERROR "block starts here"
+ { // GCCGO_ERROR "block starts here"
L:
}
goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
@@ -130,10 +130,10 @@ func _() {
// error shows first (outermost) offending block
func _() {
- goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
+ goto L // ERROR "goto L jumps into block starting at LINE+3|goto jumps into block"
{
{
- { // GCCGO_ERROR "block starts here"
+ { // GCCGO_ERROR "block starts here"
L:
}
}
@@ -145,7 +145,7 @@ func _() {
goto L // ERROR "goto L jumps into block starting at LINE+3|goto jumps into block"
x := 1
_ = x
- { // GCCGO_ERROR "block starts here"
+ { // GCCGO_ERROR "block starts here"
L:
}
}
@@ -179,30 +179,30 @@ L:
}
func _() {
- goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
- if true { // GCCGO_ERROR "block starts here"
+ goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
+ if true { // GCCGO_ERROR "block starts here"
L:
}
}
func _() {
- goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
- if true { // GCCGO_ERROR "block starts here"
+ goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
+ if true { // GCCGO_ERROR "block starts here"
L:
} else {
}
}
func _() {
- goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
+ goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
if true {
- } else { // GCCGO_ERROR "block starts here"
+ } else { // GCCGO_ERROR "block starts here"
L:
}
}
func _() {
- if false { // GCCGO_ERROR "block starts here"
+ if false { // GCCGO_ERROR "block starts here"
L:
} else {
goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
@@ -212,7 +212,7 @@ func _() {
func _() {
if true {
goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
- } else { // GCCGO_ERROR "block starts here"
+ } else { // GCCGO_ERROR "block starts here"
L:
}
}
@@ -220,7 +220,7 @@ func _() {
func _() {
if true {
goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
- } else if false { // GCCGO_ERROR "block starts here"
+ } else if false { // GCCGO_ERROR "block starts here"
L:
}
}
@@ -228,7 +228,7 @@ func _() {
func _() {
if true {
goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
- } else if false { // GCCGO_ERROR "block starts here"
+ } else if false { // GCCGO_ERROR "block starts here"
L:
} else {
}
@@ -241,9 +241,9 @@ func _() {
// really is LINE+1 (like in the previous test),
// even though it looks like it might be LINE+3 instead.
if true {
- goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
+ goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
} else if false {
- } else { // GCCGO_ERROR "block starts here"
+ } else { // GCCGO_ERROR "block starts here"
L:
}
}
@@ -287,14 +287,14 @@ func _() {
}
func _() {
- for { // GCCGO_ERROR "block starts here"
+ for { // GCCGO_ERROR "block starts here"
L:
}
goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
}
func _() {
- for { // GCCGO_ERROR "block starts here"
+ for { // GCCGO_ERROR "block starts here"
goto L
L1:
}
@@ -303,42 +303,42 @@ L:
}
func _() {
- for i < n { // GCCGO_ERROR "block starts here"
+ for i < n { // GCCGO_ERROR "block starts here"
L:
}
goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
}
func _() {
- for i = 0; i < n; i++ { // GCCGO_ERROR "block starts here"
+ for i = 0; i < n; i++ { // GCCGO_ERROR "block starts here"
L:
}
goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
}
func _() {
- for i = range x { // GCCGO_ERROR "block starts here"
+ for i = range x { // GCCGO_ERROR "block starts here"
L:
}
goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
}
func _() {
- for i = range c { // GCCGO_ERROR "block starts here"
+ for i = range c { // GCCGO_ERROR "block starts here"
L:
}
goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
}
func _() {
- for i = range m { // GCCGO_ERROR "block starts here"
+ for i = range m { // GCCGO_ERROR "block starts here"
L:
}
goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
}
func _() {
- for i = range s { // GCCGO_ERROR "block starts here"
+ for i = range s { // GCCGO_ERROR "block starts here"
L:
}
goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
@@ -395,29 +395,29 @@ func _() {
}
func _() {
- goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
+ goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
switch i {
case 0:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
}
}
func _() {
- goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
+ goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
switch i {
case 0:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
;
default:
}
}
func _() {
- goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
+ goto L // ERROR "goto L jumps into block starting at LINE+3|goto jumps into block"
switch i {
case 0:
default:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
}
}
@@ -426,14 +426,14 @@ func _() {
default:
goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
case 0:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
}
}
func _() {
switch i {
case 0:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
;
default:
goto L // ERROR "goto L jumps into block starting at LINE-4|goto jumps into block"
@@ -495,7 +495,7 @@ func _() {
goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
select {
case c <- 1:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
}
}
@@ -503,7 +503,7 @@ func _() {
goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
select {
case c <- 1:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
;
default:
}
@@ -514,7 +514,7 @@ func _() {
select {
case <-c:
default:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
}
}
@@ -523,14 +523,14 @@ func _() {
default:
goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
case <-c:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
}
}
func _() {
select {
case <-c:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
;
default:
goto L // ERROR "goto L jumps into block starting at LINE-4|goto jumps into block"
diff --git a/gcc/testsuite/go.test/test/helloworld.go b/gcc/testsuite/go.test/test/helloworld.go
index 5025ec9..06851d1 100644
--- a/gcc/testsuite/go.test/test/helloworld.go
+++ b/gcc/testsuite/go.test/test/helloworld.go
@@ -1,4 +1,4 @@
-// cmpout
+// run
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
diff --git a/gcc/testsuite/go.test/test/import2.dir/import2.go b/gcc/testsuite/go.test/test/import2.dir/import2.go
index 8bb1eb9..9c54a1b 100644
--- a/gcc/testsuite/go.test/test/import2.dir/import2.go
+++ b/gcc/testsuite/go.test/test/import2.dir/import2.go
@@ -1,4 +1,4 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/import2.dir/import3.go b/gcc/testsuite/go.test/test/import2.dir/import3.go
index d7fe37b..3bf9cb0 100644
--- a/gcc/testsuite/go.test/test/import2.dir/import3.go
+++ b/gcc/testsuite/go.test/test/import2.dir/import3.go
@@ -1,4 +1,4 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/import2.go b/gcc/testsuite/go.test/test/import2.go
index f8d0b0a..1ef1dd4 100644
--- a/gcc/testsuite/go.test/test/import2.go
+++ b/gcc/testsuite/go.test/test/import2.go
@@ -1,6 +1,6 @@
// compiledir
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/import5.go b/gcc/testsuite/go.test/test/import5.go
index 6480acf..8fdc8c3 100644
--- a/gcc/testsuite/go.test/test/import5.go
+++ b/gcc/testsuite/go.test/test/import5.go
@@ -21,35 +21,7 @@ import _ "go/parser"
//import "greek/αβ"
// Import paths must be strings.
-import 42 // ERROR "import statement"
-import 'a' // ERROR "import statement"
-import 3.14 // ERROR "import statement"
-import 0.25i // ERROR "import statement"
-
-// Each of these pairs tests both `` vs "" strings
-// and also use of invalid characters spelled out as
-// escape sequences and written directly.
-// For example `"\x00"` tests import "\x00"
-// while "`\x00`" tests import `<actual-NUL-byte>`.
-import "" // ERROR "import path"
-import `` // ERROR "import path"
-import "\x00" // ERROR "import path"
-import `\x00` // ERROR "import path"
-import "\x7f" // ERROR "import path"
-import `\x7f` // ERROR "import path"
-import "a!" // ERROR "import path"
-import `a!` // ERROR "import path"
-import "a b" // ERROR "import path"
-import `a b` // ERROR "import path"
-import "a\\b" // ERROR "import path"
-import `a\\b` // ERROR "import path"
-import "\"`a`\"" // ERROR "import path"
-import `\"a\"` // ERROR "import path"
-import "\x80\x80" // ERROR "import path"
-import `\x80\x80` // ERROR "import path"
-import "\xFFFD" // ERROR "import path"
-import `\xFFFD` // ERROR "import path"
-
-// Invalid local imports.
-import "/foo" // ERROR "import path cannot be absolute path"
-import "c:/foo" // ERROR "import path contains invalid character"
+import 42 // ERROR "import path must be a string"
+import 'a' // ERROR "import path must be a string"
+import 3.14 // ERROR "import path must be a string"
+import 0.25i // ERROR "import path must be a string"
diff --git a/gcc/testsuite/go.test/test/index.go b/gcc/testsuite/go.test/test/index.go
index a8c471b..91195ad 100644
--- a/gcc/testsuite/go.test/test/index.go
+++ b/gcc/testsuite/go.test/test/index.go
@@ -1,6 +1,6 @@
// skip
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -216,7 +216,7 @@ func main() {
thisPass := 0
if c == "c" && (a == "a" || a == "pa" || n == "n" || i == "i64big" || i == "i64bigger" || i == "huge" || i == "fbad") {
if i == "huge" {
- // Due to a detail of 6g's internals,
+ // Due to a detail of gc's internals,
// the huge constant errors happen in an
// earlier pass than the others and inhibits
// the next pass from running.
@@ -251,7 +251,7 @@ func main() {
if c == "" && (i == "fgood" || i == "fbad") {
return
}
- // Integral float constat is ok.
+ // Integral float constant is ok.
if c == "c" && n == "" && i == "fgood" {
if pass == 0 {
fmt.Fprintf(b, "\tuse(%s[%s])\n", pae, cni)
diff --git a/gcc/testsuite/go.test/test/index0.go b/gcc/testsuite/go.test/test/index0.go
index 04a1619..62f3392 100644
--- a/gcc/testsuite/go.test/test/index0.go
+++ b/gcc/testsuite/go.test/test/index0.go
@@ -1,6 +1,6 @@
// runoutput ./index.go
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/index1.go b/gcc/testsuite/go.test/test/index1.go
index e28efa35..40efc54 100644
--- a/gcc/testsuite/go.test/test/index1.go
+++ b/gcc/testsuite/go.test/test/index1.go
@@ -1,6 +1,6 @@
// errorcheckoutput ./index.go
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/index2.go b/gcc/testsuite/go.test/test/index2.go
index a7107cc..2a210cc 100644
--- a/gcc/testsuite/go.test/test/index2.go
+++ b/gcc/testsuite/go.test/test/index2.go
@@ -1,6 +1,6 @@
// errorcheckoutput ./index.go
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/init.go b/gcc/testsuite/go.test/test/init.go
index f468944..5e18228 100644
--- a/gcc/testsuite/go.test/test/init.go
+++ b/gcc/testsuite/go.test/test/init.go
@@ -9,13 +9,11 @@
package main
-import "runtime"
-
func init() {
}
func main() {
init() // ERROR "undefined.*init"
- runtime.init() // ERROR "unexported.*runtime\.init"
+ runtime.init() // ERROR "undefined.*runtime\.init|reference to undefined name"
var _ = init // ERROR "undefined.*init"
}
diff --git a/gcc/testsuite/go.test/test/init1.go b/gcc/testsuite/go.test/test/init1.go
index f6eda6e..0803dce 100644
--- a/gcc/testsuite/go.test/test/init1.go
+++ b/gcc/testsuite/go.test/test/init1.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -17,22 +17,30 @@ func init() {
go send(c)
<-c
- const chunk = 1 << 20
- memstats := new(runtime.MemStats)
- runtime.ReadMemStats(memstats)
- sys := memstats.Sys
- b := make([]byte, chunk)
+ const N = 1000
+ const MB = 1 << 20
+ b := make([]byte, MB)
for i := range b {
b[i] = byte(i%10 + '0')
}
s := string(b)
- for i := 0; i < 1000; i++ {
+
+ memstats := new(runtime.MemStats)
+ runtime.ReadMemStats(memstats)
+ sys, numGC := memstats.Sys, memstats.NumGC
+
+ // Generate 1,000 MB of garbage, only retaining 1 MB total.
+ for i := 0; i < N; i++ {
x = []byte(s)
}
+
+ // Verify that the garbage collector ran by seeing if we
+ // allocated fewer than N*MB bytes from the system.
runtime.ReadMemStats(memstats)
- sys1 := memstats.Sys
- if sys1-sys > chunk*50 {
- println("allocated 1000 chunks of", chunk, "and used ", sys1-sys, "memory")
+ sys1, numGC1 := memstats.Sys, memstats.NumGC
+ if sys1-sys >= N*MB || numGC1 == numGC {
+ println("allocated 1000 chunks of", MB, "and used ", sys1-sys, "memory")
+ println("numGC went", numGC, "to", numGC1)
panic("init1")
}
}
diff --git a/gcc/testsuite/go.test/test/initializerr.go b/gcc/testsuite/go.test/test/initializerr.go
index ca05414..5e2e9a9 100644
--- a/gcc/testsuite/go.test/test/initializerr.go
+++ b/gcc/testsuite/go.test/test/initializerr.go
@@ -23,6 +23,7 @@ var a2 = S { Y: 3, Z: 2, Y: 3 } // ERROR "duplicate"
var a3 = T { S{}, 2, 3, 4, 5, 6 } // ERROR "convert|too many"
var a4 = [5]byte{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } // ERROR "index|too many"
var a5 = []byte { x: 2 } // ERROR "index"
+var a6 = []byte{1: 1, 2: 2, 1: 3} // ERROR "duplicate"
var ok1 = S { } // should be ok
var ok2 = T { S: ok1 } // should be ok
diff --git a/gcc/testsuite/go.test/test/interface/embed2.go b/gcc/testsuite/go.test/test/interface/embed2.go
index 1636db7..df3e2e4 100644
--- a/gcc/testsuite/go.test/test/interface/embed2.go
+++ b/gcc/testsuite/go.test/test/interface/embed2.go
@@ -12,20 +12,25 @@ import "os"
const Value = 1e12
-type Inter interface { M() int64 }
+type Inter interface {
+ M() int64
+}
type T int64
+
func (t T) M() int64 { return int64(t) }
+
var t = T(Value)
var pt = &t
var ti Inter = t
var pti = &ti
-type S struct { Inter }
-var s = S{ ti }
+type S struct{ Inter }
+
+var s = S{ti}
var ps = &s
-type SP struct { *Inter } // ERROR "interface"
+type SP struct{ *Inter } // ERROR "interface"
var i Inter
var pi = &i
@@ -43,25 +48,25 @@ func main() {
check("t.M()", t.M())
check("pt.M()", pt.M())
check("ti.M()", ti.M())
- check("pti.M()", pti.M()) // ERROR "method"
+ check("pti.M()", pti.M()) // ERROR "pointer to interface, not interface"
check("s.M()", s.M())
check("ps.M()", ps.M())
i = t
check("i = t; i.M()", i.M())
- check("i = t; pi.M()", pi.M()) // ERROR "method"
+ check("i = t; pi.M()", pi.M()) // ERROR "pointer to interface, not interface"
i = pt
check("i = pt; i.M()", i.M())
- check("i = pt; pi.M()", pi.M()) // ERROR "method"
+ check("i = pt; pi.M()", pi.M()) // ERROR "pointer to interface, not interface"
i = s
check("i = s; i.M()", i.M())
- check("i = s; pi.M()", pi.M()) // ERROR "method"
+ check("i = s; pi.M()", pi.M()) // ERROR "pointer to interface, not interface"
i = ps
check("i = ps; i.M()", i.M())
- check("i = ps; pi.M()", pi.M()) // ERROR "method"
+ check("i = ps; pi.M()", pi.M()) // ERROR "pointer to interface, not interface"
if !ok {
println("BUG: interface10")
diff --git a/gcc/testsuite/go.test/test/interface/explicit.go b/gcc/testsuite/go.test/test/interface/explicit.go
index b10d02f..3f9451e 100644
--- a/gcc/testsuite/go.test/test/interface/explicit.go
+++ b/gcc/testsuite/go.test/test/interface/explicit.go
@@ -53,7 +53,12 @@ func main() {
i2 = I2(i) // ERROR "invalid|missing N method"
e = E(t) // ok
- t = T(e) // ERROR "need explicit|need type assertion|incompatible" "as type [*]T"
+ t = T(e) // ERROR "need explicit|need type assertion|incompatible"
+
+ // cannot type-assert non-interfaces
+ f := 2.0
+ _ = f.(int) // ERROR "non-interface type|only valid for interface types"
+
}
type M interface {
@@ -81,7 +86,6 @@ var m2 M = jj // ERROR "incompatible|wrong type for M method"
var m3 = M(ii) // ERROR "invalid|missing"
var m4 = M(jj) // ERROR "invalid|wrong type for M method"
-
type B1 interface {
_() // ERROR "methods must have a unique non-blank name"
}
diff --git a/gcc/testsuite/go.test/test/interface/noeq.go b/gcc/testsuite/go.test/test/interface/noeq.go
index 1c5166e..bb36893 100644
--- a/gcc/testsuite/go.test/test/interface/noeq.go
+++ b/gcc/testsuite/go.test/test/interface/noeq.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/interface/recursive1.dir/recursive1.go b/gcc/testsuite/go.test/test/interface/recursive1.dir/recursive1.go
index 441f0ec..8498cb5 100644
--- a/gcc/testsuite/go.test/test/interface/recursive1.dir/recursive1.go
+++ b/gcc/testsuite/go.test/test/interface/recursive1.dir/recursive1.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/interface/recursive1.dir/recursive2.go b/gcc/testsuite/go.test/test/interface/recursive1.dir/recursive2.go
index e8048c6..29385df 100644
--- a/gcc/testsuite/go.test/test/interface/recursive1.dir/recursive2.go
+++ b/gcc/testsuite/go.test/test/interface/recursive1.dir/recursive2.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/interface/recursive1.go b/gcc/testsuite/go.test/test/interface/recursive1.go
index 62f6108..ea2f4eb 100644
--- a/gcc/testsuite/go.test/test/interface/recursive1.go
+++ b/gcc/testsuite/go.test/test/interface/recursive1.go
@@ -1,6 +1,6 @@
// compiledir
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/ken/cplx0.go b/gcc/testsuite/go.test/test/ken/cplx0.go
index 665e52a..5d78dc0 100644
--- a/gcc/testsuite/go.test/test/ken/cplx0.go
+++ b/gcc/testsuite/go.test/test/ken/cplx0.go
@@ -1,4 +1,4 @@
-// cmpout
+// run
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
diff --git a/gcc/testsuite/go.test/test/ken/embed.go b/gcc/testsuite/go.test/test/ken/embed.go
index 9b35c56..f7ca066 100644
--- a/gcc/testsuite/go.test/test/ken/embed.go
+++ b/gcc/testsuite/go.test/test/ken/embed.go
@@ -253,7 +253,7 @@ func main() {
panic("fail")
}
- // run it thru an interface
+ // run it through an interface
i = s
s = i.(*S)
diff --git a/gcc/testsuite/go.test/test/ken/modconst.go b/gcc/testsuite/go.test/test/ken/modconst.go
index d88cf10..c27bf64 100644
--- a/gcc/testsuite/go.test/test/ken/modconst.go
+++ b/gcc/testsuite/go.test/test/ken/modconst.go
@@ -4,7 +4,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Test integer modulus by contstants.
+// Test integer modulus by constants.
package main
diff --git a/gcc/testsuite/go.test/test/ken/string.go b/gcc/testsuite/go.test/test/ken/string.go
index 6df8dc4..7bb3cab 100644
--- a/gcc/testsuite/go.test/test/ken/string.go
+++ b/gcc/testsuite/go.test/test/ken/string.go
@@ -1,4 +1,4 @@
-// cmpout
+// run
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
diff --git a/gcc/testsuite/go.test/test/label.go b/gcc/testsuite/go.test/test/label.go
index b30c27e..7deead6 100644
--- a/gcc/testsuite/go.test/test/label.go
+++ b/gcc/testsuite/go.test/test/label.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -17,8 +17,7 @@ L1: // ERROR "label .*L1.* defined and not used"
for {
}
L2: // ERROR "label .*L2.* defined and not used"
- select {
- }
+ select {}
L3: // ERROR "label .*L3.* defined and not used"
switch {
}
@@ -59,4 +58,8 @@ L10:
default:
break L10
}
+
+ goto L10
+
+ goto go2 // ERROR "label go2 not defined|reference to undefined label .*go2"
}
diff --git a/gcc/testsuite/go.test/test/label1.go b/gcc/testsuite/go.test/test/label1.go
index f923a18..a8eaecb 100644
--- a/gcc/testsuite/go.test/test/label1.go
+++ b/gcc/testsuite/go.test/test/label1.go
@@ -1,10 +1,9 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
-
// Verify that erroneous labels are caught by the compiler.
// This set is caught by pass 2. That's why this file is label1.go.
// Does not compile.
@@ -13,7 +12,19 @@ package main
var x int
-func f() {
+func f1() {
+ switch x {
+ case 1:
+ continue // ERROR "continue is not in a loop$|continue statement not within for"
+ }
+ select {
+ default:
+ continue // ERROR "continue is not in a loop$|continue statement not within for"
+ }
+
+}
+
+func f2() {
L1:
for {
if x == 0 {
@@ -32,11 +43,17 @@ L2:
break L2
}
if x == 1 {
- continue L2 // ERROR "invalid continue label .*L2"
+ continue L2 // ERROR "invalid continue label .*L2|continue is not in a loop$"
}
goto L2
}
+ for {
+ if x == 1 {
+ continue L2 // ERROR "invalid continue label .*L2"
+ }
+ }
+
L3:
switch {
case x > 10:
@@ -44,7 +61,7 @@ L3:
break L3
}
if x == 12 {
- continue L3 // ERROR "invalid continue label .*L3"
+ continue L3 // ERROR "invalid continue label .*L3|continue is not in a loop$"
}
goto L3
}
@@ -55,7 +72,7 @@ L4:
break L4 // ERROR "invalid break label .*L4"
}
if x == 14 {
- continue L4 // ERROR "invalid continue label .*L4"
+ continue L4 // ERROR "invalid continue label .*L4|continue is not in a loop$"
}
if x == 15 {
goto L4
@@ -63,12 +80,12 @@ L4:
}
L5:
- f()
+ f2()
if x == 16 {
break L5 // ERROR "invalid break label .*L5"
}
if x == 17 {
- continue L5 // ERROR "invalid continue label .*L5"
+ continue L5 // ERROR "invalid continue label .*L5|continue is not in a loop$"
}
if x == 18 {
goto L5
@@ -85,4 +102,21 @@ L5:
goto L1
}
}
+
+ continue // ERROR "continue is not in a loop$|continue statement not within for"
+ for {
+ continue on // ERROR "continue label not defined: on|invalid continue label .*on"
+ }
+
+ break // ERROR "break is not in a loop, switch, or select|break statement not within for or switch or select"
+ for {
+ break dance // ERROR "break label not defined: dance|invalid break label .*dance"
+ }
+
+ for {
+ switch x {
+ case 1:
+ continue
+ }
+ }
}
diff --git a/gcc/testsuite/go.test/test/linkx.go b/gcc/testsuite/go.test/test/linkx.go
index 12d446f..4f85b24 100644
--- a/gcc/testsuite/go.test/test/linkx.go
+++ b/gcc/testsuite/go.test/test/linkx.go
@@ -1,20 +1,38 @@
-// $G $D/$F.go && $L -X main.tbd hello $F.$A && ./$A.out
+// skip
-// NOTE: This test is not run by 'run.go' and so not run by all.bash.
-// To run this test you must use the ./run shell script.
-
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
// Test the -X facility of the gc linker (6l etc.).
+// This test is run by linkx_run.go.
package main
+import "fmt"
+
var tbd string
+var overwrite string = "dibs"
+
+var tbdcopy = tbd
+var overwritecopy = overwrite
+var arraycopy = [2]string{tbd, overwrite}
+
+var b bool
+var x int
func main() {
- if tbd != "hello" {
- println("BUG: test/linkx", len(tbd), tbd)
+ fmt.Println(tbd)
+ fmt.Println(tbdcopy)
+ fmt.Println(arraycopy[0])
+
+ fmt.Println(overwrite)
+ fmt.Println(overwritecopy)
+ fmt.Println(arraycopy[1])
+
+ // Check non-string symbols are not overwritten.
+ // This also make them used.
+ if b || x != 0 {
+ panic("b or x overwritten")
}
}
diff --git a/gcc/testsuite/go.test/test/map.go b/gcc/testsuite/go.test/test/map.go
index 485e743..2c1cf8a 100644
--- a/gcc/testsuite/go.test/test/map.go
+++ b/gcc/testsuite/go.test/test/map.go
@@ -5,7 +5,7 @@
// license that can be found in the LICENSE file.
// Test maps, almost exhaustively.
-// NaN complexity test is in mapnan.go.
+// Complexity (linearity) test is in maplinear.go.
package main
diff --git a/gcc/testsuite/go.test/test/map1.go b/gcc/testsuite/go.test/test/map1.go
index 6f1a1c8..b4aa707 100644
--- a/gcc/testsuite/go.test/test/map1.go
+++ b/gcc/testsuite/go.test/test/map1.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -9,8 +9,6 @@
package main
-func main() {}
-
type v bool
var (
@@ -60,3 +58,11 @@ type T5 *int
type T6 struct { F T5 }
type T7 *T4
type T8 struct { F *T7 }
+
+func main() {
+ m := make(map[int]int)
+ delete() // ERROR "missing arguments|not enough arguments"
+ delete(m) // ERROR "missing second \(key\) argument|not enough arguments"
+ delete(m, 2, 3) // ERROR "too many arguments"
+ delete(1, m) // ERROR "first argument to delete must be map|argument 1 must be a map"
+}
diff --git a/gcc/testsuite/go.test/test/mapnan.go b/gcc/testsuite/go.test/test/mapnan.go
deleted file mode 100644
index f081cab..0000000
--- a/gcc/testsuite/go.test/test/mapnan.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// +build darwin linux
-// run
-
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Test that NaNs in maps don't go quadratic.
-
-package main
-
-import (
- "fmt"
- "math"
- "time"
-)
-
-func main() {
-
- // Test that NaNs in maps don't go quadratic.
- t := func(n int) time.Duration {
- t1 := time.Now()
- m := map[float64]int{}
- nan := math.NaN()
- for i := 0; i < n; i++ {
- m[nan] = 1
- }
- if len(m) != n {
- panic("wrong size map after nan insertion")
- }
- return time.Since(t1)
- }
-
- // Depending on the machine and OS, this test might be too fast
- // to measure with accurate enough granularity. On failure,
- // make it run longer, hoping that the timing granularity
- // is eventually sufficient.
-
- n := 30000 // ~8ms user time on a Mid 2011 MacBook Air (1.8 GHz Core i7)
- fails := 0
- for {
- t1 := t(n)
- t2 := t(2 * n)
- // should be 2x (linear); allow up to 3x
- if t2 < 3*t1 {
- return
- }
- fails++
- if fails == 6 {
- panic(fmt.Sprintf("too slow: %d inserts: %v; %d inserts: %v\n", n, t1, 2*n, t2))
- }
- if fails < 4 {
- n *= 2
- }
- }
-}
diff --git a/gcc/testsuite/go.test/test/method1.go b/gcc/testsuite/go.test/test/method1.go
index 365b8ca..bb8c81d 100644
--- a/gcc/testsuite/go.test/test/method1.go
+++ b/gcc/testsuite/go.test/test/method1.go
@@ -9,12 +9,16 @@
package main
-type T struct { }
-func (t *T) M(int, string) // GCCGO_ERROR "previous"
-func (t *T) M(int, float64) { } // ERROR "redeclared|redefinition"
+type T struct{}
-func f(int, string) // GCCGO_ERROR "previous"
-func f(int, float64) { } // ERROR "redeclared|redefinition"
+func (t *T) M(int, string) // GCCGO_ERROR "previous"
+func (t *T) M(int, float64) {} // ERROR "redeclared|redefinition"
-func g(a int, b string) // GCCGO_ERROR "previous"
-func g(a int, c string) // ERROR "redeclared|redefinition"
+func (t T) H() // GCCGO_ERROR "previous"
+func (t *T) H() {} // ERROR "redeclared|redefinition"
+
+func f(int, string) // GCCGO_ERROR "previous"
+func f(int, float64) {} // ERROR "redeclared|redefinition"
+
+func g(a int, b string) // GCCGO_ERROR "previous"
+func g(a int, c string) // ERROR "redeclared|redefinition"
diff --git a/gcc/testsuite/go.test/test/method2.go b/gcc/testsuite/go.test/test/method2.go
index aaa850e..ac1d771 100644
--- a/gcc/testsuite/go.test/test/method2.go
+++ b/gcc/testsuite/go.test/test/method2.go
@@ -33,5 +33,9 @@ var _ = (*Val).val // ERROR "method"
var v Val
var pv = &v
-var _ = pv.val() // ERROR "method"
-var _ = pv.val // ERROR "method"
+var _ = pv.val() // ERROR "undefined|pointer to interface"
+var _ = pv.val // ERROR "undefined|pointer to interface"
+
+func (t *T) g() int { return t.a }
+
+var _ = (T).g() // ERROR "needs pointer receiver|undefined|method requires pointer"
diff --git a/gcc/testsuite/go.test/test/method4.dir/prog.go b/gcc/testsuite/go.test/test/method4.dir/prog.go
index 77d580c..cb5cf65f 100644
--- a/gcc/testsuite/go.test/test/method4.dir/prog.go
+++ b/gcc/testsuite/go.test/test/method4.dir/prog.go
@@ -73,7 +73,14 @@ func main() {
f4 := I2.Sum
eq(f4(t1, a, 17), 27)
eq(f4(t2, a, 18), 28)
-
+
+ // issue 6723
+ f5 := (interface {
+ I2
+ }).Sum
+ eq(f5(t1, a, 19), 29)
+ eq(f5(t2, a, 20), 30)
+
mt1 := method4a.T1(4)
mt2 := &method4a.T2{4}
diff --git a/gcc/testsuite/go.test/test/method5.go b/gcc/testsuite/go.test/test/method5.go
index 36508f2..d87bb6f 100644
--- a/gcc/testsuite/go.test/test/method5.go
+++ b/gcc/testsuite/go.test/test/method5.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/named.go b/gcc/testsuite/go.test/test/named.go
index d0330ab..9763c76 100644
--- a/gcc/testsuite/go.test/test/named.go
+++ b/gcc/testsuite/go.test/test/named.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/named1.go b/gcc/testsuite/go.test/test/named1.go
index 4f122e4..7feae13 100644
--- a/gcc/testsuite/go.test/test/named1.go
+++ b/gcc/testsuite/go.test/test/named1.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
@@ -41,21 +41,21 @@ func main() {
asBool(1 != 2) // ok now
asBool(i < j) // ok now
- _, b = m[2]
+ _, b = m[2] // ok now
var inter interface{}
- _, b = inter.(Map)
+ _, b = inter.(Map) // ok now
_ = b
var minter interface {
M()
}
- _, b = minter.(Map)
+ _, b = minter.(Map) // ok now
_ = b
_, bb := <-c
asBool(bb) // ERROR "cannot use.*type bool.*as type Bool"
- _, b = <-c
+ _, b = <-c // ok now
_ = b
asString(String(slice)) // ok
diff --git a/gcc/testsuite/go.test/test/nilcheck.go b/gcc/testsuite/go.test/test/nilcheck.go
index fe05d05..6879438 100644
--- a/gcc/testsuite/go.test/test/nilcheck.go
+++ b/gcc/testsuite/go.test/test/nilcheck.go
@@ -1,6 +1,6 @@
// errorcheck -0 -N -d=nil
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -17,7 +17,7 @@ type Struct struct {
type BigStruct struct {
X int
Y float64
- A [1<<20]int
+ A [1 << 20]int
Z string
}
@@ -29,86 +29,86 @@ type Empty1 struct {
}
var (
- intp *int
- arrayp *[10]int
- array0p *[0]int
- bigarrayp *[1<<26]int
- structp *Struct
+ intp *int
+ arrayp *[10]int
+ array0p *[0]int
+ bigarrayp *[1 << 26]int
+ structp *Struct
bigstructp *BigStruct
- emptyp *Empty
- empty1p *Empty1
+ emptyp *Empty
+ empty1p *Empty1
)
func f1() {
- _ = *intp // ERROR "nil check"
- _ = *arrayp // ERROR "nil check"
+ _ = *intp // ERROR "nil check"
+ _ = *arrayp // ERROR "nil check"
_ = *array0p // ERROR "nil check"
_ = *array0p // ERROR "nil check"
- _ = *intp // ERROR "nil check"
- _ = *arrayp // ERROR "nil check"
+ _ = *intp // ERROR "nil check"
+ _ = *arrayp // ERROR "nil check"
_ = *structp // ERROR "nil check"
- _ = *emptyp // ERROR "nil check"
- _ = *arrayp // ERROR "nil check"
+ _ = *emptyp // ERROR "nil check"
+ _ = *arrayp // ERROR "nil check"
}
func f2() {
var (
- intp *int
- arrayp *[10]int
- array0p *[0]int
- bigarrayp *[1<<20]int
- structp *Struct
+ intp *int
+ arrayp *[10]int
+ array0p *[0]int
+ bigarrayp *[1 << 20]int
+ structp *Struct
bigstructp *BigStruct
- emptyp *Empty
- empty1p *Empty1
+ emptyp *Empty
+ empty1p *Empty1
)
- _ = *intp // ERROR "nil check"
- _ = *arrayp // ERROR "nil check"
- _ = *array0p // ERROR "nil check"
- _ = *array0p // ERROR "nil check"
- _ = *intp // ERROR "nil check"
- _ = *arrayp // ERROR "nil check"
- _ = *structp // ERROR "nil check"
- _ = *emptyp // ERROR "nil check"
- _ = *arrayp // ERROR "nil check"
- _ = *bigarrayp // ERROR "nil check"
+ _ = *intp // ERROR "nil check"
+ _ = *arrayp // ERROR "nil check"
+ _ = *array0p // ERROR "nil check"
+ _ = *array0p // ERROR "nil check"
+ _ = *intp // ERROR "nil check"
+ _ = *arrayp // ERROR "nil check"
+ _ = *structp // ERROR "nil check"
+ _ = *emptyp // ERROR "nil check"
+ _ = *arrayp // ERROR "nil check"
+ _ = *bigarrayp // ERROR "nil check"
_ = *bigstructp // ERROR "nil check"
- _ = *empty1p // ERROR "nil check"
+ _ = *empty1p // ERROR "nil check"
}
func fx10k() *[10000]int
-var b bool
+var b bool
func f3(x *[10000]int) {
// Using a huge type and huge offsets so the compiler
// does not expect the memory hardware to fault.
_ = x[9999] // ERROR "nil check"
-
+
for {
if x[9999] != 0 { // ERROR "nil check"
break
}
}
-
- x = fx10k()
+
+ x = fx10k()
_ = x[9999] // ERROR "nil check"
if b {
_ = x[9999] // ERROR "nil check"
} else {
_ = x[9999] // ERROR "nil check"
- }
+ }
_ = x[9999] // ERROR "nil check"
- x = fx10k()
+ x = fx10k()
if b {
_ = x[9999] // ERROR "nil check"
} else {
_ = x[9999] // ERROR "nil check"
- }
+ }
_ = x[9999] // ERROR "nil check"
-
+
fx10k()
// This one is a bit redundant, if we figured out that
// x wasn't going to change across the function call.
@@ -138,7 +138,7 @@ func f3b() {
_ = &x[9] // ERROR "nil check"
}
-func fx10() *[10]int
+func fx10() *[10]int
func f4(x *[10]int) {
// Most of these have no checks because a real memory reference follows,
@@ -146,33 +146,33 @@ func f4(x *[10]int) {
// in the first unmapped page of memory.
_ = x[9] // ERROR "nil check"
-
+
for {
if x[9] != 0 { // ERROR "nil check"
break
}
}
-
- x = fx10()
+
+ x = fx10()
_ = x[9] // ERROR "nil check"
if b {
_ = x[9] // ERROR "nil check"
} else {
_ = x[9] // ERROR "nil check"
- }
+ }
_ = x[9] // ERROR "nil check"
- x = fx10()
+ x = fx10()
if b {
_ = x[9] // ERROR "nil check"
} else {
_ = &x[9] // ERROR "nil check"
- }
+ }
_ = x[9] // ERROR "nil check"
-
+
fx10()
_ = x[9] // ERROR "nil check"
-
+
x = fx10()
y := fx10()
_ = &x[9] // ERROR "nil check"
@@ -182,3 +182,8 @@ func f4(x *[10]int) {
_ = &x[9] // ERROR "nil check"
}
+func f5(m map[string]struct{}) bool {
+ // Existence-only map lookups should not generate a nil check
+ _, ok := m[""]
+ return ok
+}
diff --git a/gcc/testsuite/go.test/test/nilptr.go b/gcc/testsuite/go.test/test/nilptr.go
index 9631d16..c9a044d 100644
--- a/gcc/testsuite/go.test/test/nilptr.go
+++ b/gcc/testsuite/go.test/test/nilptr.go
@@ -1,12 +1,16 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
// Test that the implementation catches nil ptr indirection
// in a large address space.
+// +build !aix
+// +build !darwin !arm64
+// Address space starts at 1<<32 on AIX and on darwin/arm64, so dummy is too far.
+
package main
import "unsafe"
diff --git a/gcc/testsuite/go.test/test/nilptr2.go b/gcc/testsuite/go.test/test/nilptr2.go
index d2f4c91..8a85b6d 100644
--- a/gcc/testsuite/go.test/test/nilptr2.go
+++ b/gcc/testsuite/go.test/test/nilptr2.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/nilptr3.go b/gcc/testsuite/go.test/test/nilptr3.go
index 08597a0..e0f2ed9 100644
--- a/gcc/testsuite/go.test/test/nilptr3.go
+++ b/gcc/testsuite/go.test/test/nilptr3.go
@@ -1,6 +1,9 @@
// errorcheck -0 -d=nil
-// Copyright 2013 The Go Authors. All rights reserved.
+// +build !wasm
+// +build !aix
+
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -17,7 +20,7 @@ type Struct struct {
type BigStruct struct {
X int
Y float64
- A [1<<20]int
+ A [1 << 20]int
Z string
}
@@ -29,99 +32,100 @@ type Empty1 struct {
}
var (
- intp *int
- arrayp *[10]int
- array0p *[0]int
- bigarrayp *[1<<26]int
- structp *Struct
+ intp *int
+ arrayp *[10]int
+ array0p *[0]int
+ bigarrayp *[1 << 26]int
+ structp *Struct
bigstructp *BigStruct
- emptyp *Empty
- empty1p *Empty1
+ emptyp *Empty
+ empty1p *Empty1
)
func f1() {
_ = *intp // ERROR "generated nil check"
-
+
// This one should be removed but the block copy needs
// to be turned into its own pseudo-op in order to see
// the indirect.
_ = *arrayp // ERROR "generated nil check"
-
- // 0-byte indirect doesn't suffice
+
+ // 0-byte indirect doesn't suffice.
+ // we don't registerize globals, so there are no removed.* nil checks.
_ = *array0p // ERROR "generated nil check"
- _ = *array0p // ERROR "removed repeated nil check" 386
+ _ = *array0p // ERROR "removed nil check"
- _ = *intp // ERROR "removed repeated nil check"
- _ = *arrayp // ERROR "removed repeated nil check"
+ _ = *intp // ERROR "removed nil check"
+ _ = *arrayp // ERROR "removed nil check"
_ = *structp // ERROR "generated nil check"
- _ = *emptyp // ERROR "generated nil check"
- _ = *arrayp // ERROR "removed repeated nil check"
+ _ = *emptyp // ERROR "generated nil check"
+ _ = *arrayp // ERROR "removed nil check"
}
func f2() {
var (
- intp *int
- arrayp *[10]int
- array0p *[0]int
- bigarrayp *[1<<20]int
- structp *Struct
+ intp *int
+ arrayp *[10]int
+ array0p *[0]int
+ bigarrayp *[1 << 20]int
+ structp *Struct
bigstructp *BigStruct
- emptyp *Empty
- empty1p *Empty1
+ emptyp *Empty
+ empty1p *Empty1
)
- _ = *intp // ERROR "generated nil check"
- _ = *arrayp // ERROR "generated nil check"
- _ = *array0p // ERROR "generated nil check"
- _ = *array0p // ERROR "removed repeated nil check"
- _ = *intp // ERROR "removed repeated nil check"
- _ = *arrayp // ERROR "removed repeated nil check"
- _ = *structp // ERROR "generated nil check"
- _ = *emptyp // ERROR "generated nil check"
- _ = *arrayp // ERROR "removed repeated nil check"
- _ = *bigarrayp // ERROR "generated nil check" ARM removed nil check before indirect!!
+ _ = *intp // ERROR "generated nil check"
+ _ = *arrayp // ERROR "generated nil check"
+ _ = *array0p // ERROR "generated nil check"
+ _ = *array0p // ERROR "removed.* nil check"
+ _ = *intp // ERROR "removed.* nil check"
+ _ = *arrayp // ERROR "removed.* nil check"
+ _ = *structp // ERROR "generated nil check"
+ _ = *emptyp // ERROR "generated nil check"
+ _ = *arrayp // ERROR "removed.* nil check"
+ _ = *bigarrayp // ERROR "generated nil check" ARM removed nil check before indirect!!
_ = *bigstructp // ERROR "generated nil check"
- _ = *empty1p // ERROR "generated nil check"
+ _ = *empty1p // ERROR "generated nil check"
}
func fx10k() *[10000]int
-var b bool
+var b bool
func f3(x *[10000]int) {
// Using a huge type and huge offsets so the compiler
// does not expect the memory hardware to fault.
_ = x[9999] // ERROR "generated nil check"
-
+
for {
- if x[9999] != 0 { // ERROR "generated nil check"
+ if x[9999] != 0 { // ERROR "removed nil check"
break
}
}
-
- x = fx10k()
+
+ x = fx10k()
_ = x[9999] // ERROR "generated nil check"
if b {
- _ = x[9999] // ERROR "removed repeated nil check"
+ _ = x[9999] // ERROR "removed.* nil check"
} else {
- _ = x[9999] // ERROR "removed repeated nil check"
- }
- _ = x[9999] // ERROR "generated nil check"
+ _ = x[9999] // ERROR "removed.* nil check"
+ }
+ _ = x[9999] // ERROR "removed nil check"
- x = fx10k()
+ x = fx10k()
if b {
_ = x[9999] // ERROR "generated nil check"
} else {
_ = x[9999] // ERROR "generated nil check"
- }
+ }
_ = x[9999] // ERROR "generated nil check"
-
+
fx10k()
// This one is a bit redundant, if we figured out that
// x wasn't going to change across the function call.
// But it's a little complex to do and in practice doesn't
// matter enough.
- _ = x[9999] // ERROR "generated nil check"
+ _ = x[9999] // ERROR "removed nil check"
}
func f3a() {
@@ -130,7 +134,7 @@ func f3a() {
z := fx10k()
_ = &x[9] // ERROR "generated nil check"
y = z
- _ = &x[9] // ERROR "removed repeated nil check"
+ _ = &x[9] // ERROR "removed.* nil check"
x = y
_ = &x[9] // ERROR "generated nil check"
}
@@ -140,52 +144,108 @@ func f3b() {
y := fx10k()
_ = &x[9] // ERROR "generated nil check"
y = x
- _ = &x[9] // ERROR "removed repeated nil check"
+ _ = &x[9] // ERROR "removed.* nil check"
x = y
- _ = &x[9] // ERROR "removed repeated nil check"
+ _ = &x[9] // ERROR "removed.* nil check"
}
-func fx10() *[10]int
+func fx10() *[10]int
func f4(x *[10]int) {
// Most of these have no checks because a real memory reference follows,
// and the offset is small enough that if x is nil, the address will still be
// in the first unmapped page of memory.
- _ = x[9] // ERROR "removed nil check before indirect"
-
+ _ = x[9] // ERROR "generated nil check" // bug: would like to remove this check (but nilcheck and load are in different blocks)
+
for {
- if x[9] != 0 { // ERROR "removed nil check before indirect"
+ if x[9] != 0 { // ERROR "removed nil check"
break
}
}
-
- x = fx10()
- _ = x[9] // ERROR "removed nil check before indirect"
+
+ x = fx10()
+ _ = x[9] // ERROR "generated nil check" // bug would like to remove before indirect
if b {
- _ = x[9] // ERROR "removed nil check before indirect"
+ _ = x[9] // ERROR "removed nil check"
} else {
- _ = x[9] // ERROR "removed nil check before indirect"
+ _ = x[9] // ERROR "removed nil check"
}
- _ = x[9] // ERROR "removed nil check before indirect"
+ _ = x[9] // ERROR "removed nil check"
- x = fx10()
+ x = fx10()
if b {
- _ = x[9] // ERROR "removed nil check before indirect"
+ _ = x[9] // ERROR "generated nil check" // bug would like to remove before indirect
} else {
_ = &x[9] // ERROR "generated nil check"
- }
- _ = x[9] // ERROR "removed nil check before indirect"
-
+ }
+ _ = x[9] // ERROR "generated nil check" // bug would like to remove before indirect
+
fx10()
- _ = x[9] // ERROR "removed nil check before indirect"
-
+ _ = x[9] // ERROR "removed nil check"
+
x = fx10()
y := fx10()
_ = &x[9] // ERROR "generated nil check"
y = x
- _ = &x[9] // ERROR "removed repeated nil check"
+ _ = &x[9] // ERROR "removed[a-z ]* nil check"
x = y
- _ = &x[9] // ERROR "removed repeated nil check"
+ _ = &x[9] // ERROR "removed[a-z ]* nil check"
+}
+
+func m1(m map[int][80]byte) byte {
+ v := m[3] // ERROR "removed nil check"
+ return v[5]
+}
+func m2(m map[int][800]byte) byte {
+ v := m[3] // ERROR "removed nil check"
+ return v[5]
+}
+func m3(m map[int][80]byte) (byte, bool) {
+ v, ok := m[3] // ERROR "removed nil check"
+ return v[5], ok
+}
+func m4(m map[int][800]byte) (byte, bool) {
+ v, ok := m[3] // ERROR "removed nil check"
+ return v[5], ok
+}
+func p1() byte {
+ p := new([100]byte)
+ return p[5] // ERROR "removed nil check"
+}
+
+// make sure not to do nil check for access of PAUTOHEAP
+//go:noinline
+func (p *Struct) m() {}
+func c1() {
+ var x Struct
+ func() { x.m() }() // ERROR "removed nil check"
+}
+
+type SS struct {
+ x byte
+}
+
+type TT struct {
+ SS
}
+func f(t *TT) *byte {
+ // See issue 17242.
+ s := &t.SS // ERROR "generated nil check"
+ return &s.x // ERROR "removed nil check"
+}
+
+// make sure not to do nil check for newobject
+func f7() (*Struct, float64) {
+ t := new(Struct)
+ p := &t.Y // ERROR "removed nil check"
+ return t, *p // ERROR "removed nil check"
+}
+
+func f9() []int {
+ x := new([1]int)
+ x[0] = 1 // ERROR "removed nil check"
+ y := x[:] // ERROR "removed nil check"
+ return y
+}
diff --git a/gcc/testsuite/go.test/test/nul1.go b/gcc/testsuite/go.test/test/nul1.go
index 20426b4..fbba198 100644
--- a/gcc/testsuite/go.test/test/nul1.go
+++ b/gcc/testsuite/go.test/test/nul1.go
@@ -36,7 +36,7 @@ var y = ` + "`in raw string \x00 foo`" + ` // ERROR "NUL"
/* in other comment ` + "\x00" + ` */ // ERROR "NUL"
-/* in source code */ ` + "\x00" + `// ERROR "NUL" "illegal character"
+/* in source code */ ` + "\x00" + `// ERROR "NUL"
var xx = "in string ` + "\xc2\xff" + `" // ERROR "UTF-8"
@@ -47,10 +47,9 @@ var yy = ` + "`in raw string \xff foo`" + ` // ERROR "UTF-8"
/* in other comment ` + "\xe0\x00\x00" + ` */ // ERROR "UTF-8|NUL"
/* in variable name */
-var z` + "\xc1\x81" + ` int // ERROR "UTF-8" "invalid identifier character"
+var z` + "\xc1\x81" + ` int // ERROR "UTF-8"
-/* in source code */ ` + "var \xc2A int" + `// ERROR "UTF-8" "invalid identifier character"
+/* in source code */ ` + "var \xc2A int" + `// ERROR "UTF-8"
`)
}
-
diff --git a/gcc/testsuite/go.test/test/peano.go b/gcc/testsuite/go.test/test/peano.go
index 745f515..1102a97 100644
--- a/gcc/testsuite/go.test/test/peano.go
+++ b/gcc/testsuite/go.test/test/peano.go
@@ -9,6 +9,8 @@
package main
+import "runtime"
+
type Number *Number
// -------------------------------------
@@ -116,7 +118,11 @@ var results = [...]int{
}
func main() {
- for i := 0; i <= 9; i++ {
+ max := 9
+ if runtime.GOARCH == "wasm" {
+ max = 7 // stack size is limited
+ }
+ for i := 0; i <= max; i++ {
if f := count(fact(gen(i))); f != results[i] {
println("FAIL:", i, "!:", f, "!=", results[i])
panic(0)
diff --git a/gcc/testsuite/go.test/test/printbig.go b/gcc/testsuite/go.test/test/printbig.go
index 5693c58..9e08c39 100644
--- a/gcc/testsuite/go.test/test/printbig.go
+++ b/gcc/testsuite/go.test/test/printbig.go
@@ -1,4 +1,4 @@
-// cmpout
+// run
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
diff --git a/gcc/testsuite/go.test/test/range.go b/gcc/testsuite/go.test/test/range.go
index 8effbe9..3da7d17 100644
--- a/gcc/testsuite/go.test/test/range.go
+++ b/gcc/testsuite/go.test/test/range.go
@@ -23,15 +23,68 @@ func seq(lo, hi int) chan int {
return c
}
+const alphabet = "abcdefghijklmnopqrstuvwxyz"
+
+func testblankvars() {
+ n := 0
+ for range alphabet {
+ n++
+ }
+ if n != 26 {
+ println("for range: wrong count", n, "want 26")
+ panic("fail")
+ }
+ n = 0
+ for _ = range alphabet {
+ n++
+ }
+ if n != 26 {
+ println("for _ = range: wrong count", n, "want 26")
+ panic("fail")
+ }
+ n = 0
+ for _, _ = range alphabet {
+ n++
+ }
+ if n != 26 {
+ println("for _, _ = range: wrong count", n, "want 26")
+ panic("fail")
+ }
+ s := 0
+ for i, _ := range alphabet {
+ s += i
+ }
+ if s != 325 {
+ println("for i, _ := range: wrong sum", s, "want 325")
+ panic("fail")
+ }
+ r := rune(0)
+ for _, v := range alphabet {
+ r += v
+ }
+ if r != 2847 {
+ println("for _, v := range: wrong sum", r, "want 2847")
+ panic("fail")
+ }
+}
+
func testchan() {
s := ""
for i := range seq('a', 'z') {
s += string(i)
}
- if s != "abcdefghijklmnopqrstuvwxyz" {
+ if s != alphabet {
println("Wanted lowercase alphabet; got", s)
panic("fail")
}
+ n := 0
+ for range seq('a', 'z') {
+ n++
+ }
+ if n != 26 {
+ println("testchan wrong count", n, "want 26")
+ panic("fail")
+ }
}
// test that range over slice only evaluates
@@ -87,6 +140,46 @@ func testslice1() {
}
}
+func testslice2() {
+ n := 0
+ nmake = 0
+ for range makeslice() {
+ n++
+ }
+ if nmake != 1 {
+ println("range called makeslice", nmake, "times")
+ panic("fail")
+ }
+ if n != 5 {
+ println("wrong count ranging over makeslice", n)
+ panic("fail")
+ }
+}
+
+// test that range over []byte(string) only evaluates
+// the expression after "range" once.
+
+func makenumstring() string {
+ nmake++
+ return "\x01\x02\x03\x04\x05"
+}
+
+func testslice3() {
+ s := byte(0)
+ nmake = 0
+ for _, v := range []byte(makenumstring()) {
+ s += v
+ }
+ if nmake != 1 {
+ println("range called makenumstring", nmake, "times")
+ panic("fail")
+ }
+ if s != 15 {
+ println("wrong sum ranging over []byte(makenumstring)", s)
+ panic("fail")
+ }
+}
+
// test that range over array only evaluates
// the expression after "range" once.
@@ -127,6 +220,22 @@ func testarray1() {
}
}
+func testarray2() {
+ n := 0
+ nmake = 0
+ for range makearray() {
+ n++
+ }
+ if nmake != 1 {
+ println("range called makearray", nmake, "times")
+ panic("fail")
+ }
+ if n != 5 {
+ println("wrong count ranging over makearray", n)
+ panic("fail")
+ }
+}
+
func makearrayptr() *[5]int {
nmake++
return &[5]int{1, 2, 3, 4, 5}
@@ -176,6 +285,22 @@ func testarrayptr1() {
}
}
+func testarrayptr2() {
+ n := 0
+ nmake = 0
+ for range makearrayptr() {
+ n++
+ }
+ if nmake != 1 {
+ println("range called makearrayptr", nmake, "times")
+ panic("fail")
+ }
+ if n != 5 {
+ println("wrong count ranging over makearrayptr", n)
+ panic("fail")
+ }
+}
+
// test that range over string only evaluates
// the expression after "range" once.
@@ -198,6 +323,26 @@ func teststring() {
println("wrong sum ranging over makestring", s)
panic("fail")
}
+
+ x := []rune{'a', 'b'}
+ i := 1
+ for i, x[i] = range "c" {
+ break
+ }
+ if i != 0 || x[0] != 'a' || x[1] != 'c' {
+ println("wrong parallel assignment", i, x[0], x[1])
+ panic("fail")
+ }
+
+ y := []int{1, 2, 3}
+ r := rune(1)
+ for y[r], r = range "\x02" {
+ break
+ }
+ if r != 2 || y[0] != 1 || y[1] != 0 || y[2] != 3 {
+ println("wrong parallel assignment", r, y[0], y[1], y[2])
+ panic("fail")
+ }
}
func teststring1() {
@@ -216,6 +361,22 @@ func teststring1() {
}
}
+func teststring2() {
+ n := 0
+ nmake = 0
+ for range makestring() {
+ n++
+ }
+ if nmake != 1 {
+ println("range called makestring", nmake, "times")
+ panic("fail")
+ }
+ if n != 5 {
+ println("wrong count ranging over makestring", n)
+ panic("fail")
+ }
+}
+
// test that range over map only evaluates
// the expression after "range" once.
@@ -256,6 +417,22 @@ func testmap1() {
}
}
+func testmap2() {
+ n := 0
+ nmake = 0
+ for range makemap() {
+ n++
+ }
+ if nmake != 1 {
+ println("range called makemap", nmake, "times")
+ panic("fail")
+ }
+ if n != 5 {
+ println("wrong count ranging over makemap", n)
+ panic("fail")
+ }
+}
+
// test that range evaluates the index and value expressions
// exactly once per iteration.
@@ -295,16 +472,23 @@ func testcalls() {
}
func main() {
+ testblankvars()
testchan()
testarray()
testarray1()
+ testarray2()
testarrayptr()
testarrayptr1()
+ testarrayptr2()
testslice()
testslice1()
+ testslice2()
+ testslice3()
teststring()
teststring1()
+ teststring2()
testmap()
testmap1()
+ testmap2()
testcalls()
}
diff --git a/gcc/testsuite/go.test/test/recover.go b/gcc/testsuite/go.test/test/recover.go
index 071be66..e4187c0 100644
--- a/gcc/testsuite/go.test/test/recover.go
+++ b/gcc/testsuite/go.test/test/recover.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -47,6 +47,7 @@ func main() {
test11reflect1()
test11reflect2()
}
+ test111()
test12()
if !interp {
test12reflect1()
@@ -62,6 +63,7 @@ func main() {
test14reflect1()
test14reflect2()
test15()
+ test16()
}
}
@@ -77,7 +79,7 @@ func mustRecoverBody(v1, v2, v3, x interface{}) {
}
v = v2
if v == nil {
- println("missing recover")
+ println("missing recover", x.(int))
die() // panic is useless here
}
if v != x {
@@ -113,10 +115,23 @@ func withoutRecover() {
mustNotRecover() // because it's a sub-call
}
+func withoutRecoverRecursive(n int) {
+ if n == 0 {
+ withoutRecoverRecursive(1)
+ } else {
+ v := recover()
+ if v != nil {
+ println("spurious recover (recursive)", v)
+ die()
+ }
+ }
+}
+
func test1() {
- defer mustNotRecover() // because mustRecover will squelch it
- defer mustRecover(1) // because of panic below
- defer withoutRecover() // should be no-op, leaving for mustRecover to find
+ defer mustNotRecover() // because mustRecover will squelch it
+ defer mustRecover(1) // because of panic below
+ defer withoutRecover() // should be no-op, leaving for mustRecover to find
+ defer withoutRecoverRecursive(0) // ditto
panic(1)
}
@@ -137,7 +152,7 @@ func test1WithClosures() {
mustNotRecover()
v := recover()
if v == nil {
- println("missing recover")
+ println("missing recover", x.(int))
die()
}
if v != x {
@@ -406,6 +421,49 @@ func test11reflect2() {
panic(11)
}
+// tiny receiver, so basic wrapper in i.M()
+type T3deeper struct{}
+
+func (T3deeper) M() {
+ badstate() // difference from T3
+ mustRecoverBody(doubleRecover(), recover(), recover(), 111)
+}
+
+func test111() {
+ var i I = T3deeper{}
+ defer i.M()
+ panic(111)
+}
+
+type Tiny struct{}
+
+func (Tiny) M() {
+ panic(112)
+}
+
+// i.M is a wrapper, and i.M panics.
+//
+// This is a torture test for an old implementation of recover that
+// tried to deal with wrapper functions by doing some argument
+// positioning math on both entry and exit. Doing anything on exit
+// is a problem because sometimes functions exit via panic instead
+// of an ordinary return, so panic would have to know to do the
+// same math when unwinding the stack. It gets complicated fast.
+// This particular test never worked with the old scheme, because
+// panic never did the right unwinding math.
+//
+// The new scheme adjusts Panic.argp on entry to a wrapper.
+// It has no exit work, so if a wrapper is interrupted by a panic,
+// there's no cleanup that panic itself must do.
+// This test just works now.
+func badstate() {
+ defer func() {
+ recover()
+ }()
+ var i I = Tiny{}
+ i.M()
+}
+
// large receiver, so basic wrapper in i.M()
type T4 [2]string
@@ -503,3 +561,27 @@ func test15() {
defer f()
panic(15)
}
+
+func reflectFunc2(args []reflect.Value) (results []reflect.Value) {
+ // This will call reflectFunc3
+ args[0].Interface().(func())()
+ return nil
+}
+
+func reflectFunc3(args []reflect.Value) (results []reflect.Value) {
+ if v := recover(); v != nil {
+ println("spurious recover", v)
+ die()
+ }
+ return nil
+}
+
+func test16() {
+ defer mustRecover(16)
+
+ f2 := reflect.MakeFunc(reflect.TypeOf((func(func()))(nil)), reflectFunc2).Interface().(func(func()))
+ f3 := reflect.MakeFunc(reflect.TypeOf((func())(nil)), reflectFunc3).Interface().(func())
+ defer f2(f3)
+
+ panic(16)
+}
diff --git a/gcc/testsuite/go.test/test/recover1.go b/gcc/testsuite/go.test/test/recover1.go
index b763a10..c14a607 100644
--- a/gcc/testsuite/go.test/test/recover1.go
+++ b/gcc/testsuite/go.test/test/recover1.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/recover2.go b/gcc/testsuite/go.test/test/recover2.go
index 946d05a..31c06ba 100644
--- a/gcc/testsuite/go.test/test/recover2.go
+++ b/gcc/testsuite/go.test/test/recover2.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -71,7 +71,7 @@ func test5() {
}
func test6() {
- defer mustRecover("unhashable")
+ defer mustRecover("unhashable type main.T")
var x T
var z interface{} = x
m := make(map[interface{}]int)
diff --git a/gcc/testsuite/go.test/test/recover3.go b/gcc/testsuite/go.test/test/recover3.go
index e17bfb3..1b26cb3 100644
--- a/gcc/testsuite/go.test/test/recover3.go
+++ b/gcc/testsuite/go.test/test/recover3.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/rename.go b/gcc/testsuite/go.test/test/rename.go
index dc43417..83f184b 100644
--- a/gcc/testsuite/go.test/test/rename.go
+++ b/gcc/testsuite/go.test/test/rename.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/rename1.go b/gcc/testsuite/go.test/test/rename1.go
index 53db68d..c49a70a 100644
--- a/gcc/testsuite/go.test/test/rename1.go
+++ b/gcc/testsuite/go.test/test/rename1.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
@@ -10,10 +10,10 @@
package main
func main() {
- var n byte // ERROR "not a type|expected type"
+ var n byte // ERROR "not a type|expected type"
var y = float32(0) // ERROR "cannot call|expected function"
const (
- a = 1 + iota // ERROR "string|incompatible types" "convert iota"
+ a = 1 + iota // ERROR "invalid operation|incompatible types"
)
}
diff --git a/gcc/testsuite/go.test/test/reorder.go b/gcc/testsuite/go.test/test/reorder.go
index 8fd623c..3a87d02 100644
--- a/gcc/testsuite/go.test/test/reorder.go
+++ b/gcc/testsuite/go.test/test/reorder.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -19,6 +19,7 @@ func main() {
p6()
p7()
p8()
+ p9()
}
var gx []int
@@ -112,3 +113,39 @@ func p8() {
panic(m[0])
}
}
+
+// Issue #13433: Left-to-right assignment of OAS2XXX nodes.
+func p9() {
+ var x bool
+
+ // OAS2FUNC
+ x, x = fn()
+ checkOAS2XXX(x, "x, x = fn()")
+
+ // OAS2RECV
+ var c = make(chan bool, 10)
+ c <- false
+ x, x = <-c
+ checkOAS2XXX(x, "x, x <-c")
+
+ // OAS2MAPR
+ var m = map[int]bool{0: false}
+ x, x = m[0]
+ checkOAS2XXX(x, "x, x = m[0]")
+
+ // OAS2DOTTYPE
+ var i interface{} = false
+ x, x = i.(bool)
+ checkOAS2XXX(x, "x, x = i.(bool)")
+}
+
+//go:noinline
+func fn() (bool, bool) { return false, true }
+
+// checks the order of OAS2XXX.
+func checkOAS2XXX(x bool, s string) {
+ if !x {
+ fmt.Printf("%s; got=(false); want=(true)\n", s)
+ panic("failed")
+ }
+}
diff --git a/gcc/testsuite/go.test/test/reorder2.go b/gcc/testsuite/go.test/test/reorder2.go
index d91f1d8..07f1b15 100644
--- a/gcc/testsuite/go.test/test/reorder2.go
+++ b/gcc/testsuite/go.test/test/reorder2.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -58,9 +58,8 @@ func f(x, y string) {
log += "f(" + x + ", " + y + ")"
}
+//go:noinline
func ff(x, y string) {
- for false {
- } // prevent inl
log += "ff(" + x + ", " + y + ")"
}
@@ -69,9 +68,8 @@ func h(x string) string {
return x
}
+//go:noinline
func g(x string) string {
- for false {
- } // prevent inl
log += "g(" + x + ")"
return x
}
@@ -168,6 +166,175 @@ func main() {
}
log = ""
+ x := 0
+ switch x {
+ case 0:
+ if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
+ println("in switch, expecting a(1)a(2)a(3) , got ", log)
+ err++
+ }
+ log = ""
+
+ if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
+ println("in switch, expecting a(1)b(2)a(2), got ", log)
+ err++
+ }
+ log = ""
+ if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
+ println("in switch, expecting a(3)b(4)a(4)b(5)a(5), got ", log)
+ err++
+ }
+ log = ""
+ var i I = T1(0)
+ if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
+ println("in switch, expecting a(6)ba(7)ba(8)ba(9), got", log)
+ err++
+ }
+ log = ""
+ }
+
+ c := make(chan int, 1)
+ c <- 1
+ select {
+ case c <- 0:
+ case c <- 1:
+ case <-c:
+ if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
+ println("in select1, expecting a(1)a(2)a(3) , got ", log)
+ err++
+ }
+ log = ""
+
+ if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
+ println("in select1, expecting a(1)b(2)a(2), got ", log)
+ err++
+ }
+ log = ""
+ if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
+ println("in select1, expecting a(3)b(4)a(4)b(5)a(5), got ", log)
+ err++
+ }
+ log = ""
+ var i I = T1(0)
+ if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
+ println("in select1, expecting a(6)ba(7)ba(8)ba(9), got", log)
+ err++
+ }
+ log = ""
+ }
+
+ c <- 1
+ select {
+ case <-c:
+ if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
+ println("in select2, expecting a(1)a(2)a(3) , got ", log)
+ err++
+ }
+ log = ""
+
+ if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
+ println("in select2, expecting a(1)b(2)a(2), got ", log)
+ err++
+ }
+ log = ""
+ if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
+ println("in select2, expecting a(3)b(4)a(4)b(5)a(5), got ", log)
+ err++
+ }
+ log = ""
+ var i I = T1(0)
+ if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
+ println("in select2, expecting a(6)ba(7)ba(8)ba(9), got", log)
+ err++
+ }
+ log = ""
+ }
+
+ c <- 1
+ select {
+ default:
+ case c <- 1:
+ case <-c:
+ if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
+ println("in select3, expecting a(1)a(2)a(3) , got ", log)
+ err++
+ }
+ log = ""
+
+ if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
+ println("in select3, expecting a(1)b(2)a(2), got ", log)
+ err++
+ }
+ log = ""
+ if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
+ println("in select3, expecting a(3)b(4)a(4)b(5)a(5), got ", log)
+ err++
+ }
+ log = ""
+ var i I = T1(0)
+ if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
+ println("in select3, expecting a(6)ba(7)ba(8)ba(9), got", log)
+ err++
+ }
+ log = ""
+ }
+
+ c <- 1
+ select {
+ default:
+ case <-c:
+ if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
+ println("in select4, expecting a(1)a(2)a(3) , got ", log)
+ err++
+ }
+ log = ""
+
+ if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
+ println("in select4, expecting a(1)b(2)a(2), got ", log)
+ err++
+ }
+ log = ""
+ if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
+ println("in select4, expecting a(3)b(4)a(4)b(5)a(5), got ", log)
+ err++
+ }
+ log = ""
+ var i I = T1(0)
+ if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
+ println("in select4, expecting a(6)ba(7)ba(8)ba(9), got", log)
+ err++
+ }
+ log = ""
+ }
+
+ select {
+ case <-c:
+ case <-c:
+ default:
+ if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
+ println("in select5, expecting a(1)a(2)a(3) , got ", log)
+ err++
+ }
+ log = ""
+
+ if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
+ println("in select5, expecting a(1)b(2)a(2), got ", log)
+ err++
+ }
+ log = ""
+ if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
+ println("in select5, expecting a(3)b(4)a(4)b(5)a(5), got ", log)
+ err++
+ }
+ log = ""
+ var i I = T1(0)
+ if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
+ println("in select5, expecting a(6)ba(7)ba(8)ba(9), got", log)
+ err++
+ }
+ log = ""
+ }
+
if err > 0 {
panic("fail")
}
diff --git a/gcc/testsuite/go.test/test/return.go b/gcc/testsuite/go.test/test/return.go
index 482f22b..95f94b9 100644
--- a/gcc/testsuite/go.test/test/return.go
+++ b/gcc/testsuite/go.test/test/return.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/rotate.go b/gcc/testsuite/go.test/test/rotate.go
index 1d71497..9dc4b1e 100644
--- a/gcc/testsuite/go.test/test/rotate.go
+++ b/gcc/testsuite/go.test/test/rotate.go
@@ -2,7 +2,7 @@
// NOTE: the actual tests to run are rotate[0123].go
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/gcc/testsuite/go.test/test/rotate0.go b/gcc/testsuite/go.test/test/rotate0.go
index 400b225..09dd900 100644
--- a/gcc/testsuite/go.test/test/rotate0.go
+++ b/gcc/testsuite/go.test/test/rotate0.go
@@ -1,6 +1,6 @@
// runoutput ./rotate.go
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/rotate1.go b/gcc/testsuite/go.test/test/rotate1.go
index 98b0b1c..19757ec 100644
--- a/gcc/testsuite/go.test/test/rotate1.go
+++ b/gcc/testsuite/go.test/test/rotate1.go
@@ -1,6 +1,6 @@
// runoutput ./rotate.go
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/rotate2.go b/gcc/testsuite/go.test/test/rotate2.go
index c50f8ce..a55305a 100644
--- a/gcc/testsuite/go.test/test/rotate2.go
+++ b/gcc/testsuite/go.test/test/rotate2.go
@@ -1,6 +1,6 @@
// runoutput ./rotate.go
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/rotate3.go b/gcc/testsuite/go.test/test/rotate3.go
index 73d47d8..edd5d3a 100644
--- a/gcc/testsuite/go.test/test/rotate3.go
+++ b/gcc/testsuite/go.test/test/rotate3.go
@@ -1,6 +1,6 @@
// runoutput ./rotate.go
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/run b/gcc/testsuite/go.test/test/run
deleted file mode 100755
index d206312..0000000
--- a/gcc/testsuite/go.test/test/run
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/usr/bin/env bash
-# Copyright 2009 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.
-
-eval $(go tool dist env)
-export GOARCH GOOS GOROOT
-export E=
-
-case X"$GOARCH" in
-Xamd64)
- export A=6
- ;;
-X386)
- export A=8
- ;;
-Xarm)
- export A=5
- export E="$GORUN"
- ;;
-*)
- echo 1>&2 run: unsupported '$GOARCH'
- exit 1
-esac
-
-export G="${A}g ${GCFLAGS}"
-export L=${A}l
-export GOTRACEBACK=0
-export LANG=C
-unset GREP_OPTIONS # in case user has a non-standard set
-
-unset GOROOT_FINAL # breaks ./ imports
-
-failed=0
-
-PATH=${GOBIN:-$GOROOT/bin}:`pwd`:/bin:/usr/bin:/usr/local/bin
-
-# TODO: We add the tool directory to the PATH to avoid thinking about a better way.
-PATH="$GOTOOLDIR:$PATH"
-
-RUNFILE="${TMPDIR:-/tmp}/gorun-$$-$USER"
-TMP1FILE="${TMPDIR:-/tmp}/gotest1-$$-$USER"
-TMP2FILE="${TMPDIR:-/tmp}/gotest2-$$-$USER"
-
-# don't run the machine out of memory: limit individual processes to 4GB.
-# on thresher, 3GB suffices to run the tests; with 2GB, peano fails.
-ulimit -v 4000000
-
-# no core files please
-ulimit -c 0
-
-true >pass.out >times.out
-
-exclude=false # exclude nothing
-golden=golden.out
-
-rm -f tmp.go # generated by some tests, left behind if interrupted
-
-filterout() {
- grep '^'"$2"'$' $1 >/dev/null
-}
-
-for dir in . ken chan interface syntax dwarf safe fixedbugs bugs
-do
- echo
- echo '==' $dir'/'
- for i in $(ls $dir/*.go 2>/dev/null)
- do (
- if $exclude $i; then
- exit 0 # continues for loop
- fi
- export F=$(basename $i .go)
- export D=$dir
- echo '. ./testlib' >"$RUNFILE"
- sed '/^\/\//!q' $i | sed 's@//@@; $d' |sed 's|./\$A.out|$E &|g' >>"$RUNFILE"
- if ! { time -p bash -c "bash '$RUNFILE' >'$TMP1FILE' 2>&1" ; } 2>"$TMP2FILE"
- then
- echo
- echo "===========" $i
- cat "$TMP1FILE"
- echo >&2 fail: $i
- echo "# $i # fail" >>pass.out
- elif test -s "$TMP1FILE"
- then
- echo
- echo "===========" $i
- cat "$TMP1FILE"
- if grep -q '^BUG' "$TMP1FILE"
- then
- if [ $dir != bugs ]
- then
- echo >&2 bug: $i
- fi
- echo "# $i # fail, BUG" >>pass.out
- else
- echo $i >>pass.out
- fi
- elif [ $dir = "bugs" ]
- then
- echo $i succeeded with no output.
- else
- echo $i >>pass.out
- fi
- echo $(awk 'NR==1{print $2}' "$TMP2FILE") $D/$F >>times.out
- rm -f $F.$A $A.out tmp.go
- ) done
-done | # clean up some stack noise
- egrep -v '^(r[0-9a-z]+|[cfg]s) +0x' |
- sed '/tmp.*Bus error/s/.*Bus/Bus/; /tmp.*Trace.BPT/s/.*Trace/Trace/
- s!'"$RUNFILE"'!$RUNFILE!g
- s/^PC=0x[0-9a-f]*/pc: xxx/
- s/^pc: 0x[0-9a-f]*/pc: xxx/
- s/PC=0x[0-9a-f]*/PC=xxx/
- /^Trace\/breakpoint trap/d
- /^Trace\/BPT trap/d
- /RUNFILE/ s/line 1: *[0-9]*/line 1: PID/
- /^\$RUNFILE: line 1: PID Trace\/breakpoint trap/d
- /Segmentation fault/d
- /^qemu: uncaught target signal 11 (Segmentation fault) - exiting/d' > run.out
-
-rm -f "$RUNFILE" "$TMP1FILE" "$TMP2FILE" *.$A *.a $A.out
-diffmsg=""
-if ! diff $golden run.out
-then
- diffmsg="; test output differs"
- failed=1
-fi
-
-notinbugs=$(sed '/^== bugs/q' run.out | grep -c '^BUG')
-inbugs=$(sed '1,/^== bugs/d' run.out | grep -c '^BUG')
-
-echo 2>&1 $inbugs known bugs';' $notinbugs unexpected bugs$diffmsg
-
-if [ "$failed" != "0" ]; then
- echo FAILED
-fi
-
-exit $failed
diff --git a/gcc/testsuite/go.test/test/run.go b/gcc/testsuite/go.test/test/run.go
index 5c94de6..4abf32d 100644
--- a/gcc/testsuite/go.test/test/run.go
+++ b/gcc/testsuite/go.test/test/run.go
@@ -1,13 +1,10 @@
// skip
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
// Run runs tests in the test directory.
-//
-// TODO(bradfitz): docs of some sort, once we figure out how we're changing
-// headers of files
package main
import (
@@ -15,7 +12,9 @@ import (
"errors"
"flag"
"fmt"
- "go/build"
+ "hash/fnv"
+ "io"
+ "io/fs"
"io/ioutil"
"log"
"os"
@@ -33,22 +32,34 @@ import (
var (
verbose = flag.Bool("v", false, "verbose. if set, parallelism is set to 1.")
+ keep = flag.Bool("k", false, "keep. keep temporary directory.")
numParallel = flag.Int("n", runtime.NumCPU(), "number of parallel tests to run")
summary = flag.Bool("summary", false, "show summary of results")
+ allCodegen = flag.Bool("all_codegen", defaultAllCodeGen(), "run all goos/goarch for codegen")
showSkips = flag.Bool("show_skips", false, "show skipped tests")
+ runSkips = flag.Bool("run_skips", false, "run skipped tests (ignore skip and build tags)")
+ linkshared = flag.Bool("linkshared", false, "")
+ updateErrors = flag.Bool("update_errors", false, "update error messages in test file based on compiler output")
runoutputLimit = flag.Int("l", defaultRunOutputLimit(), "number of parallel runoutput tests to run")
+
+ shard = flag.Int("shard", 0, "shard index to run. Only applicable if -shards is non-zero.")
+ shards = flag.Int("shards", 0, "number of shards. If 0, all tests are run. This is used by the continuous build.")
)
-var (
- // gc and ld are [568][gl].
- gc, ld string
+// defaultAllCodeGen returns the default value of the -all_codegen
+// flag. By default, we prefer to be fast (returning false), except on
+// the linux-amd64 builder that's already very fast, so we get more
+// test coverage on trybots. See https://golang.org/issue/34297.
+func defaultAllCodeGen() bool {
+ return os.Getenv("GO_BUILDER_NAME") == "linux-amd64"
+}
- // letter is the build.ArchChar
- letter string
+var (
+ goos, goarch string
// dirs are the directories to look for *.go files in.
// TODO(bradfitz): just use all directories?
- dirs = []string{".", "ken", "chan", "interface", "syntax", "dwarf", "fixedbugs", "bugs"}
+ dirs = []string{".", "ken", "chan", "interface", "syntax", "dwarf", "fixedbugs", "codegen", "runtime"}
// ratec controls the max number of tests running at a time.
ratec chan bool
@@ -69,18 +80,19 @@ const maxTests = 5000
func main() {
flag.Parse()
- // Disable parallelism if printing
- if *verbose {
+ goos = getenv("GOOS", runtime.GOOS)
+ goarch = getenv("GOARCH", runtime.GOARCH)
+
+ findExecCmd()
+
+ // Disable parallelism if printing or if using a simulator.
+ if *verbose || len(findExecCmd()) > 0 {
*numParallel = 1
+ *runoutputLimit = 1
}
ratec = make(chan bool, *numParallel)
rungatec = make(chan bool, *runoutputLimit)
- var err error
- letter, err = build.ArchChar(build.Default.GOARCH)
- check(err)
- gc = letter + "g"
- ld = letter + "l"
var tests []*test
if flag.NArg() > 0 {
@@ -115,16 +127,13 @@ func main() {
failed := false
resCount := map[string]int{}
for _, test := range tests {
- <-test.donec
+ <-test.donec
status := "ok "
errStr := ""
- if _, isSkip := test.err.(skipError); isSkip {
- status = "skip"
+ if e, isSkip := test.err.(skipError); isSkip {
test.err = nil
- if !skipOkay[path.Join(test.dir, test.gofile)] {
- errStr = "unexpected skip for " + path.Join(test.dir, test.gofile) + ": " + errStr
- status = "FAIL"
- }
+ errStr = "unexpected skip for " + path.Join(test.dir, test.gofile) + ": " + string(e)
+ status = "FAIL"
}
if test.err != nil {
status = "FAIL"
@@ -134,9 +143,6 @@ func main() {
failed = true
}
resCount[status]++
- if status == "skip" && !*verbose && !*showSkips {
- continue
- }
dt := fmt.Sprintf("%.3fs", test.dt.Seconds())
if status == "FAIL" {
fmt.Printf("# go run run.go -- %s\n%s\nFAIL\t%s\t%s\n",
@@ -161,22 +167,44 @@ func main() {
}
}
-func toolPath(name string) string {
- p := filepath.Join(os.Getenv("GOROOT"), "bin", "tool", name)
- if _, err := os.Stat(p); err != nil {
- log.Fatalf("didn't find binary at %s", p)
+// goTool reports the path of the go tool to use to run the tests.
+// If possible, use the same Go used to run run.go, otherwise
+// fallback to the go version found in the PATH.
+func goTool() string {
+ var exeSuffix string
+ if runtime.GOOS == "windows" {
+ exeSuffix = ".exe"
}
- return p
+ path := filepath.Join(runtime.GOROOT(), "bin", "go"+exeSuffix)
+ if _, err := os.Stat(path); err == nil {
+ return path
+ }
+ // Just run "go" from PATH
+ return "go"
+}
+
+func shardMatch(name string) bool {
+ if *shards == 0 {
+ return true
+ }
+ h := fnv.New32()
+ io.WriteString(h, name)
+ return int(h.Sum32()%uint32(*shards)) == *shard
}
func goFiles(dir string) []string {
f, err := os.Open(dir)
- check(err)
+ if err != nil {
+ log.Fatal(err)
+ }
dirnames, err := f.Readdirnames(-1)
- check(err)
+ f.Close()
+ if err != nil {
+ log.Fatal(err)
+ }
names := []string{}
for _, name := range dirnames {
- if !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go") {
+ if !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go") && shardMatch(name) {
names = append(names, name)
}
}
@@ -186,21 +214,43 @@ func goFiles(dir string) []string {
type runCmd func(...string) ([]byte, error)
-func compileFile(runcmd runCmd, longname string) (out []byte, err error) {
- return runcmd("go", "tool", gc, "-e", longname)
+func compileFile(runcmd runCmd, longname string, flags []string) (out []byte, err error) {
+ cmd := []string{goTool(), "tool", "compile", "-e"}
+ cmd = append(cmd, flags...)
+ if *linkshared {
+ cmd = append(cmd, "-dynlink", "-installsuffix=dynlink")
+ }
+ cmd = append(cmd, longname)
+ return runcmd(cmd...)
}
-func compileInDir(runcmd runCmd, dir string, names ...string) (out []byte, err error) {
- cmd := []string{"go", "tool", gc, "-e", "-D", ".", "-I", "."}
+func compileInDir(runcmd runCmd, dir string, flags []string, localImports bool, names ...string) (out []byte, err error) {
+ cmd := []string{goTool(), "tool", "compile", "-e"}
+ if localImports {
+ // Set relative path for local imports and import search path to current dir.
+ cmd = append(cmd, "-D", ".", "-I", ".")
+ }
+ cmd = append(cmd, flags...)
+ if *linkshared {
+ cmd = append(cmd, "-dynlink", "-installsuffix=dynlink")
+ }
for _, name := range names {
cmd = append(cmd, filepath.Join(dir, name))
}
return runcmd(cmd...)
}
-func linkFile(runcmd runCmd, goname string) (err error) {
- pfile := strings.Replace(goname, ".go", "."+letter, -1)
- _, err = runcmd("go", "tool", ld, "-o", "a.exe", "-L", ".", pfile)
+func linkFile(runcmd runCmd, goname string, ldflags []string) (err error) {
+ pfile := strings.Replace(goname, ".go", ".o", -1)
+ cmd := []string{goTool(), "tool", "link", "-w", "-o", "a.exe", "-L", "."}
+ if *linkshared {
+ cmd = append(cmd, "-linkshared", "-installsuffix=dynlink")
+ }
+ if ldflags != nil {
+ cmd = append(cmd, ldflags...)
+ }
+ cmd = append(cmd, pfile)
+ _, err = runcmd(cmd...)
return
}
@@ -209,20 +259,13 @@ type skipError string
func (s skipError) Error() string { return string(s) }
-func check(err error) {
- if err != nil {
- log.Fatal(err)
- }
-}
-
// test holds the state of a test.
type test struct {
dir, gofile string
donec chan bool // closed when done
- dt time.Duration
-
- src string
- action string // "compile", "build", etc.
+ dt time.Duration
+
+ src string
tempDir string
err error
@@ -283,9 +326,23 @@ func goDirFiles(longdir string) (filter []os.FileInfo, err error) {
return
}
-var packageRE = regexp.MustCompile(`(?m)^package (\w+)`)
+var packageRE = regexp.MustCompile(`(?m)^package ([\p{Lu}\p{Ll}\w]+)`)
-func goDirPackages(longdir string) ([][]string, error) {
+func getPackageNameFromSource(fn string) (string, error) {
+ data, err := ioutil.ReadFile(fn)
+ if err != nil {
+ return "", err
+ }
+ pkgname := packageRE.FindStringSubmatch(string(data))
+ if pkgname == nil {
+ return "", fmt.Errorf("cannot find package name in %s", fn)
+ }
+ return pkgname[1], nil
+}
+
+// If singlefilepkgs is set, each file is considered a separate package
+// even if the package names are the same.
+func goDirPackages(longdir string, singlefilepkgs bool) ([][]string, error) {
files, err := goDirFiles(longdir)
if err != nil {
return nil, err
@@ -294,19 +351,15 @@ func goDirPackages(longdir string) ([][]string, error) {
m := make(map[string]int)
for _, file := range files {
name := file.Name()
- data, err := ioutil.ReadFile(filepath.Join(longdir, name))
+ pkgname, err := getPackageNameFromSource(filepath.Join(longdir, name))
if err != nil {
- return nil, err
- }
- pkgname := packageRE.FindStringSubmatch(string(data))
- if pkgname == nil {
- return nil, fmt.Errorf("cannot find package name in %s", name)
+ log.Fatal(err)
}
- i, ok := m[pkgname[1]]
- if !ok {
+ i, ok := m[pkgname]
+ if singlefilepkgs || !ok {
i = len(pkgs)
pkgs = append(pkgs, nil)
- m[pkgname[1]] = i
+ m[pkgname] = i
}
pkgs[i] = append(pkgs[i], name)
}
@@ -314,15 +367,16 @@ func goDirPackages(longdir string) ([][]string, error) {
}
type context struct {
- GOOS string
- GOARCH string
+ GOOS string
+ GOARCH string
+ noOptEnv bool
}
// shouldTest looks for build tags in a source file and returns
// whether the file should be used according to the tags.
func shouldTest(src string, goos, goarch string) (ok bool, whyNot string) {
- if idx := strings.Index(src, "\npackage"); idx >= 0 {
- src = src[:idx]
+ if *runSkips {
+ return true, ""
}
for _, line := range strings.Split(src, "\n") {
line = strings.TrimSpace(line)
@@ -335,10 +389,13 @@ func shouldTest(src string, goos, goarch string) (ok bool, whyNot string) {
if len(line) == 0 || line[0] != '+' {
continue
}
+ gcFlags := os.Getenv("GO_GCFLAGS")
ctxt := &context{
- GOOS: goos,
- GOARCH: goarch,
+ GOOS: goos,
+ GOARCH: goarch,
+ noOptEnv: strings.Contains(gcFlags, "-N") || strings.Contains(gcFlags, "-l"),
}
+
words := strings.Fields(line)
if words[0] == "+build" {
ok := false
@@ -385,11 +442,31 @@ func (ctxt *context) match(name string) bool {
return true
}
+ if ctxt.noOptEnv && name == "gcflags_noopt" {
+ return true
+ }
+
+ if name == "test_run" {
+ return true
+ }
+
return false
}
func init() { checkShouldTest() }
+// goGcflags returns the -gcflags argument to use with go build / go run.
+// This must match the flags used for building the standard library,
+// or else the commands will rebuild any needed packages (like runtime)
+// over and over.
+func goGcflags() string {
+ return "-gcflags=all=" + os.Getenv("GO_GCFLAGS")
+}
+
+func goGcflagsIsEmpty() bool {
+ return "" == os.Getenv("GO_GCFLAGS")
+}
+
// run runs a test.
func (t *test) run() {
start := time.Now()
@@ -408,85 +485,172 @@ func (t *test) run() {
t.err = skipError("starts with newline")
return
}
+
+ // Execution recipe stops at first blank line.
pos := strings.Index(t.src, "\n\n")
if pos == -1 {
t.err = errors.New("double newline not found")
return
}
- if ok, why := shouldTest(t.src, runtime.GOOS, runtime.GOARCH); !ok {
- t.action = "skip"
- if *showSkips {
- fmt.Printf("%-20s %-20s: %s\n", t.action, t.goFileName(), why)
- }
- return
- }
action := t.src[:pos]
if nl := strings.Index(action, "\n"); nl >= 0 && strings.Contains(action[:nl], "+build") {
// skip first line
action = action[nl+1:]
}
- if strings.HasPrefix(action, "//") {
- action = action[2:]
+ action = strings.TrimPrefix(action, "//")
+
+ // Check for build constraints only up to the actual code.
+ pkgPos := strings.Index(t.src, "\npackage")
+ if pkgPos == -1 {
+ pkgPos = pos // some files are intentionally malformed
+ }
+ if ok, why := shouldTest(t.src[:pkgPos], goos, goarch); !ok {
+ if *showSkips {
+ fmt.Printf("%-20s %-20s: %s\n", "skip", t.goFileName(), why)
+ }
+ return
}
var args, flags []string
+ var tim int
wantError := false
+ wantAuto := false
+ singlefilepkgs := false
+ setpkgpaths := false
+ localImports := true
f := strings.Fields(action)
if len(f) > 0 {
action = f[0]
args = f[1:]
}
+ // TODO: Clean up/simplify this switch statement.
switch action {
- case "rundircmpout":
- action = "rundir"
- t.action = "rundir"
- case "cmpout":
- action = "run" // the run case already looks for <dir>/<test>.out files
- fallthrough
- case "compile", "compiledir", "build", "run", "runoutput", "rundir":
- t.action = action
+ case "compile", "compiledir", "build", "builddir", "buildrundir", "run", "buildrun", "runoutput", "rundir", "runindir", "asmcheck":
+ // nothing to do
+ case "errorcheckandrundir":
+ wantError = false // should be no error if also will run
+ case "errorcheckwithauto":
+ action = "errorcheck"
+ wantAuto = true
+ wantError = true
case "errorcheck", "errorcheckdir", "errorcheckoutput":
- t.action = action
wantError = true
- for len(args) > 0 && strings.HasPrefix(args[0], "-") {
- if args[0] == "-0" {
- wantError = false
- } else {
- flags = append(flags, args[0])
- }
- args = args[1:]
- }
case "skip":
- t.action = "skip"
+ if *runSkips {
+ break
+ }
return
default:
t.err = skipError("skipped; unknown pattern: " + action)
- t.action = "??"
return
}
+ // collect flags
+ for len(args) > 0 && strings.HasPrefix(args[0], "-") {
+ switch args[0] {
+ case "-1":
+ wantError = true
+ case "-0":
+ wantError = false
+ case "-s":
+ singlefilepkgs = true
+ case "-P":
+ setpkgpaths = true
+ case "-n":
+ // Do not set relative path for local imports to current dir,
+ // e.g. do not pass -D . -I . to the compiler.
+ // Used in fixedbugs/bug345.go to allow compilation and import of local pkg.
+ // See golang.org/issue/25635
+ localImports = false
+ case "-t": // timeout in seconds
+ args = args[1:]
+ var err error
+ tim, err = strconv.Atoi(args[0])
+ if err != nil {
+ t.err = fmt.Errorf("need number of seconds for -t timeout, got %s instead", args[0])
+ }
+
+ default:
+ flags = append(flags, args[0])
+ }
+ args = args[1:]
+ }
+ if action == "errorcheck" {
+ found := false
+ for i, f := range flags {
+ if strings.HasPrefix(f, "-d=") {
+ flags[i] = f + ",ssa/check/on"
+ found = true
+ break
+ }
+ }
+ if !found {
+ flags = append(flags, "-d=ssa/check/on")
+ }
+ }
+
t.makeTempDir()
- defer os.RemoveAll(t.tempDir)
+ if !*keep {
+ defer os.RemoveAll(t.tempDir)
+ }
err = ioutil.WriteFile(filepath.Join(t.tempDir, t.gofile), srcBytes, 0644)
- check(err)
+ if err != nil {
+ log.Fatal(err)
+ }
// A few tests (of things like the environment) require these to be set.
- os.Setenv("GOOS", runtime.GOOS)
- os.Setenv("GOARCH", runtime.GOARCH)
+ if os.Getenv("GOOS") == "" {
+ os.Setenv("GOOS", runtime.GOOS)
+ }
+ if os.Getenv("GOARCH") == "" {
+ os.Setenv("GOARCH", runtime.GOARCH)
+ }
- useTmp := true
+ var (
+ runInDir = t.tempDir
+ tempDirIsGOPATH = false
+ )
runcmd := func(args ...string) ([]byte, error) {
cmd := exec.Command(args[0], args[1:]...)
var buf bytes.Buffer
cmd.Stdout = &buf
cmd.Stderr = &buf
- if useTmp {
- cmd.Dir = t.tempDir
- cmd.Env = envForDir(cmd.Dir)
+ cmd.Env = append(os.Environ(), "GOENV=off", "GOFLAGS=")
+ if runInDir != "" {
+ cmd.Dir = runInDir
+ // Set PWD to match Dir to speed up os.Getwd in the child process.
+ cmd.Env = append(cmd.Env, "PWD="+cmd.Dir)
+ }
+ if tempDirIsGOPATH {
+ cmd.Env = append(cmd.Env, "GOPATH="+t.tempDir)
+ }
+
+ var err error
+
+ if tim != 0 {
+ err = cmd.Start()
+ // This command-timeout code adapted from cmd/go/test.go
+ if err == nil {
+ tick := time.NewTimer(time.Duration(tim) * time.Second)
+ done := make(chan error)
+ go func() {
+ done <- cmd.Wait()
+ }()
+ select {
+ case err = <-done:
+ // ok
+ case <-tick.C:
+ cmd.Process.Kill()
+ err = <-done
+ // err = errors.New("Test timeout")
+ }
+ tick.Stop()
+ }
+ } else {
+ err = cmd.Run()
}
- err := cmd.Run()
if err != nil {
err = fmt.Errorf("%s\n%s", err, buf.Bytes())
}
@@ -498,8 +662,67 @@ func (t *test) run() {
default:
t.err = fmt.Errorf("unimplemented action %q", action)
+ case "asmcheck":
+ // Compile Go file and match the generated assembly
+ // against a set of regexps in comments.
+ ops := t.wantedAsmOpcodes(long)
+ self := runtime.GOOS + "/" + runtime.GOARCH
+ for _, env := range ops.Envs() {
+ // Only run checks relevant to the current GOOS/GOARCH,
+ // to avoid triggering a cross-compile of the runtime.
+ if string(env) != self && !strings.HasPrefix(string(env), self+"/") && !*allCodegen {
+ continue
+ }
+ // -S=2 forces outermost line numbers when disassembling inlined code.
+ cmdline := []string{"build", "-gcflags", "-S=2"}
+
+ // Append flags, but don't override -gcflags=-S=2; add to it instead.
+ for i := 0; i < len(flags); i++ {
+ flag := flags[i]
+ switch {
+ case strings.HasPrefix(flag, "-gcflags="):
+ cmdline[2] += " " + strings.TrimPrefix(flag, "-gcflags=")
+ case strings.HasPrefix(flag, "--gcflags="):
+ cmdline[2] += " " + strings.TrimPrefix(flag, "--gcflags=")
+ case flag == "-gcflags", flag == "--gcflags":
+ i++
+ if i < len(flags) {
+ cmdline[2] += " " + flags[i]
+ }
+ default:
+ cmdline = append(cmdline, flag)
+ }
+ }
+
+ cmdline = append(cmdline, long)
+ cmd := exec.Command(goTool(), cmdline...)
+ cmd.Env = append(os.Environ(), env.Environ()...)
+ if len(flags) > 0 && flags[0] == "-race" {
+ cmd.Env = append(cmd.Env, "CGO_ENABLED=1")
+ }
+
+ var buf bytes.Buffer
+ cmd.Stdout, cmd.Stderr = &buf, &buf
+ if err := cmd.Run(); err != nil {
+ fmt.Println(env, "\n", cmd.Stderr)
+ t.err = err
+ return
+ }
+
+ t.err = t.asmCheck(buf.String(), long, env, ops[env])
+ if t.err != nil {
+ return
+ }
+ }
+ return
+
case "errorcheck":
- cmdline := []string{"go", "tool", gc, "-e", "-o", "a." + letter}
+ // Compile Go file.
+ // Fail if wantError is true and compilation was successful and vice versa.
+ // Match errors produced by gc against errors in comments.
+ // TODO(gri) remove need for -C (disable printing of columns in error messages)
+ cmdline := []string{goTool(), "tool", "compile", "-C", "-e", "-o", "a.o"}
+ // No need to add -dynlink even if linkshared if we're just checking for errors...
cmdline = append(cmdline, flags...)
cmdline = append(cmdline, long)
out, err := runcmd(cmdline...)
@@ -514,39 +737,50 @@ func (t *test) run() {
return
}
}
- t.err = t.errorCheck(string(out), long, t.gofile)
+ if *updateErrors {
+ t.updateErrors(string(out), long)
+ }
+ t.err = t.errorCheck(string(out), wantAuto, long, t.gofile)
return
case "compile":
- _, t.err = compileFile(runcmd, long)
+ // Compile Go file.
+ _, t.err = compileFile(runcmd, long, flags)
case "compiledir":
- // Compile all files in the directory in lexicographic order.
+ // Compile all files in the directory as packages in lexicographic order.
longdir := filepath.Join(cwd, t.goDirName())
- pkgs, err := goDirPackages(longdir)
+ pkgs, err := goDirPackages(longdir, singlefilepkgs)
if err != nil {
t.err = err
return
}
for _, gofiles := range pkgs {
- _, t.err = compileInDir(runcmd, longdir, gofiles...)
+ _, t.err = compileInDir(runcmd, longdir, flags, localImports, gofiles...)
if t.err != nil {
return
}
}
- case "errorcheckdir":
- // errorcheck all files in lexicographic order
- // useful for finding importing errors
+ case "errorcheckdir", "errorcheckandrundir":
+ // Compile and errorCheck all files in the directory as packages in lexicographic order.
+ // If errorcheckdir and wantError, compilation of the last package must fail.
+ // If errorcheckandrundir and wantError, compilation of the package prior the last must fail.
longdir := filepath.Join(cwd, t.goDirName())
- pkgs, err := goDirPackages(longdir)
+ pkgs, err := goDirPackages(longdir, singlefilepkgs)
if err != nil {
t.err = err
return
}
+ errPkg := len(pkgs) - 1
+ if wantError && action == "errorcheckandrundir" {
+ // The last pkg should compiled successfully and will be run in next case.
+ // Preceding pkg must return an error from compileInDir.
+ errPkg--
+ }
for i, gofiles := range pkgs {
- out, err := compileInDir(runcmd, longdir, gofiles...)
- if i == len(pkgs)-1 {
+ out, err := compileInDir(runcmd, longdir, flags, localImports, gofiles...)
+ if i == errPkg {
if wantError && err == nil {
t.err = fmt.Errorf("compilation succeeded unexpectedly\n%s", out)
return
@@ -562,34 +796,66 @@ func (t *test) run() {
for _, name := range gofiles {
fullshort = append(fullshort, filepath.Join(longdir, name), name)
}
- t.err = t.errorCheck(string(out), fullshort...)
+ t.err = t.errorCheck(string(out), wantAuto, fullshort...)
if t.err != nil {
break
}
}
+ if action == "errorcheckdir" {
+ return
+ }
+ fallthrough
case "rundir":
- // Compile all files in the directory in lexicographic order.
- // then link as if the last file is the main package and run it
+ // Compile all files in the directory as packages in lexicographic order.
+ // In case of errorcheckandrundir, ignore failed compilation of the package before the last.
+ // Link as if the last file is the main package, run it.
+ // Verify the expected output.
longdir := filepath.Join(cwd, t.goDirName())
- pkgs, err := goDirPackages(longdir)
+ pkgs, err := goDirPackages(longdir, singlefilepkgs)
if err != nil {
t.err = err
return
}
+ // Split flags into gcflags and ldflags
+ ldflags := []string{}
+ for i, fl := range flags {
+ if fl == "-ldflags" {
+ ldflags = flags[i+1:]
+ flags = flags[0:i]
+ break
+ }
+ }
+
for i, gofiles := range pkgs {
- _, err := compileInDir(runcmd, longdir, gofiles...)
- if err != nil {
+ pflags := []string{}
+ pflags = append(pflags, flags...)
+ if setpkgpaths {
+ fp := filepath.Join(longdir, gofiles[0])
+ pkgname, err := getPackageNameFromSource(fp)
+ if err != nil {
+ log.Fatal(err)
+ }
+ pflags = append(pflags, "-p", pkgname)
+ }
+ _, err := compileInDir(runcmd, longdir, pflags, localImports, gofiles...)
+ // Allow this package compilation fail based on conditions below;
+ // its errors were checked in previous case.
+ if err != nil && !(wantError && action == "errorcheckandrundir" && i == len(pkgs)-2) {
t.err = err
return
}
if i == len(pkgs)-1 {
- err = linkFile(runcmd, gofiles[0])
+ err = linkFile(runcmd, gofiles[0], ldflags)
if err != nil {
t.err = err
return
}
- out, err := runcmd(append([]string{filepath.Join(t.tempDir, "a.exe")}, args...)...)
+ var cmd []string
+ cmd = append(cmd, findExecCmd()...)
+ cmd = append(cmd, filepath.Join(t.tempDir, "a.exe"))
+ cmd = append(cmd, args...)
+ out, err := runcmd(cmd...)
if err != nil {
t.err = err
return
@@ -600,50 +866,256 @@ func (t *test) run() {
}
}
+ case "runindir":
+ // Make a shallow copy of t.goDirName() in its own module and GOPATH, and
+ // run "go run ." in it. The module path (and hence import path prefix) of
+ // the copy is equal to the basename of the source directory.
+ //
+ // It's used when test a requires a full 'go build' in order to compile
+ // the sources, such as when importing multiple packages (issue29612.dir)
+ // or compiling a package containing assembly files (see issue15609.dir),
+ // but still needs to be run to verify the expected output.
+ tempDirIsGOPATH = true
+ srcDir := t.goDirName()
+ modName := filepath.Base(srcDir)
+ gopathSrcDir := filepath.Join(t.tempDir, "src", modName)
+ runInDir = gopathSrcDir
+
+ if err := overlayDir(gopathSrcDir, srcDir); err != nil {
+ t.err = err
+ return
+ }
+
+ modFile := fmt.Sprintf("module %s\ngo 1.14\n", modName)
+ if err := ioutil.WriteFile(filepath.Join(gopathSrcDir, "go.mod"), []byte(modFile), 0666); err != nil {
+ t.err = err
+ return
+ }
+
+ cmd := []string{goTool(), "run", goGcflags()}
+ if *linkshared {
+ cmd = append(cmd, "-linkshared")
+ }
+ cmd = append(cmd, ".")
+ out, err := runcmd(cmd...)
+ if err != nil {
+ t.err = err
+ return
+ }
+ if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
+ t.err = fmt.Errorf("incorrect output\n%s", out)
+ }
+
case "build":
- _, err := runcmd("go", "build", "-o", "a.exe", long)
+ // Build Go file.
+ _, err := runcmd(goTool(), "build", goGcflags(), "-o", "a.exe", long)
+ if err != nil {
+ t.err = err
+ }
+
+ case "builddir", "buildrundir":
+ // Build an executable from all the .go and .s files in a subdirectory.
+ // Run it and verify its output in the buildrundir case.
+ longdir := filepath.Join(cwd, t.goDirName())
+ files, dirErr := ioutil.ReadDir(longdir)
+ if dirErr != nil {
+ t.err = dirErr
+ break
+ }
+ var gos []string
+ var asms []string
+ for _, file := range files {
+ switch filepath.Ext(file.Name()) {
+ case ".go":
+ gos = append(gos, filepath.Join(longdir, file.Name()))
+ case ".s":
+ asms = append(asms, filepath.Join(longdir, file.Name()))
+ }
+
+ }
+ if len(asms) > 0 {
+ emptyHdrFile := filepath.Join(t.tempDir, "go_asm.h")
+ if err := ioutil.WriteFile(emptyHdrFile, nil, 0666); err != nil {
+ t.err = fmt.Errorf("write empty go_asm.h: %s", err)
+ return
+ }
+ cmd := []string{goTool(), "tool", "asm", "-gensymabis", "-o", "symabis"}
+ cmd = append(cmd, asms...)
+ _, err = runcmd(cmd...)
+ if err != nil {
+ t.err = err
+ break
+ }
+ }
+ var objs []string
+ cmd := []string{goTool(), "tool", "compile", "-e", "-D", ".", "-I", ".", "-o", "go.o"}
+ if len(asms) > 0 {
+ cmd = append(cmd, "-asmhdr", "go_asm.h", "-symabis", "symabis")
+ }
+ cmd = append(cmd, gos...)
+ _, err := runcmd(cmd...)
+ if err != nil {
+ t.err = err
+ break
+ }
+ objs = append(objs, "go.o")
+ if len(asms) > 0 {
+ cmd = []string{goTool(), "tool", "asm", "-e", "-I", ".", "-o", "asm.o"}
+ cmd = append(cmd, asms...)
+ _, err = runcmd(cmd...)
+ if err != nil {
+ t.err = err
+ break
+ }
+ objs = append(objs, "asm.o")
+ }
+ cmd = []string{goTool(), "tool", "pack", "c", "all.a"}
+ cmd = append(cmd, objs...)
+ _, err = runcmd(cmd...)
+ if err != nil {
+ t.err = err
+ break
+ }
+ cmd = []string{goTool(), "tool", "link", "-o", "a.exe", "all.a"}
+ _, err = runcmd(cmd...)
if err != nil {
t.err = err
+ break
+ }
+ if action == "buildrundir" {
+ cmd = append(findExecCmd(), filepath.Join(t.tempDir, "a.exe"))
+ out, err := runcmd(cmd...)
+ if err != nil {
+ t.err = err
+ break
+ }
+ if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
+ t.err = fmt.Errorf("incorrect output\n%s", out)
+ }
+ }
+
+ case "buildrun":
+ // Build an executable from Go file, then run it, verify its output.
+ // Useful for timeout tests where failure mode is infinite loop.
+ // TODO: not supported on NaCl
+ cmd := []string{goTool(), "build", goGcflags(), "-o", "a.exe"}
+ if *linkshared {
+ cmd = append(cmd, "-linkshared")
+ }
+ longdirgofile := filepath.Join(filepath.Join(cwd, t.dir), t.gofile)
+ cmd = append(cmd, flags...)
+ cmd = append(cmd, longdirgofile)
+ _, err := runcmd(cmd...)
+ if err != nil {
+ t.err = err
+ return
+ }
+ cmd = []string{"./a.exe"}
+ out, err := runcmd(append(cmd, args...)...)
+ if err != nil {
+ t.err = err
+ return
+ }
+
+ if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
+ t.err = fmt.Errorf("incorrect output\n%s", out)
}
case "run":
- useTmp = false
- out, err := runcmd(append([]string{"go", "run", t.goFileName()}, args...)...)
+ // Run Go file if no special go command flags are provided;
+ // otherwise build an executable and run it.
+ // Verify the output.
+ runInDir = ""
+ var out []byte
+ var err error
+ if len(flags)+len(args) == 0 && goGcflagsIsEmpty() && !*linkshared && goarch == runtime.GOARCH && goos == runtime.GOOS {
+ // If we're not using special go command flags,
+ // skip all the go command machinery.
+ // This avoids any time the go command would
+ // spend checking whether, for example, the installed
+ // package runtime is up to date.
+ // Because we run lots of trivial test programs,
+ // the time adds up.
+ pkg := filepath.Join(t.tempDir, "pkg.a")
+ if _, err := runcmd(goTool(), "tool", "compile", "-o", pkg, t.goFileName()); err != nil {
+ t.err = err
+ return
+ }
+ exe := filepath.Join(t.tempDir, "test.exe")
+ cmd := []string{goTool(), "tool", "link", "-s", "-w"}
+ cmd = append(cmd, "-o", exe, pkg)
+ if _, err := runcmd(cmd...); err != nil {
+ t.err = err
+ return
+ }
+ out, err = runcmd(append([]string{exe}, args...)...)
+ } else {
+ cmd := []string{goTool(), "run", goGcflags()}
+ if *linkshared {
+ cmd = append(cmd, "-linkshared")
+ }
+ cmd = append(cmd, flags...)
+ cmd = append(cmd, t.goFileName())
+ out, err = runcmd(append(cmd, args...)...)
+ }
if err != nil {
t.err = err
+ return
}
if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
t.err = fmt.Errorf("incorrect output\n%s", out)
}
case "runoutput":
+ // Run Go file and write its output into temporary Go file.
+ // Run generated Go file and verify its output.
rungatec <- true
defer func() {
<-rungatec
}()
- useTmp = false
- out, err := runcmd(append([]string{"go", "run", t.goFileName()}, args...)...)
+ runInDir = ""
+ cmd := []string{goTool(), "run", goGcflags()}
+ if *linkshared {
+ cmd = append(cmd, "-linkshared")
+ }
+ cmd = append(cmd, t.goFileName())
+ out, err := runcmd(append(cmd, args...)...)
if err != nil {
t.err = err
+ return
}
tfile := filepath.Join(t.tempDir, "tmp__.go")
if err := ioutil.WriteFile(tfile, out, 0666); err != nil {
t.err = fmt.Errorf("write tempfile:%s", err)
return
}
- out, err = runcmd("go", "run", tfile)
+ cmd = []string{goTool(), "run", goGcflags()}
+ if *linkshared {
+ cmd = append(cmd, "-linkshared")
+ }
+ cmd = append(cmd, tfile)
+ out, err = runcmd(cmd...)
if err != nil {
t.err = err
+ return
}
if string(out) != t.expectedOutput() {
t.err = fmt.Errorf("incorrect output\n%s", out)
}
case "errorcheckoutput":
- useTmp = false
- out, err := runcmd(append([]string{"go", "run", t.goFileName()}, args...)...)
+ // Run Go file and write its output into temporary Go file.
+ // Compile and errorCheck generated Go file.
+ runInDir = ""
+ cmd := []string{goTool(), "run", goGcflags()}
+ if *linkshared {
+ cmd = append(cmd, "-linkshared")
+ }
+ cmd = append(cmd, t.goFileName())
+ out, err := runcmd(append(cmd, args...)...)
if err != nil {
t.err = err
+ return
}
tfile := filepath.Join(t.tempDir, "tmp__.go")
err = ioutil.WriteFile(tfile, out, 0666)
@@ -651,7 +1123,7 @@ func (t *test) run() {
t.err = fmt.Errorf("write tempfile:%s", err)
return
}
- cmdline := []string{"go", "tool", gc, "-e", "-o", "a." + letter}
+ cmdline := []string{goTool(), "tool", "compile", "-e", "-o", "a.o"}
cmdline = append(cmdline, flags...)
cmdline = append(cmdline, tfile)
out, err = runcmd(cmdline...)
@@ -666,11 +1138,28 @@ func (t *test) run() {
return
}
}
- t.err = t.errorCheck(string(out), tfile, "tmp__.go")
+ t.err = t.errorCheck(string(out), false, tfile, "tmp__.go")
return
}
}
+var execCmd []string
+
+func findExecCmd() []string {
+ if execCmd != nil {
+ return execCmd
+ }
+ execCmd = []string{} // avoid work the second time
+ if goos == runtime.GOOS && goarch == runtime.GOARCH {
+ return execCmd
+ }
+ path, err := exec.LookPath(fmt.Sprintf("go_%s_%s_exec", goos, goarch))
+ if err == nil {
+ execCmd = []string{path}
+ }
+ return execCmd
+}
+
func (t *test) String() string {
return filepath.Join(t.dir, t.gofile)
}
@@ -678,7 +1167,12 @@ func (t *test) String() string {
func (t *test) makeTempDir() {
var err error
t.tempDir, err = ioutil.TempDir("", "")
- check(err)
+ if err != nil {
+ log.Fatal(err)
+ }
+ if *keep {
+ log.Printf("Temporary directory is %s", t.tempDir)
+ }
}
func (t *test) expectedOutput() string {
@@ -689,29 +1183,45 @@ func (t *test) expectedOutput() string {
return string(b)
}
-func (t *test) errorCheck(outStr string, fullshort ...string) (err error) {
- defer func() {
- if *verbose && err != nil {
- log.Printf("%s gc output:\n%s", t, outStr)
- }
- }()
- var errs []error
-
- var out []string
- // 6g error messages continue onto additional lines with leading tabs.
+func splitOutput(out string, wantAuto bool) []string {
+ // gc error messages continue onto additional lines with leading tabs.
// Split the output at the beginning of each line that doesn't begin with a tab.
- for _, line := range strings.Split(outStr, "\n") {
+ // <autogenerated> lines are impossible to match so those are filtered out.
+ var res []string
+ for _, line := range strings.Split(out, "\n") {
if strings.HasSuffix(line, "\r") { // remove '\r', output by compiler on windows
line = line[:len(line)-1]
}
if strings.HasPrefix(line, "\t") {
- out[len(out)-1] += "\n" + line
- } else if strings.HasPrefix(line, "go tool") {
+ res[len(res)-1] += "\n" + line
+ } else if strings.HasPrefix(line, "go tool") || strings.HasPrefix(line, "#") || !wantAuto && strings.HasPrefix(line, "<autogenerated>") {
continue
} else if strings.TrimSpace(line) != "" {
- out = append(out, line)
+ res = append(res, line)
}
}
+ return res
+}
+
+// errorCheck matches errors in outStr against comments in source files.
+// For each line of the source files which should generate an error,
+// there should be a comment of the form // ERROR "regexp".
+// If outStr has an error for a line which has no such comment,
+// this function will report an error.
+// Likewise if outStr does not have an error for a line which has a comment,
+// or if the error message does not match the <regexp>.
+// The <regexp> syntax is Perl but it's best to stick to egrep.
+//
+// Sources files are supplied as fullshort slice.
+// It consists of pairs: full path to source file and its base name.
+func (t *test) errorCheck(outStr string, wantAuto bool, fullshort ...string) (err error) {
+ defer func() {
+ if *verbose && err != nil {
+ log.Printf("%s gc output:\n%s", t, outStr)
+ }
+ }()
+ var errs []error
+ out := splitOutput(outStr, wantAuto)
// Cut directory name.
for i := range out {
@@ -729,7 +1239,11 @@ func (t *test) errorCheck(outStr string, fullshort ...string) (err error) {
for _, we := range want {
var errmsgs []string
- errmsgs, out = partitionStrings(we.filterRe, out)
+ if we.auto {
+ errmsgs, out = partitionStrings("<autogenerated>", out)
+ } else {
+ errmsgs, out = partitionStrings(we.prefix, out)
+ }
if len(errmsgs) == 0 {
errs = append(errs, fmt.Errorf("%s:%d: missing error %q", we.file, we.lineNum, we.reStr))
continue
@@ -737,7 +1251,13 @@ func (t *test) errorCheck(outStr string, fullshort ...string) (err error) {
matched := false
n := len(out)
for _, errmsg := range errmsgs {
- if we.re.MatchString(errmsg) {
+ // Assume errmsg says "file:line: foo".
+ // Cut leading "file:line: " to avoid accidental matching of file name instead of message.
+ text := errmsg
+ if i := strings.Index(text, " "); i >= 0 {
+ text = text[i+1:]
+ }
+ if we.re.MatchString(text) {
matched = true
} else {
out = append(out, errmsg)
@@ -768,12 +1288,100 @@ func (t *test) errorCheck(outStr string, fullshort ...string) (err error) {
fmt.Fprintf(&buf, "%s\n", err.Error())
}
return errors.New(buf.String())
+}
+
+func (t *test) updateErrors(out, file string) {
+ base := path.Base(file)
+ // Read in source file.
+ src, err := ioutil.ReadFile(file)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ return
+ }
+ lines := strings.Split(string(src), "\n")
+ // Remove old errors.
+ for i, ln := range lines {
+ pos := strings.Index(ln, " // ERROR ")
+ if pos >= 0 {
+ lines[i] = ln[:pos]
+ }
+ }
+ // Parse new errors.
+ errors := make(map[int]map[string]bool)
+ tmpRe := regexp.MustCompile(`autotmp_[0-9]+`)
+ for _, errStr := range splitOutput(out, false) {
+ colon1 := strings.Index(errStr, ":")
+ if colon1 < 0 || errStr[:colon1] != file {
+ continue
+ }
+ colon2 := strings.Index(errStr[colon1+1:], ":")
+ if colon2 < 0 {
+ continue
+ }
+ colon2 += colon1 + 1
+ line, err := strconv.Atoi(errStr[colon1+1 : colon2])
+ line--
+ if err != nil || line < 0 || line >= len(lines) {
+ continue
+ }
+ msg := errStr[colon2+2:]
+ msg = strings.Replace(msg, file, base, -1) // normalize file mentions in error itself
+ msg = strings.TrimLeft(msg, " \t")
+ for _, r := range []string{`\`, `*`, `+`, `?`, `[`, `]`, `(`, `)`} {
+ msg = strings.Replace(msg, r, `\`+r, -1)
+ }
+ msg = strings.Replace(msg, `"`, `.`, -1)
+ msg = tmpRe.ReplaceAllLiteralString(msg, `autotmp_[0-9]+`)
+ if errors[line] == nil {
+ errors[line] = make(map[string]bool)
+ }
+ errors[line][msg] = true
+ }
+ // Add new errors.
+ for line, errs := range errors {
+ var sorted []string
+ for e := range errs {
+ sorted = append(sorted, e)
+ }
+ sort.Strings(sorted)
+ lines[line] += " // ERROR"
+ for _, e := range sorted {
+ lines[line] += fmt.Sprintf(` "%s$"`, e)
+ }
+ }
+ // Write new file.
+ err = ioutil.WriteFile(file, []byte(strings.Join(lines, "\n")), 0640)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ return
+ }
+ // Polish.
+ exec.Command(goTool(), "fmt", file).CombinedOutput()
+}
+// matchPrefix reports whether s is of the form ^(.*/)?prefix(:|[),
+// That is, it needs the file name prefix followed by a : or a [,
+// and possibly preceded by a directory name.
+func matchPrefix(s, prefix string) bool {
+ i := strings.Index(s, ":")
+ if i < 0 {
+ return false
+ }
+ j := strings.LastIndex(s[:i], "/")
+ s = s[j+1:]
+ if len(s) <= len(prefix) || s[:len(prefix)] != prefix {
+ return false
+ }
+ switch s[len(prefix)] {
+ case '[', ':':
+ return true
+ }
+ return false
}
-func partitionStrings(rx *regexp.Regexp, strs []string) (matched, unmatched []string) {
+func partitionStrings(prefix string, strs []string) (matched, unmatched []string) {
for _, s := range strs {
- if rx.MatchString(s) {
+ if matchPrefix(s, prefix) {
matched = append(matched, s)
} else {
unmatched = append(unmatched, s)
@@ -783,20 +1391,24 @@ func partitionStrings(rx *regexp.Regexp, strs []string) (matched, unmatched []st
}
type wantedError struct {
- reStr string
- re *regexp.Regexp
- lineNum int
- file string
- filterRe *regexp.Regexp // /^file:linenum\b/m
+ reStr string
+ re *regexp.Regexp
+ lineNum int
+ auto bool // match <autogenerated> line
+ file string
+ prefix string
}
var (
errRx = regexp.MustCompile(`// (?:GC_)?ERROR (.*)`)
+ errAutoRx = regexp.MustCompile(`// (?:GC_)?ERRORAUTO (.*)`)
errQuotesRx = regexp.MustCompile(`"([^"]*)"`)
lineRx = regexp.MustCompile(`LINE(([+-])([0-9]+))?`)
)
func (t *test) wantedErrors(file, short string) (errs []wantedError) {
+ cache := make(map[string]*regexp.Regexp)
+
src, _ := ioutil.ReadFile(file)
for i, line := range strings.Split(string(src), "\n") {
lineNum := i + 1
@@ -804,7 +1416,13 @@ func (t *test) wantedErrors(file, short string) (errs []wantedError) {
// double comment disables ERROR
continue
}
- m := errRx.FindStringSubmatch(line)
+ var auto bool
+ m := errAutoRx.FindStringSubmatch(line)
+ if m != nil {
+ auto = true
+ } else {
+ m = errRx.FindStringSubmatch(line)
+ }
if m == nil {
continue
}
@@ -825,17 +1443,23 @@ func (t *test) wantedErrors(file, short string) (errs []wantedError) {
}
return fmt.Sprintf("%s:%d", short, n)
})
- re, err := regexp.Compile(rx)
- if err != nil {
- log.Fatalf("%s:%d: invalid regexp in ERROR line: %v", t.goFileName(), lineNum, err)
+ re := cache[rx]
+ if re == nil {
+ var err error
+ re, err = regexp.Compile(rx)
+ if err != nil {
+ log.Fatalf("%s:%d: invalid regexp \"%s\" in ERROR line: %v", t.goFileName(), lineNum, rx, err)
+ }
+ cache[rx] = re
}
- filterPattern := fmt.Sprintf(`^(\w+/)?%s:%d[:[]`, regexp.QuoteMeta(short), lineNum)
+ prefix := fmt.Sprintf("%s:%d", short, lineNum)
errs = append(errs, wantedError{
- reStr: rx,
- re: re,
- filterRe: regexp.MustCompile(filterPattern),
- lineNum: lineNum,
- file: short,
+ reStr: rx,
+ re: re,
+ prefix: prefix,
+ auto: auto,
+ lineNum: lineNum,
+ file: short,
})
}
}
@@ -843,15 +1467,267 @@ func (t *test) wantedErrors(file, short string) (errs []wantedError) {
return
}
-var skipOkay = map[string]bool{
- "linkx.go": true, // like "run" but wants linker flags
- "sinit.go": true,
- "fixedbugs/bug248.go": true, // combines errorcheckdir and rundir in the same dir.
- "fixedbugs/bug302.go": true, // tests both .$O and .a imports.
- "fixedbugs/bug345.go": true, // needs the appropriate flags in gc invocation.
- "fixedbugs/bug369.go": true, // needs compiler flags.
- "fixedbugs/bug429.go": true, // like "run" but program should fail
- "bugs/bug395.go": true,
+const (
+ // Regexp to match a single opcode check: optionally begin with "-" (to indicate
+ // a negative check), followed by a string literal enclosed in "" or ``. For "",
+ // backslashes must be handled.
+ reMatchCheck = `-?(?:\x60[^\x60]*\x60|"(?:[^"\\]|\\.)*")`
+)
+
+var (
+ // Regexp to split a line in code and comment, trimming spaces
+ rxAsmComment = regexp.MustCompile(`^\s*(.*?)\s*(?://\s*(.+)\s*)?$`)
+
+ // Regexp to extract an architecture check: architecture name (or triplet),
+ // followed by semi-colon, followed by a comma-separated list of opcode checks.
+ // Extraneous spaces are ignored.
+ rxAsmPlatform = regexp.MustCompile(`(\w+)(/\w+)?(/\w*)?\s*:\s*(` + reMatchCheck + `(?:\s*,\s*` + reMatchCheck + `)*)`)
+
+ // Regexp to extract a single opcoded check
+ rxAsmCheck = regexp.MustCompile(reMatchCheck)
+
+ // List of all architecture variants. Key is the GOARCH architecture,
+ // value[0] is the variant-changing environment variable, and values[1:]
+ // are the supported variants.
+ archVariants = map[string][]string{
+ "386": {"GO386", "sse2", "softfloat"},
+ "amd64": {},
+ "arm": {"GOARM", "5", "6", "7"},
+ "arm64": {},
+ "mips": {"GOMIPS", "hardfloat", "softfloat"},
+ "mips64": {"GOMIPS64", "hardfloat", "softfloat"},
+ "ppc64": {"GOPPC64", "power8", "power9"},
+ "ppc64le": {"GOPPC64", "power8", "power9"},
+ "s390x": {},
+ "wasm": {},
+ }
+)
+
+// wantedAsmOpcode is a single asmcheck check
+type wantedAsmOpcode struct {
+ fileline string // original source file/line (eg: "/path/foo.go:45")
+ line int // original source line
+ opcode *regexp.Regexp // opcode check to be performed on assembly output
+ negative bool // true if the check is supposed to fail rather than pass
+ found bool // true if the opcode check matched at least one in the output
+}
+
+// A build environment triplet separated by slashes (eg: linux/386/sse2).
+// The third field can be empty if the arch does not support variants (eg: "plan9/amd64/")
+type buildEnv string
+
+// Environ returns the environment it represents in cmd.Environ() "key=val" format
+// For instance, "linux/386/sse2".Environ() returns {"GOOS=linux", "GOARCH=386", "GO386=sse2"}
+func (b buildEnv) Environ() []string {
+ fields := strings.Split(string(b), "/")
+ if len(fields) != 3 {
+ panic("invalid buildEnv string: " + string(b))
+ }
+ env := []string{"GOOS=" + fields[0], "GOARCH=" + fields[1]}
+ if fields[2] != "" {
+ env = append(env, archVariants[fields[1]][0]+"="+fields[2])
+ }
+ return env
+}
+
+// asmChecks represents all the asmcheck checks present in a test file
+// The outer map key is the build triplet in which the checks must be performed.
+// The inner map key represent the source file line ("filename.go:1234") at which the
+// checks must be performed.
+type asmChecks map[buildEnv]map[string][]wantedAsmOpcode
+
+// Envs returns all the buildEnv in which at least one check is present
+func (a asmChecks) Envs() []buildEnv {
+ var envs []buildEnv
+ for e := range a {
+ envs = append(envs, e)
+ }
+ sort.Slice(envs, func(i, j int) bool {
+ return string(envs[i]) < string(envs[j])
+ })
+ return envs
+}
+
+func (t *test) wantedAsmOpcodes(fn string) asmChecks {
+ ops := make(asmChecks)
+
+ comment := ""
+ src, _ := ioutil.ReadFile(fn)
+ for i, line := range strings.Split(string(src), "\n") {
+ matches := rxAsmComment.FindStringSubmatch(line)
+ code, cmt := matches[1], matches[2]
+
+ // Keep comments pending in the comment variable until
+ // we find a line that contains some code.
+ comment += " " + cmt
+ if code == "" {
+ continue
+ }
+
+ // Parse and extract any architecture check from comments,
+ // made by one architecture name and multiple checks.
+ lnum := fn + ":" + strconv.Itoa(i+1)
+ for _, ac := range rxAsmPlatform.FindAllStringSubmatch(comment, -1) {
+ archspec, allchecks := ac[1:4], ac[4]
+
+ var arch, subarch, os string
+ switch {
+ case archspec[2] != "": // 3 components: "linux/386/sse2"
+ os, arch, subarch = archspec[0], archspec[1][1:], archspec[2][1:]
+ case archspec[1] != "": // 2 components: "386/sse2"
+ os, arch, subarch = "linux", archspec[0], archspec[1][1:]
+ default: // 1 component: "386"
+ os, arch, subarch = "linux", archspec[0], ""
+ if arch == "wasm" {
+ os = "js"
+ }
+ }
+
+ if _, ok := archVariants[arch]; !ok {
+ log.Fatalf("%s:%d: unsupported architecture: %v", t.goFileName(), i+1, arch)
+ }
+
+ // Create the build environments corresponding the above specifiers
+ envs := make([]buildEnv, 0, 4)
+ if subarch != "" {
+ envs = append(envs, buildEnv(os+"/"+arch+"/"+subarch))
+ } else {
+ subarchs := archVariants[arch]
+ if len(subarchs) == 0 {
+ envs = append(envs, buildEnv(os+"/"+arch+"/"))
+ } else {
+ for _, sa := range archVariants[arch][1:] {
+ envs = append(envs, buildEnv(os+"/"+arch+"/"+sa))
+ }
+ }
+ }
+
+ for _, m := range rxAsmCheck.FindAllString(allchecks, -1) {
+ negative := false
+ if m[0] == '-' {
+ negative = true
+ m = m[1:]
+ }
+
+ rxsrc, err := strconv.Unquote(m)
+ if err != nil {
+ log.Fatalf("%s:%d: error unquoting string: %v", t.goFileName(), i+1, err)
+ }
+
+ // Compile the checks as regular expressions. Notice that we
+ // consider checks as matching from the beginning of the actual
+ // assembler source (that is, what is left on each line of the
+ // compile -S output after we strip file/line info) to avoid
+ // trivial bugs such as "ADD" matching "FADD". This
+ // doesn't remove genericity: it's still possible to write
+ // something like "F?ADD", but we make common cases simpler
+ // to get right.
+ oprx, err := regexp.Compile("^" + rxsrc)
+ if err != nil {
+ log.Fatalf("%s:%d: %v", t.goFileName(), i+1, err)
+ }
+
+ for _, env := range envs {
+ if ops[env] == nil {
+ ops[env] = make(map[string][]wantedAsmOpcode)
+ }
+ ops[env][lnum] = append(ops[env][lnum], wantedAsmOpcode{
+ negative: negative,
+ fileline: lnum,
+ line: i + 1,
+ opcode: oprx,
+ })
+ }
+ }
+ }
+ comment = ""
+ }
+
+ return ops
+}
+
+func (t *test) asmCheck(outStr string, fn string, env buildEnv, fullops map[string][]wantedAsmOpcode) (err error) {
+ // The assembly output contains the concatenated dump of multiple functions.
+ // the first line of each function begins at column 0, while the rest is
+ // indented by a tabulation. These data structures help us index the
+ // output by function.
+ functionMarkers := make([]int, 1)
+ lineFuncMap := make(map[string]int)
+
+ lines := strings.Split(outStr, "\n")
+ rxLine := regexp.MustCompile(fmt.Sprintf(`\((%s:\d+)\)\s+(.*)`, regexp.QuoteMeta(fn)))
+
+ for nl, line := range lines {
+ // Check if this line begins a function
+ if len(line) > 0 && line[0] != '\t' {
+ functionMarkers = append(functionMarkers, nl)
+ }
+
+ // Search if this line contains a assembly opcode (which is prefixed by the
+ // original source file/line in parenthesis)
+ matches := rxLine.FindStringSubmatch(line)
+ if len(matches) == 0 {
+ continue
+ }
+ srcFileLine, asm := matches[1], matches[2]
+
+ // Associate the original file/line information to the current
+ // function in the output; it will be useful to dump it in case
+ // of error.
+ lineFuncMap[srcFileLine] = len(functionMarkers) - 1
+
+ // If there are opcode checks associated to this source file/line,
+ // run the checks.
+ if ops, found := fullops[srcFileLine]; found {
+ for i := range ops {
+ if !ops[i].found && ops[i].opcode.FindString(asm) != "" {
+ ops[i].found = true
+ }
+ }
+ }
+ }
+ functionMarkers = append(functionMarkers, len(lines))
+
+ var failed []wantedAsmOpcode
+ for _, ops := range fullops {
+ for _, o := range ops {
+ // There's a failure if a negative match was found,
+ // or a positive match was not found.
+ if o.negative == o.found {
+ failed = append(failed, o)
+ }
+ }
+ }
+ if len(failed) == 0 {
+ return
+ }
+
+ // At least one asmcheck failed; report them
+ sort.Slice(failed, func(i, j int) bool {
+ return failed[i].line < failed[j].line
+ })
+
+ lastFunction := -1
+ var errbuf bytes.Buffer
+ fmt.Fprintln(&errbuf)
+ for _, o := range failed {
+ // Dump the function in which this opcode check was supposed to
+ // pass but failed.
+ funcIdx := lineFuncMap[o.fileline]
+ if funcIdx != 0 && funcIdx != lastFunction {
+ funcLines := lines[functionMarkers[funcIdx]:functionMarkers[funcIdx+1]]
+ log.Println(strings.Join(funcLines, "\n"))
+ lastFunction = funcIdx // avoid printing same function twice
+ }
+
+ if o.negative {
+ fmt.Fprintf(&errbuf, "%s:%d: %s: wrong opcode found: %q\n", t.goFileName(), o.line, env, o.opcode.String())
+ } else {
+ fmt.Fprintf(&errbuf, "%s:%d: %s: opcode not found: %q\n", t.goFileName(), o.line, env, o.opcode.String())
+ }
+ }
+ err = errors.New(errbuf.String())
+ return
}
// defaultRunOutputLimit returns the number of runoutput tests that
@@ -886,7 +1762,7 @@ func checkShouldTest() {
// Build tags separated by a space are OR-ed together.
assertNot(shouldTest("// +build arm 386", "linux", "amd64"))
- // Build tags seperated by a comma are AND-ed together.
+ // Build tags separated by a comma are AND-ed together.
assertNot(shouldTest("// +build !windows,!plan9", "windows", "amd64"))
assertNot(shouldTest("// +build !windows,!plan9", "plan9", "386"))
@@ -898,19 +1774,75 @@ func checkShouldTest() {
assert(shouldTest("// +build !windows !plan9", "windows", "amd64"))
}
-// envForDir returns a copy of the environment
-// suitable for running in the given directory.
-// The environment is the current process's environment
-// but with an updated $PWD, so that an os.Getwd in the
-// child will be faster.
-func envForDir(dir string) []string {
- env := os.Environ()
- for i, kv := range env {
- if strings.HasPrefix(kv, "PWD=") {
- env[i] = "PWD=" + dir
- return env
- }
+func getenv(key, def string) string {
+ value := os.Getenv(key)
+ if value != "" {
+ return value
}
- env = append(env, "PWD="+dir)
- return env
+ return def
+}
+
+// overlayDir makes a minimal-overhead copy of srcRoot in which new files may be added.
+func overlayDir(dstRoot, srcRoot string) error {
+ dstRoot = filepath.Clean(dstRoot)
+ if err := os.MkdirAll(dstRoot, 0777); err != nil {
+ return err
+ }
+
+ srcRoot, err := filepath.Abs(srcRoot)
+ if err != nil {
+ return err
+ }
+
+ return filepath.WalkDir(srcRoot, func(srcPath string, d fs.DirEntry, err error) error {
+ if err != nil || srcPath == srcRoot {
+ return err
+ }
+
+ suffix := strings.TrimPrefix(srcPath, srcRoot)
+ for len(suffix) > 0 && suffix[0] == filepath.Separator {
+ suffix = suffix[1:]
+ }
+ dstPath := filepath.Join(dstRoot, suffix)
+
+ var info fs.FileInfo
+ if d.Type()&os.ModeSymlink != 0 {
+ info, err = os.Stat(srcPath)
+ } else {
+ info, err = d.Info()
+ }
+ if err != nil {
+ return err
+ }
+ perm := info.Mode() & os.ModePerm
+
+ // Always copy directories (don't symlink them).
+ // If we add a file in the overlay, we don't want to add it in the original.
+ if info.IsDir() {
+ return os.MkdirAll(dstPath, perm|0200)
+ }
+
+ // If the OS supports symlinks, use them instead of copying bytes.
+ if err := os.Symlink(srcPath, dstPath); err == nil {
+ return nil
+ }
+
+ // Otherwise, copy the bytes.
+ src, err := os.Open(srcPath)
+ if err != nil {
+ return err
+ }
+ defer src.Close()
+
+ dst, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm)
+ if err != nil {
+ return err
+ }
+
+ _, err = io.Copy(dst, src)
+ if closeErr := dst.Close(); err == nil {
+ err = closeErr
+ }
+ return err
+ })
}
diff --git a/gcc/testsuite/go.test/test/rune.go b/gcc/testsuite/go.test/test/rune.go
index c013c47..73a5aa2 100644
--- a/gcc/testsuite/go.test/test/rune.go
+++ b/gcc/testsuite/go.test/test/rune.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/runtime.go b/gcc/testsuite/go.test/test/runtime.go
index 89f59e3..bccc9b5 100644
--- a/gcc/testsuite/go.test/test/runtime.go
+++ b/gcc/testsuite/go.test/test/runtime.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2009 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.
diff --git a/gcc/testsuite/go.test/test/safe/main.go b/gcc/testsuite/go.test/test/safe/main.go
deleted file mode 100644
index d173ed9..0000000
--- a/gcc/testsuite/go.test/test/safe/main.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// true
-
-// Copyright 2012 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 main
-
-// can't use local path with -u, use -I. instead
-import "pkg" // ERROR "import unsafe package"
-
-func main() {
- print(pkg.Float32bits(1.0))
-}
diff --git a/gcc/testsuite/go.test/test/safe/nousesafe.go b/gcc/testsuite/go.test/test/safe/nousesafe.go
deleted file mode 100644
index fcd25af..0000000
--- a/gcc/testsuite/go.test/test/safe/nousesafe.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// $G $D/pkg.go && pack grc pkg.a pkg.$A 2> /dev/null && rm pkg.$A && errchk $G -I . -u $D/main.go
-// rm -f pkg.a
-
-// Copyright 2012 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 ignored
diff --git a/gcc/testsuite/go.test/test/safe/pkg.go b/gcc/testsuite/go.test/test/safe/pkg.go
deleted file mode 100644
index bebc43a..0000000
--- a/gcc/testsuite/go.test/test/safe/pkg.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// true
-
-// Copyright 2012 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.
-
-// a package that uses unsafe on the inside but not in it's api
-
-package pkg
-
-import "unsafe"
-
-// this should be inlinable
-func Float32bits(f float32) uint32 {
- return *(*uint32)(unsafe.Pointer(&f))
-} \ No newline at end of file
diff --git a/gcc/testsuite/go.test/test/safe/usesafe.go b/gcc/testsuite/go.test/test/safe/usesafe.go
deleted file mode 100644
index 5d0829e..0000000
--- a/gcc/testsuite/go.test/test/safe/usesafe.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// $G $D/pkg.go && pack grcS pkg.a pkg.$A 2> /dev/null && rm pkg.$A && $G -I . -u $D/main.go
-// rm -f pkg.a
-
-// Copyright 2012 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 ignored
diff --git a/gcc/testsuite/go.test/test/shift1.go b/gcc/testsuite/go.test/test/shift1.go
index 04f5321..d6a6c38 100644
--- a/gcc/testsuite/go.test/test/shift1.go
+++ b/gcc/testsuite/go.test/test/shift1.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
@@ -18,13 +18,13 @@ func h(x float64) int { return 0 }
var (
s uint = 33
u = 1.0 << s // ERROR "invalid operation|shift of non-integer operand"
- v float32 = 1 << s // ERROR "invalid" "as type float32"
+ v float32 = 1 << s // ERROR "invalid"
)
// non-constant shift expressions
var (
- e1 = g(2.0 << s) // ERROR "invalid|shift of non-integer operand" "as type interface"
- f1 = h(2 << s) // ERROR "invalid" "as type float64"
+ e1 = g(2.0 << s) // ERROR "invalid|shift of non-integer operand"
+ f1 = h(2 << s) // ERROR "invalid"
g1 int64 = 1.1 << s // ERROR "truncated"
)
@@ -66,8 +66,15 @@ func _() {
u2 = 1<<s != 1.0 // ERROR "non-integer|float64"
v float32 = 1 << s // ERROR "non-integer|float32"
w int64 = 1.0 << 33 // 1.0<<33 is a constant shift expression
+
_, _, _, _, _, _, _, _, _, _ = j, k, m, n, o, u, u1, u2, v, w
)
+
+ // non constants arguments trigger a different path
+ f2 := 1.2
+ s2 := "hi"
+ _ = f2 << 2 // ERROR "shift of type float64|non-integer"
+ _ = s2 << 2 // ERROR "shift of type string|non-integer"
}
// shifts in comparisons w/ untyped operands
@@ -146,8 +153,7 @@ func _() {
var a []int
_ = a[1<<s]
_ = a[1.]
- // For now, the spec disallows these. We may revisit past Go 1.1.
- _ = a[1.<<s] // ERROR "integer|shift of type float64"
+ _ = a[1.<<s]
_ = a[1.1<<s] // ERROR "integer|shift of type float64"
_ = make([]int, 1)
diff --git a/gcc/testsuite/go.test/test/shift2.go b/gcc/testsuite/go.test/test/shift2.go
index 80e6bbc..adbfb77 100644
--- a/gcc/testsuite/go.test/test/shift2.go
+++ b/gcc/testsuite/go.test/test/shift2.go
@@ -1,6 +1,6 @@
// compile
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/sigchld.go b/gcc/testsuite/go.test/test/sigchld.go
index a60d28d..3b49606 100644
--- a/gcc/testsuite/go.test/test/sigchld.go
+++ b/gcc/testsuite/go.test/test/sigchld.go
@@ -1,5 +1,5 @@
-// +build !windows
-// cmpout
+// +build !plan9,!windows
+// run
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
diff --git a/gcc/testsuite/go.test/test/sinit.go b/gcc/testsuite/go.test/test/sinit.go
index 5e50e11..df4d50d 100644
--- a/gcc/testsuite/go.test/test/sinit.go
+++ b/gcc/testsuite/go.test/test/sinit.go
@@ -1,17 +1,17 @@
-// $G -S $D/$F.go | egrep initdone >/dev/null && echo BUG sinit || true
+// skip
-// NOTE: This test is not run by 'run.go' and so not run by all.bash.
-// To run this test you must use the ./run shell script.
-
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Test that many initializations can be done at link time and
// generate no executable init functions.
+// This test is run by sinit_run.go.
package p
+import "unsafe"
+
// Should be no init func in the assembly.
// All these initializations should be done at link time.
@@ -43,15 +43,12 @@ var c = []int{1201, 1202, 1203}
var aa = [3][3]int{[3]int{2001, 2002, 2003}, [3]int{2004, 2005, 2006}, [3]int{2007, 2008, 2009}}
var as = [3]S{S{2101, 2102, 2103}, S{2104, 2105, 2106}, S{2107, 2108, 2109}}
-var ac = [3][]int{[]int{2201, 2202, 2203}, []int{2204, 2205, 2206}, []int{2207, 2208, 2209}}
var sa = SA{[3]int{3001, 3002, 3003}, [3]int{3004, 3005, 3006}, [3]int{3007, 3008, 3009}}
var ss = SS{S{3101, 3102, 3103}, S{3104, 3105, 3106}, S{3107, 3108, 3109}}
-var sc = SC{[]int{3201, 3202, 3203}, []int{3204, 3205, 3206}, []int{3207, 3208, 3209}}
var ca = [][3]int{[3]int{4001, 4002, 4003}, [3]int{4004, 4005, 4006}, [3]int{4007, 4008, 4009}}
var cs = []S{S{4101, 4102, 4103}, S{4104, 4105, 4106}, S{4107, 4108, 4109}}
-var cc = [][]int{[]int{4201, 4202, 4203}, []int{4204, 4205, 4206}, []int{4207, 4208, 4209}}
var answers = [...]int{
// s
@@ -106,20 +103,27 @@ var answers = [...]int{
}
var (
- copy_zero = zero
- copy_one = one
- copy_pi = pi
- copy_slice = slice
+ copy_zero = zero
+ copy_one = one
+ copy_pi = pi
+ copy_slice = slice
copy_sliceInt = sliceInt
- copy_hello = hello
- copy_bytes = bytes
+ copy_hello = hello
+
+ // Could be handled without an initialization function, but
+ // requires special handling for "a = []byte("..."); b = a"
+ // which is not a likely case.
+ // copy_bytes = bytes
+ // https://codereview.appspot.com/171840043 is one approach to
+ // make this special case work.
+
copy_four, copy_five = four, five
- copy_x, copy_y = x, y
- copy_nilslice = nilslice
- copy_nilmap = nilmap
- copy_nilfunc = nilfunc
- copy_nilchan = nilchan
- copy_nilptr = nilptr
+ copy_x, copy_y = x, y
+ copy_nilslice = nilslice
+ copy_nilmap = nilmap
+ copy_nilfunc = nilfunc
+ copy_nilchan = nilchan
+ copy_nilptr = nilptr
)
var copy_a = a
@@ -128,15 +132,12 @@ var copy_c = c
var copy_aa = aa
var copy_as = as
-var copy_ac = ac
var copy_sa = sa
var copy_ss = ss
-var copy_sc = sc
var copy_ca = ca
var copy_cs = cs
-var copy_cc = cc
var copy_answers = answers
@@ -172,7 +173,7 @@ var sx []int
var s0 = []int{0, 0, 0}
var s1 = []int{1, 2, 3}
-func fi() int
+func fi() int { return 1 }
var ax [10]int
var a0 = [10]int{0, 0, 0}
@@ -202,58 +203,66 @@ var pt0b = &T{X: 0}
var pt1 = &T{X: 1, Y: 2}
var pt1a = &T{3, 4}
-var copy_bx = bx
+// The checks similar to
+// var copy_bx = bx
+// are commented out. The compiler no longer statically initializes them.
+// See issue 7665 and https://codereview.appspot.com/93200044.
+// If https://codereview.appspot.com/169040043 is submitted, and this
+// test is changed to pass -complete to the compiler, then we can
+// uncomment the copy lines again.
+
+// var copy_bx = bx
var copy_b0 = b0
var copy_b1 = b1
-var copy_fx = fx
+// var copy_fx = fx
var copy_f0 = f0
var copy_f1 = f1
-var copy_gx = gx
+// var copy_gx = gx
var copy_g0 = g0
var copy_g1 = g1
-var copy_ix = ix
+// var copy_ix = ix
var copy_i0 = i0
var copy_i1 = i1
-var copy_jx = jx
+// var copy_jx = jx
var copy_j0 = j0
var copy_j1 = j1
-var copy_cx = cx
+// var copy_cx = cx
var copy_c0 = c0
var copy_c1 = c1
-var copy_dx = dx
+// var copy_dx = dx
var copy_d0 = d0
var copy_d1 = d1
-var copy_sx = sx
+// var copy_sx = sx
var copy_s0 = s0
var copy_s1 = s1
-var copy_ax = ax
+// var copy_ax = ax
var copy_a0 = a0
var copy_a1 = a1
-var copy_tx = tx
+// var copy_tx = tx
var copy_t0 = t0
var copy_t0a = t0a
var copy_t0b = t0b
var copy_t1 = t1
var copy_t1a = t1a
-var copy_psx = psx
+// var copy_psx = psx
var copy_ps0 = ps0
var copy_ps1 = ps1
-var copy_pax = pax
+// var copy_pax = pax
var copy_pa0 = pa0
var copy_pa1 = pa1
-var copy_ptx = ptx
+// var copy_ptx = ptx
var copy_pt0 = pt0
var copy_pt0a = pt0a
var copy_pt0b = pt0b
@@ -266,6 +275,11 @@ type T1 int
func (t *T1) M() {}
-type Mer interface { M() }
+type Mer interface {
+ M()
+}
var _ Mer = (*T1)(nil)
+
+var Byte byte
+var PtrByte unsafe.Pointer = unsafe.Pointer(&Byte)
diff --git a/gcc/testsuite/go.test/test/sizeof.go b/gcc/testsuite/go.test/test/sizeof.go
index c3db1e5..3e2689f 100644
--- a/gcc/testsuite/go.test/test/sizeof.go
+++ b/gcc/testsuite/go.test/test/sizeof.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/slice3err.go b/gcc/testsuite/go.test/test/slice3err.go
index 83fb39b..1309fdd 100644
--- a/gcc/testsuite/go.test/test/slice3err.go
+++ b/gcc/testsuite/go.test/test/slice3err.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/stress/maps.go b/gcc/testsuite/go.test/test/stress/maps.go
index d022e19..8ada23a 100644
--- a/gcc/testsuite/go.test/test/stress/maps.go
+++ b/gcc/testsuite/go.test/test/stress/maps.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -97,6 +97,8 @@ func (m intMap) Len() int { return len(m) }
func (m intMap) RangeAll() {
for _ = range m {
}
+ for range m {
+ }
}
func stressMaps() {
diff --git a/gcc/testsuite/go.test/test/stress/parsego.go b/gcc/testsuite/go.test/test/stress/parsego.go
index a781f19..98c4d9a 100644
--- a/gcc/testsuite/go.test/test/stress/parsego.go
+++ b/gcc/testsuite/go.test/test/stress/parsego.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -64,7 +64,7 @@ func parseDir(dirpath string) map[string]*ast.Package {
}
func stressParseGo() {
- pkgroot := runtime.GOROOT() + "/src/pkg/"
+ pkgroot := runtime.GOROOT() + "/src/"
for {
m := make(map[string]map[string]*ast.Package)
for _, pkg := range packages {
diff --git a/gcc/testsuite/go.test/test/stress/runstress.go b/gcc/testsuite/go.test/test/stress/runstress.go
index 76ab2a8..3f16fc9 100644
--- a/gcc/testsuite/go.test/test/stress/runstress.go
+++ b/gcc/testsuite/go.test/test/stress/runstress.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/struct0.go b/gcc/testsuite/go.test/test/struct0.go
index e29eb30..403e977 100644
--- a/gcc/testsuite/go.test/test/struct0.go
+++ b/gcc/testsuite/go.test/test/struct0.go
@@ -1,6 +1,6 @@
// run
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/syntax/chan.go b/gcc/testsuite/go.test/test/syntax/chan.go
index 3b68bda..6f9d77d 100644
--- a/gcc/testsuite/go.test/test/syntax/chan.go
+++ b/gcc/testsuite/go.test/test/syntax/chan.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -8,10 +8,10 @@ package main
type xyz struct {
ch chan
-} // ERROR "unexpected .*}.* in channel type"
+} // ERROR "unexpected .*}.* in channel type|missing channel element type"
-func Foo(y chan) { // ERROR "unexpected .*\).* in channel type"
+func Foo(y chan) { // ERROR "unexpected .*\).* in channel type|missing channel element type"
}
-func Bar(x chan, y int) { // ERROR "unexpected comma in channel type"
+func Bar(x chan, y int) { // ERROR "unexpected comma in channel type|missing channel element type"
}
diff --git a/gcc/testsuite/go.test/test/syntax/chan1.go b/gcc/testsuite/go.test/test/syntax/chan1.go
index 4860422..88a5b47 100644
--- a/gcc/testsuite/go.test/test/syntax/chan1.go
+++ b/gcc/testsuite/go.test/test/syntax/chan1.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -10,8 +10,8 @@ var c chan int
var v int
func main() {
- if c <- v { // ERROR "used as value"
+ if c <- v { // ERROR "cannot use c <- v as value|send statement used as value"
}
}
-var _ = c <- v // ERROR "used as value"
+var _ = c <- v // ERROR "unexpected <-|send statement used as value"
diff --git a/gcc/testsuite/go.test/test/syntax/composite.go b/gcc/testsuite/go.test/test/syntax/composite.go
index 6565334..f891931 100644
--- a/gcc/testsuite/go.test/test/syntax/composite.go
+++ b/gcc/testsuite/go.test/test/syntax/composite.go
@@ -1,11 +1,11 @@
// errorcheck
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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 main
var a = []int{
- 3 // ERROR "need trailing comma before newline in composite literal"
+ 3 // ERROR "need trailing comma before newline in composite literal|expecting comma or }"
}
diff --git a/gcc/testsuite/go.test/test/syntax/else.go b/gcc/testsuite/go.test/test/syntax/else.go
index e985a9c..9537329 100644
--- a/gcc/testsuite/go.test/test/syntax/else.go
+++ b/gcc/testsuite/go.test/test/syntax/else.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/syntax/forvar.go b/gcc/testsuite/go.test/test/syntax/forvar.go
deleted file mode 100644
index dc592d2..0000000
--- a/gcc/testsuite/go.test/test/syntax/forvar.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// errorcheck
-
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-func main() {
- for var x = 0; x < 10; x++ { // ERROR "var declaration not allowed in for initializer"
diff --git a/gcc/testsuite/go.test/test/syntax/if.go b/gcc/testsuite/go.test/test/syntax/if.go
index b2a65f9..c208a9f 100644
--- a/gcc/testsuite/go.test/test/syntax/if.go
+++ b/gcc/testsuite/go.test/test/syntax/if.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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.
diff --git a/gcc/testsuite/go.test/test/syntax/import.go b/gcc/testsuite/go.test/test/syntax/import.go
index f0a7921..8010bed 100644
--- a/gcc/testsuite/go.test/test/syntax/import.go
+++ b/gcc/testsuite/go.test/test/syntax/import.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/syntax/interface.go b/gcc/testsuite/go.test/test/syntax/interface.go
index 0b76b54..010d3ce 100644
--- a/gcc/testsuite/go.test/test/syntax/interface.go
+++ b/gcc/testsuite/go.test/test/syntax/interface.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/syntax/semi1.go b/gcc/testsuite/go.test/test/syntax/semi1.go
index 6e04281..8eed05c 100644
--- a/gcc/testsuite/go.test/test/syntax/semi1.go
+++ b/gcc/testsuite/go.test/test/syntax/semi1.go
@@ -1,13 +1,13 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
func main() {
- if x; y // ERROR "missing .*{.* after if clause|undefined"
+ if x; y // ERROR "expected .*{.* after if clause|undefined"
{
z // GCCGO_ERROR "undefined"
diff --git a/gcc/testsuite/go.test/test/syntax/semi2.go b/gcc/testsuite/go.test/test/syntax/semi2.go
index 23d7bd0..9216789 100644
--- a/gcc/testsuite/go.test/test/syntax/semi2.go
+++ b/gcc/testsuite/go.test/test/syntax/semi2.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/syntax/semi3.go b/gcc/testsuite/go.test/test/syntax/semi3.go
index ca070d8..d064ce6 100644
--- a/gcc/testsuite/go.test/test/syntax/semi3.go
+++ b/gcc/testsuite/go.test/test/syntax/semi3.go
@@ -1,13 +1,13 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
func main() {
- for x; y; z // ERROR "missing .*{.* after for clause|undefined"
+ for x; y; z // ERROR "expected .*{.* after for clause|undefined"
{
z // GCCGO_ERROR "undefined"
diff --git a/gcc/testsuite/go.test/test/syntax/semi4.go b/gcc/testsuite/go.test/test/syntax/semi4.go
index 99c2d22..08c3547 100644
--- a/gcc/testsuite/go.test/test/syntax/semi4.go
+++ b/gcc/testsuite/go.test/test/syntax/semi4.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -8,7 +8,5 @@ package main
func main() {
for x // GCCGO_ERROR "undefined"
- { // ERROR "missing .*{.* after for clause"
+ { // ERROR "unexpected {, expecting for loop condition|expecting .*{.* after for clause"
z // GCCGO_ERROR "undefined"
-
-
diff --git a/gcc/testsuite/go.test/test/syntax/semi5.go b/gcc/testsuite/go.test/test/syntax/semi5.go
index cf690f0..c54a994 100644
--- a/gcc/testsuite/go.test/test/syntax/semi5.go
+++ b/gcc/testsuite/go.test/test/syntax/semi5.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/syntax/semi6.go b/gcc/testsuite/go.test/test/syntax/semi6.go
index c1e1cc3..9bc730d 100644
--- a/gcc/testsuite/go.test/test/syntax/semi6.go
+++ b/gcc/testsuite/go.test/test/syntax/semi6.go
@@ -1,13 +1,11 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
-type T // ERROR "unexpected semicolon or newline in type declaration"
-{
-
-
+type T1 // ERROR "newline in type declaration"
+type T2 /* // ERROR "(semicolon.*|EOF) in type declaration" */ \ No newline at end of file
diff --git a/gcc/testsuite/go.test/test/syntax/semi7.go b/gcc/testsuite/go.test/test/syntax/semi7.go
index 6c9ade8..a1948b0 100644
--- a/gcc/testsuite/go.test/test/syntax/semi7.go
+++ b/gcc/testsuite/go.test/test/syntax/semi7.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -8,7 +8,7 @@ package main
func main() {
if x { } // GCCGO_ERROR "undefined"
- else { } // ERROR "unexpected semicolon or newline before .?else.?"
+ else { } // ERROR "unexpected semicolon or newline before .?else.?|unexpected else"
}
diff --git a/gcc/testsuite/go.test/test/syntax/topexpr.go b/gcc/testsuite/go.test/test/syntax/topexpr.go
index c5958f5..be080d2 100644
--- a/gcc/testsuite/go.test/test/syntax/topexpr.go
+++ b/gcc/testsuite/go.test/test/syntax/topexpr.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/syntax/typesw.go b/gcc/testsuite/go.test/test/syntax/typesw.go
index cd8cf35..3781933 100644
--- a/gcc/testsuite/go.test/test/syntax/typesw.go
+++ b/gcc/testsuite/go.test/test/syntax/typesw.go
@@ -1,13 +1,13 @@
// errorcheck
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 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 main
func main() {
- switch main() := interface{}(nil).(type) { // ERROR "invalid variable name"
+ switch main() := interface{}(nil).(type) { // ERROR "invalid variable name|cannot use .* as value"
default:
}
}
diff --git a/gcc/testsuite/go.test/test/syntax/vareq.go b/gcc/testsuite/go.test/test/syntax/vareq.go
index f08955e..0d4bb78 100644
--- a/gcc/testsuite/go.test/test/syntax/vareq.go
+++ b/gcc/testsuite/go.test/test/syntax/vareq.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/syntax/vareq1.go b/gcc/testsuite/go.test/test/syntax/vareq1.go
index e900eab..a2f9f34 100644
--- a/gcc/testsuite/go.test/test/syntax/vareq1.go
+++ b/gcc/testsuite/go.test/test/syntax/vareq1.go
@@ -1,10 +1,10 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
-var x map[string]string{"a":"b"} // ERROR "unexpected { at end of statement|expected ';' or newline after top level declaration"
+var x map[string]string{"a":"b"} // ERROR "unexpected { at end of statement|unexpected { after top level declaration|expected ';' or newline after top level declaration"
diff --git a/gcc/testsuite/go.test/test/testlib b/gcc/testsuite/go.test/test/testlib
deleted file mode 100644
index 4a17f4f..0000000
--- a/gcc/testsuite/go.test/test/testlib
+++ /dev/null
@@ -1,170 +0,0 @@
-# Copyright 2012 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.
-
-# These function names are also known to
-# (and are the plan for transitioning to) run.go.
-
-# helper (not known to run.go)
-# group file list by packages and return list of packages
-# each package is a comma-separated list of go files.
-pkgs() {
- pkglist=$(grep -h '^package ' $* | awk '{print $2}' | sort -u)
- for p in $pkglist
- do
- echo $(grep -l "^package $p\$" $*) | tr ' ' ,
- done | sort
-}
-
-_match() {
- case $1 in
- *,*)
- #echo >&2 "match comma separated $1"
- first=$(echo $1 | sed 's/,.*//')
- rest=$(echo $1 | sed 's/[^,]*,//')
- if _match $first && _match $rest; then
- return 0
- fi
- return 1
- ;;
- '!'*)
- #echo >&2 "match negation $1"
- neg=$(echo $1 | sed 's/^!//')
- if _match $neg; then
- return 1
- fi
- return 0
- ;;
- $GOARCH|$GOOS)
- #echo >&2 "match GOARCH or GOOS $1"
- return 0
- ;;
- esac
- return 1
-}
-
-# +build aborts execution if the supplied tags don't match,
-# i.e. none of the tags (x or !x) matches GOARCH or GOOS.
-+build() {
- if (( $# == 0 )); then
- return
- fi
- m=0
- for tag; do
- if _match $tag; then
- m=1
- fi
- done
- if [ $m = 0 ]; then
- #echo >&2 no match
- exit 0
- fi
- unset m
-}
-
-compile() {
- $G $D/$F.go
-}
-
-compiledir() {
- for pkg in $(pkgs $D/$F.dir/*.go)
- do
- $G -I . $(echo $pkg | tr , ' ') || return 1
- done
-}
-
-errorcheckdir() {
- lastzero=""
- if [ "$1" = "-0" ]; then
- lastzero="-0"
- fi
- pkgs=$(pkgs $D/$F.dir/*.go)
- for pkg in $pkgs.last
- do
- zero="-0"
- case $pkg in
- *.last)
- pkg=$(echo $pkg |sed 's/\.last$//')
- zero=$lastzero
- esac
- errchk $zero $G -D . -I . -e $(echo $pkg | tr , ' ')
- done
-}
-
-rundir() {
- lastfile=""
- for pkg in $(pkgs $D/$F.dir/*.go)
- do
- name=$(echo $pkg | sed 's/\.go.*//; s/.*\///')
- $G -D . -I . -e $(echo $pkg | tr , ' ') || return 1
- lastfile=$name
- done
- $L -o $A.out -L . $lastfile.$A
- ./$A.out
-}
-
-rundircmpout() {
- lastfile=""
- for pkg in $(pkgs $D/$F.dir/*.go)
- do
- name=$(echo $pkg | sed 's/\.go.*//; s/.*\///')
- $G -D . -I . -e $(echo $pkg | tr , ' ') || return 1
- lastfile=$name
- done
- $L -o $A.out -L . $lastfile.$A
- ./$A.out 2>&1 | cmp - $D/$F.out
-}
-
-build() {
- $G $D/$F.go && $L $F.$A
-}
-
-runoutput() {
- go run "$D/$F.go" "$@" > tmp.go
- go run tmp.go
-}
-
-run() {
- gofiles=""
- ingo=true
- while $ingo; do
- case "$1" in
- *.go)
- gofiles="$gofiles $1"
- shift
- ;;
- *)
- ingo=false
- ;;
- esac
- done
-
- $G $D/$F.go $gofiles && $L $F.$A && ./$A.out "$@"
-}
-
-cmpout() {
- $G $D/$F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out
-}
-
-errorcheck() {
- zero=""
- if [ "$1" = "-0" ]; then
- zero="-0"
- shift
- fi
- errchk $zero $G -e $* $D/$F.go
-}
-
-errorcheckoutput() {
- zero=""
- if [ "$1" = "-0" ]; then
- zero="-0"
- shift
- fi
- go run "$D/$F.go" "$@" > tmp.go
- errchk $zero $G -e tmp.go
-}
-
-skip() {
- true
-}
diff --git a/gcc/testsuite/go.test/test/torture.go b/gcc/testsuite/go.test/test/torture.go
index bbf6d34..197b481 100644
--- a/gcc/testsuite/go.test/test/torture.go
+++ b/gcc/testsuite/go.test/test/torture.go
@@ -337,3 +337,10 @@ func ChainDivConst(a int) int {
func ChainMulBytes(a, b, c byte) byte {
return a*(a*(a*(a*(a*(a*(a*(a*(a*b+c)+c)+c)+c)+c)+c)+c)+c) + c
}
+
+func ChainCap() {
+ select {
+ case <-make(chan int, cap(make(chan int, cap(make(chan int, cap(make(chan int, cap(make(chan int))))))))):
+ default:
+ }
+}
diff --git a/gcc/testsuite/go.test/test/typecheck.go b/gcc/testsuite/go.test/test/typecheck.go
index a2ad91f..4c55d2e 100644
--- a/gcc/testsuite/go.test/test/typecheck.go
+++ b/gcc/testsuite/go.test/test/typecheck.go
@@ -1,5 +1,9 @@
// errorcheck
+// Copyright 2012 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.
+
// Verify that the Go compiler will not
// die after running into an undefined
// type in the argument list for a
@@ -8,11 +12,11 @@
package main
-func mine(int b) int { // ERROR "undefined.*b"
- return b + 2 // ERROR "undefined.*b"
+func mine(int b) int { // ERROR "undefined.*b"
+ return b + 2 // ERROR "undefined.*b"
}
func main() {
- mine() // GCCGO_ERROR "not enough arguments"
- c = mine() // ERROR "undefined.*c|not enough arguments" "cannot assign to c"
+ mine() // GCCGO_ERROR "not enough arguments"
+ c = mine() // ERROR "undefined.*c|not enough arguments"
}
diff --git a/gcc/testsuite/go.test/test/typeswitch2.go b/gcc/testsuite/go.test/test/typeswitch2.go
index 6c70307..62c96c8 100644
--- a/gcc/testsuite/go.test/test/typeswitch2.go
+++ b/gcc/testsuite/go.test/test/typeswitch2.go
@@ -4,7 +4,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Verify that various erroneous type switches are caught be the compiler.
+// Verify that various erroneous type switches are caught by the compiler.
// Does not compile.
package main
@@ -26,22 +26,12 @@ func whatis(x interface{}) string {
w()
}:
return "rw"
- case interface { // GCCGO_ERROR "duplicate"
+ case interface { // ERROR "duplicate"
w()
r()
- }: // GC_ERROR "duplicate"
+ }:
return "wr"
}
return ""
}
-
-func notused(x interface{}) {
- // The first t is in a different scope than the 2nd t; it cannot
- // be accessed (=> declared and not used error); but it is legal
- // to declare it.
- switch t := 0; t := x.(type) { // ERROR "declared and not used"
- case int:
- _ = t // this is using the t of "t := x.(type)"
- }
-}
diff --git a/gcc/testsuite/go.test/test/typeswitch3.go b/gcc/testsuite/go.test/test/typeswitch3.go
index 287e32e..1388187 100644
--- a/gcc/testsuite/go.test/test/typeswitch3.go
+++ b/gcc/testsuite/go.test/test/typeswitch3.go
@@ -4,7 +4,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Verify that erroneous type switches are caught be the compiler.
+// Verify that erroneous type switches are caught by the compiler.
// Issue 2700, among other things.
// Does not compile.
@@ -18,26 +18,39 @@ type I interface {
M()
}
-func main(){
+func main() {
var x I
switch x.(type) {
- case string: // ERROR "impossible"
+ case string: // ERROR "impossible"
println("FAIL")
}
-
+
// Issue 2700: if the case type is an interface, nothing is impossible
-
+
var r io.Reader
-
+
_, _ = r.(io.Writer)
-
+
switch r.(type) {
case io.Writer:
}
-
+
// Issue 2827.
- switch _ := r.(type) { // ERROR "invalid variable name _|no new variables"
+ switch _ := r.(type) { // ERROR "invalid variable name _|no new variables"
}
}
+func noninterface() {
+ var i int
+ switch i.(type) { // ERROR "cannot type switch on non-interface value"
+ case string:
+ case int:
+ }
+ type S struct {
+ name string
+ }
+ var s S
+ switch s.(type) { // ERROR "cannot type switch on non-interface value"
+ }
+}
diff --git a/gcc/testsuite/go.test/test/undef.go b/gcc/testsuite/go.test/test/undef.go
index 0a77e59..61524f3 100644
--- a/gcc/testsuite/go.test/test/undef.go
+++ b/gcc/testsuite/go.test/test/undef.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/varerr.go b/gcc/testsuite/go.test/test/varerr.go
index 22aa932..82ab814 100644
--- a/gcc/testsuite/go.test/test/varerr.go
+++ b/gcc/testsuite/go.test/test/varerr.go
@@ -1,6 +1,6 @@
// errorcheck
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/gcc/testsuite/go.test/test/zerodivide.go b/gcc/testsuite/go.test/test/zerodivide.go
index 9ab2713..214d481 100644
--- a/gcc/testsuite/go.test/test/zerodivide.go
+++ b/gcc/testsuite/go.test/test/zerodivide.go
@@ -28,6 +28,8 @@ var (
i32, j32, k32 int32 = 0, 0, 1
i64, j64, k64 int64 = 0, 0, 1
+ bb = []int16{2, 0}
+
u, v, w uint = 0, 0, 1
u8, v8, w8 uint8 = 0, 0, 1
u16, v16, w16 uint16 = 0, 0, 1
@@ -124,6 +126,10 @@ var errorTests = []ErrorTest{
ErrorTest{"int32 1/0", func() { use(k32 / j32) }, "divide"},
ErrorTest{"int64 1/0", func() { use(k64 / j64) }, "divide"},
+ // From issue 5790, we should ensure that _ assignments
+ // still evaluate and generate zerodivide panics.
+ ErrorTest{"int16 _ = bb[0]/bb[1]", func() { _ = bb[0] / bb[1] }, "divide"},
+
ErrorTest{"uint 0/0", func() { use(u / v) }, "divide"},
ErrorTest{"uint8 0/0", func() { use(u8 / v8) }, "divide"},
ErrorTest{"uint16 0/0", func() { use(u16 / v16) }, "divide"},
@@ -195,9 +201,6 @@ func alike(a, b float64) bool {
func main() {
bad := false
for _, t := range errorTests {
- if t.err != "" {
- continue
- }
err := error_(t.fn)
switch {
case t.err == "" && err == "":
diff --git a/gcc/testsuite/jit.dg/jit.exp b/gcc/testsuite/jit.dg/jit.exp
index 2d8c884..9af87f9 100644
--- a/gcc/testsuite/jit.dg/jit.exp
+++ b/gcc/testsuite/jit.dg/jit.exp
@@ -37,12 +37,16 @@ load_lib target-libpath.exp
load_lib gcc.exp
load_lib g++.exp
load_lib dejagnu.exp
+load_lib target-supports-dg.exp
# Skip these tests for targets that don't support -lgccjit
if { ![check_effective_target_lgccjit] } {
return
}
+# The default do-what keyword.
+set dg-do-what-default compile
+
# Look for lines of the form:
# definitely lost: 11,316 bytes in 235 blocks
# indirectly lost: 352 bytes in 4 blocks
@@ -379,6 +383,33 @@ proc jit-dg-test { prog do_what extra_tool_flags } {
verbose " do_what: $do_what"
verbose " extra_tool_flags: $extra_tool_flags"
+ global dg-do-what-default
+ set dg-do-what [list ${dg-do-what-default} "" P]
+
+ set tmp [dg-get-options $prog]
+ foreach op $tmp {
+ verbose "Processing option: $op" 3
+ set status [catch "$op" errmsg]
+ if { $status != 0 } {
+ if { 0 && [info exists errorInfo] } {
+ # This also prints a backtrace which will just confuse
+ # testcase writers, so it's disabled.
+ perror "$name: $errorInfo\n"
+ } else {
+ perror "$name: $errmsg for \"$op\"\n"
+ }
+ perror "$name: $errmsg for \"$op\"" 0
+ return
+ }
+ }
+
+ # If we're not supposed to try this test on this target, we're done.
+ if { [lindex ${dg-do-what} 1] == "N" } {
+ unsupported "$name"
+ verbose "$name not supported on this target, skipping it" 3
+ return
+ }
+
# test-threads.c needs to be linked against pthreads
if {[string match "*test-threads.c" $prog]} {
append extra_tool_flags " -lpthread"
diff --git a/gcc/testsuite/jit.dg/test-asm.c b/gcc/testsuite/jit.dg/test-asm.c
new file mode 100644
index 0000000..e7777ee
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-asm.c
@@ -0,0 +1,492 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+/**********************************************************************
+ Support fns for creating code.
+ **********************************************************************/
+
+/* Make a "void FUNC_NAME (void)" function with a single block, returning
+ that block. */
+
+static gcc_jit_block *
+make_single_block_func (gcc_jit_context *ctxt, const char *func_name)
+{
+ gcc_jit_type *void_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
+ gcc_jit_function *func
+ = gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ void_type,
+ func_name,
+ 0, NULL, 0);
+ return gcc_jit_function_new_block (func, "initial");
+}
+
+static const char *
+get_desc (gcc_jit_extended_asm *ext_asm)
+{
+ return gcc_jit_object_get_debug_string
+ (gcc_jit_extended_asm_as_object (ext_asm));
+}
+
+/**********************************************************************
+ Support fns for verifying code.
+ **********************************************************************/
+
+typedef void (*void_void_fn) (void);
+
+static void_void_fn
+get_test_fn (gcc_jit_result *result, const char *func_name)
+{
+ return (void_void_fn)gcc_jit_result_get_code (result, func_name);
+}
+
+/**********************************************************************
+ test_i386_basic_asm_1: simple example of asm
+ **********************************************************************/
+
+/* Create the equivalent of:
+
+ int src;
+ int dst;
+
+ void test_i386_basic_asm_1 (void)
+ {
+ // Quote from here in docs/topics/asm.rst: example 1: C
+ asm ("mov %1, %0\n\t"
+ "add $1, %0"
+ : "=r" (dst)
+ : "r" (src));
+ // Quote up to here in docs/topics/asm.rst: example 1: C
+ }
+
+ i.e. copy src to dst and add 1 to dst. */
+
+static void
+create_test_i386_basic_asm_1 (gcc_jit_context *ctxt)
+{
+ gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_lvalue *dst
+ = gcc_jit_context_new_global (ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ int_type, "dst");
+ gcc_jit_lvalue *src
+ = gcc_jit_context_new_global (ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ int_type, "src");
+
+ gcc_jit_block *block
+ = make_single_block_func (ctxt, "test_i386_basic_asm_1");
+
+ /* Quote from here in docs/topics/asm.rst: example 1: jit. */
+ gcc_jit_extended_asm *ext_asm
+ = gcc_jit_block_add_extended_asm (block, NULL,
+ "mov %1, %0\n\t"
+ "add $1, %0");
+ gcc_jit_extended_asm_add_output_operand (ext_asm, NULL, "=r", dst);
+ gcc_jit_extended_asm_add_input_operand (ext_asm, NULL, "r",
+ gcc_jit_lvalue_as_rvalue (src));
+ /* Quote up to here in docs/topics/asm.rst: example 1: jit. */
+
+ const char *desc = get_desc (ext_asm);
+ CHECK_STRING_VALUE
+ (desc,
+ "asm (\"mov %1, %0\\n\\tadd $1, %0\" : \"=r\" (dst) : \"r\" (src) : )");
+
+ gcc_jit_block_end_with_void_return (block, NULL);
+}
+
+static void
+verify_code_1 (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ void_void_fn test_i386_basic_asm_1
+ = get_test_fn (result, "test_i386_basic_asm_1");
+ CHECK_NON_NULL (test_i386_basic_asm_1);
+
+ int *dst_ptr = (int *)gcc_jit_result_get_global (result, "dst");
+ CHECK_NON_NULL (dst_ptr);
+ int *src_ptr = (int *)gcc_jit_result_get_global (result, "src");
+ CHECK_NON_NULL (src_ptr);
+
+ *src_ptr = 42;
+ *dst_ptr = 0;
+ test_i386_basic_asm_1 ();
+ CHECK_VALUE (*src_ptr, 42);
+ CHECK_VALUE (*dst_ptr, 43);
+}
+
+/**********************************************************************
+ test_i386_basic_asm_2: test of symbolic names and clobbers
+ **********************************************************************/
+
+/* Create the equivalent of:
+ uint32_t test_i386_basic_asm_2 (uint32_t Mask)
+ {
+ uint32_t Index;
+ // Quote from here in docs/topics/asm.rst: example 2: C
+ asm ("bsfl %[aMask], %[aIndex]"
+ : [aIndex] "=r" (Index)
+ : [aMask] "r" (Mask)
+ : "cc");
+ // Quote up to here in docs/topics/asm.rst: example 2: C
+ return Index;
+ }
+ i.e. return the first bit set in "Mask"
+
+ This exercises symbolic names and clobbers. */
+
+static void
+create_test_i386_basic_asm_2 (gcc_jit_context *ctxt)
+{
+ gcc_jit_type *uint32_type = gcc_jit_context_get_int_type (ctxt, 4, 0);
+ gcc_jit_param *mask
+ = gcc_jit_context_new_param (ctxt, NULL,
+ uint32_type, "Mask");
+ gcc_jit_function *func
+ = gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ uint32_type,
+ "test_i386_basic_asm_2",
+ 1, &mask, 0);
+ gcc_jit_lvalue *index
+ = gcc_jit_function_new_local (func, NULL,
+ uint32_type, "Index");
+ gcc_jit_block *block = gcc_jit_function_new_block (func, "initial");
+
+ /* Quote from here in docs/topics/asm.rst: example 2: jit. */
+ gcc_jit_extended_asm *ext_asm
+ = gcc_jit_block_add_extended_asm (block, NULL,
+ "bsfl %[aMask], %[aIndex]");
+ gcc_jit_extended_asm_add_output_operand (ext_asm, "aIndex", "=r", index);
+ gcc_jit_extended_asm_add_input_operand (ext_asm, "aMask", "r",
+ gcc_jit_param_as_rvalue (mask));
+ gcc_jit_extended_asm_add_clobber (ext_asm, "cc");
+ /* Quote up to here in docs/topics/asm.rst: example 2: jit. */
+
+ const char *desc = get_desc (ext_asm);
+ CHECK_STRING_VALUE
+ (desc,
+ "asm (\"bsfl %[aMask], %[aIndex]\""
+ " : [aIndex] \"=r\" (Index) : [aMask] \"r\" (Mask) : \"cc\")");
+
+ gcc_jit_block_end_with_return (block, NULL,
+ gcc_jit_lvalue_as_rvalue (index));
+}
+
+static void
+verify_code_2 (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ typedef uint32_t (*fntype) (uint32_t);
+ fntype test_i386_basic_asm_2
+ = (fntype)gcc_jit_result_get_code (result, "test_i386_basic_asm_2");
+ CHECK_NON_NULL (test_i386_basic_asm_2);
+
+ CHECK_VALUE (test_i386_basic_asm_2 (1), 0);
+ CHECK_VALUE (test_i386_basic_asm_2 (2), 1);
+ CHECK_VALUE (test_i386_basic_asm_2 (4), 2);
+ CHECK_VALUE (test_i386_basic_asm_2 (8), 3);
+}
+
+/**********************************************************************
+ test_i386_basic_asm_3a/b: test of control flow: "asm goto"
+ **********************************************************************/
+
+/* Create the equivalent of:
+
+ int test_i386_basic_asm_3a (int p1, int p2)
+ {
+ asm goto ("btl %1, %0\n\t"
+ "jc %l2"
+ : // No outputs
+ : "r" (p1), "r" (p2)
+ : "cc"
+ : carry);
+
+ return 0;
+
+ carry:
+ return 1;
+ }
+
+ or (the "_3b" variant) using a name rather than a number for the goto
+ label:
+
+ // Quote from here in docs/topics/asm.rst: example 3b: C
+ asm goto ("btl %1, %0\n\t"
+ "jc %l[carry]"
+ : // No outputs
+ : "r" (p1), "r" (p2)
+ : "cc"
+ : carry);
+ // Quote up to here in docs/topics/asm.rst: example 3b: C
+
+ This exercises control flow with an asm. */
+
+static void
+create_test_i386_basic_asm_3 (gcc_jit_context *ctxt,
+ const char *funcname,
+ int use_name)
+{
+ gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_param *p1 = gcc_jit_context_new_param (ctxt, NULL, int_type, "p1");
+ gcc_jit_param *p2 = gcc_jit_context_new_param (ctxt, NULL, int_type, "p2");
+ gcc_jit_param *params[2] = {p1, p2};
+ gcc_jit_function *func
+ = gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ int_type,
+ funcname,
+ 2, params, 0);
+ gcc_jit_block *b_start = gcc_jit_function_new_block (func, "start");
+ gcc_jit_block *b_fallthru = gcc_jit_function_new_block (func, "fallthru");
+ gcc_jit_block *b_carry = gcc_jit_function_new_block (func, "carry");
+
+ gcc_jit_rvalue *zero
+ = gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0);
+ gcc_jit_rvalue *one
+ = gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 1);
+
+ /* Quote from here in docs/topics/asm.rst: example 3: jit. */
+ const char *asm_template =
+ (use_name
+ ? /* Label referred to by name: "%l[carry]". */
+ ("btl %1, %0\n\t"
+ "jc %l[carry]")
+ : /* Label referred to numerically: "%l2". */
+ ("btl %1, %0\n\t"
+ "jc %l2"));
+
+ gcc_jit_extended_asm *ext_asm
+ = gcc_jit_block_end_with_extended_asm_goto (b_start, NULL,
+ asm_template,
+ 1, &b_carry,
+ b_fallthru);
+ gcc_jit_extended_asm_add_input_operand (ext_asm, NULL, "r",
+ gcc_jit_param_as_rvalue (p1));
+ gcc_jit_extended_asm_add_input_operand (ext_asm, NULL, "r",
+ gcc_jit_param_as_rvalue (p2));
+ gcc_jit_extended_asm_add_clobber (ext_asm, "cc");
+ /* Quote up to here in docs/topics/asm.rst: example 3: jit. */
+
+ const char *desc = get_desc (ext_asm);
+ CHECK_STRING_VALUE
+ (desc,
+ (use_name
+ ? ("asm goto (\"btl %1, %0\\n\\tjc %l[carry]\" "
+ ": : \"r\" (p1), \"r\" (p2) : \"cc\" "
+ ": carry [fallthrough: fallthru])")
+ : ("asm goto (\"btl %1, %0\\n\\tjc %l2\" "
+ ": : \"r\" (p1), \"r\" (p2) : \"cc\" "
+ ": carry [fallthrough: fallthru])")));
+
+ gcc_jit_block_end_with_return (b_fallthru, NULL, zero);
+ gcc_jit_block_end_with_return (b_carry, NULL, one);
+}
+
+static void
+verify_code_3 (gcc_jit_context *ctxt, gcc_jit_result *result,
+ const char *funcname)
+{
+ typedef int (*test_i386_basic_asm_3_type) (int, int);
+
+ test_i386_basic_asm_3_type test_i386_basic_asm_3
+ = (test_i386_basic_asm_3_type) gcc_jit_result_get_code (result, funcname);
+ CHECK_NON_NULL (test_i386_basic_asm_3);
+
+ /* The fn should test bits, returning 0 or 1. */
+ /* Bit 0. */
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0000, 0), 0);
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0001, 0), 1);
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0002, 0), 0);
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0003, 0), 1);
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0004, 0), 0);
+ /* Bit 1. */
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0000, 1), 0);
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0001, 1), 0);
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0002, 1), 1);
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0003, 1), 1);
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0004, 1), 0);
+
+ for (int i = 0; i < 15; i++)
+ {
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0000, i), 0);
+ CHECK_VALUE (test_i386_basic_asm_3 (0xffff, i), 1);
+ }
+}
+
+/**********************************************************************
+ test_i386_basic_asm_4: test of "volatile"
+ **********************************************************************/
+
+/* Create the equivalent of:
+ uint64_t test_i386_basic_asm_4 (void)
+ {
+ uint64_t start_time, end_time;
+
+ // Get start time
+ asm volatile ("rdtsc\n\t" // Returns the time in EDX:EAX.
+ "shl $32, %%rdx\n\t" // Shift the upper bits left.
+ "or %%rdx, %0" // 'Or' in the lower bits.
+ : "=a" (start_time)
+ :
+ : "rdx");
+
+ // could do other work here
+
+ // Get end time
+ asm volatile ("rdtsc\n\t" // Returns the time in EDX:EAX.
+ "shl $32, %%rdx\n\t" // Shift the upper bits left.
+ "or %%rdx, %0" // 'Or' in the lower bits.
+ : "=a" (start_time)
+ :
+ : "rdx");
+
+ // Get elapsed time
+ return end_time - start_time;
+ }
+
+ This exercises "volatile"; without it, the optimizer can assume that
+ both asm generate the same value and thus the time difference is zero. */
+
+static void
+add_rdtsc (gcc_jit_block *block, gcc_jit_lvalue *msr)
+{
+ /* Quote from here in docs/topics/asm.rst: example 4: jit. */
+ gcc_jit_extended_asm *ext_asm
+ = gcc_jit_block_add_extended_asm
+ (block, NULL,
+ "rdtsc\n\t" /* Returns the time in EDX:EAX. */
+ "shl $32, %%rdx\n\t" /* Shift the upper bits left. */
+ "or %%rdx, %0"); /* 'Or' in the lower bits. */
+ gcc_jit_extended_asm_set_volatile_flag (ext_asm, 1);
+ gcc_jit_extended_asm_add_output_operand (ext_asm, NULL, "=a", msr);
+ gcc_jit_extended_asm_add_clobber (ext_asm, "rdx");
+ /* Quote up to here in docs/topics/asm.rst: example 4: jit. */
+
+ const char *desc = get_desc (ext_asm);
+ CHECK_STRING_STARTS_WITH (desc, "asm volatile (");
+}
+
+static void
+create_test_i386_basic_asm_4 (gcc_jit_context *ctxt)
+{
+ gcc_jit_type *uint64_type = gcc_jit_context_get_int_type (ctxt, 8, 0);
+ gcc_jit_function *func
+ = gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ uint64_type,
+ "test_i386_basic_asm_4",
+ 0, NULL, 0);
+ gcc_jit_block *block = gcc_jit_function_new_block (func, NULL);
+
+ gcc_jit_lvalue *start_time
+ = gcc_jit_function_new_local (func, NULL, uint64_type, "start_time");
+ add_rdtsc (block, start_time);
+
+ gcc_jit_block_add_comment (block, NULL, "other work here");
+
+ gcc_jit_lvalue *end_time
+ = gcc_jit_function_new_local (func, NULL, uint64_type, "end_time");
+ add_rdtsc (block, end_time);
+
+ gcc_jit_rvalue *elapsed
+ = gcc_jit_context_new_binary_op (ctxt, NULL, GCC_JIT_BINARY_OP_MINUS,
+ uint64_type,
+ gcc_jit_lvalue_as_rvalue (end_time),
+ gcc_jit_lvalue_as_rvalue (start_time));
+ gcc_jit_block_end_with_return (block, NULL, elapsed);
+}
+
+static void
+verify_code_4 (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ typedef uint64_t (*fntype) (void);
+ fntype test_i386_basic_asm_4
+ = (fntype)gcc_jit_result_get_code (result, "test_i386_basic_asm_4");
+
+ CHECK_NON_NULL (test_i386_basic_asm_4);
+
+ test_i386_basic_asm_4 ();
+}
+
+/**********************************************************************
+ test_i386_basic_asm_5: test of top-level asm
+ **********************************************************************/
+
+/* Create the equivalent of:
+
+ // Quote from here in docs/topics/asm.rst: example 5: C
+ asm ("\t.pushsection .text\n"
+ "\t.globl add_asm\n"
+ "\t.type add_asm, @function\n"
+ "add_asm:\n"
+ "\tmovq %rdi, %rax\n"
+ "\tadd %rsi, %rax\n"
+ "\tret\n"
+ "\t.popsection\n");
+ // Quote up to here in docs/topics/asm.rst: example 5: C
+
+ to add a simple function ("add_asm") directly in assembly language. */
+
+static void
+create_test_i386_basic_asm_5 (gcc_jit_context *ctxt)
+{
+ /* Quote from here in docs/topics/asm.rst: example 5: jit. */
+ gcc_jit_context_add_top_level_asm (ctxt, NULL,
+ "\t.pushsection .text\n"
+ "\t.globl add_asm\n"
+ "\t.type add_asm, @function\n"
+ "add_asm:\n"
+ "\tmovq %rdi, %rax\n"
+ "\tadd %rsi, %rax\n"
+ "\tret\n"
+ "\t# some asm here\n"
+ "\t.popsection\n");
+ /* Quote up to here in docs/topics/asm.rst: example 5: jit. */
+}
+
+static void
+verify_code_5 (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ typedef int (*test_i386_basic_asm_5_type) (int, int);
+ test_i386_basic_asm_5_type test_i386_basic_asm_5
+ = (test_i386_basic_asm_5_type) gcc_jit_result_get_code (result, "add_asm");
+ CHECK_NON_NULL (test_i386_basic_asm_5);
+
+ CHECK_VALUE (test_i386_basic_asm_5 (2, 2), 4);
+ CHECK_VALUE (test_i386_basic_asm_5 (20, 7), 27);
+}
+
+/**********************************************************************
+ Code for harness
+ **********************************************************************/
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ create_test_i386_basic_asm_1 (ctxt);
+ create_test_i386_basic_asm_2 (ctxt);
+ create_test_i386_basic_asm_3 (ctxt, "test_i386_basic_asm_3a", 0);
+ create_test_i386_basic_asm_3 (ctxt, "test_i386_basic_asm_3b", 1);
+ create_test_i386_basic_asm_4 (ctxt);
+ create_test_i386_basic_asm_5 (ctxt);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_NON_NULL (result);
+ verify_code_1 (ctxt, result);
+ verify_code_2 (ctxt, result);
+ verify_code_3 (ctxt, result, "test_i386_basic_asm_3a");
+ verify_code_3 (ctxt, result, "test_i386_basic_asm_3b");
+ verify_code_4 (ctxt, result);
+ verify_code_5 (ctxt, result);
+}
diff --git a/gcc/testsuite/jit.dg/test-asm.cc b/gcc/testsuite/jit.dg/test-asm.cc
new file mode 100644
index 0000000..6f18280
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-asm.cc
@@ -0,0 +1,453 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+
+#include "libgccjit++.h"
+
+#include "harness.h"
+
+/**********************************************************************
+ Support fns for creating code.
+ **********************************************************************/
+
+/* Make a "void FUNC_NAME (void)" function with a single block, returning
+ that block. */
+
+static gccjit::block
+make_single_block_func (gccjit::context ctxt, const char *func_name)
+{
+ gccjit::type void_type = ctxt.get_type (GCC_JIT_TYPE_VOID);
+ std::vector<gccjit::param> params;
+ gccjit::function func
+ = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
+ void_type,
+ func_name, params, 0);
+ return func.new_block ("initial");
+}
+
+/**********************************************************************
+ Support fns for verifying code.
+ **********************************************************************/
+
+typedef void (*void_void_fn) (void);
+
+static void_void_fn
+get_test_fn (gcc_jit_result *result, const char *func_name)
+{
+ return (void_void_fn)gcc_jit_result_get_code (result, func_name);
+}
+
+/**********************************************************************
+ test_i386_basic_asm_1: simple example of asm
+ **********************************************************************/
+
+/* Create the equivalent of:
+
+ int src;
+ int dst;
+
+ void test_i386_basic_asm_1 (void)
+ {
+ // Quote from here in docs/cp/topics/asm.rst: example 1: C
+ asm ("mov %1, %0\n\t"
+ "add $1, %0"
+ : "=r" (dst)
+ : "r" (src));
+ // Quote up to here in docs/cp/topics/asm.rst: example 1: C
+ }
+
+ i.e. copy src to dst and add 1 to dst. */
+
+static void
+create_test_i386_basic_asm_1 (gcc_jit_context *c_ctxt)
+{
+ gccjit::context ctxt (c_ctxt);
+ gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT);
+ gccjit::lvalue dst
+ = ctxt.new_global (GCC_JIT_GLOBAL_EXPORTED, int_type, "dst");
+ gccjit::lvalue src
+ = ctxt.new_global (GCC_JIT_GLOBAL_EXPORTED, int_type, "src");
+
+ gccjit::block block
+ = make_single_block_func (ctxt, "test_i386_basic_asm_1");
+
+ gccjit::extended_asm ext_asm =
+ /* Quote from here in docs/cp/topics/asm.rst: example 1: jit. */
+ block.add_extended_asm ("mov %1, %0\n\t"
+ "add $1, %0")
+ .add_output_operand ("=r", dst)
+ .add_input_operand ("r", src);
+ /* Quote up to here in docs/cp/topics/asm.rst: example 1: jit. */
+
+ std::string desc = ext_asm.get_debug_string ();
+ CHECK_STRING_VALUE
+ (desc.c_str (),
+ "asm (\"mov %1, %0\\n\\tadd $1, %0\" : \"=r\" (dst) : \"r\" (src) : )");
+
+ block.end_with_return ();
+}
+
+static void
+verify_code_1 (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ void_void_fn test_i386_basic_asm_1
+ = get_test_fn (result, "test_i386_basic_asm_1");
+ CHECK_NON_NULL (test_i386_basic_asm_1);
+
+ int *dst_ptr = (int *)gcc_jit_result_get_global (result, "dst");
+ CHECK_NON_NULL (dst_ptr);
+ int *src_ptr = (int *)gcc_jit_result_get_global (result, "src");
+ CHECK_NON_NULL (src_ptr);
+
+ *src_ptr = 42;
+ *dst_ptr = 0;
+ test_i386_basic_asm_1 ();
+ CHECK_VALUE (*src_ptr, 42);
+ CHECK_VALUE (*dst_ptr, 43);
+}
+
+/**********************************************************************
+ test_i386_basic_asm_2: test of symbolic names and clobbers
+ **********************************************************************/
+
+/* Create the equivalent of:
+ uint32_t test_i386_basic_asm_2 (uint32_t Mask)
+ {
+ uint32_t Index;
+ // Quote from here in docs/cp/topics/asm.rst: example 2: C
+ asm ("bsfl %[aMask], %[aIndex]"
+ : [aIndex] "=r" (Index)
+ : [aMask] "r" (Mask)
+ : "cc");
+ // Quote up to here in docs/cp/topics/asm.rst: example 2: C
+ return Index;
+ }
+ i.e. return the first bit set in "Mask"
+
+ This exercises symbolic names and clobbers. */
+
+static void
+create_test_i386_basic_asm_2 (gcc_jit_context *c_ctxt)
+{
+ gccjit::context ctxt (c_ctxt);
+ gccjit::type uint32_type = ctxt.get_int_type (4, 0);
+ gccjit::param mask = ctxt.new_param (uint32_type, "Mask");
+ std::vector<gccjit::param> params {mask};
+ gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
+ uint32_type,
+ "test_i386_basic_asm_2",
+ params, 0);
+ gccjit::lvalue index = func.new_local (uint32_type, "Index");
+ gccjit::block block = func.new_block ("initial");
+ gccjit::extended_asm ext_asm =
+ /* Quote from here in docs/cp/topics/asm.rst: example 2: jit. */
+ block.add_extended_asm ("bsfl %[aMask], %[aIndex]")
+ .add_output_operand ("aIndex", "=r", index)
+ .add_input_operand ("aMask", "r", mask)
+ .add_clobber ("cc");
+ /* Quote up to here in docs/cp/topics/asm.rst: example 2: jit. */
+
+ std::string desc = ext_asm.get_debug_string ();
+ CHECK_STRING_VALUE
+ (desc.c_str (),
+ "asm (\"bsfl %[aMask], %[aIndex]\""
+ " : [aIndex] \"=r\" (Index) : [aMask] \"r\" (Mask) : \"cc\")");
+
+ block.end_with_return (index);
+}
+
+static void
+verify_code_2 (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ typedef uint32_t (*fntype) (uint32_t);
+ fntype test_i386_basic_asm_2
+ = (fntype)gcc_jit_result_get_code (result, "test_i386_basic_asm_2");
+ CHECK_NON_NULL (test_i386_basic_asm_2);
+
+ CHECK_VALUE (test_i386_basic_asm_2 (1), 0);
+ CHECK_VALUE (test_i386_basic_asm_2 (2), 1);
+ CHECK_VALUE (test_i386_basic_asm_2 (4), 2);
+ CHECK_VALUE (test_i386_basic_asm_2 (8), 3);
+}
+
+/**********************************************************************
+ test_i386_basic_asm_3a/b: test of control flow: "asm goto"
+ **********************************************************************/
+
+/* Create the equivalent of:
+
+ int test_i386_basic_asm_3a (int p1, int p2)
+ {
+ asm goto ("btl %1, %0\n\t"
+ "jc %l2"
+ : // No outputs
+ : "r" (p1), "r" (p2)
+ : "cc"
+ : carry);
+
+ return 0;
+
+ carry:
+ return 1;
+ }
+
+ or (the "_3b" variant) using a name rather than a number for the goto
+ label:
+
+ // Quote from here in docs/cp/topics/asm.rst: example 3b: C
+ asm goto ("btl %1, %0\n\t"
+ "jc %l[carry]"
+ : // No outputs
+ : "r" (p1), "r" (p2)
+ : "cc"
+ : carry);
+ // Quote up to here in docs/cp/topics/asm.rst: example 3b: C
+
+ This exercises control flow with an asm. */
+
+static void
+create_test_i386_basic_asm_3 (gcc_jit_context *c_ctxt,
+ const char *funcname,
+ int use_name)
+{
+ gccjit::context ctxt (c_ctxt);
+ gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT);
+ gccjit::param p1 = ctxt.new_param (int_type, "p1");
+ gccjit::param p2 = ctxt.new_param (int_type, "p2");
+ std::vector<gccjit::param> params ({p1, p2});
+ gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
+ int_type,
+ funcname,
+ params, 0);
+ gccjit::block b_start = func.new_block ("start");
+ gccjit::block b_fallthru = func.new_block ("fallthru");
+ gccjit::block b_carry = func.new_block ("carry");
+
+ gccjit::rvalue zero = ctxt.new_rvalue (int_type, 0);
+ gccjit::rvalue one = ctxt.new_rvalue (int_type, 1);
+
+ /* Quote from here in docs/cp/topics/asm.rst: example 3: jit. */
+ const char *asm_template =
+ (use_name
+ ? /* Label referred to by name: "%l[carry]". */
+ ("btl %1, %0\n\t"
+ "jc %l[carry]")
+ : /* Label referred to numerically: "%l2". */
+ ("btl %1, %0\n\t"
+ "jc %l2"));
+
+ std::vector<gccjit::block> goto_blocks ({b_carry});
+ gccjit::extended_asm ext_asm
+ = (b_start.end_with_extended_asm_goto (asm_template,
+ goto_blocks,
+ &b_fallthru)
+ .add_input_operand ("r", p1)
+ .add_input_operand ("r", p2)
+ .add_clobber ("cc"));
+ /* Quote up to here in docs/cp/topics/asm.rst: example 3: jit. */
+
+ std::string desc = ext_asm.get_debug_string ();
+ CHECK_STRING_VALUE
+ (desc.c_str (),
+ (use_name
+ ? ("asm goto (\"btl %1, %0\\n\\tjc %l[carry]\" "
+ ": : \"r\" (p1), \"r\" (p2) : \"cc\" "
+ ": carry [fallthrough: fallthru])")
+ : ("asm goto (\"btl %1, %0\\n\\tjc %l2\" "
+ ": : \"r\" (p1), \"r\" (p2) : \"cc\" "
+ ": carry [fallthrough: fallthru])")));
+
+ b_fallthru.end_with_return (zero);
+ b_carry.end_with_return (one);
+}
+
+static void
+verify_code_3 (gcc_jit_context *ctxt, gcc_jit_result *result,
+ const char *funcname)
+{
+ typedef int (*test_i386_basic_asm_3_type) (int, int);
+
+ test_i386_basic_asm_3_type test_i386_basic_asm_3
+ = (test_i386_basic_asm_3_type) gcc_jit_result_get_code (result, funcname);
+ CHECK_NON_NULL (test_i386_basic_asm_3);
+
+ /* The fn should test bits, returning 0 or 1. */
+ /* Bit 0. */
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0000, 0), 0);
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0001, 0), 1);
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0002, 0), 0);
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0003, 0), 1);
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0004, 0), 0);
+ /* Bit 1. */
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0000, 1), 0);
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0001, 1), 0);
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0002, 1), 1);
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0003, 1), 1);
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0004, 1), 0);
+
+ for (int i = 0; i < 15; i++)
+ {
+ CHECK_VALUE (test_i386_basic_asm_3 (0x0000, i), 0);
+ CHECK_VALUE (test_i386_basic_asm_3 (0xffff, i), 1);
+ }
+}
+
+/**********************************************************************
+ test_i386_basic_asm_4: test of "volatile"
+ **********************************************************************/
+
+/* Create the equivalent of:
+ uint64_t test_i386_basic_asm_4 (void)
+ {
+ uint64_t start_time, end_time;
+
+ // Get start time
+ asm volatile ("rdtsc\n\t" // Returns the time in EDX:EAX.
+ "shl $32, %%rdx\n\t" // Shift the upper bits left.
+ "or %%rdx, %0" // 'Or' in the lower bits.
+ : "=a" (start_time)
+ :
+ : "rdx");
+
+ // could do other work here
+
+ // Get end time
+ asm volatile ("rdtsc\n\t" // Returns the time in EDX:EAX.
+ "shl $32, %%rdx\n\t" // Shift the upper bits left.
+ "or %%rdx, %0" // 'Or' in the lower bits.
+ : "=a" (start_time)
+ :
+ : "rdx");
+
+ // Get elapsed time
+ return end_time - start_time;
+ }
+
+ This exercises "volatile"; without it, the optimizer can assume that
+ both asm generate the same value and thus the time difference is zero. */
+
+static void
+add_rdtsc (gccjit::block block, gccjit::lvalue msr)
+{
+ /* Quote from here in docs/cp/topics/asm.rst: example 4: jit. */
+ gccjit::extended_asm ext_asm
+ = block.add_extended_asm
+ ("rdtsc\n\t" /* Returns the time in EDX:EAX. */
+ "shl $32, %%rdx\n\t" /* Shift the upper bits left. */
+ "or %%rdx, %0") /* 'Or' in the lower bits. */
+ .set_volatile_flag (true)
+ .add_output_operand ("=a", msr)
+ .add_clobber ("rdx");
+ /* Quote up to here in docs/cp/topics/asm.rst: example 4: jit. */
+
+ std::string desc = ext_asm.get_debug_string ();
+ CHECK_STRING_STARTS_WITH (desc.c_str (), "asm volatile (");
+}
+
+static void
+create_test_i386_basic_asm_4 (gcc_jit_context *c_ctxt)
+{
+ gccjit::context ctxt (c_ctxt);
+ gccjit::type uint64_type = ctxt.get_int_type (8, 0);
+ std::vector<gccjit::param> params;
+ gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
+ uint64_type,
+ "test_i386_basic_asm_4",
+ params, 0);
+ gccjit::block block = func.new_block ();
+
+ gccjit::lvalue start_time = func.new_local (uint64_type, "start_time");
+ add_rdtsc (block, start_time);
+
+ block.add_comment ("other work here");
+
+ gccjit::lvalue end_time = func.new_local (uint64_type, "end_time");
+ add_rdtsc (block, end_time);
+
+ block.end_with_return (end_time - start_time);
+}
+
+static void
+verify_code_4 (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ typedef uint64_t (*fntype) (void);
+ fntype test_i386_basic_asm_4
+ = (fntype)gcc_jit_result_get_code (result, "test_i386_basic_asm_4");
+
+ CHECK_NON_NULL (test_i386_basic_asm_4);
+
+ test_i386_basic_asm_4 ();
+}
+
+/**********************************************************************
+ test_i386_basic_asm_5: test of top-level asm
+ **********************************************************************/
+
+/* Create the equivalent of:
+
+ // Quote from here in docs/cp/topics/asm.rst: example 5: C
+ asm ("\t.pushsection .text\n"
+ "\t.globl add_asm\n"
+ "\t.type add_asm, @function\n"
+ "add_asm:\n"
+ "\tmovq %rdi, %rax\n"
+ "\tadd %rsi, %rax\n"
+ "\tret\n"
+ "\t.popsection\n");
+ // Quote up to here in docs/cp/topics/asm.rst: example 5: C
+
+ to add a simple function ("add_asm") directly in assembly language. */
+
+static void
+create_test_i386_basic_asm_5 (gcc_jit_context *c_ctxt)
+{
+ gccjit::context ctxt (c_ctxt);
+ /* Quote from here in docs/cp/topics/asm.rst: example 5: jit. */
+ ctxt.add_top_level_asm ("\t.pushsection .text\n"
+ "\t.globl add_asm\n"
+ "\t.type add_asm, @function\n"
+ "add_asm:\n"
+ "\tmovq %rdi, %rax\n"
+ "\tadd %rsi, %rax\n"
+ "\tret\n"
+ "\t# some asm here\n"
+ "\t.popsection\n");
+ /* Quote up to here in docs/cp/topics/asm.rst: example 5: jit. */
+}
+
+static void
+verify_code_5 (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ typedef int (*test_i386_basic_asm_5_type) (int, int);
+ test_i386_basic_asm_5_type test_i386_basic_asm_5
+ = (test_i386_basic_asm_5_type) gcc_jit_result_get_code (result, "add_asm");
+ CHECK_NON_NULL (test_i386_basic_asm_5);
+
+ CHECK_VALUE (test_i386_basic_asm_5 (2, 2), 4);
+ CHECK_VALUE (test_i386_basic_asm_5 (20, 7), 27);
+}
+
+/**********************************************************************
+ Code for harness
+ **********************************************************************/
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ create_test_i386_basic_asm_1 (ctxt);
+ create_test_i386_basic_asm_2 (ctxt);
+ create_test_i386_basic_asm_3 (ctxt, "test_i386_basic_asm_3a", 0);
+ create_test_i386_basic_asm_3 (ctxt, "test_i386_basic_asm_3b", 1);
+ create_test_i386_basic_asm_4 (ctxt);
+ create_test_i386_basic_asm_5 (ctxt);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_NON_NULL (result);
+ verify_code_1 (ctxt, result);
+ verify_code_2 (ctxt, result);
+ verify_code_3 (ctxt, result, "test_i386_basic_asm_3a");
+ verify_code_3 (ctxt, result, "test_i386_basic_asm_3b");
+ verify_code_4 (ctxt, result);
+ verify_code_5 (ctxt, result);
+}
diff --git a/gcc/testsuite/jit.dg/test-debug-strings.c b/gcc/testsuite/jit.dg/test-debug-strings.c
index e515a17..03ef337 100644
--- a/gcc/testsuite/jit.dg/test-debug-strings.c
+++ b/gcc/testsuite/jit.dg/test-debug-strings.c
@@ -178,6 +178,26 @@ create_code (gcc_jit_context *ctxt, void *user_data)
"((struct node *)ptr->next)->next");
}
+ /* Check string literal escaping. */
+ {
+ CHECK_RVALUE_DEBUG_STRING
+ (gcc_jit_context_new_string_literal (ctxt, ""),
+ "\"\"");
+ CHECK_RVALUE_DEBUG_STRING
+ (gcc_jit_context_new_string_literal (ctxt, "foo"),
+ "\"foo\"");
+ CHECK_RVALUE_DEBUG_STRING
+ (gcc_jit_context_new_string_literal (ctxt, "\""),
+ "\"\\\"\"");
+ CHECK_RVALUE_DEBUG_STRING
+ (gcc_jit_context_new_string_literal (ctxt, "line 1\nline 2\n"),
+ "\"line 1\\nline 2\\n\"");
+ CHECK_RVALUE_DEBUG_STRING
+ (gcc_jit_context_new_string_literal (ctxt, "foo\tbar"),
+ "\"foo\\tbar\"");
+ }
+
+#undef CHECK_RVALUE_DEBUG_STRING
#undef CHECK_LVALUE_DEBUG_STRING
}
diff --git a/gcc/testsuite/lib/asan-dg.exp b/gcc/testsuite/lib/asan-dg.exp
index ce745df..8f96751 100644
--- a/gcc/testsuite/lib/asan-dg.exp
+++ b/gcc/testsuite/lib/asan-dg.exp
@@ -16,6 +16,9 @@
# Return 1 if compilation with -fsanitize=address is error-free for trivial
# code, 0 otherwise.
+#
+# NOTE: This should only be used between calls to asan_init and asan_finish.
+# It is therefore defined here rather than in target-supports.exp.
proc check_effective_target_fsanitize_address {} {
if ![check_no_compiler_messages fsanitize_address executable {
@@ -58,33 +61,33 @@ proc asan_include_flags {} {
# (originally from g++.exp)
#
-proc asan_link_flags { paths } {
+proc asan_link_flags_1 { paths lib } {
global srcdir
global ld_library_path
global shlib_ext
- global asan_saved_library_path
+ global ${lib}_saved_library_path
set gccpath ${paths}
set flags ""
set shlib_ext [get_shlib_extension]
- set asan_saved_library_path $ld_library_path
+ set ${lib}_saved_library_path $ld_library_path
if { $gccpath != "" } {
- if { [file exists "${gccpath}/libsanitizer/asan/.libs/libasan.a"]
- || [file exists "${gccpath}/libsanitizer/asan/.libs/libasan.${shlib_ext}"] } {
+ if { [file exists "${gccpath}/libsanitizer/${lib}/.libs/lib${lib}.a"]
+ || [file exists "${gccpath}/libsanitizer/${lib}/.libs/lib${lib}.${shlib_ext}"] } {
append flags " -B${gccpath}/libsanitizer/ "
- append flags " -B${gccpath}/libsanitizer/asan/ "
- append flags " -L${gccpath}/libsanitizer/asan/.libs "
- append ld_library_path ":${gccpath}/libsanitizer/asan/.libs"
+ append flags " -B${gccpath}/libsanitizer/${lib}/ "
+ append flags " -L${gccpath}/libsanitizer/${lib}/.libs "
+ append ld_library_path ":${gccpath}/libsanitizer/${lib}/.libs"
}
} else {
global tool_root_dir
- set libasan [lookfor_file ${tool_root_dir} libasan]
- if { $libasan != "" } {
- append flags "-L${libasan} "
- append ld_library_path ":${libasan}"
+ set libdir [lookfor_file ${tool_root_dir} lib${lib}]
+ if { $libdir != "" } {
+ append flags "-L${libdir} "
+ append ld_library_path ":${libdir}"
}
}
@@ -93,6 +96,10 @@ proc asan_link_flags { paths } {
return "$flags"
}
+proc asan_link_flags { paths } {
+ return [asan_link_flags_1 $paths asan]
+}
+
#
# asan_init -- called at the start of each subdir of tests
#
diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp
index e8ad305..700529a 100644
--- a/gcc/testsuite/lib/gcc-dg.exp
+++ b/gcc/testsuite/lib/gcc-dg.exp
@@ -1232,7 +1232,7 @@ proc dg-optimized { args } {
# Make this variable available here and to the saved proc.
upvar dg-messages dg-messages
- process-message saved-dg-error "optimized: " "$args"
+ process-message saved-dg-warning "optimized:" "$args"
}
# Handle output from -fopt-info for MSG_MISSED_OPTIMIZATION:
@@ -1242,7 +1242,7 @@ proc dg-missed { args } {
# Make this variable available here and to the saved proc.
upvar dg-messages dg-messages
- process-message saved-dg-error "missed: " "$args"
+ process-message saved-dg-warning "missed:" "$args"
}
# Check the existence of a gdb in the path, and return true if there
diff --git a/gcc/testsuite/lib/hwasan-dg.exp b/gcc/testsuite/lib/hwasan-dg.exp
new file mode 100644
index 0000000..bd2a011
--- /dev/null
+++ b/gcc/testsuite/lib/hwasan-dg.exp
@@ -0,0 +1,167 @@
+# Copyright (C) 2020 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 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 GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+load_lib asan-dg.exp
+
+# Return 1 if target can compile a binary for hardware address
+# sanitization, 0 otherwise.
+#
+# NOTE: This should only be used between calls to hwasan_init and
+# hwasan_finish. It is therefore defined here rather than in
+# target-supports.exp.
+
+proc check_effective_target_fsanitize_hwaddress {} {
+ if ![check_no_compiler_messages fsanitize_hwaddress executable {
+ int main (void) { return 0; }
+ }] {
+ return 0;
+ }
+ return 1;
+}
+
+# Return 1 if target can compile and run a binary for hardware address
+# sanitization, 0 otherwise.
+#
+# NOTE: This should only be used between calls to hwasan_init and
+# hwasan_finish. It is therefore defined here rather than in
+# target-supports.exp.
+
+proc check_effective_target_hwaddress_exec {} {
+ if ![check_runtime hwaddress_exec {
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+ extern int prctl(int, unsigned long, unsigned long, unsigned long, unsigned long);
+ #ifdef __cplusplus
+ }
+ #endif
+ int main (void) {
+ #define PR_SET_TAGGED_ADDR_CTRL 55
+ #define PR_GET_TAGGED_ADDR_CTRL 56
+ #define PR_TAGGED_ADDR_ENABLE (1UL << 0)
+ if (prctl (PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0) == -1)
+ return 1;
+ if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == -1
+ || !prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0))
+ return 1;
+ return 0;
+ }
+ }] {
+ return 0;
+ }
+ return 1;
+}
+
+proc hwasan_include_flags {} {
+ global srcdir
+ global TESTING_IN_BUILD_TREE
+
+ set flags ""
+
+ if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } {
+ return "${flags}"
+ }
+
+ set flags "-I$srcdir/../../libsanitizer/include"
+
+ return "$flags"
+}
+
+#
+# hwasan_link_flags -- compute library path and flags to find libhwasan.
+# (implementation in asan-dg.exp)
+#
+
+proc hwasan_link_flags { paths } {
+ return [asan_link_flags_1 $paths hwasan]
+}
+
+#
+# hwasan_init -- called at the start of each subdir of tests
+#
+
+proc hwasan_init { args } {
+ global TEST_ALWAYS_FLAGS
+ global ALWAYS_CXXFLAGS
+ global TOOL_OPTIONS
+ global hwasan_saved_TEST_ALWAYS_FLAGS
+ global hwasan_saved_ALWAYS_CXXFLAGS
+
+ setenv HWASAN_OPTIONS "random_tags=0"
+
+ set link_flags ""
+ if ![is_remote host] {
+ if [info exists TOOL_OPTIONS] {
+ set link_flags "[hwasan_link_flags [get_multilibs ${TOOL_OPTIONS}]]"
+ } else {
+ set link_flags "[hwasan_link_flags [get_multilibs]]"
+ }
+ }
+
+ set include_flags "[hwasan_include_flags]"
+
+ if [info exists TEST_ALWAYS_FLAGS] {
+ set hwasan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS
+ }
+ if [info exists ALWAYS_CXXFLAGS] {
+ set hwasan_saved_ALWAYS_CXXFLAGS $ALWAYS_CXXFLAGS
+ set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS]
+ set ALWAYS_CXXFLAGS [concat "{additional_flags=-fsanitize=hwaddress --param hwasan-random-frame-tag=0 -g $include_flags}" $ALWAYS_CXXFLAGS]
+ } else {
+ if [info exists TEST_ALWAYS_FLAGS] {
+ set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=hwaddress --param hwasan-random-frame-tag=0 -g $include_flags $TEST_ALWAYS_FLAGS"
+ } else {
+ set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=hwaddress --param hwasan-random-frame-tag=0 -g $include_flags"
+ }
+ }
+}
+
+#
+# hwasan_finish -- called at the start of each subdir of tests
+#
+
+proc hwasan_finish { args } {
+ global TEST_ALWAYS_FLAGS
+ global hwasan_saved_TEST_ALWAYS_FLAGS
+ global hwasan_saved_ALWAYS_CXXFLAGS
+ global hwasan_saved_library_path
+ global ld_library_path
+
+ unsetenv HWASAN_OPTIONS
+
+ if [info exists hwasan_saved_ALWAYS_CXXFLAGS ] {
+ set ALWAYS_CXXFLAGS $hwasan_saved_ALWAYS_CXXFLAGS
+ } else {
+ if [info exists hwasan_saved_TEST_ALWAYS_FLAGS] {
+ set TEST_ALWAYS_FLAGS $hwasan_saved_TEST_ALWAYS_FLAGS
+ } else {
+ unset TEST_ALWAYS_FLAGS
+ }
+ }
+ if [info exists hwasan_saved_library_path] {
+ set ld_library_path $hwasan_saved_library_path
+ set_ld_library_path_env_vars
+ }
+ clear_effective_target_cache
+}
+
+# Utility for running gtest hwasan emulation under dejagnu, invoked via dg-final.
+# Call pass if variable has the desired value, otherwise fail.
+#
+# Argument 0 handles expected failures and the like
+proc hwasan-gtest { args } {
+ asan-gtest {*}$args
+}
diff --git a/gcc/testsuite/lib/options.exp b/gcc/testsuite/lib/options.exp
index c7f7316..7700144 100644
--- a/gcc/testsuite/lib/options.exp
+++ b/gcc/testsuite/lib/options.exp
@@ -59,6 +59,11 @@ proc check_for_options_with_filter { language gcc_options exclude \
set gcc_output [gcc_target_compile $srcfname $filebase.x executable $gcc_options]
remote_file build delete $srcfname $filebase.x $filebase.gcno
+ if {[regexp -- "compiler not installed on this system" $gcc_output]} {
+ unsupported "$test: $language compiler not available"
+ return
+ }
+
if { $exclude != "" } {
set lines [split $gcc_output "\n"]
set gcc_output ""
diff --git a/gcc/testsuite/lib/profopt.exp b/gcc/testsuite/lib/profopt.exp
index d686343..98e1a0e 100644
--- a/gcc/testsuite/lib/profopt.exp
+++ b/gcc/testsuite/lib/profopt.exp
@@ -456,6 +456,7 @@ proc profopt-execute { src } {
set id [remote_spawn "" $cmd]
if { $id < 0 } {
unsupported "$testcase -fauto-profile: cannot run create_gcov"
+ unset testname_with_flags
set status "fail"
return
}
diff --git a/gcc/testsuite/lib/prune.exp b/gcc/testsuite/lib/prune.exp
index 190367c..06904f9 100644
--- a/gcc/testsuite/lib/prune.exp
+++ b/gcc/testsuite/lib/prune.exp
@@ -48,7 +48,11 @@ proc prune_gcc_output { text } {
regsub -all "(^|\n)\[^\n\]*: re(compiling|linking)\[^\n\]*" $text "" text
regsub -all "(^|\n)Please submit.*instructions\[^\n\]*" $text "" text
regsub -all "(^|\n)\[0-9\]\[0-9\]* errors\." $text "" text
- regsub -all "(^|\n)(In file included|\[ \]+from)\[^\n\]*" $text "" text
+
+ # Diagnostic inclusion stack
+ regsub -all "(^|\n)(In file)?\[ \]+included from \[^\n\]*" $text "" text
+ regsub -all "(^|\n)\[ \]+from \[^\n\]*" $text "" text
+ regsub -all "(^|\n)(In|of) module( \[^\n \]*,)? imported at \[^\n\]*" $text "" text
# Ignore informational notes.
regsub -all "(^|\n)\[^\n\]*: note: \[^\n\]*" $text "" text
@@ -128,8 +132,8 @@ proc prune_file_path { text } {
# footnote.
proc prune_ices { text } {
- regsub -all "(^|\n)\[^\n\]*: internal compiler error:.*for instructions\[^\n\]*" $text "" text
- regsub -all "(^|\n|')*Internal compiler error:.*for instructions\[^\n\]*" $text "" text
+ regsub -all "(^|\n)\[^\n\]*: internal compiler error:.*\nSee \[^\n\]*" $text "" text
+ regsub -all "(^|\n|')*Internal compiler error:.*\nSee \[^\n\]*" $text "" text
return $text
}
diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp
index d5f2be4..43b7649 100644
--- a/gcc/testsuite/lib/scanasm.exp
+++ b/gcc/testsuite/lib/scanasm.exp
@@ -52,10 +52,7 @@ proc dg-scan { name positive testcase output_file orig_args } {
set pattern [lindex $orig_args 0]
set printable_pattern [make_pattern_printable $pattern]
- if { [is_remote host] } {
- remote_upload host "$output_file"
- }
- set files [glob -nocomplain $output_file]
+ set files [dg_glob_remote $output_file]
if { $files == "" } {
verbose -log "$testcase: output file does not exist"
unresolved "$testcase $name $printable_pattern"
@@ -73,6 +70,13 @@ proc dg-scan { name positive testcase output_file orig_args } {
}
}
+proc dg_glob_remote { file_pattern } {
+ if { [is_remote host] } {
+ remote_upload host $file_pattern
+ }
+ return [glob -nocomplain $file_pattern]
+}
+
# Look for a pattern in the .s file produced by the compiler. See
# dg-scan for details.
@@ -155,6 +159,178 @@ proc scan-not-hidden { args } {
dg-scan "scan-not-hidden" 0 $testcase $output_file $args
}
+# Check that symbols are emitted in the desired section.
+# Like scan-symbol-section, but using the assembly output generated by
+# the compiler.
+#
+# Example:
+#
+# // All numbered functions (func1, func2, etc.) must be in the .text section or
+# // in a .text sub-section (like .text._func1).
+# { dg-final { scan-assembler-symbol-section {^_func[1-5]$} {^\.text($|\.)} } }
+
+proc scan-assembler-symbol-section { args } {
+ set testcase [testname-for-summary]
+ set filename [lindex $testcase 0]
+ set output_file "[file rootname [file tail $filename]].s"
+ set symbol_pattern [lindex $args 0]
+ set expected_section_pattern [lindex $args 1]
+ dg-scan-symbol-section \
+ "scan-assembler-symbol-section" \
+ $testcase \
+ $output_file \
+ $symbol_pattern \
+ $expected_section_pattern
+}
+
+# Check that symbols are emitted in the desired section.
+#
+# Symbols and sections are interpreted as regexp patterns.
+#
+# If no matching symbol is found, scan-symbol-section reports a FAILure.
+#
+# Usage:
+#
+# { dg-final { scan-symbol-section FILENAME SYMBOL SECTION } }
+#
+# Examples:
+#
+# // The my_var C symbol must be in the .data section (or in a .data._my_var section
+# // if -ffunction-sections is in use).
+# { dg-final { scan-symbol-section "my-test.s" {^_my_var$} {^\.data(\._my_var)?$} } }
+#
+# // All numbered functions (func1, func2, etc.) must be in the .text section
+# // (and not in any other section like .text._func1).
+# { dg-final { scan-symbol-section "my-test.s" {^_func[1-5]$} {^\.text$} } }
+#
+# Caveats:
+#
+# * Only ELF and Mach-O targets are supported. Other
+# targets, like PE/COFF, might appear to work.
+# * For Mach-O targets, the section name matched by scan-symbol-section has one
+# of two forms:
+# * The Mach-O segment name followed by a comma (',') followed by the Mach-O
+# section name. For example, "__TEXT,__text". (There is no whitespace
+# between the Mach-O segment name and the Mach-O section name.)
+# * ".const", ".data", or ".text". For example, the .text assembler directive
+# causes the section name to be ".text" (not "__TEXT,__text"). (However, a
+# directive such as .section __TEXT,__text will cause the section name to be
+# "__TEXT,__text".)
+# * Because scan-symbol-section parses assembly code, scan-symbol-section is
+# unaware of section rewriting performed by the linker. For example, the
+# sections .text._f1 and .text._f2 would normally be merged by binutils'
+# linker into one section called .text, but scan-symbol-section reports the
+# sections as .text._f1 and .text._f2 (and not .text).
+# * The symbol pattern matches any assembly label, including local labels which
+# begin with `.L`.
+
+proc scan-symbol-section { args } {
+ set testcase [testname-for-summary]
+ set output_file [lindex $args 0]
+ set symbol_pattern [lindex $args 1]
+ set expected_section_pattern [lindex $args 2]
+ dg-scan-symbol-section \
+ "scan-symbol-section" \
+ $testcase \
+ $output_file \
+ $symbol_pattern \
+ $expected_section_pattern
+}
+
+# Check that symbols are emitted in the desired section.
+#
+# Avoid calling this function directly. In tests, use scan-symbol-section,
+# scan-assembler-symbol-section, or scan-lto-assembler-symbol-section instead.
+
+proc dg-scan-symbol-section { name testcase output_file symbol_pattern expected_section_pattern } {
+ set printable_symbol_pattern [make_pattern_printable $symbol_pattern]
+ set printable_expected_section_pattern [make_pattern_printable $expected_section_pattern]
+
+ set files [dg_glob_remote $output_file]
+ if { $files == "" } {
+ verbose -log "$testcase: output file does not exist"
+ unresolved "$testcase $name symbol $printable_symbol_pattern has section $printable_expected_section_pattern"
+ return
+ }
+
+ parse_section_of_symbols $output_file section_by_symbol
+
+ set found_symbol 0
+ foreach symbol_name [lsort [array names section_by_symbol]] {
+ if { [regexp -- $symbol_pattern $symbol_name] } {
+ set section $section_by_symbol($symbol_name)
+ set description "$testcase $name symbol $printable_symbol_pattern (found $symbol_name) has section $printable_expected_section_pattern"
+ if { $section == "" } {
+ fail "$description (no section detected)"
+ } else {
+ set description "$description (found $section)"
+ if { [regexp -- $expected_section_pattern $section] } {
+ pass $description
+ } else {
+ fail $description
+ }
+ }
+ set found_symbol 1
+ }
+ }
+ if { ! $found_symbol } {
+ fail "$testcase $name symbol $printable_symbol_pattern (symbol not found) has section $printable_expected_section_pattern"
+ }
+}
+
+# Extract a symbol and section names from pre-processed assembly source code.
+#
+# This function adds entries in the RESULT array where the key is the symbol's
+# name (including any leading underscores) and the value is the section's name
+# (including any leading periods).
+#
+# For example, given the following assembly source code in file.s:
+#
+# .text
+# .function _my_function
+# _my_function:
+# nop
+# .data
+# _my_data:
+# .long 42
+#
+# Executing 'parse_section_of_symbols "file.s" symbols' would have the same
+# effect as the following code:
+#
+# set $result(_my_function) .text
+# set $result(_my_data) .data
+
+proc parse_section_of_symbols { filename result } {
+ upvar $result up_result
+
+ set section_pattern {^\s*(?:(\.section|\.csect)\s+(.*)|(\.const|\.data|\.text)\s*)$}
+ set label_pattern {^(\S+):$}
+
+ set fd [open $filename r]
+ set current_section ""
+ while { [gets $fd line] >= 0 } {
+ if { [regexp -- $label_pattern $line dummy symbol_name] } {
+ set up_result($symbol_name) $current_section
+ } elseif { [regexp -- $section_pattern $line dummy section_directive_arguments full_section_directive] } {
+ if { $full_section_directive eq "" } {
+ # Example: .section .text,"ax",progbits
+ # Example: .section __TEXT,__text
+ set arguments [split $section_directive_arguments ","]
+ set current_section [string trim [lindex $arguments 0]]
+ set arg_1 [string trim [lindex $arguments 1]]
+ if { [regexp {^_} $arg_1] } {
+ # The second argument looks like a Mach-O section name.
+ set current_section "$current_section,$arg_1"
+ }
+ } else {
+ # Example: .text
+ set current_section "$full_section_directive"
+ }
+ }
+ }
+ close $fd
+}
+
# Look for a pattern in OUTPUT_FILE. See dg-scan for details.
proc scan-file { output_file args } {
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 60ebbb3..89c4f67 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -368,7 +368,7 @@ proc check_weak_override_available { } {
return [check_weak_available]
}
-# The noinit attribute is only supported by some targets.
+# 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 { } {
@@ -380,6 +380,18 @@ proc check_effective_target_noinit { } {
return 0
}
+# The "persistent" attribute is only supported by some targets.
+# This proc returns 1 if it's supported, 0 if it's not.
+
+proc check_effective_target_persistent { } {
+ if { [istarget arm*-*-eabi]
+ || [istarget msp430-*-*] } {
+ return 1
+ }
+
+ return 0
+}
+
###############################
# proc check_visibility_available { what_kind }
###############################
@@ -8461,6 +8473,18 @@ proc check_effective_target_avx2 { } {
} "-O0 -mavx2" ]
}
+# Return 1 if avxvnni instructions can be compiled.
+proc check_effective_target_avxvnni { } {
+ return [check_no_compiler_messages avxvnni object {
+ typedef int __v8si __attribute__ ((__vector_size__ (32)));
+ __v8si
+ _mm256_dpbusd_epi32 (__v8si __A, __v8si __B, __v8si __C)
+ {
+ return __builtin_ia32_vpdpbusd_v8si (__A, __B, __C);
+ }
+ } "-mavxvnni" ]
+}
+
# Return 1 if sse instructions can be compiled.
proc check_effective_target_sse { } {
return [check_no_compiler_messages sse object {
@@ -10339,6 +10363,13 @@ proc check_effective_target_inf { } {
}]
}
+# Return 1 if target supports floating point "infinite" for float.
+proc check_effective_target_inff { } {
+ return [check_no_compiler_messages supports_inff assembly {
+ const float pinf = __builtin_inff ();
+ }]
+}
+
# Return 1 if the target supports ARMv8.3 Adv.SIMD Complex instructions
# instructions, 0 otherwise. The test is valid for ARM and for AArch64.
# Record the command line options needed.
@@ -10631,3 +10662,83 @@ proc check_effective_target_no_fsanitize_address {} {
}
return 0;
}
+
+# Return 1 if this target supports 'R' flag in .section directive, 0
+# otherwise. Cache the result.
+
+proc check_effective_target_R_flag_in_section { } {
+ global tool
+ global GCC_UNDER_TEST
+
+ # Need auto-host.h to check linker support.
+ if { ![file exists ../../auto-host.h ] } {
+ return 0
+ }
+
+ return [check_cached_effective_target R_flag_in_section {
+
+ set src pie[pid].c
+ set obj pie[pid].o
+
+ set f [open $src "w"]
+ puts $f "#include \"../../auto-host.h\""
+ puts $f "#if HAVE_GAS_SHF_GNU_RETAIN == 0"
+ puts $f "# error Assembler does not support 'R' flag in .section directive."
+ puts $f "#endif"
+ close $f
+
+ verbose "check_effective_target_R_flag_in_section compiling testfile $src" 2
+ set lines [${tool}_target_compile $src $obj assembly ""]
+
+ file delete $src
+ file delete $obj
+
+ if [string match "" $lines] then {
+ verbose "check_effective_target_R_flag_in_section testfile compilation passed" 2
+ return 1
+ } else {
+ verbose "check_effective_target_R_flag_in_section testfile compilation failed" 2
+ return 0
+ }
+ }]
+}
+
+# Return 1 if this target supports 'o' flag in .section directive, 0
+# otherwise. Cache the result.
+
+proc check_effective_target_o_flag_in_section { } {
+ global tool
+ global GCC_UNDER_TEST
+
+ # Need auto-host.h to check linker support.
+ if { ![file exists ../../auto-host.h ] } {
+ return 0
+ }
+
+ return [check_cached_effective_target o_flag_in_section {
+
+ set src pie[pid].c
+ set obj pie[pid].o
+
+ set f [open $src "w"]
+ puts $f "#include \"../../auto-host.h\""
+ puts $f "#if HAVE_GAS_SECTION_LINK_ORDER == 0"
+ puts $f "# error Assembler does not support 'o' flag in .section directive."
+ puts $f "#endif"
+ close $f
+
+ verbose "check_effective_target_o_flag_in_section compiling testfile $src" 2
+ set lines [${tool}_target_compile $src $obj object ""]
+
+ file delete $src
+ file delete $obj
+
+ if [string match "" $lines] then {
+ verbose "check_effective_target_o_flag_in_section testfile compilation passed" 2
+ return 1
+ } else {
+ verbose "check_effective_target_o_flag_in_section testfile compilation failed" 2
+ return 0
+ }
+ }]
+}
diff --git a/gcc/testsuite/obj-c++.dg/attributes/class-attribute-1.mm b/gcc/testsuite/obj-c++.dg/attributes/class-attribute-1.mm
index f078339..7eafdbc 100644
--- a/gcc/testsuite/obj-c++.dg/attributes/class-attribute-1.mm
+++ b/gcc/testsuite/obj-c++.dg/attributes/class-attribute-1.mm
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* Test deprecate attribute with an @interface declaration. */
diff --git a/gcc/testsuite/obj-c++.dg/attributes/class-attribute-2.mm b/gcc/testsuite/obj-c++.dg/attributes/class-attribute-2.mm
index 35015c0..629ba86 100644
--- a/gcc/testsuite/obj-c++.dg/attributes/class-attribute-2.mm
+++ b/gcc/testsuite/obj-c++.dg/attributes/class-attribute-2.mm
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/attributes/class-attribute-3.mm b/gcc/testsuite/obj-c++.dg/attributes/class-attribute-3.mm
index f96500d..3b7c8c3 100644
--- a/gcc/testsuite/obj-c++.dg/attributes/class-attribute-3.mm
+++ b/gcc/testsuite/obj-c++.dg/attributes/class-attribute-3.mm
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* Test that you get a warning when an unknown class attribute is ignored. */
diff --git a/gcc/testsuite/obj-c++.dg/attributes/method-deprecated-1.mm b/gcc/testsuite/obj-c++.dg/attributes/method-deprecated-1.mm
index 8343856..68e8373 100644
--- a/gcc/testsuite/obj-c++.dg/attributes/method-deprecated-1.mm
+++ b/gcc/testsuite/obj-c++.dg/attributes/method-deprecated-1.mm
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/attributes/method-deprecated-2.mm b/gcc/testsuite/obj-c++.dg/attributes/method-deprecated-2.mm
index 1e5d87f..8fb0e15 100644
--- a/gcc/testsuite/obj-c++.dg/attributes/method-deprecated-2.mm
+++ b/gcc/testsuite/obj-c++.dg/attributes/method-deprecated-2.mm
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/attributes/method-deprecated-3.mm b/gcc/testsuite/obj-c++.dg/attributes/method-deprecated-3.mm
index 5c715a2..efa2d34 100644
--- a/gcc/testsuite/obj-c++.dg/attributes/method-deprecated-3.mm
+++ b/gcc/testsuite/obj-c++.dg/attributes/method-deprecated-3.mm
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/attributes/method-format-1.mm b/gcc/testsuite/obj-c++.dg/attributes/method-format-1.mm
index 9ff34f9..d3bb997 100644
--- a/gcc/testsuite/obj-c++.dg/attributes/method-format-1.mm
+++ b/gcc/testsuite/obj-c++.dg/attributes/method-format-1.mm
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
/* { dg-do compile } */
/* { dg-options "-Wall" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/obj-c++.dg/attributes/method-nonnull-1.mm b/gcc/testsuite/obj-c++.dg/attributes/method-nonnull-1.mm
index 83f918c..af48787 100644
--- a/gcc/testsuite/obj-c++.dg/attributes/method-nonnull-1.mm
+++ b/gcc/testsuite/obj-c++.dg/attributes/method-nonnull-1.mm
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, May 2011. */
/* { dg-do compile } */
/* { dg-options "-Wall" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/obj-c++.dg/attributes/method-noreturn-1.mm b/gcc/testsuite/obj-c++.dg/attributes/method-noreturn-1.mm
index a83048b..413a0be 100644
--- a/gcc/testsuite/obj-c++.dg/attributes/method-noreturn-1.mm
+++ b/gcc/testsuite/obj-c++.dg/attributes/method-noreturn-1.mm
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/obj-c++.dg/attributes/method-sentinel-1.mm b/gcc/testsuite/obj-c++.dg/attributes/method-sentinel-1.mm
index 2b8e6fd..ece7a9f 100644
--- a/gcc/testsuite/obj-c++.dg/attributes/method-sentinel-1.mm
+++ b/gcc/testsuite/obj-c++.dg/attributes/method-sentinel-1.mm
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
/* { dg-do compile } */
/* { dg-options "-Wall" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/obj-c++.dg/attributes/nsobject-01.mm b/gcc/testsuite/obj-c++.dg/attributes/nsobject-01.mm
index 498fbc7..3af785b 100644
--- a/gcc/testsuite/obj-c++.dg/attributes/nsobject-01.mm
+++ b/gcc/testsuite/obj-c++.dg/attributes/nsobject-01.mm
@@ -1,5 +1,5 @@
/* Test handling of the NSObject attribute. */
-/* { dg-additional-options "-fsyntax-only " } */
+/* { dg-additional-options "-fsyntax-only -Wno-objc-root-class" } */
typedef struct AnObj * __attribute__ ((NSObject)) AnObjRef;
typedef struct AnObj * __attribute__ ((__NSObject__)) AnotherObjRef;
diff --git a/gcc/testsuite/obj-c++.dg/attributes/nullability-00.mm b/gcc/testsuite/obj-c++.dg/attributes/nullability-00.mm
new file mode 100644
index 0000000..957fca4
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/attributes/nullability-00.mm
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class -fsyntax-only" } */
+
+__attribute__((objc_nullability(0))) id a;
+__attribute__((objc_nullability(4))) id e_1; /* { dg-error {'objc_nullability' attribute argument '4' is not an integer constant between 0 and 3} } */
+__attribute__((objc_nullability(-22))) id e_2; /* { dg-error {'objc_nullability' attribute argument '-22' is not an integer constant between 0 and 3} } */
+__attribute__((objc_nullability("unspecified"))) id b;
+__attribute__((objc_nullability("nullable"))) id c;
+__attribute__((objc_nullability("nonnull"))) id d;
+__attribute__((objc_nullability("resettable"))) id e;
+__attribute__((objc_nullability("nonsense"))) id e_3; /* { dg-error {'objc_nullability' attribute argument '"nonsense"' is not recognised} } */
+__attribute__((objc_nullability(noGoingToWork))) id e_4; /* { dg-error {'noGoingToWork' was not declared in this scope} } */
+
+@interface MyRoot
+{
+ __attribute__((objc_nullability(0))) id iv_a;
+ __attribute__((objc_nullability(3))) struct { int bad_a; } s;/* { dg-error {'objc_nullability' cannot be applied to non-pointer type '<unnamed struct>'} } */
+ __attribute__((objc_nullability("resettable"))) int iv_b;/* { dg-error {'objc_nullability' cannot be applied to non-pointer type 'int'} } */
+}
+@end
diff --git a/gcc/testsuite/obj-c++.dg/attributes/parameter-attribute-1.mm b/gcc/testsuite/obj-c++.dg/attributes/parameter-attribute-1.mm
index a4ba259..b4556ba 100644
--- a/gcc/testsuite/obj-c++.dg/attributes/parameter-attribute-1.mm
+++ b/gcc/testsuite/obj-c++.dg/attributes/parameter-attribute-1.mm
@@ -1,6 +1,7 @@
/* Test __attribute__((unused)) for an Objective-C method parameter. */
/* { dg-do compile } */
/* { dg-options "-Wunused-parameter" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/attributes/parameter-attribute-2.mm b/gcc/testsuite/obj-c++.dg/attributes/parameter-attribute-2.mm
index 3908faf..9d69e42 100644
--- a/gcc/testsuite/obj-c++.dg/attributes/parameter-attribute-2.mm
+++ b/gcc/testsuite/obj-c++.dg/attributes/parameter-attribute-2.mm
@@ -1,5 +1,6 @@
/* Test that we get warnings for unrecognized attributes. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/attributes/proto-attribute-1.mm b/gcc/testsuite/obj-c++.dg/attributes/proto-attribute-1.mm
index a852a7a..03726dc 100644
--- a/gcc/testsuite/obj-c++.dg/attributes/proto-attribute-1.mm
+++ b/gcc/testsuite/obj-c++.dg/attributes/proto-attribute-1.mm
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/attributes/proto-attribute-3.mm b/gcc/testsuite/obj-c++.dg/attributes/proto-attribute-3.mm
index fc5251e..263f927 100644
--- a/gcc/testsuite/obj-c++.dg/attributes/proto-attribute-3.mm
+++ b/gcc/testsuite/obj-c++.dg/attributes/proto-attribute-3.mm
@@ -1,7 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
-
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* Test deprecate attribute with normal @protocol declarations. */
diff --git a/gcc/testsuite/obj-c++.dg/attributes/proto-attribute-4.mm b/gcc/testsuite/obj-c++.dg/attributes/proto-attribute-4.mm
index d2e5f28..665e13d 100644
--- a/gcc/testsuite/obj-c++.dg/attributes/proto-attribute-4.mm
+++ b/gcc/testsuite/obj-c++.dg/attributes/proto-attribute-4.mm
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* Test that you get a warning when an unknown protocol attribute is ignored. */
diff --git a/gcc/testsuite/obj-c++.dg/attributes/root-class-01.mm b/gcc/testsuite/obj-c++.dg/attributes/root-class-01.mm
new file mode 100644
index 0000000..84da94a
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/attributes/root-class-01.mm
@@ -0,0 +1,11 @@
+/* Test Wobjc-root-class warning is suppressed by the objc_root_class attr.
+ Note that we don't issue a warning unless the TU contains an implementation
+ for the class. This should compile without warning. */
+/* { dg-additional-options "-fsyntax-only " } */
+
+__attribute__((objc_root_class))
+@interface ARootObject
+@end
+
+@implementation ARootObject
+@end
diff --git a/gcc/testsuite/obj-c++.dg/attributes/unused-parameter-1.mm b/gcc/testsuite/obj-c++.dg/attributes/unused-parameter-1.mm
index 8fbb11e..c56a7f7 100644
--- a/gcc/testsuite/obj-c++.dg/attributes/unused-parameter-1.mm
+++ b/gcc/testsuite/obj-c++.dg/attributes/unused-parameter-1.mm
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/bad-receiver-type.mm b/gcc/testsuite/obj-c++.dg/bad-receiver-type.mm
index 1d6699f..9c00a06 100644
--- a/gcc/testsuite/obj-c++.dg/bad-receiver-type.mm
+++ b/gcc/testsuite/obj-c++.dg/bad-receiver-type.mm
@@ -1,5 +1,6 @@
// { dg-do compile }
// { dg-options "" }
+// { dg-additional-options "-Wno-objc-root-class" }
@interface A
diff --git a/gcc/testsuite/obj-c++.dg/bitfield-3.mm b/gcc/testsuite/obj-c++.dg/bitfield-3.mm
index d81976a..c4ed984 100644
--- a/gcc/testsuite/obj-c++.dg/bitfield-3.mm
+++ b/gcc/testsuite/obj-c++.dg/bitfield-3.mm
@@ -4,6 +4,7 @@
/* { dg-do run { target *-*-darwin* } } */
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
/* { dg-options "-fsigned-char" } */
+// { dg-additional-options "-Wno-objc-root-class" }
typedef struct objc_object { struct objc_class *class_pointer; } *id;
diff --git a/gcc/testsuite/obj-c++.dg/bitfield-5.mm b/gcc/testsuite/obj-c++.dg/bitfield-5.mm
index 3b0065d..d86c9b1 100644
--- a/gcc/testsuite/obj-c++.dg/bitfield-5.mm
+++ b/gcc/testsuite/obj-c++.dg/bitfield-5.mm
@@ -3,6 +3,7 @@
(@interface vs. @implementation) checks take the bitfield width into account. */
/* Author: Ziemowit Laski <zlaski@apple.com> */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
@interface Base {
int i;
diff --git a/gcc/testsuite/obj-c++.dg/class-extension-1.mm b/gcc/testsuite/obj-c++.dg/class-extension-1.mm
index 5c89a98..c497c1d 100644
--- a/gcc/testsuite/obj-c++.dg/class-extension-1.mm
+++ b/gcc/testsuite/obj-c++.dg/class-extension-1.mm
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* This test tests the basic of class extensions. */
diff --git a/gcc/testsuite/obj-c++.dg/class-extension-2.mm b/gcc/testsuite/obj-c++.dg/class-extension-2.mm
index 7f55b60..108bc00 100644
--- a/gcc/testsuite/obj-c++.dg/class-extension-2.mm
+++ b/gcc/testsuite/obj-c++.dg/class-extension-2.mm
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* This test tests class extensions and protocols. */
diff --git a/gcc/testsuite/obj-c++.dg/class-extension-3.mm b/gcc/testsuite/obj-c++.dg/class-extension-3.mm
index 69e5705..bed8490 100644
--- a/gcc/testsuite/obj-c++.dg/class-extension-3.mm
+++ b/gcc/testsuite/obj-c++.dg/class-extension-3.mm
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* This test tests warnings on class extensions. */
diff --git a/gcc/testsuite/obj-c++.dg/class-extension-4.mm b/gcc/testsuite/obj-c++.dg/class-extension-4.mm
index 9e19aa7..2cfbc5d 100644
--- a/gcc/testsuite/obj-c++.dg/class-extension-4.mm
+++ b/gcc/testsuite/obj-c++.dg/class-extension-4.mm
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* This test tests you can not declare a class extension after the class @implementation. */
diff --git a/gcc/testsuite/obj-c++.dg/class-protocol-1.mm b/gcc/testsuite/obj-c++.dg/class-protocol-1.mm
index 78957cb..3b33264 100644
--- a/gcc/testsuite/obj-c++.dg/class-protocol-1.mm
+++ b/gcc/testsuite/obj-c++.dg/class-protocol-1.mm
@@ -1,6 +1,7 @@
/* Check Class <protocol> types */
/* Author: David Ayers <d.ayers@inode.at> */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
#include "../objc-obj-c++-shared/runtime.h"
diff --git a/gcc/testsuite/obj-c++.dg/comp-types-1.mm b/gcc/testsuite/obj-c++.dg/comp-types-1.mm
index 6d4e86e..6402abc 100644
--- a/gcc/testsuite/obj-c++.dg/comp-types-1.mm
+++ b/gcc/testsuite/obj-c++.dg/comp-types-1.mm
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
@interface A
+ new;
diff --git a/gcc/testsuite/obj-c++.dg/comp-types-10.mm b/gcc/testsuite/obj-c++.dg/comp-types-10.mm
index c7f0cb6..fdfd093 100644
--- a/gcc/testsuite/obj-c++.dg/comp-types-10.mm
+++ b/gcc/testsuite/obj-c++.dg/comp-types-10.mm
@@ -2,6 +2,7 @@
/* { dg-do compile } */
/* { dg-prune-output ".*internal compiler error.*" } */
/* { dg-options "-O3" } */
+// { dg-additional-options "-Wno-objc-root-class" }
@class NSString;
@protocol NSObject
diff --git a/gcc/testsuite/obj-c++.dg/comp-types-2.mm b/gcc/testsuite/obj-c++.dg/comp-types-2.mm
index 0704378..87750fd 100644
--- a/gcc/testsuite/obj-c++.dg/comp-types-2.mm
+++ b/gcc/testsuite/obj-c++.dg/comp-types-2.mm
@@ -1,6 +1,7 @@
/* Test various ObjC types assignments and comparisons. */
/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/comp-types-3.mm b/gcc/testsuite/obj-c++.dg/comp-types-3.mm
index 2bea015..d4d0790 100644
--- a/gcc/testsuite/obj-c++.dg/comp-types-3.mm
+++ b/gcc/testsuite/obj-c++.dg/comp-types-3.mm
@@ -1,6 +1,7 @@
/* Test simple ObjC types casts. */
/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/comp-types-5.mm b/gcc/testsuite/obj-c++.dg/comp-types-5.mm
index 99f6772..2c4fc57 100644
--- a/gcc/testsuite/obj-c++.dg/comp-types-5.mm
+++ b/gcc/testsuite/obj-c++.dg/comp-types-5.mm
@@ -1,6 +1,7 @@
/* Test errors for assignments and comparisons between ObjC and C++ types. */
/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/comp-types-6.mm b/gcc/testsuite/obj-c++.dg/comp-types-6.mm
index 23b84ed..071a756 100644
--- a/gcc/testsuite/obj-c++.dg/comp-types-6.mm
+++ b/gcc/testsuite/obj-c++.dg/comp-types-6.mm
@@ -1,6 +1,7 @@
/* Test assignments and comparisons involving `one-off' protocols. */
/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/comp-types-7.mm b/gcc/testsuite/obj-c++.dg/comp-types-7.mm
index e235581..6286355 100644
--- a/gcc/testsuite/obj-c++.dg/comp-types-7.mm
+++ b/gcc/testsuite/obj-c++.dg/comp-types-7.mm
@@ -1,6 +1,7 @@
/* Test assignments and comparisons involving category protocols. */
/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/comp-types-8.mm b/gcc/testsuite/obj-c++.dg/comp-types-8.mm
index 6db76bb..0221164 100644
--- a/gcc/testsuite/obj-c++.dg/comp-types-8.mm
+++ b/gcc/testsuite/obj-c++.dg/comp-types-8.mm
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-additional-options "-Wno-return-type" } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* We used to ICE because we removed the cast to List_linked*
in -[ListIndex_linked next]. */
diff --git a/gcc/testsuite/obj-c++.dg/demangle-2.mm b/gcc/testsuite/obj-c++.dg/demangle-2.mm
index f282085..14c7b3e 100644
--- a/gcc/testsuite/obj-c++.dg/demangle-2.mm
+++ b/gcc/testsuite/obj-c++.dg/demangle-2.mm
@@ -1,6 +1,7 @@
/* Test demangling an Objective-C method. */
/* { dg-do run } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <cstring>
#include <cstdlib>
diff --git a/gcc/testsuite/obj-c++.dg/demangle-3.mm b/gcc/testsuite/obj-c++.dg/demangle-3.mm
index afb83d7..d8d8178 100644
--- a/gcc/testsuite/obj-c++.dg/demangle-3.mm
+++ b/gcc/testsuite/obj-c++.dg/demangle-3.mm
@@ -1,6 +1,7 @@
/* Test demangling an Objective-C method in error messages. */
/* { dg-do compile } */
/* { dg-additional-options "-Wno-return-type" } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/duplicate-class-1.mm b/gcc/testsuite/obj-c++.dg/duplicate-class-1.mm
index 3a5e510..77e52c6 100644
--- a/gcc/testsuite/obj-c++.dg/duplicate-class-1.mm
+++ b/gcc/testsuite/obj-c++.dg/duplicate-class-1.mm
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* Test that a duplicated @implementation for the same class does not
crash the compiler. */
diff --git a/gcc/testsuite/obj-c++.dg/encode-1-next.mm b/gcc/testsuite/obj-c++.dg/encode-1-next.mm
index 47673f2..854dd72 100644
--- a/gcc/testsuite/obj-c++.dg/encode-1-next.mm
+++ b/gcc/testsuite/obj-c++.dg/encode-1-next.mm
@@ -5,6 +5,7 @@
/* { dg-do compile } */
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+// { dg-additional-options "-Wno-objc-root-class" }
struct Cxx {
const struct Cxx *next;
diff --git a/gcc/testsuite/obj-c++.dg/encode-1.mm b/gcc/testsuite/obj-c++.dg/encode-1.mm
index 5f5ba20..6247c64 100644
--- a/gcc/testsuite/obj-c++.dg/encode-1.mm
+++ b/gcc/testsuite/obj-c++.dg/encode-1.mm
@@ -3,6 +3,7 @@
/* { dg-do compile } */
/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+// { dg-additional-options "-Wno-objc-root-class" }
struct Cxx {
const struct Cxx *next;
diff --git a/gcc/testsuite/obj-c++.dg/enhanced-proto-2.mm b/gcc/testsuite/obj-c++.dg/enhanced-proto-2.mm
index 31c2e50..5964dfb 100644
--- a/gcc/testsuite/obj-c++.dg/enhanced-proto-2.mm
+++ b/gcc/testsuite/obj-c++.dg/enhanced-proto-2.mm
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
@protocol MyProto1
@optional
diff --git a/gcc/testsuite/obj-c++.dg/exceptions-1.mm b/gcc/testsuite/obj-c++.dg/exceptions-1.mm
index 0f3b7e8..75327ef 100644
--- a/gcc/testsuite/obj-c++.dg/exceptions-1.mm
+++ b/gcc/testsuite/obj-c++.dg/exceptions-1.mm
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-options "-fobjc-exceptions" } */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* This test checks the syntax @catch (...) which catches any
exceptions. At the moment, @catch (...) is identical to @catch (id
diff --git a/gcc/testsuite/obj-c++.dg/exceptions-3.mm b/gcc/testsuite/obj-c++.dg/exceptions-3.mm
index 622e4ca..7cf77a7 100644
--- a/gcc/testsuite/obj-c++.dg/exceptions-3.mm
+++ b/gcc/testsuite/obj-c++.dg/exceptions-3.mm
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-options "-fobjc-exceptions" } */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* Test that the compiler is checking the argument of @catch(), and
produce errors when invalid types are used. */
diff --git a/gcc/testsuite/obj-c++.dg/exceptions-4.mm b/gcc/testsuite/obj-c++.dg/exceptions-4.mm
index 4aa00a6..1391c43 100644
--- a/gcc/testsuite/obj-c++.dg/exceptions-4.mm
+++ b/gcc/testsuite/obj-c++.dg/exceptions-4.mm
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-options "-fobjc-exceptions" } */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* Test warnings when parsing syntax errors in @catch(). */
diff --git a/gcc/testsuite/obj-c++.dg/exceptions-5.mm b/gcc/testsuite/obj-c++.dg/exceptions-5.mm
index 5aa08f3..4547a75 100644
--- a/gcc/testsuite/obj-c++.dg/exceptions-5.mm
+++ b/gcc/testsuite/obj-c++.dg/exceptions-5.mm
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-options "-fobjc-exceptions" } */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* Test that you can use an unnamed argument with @catch. This test is the same
as exceptions-3.mm, but with no name for @catch arguments. */
diff --git a/gcc/testsuite/obj-c++.dg/extern-c-1.mm b/gcc/testsuite/obj-c++.dg/extern-c-1.mm
index c5fec6f..8b9147a 100644
--- a/gcc/testsuite/obj-c++.dg/extern-c-1.mm
+++ b/gcc/testsuite/obj-c++.dg/extern-c-1.mm
@@ -1,5 +1,6 @@
/* Test extern c support inside @implementation */
/* Devang Patel <dpatel@apple.com>. */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/fobjc-std-1.mm b/gcc/testsuite/obj-c++.dg/fobjc-std-1.mm
index 59db950..f7f4a19 100644
--- a/gcc/testsuite/obj-c++.dg/fobjc-std-1.mm
+++ b/gcc/testsuite/obj-c++.dg/fobjc-std-1.mm
@@ -1,6 +1,7 @@
/* Test warnings when using -fobjc-std=objc1. */
/* { dg-do compile } */
/* { dg-options "-fobjc-std=objc1" } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/gnu-api-2-class-meta.mm b/gcc/testsuite/obj-c++.dg/gnu-api-2-class-meta.mm
index bdaef98..92852c3 100644
--- a/gcc/testsuite/obj-c++.dg/gnu-api-2-class-meta.mm
+++ b/gcc/testsuite/obj-c++.dg/gnu-api-2-class-meta.mm
@@ -21,6 +21,7 @@
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
/* { dg-additional-options "-DOBJC_OLD_DISPATCH_PROTOTYPES" { target { *-*-darwin* } } } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/obj-c++.dg/gnu-api-2-class.mm b/gcc/testsuite/obj-c++.dg/gnu-api-2-class.mm
index ae39026..f6e3d8d 100644
--- a/gcc/testsuite/obj-c++.dg/gnu-api-2-class.mm
+++ b/gcc/testsuite/obj-c++.dg/gnu-api-2-class.mm
@@ -8,6 +8,7 @@
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
/* { dg-additional-options "-DOBJC_OLD_DISPATCH_PROTOTYPES" { target { *-*-darwin* } } } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/obj-c++.dg/gnu-api-2-ivar.mm b/gcc/testsuite/obj-c++.dg/gnu-api-2-ivar.mm
index 1c85d23..991edc7 100644
--- a/gcc/testsuite/obj-c++.dg/gnu-api-2-ivar.mm
+++ b/gcc/testsuite/obj-c++.dg/gnu-api-2-ivar.mm
@@ -5,6 +5,7 @@
/* { dg-do run } */
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/obj-c++.dg/gnu-api-2-method.mm b/gcc/testsuite/obj-c++.dg/gnu-api-2-method.mm
index 97bf84b..07c3a22 100644
--- a/gcc/testsuite/obj-c++.dg/gnu-api-2-method.mm
+++ b/gcc/testsuite/obj-c++.dg/gnu-api-2-method.mm
@@ -5,6 +5,7 @@
/* { dg-do run } */
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/obj-c++.dg/gnu-api-2-objc.mm b/gcc/testsuite/obj-c++.dg/gnu-api-2-objc.mm
index 201ab7e..e68e7a8 100644
--- a/gcc/testsuite/obj-c++.dg/gnu-api-2-objc.mm
+++ b/gcc/testsuite/obj-c++.dg/gnu-api-2-objc.mm
@@ -9,6 +9,7 @@
systems that don't have the V2 APis). XFAILing the run is not useful
since it will XPASS on the sub-set that works. */
/* { dg-skip-if "Incompatible" { *-*-darwin* } { "-fnext-runtime" } { "" } } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/obj-c++.dg/gnu-api-2-objc_msg_lookup.mm b/gcc/testsuite/obj-c++.dg/gnu-api-2-objc_msg_lookup.mm
index dcbf6d2..1fb56dc 100644
--- a/gcc/testsuite/obj-c++.dg/gnu-api-2-objc_msg_lookup.mm
+++ b/gcc/testsuite/obj-c++.dg/gnu-api-2-objc_msg_lookup.mm
@@ -5,6 +5,7 @@
/* { dg-do run } */
/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/obj-c++.dg/gnu-api-2-object.mm b/gcc/testsuite/obj-c++.dg/gnu-api-2-object.mm
index a2702d6..4d99053 100644
--- a/gcc/testsuite/obj-c++.dg/gnu-api-2-object.mm
+++ b/gcc/testsuite/obj-c++.dg/gnu-api-2-object.mm
@@ -5,6 +5,7 @@
/* { dg-do run } */
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/obj-c++.dg/gnu-api-2-property.mm b/gcc/testsuite/obj-c++.dg/gnu-api-2-property.mm
index 953e9bb..601f39f 100644
--- a/gcc/testsuite/obj-c++.dg/gnu-api-2-property.mm
+++ b/gcc/testsuite/obj-c++.dg/gnu-api-2-property.mm
@@ -4,6 +4,7 @@
/* { dg-do run } */
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/obj-c++.dg/gnu-api-2-protocol.mm b/gcc/testsuite/obj-c++.dg/gnu-api-2-protocol.mm
index 9a2ceca..21ae06b 100644
--- a/gcc/testsuite/obj-c++.dg/gnu-api-2-protocol.mm
+++ b/gcc/testsuite/obj-c++.dg/gnu-api-2-protocol.mm
@@ -5,6 +5,7 @@
/* { dg-do run } */
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/obj-c++.dg/gnu-api-2-resolve-method.mm b/gcc/testsuite/obj-c++.dg/gnu-api-2-resolve-method.mm
index f8a54d3..dc311324 100644
--- a/gcc/testsuite/obj-c++.dg/gnu-api-2-resolve-method.mm
+++ b/gcc/testsuite/obj-c++.dg/gnu-api-2-resolve-method.mm
@@ -5,6 +5,7 @@
/* { dg-do run } */
/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/obj-c++.dg/gnu-api-2-sel.mm b/gcc/testsuite/obj-c++.dg/gnu-api-2-sel.mm
index ff50058..dd8ff3e 100644
--- a/gcc/testsuite/obj-c++.dg/gnu-api-2-sel.mm
+++ b/gcc/testsuite/obj-c++.dg/gnu-api-2-sel.mm
@@ -4,6 +4,7 @@
/* { dg-do run } */
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/obj-c++.dg/invalid-method-2.mm b/gcc/testsuite/obj-c++.dg/invalid-method-2.mm
index e3a8ed1..8eee0ff 100644
--- a/gcc/testsuite/obj-c++.dg/invalid-method-2.mm
+++ b/gcc/testsuite/obj-c++.dg/invalid-method-2.mm
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* Test that using an invalid type in a method declaration produces a
friendly error without a compiler crash. */
diff --git a/gcc/testsuite/obj-c++.dg/ivar-invalid-type-1.mm b/gcc/testsuite/obj-c++.dg/ivar-invalid-type-1.mm
index 4c1480a..974e919 100644
--- a/gcc/testsuite/obj-c++.dg/ivar-invalid-type-1.mm
+++ b/gcc/testsuite/obj-c++.dg/ivar-invalid-type-1.mm
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
@interface MyRootClass
diff --git a/gcc/testsuite/obj-c++.dg/ivar-problem-1.mm b/gcc/testsuite/obj-c++.dg/ivar-problem-1.mm
index 4ed5afa..1736f9c 100644
--- a/gcc/testsuite/obj-c++.dg/ivar-problem-1.mm
+++ b/gcc/testsuite/obj-c++.dg/ivar-problem-1.mm
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* This test checks what happens if there are 16 instance variables.
In that case, the class was not created correctly. In this testcase,
diff --git a/gcc/testsuite/obj-c++.dg/lto/lto.exp b/gcc/testsuite/obj-c++.dg/lto/lto.exp
index 6ba5f9c..936872a 100644
--- a/gcc/testsuite/obj-c++.dg/lto/lto.exp
+++ b/gcc/testsuite/obj-c++.dg/lto/lto.exp
@@ -41,10 +41,10 @@ if { ![check_effective_target_lto] } {
global LTO_OPTIONS
set LTO_OPTIONS [list \
- {-O0 -flto -fgnu-runtime} \
- {-O2 -flto -fgnu-runtime} \
- {-O0 -flto -flto-partition=none -fgnu-runtime} \
- {-O2 -flto -flto-partition=none -fgnu-runtime} \
+ {-O0 -flto -fgnu-runtime -Wno-objc-root-class} \
+ {-O2 -flto -fgnu-runtime -Wno-objc-root-class} \
+ {-O0 -flto -flto-partition=none -fgnu-runtime -Wno-objc-root-class} \
+ {-O2 -flto -flto-partition=none -fgnu-runtime -Wno-objc-root-class} \
]
obj-c++_init
@@ -67,10 +67,10 @@ foreach src $tests {
# darwin targets can also run code with the NeXT runtime.
if [istarget "*-*-darwin*" ] {
set LTO_OPTIONS [list \
- {-O0 -flto -fnext-runtime} \
- {-O2 -flto -fnext-runtime} \
- {-O0 -flto -flto-partition=none -fnext-runtime} \
- {-O2 -flto -flto-partition=none -fnext-runtime} \
+ {-O0 -flto -fnext-runtime -Wno-objc-root-class} \
+ {-O2 -flto -fnext-runtime -Wno-objc-root-class} \
+ {-O0 -flto -flto-partition=none -fnext-runtime -Wno-objc-root-class} \
+ {-O2 -flto -flto-partition=none -fnext-runtime -Wno-objc-root-class} \
]
foreach src $tests {
# If we're only testing specific files and this isn't one of them, skip it.
diff --git a/gcc/testsuite/obj-c++.dg/lto/trivial-1_0.mm b/gcc/testsuite/obj-c++.dg/lto/trivial-1_0.mm
index 55f62f0..c3620c3 100644
--- a/gcc/testsuite/obj-c++.dg/lto/trivial-1_0.mm
+++ b/gcc/testsuite/obj-c++.dg/lto/trivial-1_0.mm
@@ -1,5 +1,5 @@
/* { dg-lto-do run } */
-/* { dg-skip-if "Needs OBJC2 ABI" { "*-*-darwin*" && lp64 } } */
+
extern "C" {
extern int printf (const char *,...) ;
extern void abort (void) ;
diff --git a/gcc/testsuite/obj-c++.dg/method-1.mm b/gcc/testsuite/obj-c++.dg/method-1.mm
index 7317ae2..5bb851a 100644
--- a/gcc/testsuite/obj-c++.dg/method-1.mm
+++ b/gcc/testsuite/obj-c++.dg/method-1.mm
@@ -3,6 +3,7 @@
/* Author: Ziemowit Laski <zlaski@apple.com>. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/method-12.mm b/gcc/testsuite/obj-c++.dg/method-12.mm
index 4546144..d3145ab 100644
--- a/gcc/testsuite/obj-c++.dg/method-12.mm
+++ b/gcc/testsuite/obj-c++.dg/method-12.mm
@@ -3,6 +3,7 @@
/* { dg-options "-Wstrict-selector-match" } */
/* { dg-do compile } */
/* { dg-skip-if "Object interface removed" { *-*-darwin[1-2]* && { lp64 } } { "-fnext-runtime" } { "" } } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/Protocol.h>
diff --git a/gcc/testsuite/obj-c++.dg/method-18.mm b/gcc/testsuite/obj-c++.dg/method-18.mm
index 411caac..c753f33 100644
--- a/gcc/testsuite/obj-c++.dg/method-18.mm
+++ b/gcc/testsuite/obj-c++.dg/method-18.mm
@@ -1,5 +1,6 @@
/* Contributed by Igor Seleznev <selez@mail.ru>. */
/* This used to be broken. */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/method-19.mm b/gcc/testsuite/obj-c++.dg/method-19.mm
index 225beca..a3b977e 100644
--- a/gcc/testsuite/obj-c++.dg/method-19.mm
+++ b/gcc/testsuite/obj-c++.dg/method-19.mm
@@ -4,6 +4,7 @@
/* Author: Ziemowit Laski <zlaski@apple.com>. */
/* { dg-do run } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
#include "../objc-obj-c++-shared/runtime.h"
diff --git a/gcc/testsuite/obj-c++.dg/method-20.mm b/gcc/testsuite/obj-c++.dg/method-20.mm
index 9698225..a7fe41d 100644
--- a/gcc/testsuite/obj-c++.dg/method-20.mm
+++ b/gcc/testsuite/obj-c++.dg/method-20.mm
@@ -2,6 +2,7 @@
used as method selectors. */
/* Author: Ziemowit Laski <zlaski@apple.com>. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
@interface Foo
- (void)insertNewButtonImage:(Foo *)newButtonImage in:(Foo *)buttonCell;
diff --git a/gcc/testsuite/obj-c++.dg/method-3.mm b/gcc/testsuite/obj-c++.dg/method-3.mm
index 9dab8c5..17b0c99 100644
--- a/gcc/testsuite/obj-c++.dg/method-3.mm
+++ b/gcc/testsuite/obj-c++.dg/method-3.mm
@@ -3,6 +3,7 @@
/* { dg-do compile } */
/* { dg-options "-Wno-strict-selector-match" } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/method-4.mm b/gcc/testsuite/obj-c++.dg/method-4.mm
index e94f8f1..1f2f93e 100644
--- a/gcc/testsuite/obj-c++.dg/method-4.mm
+++ b/gcc/testsuite/obj-c++.dg/method-4.mm
@@ -3,6 +3,7 @@
/* { dg-do compile } */
/* { dg-options "-Wstrict-selector-match" } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/method-5.mm b/gcc/testsuite/obj-c++.dg/method-5.mm
index 17c841a4..10364cc 100644
--- a/gcc/testsuite/obj-c++.dg/method-5.mm
+++ b/gcc/testsuite/obj-c++.dg/method-5.mm
@@ -3,6 +3,7 @@
/* { dg-do compile } */
/* { dg-options "-Wno-strict-selector-match" } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/method-8.mm b/gcc/testsuite/obj-c++.dg/method-8.mm
index cde1bc2..9c5c17a 100644
--- a/gcc/testsuite/obj-c++.dg/method-8.mm
+++ b/gcc/testsuite/obj-c++.dg/method-8.mm
@@ -1,5 +1,6 @@
/* Tests of duplication. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
@interface class1
- (int) meth1; /* { dg-message "previous declaration" } */
diff --git a/gcc/testsuite/obj-c++.dg/method-9.mm b/gcc/testsuite/obj-c++.dg/method-9.mm
index 787e25d..bee076e 100644
--- a/gcc/testsuite/obj-c++.dg/method-9.mm
+++ b/gcc/testsuite/obj-c++.dg/method-9.mm
@@ -1,6 +1,7 @@
/* Test for lookup of class (factory) methods. */
/* Author: Ziemowit Laski <zlaski@apple.com>. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
@interface MyBase
- (void) rootInstanceMethod;
diff --git a/gcc/testsuite/obj-c++.dg/method-namespace-1.mm b/gcc/testsuite/obj-c++.dg/method-namespace-1.mm
index 6095f57..86006a7 100644
--- a/gcc/testsuite/obj-c++.dg/method-namespace-1.mm
+++ b/gcc/testsuite/obj-c++.dg/method-namespace-1.mm
@@ -1,5 +1,6 @@
/* Test for usage of namespace inside @implementation. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
@interface MyDocument
@end
diff --git a/gcc/testsuite/obj-c++.dg/plugin/diagnostic-test-expressions-1.mm b/gcc/testsuite/obj-c++.dg/plugin/diagnostic-test-expressions-1.mm
index 988b290..128b3bd 100644
--- a/gcc/testsuite/obj-c++.dg/plugin/diagnostic-test-expressions-1.mm
+++ b/gcc/testsuite/obj-c++.dg/plugin/diagnostic-test-expressions-1.mm
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O -fdiagnostics-show-caret" } */
/* { dg-excess-errors "tree range 0:0-0:0" { target { *-*-darwin* } } } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* This file is similar to diagnostic-test-expressions-1.c
(see the notes in that file); this file adds test
diff --git a/gcc/testsuite/obj-c++.dg/pr23709.mm b/gcc/testsuite/obj-c++.dg/pr23709.mm
index 018b53a..7936956 100644
--- a/gcc/testsuite/obj-c++.dg/pr23709.mm
+++ b/gcc/testsuite/obj-c++.dg/pr23709.mm
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
@interface A
+(void)method: (int)parameter {} /* { dg-error "expected" } */
diff --git a/gcc/testsuite/obj-c++.dg/pragma-2.mm b/gcc/testsuite/obj-c++.dg/pragma-2.mm
index 14c4d79..09feac7 100644
--- a/gcc/testsuite/obj-c++.dg/pragma-2.mm
+++ b/gcc/testsuite/obj-c++.dg/pragma-2.mm
@@ -1,5 +1,6 @@
/* It is OK to use #pragma inside @implementation body. This test checks that. */
/* Ziemowit Laski <zlaski@apple.com>. */
+// { dg-additional-options "-Wno-objc-root-class" }
@interface A
{
diff --git a/gcc/testsuite/obj-c++.dg/private-1.mm b/gcc/testsuite/obj-c++.dg/private-1.mm
index 0c25aea..2173b90 100644
--- a/gcc/testsuite/obj-c++.dg/private-1.mm
+++ b/gcc/testsuite/obj-c++.dg/private-1.mm
@@ -1,6 +1,7 @@
/* Test errors for accessing @private and @protected variables. */
/* Based on work by: Nicola Pero <nicola@brainstorm.co.uk>. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
@interface MySuperClass
diff --git a/gcc/testsuite/obj-c++.dg/private-2.mm b/gcc/testsuite/obj-c++.dg/private-2.mm
index 3e6ff11..93b8a8f 100644
--- a/gcc/testsuite/obj-c++.dg/private-2.mm
+++ b/gcc/testsuite/obj-c++.dg/private-2.mm
@@ -2,6 +2,7 @@
/* Based on work by: Nicola Pero <nicola@brainstorm.co.uk>. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/property/at-property-4.mm b/gcc/testsuite/obj-c++.dg/property/at-property-4.mm
index f73d706..f589354 100644
--- a/gcc/testsuite/obj-c++.dg/property/at-property-4.mm
+++ b/gcc/testsuite/obj-c++.dg/property/at-property-4.mm
@@ -26,12 +26,17 @@
@property (class) int property_cl_1;
+@property (null_unspecified) int *property_null_1;
+@property (nullable) int *property_null_2;
+@property (nonnull) int *property_null_3;
+@property (null_resettable) int *property_null_4;
+
@property (release) int property_err_1; /* { dg-error "unknown property attribute" } */
@property (getter=myGetter) int property_g0;
@property (setter=mySetter:) int property_s0;
-/* Now test various problems. */
+/* Now test various basic problems. */
@property (readonly, readwrite) int a; /* { dg-error ".readwrite. attribute conflicts with .readonly. attribute" } */
@property (readonly, setter=mySetterB:) int b; /* { dg-error ".readonly. attribute conflicts with .setter. attribute" } */
@@ -42,6 +47,19 @@
@property (atomic, nonatomic) int property_j; /* { dg-error {'nonatomic' attribute conflicts with 'atomic' attribute} } */
+@property (null_unspecified) int property_bad_t_1; /* { dg-error {nullability specifier 'null_unspecified' cannot be applied to non-pointer type 'int'} } */
+@property (nullable) int property_bad_t_2;/* { dg-error {nullability specifier 'nullable' cannot be applied to non-pointer type 'int'} } */
+@property (nonnull) int property_bad_t_3;/* { dg-error {nullability specifier 'nonnull' cannot be applied to non-pointer type 'int'} } */
+@property (null_resettable) int property_bad_t_4;/* { dg-error {nullability specifier 'null_resettable' cannot be applied to non-pointer type 'int'} } */
+@property (nullable) int **property_bad_t_5;/* { dg-error {nullability specifier 'nullable' cannot be applied to multi-level pointer type 'int\*\*'} } */
+
+@property (null_unspecified, nullable) int *property_ne_1; /* { dg-error {'nullable' attribute conflicts with 'null_unspecified' attribute} } */
+@property (null_unspecified, nonnull) int *property_ne_2; /* { dg-error {'nonnull' attribute conflicts with 'null_unspecified' attribute} } */
+@property (null_unspecified, null_resettable) int *property_ne_3; /* { dg-error {'null_resettable' attribute conflicts with 'null_unspecified' attribute} } */
+@property (nullable,nonnull) int *property_ne_4; /* { dg-error {'nonnull' attribute conflicts with 'nullable' attribute} } */
+@property (nullable,null_resettable) int *property_ne_5; /* { dg-error {'null_resettable' attribute conflicts with 'nullable' attribute} } */
+@property (nonnull, null_resettable) int *property_ne_6; /* { dg-error {'null_resettable' attribute conflicts with 'nonnull' attribute} } */
+
@property (setter=mySetter:,setter=mySetter2:) int f; /* { dg-warning {multiple property 'setter' methods specified, the latest one will be used} } */
@property (getter=myGetter, getter=myGetter2 ) int g; /* { dg-warning {multiple property 'getter' methods specified, the latest one will be used} } */
diff --git a/gcc/testsuite/obj-c++.dg/property/nullability-00.mm b/gcc/testsuite/obj-c++.dg/property/nullability-00.mm
new file mode 100644
index 0000000..9b0c808
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/property/nullability-00.mm
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fsyntax-only" } */
+
+@interface MyRoot
+{
+ Class isa __attribute__((deprecated));
+ id p;
+ int x;
+ int *i;
+}
+
+@property(null_unspecified, assign) MyRoot *p1;
+@property(nonnull, assign) MyRoot *p2;
+@property(nullable, assign) MyRoot *p3;
+@property(null_resettable, assign) MyRoot *p4;
+@property(null_exciting, assign) MyRoot *e_5; /* { dg-error {unknown property attribute 'null_exciting'} } */
+
+@property(nonnull, retain, nullable) MyRoot *e_6; /* { dg-error {'nullable' attribute conflicts with 'nonnull' attribute} } */
+@property(nonnull, nonnull) int *i; /* { dg-warning {duplicate 'nonnull' attribute} } */
+
+@end
diff --git a/gcc/testsuite/obj-c++.dg/property/property.exp b/gcc/testsuite/obj-c++.dg/property/property.exp
index d18f610..31e683c 100644
--- a/gcc/testsuite/obj-c++.dg/property/property.exp
+++ b/gcc/testsuite/obj-c++.dg/property/property.exp
@@ -31,12 +31,12 @@ dg-init
set tests [lsort [glob -nocomplain $srcdir/$subdir/*.mm]]
# Main loop.
-dg-runtest $tests "-fgnu-runtime" $DEFAULT_OBJCXXFLAGS
+dg-runtest $tests "-fgnu-runtime -Wno-objc-root-class" $DEFAULT_OBJCXXFLAGS
# Darwin targets can also run code with the NeXT runtime.
# but Properties are not supported by the runtime lib before Darwin 9.
if [istarget "*-*-darwin\[9123\]*" ] {
- dg-runtest $tests "-fnext-runtime" $DEFAULT_OBJCXXFLAGS
+ dg-runtest $tests "-fnext-runtime -Wno-objc-root-class" $DEFAULT_OBJCXXFLAGS
}
# All done.
diff --git a/gcc/testsuite/obj-c++.dg/proto-lossage-1.mm b/gcc/testsuite/obj-c++.dg/proto-lossage-1.mm
index 2f7eb98..82cd053 100644
--- a/gcc/testsuite/obj-c++.dg/proto-lossage-1.mm
+++ b/gcc/testsuite/obj-c++.dg/proto-lossage-1.mm
@@ -2,6 +2,7 @@
may be lost, leading to superfluous warnings. */
/* Author: Ziemowit Laski <zlaski@apple.com>. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* One-line substitute for objc/objc.h */
typedef struct objc_object { struct objc_class *class_pointer; } *id;
diff --git a/gcc/testsuite/obj-c++.dg/proto-lossage-5.mm b/gcc/testsuite/obj-c++.dg/proto-lossage-5.mm
index 35c0956..2a30bc2 100644
--- a/gcc/testsuite/obj-c++.dg/proto-lossage-5.mm
+++ b/gcc/testsuite/obj-c++.dg/proto-lossage-5.mm
@@ -1,5 +1,6 @@
/* Do not lose references to forward-declared protocols. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
@class MyBaseClass;
@class MyClassThatFails;
@protocol _MyProtocol;
diff --git a/gcc/testsuite/obj-c++.dg/proto-qual-1.mm b/gcc/testsuite/obj-c++.dg/proto-qual-1.mm
index 7ef0e9a..b235064 100644
--- a/gcc/testsuite/obj-c++.dg/proto-qual-1.mm
+++ b/gcc/testsuite/obj-c++.dg/proto-qual-1.mm
@@ -3,6 +3,7 @@
/* { dg-do run } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <stdio.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/obj-c++.dg/protocol-inheritance-1.mm b/gcc/testsuite/obj-c++.dg/protocol-inheritance-1.mm
index 5241b29..c505c00 100644
--- a/gcc/testsuite/obj-c++.dg/protocol-inheritance-1.mm
+++ b/gcc/testsuite/obj-c++.dg/protocol-inheritance-1.mm
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
/* { dg-options "-Wno-protocol" } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/protocol-inheritance-2.mm b/gcc/testsuite/obj-c++.dg/protocol-inheritance-2.mm
index 74c9174..f2bc1ca 100644
--- a/gcc/testsuite/obj-c++.dg/protocol-inheritance-2.mm
+++ b/gcc/testsuite/obj-c++.dg/protocol-inheritance-2.mm
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/protocol-optional-1.mm b/gcc/testsuite/obj-c++.dg/protocol-optional-1.mm
index bc4a3d0..4ecf436 100644
--- a/gcc/testsuite/obj-c++.dg/protocol-optional-1.mm
+++ b/gcc/testsuite/obj-c++.dg/protocol-optional-1.mm
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/root-class-00.mm b/gcc/testsuite/obj-c++.dg/root-class-00.mm
new file mode 100644
index 0000000..f951b0d
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/root-class-00.mm
@@ -0,0 +1,10 @@
+/* Test Wobjc-root-class.
+ Note that we don't issue a warning unless the TU contains an implementation
+ for the class. */
+/* { dg-additional-options "-fsyntax-only " } */
+
+@interface ARootObject
+@end
+
+@implementation ARootObject /* { dg-warning {class 'ARootObject' defined without specifying a base class} } */
+@end
diff --git a/gcc/testsuite/obj-c++.dg/selector-1.mm b/gcc/testsuite/obj-c++.dg/selector-1.mm
index d34f8c8..b0cdc9c 100644
--- a/gcc/testsuite/obj-c++.dg/selector-1.mm
+++ b/gcc/testsuite/obj-c++.dg/selector-1.mm
@@ -3,6 +3,7 @@
/* Author: Ziemowit Laski <zlaski@apple.com>. */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
@interface Int1
+ (int)and_eq:(int)arg1 and:(int)arg2;
diff --git a/gcc/testsuite/obj-c++.dg/selector-2.mm b/gcc/testsuite/obj-c++.dg/selector-2.mm
index 840ee19..fa9ab41 100644
--- a/gcc/testsuite/obj-c++.dg/selector-2.mm
+++ b/gcc/testsuite/obj-c++.dg/selector-2.mm
@@ -1,6 +1,7 @@
/* Test that we don't ICE when issuing a -Wselector warning. */
/* { dg-options "-Wselector" } */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
diff --git a/gcc/testsuite/obj-c++.dg/selector-3.mm b/gcc/testsuite/obj-c++.dg/selector-3.mm
index a1321a7..0c98056 100644
--- a/gcc/testsuite/obj-c++.dg/selector-3.mm
+++ b/gcc/testsuite/obj-c++.dg/selector-3.mm
@@ -2,6 +2,7 @@
/* This is the "-fgnu-runtime" variant of objc.dg/selector-1.m. */
/* { dg-options "-Wselector -fgnu-runtime" } */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
typedef struct objc_object { struct objc_class *class_pointer; } *id;
typedef const struct objc_selector *SEL;
diff --git a/gcc/testsuite/obj-c++.dg/selector-4.mm b/gcc/testsuite/obj-c++.dg/selector-4.mm
index 690cc44..b6ddcbe 100644
--- a/gcc/testsuite/obj-c++.dg/selector-4.mm
+++ b/gcc/testsuite/obj-c++.dg/selector-4.mm
@@ -3,6 +3,7 @@
/* { dg-options "-Wselector -fnext-runtime" } */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
typedef struct objc_object { struct objc_class *class_pointer; } *id;
typedef struct objc_selector *SEL;
diff --git a/gcc/testsuite/obj-c++.dg/strings/strings.exp b/gcc/testsuite/obj-c++.dg/strings/strings.exp
index 1bfb3be..0243f24 100644
--- a/gcc/testsuite/obj-c++.dg/strings/strings.exp
+++ b/gcc/testsuite/obj-c++.dg/strings/strings.exp
@@ -34,11 +34,11 @@ dg-init
set tests [lsort [glob -nocomplain $srcdir/$subdir/*.mm]]
# Main loop.
-dg-runtest $tests "-fgnu-runtime" $DEFAULT_OBJCXXFLAGS
+dg-runtest $tests "-fgnu-runtime -Wno-objc-root-class" $DEFAULT_OBJCXXFLAGS
# darwin targets can also run code with the NeXT runtime.
if [istarget "*-*-darwin*" ] {
- dg-runtest $tests "-fnext-runtime" $DEFAULT_OBJCXXFLAGS
+ dg-runtest $tests "-fnext-runtime -Wno-objc-root-class" $DEFAULT_OBJCXXFLAGS
}
# All done.
diff --git a/gcc/testsuite/obj-c++.dg/stubify-1.mm b/gcc/testsuite/obj-c++.dg/stubify-1.mm
index a32e282..21de463 100644
--- a/gcc/testsuite/obj-c++.dg/stubify-1.mm
+++ b/gcc/testsuite/obj-c++.dg/stubify-1.mm
@@ -5,6 +5,7 @@
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
/* { dg-require-effective-target ilp32 } */
/* { dg-options "-Os -mdynamic-no-pic -fno-exceptions -mmacosx-version-min=10.4 -msymbol-stubs" } */
+// { dg-additional-options "-Wno-objc-root-class" }
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 69fea8d..cbc52b1 100644
--- a/gcc/testsuite/obj-c++.dg/stubify-2.mm
+++ b/gcc/testsuite/obj-c++.dg/stubify-2.mm
@@ -5,6 +5,7 @@
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
/* { dg-require-effective-target ilp32 } */
/* { dg-options "-mdynamic-no-pic -fdump-rtl-jump -mmacosx-version-min=10.4 -msymbol-stubs" } */
+// { dg-additional-options "-Wno-objc-root-class" }
typedef struct objc_object { } *id ;
int x = 41 ;
diff --git a/gcc/testsuite/obj-c++.dg/super-dealloc-1.mm b/gcc/testsuite/obj-c++.dg/super-dealloc-1.mm
index 0ab177b..39ddd01 100644
--- a/gcc/testsuite/obj-c++.dg/super-dealloc-1.mm
+++ b/gcc/testsuite/obj-c++.dg/super-dealloc-1.mm
@@ -2,6 +2,7 @@
/* Author: Ziemowit Laski <zlaski@apple.com> */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
@interface Foo {
void *isa;
diff --git a/gcc/testsuite/obj-c++.dg/super-dealloc-2.mm b/gcc/testsuite/obj-c++.dg/super-dealloc-2.mm
index 80dcf49..6dac31c 100644
--- a/gcc/testsuite/obj-c++.dg/super-dealloc-2.mm
+++ b/gcc/testsuite/obj-c++.dg/super-dealloc-2.mm
@@ -2,6 +2,7 @@
/* Author: Ziemowit Laski <zlaski@apple.com> */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
@interface Foo {
void *isa;
diff --git a/gcc/testsuite/obj-c++.dg/sync-3.mm b/gcc/testsuite/obj-c++.dg/sync-3.mm
index 95def43..2949d6a 100644
--- a/gcc/testsuite/obj-c++.dg/sync-3.mm
+++ b/gcc/testsuite/obj-c++.dg/sync-3.mm
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-options "-fobjc-exceptions" } */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
/* Test that the compiler is checking the argument of @synchronized(),
and produce errors when invalid types are used. */
diff --git a/gcc/testsuite/obj-c++.dg/syntax-error-2.mm b/gcc/testsuite/obj-c++.dg/syntax-error-2.mm
index ba8804a..bf4d5ff 100644
--- a/gcc/testsuite/obj-c++.dg/syntax-error-2.mm
+++ b/gcc/testsuite/obj-c++.dg/syntax-error-2.mm
@@ -1,4 +1,5 @@
/* Recover gracefully from a syntax error. */
+// { dg-additional-options "-Wno-objc-root-class" }
@implementation Whatever /* { dg-warning "cannot find interface declaration for .Whatever." } */
diff --git a/gcc/testsuite/obj-c++.dg/syntax-error-4.mm b/gcc/testsuite/obj-c++.dg/syntax-error-4.mm
index 0df0618..97587f9 100644
--- a/gcc/testsuite/obj-c++.dg/syntax-error-4.mm
+++ b/gcc/testsuite/obj-c++.dg/syntax-error-4.mm
@@ -1,5 +1,6 @@
/* Yet another stray infinite loop... */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
@interface t
{
diff --git a/gcc/testsuite/obj-c++.dg/syntax-error-7.mm b/gcc/testsuite/obj-c++.dg/syntax-error-7.mm
index 5bdccc7..c406d8f 100644
--- a/gcc/testsuite/obj-c++.dg/syntax-error-7.mm
+++ b/gcc/testsuite/obj-c++.dg/syntax-error-7.mm
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
@interface Foo
-(void) someMethod;
diff --git a/gcc/testsuite/obj-c++.dg/syntax-error-9.mm b/gcc/testsuite/obj-c++.dg/syntax-error-9.mm
index 1876c32..ad8837c 100644
--- a/gcc/testsuite/obj-c++.dg/syntax-error-9.mm
+++ b/gcc/testsuite/obj-c++.dg/syntax-error-9.mm
@@ -1,3 +1,4 @@
+// { dg-additional-options "-Wno-objc-root-class" }
@implementation SaturnDoc /* { dg-warning "cannot find interface declaration" } */
- read: (void*)aStream ggg /* { dg-error "expected .:. at end of input" } */
/* { dg-error "-:expected ..*. at end of input" "" { target *-*-* } .+1 } */
diff --git a/gcc/testsuite/obj-c++.dg/template-4.mm b/gcc/testsuite/obj-c++.dg/template-4.mm
index 5301df5..02795e7 100644
--- a/gcc/testsuite/obj-c++.dg/template-4.mm
+++ b/gcc/testsuite/obj-c++.dg/template-4.mm
@@ -4,6 +4,7 @@
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
/* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */
/* { dg-additional-sources "../objc-obj-c++-shared/nsconstantstring-class-impl.mm" } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <stdarg.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/obj-c++.dg/template-7.mm b/gcc/testsuite/obj-c++.dg/template-7.mm
index 8621abe..b3697a5 100644
--- a/gcc/testsuite/obj-c++.dg/template-7.mm
+++ b/gcc/testsuite/obj-c++.dg/template-7.mm
@@ -3,6 +3,7 @@
// Author: Fariborz Jahanian <fjahanian@apple.com>
// { dg-do compile }
// { dg-options "" }
+// { dg-additional-options "-Wno-objc-root-class" }
typedef struct objc_class *Class;
@interface Object
diff --git a/gcc/testsuite/obj-c++.dg/template-8.mm b/gcc/testsuite/obj-c++.dg/template-8.mm
index df215b8..1b9f4d1 100644
--- a/gcc/testsuite/obj-c++.dg/template-8.mm
+++ b/gcc/testsuite/obj-c++.dg/template-8.mm
@@ -5,6 +5,7 @@
/* { dg-do run } */
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <objc/objc.h>
#include <objc/runtime.h>
diff --git a/gcc/testsuite/obj-c++.dg/threedotthree-abi-1.mm b/gcc/testsuite/obj-c++.dg/threedotthree-abi-1.mm
index c481810..32f4fd8 100644
--- a/gcc/testsuite/obj-c++.dg/threedotthree-abi-1.mm
+++ b/gcc/testsuite/obj-c++.dg/threedotthree-abi-1.mm
@@ -3,6 +3,7 @@
/* { dg-do run { target *-*-darwin* } } */
/* { dg-require-effective-target ilp32 } */
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+// { dg-additional-options "-Wno-objc-root-class" }
#include <stdio.h>
#include <string.h>
diff --git a/gcc/testsuite/obj-c++.dg/torture/dg-torture.exp b/gcc/testsuite/obj-c++.dg/torture/dg-torture.exp
index c3d3f8e..4e46207 100644
--- a/gcc/testsuite/obj-c++.dg/torture/dg-torture.exp
+++ b/gcc/testsuite/obj-c++.dg/torture/dg-torture.exp
@@ -7,11 +7,11 @@ dg-init
# Gather a list of all tests.
set tests [lsort [glob -nocomplain $srcdir/$subdir/*.mm]]
-obj-c++-dg-runtest $tests "" "-fgnu-runtime"
+obj-c++-dg-runtest $tests "" "-fgnu-runtime -Wno-objc-root-class"
# darwin targets can also run code with the NeXT runtime.
if [istarget "*-*-darwin*" ] {
- obj-c++-dg-runtest $tests "" "-fnext-runtime"
+ obj-c++-dg-runtest $tests "" "-fnext-runtime -Wno-objc-root-class"
}
dg-finish
diff --git a/gcc/testsuite/obj-c++.dg/torture/strings/strings.exp b/gcc/testsuite/obj-c++.dg/torture/strings/strings.exp
index 401bc58..6181c30 100644
--- a/gcc/testsuite/obj-c++.dg/torture/strings/strings.exp
+++ b/gcc/testsuite/obj-c++.dg/torture/strings/strings.exp
@@ -24,11 +24,11 @@ dg-init
# Gather a list of all tests.
set tests [lsort [glob -nocomplain $srcdir/$subdir/*.mm]]
-obj-c++-dg-runtest $tests "" "-fgnu-runtime"
+obj-c++-dg-runtest $tests "" "-fgnu-runtime -Wno-objc-root-class"
# Darwin targets can also run code with the NeXT runtime.
if [istarget "*-*-darwin*" ] {
- obj-c++-dg-runtest $tests "" "-fnext-runtime"
+ obj-c++-dg-runtest $tests "" "-fnext-runtime -Wno-objc-root-class"
}
dg-finish
diff --git a/gcc/testsuite/obj-c++.dg/try-catch-12.mm b/gcc/testsuite/obj-c++.dg/try-catch-12.mm
index e08f321..6a60805 100644
--- a/gcc/testsuite/obj-c++.dg/try-catch-12.mm
+++ b/gcc/testsuite/obj-c++.dg/try-catch-12.mm
@@ -4,6 +4,7 @@
/* { dg-options "-fobjc-exceptions" } */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
typedef volatile int IOSharedLockData;
diff --git a/gcc/testsuite/obj-c++.dg/try-catch-13.mm b/gcc/testsuite/obj-c++.dg/try-catch-13.mm
index 050d811..0e6f01b 100644
--- a/gcc/testsuite/obj-c++.dg/try-catch-13.mm
+++ b/gcc/testsuite/obj-c++.dg/try-catch-13.mm
@@ -4,6 +4,7 @@
/* { dg-options "-fobjc-exceptions" } */
/* { dg-do compile } */
+// { dg-additional-options "-Wno-objc-root-class" }
@interface TestMyTests
- (void) testSpoon;
diff --git a/gcc/testsuite/objc.dg/anon-1.m b/gcc/testsuite/objc.dg/anon-1.m
index 5f10f7d..5dab3fa 100644
--- a/gcc/testsuite/objc.dg/anon-1.m
+++ b/gcc/testsuite/objc.dg/anon-1.m
@@ -1,5 +1,6 @@
/* Test for graceful handling of anonymous ivars. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
@interface Foo {
unsigned char : 1;
diff --git a/gcc/testsuite/objc.dg/attributes/class-attribute-1.m b/gcc/testsuite/objc.dg/attributes/class-attribute-1.m
index 3444760..93e5d7f 100644
--- a/gcc/testsuite/objc.dg/attributes/class-attribute-1.m
+++ b/gcc/testsuite/objc.dg/attributes/class-attribute-1.m
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* Test deprecate attribute with an @interface declaration. */
diff --git a/gcc/testsuite/objc.dg/attributes/class-attribute-2.m b/gcc/testsuite/objc.dg/attributes/class-attribute-2.m
index 2e1bacb..f8137ff 100644
--- a/gcc/testsuite/objc.dg/attributes/class-attribute-2.m
+++ b/gcc/testsuite/objc.dg/attributes/class-attribute-2.m
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/objc.dg/attributes/class-attribute-3.m b/gcc/testsuite/objc.dg/attributes/class-attribute-3.m
index 6cc5d4e..7c3b3b0 100644
--- a/gcc/testsuite/objc.dg/attributes/class-attribute-3.m
+++ b/gcc/testsuite/objc.dg/attributes/class-attribute-3.m
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* Test that you get a warning when an unknown class attribute is ignored. */
diff --git a/gcc/testsuite/objc.dg/attributes/method-deprecated-1.m b/gcc/testsuite/objc.dg/attributes/method-deprecated-1.m
index 8343856..68e8373 100644
--- a/gcc/testsuite/objc.dg/attributes/method-deprecated-1.m
+++ b/gcc/testsuite/objc.dg/attributes/method-deprecated-1.m
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/objc.dg/attributes/method-deprecated-2.m b/gcc/testsuite/objc.dg/attributes/method-deprecated-2.m
index 1e5d87f..8fb0e15 100644
--- a/gcc/testsuite/objc.dg/attributes/method-deprecated-2.m
+++ b/gcc/testsuite/objc.dg/attributes/method-deprecated-2.m
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/objc.dg/attributes/method-deprecated-3.m b/gcc/testsuite/objc.dg/attributes/method-deprecated-3.m
index 5c715a2..efa2d34 100644
--- a/gcc/testsuite/objc.dg/attributes/method-deprecated-3.m
+++ b/gcc/testsuite/objc.dg/attributes/method-deprecated-3.m
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/objc.dg/attributes/method-format-1.m b/gcc/testsuite/objc.dg/attributes/method-format-1.m
index 9ff34f9..d3bb997 100644
--- a/gcc/testsuite/objc.dg/attributes/method-format-1.m
+++ b/gcc/testsuite/objc.dg/attributes/method-format-1.m
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
/* { dg-do compile } */
/* { dg-options "-Wall" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/objc.dg/attributes/method-nonnull-1.m b/gcc/testsuite/objc.dg/attributes/method-nonnull-1.m
index fe5f885..a3bfd9b 100644
--- a/gcc/testsuite/objc.dg/attributes/method-nonnull-1.m
+++ b/gcc/testsuite/objc.dg/attributes/method-nonnull-1.m
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, May 2011. */
/* { dg-do compile } */
/* { dg-options "-Wall" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/objc.dg/attributes/method-noreturn-1.m b/gcc/testsuite/objc.dg/attributes/method-noreturn-1.m
index a83048b..413a0be 100644
--- a/gcc/testsuite/objc.dg/attributes/method-noreturn-1.m
+++ b/gcc/testsuite/objc.dg/attributes/method-noreturn-1.m
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/objc.dg/attributes/method-sentinel-1.m b/gcc/testsuite/objc.dg/attributes/method-sentinel-1.m
index e2abb1e..f89c981 100644
--- a/gcc/testsuite/objc.dg/attributes/method-sentinel-1.m
+++ b/gcc/testsuite/objc.dg/attributes/method-sentinel-1.m
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, October 2010. */
/* { dg-do compile } */
/* { dg-options "-Wall" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/objc.dg/attributes/nsobject-01.m b/gcc/testsuite/objc.dg/attributes/nsobject-01.m
index 5b56849..1f33150 100644
--- a/gcc/testsuite/objc.dg/attributes/nsobject-01.m
+++ b/gcc/testsuite/objc.dg/attributes/nsobject-01.m
@@ -1,5 +1,6 @@
/* Test handling of the NSObject attribute. */
/* { dg-additional-options "-fsyntax-only " } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
typedef struct AnObj * __attribute__ ((NSObject)) AnObjRef;
typedef struct AnObj * __attribute__ ((__NSObject__)) AnotherObjRef;
diff --git a/gcc/testsuite/objc.dg/attributes/nullability-00.m b/gcc/testsuite/objc.dg/attributes/nullability-00.m
new file mode 100644
index 0000000..81c0145
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/nullability-00.m
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class -fsyntax-only" } */
+
+__attribute__((objc_nullability(0))) id a;
+__attribute__((objc_nullability(4))) id e_1; /* { dg-error {'objc_nullability' attribute argument '4' is not an integer constant between 0 and 3} } */
+__attribute__((objc_nullability(-22))) id e_2; /* { dg-error {'objc_nullability' attribute argument '-22' is not an integer constant between 0 and 3} } */
+__attribute__((objc_nullability("unspecified"))) id b;
+__attribute__((objc_nullability("nullable"))) id c;
+__attribute__((objc_nullability("nonnull"))) id d;
+__attribute__((objc_nullability("resettable"))) id e;
+__attribute__((objc_nullability("nonsense"))) id e_3; /* { dg-error {'objc_nullability' attribute argument '"nonsense"' is not recognised} } */
+__attribute__((objc_nullability(noGoingToWork))) id e_4; /* { dg-error {'noGoingToWork' undeclared here} } */
+
+@interface MyRoot
+{
+ __attribute__((objc_nullability(0))) id iv_a;
+ __attribute__((objc_nullability(3))) struct { int bad_a; } s;/* { dg-error {'objc_nullability' cannot be applied to non-pointer type 'struct <anonymous>'} } */
+ __attribute__((objc_nullability("resettable"))) int iv_b;/* { dg-error {'objc_nullability' cannot be applied to non-pointer type 'int'} } */
+}
+@end
diff --git a/gcc/testsuite/objc.dg/attributes/objc-exception-1.m b/gcc/testsuite/objc.dg/attributes/objc-exception-1.m
index e7f6f85..19e5ade 100644
--- a/gcc/testsuite/objc.dg/attributes/objc-exception-1.m
+++ b/gcc/testsuite/objc.dg/attributes/objc-exception-1.m
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, February 2011. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* Test that the 'objc_exception' attribute is accepted for
@interfaces, but not for anything else. */
diff --git a/gcc/testsuite/objc.dg/attributes/parameter-attribute-1.m b/gcc/testsuite/objc.dg/attributes/parameter-attribute-1.m
index 8263df6..d6ebaf2 100644
--- a/gcc/testsuite/objc.dg/attributes/parameter-attribute-1.m
+++ b/gcc/testsuite/objc.dg/attributes/parameter-attribute-1.m
@@ -1,6 +1,7 @@
/* Test __attribute__((unused)) for an Objective-C method parameter. */
/* { dg-do compile } */
/* { dg-options "-Wunused-parameter" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/objc.dg/attributes/parameter-attribute-2.m b/gcc/testsuite/objc.dg/attributes/parameter-attribute-2.m
index 99c5a30..637846d 100644
--- a/gcc/testsuite/objc.dg/attributes/parameter-attribute-2.m
+++ b/gcc/testsuite/objc.dg/attributes/parameter-attribute-2.m
@@ -1,5 +1,6 @@
/* Test that we get warnings for unrecognized attributes. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/objc.dg/attributes/proto-attribute-1.m b/gcc/testsuite/objc.dg/attributes/proto-attribute-1.m
index a852a7a..03726dc 100644
--- a/gcc/testsuite/objc.dg/attributes/proto-attribute-1.m
+++ b/gcc/testsuite/objc.dg/attributes/proto-attribute-1.m
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/objc.dg/attributes/proto-attribute-2.m b/gcc/testsuite/objc.dg/attributes/proto-attribute-2.m
index b23b81d..6a73d24 100644
--- a/gcc/testsuite/objc.dg/attributes/proto-attribute-2.m
+++ b/gcc/testsuite/objc.dg/attributes/proto-attribute-2.m
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* Test deprecate attribute with a forward declarations of
@protocol. */
diff --git a/gcc/testsuite/objc.dg/attributes/proto-attribute-3.m b/gcc/testsuite/objc.dg/attributes/proto-attribute-3.m
index 2be286e..ad6d0c8 100644
--- a/gcc/testsuite/objc.dg/attributes/proto-attribute-3.m
+++ b/gcc/testsuite/objc.dg/attributes/proto-attribute-3.m
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* Test deprecate attribute with normal @protocol declarations. */
diff --git a/gcc/testsuite/objc.dg/attributes/proto-attribute-4.m b/gcc/testsuite/objc.dg/attributes/proto-attribute-4.m
index 226fd68..8d34ebd 100644
--- a/gcc/testsuite/objc.dg/attributes/proto-attribute-4.m
+++ b/gcc/testsuite/objc.dg/attributes/proto-attribute-4.m
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* Test that you get a warning when an unknown protocol attribute is ignored. */
diff --git a/gcc/testsuite/objc.dg/attributes/root-class-01.m b/gcc/testsuite/objc.dg/attributes/root-class-01.m
new file mode 100644
index 0000000..84da94a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/root-class-01.m
@@ -0,0 +1,11 @@
+/* Test Wobjc-root-class warning is suppressed by the objc_root_class attr.
+ Note that we don't issue a warning unless the TU contains an implementation
+ for the class. This should compile without warning. */
+/* { dg-additional-options "-fsyntax-only " } */
+
+__attribute__((objc_root_class))
+@interface ARootObject
+@end
+
+@implementation ARootObject
+@end
diff --git a/gcc/testsuite/objc.dg/bitfield-2.m b/gcc/testsuite/objc.dg/bitfield-2.m
index 7e8147a..b28c81e 100644
--- a/gcc/testsuite/objc.dg/bitfield-2.m
+++ b/gcc/testsuite/objc.dg/bitfield-2.m
@@ -4,6 +4,7 @@
/* { dg-options "-fsigned-char" } */
/* { dg-do run { target *-*-darwin* } } */
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
typedef struct objc_object { struct objc_class *class_pointer; } *id;
diff --git a/gcc/testsuite/objc.dg/break-in-ifstmt.m b/gcc/testsuite/objc.dg/break-in-ifstmt.m
index 8968494..6176832 100644
--- a/gcc/testsuite/objc.dg/break-in-ifstmt.m
+++ b/gcc/testsuite/objc.dg/break-in-ifstmt.m
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
@interface foo
- (void) test;
diff --git a/gcc/testsuite/objc.dg/class-1.m b/gcc/testsuite/objc.dg/class-1.m
index 0504937..64383f2 100644
--- a/gcc/testsuite/objc.dg/class-1.m
+++ b/gcc/testsuite/objc.dg/class-1.m
@@ -1,5 +1,6 @@
/* Redeclarations of class names. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
typedef int foo; /* { dg-line foo_def } */
@@ -8,6 +9,9 @@ typedef int foo; /* { dg-line foo_def } */
typedef int bar; /* { dg-line bar_def } */
+#if defined(__has_attribute) && __has_attribute(objc_root_class)
+__attribute__((objc_root_class))
+#endif
@interface bar
@end /* { dg-error "redeclared as different kind of symbol" } */
/* { dg-error "previous declaration of" "" { target *-*-* } bar_def } */
diff --git a/gcc/testsuite/objc.dg/class-extension-1.m b/gcc/testsuite/objc.dg/class-extension-1.m
index 5c89a98..9d6658a 100644
--- a/gcc/testsuite/objc.dg/class-extension-1.m
+++ b/gcc/testsuite/objc.dg/class-extension-1.m
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* This test tests the basic of class extensions. */
diff --git a/gcc/testsuite/objc.dg/class-extension-2.m b/gcc/testsuite/objc.dg/class-extension-2.m
index 7f55b60..293facb1 100644
--- a/gcc/testsuite/objc.dg/class-extension-2.m
+++ b/gcc/testsuite/objc.dg/class-extension-2.m
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* This test tests class extensions and protocols. */
diff --git a/gcc/testsuite/objc.dg/class-extension-3.m b/gcc/testsuite/objc.dg/class-extension-3.m
index 69e5705..51fe5ee 100644
--- a/gcc/testsuite/objc.dg/class-extension-3.m
+++ b/gcc/testsuite/objc.dg/class-extension-3.m
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* This test tests warnings on class extensions. */
diff --git a/gcc/testsuite/objc.dg/class-extension-4.m b/gcc/testsuite/objc.dg/class-extension-4.m
index 692a0fc..5d367d4 100644
--- a/gcc/testsuite/objc.dg/class-extension-4.m
+++ b/gcc/testsuite/objc.dg/class-extension-4.m
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* This test tests you can not declare a class extension after the class @implementation. */
diff --git a/gcc/testsuite/objc.dg/class-protocol-1.m b/gcc/testsuite/objc.dg/class-protocol-1.m
index 59c8f82..34680c2 100644
--- a/gcc/testsuite/objc.dg/class-protocol-1.m
+++ b/gcc/testsuite/objc.dg/class-protocol-1.m
@@ -1,6 +1,7 @@
/* Check Class <protocol> types */
/* Author: David Ayers <d.ayers@inode.at> */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
#include "../objc-obj-c++-shared/runtime.h"
diff --git a/gcc/testsuite/objc.dg/comp-types-7.m b/gcc/testsuite/objc.dg/comp-types-7.m
index 526934f..6b796f0 100644
--- a/gcc/testsuite/objc.dg/comp-types-7.m
+++ b/gcc/testsuite/objc.dg/comp-types-7.m
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* We used to ICE because we removed the cast to List_linked*
in -[ListIndex_linked next]. */
diff --git a/gcc/testsuite/objc.dg/demangle-1.m b/gcc/testsuite/objc.dg/demangle-1.m
index 42b79a9..61e79a6 100644
--- a/gcc/testsuite/objc.dg/demangle-1.m
+++ b/gcc/testsuite/objc.dg/demangle-1.m
@@ -1,6 +1,7 @@
/* Test demangling an Objective-C method. */
/* { dg-do run } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <string.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/objc.dg/duplicate-class-1.m b/gcc/testsuite/objc.dg/duplicate-class-1.m
index 30a18ff..7992ebf 100644
--- a/gcc/testsuite/objc.dg/duplicate-class-1.m
+++ b/gcc/testsuite/objc.dg/duplicate-class-1.m
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* Test that a duplicated @implementation for the same class does not
crash the compiler. */
diff --git a/gcc/testsuite/objc.dg/encode-6-next.m b/gcc/testsuite/objc.dg/encode-6-next.m
index c3d9226..18ee15d 100644
--- a/gcc/testsuite/objc.dg/encode-6-next.m
+++ b/gcc/testsuite/objc.dg/encode-6-next.m
@@ -2,6 +2,7 @@
/* Author: Ziemowit Laski <zlaski@apple.com> */
/* { dg-do compile } */
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
struct Cxx {
const struct Cxx *next;
diff --git a/gcc/testsuite/objc.dg/encode-6.m b/gcc/testsuite/objc.dg/encode-6.m
index 291a41e..9e9e492 100644
--- a/gcc/testsuite/objc.dg/encode-6.m
+++ b/gcc/testsuite/objc.dg/encode-6.m
@@ -2,6 +2,7 @@
/* Author: Ziemowit Laski <zlaski@apple.com> */
/* { dg-do compile } */
/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
struct Cxx {
const struct Cxx *next;
diff --git a/gcc/testsuite/objc.dg/enhanced-proto-2.m b/gcc/testsuite/objc.dg/enhanced-proto-2.m
index c196b51..ca99445 100644
--- a/gcc/testsuite/objc.dg/enhanced-proto-2.m
+++ b/gcc/testsuite/objc.dg/enhanced-proto-2.m
@@ -1,5 +1,6 @@
/* Test use of @optional/@required keywords in @protocol class. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
@protocol MyProto1
@optional
diff --git a/gcc/testsuite/objc.dg/exceptions-1.m b/gcc/testsuite/objc.dg/exceptions-1.m
index 0f3b7e8..1e86177 100644
--- a/gcc/testsuite/objc.dg/exceptions-1.m
+++ b/gcc/testsuite/objc.dg/exceptions-1.m
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-options "-fobjc-exceptions" } */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* This test checks the syntax @catch (...) which catches any
exceptions. At the moment, @catch (...) is identical to @catch (id
diff --git a/gcc/testsuite/objc.dg/exceptions-3.m b/gcc/testsuite/objc.dg/exceptions-3.m
index 69a6494..bedaf53 100644
--- a/gcc/testsuite/objc.dg/exceptions-3.m
+++ b/gcc/testsuite/objc.dg/exceptions-3.m
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-options "-fobjc-exceptions" } */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* Test that the compiler is checking the argument of @catch(), and
produce errors when invalid types are used. */
diff --git a/gcc/testsuite/objc.dg/exceptions-4.m b/gcc/testsuite/objc.dg/exceptions-4.m
index bbdb741..5d77ffa 100644
--- a/gcc/testsuite/objc.dg/exceptions-4.m
+++ b/gcc/testsuite/objc.dg/exceptions-4.m
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-options "-fobjc-exceptions" } */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* Test warnings when parsing syntax errors in @catch(). */
diff --git a/gcc/testsuite/objc.dg/exceptions-5.m b/gcc/testsuite/objc.dg/exceptions-5.m
index 55ef0f3..31796bc 100644
--- a/gcc/testsuite/objc.dg/exceptions-5.m
+++ b/gcc/testsuite/objc.dg/exceptions-5.m
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-options "-fobjc-exceptions" } */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* Test that you can use an unnamed argument with @catch. This test is the same
as exceptions-3.m, but with no name for @catch arguments. */
diff --git a/gcc/testsuite/objc.dg/fobjc-std-1.m b/gcc/testsuite/objc.dg/fobjc-std-1.m
index 9a15b8a..729f65c 100644
--- a/gcc/testsuite/objc.dg/fobjc-std-1.m
+++ b/gcc/testsuite/objc.dg/fobjc-std-1.m
@@ -1,6 +1,7 @@
/* Test warnings when using -fobjc-std=objc1. */
/* { dg-do compile } */
/* { dg-options "-fobjc-std=objc1" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
@@ -29,8 +30,8 @@
@end
__attribute__ ((deprecated))
-@interface MyRootClass2
-{ /* { dg-error "class attributes are not available in Objective.C 1.0" } */
+@interface MyRootClass2 /* { dg-error "class attributes are not available in Objective.C 1.0" } */
+{
Class isa;
}
@end
diff --git a/gcc/testsuite/objc.dg/foreach-2.m b/gcc/testsuite/objc.dg/foreach-2.m
index 93bc902..ccce557 100644
--- a/gcc/testsuite/objc.dg/foreach-2.m
+++ b/gcc/testsuite/objc.dg/foreach-2.m
@@ -6,6 +6,7 @@
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
/* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */
/* { dg-additional-sources "../objc-obj-c++-shared/nsconstantstring-class-impl.m" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include "../objc-obj-c++-shared/TestsuiteObject.m"
#ifndef __NEXT_RUNTIME__
diff --git a/gcc/testsuite/objc.dg/foreach-4.m b/gcc/testsuite/objc.dg/foreach-4.m
index faee73b..2365609 100644
--- a/gcc/testsuite/objc.dg/foreach-4.m
+++ b/gcc/testsuite/objc.dg/foreach-4.m
@@ -6,6 +6,7 @@
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
/* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */
/* { dg-additional-sources "../objc-obj-c++-shared/nsconstantstring-class-impl.m" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#import "../objc-obj-c++-shared/TestsuiteObject.m"
#ifndef __NEXT_RUNTIME__
diff --git a/gcc/testsuite/objc.dg/foreach-5.m b/gcc/testsuite/objc.dg/foreach-5.m
index dce26fa..1bcb10b 100644
--- a/gcc/testsuite/objc.dg/foreach-5.m
+++ b/gcc/testsuite/objc.dg/foreach-5.m
@@ -6,6 +6,7 @@
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
/* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */
/* { dg-additional-sources "../objc-obj-c++-shared/nsconstantstring-class-impl.m" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#import "../objc-obj-c++-shared/TestsuiteObject.m"
#ifndef __NEXT_RUNTIME__
diff --git a/gcc/testsuite/objc.dg/fsyntax-only.m b/gcc/testsuite/objc.dg/fsyntax-only.m
index 54a879e..70ea8ac 100644
--- a/gcc/testsuite/objc.dg/fsyntax-only.m
+++ b/gcc/testsuite/objc.dg/fsyntax-only.m
@@ -2,6 +2,9 @@
/* { dg-do compile } */
/* { dg-options "-fsyntax-only" } */
+#if defined(__has_attribute) && __has_attribute(objc_root_class)
+__attribute__((objc_root_class))
+#endif
@interface foo
-(void) my_method:(int) i with:(int) j;
@end
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-class-meta.m b/gcc/testsuite/objc.dg/gnu-api-2-class-meta.m
index 3a85b16..6c1c76a 100644
--- a/gcc/testsuite/objc.dg/gnu-api-2-class-meta.m
+++ b/gcc/testsuite/objc.dg/gnu-api-2-class-meta.m
@@ -20,6 +20,7 @@
/* { dg-do run } */
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* { dg-additional-options "-DOBJC_OLD_DISPATCH_PROTOTYPES" { target { *-*-darwin* } } } */
/* To get the modern GNU Objective-C Runtime API, you include
@@ -29,9 +30,6 @@
#include <stdio.h>
#include <string.h>
-#if __has_attribute(objc_root_class)
-__attribute__((objc_root_class))
-#endif
@interface MyRootClass
{ Class isa; }
+ alloc;
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-class.m b/gcc/testsuite/objc.dg/gnu-api-2-class.m
index eade0dc..d11dae0 100644
--- a/gcc/testsuite/objc.dg/gnu-api-2-class.m
+++ b/gcc/testsuite/objc.dg/gnu-api-2-class.m
@@ -7,6 +7,7 @@
/* { dg-do run } */
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* { dg-additional-options "-DOBJC_OLD_DISPATCH_PROTOTYPES" { target { *-*-darwin* } } } */
/* To get the modern GNU Objective-C Runtime API, you include
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-ivar.m b/gcc/testsuite/objc.dg/gnu-api-2-ivar.m
index 19ac004..072d265 100644
--- a/gcc/testsuite/objc.dg/gnu-api-2-ivar.m
+++ b/gcc/testsuite/objc.dg/gnu-api-2-ivar.m
@@ -5,6 +5,7 @@
/* { dg-do run } */
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-method.m b/gcc/testsuite/objc.dg/gnu-api-2-method.m
index 0c4fe4f..ea1da8d 100644
--- a/gcc/testsuite/objc.dg/gnu-api-2-method.m
+++ b/gcc/testsuite/objc.dg/gnu-api-2-method.m
@@ -5,6 +5,7 @@
/* { dg-do run } */
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-objc.m b/gcc/testsuite/objc.dg/gnu-api-2-objc.m
index 1b4ce8e..e9ec5d7 100644
--- a/gcc/testsuite/objc.dg/gnu-api-2-objc.m
+++ b/gcc/testsuite/objc.dg/gnu-api-2-objc.m
@@ -9,6 +9,7 @@
systems that don't have the V2 APis). XFAILing the run is not useful
since it will XPASS on the sub-set that works. */
/* { dg-skip-if "Incompatible" { *-*-darwin* } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-objc_msg_lookup.m b/gcc/testsuite/objc.dg/gnu-api-2-objc_msg_lookup.m
index 5751f3f..d417225 100644
--- a/gcc/testsuite/objc.dg/gnu-api-2-objc_msg_lookup.m
+++ b/gcc/testsuite/objc.dg/gnu-api-2-objc_msg_lookup.m
@@ -5,6 +5,7 @@
/* { dg-do run } */
/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-object.m b/gcc/testsuite/objc.dg/gnu-api-2-object.m
index 3d4d444..20c4342 100644
--- a/gcc/testsuite/objc.dg/gnu-api-2-object.m
+++ b/gcc/testsuite/objc.dg/gnu-api-2-object.m
@@ -5,6 +5,7 @@
/* { dg-do run } */
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-property.m b/gcc/testsuite/objc.dg/gnu-api-2-property.m
index 12c0d8b9..0ef4d79 100644
--- a/gcc/testsuite/objc.dg/gnu-api-2-property.m
+++ b/gcc/testsuite/objc.dg/gnu-api-2-property.m
@@ -4,6 +4,7 @@
/* { dg-do run } */
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-protocol.m b/gcc/testsuite/objc.dg/gnu-api-2-protocol.m
index a34d74c..682adcd 100644
--- a/gcc/testsuite/objc.dg/gnu-api-2-protocol.m
+++ b/gcc/testsuite/objc.dg/gnu-api-2-protocol.m
@@ -5,6 +5,7 @@
/* { dg-do run } */
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-resolve-method.m b/gcc/testsuite/objc.dg/gnu-api-2-resolve-method.m
index a387709..6eaa3dd 100644
--- a/gcc/testsuite/objc.dg/gnu-api-2-resolve-method.m
+++ b/gcc/testsuite/objc.dg/gnu-api-2-resolve-method.m
@@ -5,6 +5,7 @@
/* { dg-do run } */
/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-sel.m b/gcc/testsuite/objc.dg/gnu-api-2-sel.m
index b71fdfa..bc581be 100644
--- a/gcc/testsuite/objc.dg/gnu-api-2-sel.m
+++ b/gcc/testsuite/objc.dg/gnu-api-2-sel.m
@@ -4,6 +4,7 @@
/* { dg-do run } */
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* To get the modern GNU Objective-C Runtime API, you include
objc/runtime.h. */
diff --git a/gcc/testsuite/objc.dg/incomplete-type-1.m b/gcc/testsuite/objc.dg/incomplete-type-1.m
index f1e875f..60d0d8a 100644
--- a/gcc/testsuite/objc.dg/incomplete-type-1.m
+++ b/gcc/testsuite/objc.dg/incomplete-type-1.m
@@ -6,6 +6,9 @@
enum type1;
struct type2;
+#if defined(__has_attribute) && __has_attribute(objc_root_class)
+__attribute__((objc_root_class))
+#endif
@interface MyObject
- (void) method1: (enum type1)argument;
- (void) method2: (struct type2)argument;
diff --git a/gcc/testsuite/objc.dg/instancetype-0.m b/gcc/testsuite/objc.dg/instancetype-0.m
index 32cafdf..dc27926 100644
--- a/gcc/testsuite/objc.dg/instancetype-0.m
+++ b/gcc/testsuite/objc.dg/instancetype-0.m
@@ -6,6 +6,9 @@
extern id class_createInstance (id, int);
extern id class_getSuperclass (id);
+#if defined(__has_attribute) && __has_attribute(objc_root_class)
+__attribute__((objc_root_class))
+#endif
@interface MyObject
{
Class isa;
diff --git a/gcc/testsuite/objc.dg/invalid-method-2.m b/gcc/testsuite/objc.dg/invalid-method-2.m
index cb18de9..0a4bd63 100644
--- a/gcc/testsuite/objc.dg/invalid-method-2.m
+++ b/gcc/testsuite/objc.dg/invalid-method-2.m
@@ -3,6 +3,9 @@
/* Test that using an invalid type in a method declaration produces a
friendly error without a compiler crash. */
+#if defined(__has_attribute) && __has_attribute(objc_root_class)
+__attribute__((objc_root_class))
+#endif
@interface MyClass
@end
diff --git a/gcc/testsuite/objc.dg/ivar-invalid-type-1.m b/gcc/testsuite/objc.dg/ivar-invalid-type-1.m
index 3e7785d..98bf36e 100644
--- a/gcc/testsuite/objc.dg/ivar-invalid-type-1.m
+++ b/gcc/testsuite/objc.dg/ivar-invalid-type-1.m
@@ -1,6 +1,9 @@
/* { dg-do compile } */
#include <objc/objc.h>
+#if defined(__has_attribute) && __has_attribute(objc_root_class)
+__attribute__((objc_root_class))
+#endif
@interface MyRootClass
{
Class isa;
diff --git a/gcc/testsuite/objc.dg/ivar-problem-1.m b/gcc/testsuite/objc.dg/ivar-problem-1.m
index 4a87768..0d5bb66 100644
--- a/gcc/testsuite/objc.dg/ivar-problem-1.m
+++ b/gcc/testsuite/objc.dg/ivar-problem-1.m
@@ -10,6 +10,9 @@
#include <stdlib.h>
#include <objc/objc.h>
+#if defined(__has_attribute) && __has_attribute(objc_root_class)
+__attribute__((objc_root_class))
+#endif
@interface MyRootClass1
{
Class isa;
@@ -36,6 +39,9 @@
@end
+#if defined(__has_attribute) && __has_attribute(objc_root_class)
+__attribute__((objc_root_class))
+#endif
@interface MyRootClass2
{
Class isa;
diff --git a/gcc/testsuite/objc.dg/ivar-scope-1.m b/gcc/testsuite/objc.dg/ivar-scope-1.m
index 34443a4..64d275b 100644
--- a/gcc/testsuite/objc.dg/ivar-scope-1.m
+++ b/gcc/testsuite/objc.dg/ivar-scope-1.m
@@ -3,6 +3,9 @@
/* { dg-do compile } */
#include <objc/objc.h>
+#if defined(__has_attribute) && __has_attribute(objc_root_class)
+__attribute__((objc_root_class))
+#endif
@interface MyClass
{
int someivar;
diff --git a/gcc/testsuite/objc.dg/ivar-scope-2.m b/gcc/testsuite/objc.dg/ivar-scope-2.m
index ff795d0..1149d73 100644
--- a/gcc/testsuite/objc.dg/ivar-scope-2.m
+++ b/gcc/testsuite/objc.dg/ivar-scope-2.m
@@ -4,6 +4,9 @@
/* { dg-additional-options "-fno-local-ivars" } */
#include <objc/objc.h>
+#if defined(__has_attribute) && __has_attribute(objc_root_class)
+__attribute__((objc_root_class))
+#endif
@interface MyClass
{
int someivar;
diff --git a/gcc/testsuite/objc.dg/ivar-scope-4.m b/gcc/testsuite/objc.dg/ivar-scope-4.m
index 5fc29f9..df1c892 100644
--- a/gcc/testsuite/objc.dg/ivar-scope-4.m
+++ b/gcc/testsuite/objc.dg/ivar-scope-4.m
@@ -1,7 +1,8 @@
/* Test instance variable scope. */
/* Author: Dimitris Papavasiliou <dpapavas@gmail.com>. */
/* { dg-do run } */
-/* { dg-additional-options "-Wno-shadow-ivar -fno-local-ivars" } */
+/* { dg-additional-options "-Wno-shadow-ivar -fno-local-ivars -Wno-objc-root-class" } */
+
#include "../objc-obj-c++-shared/runtime.h"
#include <objc/objc.h>
diff --git a/gcc/testsuite/objc.dg/ivar-visibility-1.m b/gcc/testsuite/objc.dg/ivar-visibility-1.m
index 5a22259..79d791e 100644
--- a/gcc/testsuite/objc.dg/ivar-visibility-1.m
+++ b/gcc/testsuite/objc.dg/ivar-visibility-1.m
@@ -1,6 +1,7 @@
/* Test instance variable visibility. */
/* Author: Dimitris Papavasiliou <dpapavas@gmail.com>. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
@interface MySuperClass
diff --git a/gcc/testsuite/objc.dg/ivar-visibility-2.m b/gcc/testsuite/objc.dg/ivar-visibility-2.m
index eb41c8f..6ddcb5b 100644
--- a/gcc/testsuite/objc.dg/ivar-visibility-2.m
+++ b/gcc/testsuite/objc.dg/ivar-visibility-2.m
@@ -1,7 +1,7 @@
/* Test instance variable visibility. */
/* Author: Dimitris Papavasiliou <dpapavas@gmail.com>. */
/* { dg-do compile } */
-/* { dg-additional-options "-fivar-visibility=protected" } */
+/* { dg-additional-options "-fivar-visibility=protected -Wno-objc-root-class" } */
#include <objc/objc.h>
@interface MySuperClass
diff --git a/gcc/testsuite/objc.dg/ivar-visibility-3.m b/gcc/testsuite/objc.dg/ivar-visibility-3.m
index ecc6f99..6403503 100644
--- a/gcc/testsuite/objc.dg/ivar-visibility-3.m
+++ b/gcc/testsuite/objc.dg/ivar-visibility-3.m
@@ -1,7 +1,7 @@
/* Test instance variable visibility. */
/* Author: Dimitris Papavasiliou <dpapavas@gmail.com>. */
/* { dg-do compile } */
-/* { dg-additional-options "-fivar-visibility=private" } */
+/* { dg-additional-options "-fivar-visibility=private -Wno-objc-root-class" } */
#include <objc/objc.h>
@interface MySuperClass
diff --git a/gcc/testsuite/objc.dg/ivar-visibility-4.m b/gcc/testsuite/objc.dg/ivar-visibility-4.m
index adfeb44..abd802b 100644
--- a/gcc/testsuite/objc.dg/ivar-visibility-4.m
+++ b/gcc/testsuite/objc.dg/ivar-visibility-4.m
@@ -1,7 +1,7 @@
/* Test instance variable visibility. */
/* Author: Dimitris Papavasiliou <dpapavas@gmail.com>. */
/* { dg-do compile } */
-/* { dg-additional-options "-fivar-visibility=public" } */
+/* { dg-additional-options "-fivar-visibility=public -Wno-objc-root-class" } */
#include <objc/objc.h>
@interface MySuperClass
diff --git a/gcc/testsuite/objc.dg/local-decl-1.m b/gcc/testsuite/objc.dg/local-decl-1.m
index 4a4bfdf..8356a8c 100644
--- a/gcc/testsuite/objc.dg/local-decl-1.m
+++ b/gcc/testsuite/objc.dg/local-decl-1.m
@@ -1,6 +1,7 @@
/* Test for hiding of ivars by local variables. */
/* Author: Ziemowit Laski <zlaski@apple.com>. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
@interface Sprite {
int a;
diff --git a/gcc/testsuite/objc.dg/lto/lto.exp b/gcc/testsuite/objc.dg/lto/lto.exp
index e563ecb..8a362d6 100644
--- a/gcc/testsuite/objc.dg/lto/lto.exp
+++ b/gcc/testsuite/objc.dg/lto/lto.exp
@@ -41,10 +41,10 @@ if { ![check_effective_target_lto] } {
global LTO_OPTIONS
set LTO_OPTIONS [list \
- {-O0 -flto -fgnu-runtime} \
- {-O2 -flto -fgnu-runtime} \
- {-O0 -flto -flto-partition=none -fgnu-runtime} \
- {-O2 -flto -flto-partition=none -fgnu-runtime} \
+ {-O0 -flto -fgnu-runtime -Wno-objc-root-class} \
+ {-O2 -flto -fgnu-runtime -Wno-objc-root-class } \
+ {-O0 -flto -flto-partition=none -fgnu-runtime -Wno-objc-root-class} \
+ {-O2 -flto -flto-partition=none -fgnu-runtime -Wno-objc-root-class} \
]
objc_init
@@ -67,10 +67,10 @@ foreach src $tests {
# darwin targets can also run code with the NeXT runtime.
if [istarget "*-*-darwin*" ] {
set LTO_OPTIONS [list \
- {-O0 -flto -fnext-runtime} \
- {-O2 -flto -fnext-runtime} \
- {-O0 -flto -flto-partition=none -fnext-runtime} \
- {-O2 -flto -flto-partition=none -fnext-runtime} \
+ {-O0 -flto -fnext-runtime -Wno-objc-root-class} \
+ {-O2 -flto -fnext-runtime -Wno-objc-root-class} \
+ {-O0 -flto -flto-partition=none -fnext-runtime -Wno-objc-root-class} \
+ {-O2 -flto -flto-partition=none -fnext-runtime -Wno-objc-root-class} \
]
foreach src $tests {
# If we're only testing specific files and this isn't one of them, skip it.
diff --git a/gcc/testsuite/objc.dg/lto/trivial-1_0.m b/gcc/testsuite/objc.dg/lto/trivial-1_0.m
index ba1b1aa..ca07fa4 100644
--- a/gcc/testsuite/objc.dg/lto/trivial-1_0.m
+++ b/gcc/testsuite/objc.dg/lto/trivial-1_0.m
@@ -1,5 +1,5 @@
/* { dg-lto-do run } */
-/* { dg-skip-if "" { "*-*-darwin*" && lp64 } } */
+
extern int printf (char *,...) ;
typedef struct objc_class *Class;
@@ -7,7 +7,7 @@ typedef struct objc_class *Class;
struct objc_class {
Class isa;
/* other stuff... */
-} ;
+};
@interface myRootObject {
@public
diff --git a/gcc/testsuite/objc.dg/method-1.m b/gcc/testsuite/objc.dg/method-1.m
index 194c64f..bd23493 100644
--- a/gcc/testsuite/objc.dg/method-1.m
+++ b/gcc/testsuite/objc.dg/method-1.m
@@ -1,5 +1,6 @@
/* Tests of duplication. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
@interface class1
- (int) meth1; /* { dg-message "previous declaration" } */
diff --git a/gcc/testsuite/objc.dg/method-12.m b/gcc/testsuite/objc.dg/method-12.m
index 411caac..b69a84f 100644
--- a/gcc/testsuite/objc.dg/method-12.m
+++ b/gcc/testsuite/objc.dg/method-12.m
@@ -1,5 +1,6 @@
/* Contributed by Igor Seleznev <selez@mail.ru>. */
/* This used to be broken. */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/objc.dg/method-13.m b/gcc/testsuite/objc.dg/method-13.m
index 592038b..3e0fde5 100644
--- a/gcc/testsuite/objc.dg/method-13.m
+++ b/gcc/testsuite/objc.dg/method-13.m
@@ -4,6 +4,7 @@
/* Author: Ziemowit Laski <zlaski@apple.com>. */
/* { dg-do run } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
#include "../objc-obj-c++-shared/runtime.h"
diff --git a/gcc/testsuite/objc.dg/method-14.m b/gcc/testsuite/objc.dg/method-14.m
index 9698225..bc3ee12 100644
--- a/gcc/testsuite/objc.dg/method-14.m
+++ b/gcc/testsuite/objc.dg/method-14.m
@@ -2,6 +2,7 @@
used as method selectors. */
/* Author: Ziemowit Laski <zlaski@apple.com>. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
@interface Foo
- (void)insertNewButtonImage:(Foo *)newButtonImage in:(Foo *)buttonCell;
diff --git a/gcc/testsuite/objc.dg/missing-proto-3.m b/gcc/testsuite/objc.dg/missing-proto-3.m
index 05e1a25..77aa3a3 100644
--- a/gcc/testsuite/objc.dg/missing-proto-3.m
+++ b/gcc/testsuite/objc.dg/missing-proto-3.m
@@ -2,7 +2,8 @@
In addition to not crashing :-), the compiler should properly handle
valid protocol references, even when they're mixed with invalid ones. */
/* { dg-do compile } */
-
+/* { dg-additional-options "-Wno-objc-root-class" } */
+
#include <objc/objc.h>
@protocol DefinedProtocol
diff --git a/gcc/testsuite/objc.dg/next-runtime-1.m b/gcc/testsuite/objc.dg/next-runtime-1.m
index c76b616..2ce798b 100644
--- a/gcc/testsuite/objc.dg/next-runtime-1.m
+++ b/gcc/testsuite/objc.dg/next-runtime-1.m
@@ -7,6 +7,7 @@
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
/* { dg-skip-if "" { *-*-* } { "-fobjc-abi-version=1" } { "" } } */
/* { dg-options "-fobjc-abi-version=0" { target { *-*-darwin* && { ! lp64 } } } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
@interface FooBar
- (void)boo;
diff --git a/gcc/testsuite/objc.dg/objc-foreach-1.m b/gcc/testsuite/objc.dg/objc-foreach-1.m
index 81f5dae..e4c958c 100644
--- a/gcc/testsuite/objc.dg/objc-foreach-1.m
+++ b/gcc/testsuite/objc.dg/objc-foreach-1.m
@@ -1,5 +1,6 @@
/* Syntax check for the new foreach statement. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
typedef struct objc_class *Class;
diff --git a/gcc/testsuite/objc.dg/objc-foreach-2.m b/gcc/testsuite/objc.dg/objc-foreach-2.m
index a01f004..0f79089 100644
--- a/gcc/testsuite/objc.dg/objc-foreach-2.m
+++ b/gcc/testsuite/objc.dg/objc-foreach-2.m
@@ -1,5 +1,6 @@
/* Syntax check for the new foreach statement. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
typedef struct objc_class *Class;
diff --git a/gcc/testsuite/objc.dg/objc-foreach-3.m b/gcc/testsuite/objc.dg/objc-foreach-3.m
index 922db39..b551ae3 100644
--- a/gcc/testsuite/objc.dg/objc-foreach-3.m
+++ b/gcc/testsuite/objc.dg/objc-foreach-3.m
@@ -1,6 +1,7 @@
/* Syntax check for the new foreach statement.
Use of declaration in loop-header without requiring c99 mode. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
typedef struct objc_class *Class;
diff --git a/gcc/testsuite/objc.dg/objc-nofilename-1.m b/gcc/testsuite/objc.dg/objc-nofilename-1.m
index 21e0c53..3ddaa64 100644
--- a/gcc/testsuite/objc.dg/objc-nofilename-1.m
+++ b/gcc/testsuite/objc.dg/objc-nofilename-1.m
@@ -1,5 +1,6 @@
/* Test to make sure that file name does not appear in the binary. */
/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/objc.dg/param-1.m b/gcc/testsuite/objc.dg/param-1.m
index 9dbf6e3..8e77811 100644
--- a/gcc/testsuite/objc.dg/param-1.m
+++ b/gcc/testsuite/objc.dg/param-1.m
@@ -1,6 +1,7 @@
/* Test if compiler detects object as an parameter to a method
or not. It is not valid. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
@interface foo
@end
diff --git a/gcc/testsuite/objc.dg/pch/pch.exp b/gcc/testsuite/objc.dg/pch/pch.exp
index 2da3d96..54c3e42 100644
--- a/gcc/testsuite/objc.dg/pch/pch.exp
+++ b/gcc/testsuite/objc.dg/pch/pch.exp
@@ -41,7 +41,7 @@ foreach test [lsort [glob -nocomplain $srcdir/$subdir/*.m]] {
# unlikely to make any difference to PCH. However, we do want to
# add -O0 -g, since users who want PCH usually want debugging and quick
# compiles.
- dg-flags-pch $subdir $test "-fgnu-runtime" $mytorture ".h"
+ dg-flags-pch $subdir $test "-fgnu-runtime -Wno-objc-root-class" $mytorture ".h"
}
if [istarget "*-*-darwin*" ] {
@@ -52,7 +52,7 @@ if [istarget "*-*-darwin*" ] {
# unlikely to make any difference to PCH. However, we do want to
# add -O0 -g, since users who want PCH usually want debugging and quick
# compiles.
- dg-flags-pch $subdir $test "-fnext-runtime" $mytorture ".h"
+ dg-flags-pch $subdir $test "-fnext-runtime -Wno-objc-root-class" $mytorture ".h"
}
}
diff --git a/gcc/testsuite/objc.dg/plugin/diagnostic-test-expressions-1.m b/gcc/testsuite/objc.dg/plugin/diagnostic-test-expressions-1.m
index 23a9302..7070b37 100644
--- a/gcc/testsuite/objc.dg/plugin/diagnostic-test-expressions-1.m
+++ b/gcc/testsuite/objc.dg/plugin/diagnostic-test-expressions-1.m
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O -fdiagnostics-show-caret" } */
+/* { dg-options "-O -fdiagnostics-show-caret -Wno-objc-root-class" } */
/* This file is similar to diagnostic-test-expressions-1.c
(see the notes in that file); this file adds test
diff --git a/gcc/testsuite/objc.dg/pr23214.m b/gcc/testsuite/objc.dg/pr23214.m
index 341a283..56cdc02 100644
--- a/gcc/testsuite/objc.dg/pr23214.m
+++ b/gcc/testsuite/objc.dg/pr23214.m
@@ -7,7 +7,7 @@
#if defined (__NEXT_RUNTIME__) && defined(__OBJC2__) \
&& defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) \
- && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1070
+ && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1080
#include <objc/Protocol.h>
#define OBJECT NSObject
#else
diff --git a/gcc/testsuite/objc.dg/pr23709.m b/gcc/testsuite/objc.dg/pr23709.m
index 7ff9b60..2bdcca5 100644
--- a/gcc/testsuite/objc.dg/pr23709.m
+++ b/gcc/testsuite/objc.dg/pr23709.m
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
@interface A
+(void)method: (int)parameter {} /* { dg-error "expected" } */
diff --git a/gcc/testsuite/objc.dg/private-1.m b/gcc/testsuite/objc.dg/private-1.m
index 7540fc5..5bd29e5 100644
--- a/gcc/testsuite/objc.dg/private-1.m
+++ b/gcc/testsuite/objc.dg/private-1.m
@@ -1,6 +1,7 @@
/* Test errors for accessing @private and @protected variables. */
/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
@interface MySuperClass
diff --git a/gcc/testsuite/objc.dg/private-2.m b/gcc/testsuite/objc.dg/private-2.m
index eff376a..d0646f5 100644
--- a/gcc/testsuite/objc.dg/private-2.m
+++ b/gcc/testsuite/objc.dg/private-2.m
@@ -1,6 +1,7 @@
/* Test warnings for shadowing instance variables. */
/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
@interface MySuperClass
diff --git a/gcc/testsuite/objc.dg/property/at-property-4.m b/gcc/testsuite/objc.dg/property/at-property-4.m
index 0e905db..04da34e 100644
--- a/gcc/testsuite/objc.dg/property/at-property-4.m
+++ b/gcc/testsuite/objc.dg/property/at-property-4.m
@@ -26,6 +26,11 @@
@property (class) int property_cl_1;
+@property (null_unspecified) int *property_null_1;
+@property (nullable) int *property_null_2;
+@property (nonnull) int *property_null_3;
+@property (null_resettable) int *property_null_4;
+
@property (release) int property_err_1; /* { dg-error "unknown property attribute" } */
@property (getter=myGetter) int property_h;
@@ -42,6 +47,19 @@
@property (atomic, nonatomic) int property_j; /* { dg-error {'nonatomic' attribute conflicts with 'atomic' attribute} } */
+@property (null_unspecified) int property_bad_t_1; /* { dg-error {nullability specifier 'null_unspecified' cannot be applied to non-pointer type 'int'} } */
+@property (nullable) int property_bad_t_2;/* { dg-error {nullability specifier 'nullable' cannot be applied to non-pointer type 'int'} } */
+@property (nonnull) int property_bad_t_3;/* { dg-error {nullability specifier 'nonnull' cannot be applied to non-pointer type 'int'} } */
+@property (null_resettable) int property_bad_t_4;/* { dg-error {nullability specifier 'null_resettable' cannot be applied to non-pointer type 'int'} } */
+@property (nullable) int **property_bad_t_5;/* { dg-error {nullability specifier 'nullable' cannot be applied to multi-level pointer type 'int \*\*'} } */
+
+@property (null_unspecified, nullable) int *property_ne_1; /* { dg-error {'nullable' attribute conflicts with 'null_unspecified' attribute} } */
+@property (null_unspecified, nonnull) int *property_ne_2; /* { dg-error {'nonnull' attribute conflicts with 'null_unspecified' attribute} } */
+@property (null_unspecified, null_resettable) int *property_ne_3; /* { dg-error {'null_resettable' attribute conflicts with 'null_unspecified' attribute} } */
+@property (nullable,nonnull) int *property_ne_4; /* { dg-error {'nonnull' attribute conflicts with 'nullable' attribute} } */
+@property (nullable,null_resettable) int *property_ne_5; /* { dg-error {'null_resettable' attribute conflicts with 'nullable' attribute} } */
+@property (nonnull, null_resettable) int *property_ne_6; /* { dg-error {'null_resettable' attribute conflicts with 'nonnull' attribute} } */
+
@property (setter=mySetter:,setter=mySetter2:) int f; /* { dg-warning {multiple property 'setter' methods specified, the latest one will be used} } */
@property (getter=myGetter, getter=myGetter2 ) int g; /* { dg-warning {multiple property 'getter' methods specified, the latest one will be used} } */
diff --git a/gcc/testsuite/objc.dg/property/nullability-00.m b/gcc/testsuite/objc.dg/property/nullability-00.m
new file mode 100644
index 0000000..9b0c808
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/nullability-00.m
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fsyntax-only" } */
+
+@interface MyRoot
+{
+ Class isa __attribute__((deprecated));
+ id p;
+ int x;
+ int *i;
+}
+
+@property(null_unspecified, assign) MyRoot *p1;
+@property(nonnull, assign) MyRoot *p2;
+@property(nullable, assign) MyRoot *p3;
+@property(null_resettable, assign) MyRoot *p4;
+@property(null_exciting, assign) MyRoot *e_5; /* { dg-error {unknown property attribute 'null_exciting'} } */
+
+@property(nonnull, retain, nullable) MyRoot *e_6; /* { dg-error {'nullable' attribute conflicts with 'nonnull' attribute} } */
+@property(nonnull, nonnull) int *i; /* { dg-warning {duplicate 'nonnull' attribute} } */
+
+@end
diff --git a/gcc/testsuite/objc.dg/property/property.exp b/gcc/testsuite/objc.dg/property/property.exp
index 47ffcdf..1c203db 100644
--- a/gcc/testsuite/objc.dg/property/property.exp
+++ b/gcc/testsuite/objc.dg/property/property.exp
@@ -31,12 +31,12 @@ dg-init
set tests [lsort [glob -nocomplain $srcdir/$subdir/*.m]]
# Main loop.
-dg-runtest $tests "-fgnu-runtime" $DEFAULT_CFLAGS
+dg-runtest $tests "-fgnu-runtime -Wno-objc-root-class" $DEFAULT_CFLAGS
# Darwin targets can also run code with the NeXT runtime.
# but Properties are not supported by the runtime lib before Darwin 9.
if [istarget "*-*-darwin\[9123\]*" ] {
- dg-runtest $tests "-fnext-runtime" $DEFAULT_CFLAGS
+ dg-runtest $tests "-fnext-runtime -Wno-objc-root-class" $DEFAULT_CFLAGS
}
# All done.
diff --git a/gcc/testsuite/objc.dg/proto-hier-1.m b/gcc/testsuite/objc.dg/proto-hier-1.m
index 0f409fc..648a4d4 100644
--- a/gcc/testsuite/objc.dg/proto-hier-1.m
+++ b/gcc/testsuite/objc.dg/proto-hier-1.m
@@ -1,6 +1,7 @@
/* Test for handling of protocol hierarchies. */
/* Author: Ziemowit Laski <zlaski@apple.com>. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* One-line substitute for objc/objc.h */
typedef struct objc_object { struct objc_class *class_pointer; } *id;
diff --git a/gcc/testsuite/objc.dg/proto-hier-2.m b/gcc/testsuite/objc.dg/proto-hier-2.m
index 819cf4a..6b3f803 100644
--- a/gcc/testsuite/objc.dg/proto-hier-2.m
+++ b/gcc/testsuite/objc.dg/proto-hier-2.m
@@ -1,6 +1,7 @@
/* Test protocol warning. */
/* Contributed by Devang Patel <dpatel@apple.com>. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
typedef struct objc_object { struct objc_class *class_pointer; } *id;
diff --git a/gcc/testsuite/objc.dg/proto-lossage-1.m b/gcc/testsuite/objc.dg/proto-lossage-1.m
index 2f7eb98..4564a94 100644
--- a/gcc/testsuite/objc.dg/proto-lossage-1.m
+++ b/gcc/testsuite/objc.dg/proto-lossage-1.m
@@ -2,6 +2,7 @@
may be lost, leading to superfluous warnings. */
/* Author: Ziemowit Laski <zlaski@apple.com>. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* One-line substitute for objc/objc.h */
typedef struct objc_object { struct objc_class *class_pointer; } *id;
diff --git a/gcc/testsuite/objc.dg/proto-lossage-5.m b/gcc/testsuite/objc.dg/proto-lossage-5.m
index 35c0956..a18b357 100644
--- a/gcc/testsuite/objc.dg/proto-lossage-5.m
+++ b/gcc/testsuite/objc.dg/proto-lossage-5.m
@@ -1,5 +1,6 @@
/* Do not lose references to forward-declared protocols. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
@class MyBaseClass;
@class MyClassThatFails;
@protocol _MyProtocol;
diff --git a/gcc/testsuite/objc.dg/proto-qual-1.m b/gcc/testsuite/objc.dg/proto-qual-1.m
index 40eb0f9..6e90872 100644
--- a/gcc/testsuite/objc.dg/proto-qual-1.m
+++ b/gcc/testsuite/objc.dg/proto-qual-1.m
@@ -3,6 +3,7 @@
/* { dg-do run } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include "../objc-obj-c++-shared/runtime.h"
#include <objc/Protocol.h>
diff --git a/gcc/testsuite/objc.dg/protocol-inheritance-1.m b/gcc/testsuite/objc.dg/protocol-inheritance-1.m
index 5241b29..5367a98 100644
--- a/gcc/testsuite/objc.dg/protocol-inheritance-1.m
+++ b/gcc/testsuite/objc.dg/protocol-inheritance-1.m
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
/* { dg-options "-Wno-protocol" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/objc.dg/protocol-inheritance-2.m b/gcc/testsuite/objc.dg/protocol-inheritance-2.m
index 74c9174..9776a40 100644
--- a/gcc/testsuite/objc.dg/protocol-inheritance-2.m
+++ b/gcc/testsuite/objc.dg/protocol-inheritance-2.m
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/objc.dg/protocol-optional-1.m b/gcc/testsuite/objc.dg/protocol-optional-1.m
index bc4a3d0..29fe72e 100644
--- a/gcc/testsuite/objc.dg/protocol-optional-1.m
+++ b/gcc/testsuite/objc.dg/protocol-optional-1.m
@@ -1,5 +1,6 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/objc.dg/root-class-00.m b/gcc/testsuite/objc.dg/root-class-00.m
new file mode 100644
index 0000000..1f73f73
--- /dev/null
+++ b/gcc/testsuite/objc.dg/root-class-00.m
@@ -0,0 +1,10 @@
+/* Test Wobjc-root-class.
+ Note that we don't issue a warning unless the TU contains an implementation
+ for the class. */
+/* { dg-additional-options "-fsyntax-only " } */
+
+@interface ARootObject
+@end
+
+@implementation ARootObject
+@end /* { dg-warning {class 'ARootObject' defined without specifying a base class} } */
diff --git a/gcc/testsuite/objc.dg/selector-1.m b/gcc/testsuite/objc.dg/selector-1.m
index f0781b6..5ff15a2 100644
--- a/gcc/testsuite/objc.dg/selector-1.m
+++ b/gcc/testsuite/objc.dg/selector-1.m
@@ -3,6 +3,7 @@
/* { dg-options "-Wselector" } */
/* { dg-do compile } */
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
typedef struct objc_object { struct objc_class *class_pointer; } *id;
typedef struct objc_selector *SEL;
diff --git a/gcc/testsuite/objc.dg/selector-2.m b/gcc/testsuite/objc.dg/selector-2.m
index 6cad2ff..5042104 100644
--- a/gcc/testsuite/objc.dg/selector-2.m
+++ b/gcc/testsuite/objc.dg/selector-2.m
@@ -1,6 +1,7 @@
/* Test that we don't ICE when issuing a -Wselector warning. */
/* { dg-options "-Wselector" } */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/objc.dg/selector-3.m b/gcc/testsuite/objc.dg/selector-3.m
index c0c5f3d..94838cd3 100644
--- a/gcc/testsuite/objc.dg/selector-3.m
+++ b/gcc/testsuite/objc.dg/selector-3.m
@@ -3,6 +3,7 @@
/* { dg-options "-Wselector" } */
/* { dg-do compile } */
/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
typedef struct objc_object { struct objc_class *class_pointer; } *id;
typedef const struct objc_selector *SEL;
diff --git a/gcc/testsuite/objc.dg/selector-4.m b/gcc/testsuite/objc.dg/selector-4.m
index d34f8c8..2a4947e 100644
--- a/gcc/testsuite/objc.dg/selector-4.m
+++ b/gcc/testsuite/objc.dg/selector-4.m
@@ -3,6 +3,7 @@
/* Author: Ziemowit Laski <zlaski@apple.com>. */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
@interface Int1
+ (int)and_eq:(int)arg1 and:(int)arg2;
diff --git a/gcc/testsuite/objc.dg/shadow-1.m b/gcc/testsuite/objc.dg/shadow-1.m
index 739a0d0..d18fd6e 100644
--- a/gcc/testsuite/objc.dg/shadow-1.m
+++ b/gcc/testsuite/objc.dg/shadow-1.m
@@ -2,6 +2,7 @@
/* Author: Dimitris Papavasiliou <dpapavas@gmail.com>. */
/* { dg-do compile } */
/* { dg-additional-options "-Wno-shadow-ivar" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
@interface MyClass
diff --git a/gcc/testsuite/objc.dg/shadow-2.m b/gcc/testsuite/objc.dg/shadow-2.m
index 16261b9..26447fe 100644
--- a/gcc/testsuite/objc.dg/shadow-2.m
+++ b/gcc/testsuite/objc.dg/shadow-2.m
@@ -2,6 +2,7 @@
/* Author: Dimitris Papavasiliou <dpapavas@gmail.com>. */
/* { dg-do compile } */
/* { dg-additional-options "-Wno-shadow" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
@interface MyClass
diff --git a/gcc/testsuite/objc.dg/special/load-category-1.m b/gcc/testsuite/objc.dg/special/load-category-1.m
index cb22143..b72d070 100644
--- a/gcc/testsuite/objc.dg/special/load-category-1.m
+++ b/gcc/testsuite/objc.dg/special/load-category-1.m
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do run } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <stdlib.h>
#include <objc/objc.h>
diff --git a/gcc/testsuite/objc.dg/special/load-category-2.m b/gcc/testsuite/objc.dg/special/load-category-2.m
index 7dc74595..2706351 100644
--- a/gcc/testsuite/objc.dg/special/load-category-2.m
+++ b/gcc/testsuite/objc.dg/special/load-category-2.m
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do run } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <stdio.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/objc.dg/special/load-category-3.m b/gcc/testsuite/objc.dg/special/load-category-3.m
index b89d8f1..215e463 100644
--- a/gcc/testsuite/objc.dg/special/load-category-3.m
+++ b/gcc/testsuite/objc.dg/special/load-category-3.m
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do run } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* This test is identical to load-category-2, but the classes and
categories are created in inverted order in the modules, to test
diff --git a/gcc/testsuite/objc.dg/special/special.exp b/gcc/testsuite/objc.dg/special/special.exp
index d770e2a..f561d38 100644
--- a/gcc/testsuite/objc.dg/special/special.exp
+++ b/gcc/testsuite/objc.dg/special/special.exp
@@ -39,6 +39,7 @@ dg-init
# for all systems we point to the libobjc includes and use the -fgnu-runtime
set add_flags "additional_flags=-I${srcdir}/../../libobjc"
lappend add_flags "additional_flags=-fgnu-runtime"
+lappend add_flags "additional_flags=-Wno-objc-root-class"
set lines [objc_target_compile "$srcdir/$subdir/unclaimed-category-1a.m" "unclaimed-category-1a.o" object $add_flags ]
if ![string match "" $lines] then {
fail "unclaimed-category-1a.o"
@@ -50,6 +51,7 @@ if ![string match "" $lines] then {
if [istarget "*-*-darwin*" ] {
set add_flags ""
lappend add_flags "additional_flags=-fnext-runtime"
+lappend add_flags "additional_flags=-Wno-objc-root-class"
set lines [objc_target_compile "$srcdir/$subdir/unclaimed-category-1a.m" "unclaimed-category-1a.o" object $add_flags ]
if ![string match "" $lines] then {
fail "unclaimed-category-1a.o"
@@ -66,6 +68,7 @@ if ![string match "" $lines] then {
# and load-category-1a.m, link them together, and execute the result.
set add_flags "additional_flags=-I${srcdir}/../../libobjc"
lappend add_flags "additional_flags=-fgnu-runtime"
+lappend add_flags "additional_flags=-Wno-objc-root-class"
set lines [objc_target_compile "$srcdir/$subdir/load-category-1a.m" "load-category-1a.o" object $add_flags ]
if ![string match "" $lines] then {
fail "load-category-1a.o"
@@ -77,6 +80,7 @@ if ![string match "" $lines] then {
if [istarget "*-*-darwin*" ] {
set add_flags ""
lappend add_flags "additional_flags=-fnext-runtime"
+lappend add_flags "additional_flags=-Wno-objc-root-class"
set lines [objc_target_compile "$srcdir/$subdir/load-category-1a.m" "load-category-1a.o" object $add_flags ]
if ![string match "" $lines] then {
fail "load-category-1a.o"
@@ -93,6 +97,7 @@ if ![string match "" $lines] then {
# and load-category-2a.m, link them together, and execute the result.
set add_flags "additional_flags=-I${srcdir}/../../libobjc"
lappend add_flags "additional_flags=-fgnu-runtime"
+lappend add_flags "additional_flags=-Wno-objc-root-class"
set lines [objc_target_compile "$srcdir/$subdir/load-category-2a.m" "load-category-2a.o" object $add_flags ]
if ![string match "" $lines] then {
fail "load-category-2a.o"
@@ -104,6 +109,7 @@ if ![string match "" $lines] then {
if [istarget "*-*-darwin*" ] {
set add_flags ""
lappend add_flags "additional_flags=-fnext-runtime"
+lappend add_flags "additional_flags=-Wno-objc-root-class"
set lines [objc_target_compile "$srcdir/$subdir/load-category-2a.m" "load-category-2a.o" object $add_flags ]
if ![string match "" $lines] then {
fail "load-category-2a.o"
@@ -120,6 +126,7 @@ if ![string match "" $lines] then {
# and load-category-3a.m, link them together, and execute the result.
set add_flags "additional_flags=-I${srcdir}/../../libobjc"
lappend add_flags "additional_flags=-fgnu-runtime"
+lappend add_flags "additional_flags=-Wno-objc-root-class"
set lines [objc_target_compile "$srcdir/$subdir/load-category-3a.m" "load-category-3a.o" object $add_flags ]
if ![string match "" $lines] then {
fail "load-category-3a.o"
@@ -131,6 +138,7 @@ if ![string match "" $lines] then {
if [istarget "*-*-darwin*" ] {
set add_flags ""
lappend add_flags "additional_flags=-fnext-runtime"
+lappend add_flags "additional_flags=-Wno-objc-root-class"
set lines [objc_target_compile "$srcdir/$subdir/load-category-3a.m" "load-category-3a.o" object $add_flags ]
if ![string match "" $lines] then {
fail "load-category-3a.o"
diff --git a/gcc/testsuite/objc.dg/special/unclaimed-category-1.h b/gcc/testsuite/objc.dg/special/unclaimed-category-1.h
index a32024d..cb5812e 100644
--- a/gcc/testsuite/objc.dg/special/unclaimed-category-1.h
+++ b/gcc/testsuite/objc.dg/special/unclaimed-category-1.h
@@ -1,4 +1,5 @@
/* Contributed by Nicola Pero - Fri Dec 14 08:36:00 GMT 2001 */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* Test loading unclaimed categories - categories of a class defined
separately from the class itself. */
diff --git a/gcc/testsuite/objc.dg/special/unclaimed-category-1.m b/gcc/testsuite/objc.dg/special/unclaimed-category-1.m
index 7b434b4..a8e422d 100644
--- a/gcc/testsuite/objc.dg/special/unclaimed-category-1.m
+++ b/gcc/testsuite/objc.dg/special/unclaimed-category-1.m
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero - Fri Dec 14 08:36:00 GMT 2001 */
/* { dg-do run } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
#include "../../objc-obj-c++-shared/runtime.h"
diff --git a/gcc/testsuite/objc.dg/stabs-1.m b/gcc/testsuite/objc.dg/stabs-1.m
index 452993e..b97e4d6 100644
--- a/gcc/testsuite/objc.dg/stabs-1.m
+++ b/gcc/testsuite/objc.dg/stabs-1.m
@@ -3,6 +3,7 @@
/* { dg-do compile { target stabs } } */
/* { dg-options "-gstabs" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
@interface MyClass
+ newWithArg: arg;
diff --git a/gcc/testsuite/objc.dg/strings/strings.exp b/gcc/testsuite/objc.dg/strings/strings.exp
index 41da5cb..6042d3c 100644
--- a/gcc/testsuite/objc.dg/strings/strings.exp
+++ b/gcc/testsuite/objc.dg/strings/strings.exp
@@ -35,11 +35,11 @@ dg-init
set tests [lsort [glob -nocomplain $srcdir/$subdir/*.m]]
# Main loop.
-dg-runtest $tests "-fgnu-runtime" $DEFAULT_CFLAGS
+dg-runtest $tests "-fgnu-runtime -Wno-objc-root-class" $DEFAULT_CFLAGS
# darwin targets can also run code with the NeXT runtime.
if [istarget "*-*-darwin*" ] {
- dg-runtest $tests "-fnext-runtime" $DEFAULT_CFLAGS
+ dg-runtest $tests "-fnext-runtime -Wno-objc-root-class" $DEFAULT_CFLAGS
}
# All done.
diff --git a/gcc/testsuite/objc.dg/stubify-1.m b/gcc/testsuite/objc.dg/stubify-1.m
index 641595c..4043492 100644
--- a/gcc/testsuite/objc.dg/stubify-1.m
+++ b/gcc/testsuite/objc.dg/stubify-1.m
@@ -5,6 +5,7 @@
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
/* { dg-require-effective-target ilp32 } */
/* { dg-options "-Os -mdynamic-no-pic -mmacosx-version-min=10.4 -msymbol-stubs" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
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 904ac44..3e9097e 100644
--- a/gcc/testsuite/objc.dg/stubify-2.m
+++ b/gcc/testsuite/objc.dg/stubify-2.m
@@ -5,6 +5,7 @@
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
/* { dg-require-effective-target ilp32 } */
/* { dg-options "-mdynamic-no-pic -fdump-rtl-jump -mmacosx-version-min=10.4 -msymbol-stubs" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
typedef struct objc_object { } *id ;
int x = 41 ;
diff --git a/gcc/testsuite/objc.dg/super-class-2.m b/gcc/testsuite/objc.dg/super-class-2.m
index 144ea81..63792fd 100644
--- a/gcc/testsuite/objc.dg/super-class-2.m
+++ b/gcc/testsuite/objc.dg/super-class-2.m
@@ -1,6 +1,7 @@
/* Test calling super from within a category class method. */
/* Author: Ziemowit Laski <zlaski@apple.com> */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
typedef struct objc_object { struct objc_class *isa; } *id;
diff --git a/gcc/testsuite/objc.dg/super-dealloc-1.m b/gcc/testsuite/objc.dg/super-dealloc-1.m
index 0ab177b..035de05 100644
--- a/gcc/testsuite/objc.dg/super-dealloc-1.m
+++ b/gcc/testsuite/objc.dg/super-dealloc-1.m
@@ -2,6 +2,7 @@
/* Author: Ziemowit Laski <zlaski@apple.com> */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
@interface Foo {
void *isa;
diff --git a/gcc/testsuite/objc.dg/super-dealloc-2.m b/gcc/testsuite/objc.dg/super-dealloc-2.m
index 80dcf49..5d588c5 100644
--- a/gcc/testsuite/objc.dg/super-dealloc-2.m
+++ b/gcc/testsuite/objc.dg/super-dealloc-2.m
@@ -2,6 +2,7 @@
/* Author: Ziemowit Laski <zlaski@apple.com> */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
@interface Foo {
void *isa;
diff --git a/gcc/testsuite/objc.dg/sync-3.m b/gcc/testsuite/objc.dg/sync-3.m
index 5cee890..6ef72a1 100644
--- a/gcc/testsuite/objc.dg/sync-3.m
+++ b/gcc/testsuite/objc.dg/sync-3.m
@@ -1,6 +1,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-options "-fobjc-exceptions" } */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
/* Test that the compiler is checking the argument of @synchronized(),
and produce errors when invalid types are used. */
diff --git a/gcc/testsuite/objc.dg/threedotthree-abi-1.m b/gcc/testsuite/objc.dg/threedotthree-abi-1.m
index 53154d3..8c22850 100644
--- a/gcc/testsuite/objc.dg/threedotthree-abi-1.m
+++ b/gcc/testsuite/objc.dg/threedotthree-abi-1.m
@@ -3,6 +3,7 @@
/* { dg-do run { target *-*-darwin* } } */
/* { dg-require-effective-target ilp32 } */
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <stdio.h>
#include <string.h>
diff --git a/gcc/testsuite/objc.dg/torture/dg-torture.exp b/gcc/testsuite/objc.dg/torture/dg-torture.exp
index 28c2359..11f50fc 100644
--- a/gcc/testsuite/objc.dg/torture/dg-torture.exp
+++ b/gcc/testsuite/objc.dg/torture/dg-torture.exp
@@ -7,11 +7,11 @@ dg-init
# Gather a list of all tests.
set tests [lsort [glob -nocomplain $srcdir/$subdir/*.m]]
-objc-dg-runtest $tests "" "-fgnu-runtime"
+objc-dg-runtest $tests "" "-fgnu-runtime -Wno-objc-root-class"
# darwin targets can also run code with the NeXT runtime.
if [istarget "*-*-darwin*" ] {
- objc-dg-runtest $tests "" "-fnext-runtime"
+ objc-dg-runtest $tests "" "-fnext-runtime -Wno-objc-root-class"
}
dg-finish
diff --git a/gcc/testsuite/objc.dg/torture/strings/strings.exp b/gcc/testsuite/objc.dg/torture/strings/strings.exp
index 64e53c6..3e2b3b0 100644
--- a/gcc/testsuite/objc.dg/torture/strings/strings.exp
+++ b/gcc/testsuite/objc.dg/torture/strings/strings.exp
@@ -24,11 +24,11 @@ dg-init
# Gather a list of all tests.
set tests [lsort [glob -nocomplain $srcdir/$subdir/*.m]]
-objc-dg-runtest $tests "" "-fgnu-runtime"
+objc-dg-runtest $tests "" "-fgnu-runtime -Wno-objc-root-class"
# Darwin targets also test with the NeXT runtime.
if [istarget "*-*-darwin*" ] {
- objc-dg-runtest $tests "" "-fnext-runtime"
+ objc-dg-runtest $tests "" "-fnext-runtime -Wno-objc-root-class"
}
dg-finish
diff --git a/gcc/testsuite/objc.dg/try-catch-11.m b/gcc/testsuite/objc.dg/try-catch-11.m
index e08f321..c792c83 100644
--- a/gcc/testsuite/objc.dg/try-catch-11.m
+++ b/gcc/testsuite/objc.dg/try-catch-11.m
@@ -4,6 +4,7 @@
/* { dg-options "-fobjc-exceptions" } */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
typedef volatile int IOSharedLockData;
diff --git a/gcc/testsuite/objc.dg/try-catch-12.m b/gcc/testsuite/objc.dg/try-catch-12.m
index ce26b32..6c9afc2 100644
--- a/gcc/testsuite/objc.dg/try-catch-12.m
+++ b/gcc/testsuite/objc.dg/try-catch-12.m
@@ -4,6 +4,7 @@
/* { dg-options "-fobjc-exceptions" } */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
@interface TestMyTests
- (void) testSpoon;
diff --git a/gcc/testsuite/objc.dg/type-size-2.m b/gcc/testsuite/objc.dg/type-size-2.m
index d02a8af..64444cfe 100644
--- a/gcc/testsuite/objc.dg/type-size-2.m
+++ b/gcc/testsuite/objc.dg/type-size-2.m
@@ -4,6 +4,7 @@
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
/* { dg-do run } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include "../objc-obj-c++-shared/runtime.h"
#include <stdio.h>
diff --git a/gcc/testsuite/objc.dg/type-size-3.m b/gcc/testsuite/objc.dg/type-size-3.m
index bc66b0b..3f65516 100644
--- a/gcc/testsuite/objc.dg/type-size-3.m
+++ b/gcc/testsuite/objc.dg/type-size-3.m
@@ -1,6 +1,7 @@
/* Reject ivars that use flexible array members. */
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com> */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
typedef struct
{
diff --git a/gcc/testsuite/objc.dg/type-size-4.m b/gcc/testsuite/objc.dg/type-size-4.m
index 7e26da3..f10ed5b 100644
--- a/gcc/testsuite/objc.dg/type-size-4.m
+++ b/gcc/testsuite/objc.dg/type-size-4.m
@@ -2,6 +2,7 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com> */
/* PR objc/47832 */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
typedef struct
{
diff --git a/gcc/testsuite/objc.dg/type-size-5.m b/gcc/testsuite/objc.dg/type-size-5.m
index d89af32..e1b11f7 100644
--- a/gcc/testsuite/objc.dg/type-size-5.m
+++ b/gcc/testsuite/objc.dg/type-size-5.m
@@ -1,6 +1,7 @@
/* Reject ivars that use flexible array members. */
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com> */
/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
typedef struct
{
diff --git a/gcc/testsuite/objc.dg/undeclared-selector.m b/gcc/testsuite/objc.dg/undeclared-selector.m
index 1cfc6c8..389b032 100644
--- a/gcc/testsuite/objc.dg/undeclared-selector.m
+++ b/gcc/testsuite/objc.dg/undeclared-selector.m
@@ -2,6 +2,7 @@
/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
/* { dg-do compile } */
/* { dg-options "-Wundeclared-selector" } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
#include <objc/objc.h>
diff --git a/gcc/testsuite/objc.dg/volatile-1.m b/gcc/testsuite/objc.dg/volatile-1.m
index 8b5381a..a713631 100644
--- a/gcc/testsuite/objc.dg/volatile-1.m
+++ b/gcc/testsuite/objc.dg/volatile-1.m
@@ -1,7 +1,8 @@
/* Test for proper handling of volatile parameters in ObjC methods. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
/* { dg-do compile } */
/* { dg-options "-O2" } */
-/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+/* { dg-additional-options "-Wno-objc-root-class" } */
@interface Test
-(void) test2: (volatile int) a;
diff --git a/gcc/timevar.def b/gcc/timevar.def
index a303179..1f85e2d 100644
--- a/gcc/timevar.def
+++ b/gcc/timevar.def
@@ -145,6 +145,9 @@ DEFTIMEVAR (TV_CONSTEXPR , "constant expression evaluation")
DEFTIMEVAR (TV_CONSTRAINT_NORM , "constraint normalization")
DEFTIMEVAR (TV_CONSTRAINT_SAT , "constraint satisfaction")
DEFTIMEVAR (TV_CONSTRAINT_SUB , "constraint subsumption")
+DEFTIMEVAR (TV_MODULE_IMPORT , "module import")
+DEFTIMEVAR (TV_MODULE_EXPORT , "module export")
+DEFTIMEVAR (TV_MODULE_MAPPER , "module mapper")
DEFTIMEVAR (TV_FLATTEN_INLINING , "flatten inlining")
DEFTIMEVAR (TV_EARLY_INLINING , "early inlining heuristics")
DEFTIMEVAR (TV_INLINE_PARAMETERS , "inline parameters")
@@ -293,6 +296,7 @@ DEFTIMEVAR (TV_VAR_TRACKING , "variable tracking")
DEFTIMEVAR (TV_VAR_TRACKING_DATAFLOW , "var-tracking dataflow")
DEFTIMEVAR (TV_VAR_TRACKING_EMIT , "var-tracking emit")
DEFTIMEVAR (TV_TREE_IFCOMBINE , "tree if-combine")
+DEFTIMEVAR (TV_TREE_IF_TO_SWITCH , "if to switch conversion")
DEFTIMEVAR (TV_TREE_UNINIT , "uninit var analysis")
DEFTIMEVAR (TV_PLUGIN_INIT , "plugin initialization")
DEFTIMEVAR (TV_PLUGIN_RUN , "plugin execution")
diff --git a/gcc/toplev.c b/gcc/toplev.c
index e32dc28..cb4ae77 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -512,6 +512,9 @@ compile_file (void)
if (flag_sanitize & SANITIZE_THREAD)
tsan_finish_file ();
+ if (gate_hwasan ())
+ hwasan_finish_file ();
+
omp_finish_file ();
output_shared_constant_pool ();
@@ -1834,7 +1837,8 @@ process_options (void)
}
if ((flag_sanitize & SANITIZE_USER_ADDRESS)
- && targetm.asan_shadow_offset == NULL)
+ && ((targetm.asan_shadow_offset == NULL)
+ || (targetm.asan_shadow_offset () == 0)))
{
warning_at (UNKNOWN_LOCATION, 0,
"%<-fsanitize=address%> not supported for this target");
@@ -1852,6 +1856,15 @@ process_options (void)
flag_sanitize &= ~SANITIZE_ADDRESS;
}
+ /* HWAsan requires top byte ignore feature in the backend. */
+ if (flag_sanitize & SANITIZE_HWADDRESS
+ && ! targetm.memtag.can_tag_addresses ())
+ {
+ warning_at (UNKNOWN_LOCATION, 0, "%qs is not supported for this target",
+ "-fsanitize=hwaddress");
+ flag_sanitize &= ~SANITIZE_HWADDRESS;
+ }
+
/* 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 e4f264d..c078a12 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -4998,7 +4998,7 @@ ipa_tm_create_version (struct cgraph_node *old_node)
new_node->lowered = true;
new_node->tm_clone = 1;
if (!old_node->implicit_section)
- new_node->set_section (old_node->get_section ());
+ new_node->set_section (*old_node);
get_cg_data (&old_node, true)->clone = new_node;
if (old_node->get_availability () >= AVAIL_INTERPOSABLE)
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 5139f11..f59a0c0 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -3885,6 +3885,8 @@ verify_gimple_assign_binary (gassign *stmt)
return false;
}
+ case WIDEN_PLUS_EXPR:
+ case WIDEN_MINUS_EXPR:
case PLUS_EXPR:
case MINUS_EXPR:
{
@@ -4005,6 +4007,10 @@ verify_gimple_assign_binary (gassign *stmt)
return false;
}
+ case VEC_WIDEN_MINUS_HI_EXPR:
+ case VEC_WIDEN_MINUS_LO_EXPR:
+ case VEC_WIDEN_PLUS_HI_EXPR:
+ case VEC_WIDEN_PLUS_LO_EXPR:
case VEC_WIDEN_MULT_HI_EXPR:
case VEC_WIDEN_MULT_LO_EXPR:
case VEC_WIDEN_MULT_EVEN_EXPR:
@@ -7966,14 +7972,19 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags)
&& decl_is_tm_clone (fndecl));
struct function *fun = DECL_STRUCT_FUNCTION (fndecl);
- if (DECL_ATTRIBUTES (fndecl) != NULL_TREE)
+ tree fntype = TREE_TYPE (fndecl);
+ tree attrs[] = { DECL_ATTRIBUTES (fndecl), TYPE_ATTRIBUTES (fntype) };
+
+ for (int i = 0; i != 2; ++i)
{
+ if (!attrs[i])
+ continue;
+
fprintf (file, "__attribute__((");
bool first = true;
tree chain;
- for (chain = DECL_ATTRIBUTES (fndecl); chain;
- first = false, chain = TREE_CHAIN (chain))
+ for (chain = attrs[i]; chain; first = false, chain = TREE_CHAIN (chain))
{
if (!first)
fprintf (file, ", ");
@@ -8026,7 +8037,11 @@ dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags)
}
}
else
- fprintf (file, "%s %s(", function_name (fun), tmclone ? "[tm-clone] " : "");
+ {
+ print_generic_expr (file, TREE_TYPE (fntype), dump_flags);
+ fprintf (file, " %s %s(", function_name (fun),
+ tmclone ? "[tm-clone] " : "");
+ }
arg = DECL_ARGUMENTS (fndecl);
while (arg)
diff --git a/gcc/tree-cfgcleanup.h b/gcc/tree-cfgcleanup.h
index 6ff6726..9e368d6 100644
--- a/gcc/tree-cfgcleanup.h
+++ b/gcc/tree-cfgcleanup.h
@@ -26,5 +26,6 @@ extern bool cleanup_tree_cfg (unsigned = 0);
extern bool fixup_noreturn_call (gimple *stmt);
extern bool delete_unreachable_blocks_update_callgraph (cgraph_node *dst_node,
bool update_clones);
+extern unsigned clean_up_loop_closed_phi (function *);
#endif /* GCC_TREE_CFGCLEANUP_H */
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
index f132e0f..1cfb3e8 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -318,7 +318,7 @@ complex_propagate::visit_stmt (gimple *stmt, edge *taken_edge_p ATTRIBUTE_UNUSED
lhs = gimple_get_lhs (stmt);
/* Skip anything but GIMPLE_ASSIGN and GIMPLE_CALL with a lhs. */
- if (!lhs)
+ if (!lhs || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
return SSA_PROP_VARYING;
/* These conditions should be satisfied due to the initial filter
@@ -417,6 +417,9 @@ complex_propagate::visit_phi (gphi *phi)
set up in init_dont_simulate_again. */
gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
+ if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
+ return SSA_PROP_VARYING;
+
/* We've set up the lattice values such that IOR neatly models PHI meet. */
new_l = UNINITIALIZED;
for (i = gimple_phi_num_args (phi) - 1; i >= 0; --i)
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index c9280a8..e457b91 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -110,6 +110,10 @@ struct die_struct;
/* Nonzero if the argument is not used by the function. */
#define EAF_UNUSED (1 << 3)
+/* Nonzero if the argument itself does not escape but memory
+ referenced by it can escape. */
+#define EAF_NODIRECTESCAPE (1 << 4)
+
/* Call return flags. */
/* Mask for the argument number that is returned. Lower two bits of
the return flags, encodes argument slots zero to three. */
@@ -859,7 +863,10 @@ enum attribute_flags {
are not in fact compatible with the function type. */
ATTR_FLAG_BUILT_IN = 16,
/* A given attribute has been parsed as a C++-11 attribute. */
- ATTR_FLAG_CXX11 = 32
+ ATTR_FLAG_CXX11 = 32,
+ /* The attribute handler is being invoked with an internal argument
+ that may not otherwise be valid when specified in source code. */
+ ATTR_FLAG_INTERNAL = 64
};
/* Types used to represent sizes. */
diff --git a/gcc/tree-diagnostic-path.cc b/gcc/tree-diagnostic-path.cc
index 164df86..b4fef2b 100644
--- a/gcc/tree-diagnostic-path.cc
+++ b/gcc/tree-diagnostic-path.cc
@@ -411,7 +411,7 @@ print_path_summary_as_text (const path_summary *ps, diagnostic_context *dc,
write_indent (pp, vbar_for_next_frame);
pp_string (pp, start_line_color);
- pp_printf (pp, "|");
+ pp_character (pp, '|');
pp_string (pp, end_line_color);
pp_newline (pp);
}
@@ -520,6 +520,13 @@ default_tree_make_json_for_path (diagnostic_context *context,
#if CHECKING_P
+/* Disable warnings about missing quoting in GCC diagnostics for the print
+ calls in the tests below. */
+#if __GNUC__ >= 10
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wformat-diag"
+#endif
+
namespace selftest {
/* A subclass of simple_diagnostic_path that adds member functions
@@ -814,4 +821,8 @@ tree_diagnostic_path_cc_tests ()
} // namespace selftest
+#if __GNUC__ >= 10
+# pragma GCC diagnostic pop
+#endif
+
#endif /* #if CHECKING_P */
diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c
index 44755dd..5b55832 100644
--- a/gcc/tree-emutls.c
+++ b/gcc/tree-emutls.c
@@ -259,7 +259,7 @@ get_emutls_init_templ_addr (tree decl)
if (targetm.emutls.tmpl_section)
set_decl_section_name (to, targetm.emutls.tmpl_section);
else
- set_decl_section_name (to, DECL_SECTION_NAME (decl));
+ set_decl_section_name (to, decl);
/* Create varpool node for the new variable and finalize it if it is
not external one. */
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index 2062758..93effaa 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -2916,12 +2916,6 @@ ifcvt_local_dce (class loop *loop)
enum gimple_code code;
use_operand_p use_p;
imm_use_iterator imm_iter;
- std::pair <tree, tree> *name_pair;
- unsigned int i;
-
- FOR_EACH_VEC_ELT (redundant_ssa_names, i, name_pair)
- replace_uses_by (name_pair->first, name_pair->second);
- redundant_ssa_names.release ();
/* The loop has a single BB only. */
basic_block bb = loop->header;
@@ -3124,6 +3118,13 @@ tree_if_conversion (class loop *loop, vec<gimple *> *preds)
exit_bbs = BITMAP_ALLOC (NULL);
bitmap_set_bit (exit_bbs, single_exit (loop)->dest->index);
bitmap_set_bit (exit_bbs, loop->latch->index);
+
+ std::pair <tree, tree> *name_pair;
+ unsigned ssa_names_idx;
+ FOR_EACH_VEC_ELT (redundant_ssa_names, ssa_names_idx, name_pair)
+ replace_uses_by (name_pair->first, name_pair->second);
+ redundant_ssa_names.release ();
+
todo |= do_rpo_vn (cfun, loop_preheader_edge (loop), exit_bbs);
/* Delete dead predicate computations. */
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 32424b1..d9814bd 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -4224,6 +4224,8 @@ estimate_operator_cost (enum tree_code code, eni_weights *weights,
case REALIGN_LOAD_EXPR:
+ case WIDEN_PLUS_EXPR:
+ case WIDEN_MINUS_EXPR:
case WIDEN_SUM_EXPR:
case WIDEN_MULT_EXPR:
case DOT_PROD_EXPR:
@@ -4232,6 +4234,10 @@ estimate_operator_cost (enum tree_code code, eni_weights *weights,
case WIDEN_MULT_MINUS_EXPR:
case WIDEN_LSHIFT_EXPR:
+ case VEC_WIDEN_PLUS_HI_EXPR:
+ case VEC_WIDEN_PLUS_LO_EXPR:
+ case VEC_WIDEN_MINUS_HI_EXPR:
+ case VEC_WIDEN_MINUS_LO_EXPR:
case VEC_WIDEN_MULT_HI_EXPR:
case VEC_WIDEN_MULT_LO_EXPR:
case VEC_WIDEN_MULT_EVEN_EXPR:
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index 1493b32..51c619d 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -1412,6 +1412,10 @@ rewrite_stmt (gimple_stmt_iterator *si)
SET_DEF (def_p, name);
register_new_def (DEF_FROM_PTR (def_p), var);
+ /* Do not insert debug stmts if the stmt ends the BB. */
+ if (stmt_ends_bb_p (stmt))
+ continue;
+
tracked_var = target_for_debug_bind (var);
if (tracked_var)
{
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 9cb22ac..450a379 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -379,6 +379,7 @@ extern gimple_opt_pass *make_pass_empty_loop (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_graphite (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_graphite_transforms (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_if_conversion (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_if_to_switch (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_loop_distribution (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_vectorize (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_simduid_cleanup (gcc::context *ctxt);
@@ -416,6 +417,7 @@ extern gimple_opt_pass *make_pass_lower_switch (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_lower_switch_O0 (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_lower_vector (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_lower_vector_ssa (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_omp_oacc_kernels_decompose (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_lower_omp (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_diagnose_omp_blocks (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_expand_omp (gcc::context *ctxt);
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 318f048..5a93c4d 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -1708,6 +1708,7 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
case VECTOR_TYPE:
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
+ case OPAQUE_TYPE:
{
unsigned int quals = TYPE_QUALS (node);
enum tree_code_class tclass;
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index edab778..2c7923d 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -3043,22 +3043,12 @@ iv_can_overflow_p (class loop *loop, tree type, tree base, tree step)
if (integer_zerop (step))
return false;
- if (TREE_CODE (base) == INTEGER_CST)
- base_min = base_max = wi::to_wide (base);
- else if (TREE_CODE (base) == SSA_NAME
- && INTEGRAL_TYPE_P (TREE_TYPE (base))
- && get_range_info (base, &base_min, &base_max) == VR_RANGE)
- ;
- else
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (base))
+ || get_range_info (base, &base_min, &base_max) != VR_RANGE)
return true;
- if (TREE_CODE (step) == INTEGER_CST)
- step_min = step_max = wi::to_wide (step);
- else if (TREE_CODE (step) == SSA_NAME
- && INTEGRAL_TYPE_P (TREE_TYPE (step))
- && get_range_info (step, &step_min, &step_max) == VR_RANGE)
- ;
- else
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (step))
+ || get_range_info (step, &step_min, &step_max) != VR_RANGE)
return true;
if (!get_max_loop_iterations (loop, &nit))
diff --git a/gcc/tree-ssa-alias-compare.h b/gcc/tree-ssa-alias-compare.h
new file mode 100644
index 0000000..0e8409a
--- /dev/null
+++ b/gcc/tree-ssa-alias-compare.h
@@ -0,0 +1,43 @@
+/* Comparsion of AO ref.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef TREE_SSA_ALIAS_COMPARE_H
+#define TREE_SSA_ALIAS_COMPARE_H
+
+class operand_compare;
+/* A class aggregating all connections and semantic equivalents
+ for a given pair of semantic function candidates. */
+class ao_compare : public operand_compare
+{
+ public:
+ enum ao_ref_diff
+ {
+ SEMANTICS = 1,
+ BASE_ALIAS_SET = 2,
+ REF_ALIAS_SET = 4,
+ ACCESS_PATH = 8,
+ DEPENDENCE_CLIQUE = 16
+ };
+ int compare_ao_refs (ao_ref *ref1, ao_ref *ref2, bool lto_streaming_safe,
+ bool tbaa);
+ void hash_ao_ref (ao_ref *ref, bool lto_streaming_safe, bool tbaa,
+ inchash::hash &hstate);
+};
+
+#endif
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index e64011d..311ce66 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -45,6 +45,8 @@ along with GCC; see the file COPYING3. If not see
#include "dbgcnt.h"
#include "gimple-pretty-print.h"
#include "print-tree.h"
+#include "tree-ssa-alias-compare.h"
+#include "builtins.h"
/* Broad overview of how alias analysis on gimple works:
@@ -739,6 +741,36 @@ ao_ref_alias_set (ao_ref *ref)
return ref->ref_alias_set;
}
+/* Returns a type satisfying
+ get_deref_alias_set (type) == ao_ref_base_alias_set (REF). */
+
+tree
+ao_ref_base_alias_ptr_type (ao_ref *ref)
+{
+ tree base_ref;
+
+ if (!ref->ref)
+ return NULL_TREE;
+ base_ref = ref->ref;
+ while (handled_component_p (base_ref))
+ base_ref = TREE_OPERAND (base_ref, 0);
+ tree ret = reference_alias_ptr_type (base_ref);
+ return ret;
+}
+
+/* Returns a type satisfying
+ get_deref_alias_set (type) == ao_ref_alias_set (REF). */
+
+tree
+ao_ref_alias_ptr_type (ao_ref *ref)
+{
+ if (!ref->ref)
+ return NULL_TREE;
+ tree ret = reference_alias_ptr_type (ref->ref);
+ return ret;
+}
+
+
/* Init an alias-oracle reference representation from a gimple pointer
PTR a range specified by OFFSET, SIZE and MAX_SIZE under the assumption
that RANGE_KNOWN is set.
@@ -1175,7 +1207,7 @@ aliasing_component_refs_p (tree ref1,
struct a {int array1[0]; int array[];};
Such struct has size 0 but accesses to a.array may have non-zero size.
In this case the size of TREE_TYPE (base1) is smaller than
- size of TREE_TYPE (TREE_OPERNAD (base1, 0)).
+ size of TREE_TYPE (TREE_OPERAND (base1, 0)).
Because we compare sizes of arrays just by sizes of their elements,
we only need to care about zero sized array fields here. */
@@ -1950,6 +1982,20 @@ decl_refs_may_alias_p (tree ref1, tree base1,
return true;
}
+/* Return true if access with BASE is view converted.
+ Base must not be stripped from inner MEM_REF (&decl)
+ which is done by ao_ref_base and thus one extra walk
+ of handled components is needed. */
+
+static bool
+view_converted_memref_p (tree base)
+{
+ if (TREE_CODE (base) != MEM_REF && TREE_CODE (base) != TARGET_MEM_REF)
+ return false;
+ return same_type_for_tbaa (TREE_TYPE (base),
+ TREE_TYPE (TREE_OPERAND (base, 1))) != 1;
+}
+
/* Return true if an indirect reference based on *PTR1 constrained
to [OFFSET1, OFFSET1 + MAX_SIZE1) may alias a variable based on BASE2
constrained to [OFFSET2, OFFSET2 + MAX_SIZE2). *PTR1 and BASE2 have
@@ -3797,6 +3843,8 @@ attr_fnspec::verify ()
default:
err = true;
}
+ if (err)
+ internal_error ("invalid fn spec attribute \"%s\"", str);
/* Now check all parameters. */
for (unsigned int i = 0; arg_specified_p (i); i++)
@@ -3813,21 +3861,355 @@ attr_fnspec::verify ()
case 'w':
case 'W':
case '.':
+ if ((str[idx + 1] >= '1' && str[idx + 1] <= '9')
+ || str[idx + 1] == 't')
+ {
+ if (str[idx] != 'r' && str[idx] != 'R'
+ && str[idx] != 'w' && str[idx] != 'W'
+ && str[idx] != 'o' && str[idx] != 'O')
+ err = true;
+ if (str[idx] != 't'
+ /* Size specified is scalar, so it should be described
+ by ". " if specified at all. */
+ && (arg_specified_p (str[idx + 1] - '1')
+ && str[arg_idx (str[idx + 1] - '1')] != '.'))
+ err = true;
+ }
+ else if (str[idx + 1] != ' ')
+ err = true;
break;
default:
- err = true;
+ if (str[idx] < '1' || str[idx] > '9')
+ err = true;
}
- if ((str[idx + 1] >= '1' && str[idx + 1] <= '9')
- || str[idx + 1] == 't')
+ if (err)
+ internal_error ("invalid fn spec attribute \"%s\" arg %i", str, i);
+ }
+}
+
+/* Return ture if TYPE1 and TYPE2 will always give the same answer
+ when compared wit hother types using same_type_for_tbaa_p. */
+
+static bool
+types_equal_for_same_type_for_tbaa_p (tree type1, tree type2,
+ bool lto_streaming_safe)
+{
+ /* We use same_type_for_tbaa_p to match types in the access path.
+ This check is overly conservative. */
+ type1 = TYPE_MAIN_VARIANT (type1);
+ type2 = TYPE_MAIN_VARIANT (type2);
+
+ if (TYPE_STRUCTURAL_EQUALITY_P (type1)
+ != TYPE_STRUCTURAL_EQUALITY_P (type2))
+ return false;
+ if (TYPE_STRUCTURAL_EQUALITY_P (type1))
+ return true;
+
+ if (lto_streaming_safe)
+ return type1 == type2;
+ else
+ return TYPE_CANONICAL (type1) == TYPE_CANONICAL (type2);
+}
+
+/* Compare REF1 and REF2 and return flags specifying their differences.
+ If LTO_STREAMING_SAFE is true do not use alias sets and canonical
+ types that are going to be recomputed.
+ If TBAA is true also compare TBAA metadata. */
+
+int
+ao_compare::compare_ao_refs (ao_ref *ref1, ao_ref *ref2,
+ bool lto_streaming_safe,
+ bool tbaa)
+{
+ if (TREE_THIS_VOLATILE (ref1->ref) != TREE_THIS_VOLATILE (ref2->ref))
+ return SEMANTICS;
+ tree base1 = ao_ref_base (ref1);
+ tree base2 = ao_ref_base (ref2);
+
+ if (!known_eq (ref1->offset, ref2->offset)
+ || !known_eq (ref1->size, ref2->size)
+ || !known_eq (ref1->max_size, ref2->max_size))
+ return SEMANTICS;
+
+ /* For variable accesses we need to compare actual paths
+ to check that both refs are accessing same address and the access size. */
+ if (!known_eq (ref1->size, ref1->max_size))
+ {
+ if (!operand_equal_p (TYPE_SIZE (TREE_TYPE (ref1->ref)),
+ TYPE_SIZE (TREE_TYPE (ref2->ref)), 0))
+ return SEMANTICS;
+ tree r1 = ref1->ref;
+ tree r2 = ref2->ref;
+
+ /* Handle toplevel COMPONENT_REFs of bitfields.
+ Those are special since they are not allowed in
+ ADDR_EXPR. */
+ if (TREE_CODE (r1) == COMPONENT_REF
+ && DECL_BIT_FIELD (TREE_OPERAND (r1, 1)))
{
- if (str[idx] != 'r' && str[idx] != 'R'
- && str[idx] != 'w' && str[idx] != 'W'
- && str[idx] != 'o' && str[idx] != 'O')
- err = true;
+ if (TREE_CODE (r2) != COMPONENT_REF
+ || !DECL_BIT_FIELD (TREE_OPERAND (r2, 1)))
+ return SEMANTICS;
+ tree field1 = TREE_OPERAND (r1, 1);
+ tree field2 = TREE_OPERAND (r2, 1);
+ if (!operand_equal_p (DECL_FIELD_OFFSET (field1),
+ DECL_FIELD_OFFSET (field2), 0)
+ || !operand_equal_p (DECL_FIELD_BIT_OFFSET (field1),
+ DECL_FIELD_BIT_OFFSET (field2), 0)
+ || !operand_equal_p (DECL_SIZE (field1), DECL_SIZE (field2), 0)
+ || !types_compatible_p (TREE_TYPE (r1),
+ TREE_TYPE (r2)))
+ return SEMANTICS;
+ r1 = TREE_OPERAND (r1, 0);
+ r2 = TREE_OPERAND (r2, 0);
}
- else if (str[idx + 1] != ' ')
- err = true;
+ else if (TREE_CODE (r2) == COMPONENT_REF
+ && DECL_BIT_FIELD (TREE_OPERAND (r2, 1)))
+ return SEMANTICS;
+
+ /* Similarly for bit field refs. */
+ if (TREE_CODE (r1) == BIT_FIELD_REF)
+ {
+ if (TREE_CODE (r2) != BIT_FIELD_REF
+ || !operand_equal_p (TREE_OPERAND (r1, 1),
+ TREE_OPERAND (r2, 1), 0)
+ || !operand_equal_p (TREE_OPERAND (r1, 2),
+ TREE_OPERAND (r2, 2), 0)
+ || !types_compatible_p (TREE_TYPE (r1),
+ TREE_TYPE (r2)))
+ return SEMANTICS;
+ r1 = TREE_OPERAND (r1, 0);
+ r2 = TREE_OPERAND (r2, 0);
+ }
+ else if (TREE_CODE (r2) == BIT_FIELD_REF)
+ return SEMANTICS;
+
+ /* Now we can compare the address of actual memory access. */
+ if (!operand_equal_p (r1, r2, OEP_ADDRESS_OF | OEP_MATCH_SIDE_EFFECTS))
+ return SEMANTICS;
+ }
+ /* For constant accesses we get more matches by comparing offset only. */
+ else if (!operand_equal_p (base1, base2,
+ OEP_ADDRESS_OF | OEP_MATCH_SIDE_EFFECTS))
+ return SEMANTICS;
+
+ /* We can't simply use get_object_alignment_1 on the full
+ reference as for accesses with variable indexes this reports
+ too conservative alignment. */
+ unsigned int align1, align2;
+ unsigned HOST_WIDE_INT bitpos1, bitpos2;
+ bool known1 = get_object_alignment_1 (base1, &align1, &bitpos1);
+ bool known2 = get_object_alignment_1 (base2, &align2, &bitpos2);
+ /* ??? For MEMREF get_object_alignment_1 determines aligned from
+ TYPE_ALIGN but still returns false. This seem to contradict
+ its description. So compare even if alignment is unknown. */
+ if (known1 != known2
+ || (bitpos1 != bitpos2 || align1 != align2))
+ return SEMANTICS;
+
+ /* Now we know that accesses are semantically same. */
+ int flags = 0;
+
+ /* ao_ref_base strips inner MEM_REF [&decl], recover from that here. */
+ tree rbase1 = ref1->ref;
+ if (rbase1)
+ while (handled_component_p (rbase1))
+ rbase1 = TREE_OPERAND (rbase1, 0);
+ tree rbase2 = ref2->ref;
+ while (handled_component_p (rbase2))
+ rbase2 = TREE_OPERAND (rbase2, 0);
+
+ /* MEM_REFs and TARGET_MEM_REFs record dependence cliques which are used to
+ implement restrict pointers. MR_DEPENDENCE_CLIQUE 0 means no information.
+ Otherwise we need to match bases and cliques. */
+ if ((((TREE_CODE (rbase1) == MEM_REF || TREE_CODE (rbase1) == TARGET_MEM_REF)
+ && MR_DEPENDENCE_CLIQUE (rbase1))
+ || ((TREE_CODE (rbase2) == MEM_REF || TREE_CODE (rbase2) == TARGET_MEM_REF)
+ && MR_DEPENDENCE_CLIQUE (rbase2)))
+ && (TREE_CODE (rbase1) != TREE_CODE (rbase2)
+ || MR_DEPENDENCE_CLIQUE (rbase1) != MR_DEPENDENCE_CLIQUE (rbase2)
+ || (MR_DEPENDENCE_BASE (rbase1) != MR_DEPENDENCE_BASE (rbase2))))
+ flags |= DEPENDENCE_CLIQUE;
+
+ if (!tbaa)
+ return flags;
+
+ /* Alias sets are not stable across LTO sreaming; be conservative here
+ and compare types the alias sets are ultimately based on. */
+ if (lto_streaming_safe)
+ {
+ tree t1 = ao_ref_alias_ptr_type (ref1);
+ tree t2 = ao_ref_alias_ptr_type (ref2);
+ if (!alias_ptr_types_compatible_p (t1, t2))
+ flags |= REF_ALIAS_SET;
+
+ t1 = ao_ref_base_alias_ptr_type (ref1);
+ t2 = ao_ref_base_alias_ptr_type (ref2);
+ if (!alias_ptr_types_compatible_p (t1, t2))
+ flags |= BASE_ALIAS_SET;
+ }
+ else
+ {
+ if (ao_ref_alias_set (ref1) != ao_ref_alias_set (ref2))
+ flags |= REF_ALIAS_SET;
+ if (ao_ref_base_alias_set (ref1) != ao_ref_base_alias_set (ref2))
+ flags |= BASE_ALIAS_SET;
+ }
+
+ /* Access path is used only on non-view-converted references. */
+ bool view_converted = view_converted_memref_p (rbase1);
+ if (view_converted_memref_p (rbase2) != view_converted)
+ return flags | ACCESS_PATH;
+ else if (view_converted)
+ return flags;
+
+
+ /* Find start of access paths and look for trailing arrays. */
+ tree c1 = ref1->ref, c2 = ref2->ref;
+ tree end_struct_ref1 = NULL, end_struct_ref2 = NULL;
+ int nskipped1 = 0, nskipped2 = 0;
+ int i = 0;
+
+ for (tree p1 = ref1->ref; handled_component_p (p1); p1 = TREE_OPERAND (p1, 0))
+ {
+ if (component_ref_to_zero_sized_trailing_array_p (p1))
+ end_struct_ref1 = p1;
+ if (ends_tbaa_access_path_p (p1))
+ c1 = p1, nskipped1 = i;
+ i++;
+ }
+ for (tree p2 = ref2->ref; handled_component_p (p2); p2 = TREE_OPERAND (p2, 0))
+ {
+ if (component_ref_to_zero_sized_trailing_array_p (p2))
+ end_struct_ref2 = p2;
+ if (ends_tbaa_access_path_p (p2))
+ c2 = p2, nskipped1 = i;
+ i++;
+ }
+
+ /* For variable accesses we can not rely on offset match bellow.
+ We know that paths are struturally same, so only check that
+ starts of TBAA paths did not diverge. */
+ if (!known_eq (ref1->size, ref1->max_size)
+ && nskipped1 != nskipped2)
+ return flags | ACCESS_PATH;
+
+ /* Information about trailing refs is used by
+ aliasing_component_refs_p that is applied only if paths
+ has handled components.. */
+ if (!handled_component_p (c1) && !handled_component_p (c2))
+ ;
+ else if ((end_struct_ref1 != NULL) != (end_struct_ref2 != NULL))
+ return flags | ACCESS_PATH;
+ if (end_struct_ref1
+ && TYPE_MAIN_VARIANT (TREE_TYPE (end_struct_ref1))
+ != TYPE_MAIN_VARIANT (TREE_TYPE (end_struct_ref2)))
+ return flags | ACCESS_PATH;
+
+ /* Now compare all handled components of the access path.
+ We have three oracles that cares about access paths:
+ - aliasing_component_refs_p
+ - nonoverlapping_refs_since_match_p
+ - nonoverlapping_component_refs_p
+ We need to match things these oracles compare.
+
+ It is only necessary to check types for compatibility
+ and offsets. Rest of what oracles compares are actual
+ addresses. Those are already known to be same:
+ - for constant accesses we check offsets
+ - for variable accesses we already matched
+ the path lexically with operand_equal_p. */
+ while (true)
+ {
+ bool comp1 = handled_component_p (c1);
+ bool comp2 = handled_component_p (c2);
+
+ if (comp1 != comp2)
+ return flags | ACCESS_PATH;
+ if (!comp1)
+ break;
+
+ if (TREE_CODE (c1) != TREE_CODE (c2))
+ return flags | ACCESS_PATH;
+
+ /* aliasing_component_refs_p attempts to find type match within
+ the paths. For that reason both types needs to be equal
+ with respect to same_type_for_tbaa_p. */
+ if (!types_equal_for_same_type_for_tbaa_p (TREE_TYPE (c1),
+ TREE_TYPE (c2),
+ lto_streaming_safe))
+ return flags | ACCESS_PATH;
+ if (component_ref_to_zero_sized_trailing_array_p (c1)
+ != component_ref_to_zero_sized_trailing_array_p (c2))
+ return flags | ACCESS_PATH;
+
+ /* aliasing_matching_component_refs_p compares
+ offsets within the path. Other properties are ignored.
+ Do not bother to verify offsets in variable accesses. Here we
+ already compared them by operand_equal_p so they are
+ structurally same. */
+ if (!known_eq (ref1->size, ref1->max_size))
+ {
+ poly_int64 offadj1, sztmc1, msztmc1;
+ bool reverse1;
+ get_ref_base_and_extent (c1, &offadj1, &sztmc1, &msztmc1, &reverse1);
+ poly_int64 offadj2, sztmc2, msztmc2;
+ bool reverse2;
+ get_ref_base_and_extent (c2, &offadj2, &sztmc2, &msztmc2, &reverse2);
+ if (!known_eq (offadj1, offadj2))
+ return flags | ACCESS_PATH;
+ }
+ c1 = TREE_OPERAND (c1, 0);
+ c2 = TREE_OPERAND (c2, 0);
+ }
+ /* Finally test the access type. */
+ if (!types_equal_for_same_type_for_tbaa_p (TREE_TYPE (c1),
+ TREE_TYPE (c2),
+ lto_streaming_safe))
+ return flags | ACCESS_PATH;
+ return flags;
+}
+
+/* Hash REF to HSTATE. If LTO_STREAMING_SAFE do not use alias sets
+ and canonical types. */
+void
+ao_compare::hash_ao_ref (ao_ref *ref, bool lto_streaming_safe, bool tbaa,
+ inchash::hash &hstate)
+{
+ tree base = ao_ref_base (ref);
+ tree tbase = base;
+
+ if (!known_eq (ref->size, ref->max_size))
+ {
+ tree r = ref->ref;
+ if (TREE_CODE (r) == COMPONENT_REF
+ && DECL_BIT_FIELD (TREE_OPERAND (r, 1)))
+ {
+ tree field = TREE_OPERAND (r, 1);
+ hash_operand (DECL_FIELD_OFFSET (field), hstate, 0);
+ hash_operand (DECL_FIELD_BIT_OFFSET (field), hstate, 0);
+ hash_operand (DECL_SIZE (field), hstate, 0);
+ r = TREE_OPERAND (r, 0);
+ }
+ if (TREE_CODE (r) == BIT_FIELD_REF)
+ {
+ hash_operand (TREE_OPERAND (r, 1), hstate, 0);
+ hash_operand (TREE_OPERAND (r, 2), hstate, 0);
+ r = TREE_OPERAND (r, 0);
+ }
+ hash_operand (TYPE_SIZE (TREE_TYPE (ref->ref)), hstate, 0);
+ hash_operand (r, hstate, OEP_ADDRESS_OF | OEP_MATCH_SIDE_EFFECTS);
+ }
+ else
+ {
+ hash_operand (tbase, hstate, OEP_ADDRESS_OF | OEP_MATCH_SIDE_EFFECTS);
+ hstate.add_poly_int (ref->offset);
+ hstate.add_poly_int (ref->size);
+ hstate.add_poly_int (ref->max_size);
+ }
+ if (!lto_streaming_safe && tbaa)
+ {
+ hstate.add_int (ao_ref_alias_set (ref));
+ hstate.add_int (ao_ref_base_alias_set (ref));
}
- if (err)
- internal_error ("invalid fn spec attribute \"%s\"", str);
}
diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h
index 1561ead..830ac1b 100644
--- a/gcc/tree-ssa-alias.h
+++ b/gcc/tree-ssa-alias.h
@@ -114,6 +114,8 @@ extern void ao_ref_init_from_ptr_and_size (ao_ref *, tree, tree);
extern tree ao_ref_base (ao_ref *);
extern alias_set_type ao_ref_alias_set (ao_ref *);
extern alias_set_type ao_ref_base_alias_set (ao_ref *);
+extern tree ao_ref_alias_ptr_type (ao_ref *);
+extern tree ao_ref_base_alias_ptr_type (ao_ref *);
extern bool ptr_deref_may_alias_global_p (tree);
extern bool ptr_derefs_may_alias_p (tree, tree);
extern bool ptrs_compare_unequal (tree, tree);
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 23b2902..466be20 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -1432,13 +1432,7 @@ bit_value_binop (enum tree_code code, signop sgn, int width,
else
{
if (wi::neg_p (shift))
- {
- shift = -shift;
- if (code == RSHIFT_EXPR)
- code = LSHIFT_EXPR;
- else
- code = RSHIFT_EXPR;
- }
+ break;
if (code == RSHIFT_EXPR)
{
*mask = wi::rshift (wi::ext (r1mask, width, sgn), shift, sgn);
@@ -1972,6 +1966,7 @@ evaluate_stmt (gimple *stmt)
break;
case BUILT_IN_ALIGNED_ALLOC:
+ case BUILT_IN_GOMP_ALLOC:
{
tree align = get_constant_value (gimple_call_arg (stmt, 0));
if (align
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index a046612..9fb156c 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -239,6 +239,7 @@ mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive)
CASE_BUILT_IN_ALLOCA:
case BUILT_IN_STRDUP:
case BUILT_IN_STRNDUP:
+ case BUILT_IN_GOMP_ALLOC:
return;
default:;
@@ -605,6 +606,8 @@ mark_all_reaching_defs_necessary_1 (ao_ref *ref ATTRIBUTE_UNUSED,
case BUILT_IN_CALLOC:
CASE_BUILT_IN_ALLOCA:
case BUILT_IN_FREE:
+ case BUILT_IN_GOMP_ALLOC:
+ case BUILT_IN_GOMP_FREE:
return false;
default:;
@@ -879,7 +882,8 @@ propagate_necessity (bool aggressive)
&& gimple_call_from_new_or_delete (as_a <gcall *> (stmt))
&& gimple_call_operator_delete_p (as_a <gcall *> (stmt)));
if (is_delete_operator
- || gimple_call_builtin_p (stmt, BUILT_IN_FREE))
+ || gimple_call_builtin_p (stmt, BUILT_IN_FREE)
+ || gimple_call_builtin_p (stmt, BUILT_IN_GOMP_FREE))
{
tree ptr = gimple_call_arg (stmt, 0);
gcall *def_stmt;
@@ -892,27 +896,26 @@ propagate_necessity (bool aggressive)
&& ((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_FUNCTION_CODE (def_callee) == BUILT_IN_CALLOC
+ || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_GOMP_ALLOC))
|| (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (def_callee)
&& gimple_call_from_new_or_delete (def_stmt))))
{
- if (is_delete_operator)
- {
- if (!valid_new_delete_pair_p (def_stmt, stmt))
- mark_operand_necessary (gimple_call_arg (stmt, 0));
-
- /* Delete operators can have alignment and (or) size
- as next arguments. When being a SSA_NAME, they
- must be marked as necessary. */
- if (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);
- }
- }
+ if (is_delete_operator
+ && !valid_new_delete_pair_p (def_stmt, stmt))
+ mark_operand_necessary (gimple_call_arg (stmt, 0));
+
+ /* Delete operators can have alignment and (or) size
+ as next arguments. When being a SSA_NAME, they
+ must be marked as necessary. Similarly GOMP_free. */
+ if (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;
}
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 6bb07e1..92e5a8d 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -1622,7 +1622,7 @@ sort_locs_in_loop_postorder_cmp (const void *loc1_, const void *loc2_,
/* Gathers memory references in loops. */
static void
-analyze_memory_references (void)
+analyze_memory_references (bool store_motion)
{
gimple_stmt_iterator bsi;
basic_block bb, *bbs;
@@ -1665,6 +1665,9 @@ analyze_memory_references (void)
free (bbs);
+ if (!store_motion)
+ return;
+
/* Propagate the information about accessed memory references up
the loop hierarchy. */
FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
@@ -3010,7 +3013,7 @@ fill_always_executed_in (void)
/* Compute the global information needed by the loop invariant motion pass. */
static void
-tree_ssa_lim_initialize (void)
+tree_ssa_lim_initialize (bool store_motion)
{
class loop *loop;
unsigned i;
@@ -3032,8 +3035,12 @@ tree_ssa_lim_initialize (void)
memory_accesses.refs_loaded_in_loop.quick_grow (number_of_loops (cfun));
memory_accesses.refs_stored_in_loop.create (number_of_loops (cfun));
memory_accesses.refs_stored_in_loop.quick_grow (number_of_loops (cfun));
- memory_accesses.all_refs_stored_in_loop.create (number_of_loops (cfun));
- memory_accesses.all_refs_stored_in_loop.quick_grow (number_of_loops (cfun));
+ if (store_motion)
+ {
+ memory_accesses.all_refs_stored_in_loop.create (number_of_loops (cfun));
+ memory_accesses.all_refs_stored_in_loop.quick_grow
+ (number_of_loops (cfun));
+ }
for (i = 0; i < number_of_loops (cfun); i++)
{
@@ -3041,8 +3048,9 @@ tree_ssa_lim_initialize (void)
&lim_bitmap_obstack);
bitmap_initialize (&memory_accesses.refs_stored_in_loop[i],
&lim_bitmap_obstack);
- bitmap_initialize (&memory_accesses.all_refs_stored_in_loop[i],
- &lim_bitmap_obstack);
+ if (store_motion)
+ bitmap_initialize (&memory_accesses.all_refs_stored_in_loop[i],
+ &lim_bitmap_obstack);
}
memory_accesses.ttae_cache = NULL;
@@ -3089,17 +3097,18 @@ tree_ssa_lim_finalize (void)
}
/* Moves invariants from loops. Only "expensive" invariants are moved out --
- i.e. those that are likely to be win regardless of the register pressure. */
+ i.e. those that are likely to be win regardless of the register pressure.
+ Only perform store motion if STORE_MOTION is true. */
-static unsigned int
-tree_ssa_lim (function *fun)
+unsigned int
+loop_invariant_motion_in_fun (function *fun, bool store_motion)
{
unsigned int todo = 0;
- tree_ssa_lim_initialize ();
+ tree_ssa_lim_initialize (store_motion);
/* Gathers information about memory accesses in the loops. */
- analyze_memory_references ();
+ analyze_memory_references (store_motion);
/* Fills ALWAYS_EXECUTED_IN information for basic blocks. */
fill_always_executed_in ();
@@ -3114,7 +3123,8 @@ tree_ssa_lim (function *fun)
/* Execute store motion. Force the necessary invariants to be moved
out of the loops as well. */
- do_store_motion ();
+ if (store_motion)
+ do_store_motion ();
free (rpo);
rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
@@ -3175,7 +3185,7 @@ pass_lim::execute (function *fun)
if (number_of_loops (fun) <= 1)
return 0;
- unsigned int todo = tree_ssa_lim (fun);
+ unsigned int todo = loop_invariant_motion_in_fun (fun, true);
if (!in_loop_pipeline)
loop_optimizer_finalize ();
diff --git a/gcc/tree-ssa-loop-manip.h b/gcc/tree-ssa-loop-manip.h
index e789e4f..d8e918e 100644
--- a/gcc/tree-ssa-loop-manip.h
+++ b/gcc/tree-ssa-loop-manip.h
@@ -55,7 +55,7 @@ extern void tree_transform_and_unroll_loop (class loop *, unsigned,
extern void tree_unroll_loop (class loop *, unsigned,
edge, class tree_niter_desc *);
extern tree canonicalize_loop_ivs (class loop *, tree *, bool);
-
+extern unsigned int loop_invariant_motion_in_fun (function *, bool);
#endif /* GCC_TREE_SSA_LOOP_MANIP_H */
diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c
index 5e8365d..339a0c5 100644
--- a/gcc/tree-ssa-loop.c
+++ b/gcc/tree-ssa-loop.c
@@ -529,7 +529,7 @@ tree_ssa_loop_done (void)
{
free_numbers_of_iterations_estimates (cfun);
scev_finalize ();
- loop_optimizer_finalize ();
+ loop_optimizer_finalize (cfun, true);
return 0;
}
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index 65c7b34..4ade0b6 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -3457,7 +3457,7 @@ convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2,
and 0 otherwise. */
static int
-uaddsub_overflow_check_p (gimple *stmt, gimple *use_stmt)
+uaddsub_overflow_check_p (gimple *stmt, gimple *use_stmt, tree maxval)
{
enum tree_code ccode = ERROR_MARK;
tree crhs1 = NULL_TREE, crhs2 = NULL_TREE;
@@ -3505,6 +3505,15 @@ uaddsub_overflow_check_p (gimple *stmt, gimple *use_stmt)
{
case GT_EXPR:
case LE_EXPR:
+ if (maxval)
+ {
+ /* r = a + b; r > maxval or r <= maxval */
+ if (crhs1 == lhs
+ && TREE_CODE (crhs2) == INTEGER_CST
+ && tree_int_cst_equal (crhs2, maxval))
+ return ccode == GT_EXPR ? 1 : -1;
+ break;
+ }
/* r = a - b; r > a or r <= a
r = a + b; a > r or a <= r or b > r or b <= r. */
if ((code == MINUS_EXPR && crhs1 == lhs && crhs2 == rhs1)
@@ -3514,6 +3523,8 @@ uaddsub_overflow_check_p (gimple *stmt, gimple *use_stmt)
break;
case LT_EXPR:
case GE_EXPR:
+ if (maxval)
+ break;
/* r = a - b; a < r or a >= r
r = a + b; r < a or r >= a or r < b or r >= b. */
if ((code == MINUS_EXPR && crhs1 == rhs1 && crhs2 == lhs)
@@ -3535,7 +3546,21 @@ uaddsub_overflow_check_p (gimple *stmt, gimple *use_stmt)
x = REALPART_EXPR <_7>;
_8 = IMAGPART_EXPR <_7>;
if (_8)
- and similarly for addition. */
+ and similarly for addition.
+
+ Also recognize:
+ yc = (type) y;
+ zc = (type) z;
+ x = yc + zc;
+ if (x > max)
+ where y and z have unsigned types with maximum max
+ and there are other uses of x and all of those cast x
+ back to that unsigned type and again replace it with
+ _7 = ADD_OVERFLOW (y, z);
+ _9 = REALPART_EXPR <_7>;
+ _8 = IMAGPART_EXPR <_8>;
+ if (_8)
+ and replace (utype) x with _9. */
static bool
match_uaddsub_overflow (gimple_stmt_iterator *gsi, gimple *stmt,
@@ -3548,14 +3573,16 @@ match_uaddsub_overflow (gimple_stmt_iterator *gsi, gimple *stmt,
bool use_seen = false;
bool ovf_use_seen = false;
gimple *use_stmt;
+ gimple *add_stmt = NULL;
+ bool add_first = false;
gcc_checking_assert (code == PLUS_EXPR || code == MINUS_EXPR);
if (!INTEGRAL_TYPE_P (type)
|| !TYPE_UNSIGNED (type)
|| has_zero_uses (lhs)
- || has_single_use (lhs)
- || optab_handler (code == PLUS_EXPR ? uaddv4_optab : usubv4_optab,
- TYPE_MODE (type)) == CODE_FOR_nothing)
+ || (code == MINUS_EXPR
+ && optab_handler (usubv4_optab,
+ TYPE_MODE (type)) == CODE_FOR_nothing))
return false;
FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
@@ -3564,7 +3591,7 @@ match_uaddsub_overflow (gimple_stmt_iterator *gsi, gimple *stmt,
if (is_gimple_debug (use_stmt))
continue;
- if (uaddsub_overflow_check_p (stmt, use_stmt))
+ if (uaddsub_overflow_check_p (stmt, use_stmt, NULL_TREE))
ovf_use_seen = true;
else
use_seen = true;
@@ -3572,21 +3599,205 @@ match_uaddsub_overflow (gimple_stmt_iterator *gsi, gimple *stmt,
break;
}
- if (!ovf_use_seen || !use_seen)
- return false;
-
- tree ctype = build_complex_type (type);
tree rhs1 = gimple_assign_rhs1 (stmt);
tree rhs2 = gimple_assign_rhs2 (stmt);
+ tree maxval = NULL_TREE;
+ if (!ovf_use_seen
+ || !use_seen
+ || (code == PLUS_EXPR
+ && optab_handler (uaddv4_optab,
+ TYPE_MODE (type)) == CODE_FOR_nothing))
+ {
+ if (code != PLUS_EXPR)
+ return false;
+ if (TREE_CODE (rhs1) != SSA_NAME
+ || !gimple_assign_cast_p (SSA_NAME_DEF_STMT (rhs1)))
+ return false;
+ rhs1 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (rhs1));
+ tree type1 = TREE_TYPE (rhs1);
+ if (!INTEGRAL_TYPE_P (type1)
+ || !TYPE_UNSIGNED (type1)
+ || TYPE_PRECISION (type1) >= TYPE_PRECISION (type)
+ || (TYPE_PRECISION (type1)
+ != GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type1))))
+ return false;
+ if (TREE_CODE (rhs2) == INTEGER_CST)
+ {
+ if (wi::ne_p (wi::rshift (wi::to_wide (rhs2),
+ TYPE_PRECISION (type1),
+ UNSIGNED), 0))
+ return false;
+ rhs2 = fold_convert (type1, rhs2);
+ }
+ else
+ {
+ if (TREE_CODE (rhs2) != SSA_NAME
+ || !gimple_assign_cast_p (SSA_NAME_DEF_STMT (rhs2)))
+ return false;
+ rhs2 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (rhs2));
+ tree type2 = TREE_TYPE (rhs2);
+ if (!INTEGRAL_TYPE_P (type2)
+ || !TYPE_UNSIGNED (type2)
+ || TYPE_PRECISION (type2) >= TYPE_PRECISION (type)
+ || (TYPE_PRECISION (type2)
+ != GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type2))))
+ return false;
+ }
+ if (TYPE_PRECISION (type1) >= TYPE_PRECISION (TREE_TYPE (rhs2)))
+ type = type1;
+ else
+ type = TREE_TYPE (rhs2);
+
+ if (TREE_CODE (type) != INTEGER_TYPE
+ || optab_handler (uaddv4_optab,
+ TYPE_MODE (type)) == CODE_FOR_nothing)
+ return false;
+
+ maxval = wide_int_to_tree (type, wi::max_value (TYPE_PRECISION (type),
+ UNSIGNED));
+ ovf_use_seen = false;
+ use_seen = false;
+ basic_block use_bb = NULL;
+ FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
+ {
+ use_stmt = USE_STMT (use_p);
+ if (is_gimple_debug (use_stmt))
+ continue;
+
+ if (uaddsub_overflow_check_p (stmt, use_stmt, maxval))
+ {
+ ovf_use_seen = true;
+ use_bb = gimple_bb (use_stmt);
+ }
+ else
+ {
+ if (!gimple_assign_cast_p (use_stmt)
+ || gimple_assign_rhs_code (use_stmt) == VIEW_CONVERT_EXPR)
+ return false;
+ tree use_lhs = gimple_assign_lhs (use_stmt);
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (use_lhs))
+ || (TYPE_PRECISION (TREE_TYPE (use_lhs))
+ > TYPE_PRECISION (type)))
+ return false;
+ use_seen = true;
+ }
+ }
+ if (!ovf_use_seen)
+ return false;
+ if (!useless_type_conversion_p (type, TREE_TYPE (rhs1)))
+ {
+ if (!use_seen)
+ return false;
+ tree new_rhs1 = make_ssa_name (type);
+ gimple *g = gimple_build_assign (new_rhs1, NOP_EXPR, rhs1);
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ rhs1 = new_rhs1;
+ }
+ else if (!useless_type_conversion_p (type, TREE_TYPE (rhs2)))
+ {
+ if (!use_seen)
+ return false;
+ tree new_rhs2 = make_ssa_name (type);
+ gimple *g = gimple_build_assign (new_rhs2, NOP_EXPR, rhs2);
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ rhs2 = new_rhs2;
+ }
+ else if (!use_seen)
+ {
+ /* If there are no uses of the wider addition, check if
+ forwprop has not created a narrower addition.
+ Require it to be in the same bb as the overflow check. */
+ FOR_EACH_IMM_USE_FAST (use_p, iter, rhs1)
+ {
+ use_stmt = USE_STMT (use_p);
+ if (is_gimple_debug (use_stmt))
+ continue;
+
+ if (use_stmt == stmt)
+ continue;
+
+ if (!is_gimple_assign (use_stmt)
+ || gimple_bb (use_stmt) != use_bb
+ || gimple_assign_rhs_code (use_stmt) != PLUS_EXPR)
+ continue;
+
+ if (gimple_assign_rhs1 (use_stmt) == rhs1)
+ {
+ if (!operand_equal_p (gimple_assign_rhs2 (use_stmt),
+ rhs2, 0))
+ continue;
+ }
+ else if (gimple_assign_rhs2 (use_stmt) == rhs1)
+ {
+ if (gimple_assign_rhs1 (use_stmt) != rhs2)
+ continue;
+ }
+ else
+ continue;
+
+ add_stmt = use_stmt;
+ break;
+ }
+ if (add_stmt == NULL)
+ return false;
+
+ /* If stmt and add_stmt are in the same bb, we need to find out
+ which one is earlier. If they are in different bbs, we've
+ checked add_stmt is in the same bb as one of the uses of the
+ stmt lhs, so stmt needs to dominate add_stmt too. */
+ if (gimple_bb (stmt) == gimple_bb (add_stmt))
+ {
+ gimple_stmt_iterator gsif = *gsi;
+ gimple_stmt_iterator gsib = *gsi;
+ int i;
+ /* Search both forward and backward from stmt and have a small
+ upper bound. */
+ for (i = 0; i < 128; i++)
+ {
+ if (!gsi_end_p (gsib))
+ {
+ gsi_prev_nondebug (&gsib);
+ if (gsi_stmt (gsib) == add_stmt)
+ {
+ add_first = true;
+ break;
+ }
+ }
+ else if (gsi_end_p (gsif))
+ break;
+ if (!gsi_end_p (gsif))
+ {
+ gsi_next_nondebug (&gsif);
+ if (gsi_stmt (gsif) == add_stmt)
+ break;
+ }
+ }
+ if (i == 128)
+ return false;
+ if (add_first)
+ *gsi = gsi_for_stmt (add_stmt);
+ }
+ }
+ }
+
+ tree ctype = build_complex_type (type);
gcall *g = gimple_build_call_internal (code == PLUS_EXPR
? IFN_ADD_OVERFLOW : IFN_SUB_OVERFLOW,
2, rhs1, rhs2);
tree ctmp = make_ssa_name (ctype);
gimple_call_set_lhs (g, ctmp);
gsi_insert_before (gsi, g, GSI_SAME_STMT);
- gassign *g2 = gimple_build_assign (lhs, REALPART_EXPR,
+ tree new_lhs = maxval ? make_ssa_name (type) : lhs;
+ gassign *g2 = gimple_build_assign (new_lhs, REALPART_EXPR,
build1 (REALPART_EXPR, type, ctmp));
- gsi_replace (gsi, g2, true);
+ if (maxval)
+ {
+ gsi_insert_before (gsi, g2, GSI_SAME_STMT);
+ if (add_first)
+ *gsi = gsi_for_stmt (stmt);
+ }
+ else
+ gsi_replace (gsi, g2, true);
tree ovf = make_ssa_name (type);
g2 = gimple_build_assign (ovf, IMAGPART_EXPR,
build1 (IMAGPART_EXPR, type, ctmp));
@@ -3597,9 +3808,20 @@ match_uaddsub_overflow (gimple_stmt_iterator *gsi, gimple *stmt,
if (is_gimple_debug (use_stmt))
continue;
- int ovf_use = uaddsub_overflow_check_p (stmt, use_stmt);
+ int ovf_use = uaddsub_overflow_check_p (stmt, use_stmt, maxval);
if (ovf_use == 0)
- continue;
+ {
+ if (maxval)
+ {
+ tree use_lhs = gimple_assign_lhs (use_stmt);
+ gimple_assign_set_rhs1 (use_stmt, new_lhs);
+ if (useless_type_conversion_p (TREE_TYPE (use_lhs),
+ TREE_TYPE (new_lhs)))
+ gimple_assign_set_rhs_code (use_stmt, SSA_NAME);
+ update_stmt (use_stmt);
+ }
+ continue;
+ }
if (gimple_code (use_stmt) == GIMPLE_COND)
{
gcond *cond_stmt = as_a <gcond *> (use_stmt);
@@ -3629,6 +3851,18 @@ match_uaddsub_overflow (gimple_stmt_iterator *gsi, gimple *stmt,
}
update_stmt (use_stmt);
}
+ if (maxval)
+ {
+ gimple_stmt_iterator gsi2 = gsi_for_stmt (stmt);
+ gsi_remove (&gsi2, true);
+ if (add_stmt)
+ {
+ gimple *g = gimple_build_assign (gimple_assign_lhs (add_stmt),
+ new_lhs);
+ gsi2 = gsi_for_stmt (add_stmt);
+ gsi_replace (&gsi2, g, true);
+ }
+ }
return true;
}
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 90877e3..a17a09a 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -524,7 +524,7 @@ static struct
static bool do_partial_partial;
static pre_expr bitmap_find_leader (bitmap_set_t, unsigned int);
static void bitmap_value_insert_into_set (bitmap_set_t, pre_expr);
-static void bitmap_value_replace_in_set (bitmap_set_t, pre_expr);
+static bool bitmap_value_replace_in_set (bitmap_set_t, pre_expr);
static void bitmap_set_copy (bitmap_set_t, bitmap_set_t);
static bool bitmap_set_contains_value (bitmap_set_t, unsigned int);
static void bitmap_insert_into_set (bitmap_set_t, pre_expr);
@@ -805,38 +805,105 @@ bitmap_set_free (bitmap_set_t set)
bitmap_clear (&set->values);
}
+static void
+pre_expr_DFS (pre_expr expr, bitmap_set_t set, bitmap val_visited,
+ vec<pre_expr> &post);
+
+/* DFS walk leaders of VAL to their operands with leaders in SET, collecting
+ expressions in SET in postorder into POST. */
+
+static void
+pre_expr_DFS (unsigned val, bitmap_set_t set, bitmap val_visited,
+ vec<pre_expr> &post)
+{
+ unsigned int i;
+ bitmap_iterator bi;
+
+ /* Iterate over all leaders and DFS recurse. Borrowed from
+ bitmap_find_leader. */
+ bitmap exprset = value_expressions[val];
+ if (!exprset->first->next)
+ {
+ EXECUTE_IF_SET_IN_BITMAP (exprset, 0, i, bi)
+ if (bitmap_bit_p (&set->expressions, i))
+ pre_expr_DFS (expression_for_id (i), set, val_visited, post);
+ return;
+ }
+
+ EXECUTE_IF_AND_IN_BITMAP (exprset, &set->expressions, 0, i, bi)
+ pre_expr_DFS (expression_for_id (i), set, val_visited, post);
+}
+
+/* DFS walk EXPR to its operands with leaders in SET, collecting
+ expressions in SET in postorder into POST. */
+
+static void
+pre_expr_DFS (pre_expr expr, bitmap_set_t set, bitmap val_visited,
+ vec<pre_expr> &post)
+{
+ switch (expr->kind)
+ {
+ case NARY:
+ {
+ vn_nary_op_t nary = PRE_EXPR_NARY (expr);
+ for (unsigned i = 0; i < nary->length; i++)
+ {
+ if (TREE_CODE (nary->op[i]) != SSA_NAME)
+ continue;
+ unsigned int op_val_id = VN_INFO (nary->op[i])->value_id;
+ /* If we already found a leader for the value we've
+ recursed already. Avoid the costly bitmap_find_leader. */
+ if (bitmap_bit_p (&set->values, op_val_id)
+ && bitmap_set_bit (val_visited, op_val_id))
+ pre_expr_DFS (op_val_id, set, val_visited, post);
+ }
+ break;
+ }
+ case REFERENCE:
+ {
+ vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
+ vec<vn_reference_op_s> operands = ref->operands;
+ vn_reference_op_t operand;
+ for (unsigned i = 0; operands.iterate (i, &operand); i++)
+ {
+ tree op[3];
+ op[0] = operand->op0;
+ op[1] = operand->op1;
+ op[2] = operand->op2;
+ for (unsigned n = 0; n < 3; ++n)
+ {
+ if (!op[n] || TREE_CODE (op[n]) != SSA_NAME)
+ continue;
+ unsigned op_val_id = VN_INFO (op[n])->value_id;
+ if (bitmap_bit_p (&set->values, op_val_id)
+ && bitmap_set_bit (val_visited, op_val_id))
+ pre_expr_DFS (op_val_id, set, val_visited, post);
+ }
+ }
+ break;
+ }
+ default:;
+ }
+ post.quick_push (expr);
+}
/* Generate an topological-ordered array of bitmap set SET. */
static vec<pre_expr>
sorted_array_from_bitmap_set (bitmap_set_t set)
{
- unsigned int i, j;
- bitmap_iterator bi, bj;
+ unsigned int i;
+ bitmap_iterator bi;
vec<pre_expr> result;
/* Pre-allocate enough space for the array. */
result.create (bitmap_count_bits (&set->expressions));
+ auto_bitmap val_visited (&grand_bitmap_obstack);
+ bitmap_tree_view (val_visited);
FOR_EACH_VALUE_ID_IN_SET (set, i, bi)
- {
- /* The number of expressions having a given value is usually
- relatively small. Thus, rather than making a vector of all
- the expressions and sorting it by value-id, we walk the values
- and check in the reverse mapping that tells us what expressions
- have a given value, to filter those in our set. As a result,
- the expressions are inserted in value-id order, which means
- topological order.
-
- If this is somehow a significant lose for some cases, we can
- choose which set to walk based on the set size. */
- bitmap exprset = value_expressions[i];
- EXECUTE_IF_SET_IN_BITMAP (exprset, 0, j, bj)
- {
- if (bitmap_bit_p (&set->expressions, j))
- result.quick_push (expression_for_id (j));
- }
- }
+ if (bitmap_set_bit (val_visited, i))
+ pre_expr_DFS (i, set, val_visited, result);
return result;
}
@@ -908,14 +975,14 @@ bitmap_set_equal (bitmap_set_t a, bitmap_set_t b)
}
/* Replace an instance of EXPR's VALUE with EXPR in SET if it exists,
- and add it otherwise. */
+ and add it otherwise. Return true if any changes were made. */
-static void
+static bool
bitmap_value_replace_in_set (bitmap_set_t set, pre_expr expr)
{
unsigned int val = get_expr_value_id (expr);
if (value_id_constant_p (val))
- return;
+ return false;
if (bitmap_set_contains_value (set, val))
{
@@ -936,13 +1003,14 @@ bitmap_value_replace_in_set (bitmap_set_t set, pre_expr expr)
if (bitmap_clear_bit (&set->expressions, i))
{
bitmap_set_bit (&set->expressions, get_expression_id (expr));
- return;
+ return i != get_expression_id (expr);
}
}
gcc_unreachable ();
}
- else
- bitmap_insert_into_set (set, expr);
+
+ bitmap_insert_into_set (set, expr);
+ return true;
}
/* Insert EXPR into SET if EXPR's value is not already present in
@@ -1762,9 +1830,8 @@ phi_translate (bitmap_set_t dest, pre_expr expr,
static void
phi_translate_set (bitmap_set_t dest, bitmap_set_t set, edge e)
{
- vec<pre_expr> exprs;
- pre_expr expr;
- int i;
+ bitmap_iterator bi;
+ unsigned int i;
if (gimple_seq_empty_p (phi_nodes (e->dest)))
{
@@ -1772,24 +1839,22 @@ phi_translate_set (bitmap_set_t dest, bitmap_set_t set, edge e)
return;
}
- exprs = sorted_array_from_bitmap_set (set);
/* Allocate the phi-translation cache where we have an idea about
its size. hash-table implementation internals tell us that
allocating the table to fit twice the number of elements will
make sure we do not usually re-allocate. */
if (!PHI_TRANS_TABLE (e->src))
- PHI_TRANS_TABLE (e->src)
- = new hash_table<expr_pred_trans_d> (2 * exprs.length ());
- FOR_EACH_VEC_ELT (exprs, i, expr)
+ PHI_TRANS_TABLE (e->src) = new hash_table<expr_pred_trans_d>
+ (2 * bitmap_count_bits (&set->expressions));
+ FOR_EACH_EXPR_ID_IN_SET (set, i, bi)
{
- pre_expr translated;
- translated = phi_translate (dest, expr, set, NULL, e);
+ pre_expr expr = expression_for_id (i);
+ pre_expr translated = phi_translate (dest, expr, set, NULL, e);
if (!translated)
continue;
bitmap_insert_into_set (dest, translated);
}
- exprs.release ();
}
/* Find the leader for a value (i.e., the name representing that
@@ -1819,6 +1884,11 @@ bitmap_find_leader (bitmap_set_t set, unsigned int val)
bitmap_iterator bi;
bitmap exprset = value_expressions[val];
+ if (!exprset->first->next)
+ EXECUTE_IF_SET_IN_BITMAP (exprset, 0, i, bi)
+ if (bitmap_bit_p (&set->expressions, i))
+ return expression_for_id (i);
+
EXECUTE_IF_AND_IN_BITMAP (exprset, &set->expressions, 0, i, bi)
return expression_for_id (i);
}
@@ -1991,6 +2061,14 @@ clean (bitmap_set_t set1, bitmap_set_t set2 = NULL)
}
}
exprs.release ();
+
+ if (flag_checking)
+ {
+ unsigned j;
+ bitmap_iterator bi;
+ FOR_EACH_EXPR_ID_IN_SET (set1, j, bi)
+ gcc_assert (valid_in_sets (set1, set2, expression_for_id (j)));
+ }
}
/* Clean the set of expressions that are no longer valid in SET because
@@ -3003,7 +3081,8 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
vn_info->value_id = get_next_value_id ();
nameexpr = get_or_alloc_expr_for_name (forcedname);
add_to_value (vn_info->value_id, nameexpr);
- bitmap_value_replace_in_set (NEW_SETS (block), nameexpr);
+ if (NEW_SETS (block))
+ bitmap_value_replace_in_set (NEW_SETS (block), nameexpr);
bitmap_value_replace_in_set (AVAIL_OUT (block), nameexpr);
}
@@ -3086,7 +3165,8 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
&& expr->kind != REFERENCE)
{
if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Skipping insertion of phi for partial redundancy: Looks like an induction variable\n");
+ fprintf (dump_file, "Skipping insertion of phi for partial "
+ "redundancy: Looks like an induction variable\n");
nophi = true;
}
}
@@ -3094,6 +3174,10 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
/* Make the necessary insertions. */
FOR_EACH_EDGE (pred, ei, block->preds)
{
+ /* When we are not inserting a PHI node do not bother inserting
+ into places that do not dominate the anticipated computations. */
+ if (nophi && !dominated_by_p (CDI_DOMINATORS, block, pred->src))
+ continue;
gimple_seq stmts = NULL;
tree builtexpr;
bprime = pred->src;
@@ -3170,8 +3254,8 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
bitmap_insert_into_set (PHI_GEN (block), newphi);
bitmap_value_replace_in_set (AVAIL_OUT (block),
newphi);
- bitmap_insert_into_set (NEW_SETS (block),
- newphi);
+ if (NEW_SETS (block))
+ bitmap_insert_into_set (NEW_SETS (block), newphi);
/* If we insert a PHI node for a conversion of another PHI node
in the same basic-block try to preserve range information.
@@ -3236,15 +3320,14 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
*/
static bool
-do_pre_regular_insertion (basic_block block, basic_block dom)
+do_pre_regular_insertion (basic_block block, basic_block dom,
+ vec<pre_expr> exprs)
{
bool new_stuff = false;
- vec<pre_expr> exprs;
pre_expr expr;
auto_vec<pre_expr, 2> avail;
int i;
- exprs = sorted_array_from_bitmap_set (ANTIC_IN (block));
avail.safe_grow (EDGE_COUNT (block->preds), true);
FOR_EACH_VEC_ELT (exprs, i, expr)
@@ -3388,11 +3471,11 @@ do_pre_regular_insertion (basic_block block, basic_block dom)
add_to_value (val, newe);
bitmap_value_replace_in_set (AVAIL_OUT (block), newe);
bitmap_insert_into_set (NEW_SETS (block), newe);
+ bitmap_insert_into_set (PHI_GEN (block), newe);
}
}
}
- exprs.release ();
return new_stuff;
}
@@ -3404,15 +3487,14 @@ do_pre_regular_insertion (basic_block block, basic_block dom)
remove the later computation. */
static bool
-do_pre_partial_partial_insertion (basic_block block, basic_block dom)
+do_pre_partial_partial_insertion (basic_block block, basic_block dom,
+ vec<pre_expr> exprs)
{
bool new_stuff = false;
- vec<pre_expr> exprs;
pre_expr expr;
auto_vec<pre_expr, 2> avail;
int i;
- exprs = sorted_array_from_bitmap_set (PA_IN (block));
avail.safe_grow (EDGE_COUNT (block->preds), true);
FOR_EACH_VEC_ELT (exprs, i, expr)
@@ -3527,7 +3609,6 @@ do_pre_partial_partial_insertion (basic_block block, basic_block dom)
}
}
- exprs.release ();
return new_stuff;
}
@@ -3687,7 +3768,10 @@ insert (void)
NEW_SETS (bb) = bitmap_set_new ();
int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
+ int *bb_rpo = XNEWVEC (int, last_basic_block_for_fn (cfun) + 1);
int rpo_num = pre_and_rev_post_order_compute (NULL, rpo, false);
+ for (int i = 0; i < rpo_num; ++i)
+ bb_rpo[rpo[i]] = i;
int num_iterations = 0;
bool changed;
@@ -3698,18 +3782,6 @@ insert (void)
fprintf (dump_file, "Starting insert iteration %d\n", num_iterations);
changed = false;
- /* Insert expressions for hoisting. Do a backward walk here since
- inserting into BLOCK exposes new opportunities in its predecessors.
- Since PRE and hoist insertions can cause back-to-back iteration
- limit that on the hoist side. */
- if (flag_code_hoisting
- && num_iterations <= param_max_pre_hoist_insert_iterations)
- for (int idx = rpo_num - 1; idx >= 0; --idx)
- {
- basic_block block = BASIC_BLOCK_FOR_FN (cfun, rpo[idx]);
- if (EDGE_COUNT (block->succs) >= 2)
- changed |= do_hoist_insertion (block);
- }
for (int idx = 0; idx < rpo_num; ++idx)
{
basic_block block = BASIC_BLOCK_FOR_FN (cfun, rpo[idx]);
@@ -3723,26 +3795,48 @@ insert (void)
/* First, update the AVAIL_OUT set with anything we may have
inserted higher up in the dominator tree. */
newset = NEW_SETS (dom);
- if (newset)
+
+ /* Note that we need to value_replace both NEW_SETS, and
+ AVAIL_OUT. For both the case of NEW_SETS, the value may be
+ represented by some non-simple expression here that we want
+ to replace it with. */
+ bool avail_out_changed = false;
+ FOR_EACH_EXPR_ID_IN_SET (newset, i, bi)
{
- /* Note that we need to value_replace both NEW_SETS, and
- AVAIL_OUT. For both the case of NEW_SETS, the value may be
- represented by some non-simple expression here that we want
- to replace it with. */
- FOR_EACH_EXPR_ID_IN_SET (newset, i, bi)
- {
- pre_expr expr = expression_for_id (i);
- bitmap_value_replace_in_set (NEW_SETS (block), expr);
- bitmap_value_replace_in_set (AVAIL_OUT (block), expr);
- }
+ pre_expr expr = expression_for_id (i);
+ bitmap_value_replace_in_set (NEW_SETS (block), expr);
+ avail_out_changed
+ |= bitmap_value_replace_in_set (AVAIL_OUT (block), expr);
+ }
+ /* We need to iterate if AVAIL_OUT of an already processed
+ block source changed. */
+ if (avail_out_changed && !changed)
+ {
+ edge_iterator ei;
+ edge e;
+ FOR_EACH_EDGE (e, ei, block->succs)
+ if (e->dest->index != EXIT_BLOCK
+ && bb_rpo[e->dest->index] < idx)
+ changed = true;
}
/* Insert expressions for partial redundancies. */
if (flag_tree_pre && !single_pred_p (block))
{
- changed |= do_pre_regular_insertion (block, dom);
+ vec<pre_expr> exprs
+ = sorted_array_from_bitmap_set (ANTIC_IN (block));
+ /* Sorting is not perfect, iterate locally. */
+ while (do_pre_regular_insertion (block, dom, exprs))
+ ;
+ exprs.release ();
if (do_partial_partial)
- changed |= do_pre_partial_partial_insertion (block, dom);
+ {
+ exprs = sorted_array_from_bitmap_set (PA_IN (block));
+ while (do_pre_partial_partial_insertion (block, dom,
+ exprs))
+ ;
+ exprs.release ();
+ }
}
}
}
@@ -3757,7 +3851,31 @@ insert (void)
statistics_histogram_event (cfun, "insert iterations", num_iterations);
+ /* AVAIL_OUT is not needed after insertion so we don't have to
+ propagate NEW_SETS from hoist insertion. */
+ FOR_ALL_BB_FN (bb, cfun)
+ {
+ bitmap_set_free (NEW_SETS (bb));
+ bitmap_set_pool.remove (NEW_SETS (bb));
+ NEW_SETS (bb) = NULL;
+ }
+
+ /* Insert expressions for hoisting. Do a backward walk here since
+ inserting into BLOCK exposes new opportunities in its predecessors.
+ Since PRE and hoist insertions can cause back-to-back iteration
+ and we are interested in PRE insertion exposed hoisting opportunities
+ but not in hoisting exposed PRE ones do hoist insertion only after
+ PRE insertion iteration finished and do not iterate it. */
+ if (flag_code_hoisting)
+ for (int idx = rpo_num - 1; idx >= 0; --idx)
+ {
+ basic_block block = BASIC_BLOCK_FOR_FN (cfun, rpo[idx]);
+ if (EDGE_COUNT (block->succs) >= 2)
+ changed |= do_hoist_insertion (block);
+ }
+
free (rpo);
+ free (bb_rpo);
}
diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c
index 87dbf55..bc656ff 100644
--- a/gcc/tree-ssa-propagate.c
+++ b/gcc/tree-ssa-propagate.c
@@ -1549,3 +1549,63 @@ propagate_tree_value_into_stmt (gimple_stmt_iterator *gsi, tree val)
else
gcc_unreachable ();
}
+
+/* Check exits of each loop in FUN, walk over loop closed PHIs in
+ each exit basic block and propagate degenerate PHIs. */
+
+unsigned
+clean_up_loop_closed_phi (function *fun)
+{
+ unsigned i;
+ edge e;
+ gphi *phi;
+ tree rhs;
+ tree lhs;
+ gphi_iterator gsi;
+ struct loop *loop;
+
+ /* Avoid possibly quadratic work when scanning for loop exits across
+ all loops of a nest. */
+ if (!loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
+ return 0;
+
+ /* replace_uses_by might purge dead EH edges and we want it to also
+ remove dominated blocks. */
+ calculate_dominance_info (CDI_DOMINATORS);
+
+ /* Walk over loop in function. */
+ FOR_EACH_LOOP_FN (fun, loop, 0)
+ {
+ /* Check each exit edege of loop. */
+ auto_vec<edge> exits = get_loop_exit_edges (loop);
+ FOR_EACH_VEC_ELT (exits, i, e)
+ if (single_pred_p (e->dest))
+ /* Walk over loop-closed PHIs. */
+ for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi);)
+ {
+ phi = gsi.phi ();
+ rhs = gimple_phi_arg_def (phi, 0);
+ lhs = gimple_phi_result (phi);
+
+ if (rhs && may_propagate_copy (lhs, rhs))
+ {
+ /* Dump details. */
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, " Replacing '");
+ print_generic_expr (dump_file, lhs, dump_flags);
+ fprintf (dump_file, "' with '");
+ print_generic_expr (dump_file, rhs, dump_flags);
+ fprintf (dump_file, "'\n");
+ }
+
+ replace_uses_by (lhs, rhs);
+ remove_phi_node (&gsi, true);
+ }
+ else
+ gsi_next (&gsi);
+ }
+ }
+
+ return 0;
+}
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index a2ca171..e594230 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see
#include "builtins.h"
#include "gimplify.h"
#include "case-cfn-macros.h"
+#include "tree-ssa-reassoc.h"
/* This is a simple global reassociation pass. It is, in part, based
on the LLVM pass of the same name (They do some things more/less
@@ -188,15 +189,6 @@ static struct
int pows_created;
} reassociate_stats;
-/* Operator, rank pair. */
-struct operand_entry
-{
- unsigned int rank;
- unsigned int id;
- tree op;
- unsigned int count;
- gimple *stmt_to_insert;
-};
static object_allocator<operand_entry> operand_entry_pool
("operand entry pool");
@@ -226,7 +218,7 @@ static bool reassoc_stmt_dominates_stmt_p (gimple *, gimple *);
/* Wrapper around gsi_remove, which adjusts gimple_uid of debug stmts
possibly added by gsi_remove. */
-bool
+static bool
reassoc_remove_stmt (gimple_stmt_iterator *gsi)
{
gimple *stmt = gsi_stmt (*gsi);
@@ -425,41 +417,43 @@ get_rank (tree e)
long rank;
tree op;
- if (SSA_NAME_IS_DEFAULT_DEF (e))
- return find_operand_rank (e);
-
- stmt = SSA_NAME_DEF_STMT (e);
- if (gimple_code (stmt) == GIMPLE_PHI)
- return phi_rank (stmt);
-
- if (!is_gimple_assign (stmt))
- return bb_rank[gimple_bb (stmt)->index];
-
/* If we already have a rank for this expression, use that. */
rank = find_operand_rank (e);
if (rank != -1)
return rank;
- /* Otherwise, find the maximum rank for the operands. As an
- exception, remove the bias from loop-carried phis when propagating
- the rank so that dependent operations are not also biased. */
- /* Simply walk over all SSA uses - this takes advatage of the
- fact that non-SSA operands are is_gimple_min_invariant and
- thus have rank 0. */
- rank = 0;
- FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
- rank = propagate_rank (rank, op);
+ stmt = SSA_NAME_DEF_STMT (e);
+ if (gimple_code (stmt) == GIMPLE_PHI)
+ rank = phi_rank (stmt);
+
+ else if (!is_gimple_assign (stmt))
+ rank = bb_rank[gimple_bb (stmt)->index];
+
+ else
+ {
+ /* Otherwise, find the maximum rank for the operands. As an
+ exception, remove the bias from loop-carried phis when propagating
+ the rank so that dependent operations are not also biased. */
+ /* Simply walk over all SSA uses - this takes advatage of the
+ fact that non-SSA operands are is_gimple_min_invariant and
+ thus have rank 0. */
+ rank = 0;
+ FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
+ rank = propagate_rank (rank, op);
+
+ rank += 1;
+ }
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Rank for ");
print_generic_expr (dump_file, e);
- fprintf (dump_file, " is %ld\n", (rank + 1));
+ fprintf (dump_file, " is %ld\n", rank);
}
/* Note the rank in the hashtable so we don't recompute it. */
- insert_operand_rank (e, (rank + 1));
- return (rank + 1);
+ insert_operand_rank (e, rank);
+ return rank;
}
/* Constants, globals, etc., are rank 0 */
@@ -2406,18 +2400,7 @@ optimize_ops_list (enum tree_code opcode,
For more information see comments above fold_test_range in fold-const.c,
this implementation is for GIMPLE. */
-struct range_entry
-{
- tree exp;
- tree low;
- tree high;
- bool in_p;
- bool strict_overflow_p;
- unsigned int idx, next;
-};
-void dump_range_entry (FILE *file, struct range_entry *r);
-void debug_range_entry (struct range_entry *r);
/* Dump the range entry R to FILE, skipping its expression if SKIP_EXP. */
@@ -2447,7 +2430,7 @@ debug_range_entry (struct range_entry *r)
an SSA_NAME and STMT argument is ignored, otherwise STMT
argument should be a GIMPLE_COND. */
-static void
+void
init_range_entry (struct range_entry *r, tree exp, gimple *stmt)
{
int in_p;
@@ -4284,7 +4267,7 @@ suitable_cond_bb (basic_block bb, basic_block test_bb, basic_block *other_bb,
range test optimization, all SSA_NAMEs set in the bb are consumed
in the bb and there are no PHIs. */
-static bool
+bool
no_side_effect_bb (basic_block bb)
{
gimple_stmt_iterator gsi;
diff --git a/gcc/tree-ssa-reassoc.h b/gcc/tree-ssa-reassoc.h
new file mode 100644
index 0000000..dc7f59f
--- /dev/null
+++ b/gcc/tree-ssa-reassoc.h
@@ -0,0 +1,48 @@
+/* Reassociation for trees.
+ Copyright (C) 2020 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/>. */
+
+#ifndef GCC_SSA_REASSOC_H
+#define GCC_SSA_REASSOC_H
+
+/* Operator, rank pair. */
+struct operand_entry
+{
+ unsigned int rank;
+ unsigned int id;
+ tree op;
+ unsigned int count;
+ gimple *stmt_to_insert;
+};
+
+struct range_entry
+{
+ tree exp;
+ tree low;
+ tree high;
+ bool in_p;
+ bool strict_overflow_p;
+ unsigned int idx, next;
+};
+
+void dump_range_entry (FILE *file, struct range_entry *r);
+void debug_range_entry (struct range_entry *r);
+void init_range_entry (struct range_entry *r, tree exp, gimple *stmt);
+bool no_side_effect_bb (basic_block bb);
+
+#endif /* GCC_SSA_REASSOC_H */
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 8c93e51..81990fc 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -702,7 +702,10 @@ vn_reference_eq (const_vn_reference_t const vr1, const_vn_reference_t const vr2)
if (vr1->operands == vr2->operands)
return true;
- if (!expressions_equal_p (TYPE_SIZE (vr1->type), TYPE_SIZE (vr2->type)))
+ if (COMPLETE_TYPE_P (vr1->type) != COMPLETE_TYPE_P (vr2->type)
+ || (COMPLETE_TYPE_P (vr1->type)
+ && !expressions_equal_p (TYPE_SIZE (vr1->type),
+ TYPE_SIZE (vr2->type))))
return false;
if (INTEGRAL_TYPE_P (vr1->type)
@@ -4126,13 +4129,27 @@ vn_nary_op_insert_stmt (gimple *stmt, tree result)
static inline hashval_t
vn_phi_compute_hash (vn_phi_t vp1)
{
- inchash::hash hstate (EDGE_COUNT (vp1->block->preds) > 2
- ? vp1->block->index : EDGE_COUNT (vp1->block->preds));
+ inchash::hash hstate;
tree phi1op;
tree type;
edge e;
edge_iterator ei;
+ hstate.add_int (EDGE_COUNT (vp1->block->preds));
+ switch (EDGE_COUNT (vp1->block->preds))
+ {
+ case 1:
+ break;
+ case 2:
+ if (vp1->block->loop_father->header == vp1->block)
+ ;
+ else
+ break;
+ /* Fallthru. */
+ default:
+ hstate.add_int (vp1->block->index);
+ }
+
/* If all PHI arguments are constants we need to distinguish
the PHI node via its type. */
type = vp1->type;
@@ -4277,11 +4294,12 @@ vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2)
/* Any phi in the same block will have it's arguments in the
same edge order, because of how we store phi nodes. */
- for (unsigned i = 0; i < EDGE_COUNT (vp1->block->preds); ++i)
+ unsigned nargs = EDGE_COUNT (vp1->block->preds);
+ for (unsigned i = 0; i < nargs; ++i)
{
tree phi1op = vp1->phiargs[i];
tree phi2op = vp2->phiargs[i];
- if (phi1op == VN_TOP || phi2op == VN_TOP)
+ if (phi1op == phi2op)
continue;
if (!expressions_equal_p (phi1op, phi2op))
return false;
@@ -5612,8 +5630,8 @@ expressions_equal_p (tree e1, tree e2)
if (e1 == VN_TOP || e2 == VN_TOP)
return true;
- /* If only one of them is null, they cannot be equal. */
- if (!e1 || !e2)
+ /* SSA_NAME compare pointer equal. */
+ if (TREE_CODE (e1) == SSA_NAME || TREE_CODE (e2) == SSA_NAME)
return false;
/* Now perform the actual comparison. */
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index ebb17cd..522b2d4 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -46,7 +46,6 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-propagate.h"
#include "tree-ssa-strlen.h"
#include "tree-hash-traits.h"
-#include "tree-object-size.h"
#include "builtins.h"
#include "target.h"
#include "diagnostic-core.h"
@@ -1667,7 +1666,8 @@ valid_builtin_call (gimple *stmt)
strinfo. */
static void
-adjust_last_stmt (strinfo *si, gimple *stmt, bool is_strcat)
+adjust_last_stmt (strinfo *si, gimple *stmt, bool is_strcat,
+ pointer_query &ptr_qry)
{
tree vuse, callee, len;
struct laststmt_struct last = laststmt;
@@ -1754,7 +1754,9 @@ adjust_last_stmt (strinfo *si, gimple *stmt, bool is_strcat)
/* Don't fold away an out of bounds access, as this defeats proper
warnings. */
tree dst = gimple_call_arg (last.stmt, 0);
- tree size = compute_objsize (dst, 0);
+
+ access_ref aref;
+ tree size = compute_objsize (dst, 1, &aref, &ptr_qry);
if (size && tree_int_cst_lt (size, len))
return;
}
@@ -1912,8 +1914,7 @@ maybe_set_strlen_range (tree lhs, tree src, tree bound)
to allow accesses across subobject boundaries. */
static void
-maybe_warn_overflow (gimple *stmt, tree len,
- range_query *rvals = NULL,
+maybe_warn_overflow (gimple *stmt, tree len, pointer_query &ptr_qry,
strinfo *si = NULL, bool plus_one = false,
bool rawmem = false)
{
@@ -1933,160 +1934,39 @@ maybe_warn_overflow (gimple *stmt, tree len,
dest = gimple_call_arg (stmt, 0);
writefn = gimple_call_fndecl (stmt);
}
+ else
+ return;
if (TREE_NO_WARNING (dest))
return;
+ const int ostype = rawmem ? 0 : 1;
+
/* Use maximum precision to avoid overflow in the addition below.
Make sure all operands have the same precision to keep wide_int
from ICE'ing. */
- /* Convenience constants. */
- const widest_int diff_min
- = wi::to_widest (TYPE_MIN_VALUE (ptrdiff_type_node));
- const widest_int diff_max
- = wi::to_widest (TYPE_MAX_VALUE (ptrdiff_type_node));
- const widest_int size_max
- = wi::to_widest (TYPE_MAX_VALUE (size_type_node));
-
- /* The offset into the destination object computed below and not
- reflected in DESTSIZE. */
- widest_int offrng[2] = { 0, 0 };
-
- if (!si)
- {
- /* If no destination STRINFO was provided try to get it from
- the DEST argument. */
- tree ref = dest;
- if (TREE_CODE (ref) == ARRAY_REF)
- {
- /* Handle stores to VLAs (represented as
- ARRAY_REF (MEM_REF (vlaptr, 0), N]. */
- tree off = TREE_OPERAND (ref, 1);
- ref = TREE_OPERAND (ref, 0);
- wide_int rng[2];
- if (get_range (off, stmt, rng, rvals))
- {
- /* Convert offsets to the maximum precision. */
- offrng[0] = widest_int::from (rng[0], SIGNED);
- offrng[1] = widest_int::from (rng[1], SIGNED);
- }
- else
- {
- offrng[0] = diff_min;
- offrng[1] = diff_max;
- }
- }
-
- if (TREE_CODE (ref) == MEM_REF)
- {
- tree mem_off = TREE_OPERAND (ref, 1);
- ref = TREE_OPERAND (ref, 0);
- wide_int rng[2];
- if (get_range (mem_off, stmt, rng, rvals))
- {
- offrng[0] += widest_int::from (rng[0], SIGNED);
- offrng[1] += widest_int::from (rng[1], SIGNED);
- }
- else
- {
- offrng[0] = diff_min;
- offrng[1] = diff_max;
- }
- }
-
- wide_int rng[2];
- if (int idx = get_stridx (ref, rng, rvals))
- {
- si = get_strinfo (idx);
- offrng[0] += widest_int::from (rng[0], SIGNED);
- offrng[1] += widest_int::from (rng[1], SIGNED);
- }
- }
-
- /* The allocation call if the destination object was allocated
- by one. */
- gimple *alloc_call = NULL;
- /* The DECL of the destination object if known and not dynamically
- allocated. */
- tree destdecl = NULL_TREE;
- /* The offset into the destination object set by compute_objsize
- but already reflected in DESTSIZE. */
- tree destoff = NULL_TREE;
+ access_ref aref;
/* The size of the destination region (which is smaller than
the destination object for stores at a non-zero offset). */
- tree destsize = NULL_TREE;
-
- /* Compute the range of sizes of the destination object. The range
- is constant for declared objects but may be a range for allocated
- objects. */
- widest_int sizrng[2] = { 0, 0 };
- if (si)
- {
- wide_int rng[2];
- destsize = gimple_call_alloc_size (si->alloc, rng, rvals);
- if (destsize)
- {
- sizrng[0] = widest_int::from (rng[0], UNSIGNED);
- sizrng[1] = widest_int::from (rng[1], UNSIGNED);
- }
- alloc_call = si->alloc;
- }
- else
- offrng[0] = offrng[1] = 0;
+ tree destsize = compute_objsize (dest, ostype, &aref, &ptr_qry);
if (!destsize)
{
- /* If there is no STRINFO for DEST, fall back on compute_objsize. */
- tree off = NULL_TREE;
- destsize = compute_objsize (dest, rawmem ? 0 : 1, &destdecl, &off, rvals);
- if (destsize)
- {
- /* Remember OFF but clear OFFRNG that may have been set above. */
- destoff = off;
- offrng[0] = offrng[1] = 0;
-
- if (destdecl && TREE_CODE (destdecl) == SSA_NAME)
- {
- gimple *stmt = SSA_NAME_DEF_STMT (destdecl);
- if (is_gimple_call (stmt))
- alloc_call = stmt;
- destdecl = NULL_TREE;
- }
-
- wide_int rng[2];
- if (get_range (destsize, stmt, rng, rvals))
- {
- sizrng[0] = widest_int::from (rng[0], UNSIGNED);
- sizrng[1] = widest_int::from (rng[1], UNSIGNED);
- }
- else
- {
- /* On failure, rather than failing, set the maximum range
- so that overflow in allocated objects whose size depends
- on the strlen of the source can still be diagnosed
- below. */
- sizrng[0] = 0;
- sizrng[1] = size_max;
- }
- }
+ aref.sizrng[0] = 0;
+ aref.sizrng[1] = wi::to_offset (max_object_size ());
}
- if (!destsize)
- {
- sizrng[0] = 0;
- sizrng[1] = size_max;
- };
-
/* Return early if the DESTSIZE size expression is the same as LEN
and the offset into the destination is zero. This might happen
in the case of a pair of malloc and memset calls to allocate
an object and clear it as if by calloc. */
- if (destsize == len && !plus_one && offrng[0] == 0 && offrng[0] == offrng[1])
+ if (destsize == len && !plus_one
+ && aref.offrng[0] == 0 && aref.offrng[0] == aref.offrng[1])
return;
wide_int rng[2];
- if (!get_range (len, stmt, rng, rvals))
+ if (!get_range (len, stmt, rng, ptr_qry.rvals))
return;
widest_int lenrng[2] =
@@ -2100,38 +1980,13 @@ maybe_warn_overflow (gimple *stmt, tree len,
/* The size of the remaining space in the destination computed
as the size of the latter minus the offset into it. */
- widest_int spcrng[2] = { sizrng[0], sizrng[1] };
- if (wi::neg_p (offrng[0]) && wi::neg_p (offrng[1]))
- {
- /* When the offset is negative and the size of the destination
- object unknown there is little to do.
- FIXME: Detect offsets that are necessarily invalid regardless
- of the size of the object. */
- if (!destsize)
- return;
-
- /* The remaining space is necessarily zero. */
- spcrng[0] = spcrng[1] = 0;
- }
- else if (wi::neg_p (offrng[0]))
- {
- /* When the lower bound of the offset is negative but the upper
- bound is not, reduce the upper bound of the remaining space
- by the upper bound of the offset but leave the lower bound
- unchanged. If that makes the upper bound of the space less
- than the lower bound swap the two. */
- spcrng[1] -= wi::ltu_p (offrng[1], spcrng[1]) ? offrng[1] : spcrng[1];
- if (wi::ltu_p (spcrng[1], spcrng[0]))
- std::swap (spcrng[1], spcrng[0]);
- }
- else
- {
- /* When the offset is positive reduce the remaining space by
- the lower bound of the offset or clear it if the offset is
- greater. */
- spcrng[0] -= wi::ltu_p (offrng[0], spcrng[0]) ? offrng[0] : spcrng[0];
- spcrng[1] -= wi::ltu_p (offrng[0], spcrng[1]) ? offrng[0] : spcrng[1];
- }
+ widest_int spcrng[2];
+ {
+ offset_int remrng[2];
+ remrng[1] = aref.size_remaining (remrng);
+ spcrng[0] = remrng[0] == -1 ? 0 : widest_int::from (remrng[0], UNSIGNED);
+ spcrng[1] = widest_int::from (remrng[1], UNSIGNED);
+ }
if (wi::leu_p (lenrng[0], spcrng[0])
&& wi::leu_p (lenrng[1], spcrng[1]))
@@ -2233,122 +2088,17 @@ maybe_warn_overflow (gimple *stmt, tree len,
gimple_set_no_warning (stmt, true);
- /* If DESTOFF is not null, use it to format the offset value/range. */
- if (destoff)
- {
- wide_int rng[2];
- if (get_range (destoff, stmt, rng))
- {
- offrng[0] = widest_int::from (rng[0], SIGNED);
- offrng[1] = widest_int::from (rng[1], SIGNED);
- }
- else
- offrng[0] = offrng[1] = 0;
- }
-
- /* Format the offset to keep the number of inform calls from growing
- out of control. */
- char offstr[64];
- if (offrng[0] == offrng[1])
- sprintf (offstr, "%lli", (long long) offrng[0].to_shwi ());
- else
- sprintf (offstr, "[%lli, %lli]",
- (long long) offrng[0].to_shwi (), (long long) offrng[1].to_shwi ());
-
- if (destdecl && DECL_P (destdecl))
- {
- if (tree size = DECL_SIZE_UNIT (destdecl))
- inform (DECL_SOURCE_LOCATION (destdecl),
- "at offset %s to object %qD with size %E declared here",
- offstr, destdecl, size);
- else
- inform (DECL_SOURCE_LOCATION (destdecl),
- "at offset %s to object %qD declared here",
- offstr, destdecl);
- return;
- }
-
- if (!alloc_call)
- return;
-
- tree allocfn = gimple_call_fndecl (alloc_call);
- if (!allocfn)
- {
- /* For an ALLOC_CALL via a function pointer make a small effort
- to determine the destination of the pointer. */
- allocfn = gimple_call_fn (alloc_call);
- if (TREE_CODE (allocfn) == SSA_NAME)
- {
- gimple *def = SSA_NAME_DEF_STMT (allocfn);
- if (gimple_assign_single_p (def))
- {
- tree rhs = gimple_assign_rhs1 (def);
- if (DECL_P (rhs))
- allocfn = rhs;
- else if (TREE_CODE (rhs) == COMPONENT_REF)
- allocfn = TREE_OPERAND (rhs, 1);
- }
- }
- }
-
- if (gimple_call_builtin_p (alloc_call, BUILT_IN_ALLOCA_WITH_ALIGN))
- {
- if (sizrng[0] == sizrng[1])
- inform (gimple_location (alloc_call),
- "at offset %s to an object with size %wu declared here",
- offstr, sizrng[0].to_uhwi ());
- else if (sizrng[0] == 0)
- {
- /* Avoid printing impossible sizes. */
- if (wi::ltu_p (sizrng[1], diff_max - 2))
- inform (gimple_location (alloc_call),
- "at offset %s to an object with size at most %wu "
- "declared here",
- offstr, sizrng[1].to_uhwi ());
- else
- inform (gimple_location (alloc_call),
- "at offset %s to an object declared here", offstr);
- }
- else
- inform (gimple_location (alloc_call),
- "at offset %s to an object with size between %wu and %wu "
- "declared here",
- offstr, sizrng[0].to_uhwi (), sizrng[1].to_uhwi ());
- return;
- }
-
- if (sizrng[0] == sizrng[1])
- inform (gimple_location (alloc_call),
- "at offset %s to an object with size %wu allocated by %qE here",
- offstr, sizrng[0].to_uhwi (), allocfn);
- else if (sizrng[0] == 0)
- {
- /* Avoid printing impossible sizes. */
- if (wi::ltu_p (sizrng[1], diff_max - 2))
- inform (gimple_location (alloc_call),
- "at offset %s to an object with size at most %wu allocated "
- "by %qD here",
- offstr, sizrng[1].to_uhwi (), allocfn);
- else
- inform (gimple_location (alloc_call),
- "at offset %s to an object allocated by %qE here",
- offstr, allocfn);
- }
- else
- inform (gimple_location (alloc_call),
- "at offset %s to an object with size between %wu and %wu "
- "allocated by %qE here",
- offstr, sizrng[0].to_uhwi (), sizrng[1].to_uhwi (), allocfn);
+ aref.inform_access (access_write_only);
}
/* Convenience wrapper for the above. */
static inline void
maybe_warn_overflow (gimple *stmt, unsigned HOST_WIDE_INT len,
- range_query *rvals = NULL, strinfo *si = NULL,
+ pointer_query &ptr_qry, strinfo *si = NULL,
bool plus_one = false, bool rawmem = false)
{
- maybe_warn_overflow (stmt, build_int_cst (size_type_node, len), rvals,
+ maybe_warn_overflow (stmt, build_int_cst (size_type_node, len), ptr_qry,
si, plus_one, rawmem);
}
@@ -2648,7 +2398,7 @@ handle_builtin_strchr (gimple_stmt_iterator *gsi)
static void
handle_builtin_strcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi,
- range_query *rvals)
+ pointer_query &ptr_qry)
{
int idx, didx;
tree src, dst, srclen, len, lhs, type, fn, oldlen;
@@ -2674,7 +2424,7 @@ handle_builtin_strcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi,
return;
if (olddsi != NULL)
- adjust_last_stmt (olddsi, stmt, false);
+ adjust_last_stmt (olddsi, stmt, false, ptr_qry);
srclen = NULL_TREE;
if (si != NULL)
@@ -2682,10 +2432,10 @@ handle_builtin_strcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi,
else if (idx < 0)
srclen = build_int_cst (size_type_node, ~idx);
- maybe_warn_overflow (stmt, srclen, rvals, olddsi, true);
+ maybe_warn_overflow (stmt, srclen, ptr_qry, olddsi, true);
if (olddsi != NULL)
- adjust_last_stmt (olddsi, stmt, false);
+ adjust_last_stmt (olddsi, stmt, false, ptr_qry);
loc = gimple_location (stmt);
if (srclen == NULL_TREE)
@@ -3030,7 +2780,8 @@ is_strlen_related_p (tree src, tree len)
*/
bool
-maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt)
+maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt,
+ pointer_query *ptr_qry /* = NULL */)
{
gimple *stmt = gsi_stmt (gsi);
if (gimple_no_warning_p (stmt))
@@ -3038,31 +2789,24 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt)
wide_int cntrange[2];
- if (TREE_CODE (cnt) == INTEGER_CST)
- cntrange[0] = cntrange[1] = wi::to_wide (cnt);
- else if (TREE_CODE (cnt) == SSA_NAME)
+ // FIXME: Use range_query instead of global ranges.
+ enum value_range_kind rng = get_range_info (cnt, cntrange, cntrange + 1);
+ if (rng == VR_RANGE)
+ ;
+ else if (rng == VR_ANTI_RANGE)
{
- // FIXME: Use range_query instead of global ranges.
- enum value_range_kind rng = get_range_info (cnt, cntrange, cntrange + 1);
- if (rng == VR_RANGE)
- ;
- else if (rng == VR_ANTI_RANGE)
- {
- wide_int maxobjsize = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node));
+ wide_int maxobjsize = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node));
- if (wi::ltu_p (cntrange[1], maxobjsize))
- {
- cntrange[0] = cntrange[1] + 1;
- cntrange[1] = maxobjsize;
- }
- else
- {
- cntrange[1] = cntrange[0] - 1;
- cntrange[0] = wi::zero (TYPE_PRECISION (TREE_TYPE (cnt)));
- }
+ if (wi::ltu_p (cntrange[1], maxobjsize))
+ {
+ cntrange[0] = cntrange[1] + 1;
+ cntrange[1] = maxobjsize;
}
else
- return false;
+ {
+ cntrange[1] = cntrange[0] - 1;
+ cntrange[0] = wi::zero (TYPE_PRECISION (TREE_TYPE (cnt)));
+ }
}
else
return false;
@@ -3293,7 +3037,8 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt)
}
}
- if (tree dstsize = compute_objsize (dst, 1))
+ access_ref aref;
+ if (tree dstsize = compute_objsize (dst, 1, &aref, ptr_qry))
{
/* The source length is unknown. Try to determine the destination
size and see if it matches the specified bound. If not, bail.
@@ -3308,7 +3053,7 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt)
/* Avoid warning for strncpy(a, b, N) calls where the following
equalities hold:
N == sizeof a && N == sizeof b */
- if (tree srcsize = compute_objsize (src, 1))
+ if (tree srcsize = compute_objsize (src, 1, &aref, ptr_qry))
if (wi::to_wide (srcsize) == cntrange[1])
return false;
@@ -3451,7 +3196,7 @@ handle_builtin_stxncpy_strncat (bool append_p, gimple_stmt_iterator *gsi)
static void
handle_builtin_memcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi,
- range_query *rvals)
+ pointer_query &ptr_qry)
{
tree lhs, oldlen, newlen;
gimple *stmt = gsi_stmt (*gsi);
@@ -3471,8 +3216,8 @@ handle_builtin_memcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi,
if (olddsi != NULL
&& !integer_zerop (len))
{
- maybe_warn_overflow (stmt, len, rvals, olddsi, false, true);
- adjust_last_stmt (olddsi, stmt, false);
+ maybe_warn_overflow (stmt, len, ptr_qry, olddsi, false, false);
+ adjust_last_stmt (olddsi, stmt, false, ptr_qry);
}
int idx = get_stridx (src);
@@ -3549,7 +3294,7 @@ handle_builtin_memcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi,
}
if (olddsi != NULL && TREE_CODE (len) == SSA_NAME)
- adjust_last_stmt (olddsi, stmt, false);
+ adjust_last_stmt (olddsi, stmt, false, ptr_qry);
if (didx == 0)
{
@@ -3631,7 +3376,8 @@ handle_builtin_memcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi,
is known. */
static void
-handle_builtin_strcat (enum built_in_function bcode, gimple_stmt_iterator *gsi)
+handle_builtin_strcat (enum built_in_function bcode, gimple_stmt_iterator *gsi,
+ pointer_query &ptr_qry)
{
int idx, didx;
tree srclen, args, type, fn, objsz, endptr;
@@ -3859,7 +3605,7 @@ handle_builtin_strcat (enum built_in_function bcode, gimple_stmt_iterator *gsi)
computed by transforming this strcpy into stpcpy. */
if (srclen == NULL_TREE && dsi->dont_invalidate)
dsi->stmt = stmt;
- adjust_last_stmt (dsi, stmt, true);
+ adjust_last_stmt (dsi, stmt, true, ptr_qry);
if (srclen != NULL_TREE)
{
laststmt.stmt = stmt;
@@ -3916,13 +3662,13 @@ handle_alloc_call (enum built_in_function bcode, gimple_stmt_iterator *gsi)
static bool
handle_builtin_memset (gimple_stmt_iterator *gsi, bool *zero_write,
- range_query *rvals)
+ pointer_query &ptr_qry)
{
gimple *memset_stmt = gsi_stmt (*gsi);
tree ptr = gimple_call_arg (memset_stmt, 0);
/* Set to the non-constant offset added to PTR. */
wide_int offrng[2];
- int idx1 = get_stridx (ptr, offrng, rvals);
+ int idx1 = get_stridx (ptr, offrng, ptr_qry.rvals);
if (idx1 <= 0)
return false;
strinfo *si1 = get_strinfo (idx1);
@@ -3938,7 +3684,7 @@ handle_builtin_memset (gimple_stmt_iterator *gsi, bool *zero_write,
tree memset_size = gimple_call_arg (memset_stmt, 2);
/* Check for overflow. */
- maybe_warn_overflow (memset_stmt, memset_size, rvals, NULL, false, true);
+ maybe_warn_overflow (memset_stmt, memset_size, ptr_qry, NULL, false, false);
/* Bail when there is no statement associated with the destination
(the statement may be null even when SI1->ALLOC is not). */
@@ -3989,11 +3735,13 @@ handle_builtin_memset (gimple_stmt_iterator *gsi, bool *zero_write,
return true;
}
-/* Return a pointer to the first such equality expression if RES is used
- only in expressions testing its equality to zero, and null otherwise. */
+/* Return first such statement if RES is used in statements testing its
+ equality to zero, and null otherwise. If EXCLUSIVE is true, return
+ nonnull if and only RES is used in such expressions exclusively and
+ in none other. */
static gimple *
-used_only_for_zero_equality (tree res)
+use_in_zero_equality (tree res, bool exclusive = true)
{
gimple *first_use = NULL;
@@ -4006,6 +3754,7 @@ used_only_for_zero_equality (tree res)
if (is_gimple_debug (use_stmt))
continue;
+
if (gimple_code (use_stmt) == GIMPLE_ASSIGN)
{
tree_code code = gimple_assign_rhs_code (use_stmt);
@@ -4015,25 +3764,41 @@ used_only_for_zero_equality (tree res)
if ((TREE_CODE (cond_expr) != EQ_EXPR
&& (TREE_CODE (cond_expr) != NE_EXPR))
|| !integer_zerop (TREE_OPERAND (cond_expr, 1)))
- return NULL;
+ {
+ if (exclusive)
+ return NULL;
+ continue;
+ }
}
else if (code == EQ_EXPR || code == NE_EXPR)
{
if (!integer_zerop (gimple_assign_rhs2 (use_stmt)))
- return NULL;
+ {
+ if (exclusive)
+ return NULL;
+ continue;
+ }
}
- else
+ else if (exclusive)
return NULL;
+ else
+ continue;
}
else if (gimple_code (use_stmt) == GIMPLE_COND)
{
tree_code code = gimple_cond_code (use_stmt);
if ((code != EQ_EXPR && code != NE_EXPR)
|| !integer_zerop (gimple_cond_rhs (use_stmt)))
- return NULL;
+ {
+ if (exclusive)
+ return NULL;
+ continue;
+ }
}
+ else if (exclusive)
+ return NULL;
else
- return NULL;
+ continue;
if (!first_use)
first_use = use_stmt;
@@ -4053,7 +3818,7 @@ handle_builtin_memcmp (gimple_stmt_iterator *gsi)
gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
tree res = gimple_call_lhs (stmt);
- if (!res || !used_only_for_zero_equality (res))
+ if (!res || !use_in_zero_equality (res))
return false;
tree arg1 = gimple_call_arg (stmt, 0);
@@ -4317,7 +4082,7 @@ maybe_warn_pointless_strcmp (gimple *stmt, HOST_WIDE_INT bound,
unsigned HOST_WIDE_INT siz)
{
tree lhs = gimple_call_lhs (stmt);
- gimple *use = used_only_for_zero_equality (lhs);
+ gimple *use = use_in_zero_equality (lhs, /* exclusive = */ false);
if (!use)
return;
@@ -4367,12 +4132,12 @@ maybe_warn_pointless_strcmp (gimple *stmt, HOST_WIDE_INT bound,
stmt, callee, minlen, siz, bound);
}
- if (warned)
- {
- location_t use_loc = gimple_location (use);
- if (LOCATION_LINE (stmt_loc) != LOCATION_LINE (use_loc))
- inform (use_loc, "in this expression");
- }
+ if (!warned)
+ return;
+
+ location_t use_loc = gimple_location (use);
+ if (LOCATION_LINE (stmt_loc) != LOCATION_LINE (use_loc))
+ inform (use_loc, "in this expression");
}
@@ -4507,7 +4272,7 @@ handle_builtin_string_cmp (gimple_stmt_iterator *gsi, range_query *rvals)
/* The size of the array in which the unknown string is stored. */
HOST_WIDE_INT varsiz = arysiz1 < 0 ? arysiz2 : arysiz1;
- if ((varsiz < 0 || cmpsiz < varsiz) && used_only_for_zero_equality (lhs))
+ if ((varsiz < 0 || cmpsiz < varsiz) && use_in_zero_equality (lhs))
{
/* If the known length is less than the size of the other array
and the strcmp result is only used to test equality to zero,
@@ -4581,55 +4346,6 @@ handle_pointer_plus (gimple_stmt_iterator *gsi)
}
}
-/* Describes recursion limits used by count_nonzero_bytes. */
-
-class ssa_name_limit_t
-{
- 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_ssa_name_def_chain_limit) { }
-
- int next_ssa_name (tree);
-
- ~ssa_name_limit_t ()
- {
- if (visited)
- BITMAP_FREE (visited);
- }
-};
-
-/* 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;
-}
-
static bool
count_nonzero_bytes_addr (tree, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
unsigned [3], bool *, bool *, bool *,
@@ -4687,7 +4403,7 @@ count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset,
/* 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))
+ if (int res = snlim.next_phi (exp))
return res > 0;
/* Determine the minimum and maximum from the PHI arguments. */
@@ -4922,7 +4638,7 @@ count_nonzero_bytes_addr (tree exp, unsigned HOST_WIDE_INT offset,
/* 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))
+ if (int res = snlim.next_phi (exp))
return res > 0;
/* Determine the minimum and maximum from the PHI arguments. */
@@ -4982,7 +4698,7 @@ count_nonzero_bytes (tree exp, unsigned lenrange[3], bool *nulterm,
static bool
handle_store (gimple_stmt_iterator *gsi, bool *zero_write,
- range_query *rvals)
+ pointer_query &ptr_qry)
{
int idx = -1;
strinfo *si = NULL;
@@ -4990,6 +4706,8 @@ handle_store (gimple_stmt_iterator *gsi, bool *zero_write,
tree ssaname = NULL_TREE, lhs = gimple_assign_lhs (stmt);
tree rhs = gimple_assign_rhs1 (stmt);
+ range_query *const rvals = ptr_qry.rvals;
+
/* The offset of the first byte in LHS modified by the store. */
unsigned HOST_WIDE_INT offset = 0;
@@ -5016,7 +4734,7 @@ handle_store (gimple_stmt_iterator *gsi, bool *zero_write,
unsigned lenrange[] = { UINT_MAX, 0, 0 };
if (count_nonzero_bytes (rhs, lenrange, &dummy, &dummy, &dummy,
rvals))
- maybe_warn_overflow (stmt, lenrange[2], rvals);
+ maybe_warn_overflow (stmt, lenrange[2], ptr_qry);
return true;
}
@@ -5056,7 +4774,7 @@ handle_store (gimple_stmt_iterator *gsi, bool *zero_write,
storing_nonzero_p = lenrange[1] > 0;
*zero_write = storing_all_zeros_p;
- maybe_warn_overflow (stmt, lenrange[2], rvals);
+ maybe_warn_overflow (stmt, lenrange[2], ptr_qry);
}
else
{
@@ -5174,7 +4892,7 @@ handle_store (gimple_stmt_iterator *gsi, bool *zero_write,
/* We're overwriting the nul terminator with a nonzero or
unknown character. If the previous stmt was a memcpy,
its length may be decreased. */
- adjust_last_stmt (si, stmt, false);
+ adjust_last_stmt (si, stmt, false, ptr_qry);
si = unshare_strinfo (si);
if (storing_nonzero_p)
{
@@ -5392,7 +5110,7 @@ is_char_type (tree type)
static bool
strlen_check_and_optimize_call (gimple_stmt_iterator *gsi, bool *zero_write,
- range_query *rvals)
+ pointer_query &ptr_qry)
{
gimple *stmt = gsi_stmt (*gsi);
@@ -5409,7 +5127,7 @@ strlen_check_and_optimize_call (gimple_stmt_iterator *gsi, bool *zero_write,
if (!flag_optimize_strlen
|| !strlen_optimize
|| !valid_builtin_call (stmt))
- return !handle_printf_call (gsi, rvals);
+ return !handle_printf_call (gsi, ptr_qry);
tree callee = gimple_call_fndecl (stmt);
switch (DECL_FUNCTION_CODE (callee))
@@ -5425,7 +5143,7 @@ strlen_check_and_optimize_call (gimple_stmt_iterator *gsi, bool *zero_write,
case BUILT_IN_STRCPY_CHK:
case BUILT_IN_STPCPY:
case BUILT_IN_STPCPY_CHK:
- handle_builtin_strcpy (DECL_FUNCTION_CODE (callee), gsi, rvals);
+ handle_builtin_strcpy (DECL_FUNCTION_CODE (callee), gsi, ptr_qry);
break;
case BUILT_IN_STRNCAT:
@@ -5444,11 +5162,11 @@ strlen_check_and_optimize_call (gimple_stmt_iterator *gsi, bool *zero_write,
case BUILT_IN_MEMCPY_CHK:
case BUILT_IN_MEMPCPY:
case BUILT_IN_MEMPCPY_CHK:
- handle_builtin_memcpy (DECL_FUNCTION_CODE (callee), gsi, rvals);
+ handle_builtin_memcpy (DECL_FUNCTION_CODE (callee), gsi, ptr_qry);
break;
case BUILT_IN_STRCAT:
case BUILT_IN_STRCAT_CHK:
- handle_builtin_strcat (DECL_FUNCTION_CODE (callee), gsi);
+ handle_builtin_strcat (DECL_FUNCTION_CODE (callee), gsi, ptr_qry);
break;
case BUILT_IN_ALLOCA:
case BUILT_IN_ALLOCA_WITH_ALIGN:
@@ -5457,7 +5175,7 @@ strlen_check_and_optimize_call (gimple_stmt_iterator *gsi, bool *zero_write,
handle_alloc_call (DECL_FUNCTION_CODE (callee), gsi);
break;
case BUILT_IN_MEMSET:
- if (handle_builtin_memset (gsi, zero_write, rvals))
+ if (handle_builtin_memset (gsi, zero_write, ptr_qry))
return false;
break;
case BUILT_IN_MEMCMP:
@@ -5466,11 +5184,11 @@ strlen_check_and_optimize_call (gimple_stmt_iterator *gsi, bool *zero_write,
break;
case BUILT_IN_STRCMP:
case BUILT_IN_STRNCMP:
- if (handle_builtin_string_cmp (gsi, rvals))
+ if (handle_builtin_string_cmp (gsi, ptr_qry.rvals))
return false;
break;
default:
- if (handle_printf_call (gsi, rvals))
+ if (handle_printf_call (gsi, ptr_qry))
return false;
break;
}
@@ -5628,7 +5346,7 @@ handle_integral_assign (gimple_stmt_iterator *gsi, bool *cleanup_eh,
static bool
check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh,
- range_query *rvals)
+ pointer_query &ptr_qry)
{
gimple *stmt = gsi_stmt (*gsi);
@@ -5638,7 +5356,7 @@ check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh,
if (is_gimple_call (stmt))
{
- if (!strlen_check_and_optimize_call (gsi, &zero_write, rvals))
+ if (!strlen_check_and_optimize_call (gsi, &zero_write, ptr_qry))
return false;
}
else if (!flag_optimize_strlen || !strlen_optimize)
@@ -5663,7 +5381,7 @@ check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh,
}
else if (TREE_CODE (lhs) == SSA_NAME && INTEGRAL_TYPE_P (lhs_type))
/* Handle assignment to a character. */
- handle_integral_assign (gsi, cleanup_eh, rvals);
+ handle_integral_assign (gsi, cleanup_eh, ptr_qry.rvals);
else if (TREE_CODE (lhs) != SSA_NAME && !TREE_SIDE_EFFECTS (lhs))
{
tree type = TREE_TYPE (lhs);
@@ -5694,7 +5412,7 @@ check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh,
}
/* Handle a single or multibyte assignment. */
- if (is_char_store && !handle_store (gsi, &zero_write, rvals))
+ if (is_char_store && !handle_store (gsi, &zero_write, ptr_qry))
return false;
}
}
@@ -5768,8 +5486,10 @@ public:
strlen_dom_walker (cdi_direction direction)
: dom_walker (direction),
evrp (false),
+ ptr_qry (&evrp, &var_cache),
+ var_cache (),
m_cleanup_cfg (false)
- {}
+ { }
virtual edge before_dom_children (basic_block);
virtual void after_dom_children (basic_block);
@@ -5778,6 +5498,11 @@ public:
to track strlen results across integer variable assignments. */
evrp_range_analyzer evrp;
+ /* A pointer_query object and its cache to store information about
+ pointers and their targets in. */
+ pointer_query ptr_qry;
+ pointer_query::cache_type var_cache;
+
/* Flag that will trigger TODO_cleanup_cfg to be returned in strlen
execute function. */
bool m_cleanup_cfg;
@@ -5871,7 +5596,10 @@ strlen_dom_walker::before_dom_children (basic_block bb)
can be used by printf argument processing. */
evrp.record_ranges_from_stmt (stmt, false);
- if (check_and_optimize_stmt (&gsi, &cleanup_eh, &evrp))
+ /* Reset search depth preformance counter. */
+ ptr_qry.depth = 0;
+
+ if (check_and_optimize_stmt (&gsi, &cleanup_eh, ptr_qry))
gsi_next (&gsi);
}
@@ -5939,6 +5667,29 @@ printf_strlen_execute (function *fun, bool warn_only)
strlen_dom_walker walker (CDI_DOMINATORS);
walker.walk (ENTRY_BLOCK_PTR_FOR_FN (fun));
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ unsigned nused = 0;
+ unsigned nidxs = walker.ptr_qry.var_cache->indices.length ();
+ for (unsigned i = 0; i != nidxs; ++i)
+ if (walker.ptr_qry.var_cache->indices[i])
+ ++nused;
+
+ fprintf (dump_file, "pointer_query counters\n"
+ " index cache size: %u\n"
+ " utilization: %u%%\n"
+ " access cache size: %u\n"
+ " hits: %u\n"
+ " misses: %u\n"
+ " failures: %u\n"
+ " max_depth: %u\n",
+ nidxs,
+ nidxs == 0 ? 0 : (nused * 100) / nidxs,
+ walker.ptr_qry.var_cache->access_refs.length (),
+ walker.ptr_qry.hits, walker.ptr_qry.misses,
+ walker.ptr_qry.failures, walker.ptr_qry.max_depth);
+ }
+
ssa_ver_to_stridx.release ();
strinfo_pool.release ();
if (decl_to_stridxlist_htab)
@@ -5964,9 +5715,6 @@ printf_strlen_execute (function *fun, bool warn_only)
loop_optimizer_finalize ();
}
- /* Clean up object size info. */
- fini_object_sizes ();
-
return walker.m_cleanup_cfg ? TODO_cleanup_cfg : 0;
}
diff --git a/gcc/tree-ssa-strlen.h b/gcc/tree-ssa-strlen.h
index 225f64b..e3435c1 100644
--- a/gcc/tree-ssa-strlen.h
+++ b/gcc/tree-ssa-strlen.h
@@ -21,8 +21,11 @@
#ifndef GCC_TREE_SSA_STRLEN_H
#define GCC_TREE_SSA_STRLEN_H
+class pointer_query;
+
extern bool is_strlen_related_p (tree, tree);
-extern bool maybe_diag_stxncpy_trunc (gimple_stmt_iterator, tree, tree);
+extern bool maybe_diag_stxncpy_trunc (gimple_stmt_iterator, tree, tree,
+ pointer_query * = NULL);
extern tree set_strlen_range (tree, wide_int, wide_int, tree = NULL_TREE);
extern tree get_range (tree, gimple *, wide_int[2],
@@ -33,6 +36,6 @@ extern void get_range_strlen_dynamic (tree, gimple *, c_strlen_data *,
class range_query *);
/* APIs internal to strlen pass. Defined in gimple-ssa-sprintf.c. */
-extern bool handle_printf_call (gimple_stmt_iterator *, class range_query *);
+extern bool handle_printf_call (gimple_stmt_iterator *, pointer_query &);
#endif // GCC_TREE_SSA_STRLEN_H
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index a4832b7..cf653be 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -3851,6 +3851,23 @@ make_escape_constraint (tree op)
make_constraint_to (escaped_id, op);
}
+/* Make constraint necessary to make all indirect references
+ from VI escape. */
+
+static void
+make_indirect_escape_constraint (varinfo_t vi)
+{
+ struct constraint_expr lhs, rhs;
+ /* escaped = *(VAR + UNKNOWN); */
+ lhs.type = SCALAR;
+ lhs.var = escaped_id;
+ lhs.offset = 0;
+ rhs.type = DEREF;
+ rhs.var = vi->id;
+ rhs.offset = UNKNOWN_OFFSET;
+ process_constraint (new_constraint (lhs, rhs));
+}
+
/* Add constraints to that the solution of VI is transitively closed. */
static void
@@ -4026,7 +4043,7 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results)
set. The argument would still get clobbered through the
escape solution. */
if ((flags & EAF_NOCLOBBER)
- && (flags & EAF_NOESCAPE))
+ && (flags & (EAF_NOESCAPE | EAF_NODIRECTESCAPE)))
{
varinfo_t uses = get_call_use_vi (stmt);
varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
@@ -4036,9 +4053,11 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results)
if (!(flags & EAF_DIRECT))
make_transitive_closure_constraints (tem);
make_copy_constraint (uses, tem->id);
+ if (!(flags & (EAF_NOESCAPE | EAF_DIRECT)))
+ make_indirect_escape_constraint (tem);
returns_uses = true;
}
- else if (flags & EAF_NOESCAPE)
+ else if (flags & (EAF_NOESCAPE | EAF_NODIRECTESCAPE))
{
struct constraint_expr lhs, rhs;
varinfo_t uses = get_call_use_vi (stmt);
@@ -4061,6 +4080,8 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results)
rhs.var = nonlocal_id;
rhs.offset = 0;
process_constraint (new_constraint (lhs, rhs));
+ if (!(flags & (EAF_NOESCAPE | EAF_DIRECT)))
+ make_indirect_escape_constraint (tem);
returns_uses = true;
}
else
@@ -4253,6 +4274,11 @@ handle_pure_call (gcall *stmt, vec<ce_s> *results)
for (i = 0; i < gimple_call_num_args (stmt); ++i)
{
tree arg = gimple_call_arg (stmt, i);
+ int flags = gimple_call_arg_flags (stmt, i);
+
+ /* If the argument is not used we can ignore it. */
+ if (flags & EAF_UNUSED)
+ continue;
if (!uses)
{
uses = get_call_use_vi (stmt);
diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
index 7361e0b..a4879fe 100644
--- a/gcc/tree-ssa-tail-merge.c
+++ b/gcc/tree-ssa-tail-merge.c
@@ -1189,8 +1189,8 @@ gimple_equal_p (same_succ *same_succ, gimple *s1, gimple *s2)
if (!gimple_operand_equal_value_p (t1, t2))
return false;
- code1 = gimple_expr_code (s1);
- code2 = gimple_expr_code (s2);
+ code1 = gimple_cond_code (s1);
+ code2 = gimple_cond_code (s2);
inv_cond = (bitmap_bit_p (same_succ->inverse, bb1->index)
!= bitmap_bit_p (same_succ->inverse, bb2->index));
if (inv_cond)
diff --git a/gcc/tree-ssa-threadbackward.c b/gcc/tree-ssa-threadbackward.c
index 327628f..30f6926 100644
--- a/gcc/tree-ssa-threadbackward.c
+++ b/gcc/tree-ssa-threadbackward.c
@@ -259,8 +259,13 @@ thread_jumps::profitable_jump_thread_path (basic_block bbi, tree name,
!gsi_end_p (gsi);
gsi_next_nondebug (&gsi))
{
+ /* Do not allow OpenACC loop markers and __builtin_constant_p on
+ threading paths. The latter is disallowed, because an
+ expression might be constant on two threading paths, and
+ become non-constant (i.e.: phi) when they merge. */
gimple *stmt = gsi_stmt (gsi);
- if (gimple_call_internal_p (stmt, IFN_UNIQUE))
+ if (gimple_call_internal_p (stmt, IFN_UNIQUE)
+ || gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P))
{
m_path.pop ();
return NULL;
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index f43d581..32d63a9 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -265,6 +265,12 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
&& gimple_call_internal_unique_p (stmt))
return NULL;
+ /* We cannot thread through __builtin_constant_p, because an
+ expression that is constant on two threading paths may become
+ non-constant (i.e.: phi) when they merge. */
+ if (gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P))
+ return NULL;
+
/* If duplicating this block is going to cause too much code
expansion, then do not thread through this block. */
stmt_count++;
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index f235143..516a7bd 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -404,10 +404,7 @@ maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs,
tree rhstype = TREE_TYPE (rhs);
if (POINTER_TYPE_P (rhstype))
rhstype = TREE_TYPE (rhstype);
- if (TYPE_EMPTY_P (rhstype)
- || (RECORD_OR_UNION_TYPE_P (rhstype)
- && (!first_field (rhstype)
- || default_is_empty_record (rhstype))))
+ if (is_empty_type (rhstype))
return NULL_TREE;
bool warned = false;
@@ -443,7 +440,7 @@ maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs,
access implying read access to those objects. */
static void
-maybe_warn_pass_by_reference (gimple *stmt, wlimits &wlims)
+maybe_warn_pass_by_reference (gcall *stmt, wlimits &wlims)
{
if (!wlims.wmaybe_uninit)
return;
@@ -457,6 +454,10 @@ maybe_warn_pass_by_reference (gimple *stmt, wlimits &wlims)
if (!fntype)
return;
+ /* Const function do not read their arguments. */
+ if (gimple_call_flags (stmt) & ECF_CONST)
+ return;
+
const built_in_function fncode
= (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
? DECL_FUNCTION_CODE (fndecl) : (built_in_function)BUILT_IN_LAST);
@@ -523,6 +524,10 @@ maybe_warn_pass_by_reference (gimple *stmt, wlimits &wlims)
(but not definitive) read access. */
wlims.always_executed = false;
+ /* Ignore args we are not going to read from. */
+ if (gimple_call_arg_flags (stmt, argno - 1) & EAF_UNUSED)
+ continue;
+
tree arg = gimple_call_arg (stmt, argno - 1);
ao_ref ref;
@@ -639,8 +644,8 @@ warn_uninitialized_vars (bool wmaybe_uninit)
if (gimple_vdef (stmt))
wlims.vdef_cnt++;
- if (is_gimple_call (stmt))
- maybe_warn_pass_by_reference (stmt, wlims);
+ if (gcall *call = dyn_cast <gcall *> (stmt))
+ maybe_warn_pass_by_reference (call, wlims);
else if (gimple_assign_load_p (stmt)
&& gimple_has_location (stmt))
{
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index c47b963..a575979 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -987,6 +987,12 @@ verify_phi_args (gphi *phi, basic_block bb, basic_block *definition_block)
err = true;
}
+ if ((e->flags & EDGE_ABNORMAL) && TREE_CODE (op) != SSA_NAME)
+ {
+ error ("PHI argument on abnormal edge is not SSA_NAME");
+ err = true;
+ }
+
if (TREE_CODE (op) == SSA_NAME)
{
err = verify_ssa_name (op, virtual_operand_p (gimple_phi_result (phi)));
@@ -1212,15 +1218,16 @@ err:
# pragma GCC diagnostic pop
#endif
-/* Initialize global DFA and SSA structures. */
+/* Initialize global DFA and SSA structures.
+ If SIZE is non-zero allocated ssa names array of a given size. */
void
-init_tree_ssa (struct function *fn)
+init_tree_ssa (struct function *fn, int size)
{
fn->gimple_df = ggc_cleared_alloc<gimple_df> ();
fn->gimple_df->default_defs = hash_table<ssa_name_hasher>::create_ggc (20);
pt_solution_reset (&fn->gimple_df->escaped);
- init_ssanames (fn, 0);
+ init_ssanames (fn, size);
}
/* Deallocate memory associated with SSA data structures for FNDECL. */
diff --git a/gcc/tree-ssa.h b/gcc/tree-ssa.h
index 79f2b13..7e7fa4a 100644
--- a/gcc/tree-ssa.h
+++ b/gcc/tree-ssa.h
@@ -45,7 +45,7 @@ extern void insert_debug_temps_for_defs (gimple_stmt_iterator *);
extern void reset_debug_uses (gimple *);
extern void release_defs_bitset (bitmap toremove);
extern void verify_ssa (bool, bool);
-extern void init_tree_ssa (function *);
+extern void init_tree_ssa (function *, int size = 0);
extern void delete_tree_ssa (function *);
extern bool tree_ssa_useless_type_conversion (tree);
extern tree tree_ssa_strip_useless_type_conversions (tree);
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 6ac97fe..1b9dcec 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -77,10 +77,10 @@ unsigned int ssa_name_nodes_created;
void
init_ssanames (struct function *fn, int size)
{
- if (size < 50)
- size = 50;
-
- vec_alloc (SSANAMES (fn), size);
+ if (!size)
+ vec_alloc (SSANAMES (fn), 50);
+ else
+ vec_safe_reserve (SSANAMES (fn), size, true);
/* Version 0 is special, so reserve the first slot in the table. Though
currently unused, we may use version 0 in alias analysis as part of
@@ -420,21 +420,30 @@ set_range_info (tree name, const value_range &vr)
is used to determine if MIN and MAX are valid values. */
enum value_range_kind
-get_range_info (const_tree name, wide_int *min, wide_int *max)
+get_range_info (const_tree expr, wide_int *min, wide_int *max)
{
- gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+ gcc_assert (!POINTER_TYPE_P (TREE_TYPE (expr)));
gcc_assert (min && max);
- range_info_def *ri = SSA_NAME_RANGE_INFO (name);
+ if (TREE_CODE (expr) == INTEGER_CST)
+ {
+ *min = wi::to_wide (expr);
+ *max = *min;
+ return VR_RANGE;
+ }
+ if (TREE_CODE (expr) != SSA_NAME)
+ return VR_VARYING;
+
+ range_info_def *ri = SSA_NAME_RANGE_INFO (expr);
/* Return VR_VARYING for SSA_NAMEs with NULL RANGE_INFO or SSA_NAMEs
with integral types width > 2 * HOST_BITS_PER_WIDE_INT precision. */
- if (!ri || (GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (TREE_TYPE (name)))
+ if (!ri || (GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (TREE_TYPE (expr)))
> 2 * HOST_BITS_PER_WIDE_INT))
return VR_VARYING;
*min = ri->get_min ();
*max = ri->get_max ();
- return SSA_NAME_RANGE_TYPE (name);
+ return SSA_NAME_RANGE_TYPE (expr);
}
/* Gets range information corresponding to ssa_name NAME and stores it
diff --git a/gcc/tree-streamer-out.c b/gcc/tree-streamer-out.c
index d7a451cf..9383cc4 100644
--- a/gcc/tree-streamer-out.c
+++ b/gcc/tree-streamer-out.c
@@ -343,7 +343,11 @@ pack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
{
bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1);
bp_pack_value (bp, TYPE_FINAL_P (expr), 1);
- bp_pack_value (bp, TYPE_CXX_ODR_P (expr), 1);
+ /* alias_ptr_types_compatible_p relies on fact that during LTO
+ types do not get refined from WPA time to ltrans. */
+ bp_pack_value (bp, flag_wpa && TYPE_CANONICAL (expr)
+ ? TYPE_CXX_ODR_P (TYPE_CANONICAL (expr))
+ : TYPE_CXX_ODR_P (expr), 1);
}
else if (TREE_CODE (expr) == ARRAY_TYPE)
bp_pack_value (bp, TYPE_NONALIASED_COMPONENT (expr), 1);
diff --git a/gcc/tree-streamer.c b/gcc/tree-streamer.c
index b0afa1d..a393983 100644
--- a/gcc/tree-streamer.c
+++ b/gcc/tree-streamer.c
@@ -317,6 +317,7 @@ record_common_node (struct streamer_tree_cache_d *cache, tree node)
case TREE_LIST:
case VOID_CST:
case VOID_TYPE:
+ case OPAQUE_TYPE:
/* No recursive trees. */
break;
case ARRAY_TYPE:
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 426462e..a87a2a3 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -1743,10 +1743,10 @@ switch_decision_tree::analyze_switch_statement ()
reset_out_edges_aux (m_switch);
- /* Find jump table clusters. */
- vec<cluster *> output = jump_table_cluster::find_jump_tables (clusters);
+ /* Find bit-test clusters. */
+ vec<cluster *> output = bit_test_cluster::find_bit_tests (clusters);
- /* Find bit test clusters. */
+ /* Find jump table clusters. */
vec<cluster *> output2;
auto_vec<cluster *> tmp;
output2.create (1);
@@ -1759,7 +1759,7 @@ switch_decision_tree::analyze_switch_statement ()
{
if (!tmp.is_empty ())
{
- vec<cluster *> n = bit_test_cluster::find_bit_tests (tmp);
+ vec<cluster *> n = jump_table_cluster::find_jump_tables (tmp);
output2.safe_splice (n);
n.release ();
tmp.truncate (0);
@@ -1773,7 +1773,7 @@ switch_decision_tree::analyze_switch_statement ()
/* We still can have a temporary vector to test. */
if (!tmp.is_empty ())
{
- vec<cluster *> n = bit_test_cluster::find_bit_tests (tmp);
+ vec<cluster *> n = jump_table_cluster::find_jump_tables (tmp);
output2.safe_splice (n);
n.release ();
}
diff --git a/gcc/tree-switch-conversion.h b/gcc/tree-switch-conversion.h
index 7515e95..62cfde1 100644
--- a/gcc/tree-switch-conversion.h
+++ b/gcc/tree-switch-conversion.h
@@ -48,8 +48,8 @@ class cluster
{
public:
/* Constructor. */
- cluster (tree case_label_expr, basic_block case_bb, profile_probability prob,
- profile_probability subtree_prob);
+ inline cluster (tree case_label_expr, basic_block case_bb,
+ profile_probability prob, profile_probability subtree_prob);
/* Destructor. */
virtual ~cluster ()
@@ -121,8 +121,9 @@ class simple_cluster: public cluster
{
public:
/* Constructor. */
- simple_cluster (tree low, tree high, tree case_label_expr,
- basic_block case_bb, profile_probability prob);
+ inline simple_cluster (tree low, tree high, tree case_label_expr,
+ basic_block case_bb, profile_probability prob,
+ bool has_forward_bb = false);
/* Destructor. */
~simple_cluster ()
@@ -146,6 +147,11 @@ public:
return m_high;
}
+ void set_high (tree high)
+ {
+ m_high = high;
+ }
+
void
debug ()
{
@@ -182,12 +188,16 @@ public:
/* True if case is a range. */
bool m_range_p;
+
+ /* True if the case will use a forwarder BB. */
+ bool m_has_forward_bb;
};
simple_cluster::simple_cluster (tree low, tree high, tree case_label_expr,
- basic_block case_bb, profile_probability prob):
+ basic_block case_bb, profile_probability prob,
+ bool has_forward_bb):
cluster (case_label_expr, case_bb, prob, prob),
- m_low (low), m_high (high)
+ m_low (low), m_high (high), m_has_forward_bb (has_forward_bb)
{
m_range_p = m_high != NULL;
if (m_high == NULL)
@@ -271,7 +281,7 @@ public:
static inline unsigned int case_values_threshold (void);
/* Return whether jump table expansion is allowed. */
- static bool is_enabled (void);
+ static inline bool is_enabled (void);
};
/* A GIMPLE switch statement can be expanded to a short sequence of bit-wise
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 0efab49..18e36c8 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -2161,7 +2161,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
{
unsigned max_allowed_peel
= param_vect_max_peeling_for_alignment;
- if (flag_vect_cost_model == VECT_COST_MODEL_CHEAP)
+ if (flag_vect_cost_model <= VECT_COST_MODEL_CHEAP)
max_allowed_peel = 0;
if (max_allowed_peel != (unsigned)-1)
{
@@ -2259,7 +2259,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
do_versioning
= (optimize_loop_nest_for_speed_p (loop)
&& !loop->inner /* FORNOW */
- && flag_vect_cost_model != VECT_COST_MODEL_CHEAP);
+ && flag_vect_cost_model > VECT_COST_MODEL_CHEAP);
if (do_versioning)
{
@@ -3682,6 +3682,10 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
unsigned int count = (comp_alias_ddrs.length ()
+ check_unequal_addrs.length ());
+ if (count && flag_vect_cost_model == VECT_COST_MODEL_VERY_CHEAP)
+ return opt_result::failure_at
+ (vect_location, "would need a runtime alias check\n");
+
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
"improved number of alias checks from %d to %d\n",
diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index d7bafa7..55cf0d9 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -2089,7 +2089,7 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi,
if (op >= FIRST_NORM_OPTAB && op <= LAST_NORM_OPTAB
&& optab_handler (op, TYPE_MODE (TREE_TYPE (type))) != CODE_FOR_nothing)
{
- tree slhs = make_ssa_name (TREE_TYPE (srhs1));
+ tree slhs = make_ssa_name (TREE_TYPE (TREE_TYPE (lhs)));
gimple *repl = gimple_build_assign (slhs, code, srhs1, srhs2);
gsi_insert_before (gsi, repl, GSI_SAME_STMT);
gimple_assign_set_rhs_from_tree (gsi,
@@ -2118,6 +2118,10 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi,
arguments, not the widened result. VEC_UNPACK_FLOAT_*_EXPR is
calculated in the same way above. */
if (code == WIDEN_SUM_EXPR
+ || code == VEC_WIDEN_PLUS_HI_EXPR
+ || code == VEC_WIDEN_PLUS_LO_EXPR
+ || code == VEC_WIDEN_MINUS_HI_EXPR
+ || code == VEC_WIDEN_MINUS_LO_EXPR
|| code == VEC_WIDEN_MULT_HI_EXPR
|| code == VEC_WIDEN_MULT_LO_EXPR
|| code == VEC_WIDEN_MULT_EVEN_EXPR
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 39b7319..72bbec4 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -1827,6 +1827,19 @@ vect_analyze_loop_costing (loop_vec_info loop_vinfo)
}
}
+ /* If using the "very cheap" model. reject cases in which we'd keep
+ a copy of the scalar code (even if we might be able to vectorize it). */
+ if (flag_vect_cost_model == VECT_COST_MODEL_VERY_CHEAP
+ && (LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo)
+ || LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo)
+ || LOOP_VINFO_PEELING_FOR_NITER (loop_vinfo)))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "some scalar iterations would need to be peeled\n");
+ return 0;
+ }
+
int min_profitable_iters, min_profitable_estimate;
vect_estimate_min_profitable_iters (loop_vinfo, &min_profitable_iters,
&min_profitable_estimate);
@@ -1885,6 +1898,20 @@ vect_analyze_loop_costing (loop_vec_info loop_vinfo)
min_profitable_estimate = min_profitable_iters;
}
+ /* If the vector loop needs multiple iterations to be beneficial then
+ things are probably too close to call, and the conservative thing
+ would be to stick with the scalar code. */
+ if (flag_vect_cost_model == VECT_COST_MODEL_VERY_CHEAP
+ && min_profitable_estimate > (int) vect_vf_for_cost (loop_vinfo))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "one iteration of the vector loop would be"
+ " more expensive than the equivalent number of"
+ " iterations of the scalar loop\n");
+ return 0;
+ }
+
HOST_WIDE_INT estimated_niter;
/* If we are vectorizing an epilogue then we know the maximum number of
@@ -2298,6 +2325,9 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo, bool &fatal, unsigned *n_stmts)
/* Optimize the SLP graph with the vectorization factor fixed. */
vect_optimize_slp (loop_vinfo);
+
+ /* Gather the loads reachable from the SLP graph entries. */
+ vect_gather_slp_loads (loop_vinfo);
}
bool saved_can_use_partial_vectors_p
@@ -7590,6 +7620,17 @@ vectorizable_lc_phi (loop_vec_info loop_vinfo,
if (!vec_stmt) /* transformation not required. */
{
+ /* Deal with copies from externs or constants that disguise as
+ loop-closed PHI nodes (PR97886). */
+ if (slp_node
+ && !vect_maybe_update_slp_op_vectype (SLP_TREE_CHILDREN (slp_node)[0],
+ SLP_TREE_VECTYPE (slp_node)))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "incompatible vector types for invariants\n");
+ return false;
+ }
STMT_VINFO_TYPE (stmt_info) = lc_phi_info_type;
return true;
}
@@ -7999,6 +8040,7 @@ vectorizable_induction (loop_vec_info loop_vinfo,
{
/* The scalar steps of the IVs. */
tree elt = steps[(ivn*const_nunits + eltn) % group_size];
+ elt = gimple_convert (&init_stmts, TREE_TYPE (step_vectype), elt);
step_elts.quick_push (elt);
if (!init_node)
{
@@ -8018,7 +8060,6 @@ vectorizable_induction (loop_vec_info loop_vinfo,
: build_int_cstu (stept, mul_elt));
}
vec_step = gimple_build_vector (&init_stmts, &step_elts);
- vec_step = gimple_convert (&init_stmts, step_vectype, vec_step);
vec_steps.safe_push (vec_step);
tree step_mul = gimple_build_vector (&init_stmts, &mul_elts);
if (peel_mul)
@@ -8702,6 +8743,24 @@ vectorizable_live_operation (vec_info *vinfo,
"def\n");
continue;
}
+ /* ??? It can also happen that we end up pulling a def into
+ a loop where replacing out-of-loop uses would require
+ a new LC SSA PHI node. Retain the original scalar in
+ those cases as well. PR98064. */
+ if (TREE_CODE (new_tree) == SSA_NAME
+ && !SSA_NAME_IS_DEFAULT_DEF (new_tree)
+ && (gimple_bb (use_stmt)->loop_father
+ != gimple_bb (vec_stmt)->loop_father)
+ && !flow_loop_nested_p (gimple_bb (vec_stmt)->loop_father,
+ gimple_bb (use_stmt)->loop_father))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Using original scalar computation for "
+ "live lane because there is an out-of-loop "
+ "definition for it\n");
+ continue;
+ }
FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
SET_USE (use_p, new_tree);
update_stmt (use_stmt);
@@ -9022,7 +9081,7 @@ maybe_set_vectorized_backedge_value (loop_vec_info loop_vinfo,
When vectorizing STMT_INFO as a store, set *SEEN_STORE to its
stmt_vec_info. */
-static void
+static bool
vect_transform_loop_stmt (loop_vec_info loop_vinfo, stmt_vec_info stmt_info,
gimple_stmt_iterator *gsi, stmt_vec_info *seen_store)
{
@@ -9038,7 +9097,7 @@ vect_transform_loop_stmt (loop_vec_info loop_vinfo, stmt_vec_info stmt_info,
if (!STMT_VINFO_RELEVANT_P (stmt_info)
&& !STMT_VINFO_LIVE_P (stmt_info))
- return;
+ return false;
if (STMT_VINFO_VECTYPE (stmt_info))
{
@@ -9055,13 +9114,15 @@ vect_transform_loop_stmt (loop_vec_info loop_vinfo, stmt_vec_info stmt_info,
/* Pure SLP statements have already been vectorized. We still need
to apply loop vectorization to hybrid SLP statements. */
if (PURE_SLP_STMT (stmt_info))
- return;
+ return false;
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location, "transform statement.\n");
if (vect_transform_stmt (loop_vinfo, stmt_info, gsi, NULL, NULL))
*seen_store = stmt_info;
+
+ return true;
}
/* Helper function to pass to simplify_replace_tree to enable replacing tree's
@@ -9487,17 +9548,17 @@ vect_transform_loop (loop_vec_info loop_vinfo, gimple *loop_vectorized_call)
}
stmt_vec_info pat_stmt_info
= STMT_VINFO_RELATED_STMT (stmt_info);
- vect_transform_loop_stmt (loop_vinfo, pat_stmt_info, &si,
- &seen_store);
- maybe_set_vectorized_backedge_value (loop_vinfo,
- pat_stmt_info);
+ if (vect_transform_loop_stmt (loop_vinfo, pat_stmt_info,
+ &si, &seen_store))
+ maybe_set_vectorized_backedge_value (loop_vinfo,
+ pat_stmt_info);
}
else
{
- vect_transform_loop_stmt (loop_vinfo, stmt_info, &si,
- &seen_store);
- maybe_set_vectorized_backedge_value (loop_vinfo,
- stmt_info);
+ if (vect_transform_loop_stmt (loop_vinfo, stmt_info, &si,
+ &seen_store))
+ maybe_set_vectorized_backedge_value (loop_vinfo,
+ stmt_info);
}
}
gsi_next (&si);
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index f68a87e..f2ce75a 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -1148,7 +1148,7 @@ vect_recog_sad_pattern (vec_info *vinfo,
/* FORNOW. Can continue analyzing the def-use chain when this stmt in a phi
inside the loop (in case we are analyzing an outer-loop). */
vect_unpromoted_value unprom[2];
- if (!vect_widened_op_tree (vinfo, diff_stmt_vinfo, MINUS_EXPR, MINUS_EXPR,
+ if (!vect_widened_op_tree (vinfo, diff_stmt_vinfo, MINUS_EXPR, WIDEN_MINUS_EXPR,
false, 2, unprom, &half_type))
return NULL;
@@ -1262,6 +1262,29 @@ vect_recog_widen_mult_pattern (vec_info *vinfo, stmt_vec_info last_stmt_info,
"vect_recog_widen_mult_pattern");
}
+/* Try to detect addition on widened inputs, converting PLUS_EXPR
+ to WIDEN_PLUS_EXPR. See vect_recog_widen_op_pattern for details. */
+
+static gimple *
+vect_recog_widen_plus_pattern (vec_info *vinfo, stmt_vec_info last_stmt_info,
+ tree *type_out)
+{
+ return vect_recog_widen_op_pattern (vinfo, last_stmt_info, type_out,
+ PLUS_EXPR, WIDEN_PLUS_EXPR, false,
+ "vect_recog_widen_plus_pattern");
+}
+
+/* Try to detect subtraction on widened inputs, converting MINUS_EXPR
+ to WIDEN_MINUS_EXPR. See vect_recog_widen_op_pattern for details. */
+static gimple *
+vect_recog_widen_minus_pattern (vec_info *vinfo, stmt_vec_info last_stmt_info,
+ tree *type_out)
+{
+ return vect_recog_widen_op_pattern (vinfo, last_stmt_info, type_out,
+ MINUS_EXPR, WIDEN_MINUS_EXPR, false,
+ "vect_recog_widen_minus_pattern");
+}
+
/* Function vect_recog_pow_pattern
Try to find the following pattern:
@@ -1978,7 +2001,7 @@ vect_recog_average_pattern (vec_info *vinfo,
vect_unpromoted_value unprom[3];
tree new_type;
unsigned int nops = vect_widened_op_tree (vinfo, plus_stmt_info, PLUS_EXPR,
- PLUS_EXPR, false, 3,
+ WIDEN_PLUS_EXPR, false, 3,
unprom, &new_type);
if (nops == 0)
return NULL;
@@ -5249,7 +5272,9 @@ static vect_recog_func vect_vect_recog_func_ptrs[] = {
of mask conversion that are needed for gather and scatter
internal functions. */
{ vect_recog_gather_scatter_pattern, "gather_scatter" },
- { vect_recog_mask_conversion_pattern, "mask_conversion" }
+ { vect_recog_mask_conversion_pattern, "mask_conversion" },
+ { vect_recog_widen_plus_pattern, "widen_plus" },
+ { vect_recog_widen_minus_pattern, "widen_minus" },
};
const unsigned int NUM_PATTERNS = ARRAY_SIZE (vect_vect_recog_func_ptrs);
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index e4c2aa4..3bd40cb 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -48,11 +48,28 @@ along with GCC; see the file COPYING3. If not see
#include "cfganal.h"
#include "tree-eh.h"
#include "tree-cfg.h"
+#include "alloc-pool.h"
static bool vectorizable_slp_permutation (vec_info *, gimple_stmt_iterator *,
slp_tree, stmt_vector_for_cost *);
-object_allocator<_slp_tree> *slp_tree_pool;
+static object_allocator<_slp_tree> *slp_tree_pool;
+static slp_tree slp_first_node;
+
+void
+vect_slp_init (void)
+{
+ slp_tree_pool = new object_allocator<_slp_tree> ("SLP nodes");
+}
+
+void
+vect_slp_fini (void)
+{
+ while (slp_first_node)
+ delete slp_first_node;
+ delete slp_tree_pool;
+ slp_tree_pool = NULL;
+}
void *
_slp_tree::operator new (size_t n)
@@ -73,6 +90,11 @@ _slp_tree::operator delete (void *node, size_t n)
_slp_tree::_slp_tree ()
{
+ this->prev_node = NULL;
+ if (slp_first_node)
+ slp_first_node->prev_node = this;
+ this->next_node = slp_first_node;
+ slp_first_node = this;
SLP_TREE_SCALAR_STMTS (this) = vNULL;
SLP_TREE_SCALAR_OPS (this) = vNULL;
SLP_TREE_VEC_STMTS (this) = vNULL;
@@ -94,6 +116,12 @@ _slp_tree::_slp_tree ()
_slp_tree::~_slp_tree ()
{
+ if (this->prev_node)
+ this->prev_node->next_node = this->next_node;
+ else
+ slp_first_node = this->next_node;
+ if (this->next_node)
+ this->next_node->prev_node = this->prev_node;
SLP_TREE_CHILDREN (this).release ();
SLP_TREE_SCALAR_STMTS (this).release ();
SLP_TREE_SCALAR_OPS (this).release ();
@@ -1908,6 +1936,14 @@ vect_print_slp_tree (dump_flags_t dump_kind, dump_location_t loc,
: ""), node,
estimated_poly_value (node->max_nunits),
SLP_TREE_REF_COUNT (node));
+ if (SLP_TREE_DEF_TYPE (node) == vect_internal_def)
+ {
+ if (SLP_TREE_CODE (node) == VEC_PERM_EXPR)
+ dump_printf_loc (metadata, user_loc, "op: VEC_PERM_EXPR\n");
+ else
+ dump_printf_loc (metadata, user_loc, "op template: %G",
+ SLP_TREE_REPRESENTATIVE (node)->stmt);
+ }
if (SLP_TREE_SCALAR_STMTS (node).exists ())
FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt_info)
dump_printf_loc (metadata, user_loc, "\tstmt %u %G", i, stmt_info->stmt);
@@ -2071,13 +2107,6 @@ vect_gather_slp_loads (vec<slp_tree> &loads, slp_tree node,
}
}
-static void
-vect_gather_slp_loads (slp_instance inst, slp_tree node)
-{
- hash_set<slp_tree> visited;
- vect_gather_slp_loads (SLP_INSTANCE_LOADS (inst), node, visited);
-}
-
/* Find the last store in SLP INSTANCE. */
@@ -2252,7 +2281,6 @@ vect_build_slp_instance (vec_info *vinfo,
new_instance->cost_vec = vNULL;
new_instance->subgraph_entries = vNULL;
- vect_gather_slp_loads (new_instance, node);
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
"SLP size %u vs. limit %u.\n",
@@ -2629,8 +2657,18 @@ vect_slp_build_vertices (vec_info *info, vec<slp_tree> &vertices,
unsigned i;
slp_instance instance;
FOR_EACH_VEC_ELT (info->slp_instances, i, instance)
- vect_slp_build_vertices (visited, SLP_INSTANCE_TREE (instance), vertices,
- leafs);
+ {
+ unsigned n_v = vertices.length ();
+ unsigned n_l = leafs.length ();
+ vect_slp_build_vertices (visited, SLP_INSTANCE_TREE (instance), vertices,
+ leafs);
+ /* If we added vertices but no entries to the reverse graph we've
+ added a cycle that is not backwards-reachable. Push the entry
+ to mimic as leaf then. */
+ if (vertices.length () > n_v
+ && leafs.length () == n_l)
+ leafs.safe_push (SLP_INSTANCE_TREE (instance)->vertex);
+ }
}
/* Apply (reverse) bijectite PERM to VEC. */
@@ -2724,9 +2762,11 @@ vect_optimize_slp (vec_info *vinfo)
|| SLP_TREE_DEF_TYPE (node) == vect_constant_def)
continue;
- /* Loads are the only thing generating permutes and leafs do not
- change across iterations. */
- bitmap_set_bit (n_visited, idx);
+ /* Leafs do not change across iterations. Note leafs also double
+ as entries to the reverse graph. */
+ if (!slpg->vertices[idx].succ)
+ bitmap_set_bit (n_visited, idx);
+ /* Loads are the only thing generating permutes. */
if (!SLP_TREE_LOAD_PERMUTATION (node).exists ())
continue;
@@ -3059,6 +3099,21 @@ vect_optimize_slp (vec_info *vinfo)
}
}
+/* Gather loads reachable from the individual SLP graph entries. */
+
+void
+vect_gather_slp_loads (vec_info *vinfo)
+{
+ unsigned i;
+ slp_instance instance;
+ FOR_EACH_VEC_ELT (vinfo->slp_instances, i, instance)
+ {
+ hash_set<slp_tree> visited;
+ vect_gather_slp_loads (SLP_INSTANCE_LOADS (instance),
+ SLP_INSTANCE_TREE (instance), visited);
+ }
+}
+
/* For each possible SLP instance decide whether to SLP it and calculate overall
unrolling factor needed to SLP the loop. Return TRUE if decided to SLP at
@@ -3142,6 +3197,65 @@ vect_detect_hybrid_slp (tree *tp, int *, void *data)
return NULL_TREE;
}
+/* Look if STMT_INFO is consumed by SLP indirectly and mark it pure_slp
+ if so, otherwise pushing it to WORKLIST. */
+
+static void
+maybe_push_to_hybrid_worklist (vec_info *vinfo,
+ vec<stmt_vec_info> &worklist,
+ stmt_vec_info stmt_info)
+{
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Processing hybrid candidate : %G", stmt_info->stmt);
+ stmt_vec_info orig_info = vect_orig_stmt (stmt_info);
+ imm_use_iterator iter2;
+ ssa_op_iter iter1;
+ use_operand_p use_p;
+ def_operand_p def_p;
+ bool any_def = false;
+ FOR_EACH_PHI_OR_STMT_DEF (def_p, orig_info->stmt, iter1, SSA_OP_DEF)
+ {
+ any_def = true;
+ FOR_EACH_IMM_USE_FAST (use_p, iter2, DEF_FROM_PTR (def_p))
+ {
+ if (is_gimple_debug (USE_STMT (use_p)))
+ continue;
+ stmt_vec_info use_info = vinfo->lookup_stmt (USE_STMT (use_p));
+ /* An out-of loop use means this is a loop_vect sink. */
+ if (!use_info)
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Found loop_vect sink: %G", stmt_info->stmt);
+ worklist.safe_push (stmt_info);
+ return;
+ }
+ else if (!STMT_SLP_TYPE (vect_stmt_to_vectorize (use_info)))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Found loop_vect use: %G", use_info->stmt);
+ worklist.safe_push (stmt_info);
+ return;
+ }
+ }
+ }
+ /* No def means this is a loo_vect sink. */
+ if (!any_def)
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Found loop_vect sink: %G", stmt_info->stmt);
+ worklist.safe_push (stmt_info);
+ return;
+ }
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Marked SLP consumed stmt pure: %G", stmt_info->stmt);
+ STMT_SLP_TYPE (stmt_info) = pure_slp;
+}
+
/* Find stmts that must be both vectorized and SLPed. */
void
@@ -3151,9 +3265,14 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo)
/* All stmts participating in SLP are marked pure_slp, all other
stmts are loop_vect.
- First collect all loop_vect stmts into a worklist. */
+ First collect all loop_vect stmts into a worklist.
+ SLP patterns cause not all original scalar stmts to appear in
+ SLP_TREE_SCALAR_STMTS and thus not all of them are marked pure_slp.
+ Rectify this here and do a backward walk over the IL only considering
+ stmts as loop_vect when they are used by a loop_vect stmt and otherwise
+ mark them as pure_slp. */
auto_vec<stmt_vec_info> worklist;
- for (unsigned i = 0; i < LOOP_VINFO_LOOP (loop_vinfo)->num_nodes; ++i)
+ for (int i = LOOP_VINFO_LOOP (loop_vinfo)->num_nodes - 1; i >= 0; --i)
{
basic_block bb = LOOP_VINFO_BBS (loop_vinfo)[i];
for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
@@ -3162,10 +3281,11 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo)
gphi *phi = gsi.phi ();
stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (phi);
if (!STMT_SLP_TYPE (stmt_info) && STMT_VINFO_RELEVANT (stmt_info))
- worklist.safe_push (stmt_info);
+ maybe_push_to_hybrid_worklist (loop_vinfo,
+ worklist, stmt_info);
}
- for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
- gsi_next (&gsi))
+ for (gimple_stmt_iterator gsi = gsi_last_bb (bb); !gsi_end_p (gsi);
+ gsi_prev (&gsi))
{
gimple *stmt = gsi_stmt (gsi);
if (is_gimple_debug (stmt))
@@ -3181,12 +3301,14 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo)
= loop_vinfo->lookup_stmt (gsi_stmt (gsi2));
if (!STMT_SLP_TYPE (patt_info)
&& STMT_VINFO_RELEVANT (patt_info))
- worklist.safe_push (patt_info);
+ maybe_push_to_hybrid_worklist (loop_vinfo,
+ worklist, patt_info);
}
stmt_info = STMT_VINFO_RELATED_STMT (stmt_info);
}
if (!STMT_SLP_TYPE (stmt_info) && STMT_VINFO_RELEVANT (stmt_info))
- worklist.safe_push (stmt_info);
+ maybe_push_to_hybrid_worklist (loop_vinfo,
+ worklist, stmt_info);
}
}
@@ -4140,6 +4262,9 @@ vect_slp_analyze_bb_1 (bb_vec_info bb_vinfo, int n_stmts, bool &fatal,
/* Optimize permutations. */
vect_optimize_slp (bb_vinfo);
+ /* Gather the loads reachable from the SLP graph entries. */
+ vect_gather_slp_loads (bb_vinfo);
+
vect_record_base_alignments (bb_vinfo);
/* Analyze and verify the alignment of data references and the
@@ -5092,7 +5217,8 @@ vectorizable_slp_permutation (vec_info *vinfo, gimple_stmt_iterator *gsi,
slp_tree child;
unsigned i;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
- if (!types_compatible_p (SLP_TREE_VECTYPE (child), vectype))
+ if (!vect_maybe_update_slp_op_vectype (child, vectype)
+ || !types_compatible_p (SLP_TREE_VECTYPE (child), vectype))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 2c7a8a7..a4980a9 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -3427,7 +3427,8 @@ vectorizable_call (vec_info *vinfo,
{
vec_defs.quick_push (vNULL);
vect_get_vec_defs_for_operand (vinfo, stmt_info, ncopies,
- op, &vec_defs[i]);
+ op, &vec_defs[i],
+ vectypes[i]);
}
orig_vargs[i] = vargs[i] = vec_defs[i][j];
}
@@ -4570,6 +4571,8 @@ vectorizable_conversion (vec_info *vinfo,
if (!CONVERT_EXPR_CODE_P (code)
&& code != FIX_TRUNC_EXPR
&& code != FLOAT_EXPR
+ && code != WIDEN_PLUS_EXPR
+ && code != WIDEN_MINUS_EXPR
&& code != WIDEN_MULT_EXPR
&& code != WIDEN_LSHIFT_EXPR)
return false;
@@ -4615,7 +4618,8 @@ vectorizable_conversion (vec_info *vinfo,
if (op_type == binary_op)
{
- gcc_assert (code == WIDEN_MULT_EXPR || code == WIDEN_LSHIFT_EXPR);
+ gcc_assert (code == WIDEN_MULT_EXPR || code == WIDEN_LSHIFT_EXPR
+ || code == WIDEN_PLUS_EXPR || code == WIDEN_MINUS_EXPR);
op1 = gimple_assign_rhs2 (stmt);
tree vectype1_in;
@@ -4931,8 +4935,9 @@ vectorizable_conversion (vec_info *vinfo,
&vec_oprnds1);
if (code == WIDEN_LSHIFT_EXPR)
{
- vec_oprnds1.create (ncopies * ninputs);
- for (i = 0; i < ncopies * ninputs; ++i)
+ int oprnds_size = vec_oprnds0.length ();
+ vec_oprnds1.create (oprnds_size);
+ for (i = 0; i < oprnds_size; ++i)
vec_oprnds1.quick_push (op1);
}
/* Arguments are ready. Create the new vector stmts. */
@@ -11534,6 +11539,16 @@ supportable_widening_operation (vec_info *vinfo,
c2 = VEC_WIDEN_LSHIFT_HI_EXPR;
break;
+ case WIDEN_PLUS_EXPR:
+ c1 = VEC_WIDEN_PLUS_LO_EXPR;
+ c2 = VEC_WIDEN_PLUS_HI_EXPR;
+ break;
+
+ case WIDEN_MINUS_EXPR:
+ c1 = VEC_WIDEN_MINUS_LO_EXPR;
+ c2 = VEC_WIDEN_MINUS_HI_EXPR;
+ break;
+
CASE_CONVERT:
c1 = VEC_UNPACK_LO_EXPR;
c2 = VEC_UNPACK_HI_EXPR;
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index b63dda3..f9e2642 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -1171,7 +1171,7 @@ vectorize_loops (void)
if (vect_loops_num <= 1)
return 0;
- slp_tree_pool = new object_allocator<_slp_tree> ("SLP nodes for vect");
+ vect_slp_init ();
if (cfun->has_simduid_loops)
note_simd_array_uses (&simd_array_to_simduid_htab);
@@ -1295,8 +1295,7 @@ vectorize_loops (void)
shrink_simd_arrays (simd_array_to_simduid_htab, simduid_to_vf_htab);
delete simduid_to_vf_htab;
cfun->has_simduid_loops = false;
- delete slp_tree_pool;
- slp_tree_pool = NULL;
+ vect_slp_fini ();
if (num_vectorized_loops > 0)
{
@@ -1432,12 +1431,11 @@ pass_slp_vectorize::execute (function *fun)
}
}
- slp_tree_pool = new object_allocator<_slp_tree> ("SLP nodes for slp");
+ vect_slp_init ();
vect_slp_function (fun);
- delete slp_tree_pool;
- slp_tree_pool = NULL;
+ vect_slp_fini ();
if (!in_loop_pipeline)
{
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 3ccd0fd..c0f786c 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -26,7 +26,6 @@ typedef class _stmt_vec_info *stmt_vec_info;
#include "tree-data-ref.h"
#include "tree-hash-traits.h"
#include "target.h"
-#include "alloc-pool.h"
/* Used for naming of new temporaries. */
@@ -116,8 +115,6 @@ typedef hash_map<tree_operand_hash,
************************************************************************/
typedef struct _slp_tree *slp_tree;
-extern object_allocator<_slp_tree> *slp_tree_pool;
-
/* A computation tree of an SLP instance. Each node corresponds to a group of
stmts to be packed in a SIMD stmt. */
struct _slp_tree {
@@ -172,6 +169,10 @@ struct _slp_tree {
/* Return memory to slp_tree_pool. */
static void operator delete (void *, size_t);
+
+ /* Linked list of nodes to release when we free the slp_tree_pool. */
+ slp_tree next_node;
+ slp_tree prev_node;
};
/* The enum describes the type of operations that an SLP instance
@@ -1963,6 +1964,8 @@ extern int vect_get_known_peeling_cost (loop_vec_info, int, int *,
extern tree cse_and_gimplify_to_preheader (loop_vec_info, tree);
/* In tree-vect-slp.c. */
+extern void vect_slp_init (void);
+extern void vect_slp_fini (void);
extern void vect_free_slp_instance (slp_instance);
extern bool vect_transform_slp_perm_load (vec_info *, slp_tree, vec<tree>,
gimple_stmt_iterator *, poly_uint64,
@@ -1974,6 +1977,7 @@ extern opt_result vect_analyze_slp (vec_info *, unsigned);
extern bool vect_make_slp_decision (loop_vec_info);
extern void vect_detect_hybrid_slp (loop_vec_info);
extern void vect_optimize_slp (vec_info *);
+extern void vect_gather_slp_loads (vec_info *);
extern void vect_get_slp_defs (slp_tree, vec<tree> *);
extern void vect_get_slp_defs (vec_info *, slp_tree, vec<vec<tree> > *,
unsigned n = -1U);
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index e00c034..d661866 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -161,153 +161,6 @@ live_names::live_on_block_p (tree name, basic_block bb)
&& bitmap_bit_p (live[bb->index], SSA_NAME_VERSION (name)));
}
-
-/* Location information for ASSERT_EXPRs. Each instance of this
- structure describes an ASSERT_EXPR for an SSA name. Since a single
- SSA name may have more than one assertion associated with it, these
- locations are kept in a linked list attached to the corresponding
- SSA name. */
-struct assert_locus
-{
- /* Basic block where the assertion would be inserted. */
- basic_block bb;
-
- /* Some assertions need to be inserted on an edge (e.g., assertions
- generated by COND_EXPRs). In those cases, BB will be NULL. */
- edge e;
-
- /* Pointer to the statement that generated this assertion. */
- gimple_stmt_iterator si;
-
- /* Predicate code for the ASSERT_EXPR. Must be COMPARISON_CLASS_P. */
- enum tree_code comp_code;
-
- /* Value being compared against. */
- tree val;
-
- /* Expression to compare. */
- tree expr;
-
- /* Next node in the linked list. */
- assert_locus *next;
-};
-
-class vrp_insert
-{
-public:
- vrp_insert (struct function *fn) : fun (fn) { }
-
- /* Traverse the flowgraph looking for conditional jumps to insert range
- expressions. These range expressions are meant to provide information
- to optimizations that need to reason in terms of value ranges. They
- will not be expanded into RTL. See method implementation comment
- for example. */
- void insert_range_assertions ();
-
- /* Convert range assertion expressions into the implied copies and
- copy propagate away the copies. */
- void remove_range_assertions ();
-
- /* Dump all the registered assertions for all the names to FILE. */
- void dump (FILE *);
-
- /* Dump all the registered assertions for NAME to FILE. */
- void dump (FILE *file, tree name);
-
- /* Dump all the registered assertions for NAME to stderr. */
- void debug (tree name)
- {
- dump (stderr, name);
- }
-
- /* Dump all the registered assertions for all the names to stderr. */
- void debug ()
- {
- dump (stderr);
- }
-
-private:
- /* Set of SSA names found live during the RPO traversal of the function
- for still active basic-blocks. */
- live_names live;
-
- /* Function to work on. */
- struct function *fun;
-
- /* If bit I is present, it means that SSA name N_i has a list of
- assertions that should be inserted in the IL. */
- bitmap need_assert_for;
-
- /* Array of locations lists where to insert assertions. ASSERTS_FOR[I]
- holds a list of ASSERT_LOCUS_T nodes that describe where
- ASSERT_EXPRs for SSA name N_I should be inserted. */
- assert_locus **asserts_for;
-
- /* Finish found ASSERTS for E and register them at GSI. */
- void finish_register_edge_assert_for (edge e, gimple_stmt_iterator gsi,
- vec<assert_info> &asserts);
-
- /* Determine whether the outgoing edges of BB should receive an
- ASSERT_EXPR for each of the operands of BB's LAST statement. The
- last statement of BB must be a SWITCH_EXPR.
-
- If any of the sub-graphs rooted at BB have an interesting use of
- the predicate operands, an assert location node is added to the
- list of assertions for the corresponding operands. */
- void find_switch_asserts (basic_block bb, gswitch *last);
-
- /* Do an RPO walk over the function computing SSA name liveness
- on-the-fly and deciding on assert expressions to insert. */
- void find_assert_locations ();
-
- /* Traverse all the statements in block BB looking for statements that
- may generate useful assertions for the SSA names in their operand.
- See method implementation comentary for more information. */
- void find_assert_locations_in_bb (basic_block bb);
-
- /* Determine whether the outgoing edges of BB should receive an
- ASSERT_EXPR for each of the operands of BB's LAST statement.
- The last statement of BB must be a COND_EXPR.
-
- If any of the sub-graphs rooted at BB have an interesting use of
- the predicate operands, an assert location node is added to the
- list of assertions for the corresponding operands. */
- void find_conditional_asserts (basic_block bb, gcond *last);
-
- /* Process all the insertions registered for every name N_i registered
- in NEED_ASSERT_FOR. The list of assertions to be inserted are
- found in ASSERTS_FOR[i]. */
- void process_assert_insertions ();
-
- /* If NAME doesn't have an ASSERT_EXPR registered for asserting
- 'EXPR COMP_CODE VAL' at a location that dominates block BB or
- E->DEST, then register this location as a possible insertion point
- for ASSERT_EXPR <NAME, EXPR COMP_CODE VAL>.
-
- BB, E and SI provide the exact insertion point for the new
- ASSERT_EXPR. If BB is NULL, then the ASSERT_EXPR is to be inserted
- on edge E. Otherwise, if E is NULL, the ASSERT_EXPR is inserted on
- BB. If SI points to a COND_EXPR or a SWITCH_EXPR statement, then E
- must not be NULL. */
- void register_new_assert_for (tree name, tree expr,
- enum tree_code comp_code,
- tree val, basic_block bb,
- edge e, gimple_stmt_iterator si);
-
- /* Given a COND_EXPR COND of the form 'V OP W', and an SSA name V,
- create a new SSA name N and return the assertion assignment
- 'N = ASSERT_EXPR <V, V OP W>'. */
- gimple *build_assert_expr_for (tree cond, tree v);
-
- /* Create an ASSERT_EXPR for NAME and insert it in the location
- indicated by LOC. Return true if we made any edge insertions. */
- bool process_assert_insertions_for (tree name, assert_locus *loc);
-
- /* Qsort callback for sorting assert locations. */
- template <bool stable> static int compare_assert_loc (const void *,
- const void *);
-};
-
/* Return true if the SSA name NAME is live on the edge E. */
bool
@@ -1266,48 +1119,6 @@ range_fold_unary_expr (value_range *vr,
op->fold_range (*vr, expr_type, vr0_cst, value_range (expr_type));
}
-/* Given a COND_EXPR COND of the form 'V OP W', and an SSA name V,
- create a new SSA name N and return the assertion assignment
- 'N = ASSERT_EXPR <V, V OP W>'. */
-
-gimple *
-vrp_insert::build_assert_expr_for (tree cond, tree v)
-{
- tree a;
- gassign *assertion;
-
- gcc_assert (TREE_CODE (v) == SSA_NAME
- && COMPARISON_CLASS_P (cond));
-
- a = build2 (ASSERT_EXPR, TREE_TYPE (v), v, cond);
- assertion = gimple_build_assign (NULL_TREE, a);
-
- /* The new ASSERT_EXPR, creates a new SSA name that replaces the
- operand of the ASSERT_EXPR. Create it so the new name and the old one
- are registered in the replacement table so that we can fix the SSA web
- after adding all the ASSERT_EXPRs. */
- tree new_def = create_new_def_for (v, assertion, NULL);
- /* Make sure we preserve abnormalness throughout an ASSERT_EXPR chain
- given we have to be able to fully propagate those out to re-create
- valid SSA when removing the asserts. */
- if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (v))
- SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_def) = 1;
-
- return assertion;
-}
-
-
-/* Return false if EXPR is a predicate expression involving floating
- point values. */
-
-static inline bool
-fp_predicate (gimple *stmt)
-{
- GIMPLE_CHECK (stmt, GIMPLE_COND);
-
- return FLOAT_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)));
-}
-
/* If the range of values taken by OP can be inferred after STMT executes,
return the comparison code (COMP_CODE_P) and value (VAL_P) that
describes the inferred range. Return true if a range could be
@@ -1350,54 +1161,6 @@ infer_value_range (gimple *stmt, tree op, tree_code *comp_code_p, tree *val_p)
return false;
}
-/* Dump all the registered assertions for NAME to FILE. */
-
-void
-vrp_insert::dump (FILE *file, tree name)
-{
- assert_locus *loc;
-
- fprintf (file, "Assertions to be inserted for ");
- print_generic_expr (file, name);
- fprintf (file, "\n");
-
- loc = asserts_for[SSA_NAME_VERSION (name)];
- while (loc)
- {
- fprintf (file, "\t");
- print_gimple_stmt (file, gsi_stmt (loc->si), 0);
- fprintf (file, "\n\tBB #%d", loc->bb->index);
- if (loc->e)
- {
- fprintf (file, "\n\tEDGE %d->%d", loc->e->src->index,
- loc->e->dest->index);
- dump_edge_info (file, loc->e, dump_flags, 0);
- }
- fprintf (file, "\n\tPREDICATE: ");
- print_generic_expr (file, loc->expr);
- fprintf (file, " %s ", get_tree_code_name (loc->comp_code));
- print_generic_expr (file, loc->val);
- fprintf (file, "\n\n");
- loc = loc->next;
- }
-
- fprintf (file, "\n");
-}
-
-/* Dump all the registered assertions for all the names to FILE. */
-
-void
-vrp_insert::dump (FILE *file)
-{
- unsigned i;
- bitmap_iterator bi;
-
- fprintf (file, "\nASSERT_EXPRs to be inserted\n\n");
- EXECUTE_IF_SET_IN_BITMAP (need_assert_for, 0, i, bi)
- dump (file, ssa_name (i));
- fprintf (file, "\n");
-}
-
/* Dump assert_info structure. */
void
@@ -1457,117 +1220,6 @@ add_assert_info (vec<assert_info> &asserts,
name, expr, op_symbol_code (comp_code), val);
}
-/* If NAME doesn't have an ASSERT_EXPR registered for asserting
- 'EXPR COMP_CODE VAL' at a location that dominates block BB or
- E->DEST, then register this location as a possible insertion point
- for ASSERT_EXPR <NAME, EXPR COMP_CODE VAL>.
-
- BB, E and SI provide the exact insertion point for the new
- ASSERT_EXPR. If BB is NULL, then the ASSERT_EXPR is to be inserted
- on edge E. Otherwise, if E is NULL, the ASSERT_EXPR is inserted on
- BB. If SI points to a COND_EXPR or a SWITCH_EXPR statement, then E
- must not be NULL. */
-
-void
-vrp_insert::register_new_assert_for (tree name, tree expr,
- enum tree_code comp_code,
- tree val,
- basic_block bb,
- edge e,
- gimple_stmt_iterator si)
-{
- assert_locus *n, *loc, *last_loc;
- basic_block dest_bb;
-
- gcc_checking_assert (bb == NULL || e == NULL);
-
- if (e == NULL)
- gcc_checking_assert (gimple_code (gsi_stmt (si)) != GIMPLE_COND
- && gimple_code (gsi_stmt (si)) != GIMPLE_SWITCH);
-
- /* Never build an assert comparing against an integer constant with
- TREE_OVERFLOW set. This confuses our undefined overflow warning
- machinery. */
- if (TREE_OVERFLOW_P (val))
- val = drop_tree_overflow (val);
-
- /* The new assertion A will be inserted at BB or E. We need to
- determine if the new location is dominated by a previously
- registered location for A. If we are doing an edge insertion,
- assume that A will be inserted at E->DEST. Note that this is not
- necessarily true.
-
- If E is a critical edge, it will be split. But even if E is
- split, the new block will dominate the same set of blocks that
- E->DEST dominates.
-
- The reverse, however, is not true, blocks dominated by E->DEST
- will not be dominated by the new block created to split E. So,
- if the insertion location is on a critical edge, we will not use
- the new location to move another assertion previously registered
- at a block dominated by E->DEST. */
- dest_bb = (bb) ? bb : e->dest;
-
- /* If NAME already has an ASSERT_EXPR registered for COMP_CODE and
- VAL at a block dominating DEST_BB, then we don't need to insert a new
- one. Similarly, if the same assertion already exists at a block
- dominated by DEST_BB and the new location is not on a critical
- edge, then update the existing location for the assertion (i.e.,
- move the assertion up in the dominance tree).
-
- Note, this is implemented as a simple linked list because there
- should not be more than a handful of assertions registered per
- name. If this becomes a performance problem, a table hashed by
- COMP_CODE and VAL could be implemented. */
- loc = asserts_for[SSA_NAME_VERSION (name)];
- last_loc = loc;
- while (loc)
- {
- if (loc->comp_code == comp_code
- && (loc->val == val
- || operand_equal_p (loc->val, val, 0))
- && (loc->expr == expr
- || operand_equal_p (loc->expr, expr, 0)))
- {
- /* If E is not a critical edge and DEST_BB
- dominates the existing location for the assertion, move
- the assertion up in the dominance tree by updating its
- location information. */
- if ((e == NULL || !EDGE_CRITICAL_P (e))
- && dominated_by_p (CDI_DOMINATORS, loc->bb, dest_bb))
- {
- loc->bb = dest_bb;
- loc->e = e;
- loc->si = si;
- return;
- }
- }
-
- /* Update the last node of the list and move to the next one. */
- last_loc = loc;
- loc = loc->next;
- }
-
- /* If we didn't find an assertion already registered for
- NAME COMP_CODE VAL, add a new one at the end of the list of
- assertions associated with NAME. */
- n = XNEW (struct assert_locus);
- n->bb = dest_bb;
- n->e = e;
- n->si = si;
- n->comp_code = comp_code;
- n->val = val;
- n->expr = expr;
- n->next = NULL;
-
- if (last_loc)
- last_loc->next = n;
- else
- asserts_for[SSA_NAME_VERSION (name)] = n;
-
- bitmap_set_bit (need_assert_for, SSA_NAME_VERSION (name));
-}
-
/* (COND_OP0 COND_CODE COND_OP1) is a predicate which uses NAME.
Extract a suitable test code and value and store them into *CODE_P and
*VAL_P so the predicate is normalized to NAME *CODE_P *VAL_P.
@@ -2088,8 +1740,14 @@ register_edge_assert_for_2 (tree name, edge e,
&& ((TYPE_PRECISION (TREE_TYPE (name))
> TYPE_PRECISION (TREE_TYPE (rhs1)))
|| (get_range_info (rhs1, &rmin, &rmax) == VR_RANGE
- && wi::fits_to_tree_p (rmin, TREE_TYPE (name))
- && wi::fits_to_tree_p (rmax, TREE_TYPE (name)))))
+ && wi::fits_to_tree_p
+ (widest_int::from (rmin,
+ TYPE_SIGN (TREE_TYPE (rhs1))),
+ TREE_TYPE (name))
+ && wi::fits_to_tree_p
+ (widest_int::from (rmax,
+ TYPE_SIGN (TREE_TYPE (rhs1))),
+ TREE_TYPE (name)))))
add_assert_info (asserts, rhs1, rhs1,
comp_code, fold_convert (TREE_TYPE (rhs1), val));
}
@@ -2578,11 +2236,671 @@ register_edge_assert_for (tree name, edge e,
}
}
+/* Handle
+ _4 = x_3 & 31;
+ if (_4 != 0)
+ goto <bb 6>;
+ else
+ goto <bb 7>;
+ <bb 6>:
+ __builtin_unreachable ();
+ <bb 7>:
+ x_5 = ASSERT_EXPR <x_3, ...>;
+ If x_3 has no other immediate uses (checked by caller),
+ var is the x_3 var from ASSERT_EXPR, we can clear low 5 bits
+ from the non-zero bitmask. */
+
+void
+maybe_set_nonzero_bits (edge e, tree var)
+{
+ basic_block cond_bb = e->src;
+ gimple *stmt = last_stmt (cond_bb);
+ tree cst;
+
+ if (stmt == NULL
+ || gimple_code (stmt) != GIMPLE_COND
+ || gimple_cond_code (stmt) != ((e->flags & EDGE_TRUE_VALUE)
+ ? EQ_EXPR : NE_EXPR)
+ || TREE_CODE (gimple_cond_lhs (stmt)) != SSA_NAME
+ || !integer_zerop (gimple_cond_rhs (stmt)))
+ return;
+
+ stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (stmt));
+ if (!is_gimple_assign (stmt)
+ || gimple_assign_rhs_code (stmt) != BIT_AND_EXPR
+ || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST)
+ return;
+ if (gimple_assign_rhs1 (stmt) != var)
+ {
+ gimple *stmt2;
+
+ if (TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME)
+ return;
+ stmt2 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
+ if (!gimple_assign_cast_p (stmt2)
+ || gimple_assign_rhs1 (stmt2) != var
+ || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt2))
+ || (TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (stmt)))
+ != TYPE_PRECISION (TREE_TYPE (var))))
+ return;
+ }
+ cst = gimple_assign_rhs2 (stmt);
+ set_nonzero_bits (var, wi::bit_and_not (get_nonzero_bits (var),
+ wi::to_wide (cst)));
+}
+
+/* Return true if STMT is interesting for VRP. */
+
+bool
+stmt_interesting_for_vrp (gimple *stmt)
+{
+ if (gimple_code (stmt) == GIMPLE_PHI)
+ {
+ tree res = gimple_phi_result (stmt);
+ return (!virtual_operand_p (res)
+ && (INTEGRAL_TYPE_P (TREE_TYPE (res))
+ || POINTER_TYPE_P (TREE_TYPE (res))));
+ }
+ else if (is_gimple_assign (stmt) || is_gimple_call (stmt))
+ {
+ tree lhs = gimple_get_lhs (stmt);
+
+ /* In general, assignments with virtual operands are not useful
+ for deriving ranges, with the obvious exception of calls to
+ builtin functions. */
+ if (lhs && TREE_CODE (lhs) == SSA_NAME
+ && (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
+ || POINTER_TYPE_P (TREE_TYPE (lhs)))
+ && (is_gimple_call (stmt)
+ || !gimple_vuse (stmt)))
+ return true;
+ else if (is_gimple_call (stmt) && gimple_call_internal_p (stmt))
+ switch (gimple_call_internal_fn (stmt))
+ {
+ case IFN_ADD_OVERFLOW:
+ case IFN_SUB_OVERFLOW:
+ case IFN_MUL_OVERFLOW:
+ case IFN_ATOMIC_COMPARE_EXCHANGE:
+ /* These internal calls return _Complex integer type,
+ but are interesting to VRP nevertheless. */
+ if (lhs && TREE_CODE (lhs) == SSA_NAME)
+ return true;
+ break;
+ default:
+ break;
+ }
+ }
+ else if (gimple_code (stmt) == GIMPLE_COND
+ || gimple_code (stmt) == GIMPLE_SWITCH)
+ return true;
+
+ return false;
+}
+
+
+/* Return the LHS of any ASSERT_EXPR where OP appears as the first
+ argument to the ASSERT_EXPR and in which the ASSERT_EXPR dominates
+ BB. If no such ASSERT_EXPR is found, return OP. */
+
+static tree
+lhs_of_dominating_assert (tree op, basic_block bb, gimple *stmt)
+{
+ imm_use_iterator imm_iter;
+ gimple *use_stmt;
+ use_operand_p use_p;
+
+ if (TREE_CODE (op) == SSA_NAME)
+ {
+ FOR_EACH_IMM_USE_FAST (use_p, imm_iter, op)
+ {
+ use_stmt = USE_STMT (use_p);
+ if (use_stmt != stmt
+ && gimple_assign_single_p (use_stmt)
+ && TREE_CODE (gimple_assign_rhs1 (use_stmt)) == ASSERT_EXPR
+ && TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) == op
+ && dominated_by_p (CDI_DOMINATORS, bb, gimple_bb (use_stmt)))
+ return gimple_assign_lhs (use_stmt);
+ }
+ }
+ return op;
+}
+
+/* A hack. */
+static class vr_values *x_vr_values;
+
+/* Searches the case label vector VEC for the index *IDX of the CASE_LABEL
+ that includes the value VAL. The search is restricted to the range
+ [START_IDX, n - 1] where n is the size of VEC.
+
+ If there is a CASE_LABEL for VAL, its index is placed in IDX and true is
+ returned.
+
+ If there is no CASE_LABEL for VAL and there is one that is larger than VAL,
+ it is placed in IDX and false is returned.
+
+ If VAL is larger than any CASE_LABEL, n is placed on IDX and false is
+ returned. */
+
+bool
+find_case_label_index (gswitch *stmt, size_t start_idx, tree val, size_t *idx)
+{
+ size_t n = gimple_switch_num_labels (stmt);
+ size_t low, high;
+
+ /* Find case label for minimum of the value range or the next one.
+ At each iteration we are searching in [low, high - 1]. */
+
+ for (low = start_idx, high = n; high != low; )
+ {
+ tree t;
+ int cmp;
+ /* Note that i != high, so we never ask for n. */
+ size_t i = (high + low) / 2;
+ t = gimple_switch_label (stmt, i);
+
+ /* Cache the result of comparing CASE_LOW and val. */
+ cmp = tree_int_cst_compare (CASE_LOW (t), val);
+
+ if (cmp == 0)
+ {
+ /* Ranges cannot be empty. */
+ *idx = i;
+ return true;
+ }
+ else if (cmp > 0)
+ high = i;
+ else
+ {
+ low = i + 1;
+ if (CASE_HIGH (t) != NULL
+ && tree_int_cst_compare (CASE_HIGH (t), val) >= 0)
+ {
+ *idx = i;
+ return true;
+ }
+ }
+ }
+
+ *idx = high;
+ return false;
+}
+
+/* Searches the case label vector VEC for the range of CASE_LABELs that is used
+ for values between MIN and MAX. The first index is placed in MIN_IDX. The
+ last index is placed in MAX_IDX. If the range of CASE_LABELs is empty
+ then MAX_IDX < MIN_IDX.
+ Returns true if the default label is not needed. */
+
+bool
+find_case_label_range (gswitch *stmt, tree min, tree max, size_t *min_idx,
+ size_t *max_idx)
+{
+ size_t i, j;
+ bool min_take_default = !find_case_label_index (stmt, 1, min, &i);
+ bool max_take_default = !find_case_label_index (stmt, i, max, &j);
+
+ if (i == j
+ && min_take_default
+ && max_take_default)
+ {
+ /* Only the default case label reached.
+ Return an empty range. */
+ *min_idx = 1;
+ *max_idx = 0;
+ return false;
+ }
+ else
+ {
+ bool take_default = min_take_default || max_take_default;
+ tree low, high;
+ size_t k;
+
+ if (max_take_default)
+ j--;
+
+ /* If the case label range is continuous, we do not need
+ the default case label. Verify that. */
+ high = CASE_LOW (gimple_switch_label (stmt, i));
+ if (CASE_HIGH (gimple_switch_label (stmt, i)))
+ high = CASE_HIGH (gimple_switch_label (stmt, i));
+ for (k = i + 1; k <= j; ++k)
+ {
+ low = CASE_LOW (gimple_switch_label (stmt, k));
+ if (!integer_onep (int_const_binop (MINUS_EXPR, low, high)))
+ {
+ take_default = true;
+ break;
+ }
+ high = low;
+ if (CASE_HIGH (gimple_switch_label (stmt, k)))
+ high = CASE_HIGH (gimple_switch_label (stmt, k));
+ }
+
+ *min_idx = i;
+ *max_idx = j;
+ return !take_default;
+ }
+}
+
+/* Given a SWITCH_STMT, return the case label that encompasses the
+ known possible values for the switch operand. RANGE_OF_OP is a
+ range for the known values of the switch operand. */
+
+tree
+find_case_label_range (gswitch *switch_stmt, const irange *range_of_op)
+{
+ if (range_of_op->undefined_p ()
+ || range_of_op->varying_p ()
+ || range_of_op->symbolic_p ())
+ return NULL_TREE;
+
+ size_t i, j;
+ tree op = gimple_switch_index (switch_stmt);
+ tree type = TREE_TYPE (op);
+ tree tmin = wide_int_to_tree (type, range_of_op->lower_bound ());
+ tree tmax = wide_int_to_tree (type, range_of_op->upper_bound ());
+ find_case_label_range (switch_stmt, tmin, tmax, &i, &j);
+ if (i == j)
+ {
+ /* Look for exactly one label that encompasses the range of
+ the operand. */
+ tree label = gimple_switch_label (switch_stmt, i);
+ tree case_high
+ = CASE_HIGH (label) ? CASE_HIGH (label) : CASE_LOW (label);
+ int_range_max label_range (CASE_LOW (label), case_high);
+ if (!types_compatible_p (label_range.type (), range_of_op->type ()))
+ range_cast (label_range, range_of_op->type ());
+ label_range.intersect (range_of_op);
+ if (label_range == *range_of_op)
+ return label;
+ }
+ else if (i > j)
+ {
+ /* If there are no labels at all, take the default. */
+ return gimple_switch_label (switch_stmt, 0);
+ }
+ else
+ {
+ /* Otherwise, there are various labels that can encompass
+ the range of operand. In which case, see if the range of
+ the operand is entirely *outside* the bounds of all the
+ (non-default) case labels. If so, take the default. */
+ unsigned n = gimple_switch_num_labels (switch_stmt);
+ tree min_label = gimple_switch_label (switch_stmt, 1);
+ tree max_label = gimple_switch_label (switch_stmt, n - 1);
+ tree case_high = CASE_HIGH (max_label);
+ if (!case_high)
+ case_high = CASE_LOW (max_label);
+ int_range_max label_range (CASE_LOW (min_label), case_high);
+ if (!types_compatible_p (label_range.type (), range_of_op->type ()))
+ range_cast (label_range, range_of_op->type ());
+ label_range.intersect (range_of_op);
+ if (label_range.undefined_p ())
+ return gimple_switch_label (switch_stmt, 0);
+ }
+ return NULL_TREE;
+}
+
+struct case_info
+{
+ tree expr;
+ basic_block bb;
+};
+
+/* Location information for ASSERT_EXPRs. Each instance of this
+ structure describes an ASSERT_EXPR for an SSA name. Since a single
+ SSA name may have more than one assertion associated with it, these
+ locations are kept in a linked list attached to the corresponding
+ SSA name. */
+struct assert_locus
+{
+ /* Basic block where the assertion would be inserted. */
+ basic_block bb;
+
+ /* Some assertions need to be inserted on an edge (e.g., assertions
+ generated by COND_EXPRs). In those cases, BB will be NULL. */
+ edge e;
+
+ /* Pointer to the statement that generated this assertion. */
+ gimple_stmt_iterator si;
+
+ /* Predicate code for the ASSERT_EXPR. Must be COMPARISON_CLASS_P. */
+ enum tree_code comp_code;
+
+ /* Value being compared against. */
+ tree val;
+
+ /* Expression to compare. */
+ tree expr;
+
+ /* Next node in the linked list. */
+ assert_locus *next;
+};
+
+/* Class to traverse the flowgraph looking for conditional jumps to
+ insert ASSERT_EXPR range expressions. These range expressions are
+ meant to provide information to optimizations that need to reason
+ in terms of value ranges. They will not be expanded into RTL. */
+
+class vrp_asserts
+{
+public:
+ vrp_asserts (struct function *fn) : fun (fn) { }
+
+ void insert_range_assertions ();
+
+ /* Convert range assertion expressions into the implied copies and
+ copy propagate away the copies. */
+ void remove_range_assertions ();
+
+ /* Dump all the registered assertions for all the names to FILE. */
+ void dump (FILE *);
+
+ /* Dump all the registered assertions for NAME to FILE. */
+ void dump (FILE *file, tree name);
+
+ /* Dump all the registered assertions for NAME to stderr. */
+ void debug (tree name)
+ {
+ dump (stderr, name);
+ }
+
+ /* Dump all the registered assertions for all the names to stderr. */
+ void debug ()
+ {
+ dump (stderr);
+ }
+
+private:
+ /* Set of SSA names found live during the RPO traversal of the function
+ for still active basic-blocks. */
+ live_names live;
+
+ /* Function to work on. */
+ struct function *fun;
+
+ /* If bit I is present, it means that SSA name N_i has a list of
+ assertions that should be inserted in the IL. */
+ bitmap need_assert_for;
+
+ /* Array of locations lists where to insert assertions. ASSERTS_FOR[I]
+ holds a list of ASSERT_LOCUS_T nodes that describe where
+ ASSERT_EXPRs for SSA name N_I should be inserted. */
+ assert_locus **asserts_for;
+
+ /* Finish found ASSERTS for E and register them at GSI. */
+ void finish_register_edge_assert_for (edge e, gimple_stmt_iterator gsi,
+ vec<assert_info> &asserts);
+
+ /* Determine whether the outgoing edges of BB should receive an
+ ASSERT_EXPR for each of the operands of BB's LAST statement. The
+ last statement of BB must be a SWITCH_EXPR.
+
+ If any of the sub-graphs rooted at BB have an interesting use of
+ the predicate operands, an assert location node is added to the
+ list of assertions for the corresponding operands. */
+ void find_switch_asserts (basic_block bb, gswitch *last);
+
+ /* Do an RPO walk over the function computing SSA name liveness
+ on-the-fly and deciding on assert expressions to insert. */
+ void find_assert_locations ();
+
+ /* Traverse all the statements in block BB looking for statements that
+ may generate useful assertions for the SSA names in their operand.
+ See method implementation comentary for more information. */
+ void find_assert_locations_in_bb (basic_block bb);
+
+ /* Determine whether the outgoing edges of BB should receive an
+ ASSERT_EXPR for each of the operands of BB's LAST statement.
+ The last statement of BB must be a COND_EXPR.
+
+ If any of the sub-graphs rooted at BB have an interesting use of
+ the predicate operands, an assert location node is added to the
+ list of assertions for the corresponding operands. */
+ void find_conditional_asserts (basic_block bb, gcond *last);
+
+ /* Process all the insertions registered for every name N_i registered
+ in NEED_ASSERT_FOR. The list of assertions to be inserted are
+ found in ASSERTS_FOR[i]. */
+ void process_assert_insertions ();
+
+ /* If NAME doesn't have an ASSERT_EXPR registered for asserting
+ 'EXPR COMP_CODE VAL' at a location that dominates block BB or
+ E->DEST, then register this location as a possible insertion point
+ for ASSERT_EXPR <NAME, EXPR COMP_CODE VAL>.
+
+ BB, E and SI provide the exact insertion point for the new
+ ASSERT_EXPR. If BB is NULL, then the ASSERT_EXPR is to be inserted
+ on edge E. Otherwise, if E is NULL, the ASSERT_EXPR is inserted on
+ BB. If SI points to a COND_EXPR or a SWITCH_EXPR statement, then E
+ must not be NULL. */
+ void register_new_assert_for (tree name, tree expr,
+ enum tree_code comp_code,
+ tree val, basic_block bb,
+ edge e, gimple_stmt_iterator si);
+
+ /* Given a COND_EXPR COND of the form 'V OP W', and an SSA name V,
+ create a new SSA name N and return the assertion assignment
+ 'N = ASSERT_EXPR <V, V OP W>'. */
+ gimple *build_assert_expr_for (tree cond, tree v);
+
+ /* Create an ASSERT_EXPR for NAME and insert it in the location
+ indicated by LOC. Return true if we made any edge insertions. */
+ bool process_assert_insertions_for (tree name, assert_locus *loc);
+
+ /* Qsort callback for sorting assert locations. */
+ template <bool stable> static int compare_assert_loc (const void *,
+ const void *);
+
+ /* Return false if EXPR is a predicate expression involving floating
+ point values. */
+ bool fp_predicate (gimple *stmt)
+ {
+ GIMPLE_CHECK (stmt, GIMPLE_COND);
+ return FLOAT_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)));
+ }
+
+ bool all_imm_uses_in_stmt_or_feed_cond (tree var, gimple *stmt,
+ basic_block cond_bb);
+
+ static int compare_case_labels (const void *, const void *);
+};
+
+/* Given a COND_EXPR COND of the form 'V OP W', and an SSA name V,
+ create a new SSA name N and return the assertion assignment
+ 'N = ASSERT_EXPR <V, V OP W>'. */
+
+gimple *
+vrp_asserts::build_assert_expr_for (tree cond, tree v)
+{
+ tree a;
+ gassign *assertion;
+
+ gcc_assert (TREE_CODE (v) == SSA_NAME
+ && COMPARISON_CLASS_P (cond));
+
+ a = build2 (ASSERT_EXPR, TREE_TYPE (v), v, cond);
+ assertion = gimple_build_assign (NULL_TREE, a);
+
+ /* The new ASSERT_EXPR, creates a new SSA name that replaces the
+ operand of the ASSERT_EXPR. Create it so the new name and the old one
+ are registered in the replacement table so that we can fix the SSA web
+ after adding all the ASSERT_EXPRs. */
+ tree new_def = create_new_def_for (v, assertion, NULL);
+ /* Make sure we preserve abnormalness throughout an ASSERT_EXPR chain
+ given we have to be able to fully propagate those out to re-create
+ valid SSA when removing the asserts. */
+ if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (v))
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_def) = 1;
+
+ return assertion;
+}
+
+/* Dump all the registered assertions for NAME to FILE. */
+
+void
+vrp_asserts::dump (FILE *file, tree name)
+{
+ assert_locus *loc;
+
+ fprintf (file, "Assertions to be inserted for ");
+ print_generic_expr (file, name);
+ fprintf (file, "\n");
+
+ loc = asserts_for[SSA_NAME_VERSION (name)];
+ while (loc)
+ {
+ fprintf (file, "\t");
+ print_gimple_stmt (file, gsi_stmt (loc->si), 0);
+ fprintf (file, "\n\tBB #%d", loc->bb->index);
+ if (loc->e)
+ {
+ fprintf (file, "\n\tEDGE %d->%d", loc->e->src->index,
+ loc->e->dest->index);
+ dump_edge_info (file, loc->e, dump_flags, 0);
+ }
+ fprintf (file, "\n\tPREDICATE: ");
+ print_generic_expr (file, loc->expr);
+ fprintf (file, " %s ", get_tree_code_name (loc->comp_code));
+ print_generic_expr (file, loc->val);
+ fprintf (file, "\n\n");
+ loc = loc->next;
+ }
+
+ fprintf (file, "\n");
+}
+
+/* Dump all the registered assertions for all the names to FILE. */
+
+void
+vrp_asserts::dump (FILE *file)
+{
+ unsigned i;
+ bitmap_iterator bi;
+
+ fprintf (file, "\nASSERT_EXPRs to be inserted\n\n");
+ EXECUTE_IF_SET_IN_BITMAP (need_assert_for, 0, i, bi)
+ dump (file, ssa_name (i));
+ fprintf (file, "\n");
+}
+
+/* If NAME doesn't have an ASSERT_EXPR registered for asserting
+ 'EXPR COMP_CODE VAL' at a location that dominates block BB or
+ E->DEST, then register this location as a possible insertion point
+ for ASSERT_EXPR <NAME, EXPR COMP_CODE VAL>.
+
+ BB, E and SI provide the exact insertion point for the new
+ ASSERT_EXPR. If BB is NULL, then the ASSERT_EXPR is to be inserted
+ on edge E. Otherwise, if E is NULL, the ASSERT_EXPR is inserted on
+ BB. If SI points to a COND_EXPR or a SWITCH_EXPR statement, then E
+ must not be NULL. */
+
+void
+vrp_asserts::register_new_assert_for (tree name, tree expr,
+ enum tree_code comp_code,
+ tree val,
+ basic_block bb,
+ edge e,
+ gimple_stmt_iterator si)
+{
+ assert_locus *n, *loc, *last_loc;
+ basic_block dest_bb;
+
+ gcc_checking_assert (bb == NULL || e == NULL);
+
+ if (e == NULL)
+ gcc_checking_assert (gimple_code (gsi_stmt (si)) != GIMPLE_COND
+ && gimple_code (gsi_stmt (si)) != GIMPLE_SWITCH);
+
+ /* Never build an assert comparing against an integer constant with
+ TREE_OVERFLOW set. This confuses our undefined overflow warning
+ machinery. */
+ if (TREE_OVERFLOW_P (val))
+ val = drop_tree_overflow (val);
+
+ /* The new assertion A will be inserted at BB or E. We need to
+ determine if the new location is dominated by a previously
+ registered location for A. If we are doing an edge insertion,
+ assume that A will be inserted at E->DEST. Note that this is not
+ necessarily true.
+
+ If E is a critical edge, it will be split. But even if E is
+ split, the new block will dominate the same set of blocks that
+ E->DEST dominates.
+
+ The reverse, however, is not true, blocks dominated by E->DEST
+ will not be dominated by the new block created to split E. So,
+ if the insertion location is on a critical edge, we will not use
+ the new location to move another assertion previously registered
+ at a block dominated by E->DEST. */
+ dest_bb = (bb) ? bb : e->dest;
+
+ /* If NAME already has an ASSERT_EXPR registered for COMP_CODE and
+ VAL at a block dominating DEST_BB, then we don't need to insert a new
+ one. Similarly, if the same assertion already exists at a block
+ dominated by DEST_BB and the new location is not on a critical
+ edge, then update the existing location for the assertion (i.e.,
+ move the assertion up in the dominance tree).
+
+ Note, this is implemented as a simple linked list because there
+ should not be more than a handful of assertions registered per
+ name. If this becomes a performance problem, a table hashed by
+ COMP_CODE and VAL could be implemented. */
+ loc = asserts_for[SSA_NAME_VERSION (name)];
+ last_loc = loc;
+ while (loc)
+ {
+ if (loc->comp_code == comp_code
+ && (loc->val == val
+ || operand_equal_p (loc->val, val, 0))
+ && (loc->expr == expr
+ || operand_equal_p (loc->expr, expr, 0)))
+ {
+ /* If E is not a critical edge and DEST_BB
+ dominates the existing location for the assertion, move
+ the assertion up in the dominance tree by updating its
+ location information. */
+ if ((e == NULL || !EDGE_CRITICAL_P (e))
+ && dominated_by_p (CDI_DOMINATORS, loc->bb, dest_bb))
+ {
+ loc->bb = dest_bb;
+ loc->e = e;
+ loc->si = si;
+ return;
+ }
+ }
+
+ /* Update the last node of the list and move to the next one. */
+ last_loc = loc;
+ loc = loc->next;
+ }
+
+ /* If we didn't find an assertion already registered for
+ NAME COMP_CODE VAL, add a new one at the end of the list of
+ assertions associated with NAME. */
+ n = XNEW (struct assert_locus);
+ n->bb = dest_bb;
+ n->e = e;
+ n->si = si;
+ n->comp_code = comp_code;
+ n->val = val;
+ n->expr = expr;
+ n->next = NULL;
+
+ if (last_loc)
+ last_loc->next = n;
+ else
+ asserts_for[SSA_NAME_VERSION (name)] = n;
+
+ bitmap_set_bit (need_assert_for, SSA_NAME_VERSION (name));
+}
+
/* Finish found ASSERTS for E and register them at GSI. */
void
-vrp_insert::finish_register_edge_assert_for (edge e, gimple_stmt_iterator gsi,
- vec<assert_info> &asserts)
+vrp_asserts::finish_register_edge_assert_for (edge e,
+ gimple_stmt_iterator gsi,
+ vec<assert_info> &asserts)
{
for (unsigned i = 0; i < asserts.length (); ++i)
/* Only register an ASSERT_EXPR if NAME was found in the sub-graph
@@ -2593,8 +2911,6 @@ vrp_insert::finish_register_edge_assert_for (edge e, gimple_stmt_iterator gsi,
NULL, e, gsi);
}
-
-
/* Determine whether the outgoing edges of BB should receive an
ASSERT_EXPR for each of the operands of BB's LAST statement.
The last statement of BB must be a COND_EXPR.
@@ -2604,7 +2920,7 @@ vrp_insert::finish_register_edge_assert_for (edge e, gimple_stmt_iterator gsi,
list of assertions for the corresponding operands. */
void
-vrp_insert::find_conditional_asserts (basic_block bb, gcond *last)
+vrp_asserts::find_conditional_asserts (basic_block bb, gcond *last)
{
gimple_stmt_iterator bsi;
tree op;
@@ -2635,17 +2951,11 @@ vrp_insert::find_conditional_asserts (basic_block bb, gcond *last)
}
}
-struct case_info
-{
- tree expr;
- basic_block bb;
-};
-
/* Compare two case labels sorting first by the destination bb index
and then by the case value. */
-static int
-compare_case_labels (const void *p1, const void *p2)
+int
+vrp_asserts::compare_case_labels (const void *p1, const void *p2)
{
const struct case_info *ci1 = (const struct case_info *) p1;
const struct case_info *ci2 = (const struct case_info *) p2;
@@ -2678,7 +2988,7 @@ compare_case_labels (const void *p1, const void *p2)
list of assertions for the corresponding operands. */
void
-vrp_insert::find_switch_asserts (basic_block bb, gswitch *last)
+vrp_asserts::find_switch_asserts (basic_block bb, gswitch *last)
{
gimple_stmt_iterator bsi;
tree op;
@@ -2827,7 +3137,6 @@ vrp_insert::find_switch_asserts (basic_block bb, gswitch *last)
}
}
-
/* Traverse all the statements in block BB looking for statements that
may generate useful assertions for the SSA names in their operand.
If a statement produces a useful assertion A for name N_i, then the
@@ -2888,7 +3197,7 @@ vrp_insert::find_switch_asserts (basic_block bb, gswitch *last)
P_4 will receive an ASSERT_EXPR. */
void
-vrp_insert::find_assert_locations_in_bb (basic_block bb)
+vrp_asserts::find_assert_locations_in_bb (basic_block bb)
{
gimple *last;
@@ -3008,7 +3317,7 @@ vrp_insert::find_assert_locations_in_bb (basic_block bb)
on-the-fly and deciding on assert expressions to insert. */
void
-vrp_insert::find_assert_locations (void)
+vrp_asserts::find_assert_locations (void)
{
int *rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
int *bb_rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
@@ -3088,7 +3397,7 @@ vrp_insert::find_assert_locations (void)
indicated by LOC. Return true if we made any edge insertions. */
bool
-vrp_insert::process_assert_insertions_for (tree name, assert_locus *loc)
+vrp_asserts::process_assert_insertions_for (tree name, assert_locus *loc)
{
/* Build the comparison expression NAME_i COMP_CODE VAL. */
gimple *stmt;
@@ -3153,7 +3462,7 @@ vrp_insert::process_assert_insertions_for (tree name, assert_locus *loc)
template <bool stable>
int
-vrp_insert::compare_assert_loc (const void *pa, const void *pb)
+vrp_asserts::compare_assert_loc (const void *pa, const void *pb)
{
assert_locus * const a = *(assert_locus * const *)pa;
assert_locus * const b = *(assert_locus * const *)pb;
@@ -3221,7 +3530,7 @@ vrp_insert::compare_assert_loc (const void *pa, const void *pb)
found in ASSERTS_FOR[i]. */
void
-vrp_insert::process_assert_insertions ()
+vrp_asserts::process_assert_insertions ()
{
unsigned i;
bitmap_iterator bi;
@@ -3314,7 +3623,6 @@ vrp_insert::process_assert_insertions ()
num_asserts);
}
-
/* Traverse the flowgraph looking for conditional jumps to insert range
expressions. These range expressions are meant to provide information
to optimizations that need to reason in terms of value ranges. They
@@ -3348,7 +3656,7 @@ vrp_insert::process_assert_insertions ()
definition of 'x'. */
void
-vrp_insert::insert_range_assertions (void)
+vrp_asserts::insert_range_assertions (void)
{
need_assert_for = BITMAP_ALLOC (NULL);
asserts_for = XCNEWVEC (assert_locus *, num_ssa_names);
@@ -3372,44 +3680,14 @@ vrp_insert::insert_range_assertions (void)
BITMAP_FREE (need_assert_for);
}
-class vrp_prop : public ssa_propagation_engine
-{
-public:
- enum ssa_prop_result visit_stmt (gimple *, edge *, tree *) FINAL OVERRIDE;
- enum ssa_prop_result visit_phi (gphi *) FINAL OVERRIDE;
-
- struct function *fun;
-
- void vrp_initialize (struct function *);
- void vrp_finalize (class vrp_folder *, bool);
-
- class vr_values vr_values;
-
-private:
- /* Temporary delegator to minimize code churn. */
- const value_range_equiv *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)
- { vr_values.set_defs_to_varying (stmt); }
- void extract_range_from_stmt (gimple *stmt, edge *taken_edge_p,
- tree *output_p, value_range_equiv *vr)
- { vr_values.extract_range_from_stmt (stmt, taken_edge_p, output_p, vr); }
- bool update_value_range (const_tree op, value_range_equiv *vr)
- { return vr_values.update_value_range (op, vr); }
- void extract_range_basic (value_range_equiv *vr, gimple *stmt)
- { vr_values.extract_range_basic (vr, stmt); }
- void extract_range_from_phi_node (gphi *phi, value_range_equiv *vr)
- { vr_values.extract_range_from_phi_node (phi, vr); }
-};
-
/* Return true if all imm uses of VAR are either in STMT, or
feed (optionally through a chain of single imm uses) GIMPLE_COND
in basic block COND_BB. */
-static bool
-all_imm_uses_in_stmt_or_feed_cond (tree var, gimple *stmt, basic_block cond_bb)
+bool
+vrp_asserts::all_imm_uses_in_stmt_or_feed_cond (tree var,
+ gimple *stmt,
+ basic_block cond_bb)
{
use_operand_p use_p, use2_p;
imm_use_iterator iter;
@@ -3432,59 +3710,6 @@ all_imm_uses_in_stmt_or_feed_cond (tree var, gimple *stmt, basic_block cond_bb)
return true;
}
-/* Handle
- _4 = x_3 & 31;
- if (_4 != 0)
- goto <bb 6>;
- else
- goto <bb 7>;
- <bb 6>:
- __builtin_unreachable ();
- <bb 7>:
- x_5 = ASSERT_EXPR <x_3, ...>;
- If x_3 has no other immediate uses (checked by caller),
- var is the x_3 var from ASSERT_EXPR, we can clear low 5 bits
- from the non-zero bitmask. */
-
-void
-maybe_set_nonzero_bits (edge e, tree var)
-{
- basic_block cond_bb = e->src;
- gimple *stmt = last_stmt (cond_bb);
- tree cst;
-
- if (stmt == NULL
- || gimple_code (stmt) != GIMPLE_COND
- || gimple_cond_code (stmt) != ((e->flags & EDGE_TRUE_VALUE)
- ? EQ_EXPR : NE_EXPR)
- || TREE_CODE (gimple_cond_lhs (stmt)) != SSA_NAME
- || !integer_zerop (gimple_cond_rhs (stmt)))
- return;
-
- stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (stmt));
- if (!is_gimple_assign (stmt)
- || gimple_assign_rhs_code (stmt) != BIT_AND_EXPR
- || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST)
- return;
- if (gimple_assign_rhs1 (stmt) != var)
- {
- gimple *stmt2;
-
- if (TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME)
- return;
- stmt2 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
- if (!gimple_assign_cast_p (stmt2)
- || gimple_assign_rhs1 (stmt2) != var
- || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt2))
- || (TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (stmt)))
- != TYPE_PRECISION (TREE_TYPE (var))))
- return;
- }
- cst = gimple_assign_rhs2 (stmt);
- set_nonzero_bits (var, wi::bit_and_not (get_nonzero_bits (var),
- wi::to_wide (cst)));
-}
-
/* Convert range assertion expressions into the implied copies and
copy propagate away the copies. Doing the trivial copy propagation
here avoids the need to run the full copy propagation pass after
@@ -3510,7 +3735,7 @@ maybe_set_nonzero_bits (edge e, tree var)
multiple ranges to be associated with one SSA_NAME. */
void
-vrp_insert::remove_range_assertions ()
+vrp_asserts::remove_range_assertions ()
{
basic_block bb;
gimple_stmt_iterator si;
@@ -3595,58 +3820,28 @@ vrp_insert::remove_range_assertions ()
}
}
-/* Return true if STMT is interesting for VRP. */
-
-bool
-stmt_interesting_for_vrp (gimple *stmt)
+class vrp_prop : public ssa_propagation_engine
{
- if (gimple_code (stmt) == GIMPLE_PHI)
- {
- tree res = gimple_phi_result (stmt);
- return (!virtual_operand_p (res)
- && (INTEGRAL_TYPE_P (TREE_TYPE (res))
- || POINTER_TYPE_P (TREE_TYPE (res))));
- }
- else if (is_gimple_assign (stmt) || is_gimple_call (stmt))
- {
- tree lhs = gimple_get_lhs (stmt);
+public:
+ vrp_prop (vr_values *v)
+ : ssa_propagation_engine (),
+ m_vr_values (v) { }
- /* In general, assignments with virtual operands are not useful
- for deriving ranges, with the obvious exception of calls to
- builtin functions. */
- if (lhs && TREE_CODE (lhs) == SSA_NAME
- && (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
- || POINTER_TYPE_P (TREE_TYPE (lhs)))
- && (is_gimple_call (stmt)
- || !gimple_vuse (stmt)))
- return true;
- else if (is_gimple_call (stmt) && gimple_call_internal_p (stmt))
- switch (gimple_call_internal_fn (stmt))
- {
- case IFN_ADD_OVERFLOW:
- case IFN_SUB_OVERFLOW:
- case IFN_MUL_OVERFLOW:
- case IFN_ATOMIC_COMPARE_EXCHANGE:
- /* These internal calls return _Complex integer type,
- but are interesting to VRP nevertheless. */
- if (lhs && TREE_CODE (lhs) == SSA_NAME)
- return true;
- break;
- default:
- break;
- }
- }
- else if (gimple_code (stmt) == GIMPLE_COND
- || gimple_code (stmt) == GIMPLE_SWITCH)
- return true;
+ void initialize (struct function *);
+ void finalize ();
- return false;
-}
+private:
+ enum ssa_prop_result visit_stmt (gimple *, edge *, tree *) FINAL OVERRIDE;
+ enum ssa_prop_result visit_phi (gphi *) FINAL OVERRIDE;
+
+ struct function *fun;
+ vr_values *m_vr_values;
+};
/* Initialization required by ssa_propagate engine. */
void
-vrp_prop::vrp_initialize (struct function *fn)
+vrp_prop::initialize (struct function *fn)
{
basic_block bb;
fun = fn;
@@ -3660,7 +3855,7 @@ vrp_prop::vrp_initialize (struct function *fn)
if (!stmt_interesting_for_vrp (phi))
{
tree lhs = PHI_RESULT (phi);
- set_def_to_varying (lhs);
+ m_vr_values->set_def_to_varying (lhs);
prop_set_simulate_again (phi, false);
}
else
@@ -3679,7 +3874,7 @@ vrp_prop::vrp_initialize (struct function *fn)
prop_set_simulate_again (stmt, true);
else if (!stmt_interesting_for_vrp (stmt))
{
- set_defs_to_varying (stmt);
+ m_vr_values->set_defs_to_varying (stmt);
prop_set_simulate_again (stmt, false);
}
else
@@ -3688,179 +3883,6 @@ vrp_prop::vrp_initialize (struct function *fn)
}
}
-/* Searches the case label vector VEC for the index *IDX of the CASE_LABEL
- that includes the value VAL. The search is restricted to the range
- [START_IDX, n - 1] where n is the size of VEC.
-
- If there is a CASE_LABEL for VAL, its index is placed in IDX and true is
- returned.
-
- If there is no CASE_LABEL for VAL and there is one that is larger than VAL,
- it is placed in IDX and false is returned.
-
- If VAL is larger than any CASE_LABEL, n is placed on IDX and false is
- returned. */
-
-bool
-find_case_label_index (gswitch *stmt, size_t start_idx, tree val, size_t *idx)
-{
- size_t n = gimple_switch_num_labels (stmt);
- size_t low, high;
-
- /* Find case label for minimum of the value range or the next one.
- At each iteration we are searching in [low, high - 1]. */
-
- for (low = start_idx, high = n; high != low; )
- {
- tree t;
- int cmp;
- /* Note that i != high, so we never ask for n. */
- size_t i = (high + low) / 2;
- t = gimple_switch_label (stmt, i);
-
- /* Cache the result of comparing CASE_LOW and val. */
- cmp = tree_int_cst_compare (CASE_LOW (t), val);
-
- if (cmp == 0)
- {
- /* Ranges cannot be empty. */
- *idx = i;
- return true;
- }
- else if (cmp > 0)
- high = i;
- else
- {
- low = i + 1;
- if (CASE_HIGH (t) != NULL
- && tree_int_cst_compare (CASE_HIGH (t), val) >= 0)
- {
- *idx = i;
- return true;
- }
- }
- }
-
- *idx = high;
- return false;
-}
-
-/* Searches the case label vector VEC for the range of CASE_LABELs that is used
- for values between MIN and MAX. The first index is placed in MIN_IDX. The
- last index is placed in MAX_IDX. If the range of CASE_LABELs is empty
- then MAX_IDX < MIN_IDX.
- Returns true if the default label is not needed. */
-
-bool
-find_case_label_range (gswitch *stmt, tree min, tree max, size_t *min_idx,
- size_t *max_idx)
-{
- size_t i, j;
- bool min_take_default = !find_case_label_index (stmt, 1, min, &i);
- bool max_take_default = !find_case_label_index (stmt, i, max, &j);
-
- if (i == j
- && min_take_default
- && max_take_default)
- {
- /* Only the default case label reached.
- Return an empty range. */
- *min_idx = 1;
- *max_idx = 0;
- return false;
- }
- else
- {
- bool take_default = min_take_default || max_take_default;
- tree low, high;
- size_t k;
-
- if (max_take_default)
- j--;
-
- /* If the case label range is continuous, we do not need
- the default case label. Verify that. */
- high = CASE_LOW (gimple_switch_label (stmt, i));
- if (CASE_HIGH (gimple_switch_label (stmt, i)))
- high = CASE_HIGH (gimple_switch_label (stmt, i));
- for (k = i + 1; k <= j; ++k)
- {
- low = CASE_LOW (gimple_switch_label (stmt, k));
- if (!integer_onep (int_const_binop (MINUS_EXPR, low, high)))
- {
- take_default = true;
- break;
- }
- high = low;
- if (CASE_HIGH (gimple_switch_label (stmt, k)))
- high = CASE_HIGH (gimple_switch_label (stmt, k));
- }
-
- *min_idx = i;
- *max_idx = j;
- return !take_default;
- }
-}
-
-/* Given a SWITCH_STMT, return the case label that encompasses the
- known possible values for the switch operand. RANGE_OF_OP is a
- range for the known values of the switch operand. */
-
-tree
-find_case_label_range (gswitch *switch_stmt, const irange *range_of_op)
-{
- if (range_of_op->undefined_p ()
- || range_of_op->varying_p ()
- || range_of_op->symbolic_p ())
- return NULL_TREE;
-
- size_t i, j;
- tree op = gimple_switch_index (switch_stmt);
- tree type = TREE_TYPE (op);
- tree tmin = wide_int_to_tree (type, range_of_op->lower_bound ());
- tree tmax = wide_int_to_tree (type, range_of_op->upper_bound ());
- find_case_label_range (switch_stmt, tmin, tmax, &i, &j);
- if (i == j)
- {
- /* Look for exactly one label that encompasses the range of
- the operand. */
- tree label = gimple_switch_label (switch_stmt, i);
- tree case_high
- = CASE_HIGH (label) ? CASE_HIGH (label) : CASE_LOW (label);
- int_range_max label_range (CASE_LOW (label), case_high);
- if (!types_compatible_p (label_range.type (), range_of_op->type ()))
- range_cast (label_range, range_of_op->type ());
- label_range.intersect (range_of_op);
- if (label_range == *range_of_op)
- return label;
- }
- else if (i > j)
- {
- /* If there are no labels at all, take the default. */
- return gimple_switch_label (switch_stmt, 0);
- }
- else
- {
- /* Otherwise, there are various labels that can encompass
- the range of operand. In which case, see if the range of
- the operand is entirely *outside* the bounds of all the
- (non-default) case labels. If so, take the default. */
- unsigned n = gimple_switch_num_labels (switch_stmt);
- tree min_label = gimple_switch_label (switch_stmt, 1);
- tree max_label = gimple_switch_label (switch_stmt, n - 1);
- tree case_high = CASE_HIGH (max_label);
- if (!case_high)
- case_high = CASE_LOW (max_label);
- int_range_max label_range (CASE_LOW (min_label), case_high);
- if (!types_compatible_p (label_range.type (), range_of_op->type ()))
- range_cast (label_range, range_of_op->type ());
- label_range.intersect (range_of_op);
- if (label_range.undefined_p ())
- return gimple_switch_label (switch_stmt, 0);
- }
- return NULL_TREE;
-}
-
/* Evaluate statement STMT. If the statement produces a useful range,
return SSA_PROP_INTERESTING and record the SSA name with the
interesting range into *OUTPUT_P.
@@ -3875,11 +3897,11 @@ vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
{
tree lhs = gimple_get_lhs (stmt);
value_range_equiv vr;
- extract_range_from_stmt (stmt, taken_edge_p, output_p, &vr);
+ m_vr_values->extract_range_from_stmt (stmt, taken_edge_p, output_p, &vr);
if (*output_p)
{
- if (update_value_range (*output_p, &vr))
+ if (m_vr_values->update_value_range (*output_p, &vr))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -3914,7 +3936,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;
- set_def_to_varying (lhs);
+ m_vr_values->set_def_to_varying (lhs);
FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
{
@@ -3944,8 +3966,9 @@ vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
{REAL,IMAG}PART_EXPR uses at all,
return SSA_PROP_VARYING. */
value_range_equiv new_vr;
- extract_range_basic (&new_vr, use_stmt);
- const value_range_equiv *old_vr = get_value_range (use_lhs);
+ m_vr_values->extract_range_basic (&new_vr, use_stmt);
+ const value_range_equiv *old_vr
+ = m_vr_values->get_value_range (use_lhs);
if (!old_vr->equal_p (new_vr, /*ignore_equivs=*/false))
res = SSA_PROP_INTERESTING;
else
@@ -3967,7 +3990,7 @@ vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
/* All other statements produce nothing of interest for VRP, so mark
their outputs varying and prevent further simulation. */
- set_defs_to_varying (stmt);
+ m_vr_values->set_defs_to_varying (stmt);
return (*taken_edge_p) ? SSA_PROP_INTERESTING : SSA_PROP_VARYING;
}
@@ -3981,8 +4004,8 @@ vrp_prop::visit_phi (gphi *phi)
{
tree lhs = PHI_RESULT (phi);
value_range_equiv vr_result;
- extract_range_from_phi_node (phi, &vr_result);
- if (update_value_range (lhs, &vr_result))
+ m_vr_values->extract_range_from_phi_node (phi, &vr_result);
+ if (m_vr_values->update_value_range (lhs, &vr_result))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -4003,6 +4026,42 @@ vrp_prop::visit_phi (gphi *phi)
return SSA_PROP_NOT_INTERESTING;
}
+/* Traverse all the blocks folding conditionals with known ranges. */
+
+void
+vrp_prop::finalize ()
+{
+ size_t i;
+
+ /* We have completed propagating through the lattice. */
+ m_vr_values->set_lattice_propagation_complete ();
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "\nValue ranges after VRP:\n\n");
+ m_vr_values->dump_all_value_ranges (dump_file);
+ fprintf (dump_file, "\n");
+ }
+
+ /* Set value range to non pointer SSA_NAMEs. */
+ for (i = 0; i < num_ssa_names; i++)
+ {
+ tree name = ssa_name (i);
+ if (!name)
+ continue;
+
+ const value_range_equiv *vr = m_vr_values->get_value_range (name);
+ if (!name || !vr->constant_p ())
+ continue;
+
+ if (POINTER_TYPE_P (TREE_TYPE (name))
+ && range_includes_zero_p (vr) == 0)
+ set_ptr_nonnull (name);
+ else if (!POINTER_TYPE_P (TREE_TYPE (name)))
+ set_range_info (name, *vr);
+ }
+}
+
class vrp_folder : public substitute_and_fold_engine
{
public:
@@ -4010,23 +4069,16 @@ class vrp_folder : public substitute_and_fold_engine
: substitute_and_fold_engine (/* Fold all stmts. */ true),
m_vr_values (v), simplifier (v)
{ }
- bool fold_stmt (gimple_stmt_iterator *) FINAL OVERRIDE;
+private:
tree value_of_expr (tree name, gimple *stmt) OVERRIDE
{
return m_vr_values->value_of_expr (name, stmt);
}
- class vr_values *m_vr_values;
-
-private:
+ bool fold_stmt (gimple_stmt_iterator *) FINAL OVERRIDE;
bool fold_predicate_in (gimple_stmt_iterator *);
- /* Delegators. */
- tree vrp_evaluate_conditional (tree_code code, tree op0,
- tree op1, gimple *stmt)
- { return simplifier.vrp_evaluate_conditional (code, op0, op1, stmt); }
- bool simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
- { return simplifier.simplify (gsi); }
+ vr_values *m_vr_values;
simplify_using_ranges simplifier;
};
@@ -4045,16 +4097,16 @@ vrp_folder::fold_predicate_in (gimple_stmt_iterator *si)
&& TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
{
assignment_p = true;
- val = vrp_evaluate_conditional (gimple_assign_rhs_code (stmt),
- gimple_assign_rhs1 (stmt),
- gimple_assign_rhs2 (stmt),
- stmt);
+ val = simplifier.vrp_evaluate_conditional (gimple_assign_rhs_code (stmt),
+ gimple_assign_rhs1 (stmt),
+ gimple_assign_rhs2 (stmt),
+ stmt);
}
else if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
- val = vrp_evaluate_conditional (gimple_cond_code (cond_stmt),
- gimple_cond_lhs (cond_stmt),
- gimple_cond_rhs (cond_stmt),
- stmt);
+ val = simplifier.vrp_evaluate_conditional (gimple_cond_code (cond_stmt),
+ gimple_cond_lhs (cond_stmt),
+ gimple_cond_rhs (cond_stmt),
+ stmt);
else
return false;
@@ -4100,39 +4152,130 @@ vrp_folder::fold_stmt (gimple_stmt_iterator *si)
if (fold_predicate_in (si))
return true;
- return simplify_stmt_using_ranges (si);
+ return simplifier.simplify (si);
}
-/* Return the LHS of any ASSERT_EXPR where OP appears as the first
- argument to the ASSERT_EXPR and in which the ASSERT_EXPR dominates
- BB. If no such ASSERT_EXPR is found, return OP. */
+/* Blocks which have more than one predecessor and more than
+ one successor present jump threading opportunities, i.e.,
+ when the block is reached from a specific predecessor, we
+ may be able to determine which of the outgoing edges will
+ be traversed. When this optimization applies, we are able
+ to avoid conditionals at runtime and we may expose secondary
+ optimization opportunities.
-static tree
-lhs_of_dominating_assert (tree op, basic_block bb, gimple *stmt)
+ This class is effectively a driver for the generic jump
+ threading code. It basically just presents the generic code
+ with edges that may be suitable for jump threading.
+
+ Unlike DOM, we do not iterate VRP if jump threading was successful.
+ While iterating may expose new opportunities for VRP, it is expected
+ those opportunities would be very limited and the compile time cost
+ to expose those opportunities would be significant.
+
+ As jump threading opportunities are discovered, they are registered
+ for later realization. */
+
+class vrp_jump_threader : public dom_walker
{
- imm_use_iterator imm_iter;
- gimple *use_stmt;
- use_operand_p use_p;
+public:
+ vrp_jump_threader (struct function *, vr_values *);
+ ~vrp_jump_threader ();
- if (TREE_CODE (op) == SSA_NAME)
+ void thread_jumps ()
+ {
+ walk (m_fun->cfg->x_entry_block_ptr);
+ }
+
+private:
+ static tree simplify_stmt (gimple *stmt, gimple *within_stmt,
+ avail_exprs_stack *, basic_block);
+ virtual edge before_dom_children (basic_block);
+ virtual void after_dom_children (basic_block);
+
+ function *m_fun;
+ vr_values *m_vr_values;
+ const_and_copies *m_const_and_copies;
+ avail_exprs_stack *m_avail_exprs_stack;
+ hash_table<expr_elt_hasher> *m_avail_exprs;
+ gcond *m_dummy_cond;
+};
+
+vrp_jump_threader::vrp_jump_threader (struct function *fun, vr_values *v)
+ : dom_walker (CDI_DOMINATORS, REACHABLE_BLOCKS)
+{
+ /* Ugh. When substituting values earlier in this pass we can wipe
+ the dominance information. So rebuild the dominator information
+ as we need it within the jump threading code. */
+ calculate_dominance_info (CDI_DOMINATORS);
+
+ /* We do not allow VRP information to be used for jump threading
+ across a back edge in the CFG. Otherwise it becomes too
+ difficult to avoid eliminating loop exit tests. Of course
+ EDGE_DFS_BACK is not accurate at this time so we have to
+ recompute it. */
+ mark_dfs_back_edges ();
+
+ /* Allocate our unwinder stack to unwind any temporary equivalences
+ that might be recorded. */
+ m_const_and_copies = new const_and_copies ();
+
+ m_dummy_cond = NULL;
+ m_fun = fun;
+ m_vr_values = v;
+ m_avail_exprs = new hash_table<expr_elt_hasher> (1024);
+ m_avail_exprs_stack = new avail_exprs_stack (m_avail_exprs);
+}
+
+vrp_jump_threader::~vrp_jump_threader ()
+{
+ /* We do not actually update the CFG or SSA graphs at this point as
+ ASSERT_EXPRs are still in the IL and cfg cleanup code does not
+ yet handle ASSERT_EXPRs gracefully. */
+ delete m_const_and_copies;
+ delete m_avail_exprs;
+ delete m_avail_exprs_stack;
+}
+
+/* Called before processing dominator children of BB. We want to look
+ at ASSERT_EXPRs and record information from them in the appropriate
+ tables.
+
+ We could look at other statements here. It's not seen as likely
+ to significantly increase the jump threads we discover. */
+
+edge
+vrp_jump_threader::before_dom_children (basic_block bb)
+{
+ gimple_stmt_iterator gsi;
+
+ m_avail_exprs_stack->push_marker ();
+ m_const_and_copies->push_marker ();
+ for (gsi = gsi_start_nondebug_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- FOR_EACH_IMM_USE_FAST (use_p, imm_iter, op)
+ gimple *stmt = gsi_stmt (gsi);
+ if (gimple_assign_single_p (stmt)
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == ASSERT_EXPR)
{
- use_stmt = USE_STMT (use_p);
- if (use_stmt != stmt
- && gimple_assign_single_p (use_stmt)
- && TREE_CODE (gimple_assign_rhs1 (use_stmt)) == ASSERT_EXPR
- && TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) == op
- && dominated_by_p (CDI_DOMINATORS, bb, gimple_bb (use_stmt)))
- return gimple_assign_lhs (use_stmt);
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ tree cond = TREE_OPERAND (rhs1, 1);
+ tree inverted = invert_truthvalue (cond);
+ vec<cond_equivalence> p;
+ p.create (3);
+ record_conditions (&p, cond, inverted);
+ for (unsigned int i = 0; i < p.length (); i++)
+ m_avail_exprs_stack->record_cond (&p[i]);
+
+ tree lhs = gimple_assign_lhs (stmt);
+ m_const_and_copies->record_const_or_copy (lhs,
+ TREE_OPERAND (rhs1, 0));
+ p.release ();
+ continue;
}
+ break;
}
- return op;
+ return NULL;
}
-/* A hack. */
-static class vr_values *x_vr_values;
-
/* A trivial wrapper so that we can present the generic jump threading
code with a simple API for simplifying statements. STMT is the
statement we want to simplify, WITHIN_STMT provides the location
@@ -4141,17 +4284,18 @@ static class vr_values *x_vr_values;
?? This should be cleaned up. There's a virtually identical copy
of this function in tree-ssa-dom.c. */
-static tree
-simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt,
- class avail_exprs_stack *avail_exprs_stack ATTRIBUTE_UNUSED,
- basic_block bb)
+tree
+vrp_jump_threader::simplify_stmt (gimple *stmt,
+ gimple *within_stmt,
+ avail_exprs_stack *avail_exprs_stack,
+ basic_block bb)
{
/* First see if the conditional is in the hash table. */
tree cached_lhs = avail_exprs_stack->lookup_avail_expr (stmt, false, true);
if (cached_lhs && is_gimple_min_invariant (cached_lhs))
return cached_lhs;
- vr_values *vr_values = x_vr_values;
+ class vr_values *vr_values = x_vr_values;
if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
{
tree op0 = gimple_cond_lhs (cond_stmt);
@@ -4199,202 +4343,26 @@ simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt,
return NULL_TREE;
}
-class vrp_dom_walker : public dom_walker
-{
-public:
- vrp_dom_walker (cdi_direction direction,
- class const_and_copies *const_and_copies,
- class avail_exprs_stack *avail_exprs_stack)
- : dom_walker (direction, REACHABLE_BLOCKS),
- m_const_and_copies (const_and_copies),
- m_avail_exprs_stack (avail_exprs_stack),
- m_dummy_cond (NULL) {}
-
- virtual edge before_dom_children (basic_block);
- virtual void after_dom_children (basic_block);
-
- class vr_values *vr_values;
-
-private:
- class const_and_copies *m_const_and_copies;
- class avail_exprs_stack *m_avail_exprs_stack;
-
- gcond *m_dummy_cond;
-
-};
-
-/* Called before processing dominator children of BB. We want to look
- at ASSERT_EXPRs and record information from them in the appropriate
- tables.
-
- We could look at other statements here. It's not seen as likely
- to significantly increase the jump threads we discover. */
-
-edge
-vrp_dom_walker::before_dom_children (basic_block bb)
-{
- gimple_stmt_iterator gsi;
-
- m_avail_exprs_stack->push_marker ();
- m_const_and_copies->push_marker ();
- for (gsi = gsi_start_nondebug_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- {
- gimple *stmt = gsi_stmt (gsi);
- if (gimple_assign_single_p (stmt)
- && TREE_CODE (gimple_assign_rhs1 (stmt)) == ASSERT_EXPR)
- {
- tree rhs1 = gimple_assign_rhs1 (stmt);
- tree cond = TREE_OPERAND (rhs1, 1);
- tree inverted = invert_truthvalue (cond);
- vec<cond_equivalence> p;
- p.create (3);
- record_conditions (&p, cond, inverted);
- for (unsigned int i = 0; i < p.length (); i++)
- m_avail_exprs_stack->record_cond (&p[i]);
-
- tree lhs = gimple_assign_lhs (stmt);
- m_const_and_copies->record_const_or_copy (lhs,
- TREE_OPERAND (rhs1, 0));
- p.release ();
- continue;
- }
- break;
- }
- return NULL;
-}
-
/* Called after processing dominator children of BB. This is where we
actually call into the threader. */
void
-vrp_dom_walker::after_dom_children (basic_block bb)
+vrp_jump_threader::after_dom_children (basic_block bb)
{
if (!m_dummy_cond)
m_dummy_cond = gimple_build_cond (NE_EXPR,
integer_zero_node, integer_zero_node,
NULL, NULL);
- x_vr_values = vr_values;
+ x_vr_values = m_vr_values;
thread_outgoing_edges (bb, m_dummy_cond, m_const_and_copies,
m_avail_exprs_stack, NULL,
- simplify_stmt_for_jump_threading);
+ simplify_stmt);
x_vr_values = NULL;
m_avail_exprs_stack->pop_to_marker ();
m_const_and_copies->pop_to_marker ();
}
-/* Blocks which have more than one predecessor and more than
- one successor present jump threading opportunities, i.e.,
- when the block is reached from a specific predecessor, we
- may be able to determine which of the outgoing edges will
- be traversed. When this optimization applies, we are able
- to avoid conditionals at runtime and we may expose secondary
- optimization opportunities.
-
- This routine is effectively a driver for the generic jump
- threading code. It basically just presents the generic code
- with edges that may be suitable for jump threading.
-
- Unlike DOM, we do not iterate VRP if jump threading was successful.
- While iterating may expose new opportunities for VRP, it is expected
- those opportunities would be very limited and the compile time cost
- to expose those opportunities would be significant.
-
- As jump threading opportunities are discovered, they are registered
- for later realization. */
-
-static void
-identify_jump_threads (struct function *fun, class vr_values *vr_values)
-{
- /* Ugh. When substituting values earlier in this pass we can
- wipe the dominance information. So rebuild the dominator
- information as we need it within the jump threading code. */
- calculate_dominance_info (CDI_DOMINATORS);
-
- /* We do not allow VRP information to be used for jump threading
- across a back edge in the CFG. Otherwise it becomes too
- difficult to avoid eliminating loop exit tests. Of course
- EDGE_DFS_BACK is not accurate at this time so we have to
- recompute it. */
- mark_dfs_back_edges ();
-
- /* Allocate our unwinder stack to unwind any temporary equivalences
- that might be recorded. */
- const_and_copies *equiv_stack = new const_and_copies ();
-
- hash_table<expr_elt_hasher> *avail_exprs
- = new hash_table<expr_elt_hasher> (1024);
- avail_exprs_stack *avail_exprs_stack
- = new class avail_exprs_stack (avail_exprs);
-
- vrp_dom_walker walker (CDI_DOMINATORS, equiv_stack, avail_exprs_stack);
- walker.vr_values = vr_values;
- walker.walk (fun->cfg->x_entry_block_ptr);
-
- /* We do not actually update the CFG or SSA graphs at this point as
- ASSERT_EXPRs are still in the IL and cfg cleanup code does not yet
- handle ASSERT_EXPRs gracefully. */
- delete equiv_stack;
- delete avail_exprs;
- delete avail_exprs_stack;
-}
-
-/* Traverse all the blocks folding conditionals with known ranges. */
-
-void
-vrp_prop::vrp_finalize (vrp_folder *folder, bool warn_array_bounds_p)
-{
- size_t i;
-
- /* We have completed propagating through the lattice. */
- vr_values.set_lattice_propagation_complete ();
-
- if (dump_file)
- {
- fprintf (dump_file, "\nValue ranges after VRP:\n\n");
- vr_values.dump_all_value_ranges (dump_file);
- fprintf (dump_file, "\n");
- }
-
- /* Set value range to non pointer SSA_NAMEs. */
- for (i = 0; i < num_ssa_names; i++)
- {
- tree name = ssa_name (i);
- if (!name)
- continue;
-
- const value_range_equiv *vr = get_value_range (name);
- if (!name || !vr->constant_p ())
- continue;
-
- if (POINTER_TYPE_P (TREE_TYPE (name))
- && range_includes_zero_p (vr) == 0)
- set_ptr_nonnull (name);
- else if (!POINTER_TYPE_P (TREE_TYPE (name)))
- set_range_info (name, *vr);
- }
-
- /* If we're checking array refs, we want to merge information on
- the executability of each edge between vrp_folder and the
- check_array_bounds_dom_walker: each can clear the
- EDGE_EXECUTABLE flag on edges, in different ways.
-
- Hence, if we're going to call check_all_array_refs, set
- the flag on every edge now, rather than in
- check_array_bounds_dom_walker's ctor; vrp_folder may clear
- it from some edges. */
- if (warn_array_bounds && warn_array_bounds_p)
- set_all_edges_as_executable (fun);
-
- folder->substitute_and_fold ();
-
- if (warn_array_bounds && warn_array_bounds_p)
- {
- array_bounds_checker array_checker (fun, &vr_values);
- array_checker.check ();
- }
-}
-
/* STMT is a conditional at the end of a basic block.
If the conditional is of the form SSA_NAME op constant and the SSA_NAME
@@ -4503,7 +4471,6 @@ vrp_simplify_cond_using_ranges (vr_values *query, gcond *stmt)
static unsigned int
execute_vrp (struct function *fun, bool warn_array_bounds_p)
{
-
loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
scev_initialize ();
@@ -4511,7 +4478,7 @@ execute_vrp (struct function *fun, bool warn_array_bounds_p)
/* ??? This ends up using stale EDGE_DFS_BACK for liveness computation.
Inserting assertions may split edges which will invalidate
EDGE_DFS_BACK. */
- vrp_insert assert_engine (fun);
+ vrp_asserts assert_engine (fun);
assert_engine.insert_range_assertions ();
threadedge_initialize_values ();
@@ -4519,17 +4486,41 @@ execute_vrp (struct function *fun, bool warn_array_bounds_p)
/* For visiting PHI nodes we need EDGE_DFS_BACK computed. */
mark_dfs_back_edges ();
- class vrp_prop vrp_prop;
- vrp_prop.vrp_initialize (fun);
+ vr_values vrp_vr_values;
+
+ class vrp_prop vrp_prop (&vrp_vr_values);
+ vrp_prop.initialize (fun);
vrp_prop.ssa_propagate ();
+
/* Instantiate the folder here, so that edge cleanups happen at the
end of this function. */
- vrp_folder folder (&vrp_prop.vr_values);
- vrp_prop.vrp_finalize (&folder, warn_array_bounds_p);
+ vrp_folder folder (&vrp_vr_values);
+ vrp_prop.finalize ();
+
+ /* If we're checking array refs, we want to merge information on
+ the executability of each edge between vrp_folder and the
+ check_array_bounds_dom_walker: each can clear the
+ EDGE_EXECUTABLE flag on edges, in different ways.
+
+ Hence, if we're going to call check_all_array_refs, set
+ the flag on every edge now, rather than in
+ check_array_bounds_dom_walker's ctor; vrp_folder may clear
+ it from some edges. */
+ if (warn_array_bounds && warn_array_bounds_p)
+ set_all_edges_as_executable (fun);
+
+ folder.substitute_and_fold ();
+
+ if (warn_array_bounds && warn_array_bounds_p)
+ {
+ array_bounds_checker array_checker (fun, &vrp_vr_values);
+ array_checker.check ();
+ }
/* We must identify jump threading opportunities before we release
the datastructures built by VRP. */
- identify_jump_threads (fun, &vrp_prop.vr_values);
+ vrp_jump_threader threader (fun, &vrp_vr_values);
+ threader.thread_jumps ();
/* A comparison of an SSA_NAME against a constant where the SSA_NAME
was set by a type conversion can often be rewritten to use the
@@ -4543,7 +4534,7 @@ execute_vrp (struct function *fun, bool warn_array_bounds_p)
{
gimple *last = last_stmt (bb);
if (last && gimple_code (last) == GIMPLE_COND)
- vrp_simplify_cond_using_ranges (&vrp_prop.vr_values,
+ vrp_simplify_cond_using_ranges (&vrp_vr_values,
as_a <gcond *> (last));
}
diff --git a/gcc/tree.c b/gcc/tree.c
index 9260772..72311005 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -773,6 +773,33 @@ set_decl_section_name (tree node, const char *value)
snode->set_section (value);
}
+/* Set section name of NODE to match the section name of OTHER.
+
+ set_decl_section_name (decl, other) is equivalent to
+ set_decl_section_name (decl, DECL_SECTION_NAME (other)), but possibly more
+ efficient. */
+void
+set_decl_section_name (tree decl, const_tree other)
+{
+ struct symtab_node *other_node = symtab_node::get (other);
+ if (other_node)
+ {
+ struct symtab_node *decl_node;
+ if (VAR_P (decl))
+ decl_node = varpool_node::get_create (decl);
+ else
+ decl_node = cgraph_node::get_create (decl);
+ decl_node->set_section (*other_node);
+ }
+ else
+ {
+ struct symtab_node *decl_node = symtab_node::get (decl);
+ if (!decl_node)
+ return;
+ decl_node->set_section (NULL);
+ }
+}
+
/* Return TLS model of a variable NODE. */
enum tls_model
decl_tls_model (const_tree node)
@@ -837,6 +864,7 @@ tree_code_size (enum tree_code code)
case BOOLEAN_TYPE:
case INTEGER_TYPE:
case REAL_TYPE:
+ case OPAQUE_TYPE:
case POINTER_TYPE:
case REFERENCE_TYPE:
case NULLPTR_TYPE:
@@ -1214,7 +1242,7 @@ copy_node (tree node MEM_STAT_DECL)
SET_DECL_VALUE_EXPR (t, DECL_VALUE_EXPR (node));
DECL_HAS_VALUE_EXPR_P (t) = 1;
}
- /* DECL_DEBUG_EXPR is copied explicitely by callers. */
+ /* DECL_DEBUG_EXPR is copied explicitly by callers. */
if (VAR_P (node))
{
DECL_HAS_DEBUG_EXPR_P (t) = 0;
@@ -1727,8 +1755,15 @@ wide_int_to_tree (tree type, const poly_wide_int_ref &value)
return build_poly_int_cst (type, value);
}
-void
-cache_integer_cst (tree t)
+/* Insert INTEGER_CST T into a cache of integer constants. And return
+ the cached constant (which may or may not be T). If MIGHT_DUPLICATE
+ is false, and T falls into the type's 'smaller values' range, there
+ cannot be an existing entry. Otherwise, if MIGHT_DUPLICATE is true,
+ or the value is large, should an existing entry exist, it is
+ returned (rather than inserting T). */
+
+tree
+cache_integer_cst (tree t, bool might_duplicate ATTRIBUTE_UNUSED)
{
tree type = TREE_TYPE (t);
int ix = -1;
@@ -1742,7 +1777,7 @@ cache_integer_cst (tree t)
switch (TREE_CODE (type))
{
case NULLPTR_TYPE:
- gcc_assert (integer_zerop (t));
+ gcc_checking_assert (integer_zerop (t));
/* Fallthru. */
case POINTER_TYPE:
@@ -1822,21 +1857,32 @@ cache_integer_cst (tree t)
TYPE_CACHED_VALUES (type) = make_tree_vec (limit);
}
- gcc_assert (TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) == NULL_TREE);
- TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) = t;
+ if (tree r = TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix))
+ {
+ gcc_checking_assert (might_duplicate);
+ t = r;
+ }
+ else
+ TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) = t;
}
else
{
/* Use the cache of larger shared ints. */
tree *slot = int_cst_hash_table->find_slot (t, INSERT);
- /* If there is already an entry for the number verify it's the
- same. */
- if (*slot)
- gcc_assert (wi::to_wide (tree (*slot)) == wi::to_wide (t));
+ if (tree r = *slot)
+ {
+ /* If there is already an entry for the number verify it's the
+ same value. */
+ gcc_checking_assert (wi::to_wide (tree (r)) == wi::to_wide (t));
+ /* And return the cached value. */
+ t = r;
+ }
else
/* Otherwise insert this one into the hash table. */
*slot = t;
}
+
+ return t;
}
@@ -3437,7 +3483,17 @@ array_type_nelts (const_tree type)
/* TYPE_MAX_VALUE may not be set if the array has unknown length. */
if (!max)
- return error_mark_node;
+ {
+ /* zero sized arrays are represented from C FE as complete types with
+ NULL TYPE_MAX_VALUE and zero TYPE_SIZE, while C++ FE represents
+ them as min 0, max -1. */
+ if (COMPLETE_TYPE_P (type)
+ && integer_zerop (TYPE_SIZE (type))
+ && integer_zerop (min))
+ return build_int_cst (TREE_TYPE (min), -1);
+
+ return error_mark_node;
+ }
return (integer_zerop (min)
? max
@@ -3916,6 +3972,7 @@ type_contains_placeholder_1 (const_tree type)
switch (TREE_CODE (type))
{
case VOID_TYPE:
+ case OPAQUE_TYPE:
case COMPLEX_TYPE:
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
@@ -7044,6 +7101,7 @@ type_cache_hasher::equal (type_hash *a, type_hash *b)
switch (TREE_CODE (a->type))
{
case VOID_TYPE:
+ case OPAQUE_TYPE:
case COMPLEX_TYPE:
case POINTER_TYPE:
case REFERENCE_TYPE:
@@ -10675,6 +10733,12 @@ build_common_builtin_nodes (void)
ftype = build_function_type_list (void_type_node,
ptr_type_node, ptr_type_node, NULL_TREE);
+ if (!builtin_decl_explicit_p (BUILT_IN_CLEAR_CACHE))
+ local_define_builtin ("__builtin___clear_cache", ftype,
+ BUILT_IN_CLEAR_CACHE,
+ "__builtin___clear_cache",
+ ECF_NOTHROW);
+
local_define_builtin ("__builtin_nonlocal_goto", ftype,
BUILT_IN_NONLOCAL_GOTO,
"__builtin_nonlocal_goto",
@@ -13682,9 +13746,9 @@ component_ref_size (tree ref, special_array_member *sam /* = NULL */)
{
gcc_assert (TREE_CODE (ref) == COMPONENT_REF);
- special_array_member arkbuf;
+ special_array_member sambuf;
if (!sam)
- sam = &arkbuf;
+ sam = &sambuf;
*sam = special_array_member::none;
/* The object/argument referenced by the COMPONENT_REF and its type. */
@@ -13698,7 +13762,13 @@ component_ref_size (tree ref, special_array_member *sam /* = NULL */)
{
tree memtype = TREE_TYPE (member);
if (TREE_CODE (memtype) != ARRAY_TYPE)
- return memsize;
+ /* DECL_SIZE may be less than TYPE_SIZE in C++ when referring
+ to the type of a class with a virtual base which doesn't
+ reflect the size of the virtual's members (see pr97595).
+ If that's the case fail for now and implement something
+ more robust in the future. */
+ return (tree_int_cst_equal (memsize, TYPE_SIZE_UNIT (memtype))
+ ? memsize : NULL_TREE);
bool trailing = array_at_struct_end_p (ref);
bool zero_length = integer_zerop (memsize);
@@ -15014,6 +15084,10 @@ maybe_wrap_with_location (tree expr, location_t loc)
if (EXCEPTIONAL_CLASS_P (expr))
return expr;
+ /* Compiler-generated temporary variables don't need a wrapper. */
+ if (DECL_P (expr) && DECL_ARTIFICIAL (expr) && DECL_IGNORED_P (expr))
+ return expr;
+
/* If any auto_suppress_location_wrappers are active, don't create
wrappers. */
if (suppress_location_wrappers > 0)
@@ -15105,22 +15179,22 @@ get_nonnull_args (const_tree fntype)
/* Returns true if TYPE is a type where it and all of its subobjects
(recursively) are of structure, union, or array type. */
-static bool
-default_is_empty_type (tree type)
+bool
+is_empty_type (const_tree type)
{
if (RECORD_OR_UNION_TYPE_P (type))
{
for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
if (TREE_CODE (field) == FIELD_DECL
&& !DECL_PADDING_P (field)
- && !default_is_empty_type (TREE_TYPE (field)))
+ && !is_empty_type (TREE_TYPE (field)))
return false;
return true;
}
else if (TREE_CODE (type) == ARRAY_TYPE)
return (integer_minus_onep (array_type_nelts (type))
|| TYPE_DOMAIN (type) == NULL_TREE
- || default_is_empty_type (TREE_TYPE (type)));
+ || is_empty_type (TREE_TYPE (type)));
return false;
}
@@ -15139,7 +15213,7 @@ default_is_empty_record (const_tree type)
if (TREE_ADDRESSABLE (type))
return false;
- return default_is_empty_type (TYPE_MAIN_VARIANT (type));
+ return is_empty_type (TYPE_MAIN_VARIANT (type));
}
/* Determine whether TYPE is a structure with a flexible array member,
diff --git a/gcc/tree.def b/gcc/tree.def
index 6c53fe1..11f5a98 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -250,6 +250,12 @@ DEFTREECODE (METHOD_TYPE, "method_type", tcc_type, 0)
layout_type does not know how to lay this out,
so the front-end must do so manually. */
DEFTREECODE (LANG_TYPE, "lang_type", tcc_type, 0)
+
+/* This is for types that will use MODE_OPAQUE in the back end. They are meant
+ to be able to go in a register of some sort but are explicitly not to be
+ converted or operated on like INTEGER_TYPE. They will have size and
+ alignment information only. */
+DEFTREECODE (OPAQUE_TYPE, "opaque_type", tcc_type, 0)
/* Expressions */
@@ -1359,6 +1365,8 @@ DEFTREECODE (WIDEN_MULT_MINUS_EXPR, "widen_mult_minus_expr", tcc_expression, 3)
the first argument from type t1 to type t2, and then shifting it
by the second argument. */
DEFTREECODE (WIDEN_LSHIFT_EXPR, "widen_lshift_expr", tcc_binary, 2)
+DEFTREECODE (WIDEN_PLUS_EXPR, "widen_plus_expr", tcc_binary, 2)
+DEFTREECODE (WIDEN_MINUS_EXPR, "widen_minus_expr", tcc_binary, 2)
/* Widening vector multiplication.
The two operands are vectors with N elements of size S. Multiplying the
@@ -1423,6 +1431,10 @@ DEFTREECODE (VEC_PACK_FLOAT_EXPR, "vec_pack_float_expr", tcc_binary, 2)
*/
DEFTREECODE (VEC_WIDEN_LSHIFT_HI_EXPR, "widen_lshift_hi_expr", tcc_binary, 2)
DEFTREECODE (VEC_WIDEN_LSHIFT_LO_EXPR, "widen_lshift_lo_expr", tcc_binary, 2)
+DEFTREECODE (VEC_WIDEN_PLUS_HI_EXPR, "widen_plus_hi_expr", tcc_binary, 2)
+DEFTREECODE (VEC_WIDEN_PLUS_LO_EXPR, "widen_plus_lo_expr", tcc_binary, 2)
+DEFTREECODE (VEC_WIDEN_MINUS_HI_EXPR, "widen_minus_hi_expr", tcc_binary, 2)
+DEFTREECODE (VEC_WIDEN_MINUS_LO_EXPR, "widen_minus_lo_expr", tcc_binary, 2)
/* PREDICT_EXPR. Specify hint for branch prediction. The
PREDICT_EXPR_PREDICTOR specify predictor and PREDICT_EXPR_OUTCOME the
diff --git a/gcc/tree.h b/gcc/tree.h
index f8f0a60..7faa49d 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -625,6 +625,9 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
#define FUNC_OR_METHOD_TYPE_P(NODE) \
(TREE_CODE (NODE) == FUNCTION_TYPE || TREE_CODE (NODE) == METHOD_TYPE)
+#define OPAQUE_TYPE_P(NODE) \
+ (TREE_CODE (NODE) == OPAQUE_TYPE)
+
/* Define many boolean fields that all tree nodes have. */
/* In VAR_DECL, PARM_DECL and RESULT_DECL nodes, nonzero means address
@@ -1214,7 +1217,7 @@ get_expr_source_range (tree expr)
extern void protected_set_expr_location (tree, location_t);
extern void protected_set_expr_location_if_unset (tree, location_t);
-extern tree maybe_wrap_with_location (tree, location_t);
+WARN_UNUSED_RESULT extern tree maybe_wrap_with_location (tree, location_t);
extern int suppress_location_wrappers;
@@ -1984,8 +1987,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. */
+/* Type size in bits as a tree expression. Need not be constant and may
+ be greater than TYPE_SIZE for a C++ FIELD_DECL representing a base
+ class subobject with its own virtual base classes (which are laid out
+ separately). */
#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)
@@ -2518,7 +2523,9 @@ extern tree vector_element_bits_tree (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 and may be null. */
+ Need not be constant and may be null. May be less than TYPE_SIZE
+ for a C++ FIELD_DECL representing a base class subobject with its
+ own virtual base classes (which are laid out separately). */
#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)
@@ -2659,6 +2666,20 @@ extern tree vector_element_bits_tree (const_tree);
#define DECL_PRESERVE_P(DECL) \
DECL_COMMON_CHECK (DECL)->decl_common.preserve_flag
+/* Nonzero for a decl that is decorated with the "noinit" attribute.
+ decls with this attribute are placed into the ".noinit" section, so they are
+ not initialized by the target's startup code. */
+#define DECL_NOINIT_P(DECL) \
+ (DECL_P (DECL) \
+ && (lookup_attribute ("noinit", DECL_ATTRIBUTES (DECL)) != NULL_TREE))
+
+/* Nonzero for a decl that is decorated with the "persistent" attribute.
+ decls with this attribute are placed into the ".persistent" section, so they
+ are not initialized by the target's startup code. */
+#define DECL_PERSISTENT_P(DECL) \
+ (DECL_P (DECL) \
+ && (lookup_attribute ("persistent", DECL_ATTRIBUTES (DECL)) != NULL_TREE))
+
/* For function local variables of COMPLEX and VECTOR types,
indicates that the variable is not aliased, and that all
modifications to the variable have been adjusted so that
@@ -4281,6 +4302,7 @@ extern tree decl_comdat_group (const_tree);
extern tree decl_comdat_group_id (const_tree);
extern const char *decl_section_name (const_tree);
extern void set_decl_section_name (tree, const char *);
+extern void set_decl_section_name (tree, const_tree);
extern enum tls_model decl_tls_model (const_tree);
extern void set_decl_tls_model (tree, enum tls_model);
@@ -5120,7 +5142,7 @@ extern const_tree strip_invariant_refs (const_tree);
extern tree lhd_gcc_personality (void);
extern void assign_assembler_name_if_needed (tree);
extern bool warn_deprecated_use (tree, tree);
-extern void cache_integer_cst (tree);
+extern tree cache_integer_cst (tree, bool might_duplicate = false);
extern const char *combined_fn_name (combined_fn);
/* Compare and hash for any structure which begins with a canonical
@@ -5578,6 +5600,13 @@ is_lang_specific (const_tree t)
#define BUILTIN_VALID_P(FNCODE) \
(IN_RANGE ((int)FNCODE, ((int)BUILT_IN_NONE) + 1, ((int) END_BUILTINS) - 1))
+/* Obtain a pointer to the identifier string holding the asm name for
+ BUILTIN, a BUILT_IN code. This is handy if the target
+ mangles/overrides the function name that implements the
+ builtin. */
+#define BUILTIN_ASM_NAME_PTR(BUILTIN) \
+ (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (builtin_decl_explicit (BUILTIN))))
+
/* Return the tree node for an explicit standard builtin function or NULL. */
static inline tree
builtin_decl_explicit (enum built_in_function fncode)
@@ -6232,6 +6261,7 @@ extern void gt_pch_nx (tree &);
extern void gt_pch_nx (tree &, gt_pointer_operator, void *);
extern bool nonnull_arg_p (const_tree);
+extern bool is_empty_type (const_tree);
extern bool default_is_empty_record (const_tree);
extern bool flexible_array_type_p (const_tree);
extern HOST_WIDE_INT arg_int_size_in_bytes (const_tree);
diff --git a/gcc/typeclass.h b/gcc/typeclass.h
index 434e6ac..b4e3dda2 100644
--- a/gcc/typeclass.h
+++ b/gcc/typeclass.h
@@ -37,7 +37,7 @@ enum type_class
function_type_class, method_type_class,
record_type_class, union_type_class,
array_type_class, string_type_class,
- lang_type_class
+ lang_type_class, opaque_type_class
};
#endif /* GCC_TYPECLASS_H */
diff --git a/gcc/ubsan.c b/gcc/ubsan.c
index acd8a0b..4c14a38 100644
--- a/gcc/ubsan.c
+++ b/gcc/ubsan.c
@@ -405,10 +405,12 @@ ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
/* We weren't able to determine the type name. */
tname = "<unknown>";
+ pp_quote (&pretty_name);
+
tree eltype = type;
if (pstyle == UBSAN_PRINT_POINTER)
{
- pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
+ pp_printf (&pretty_name, "%s%s%s%s%s%s%s",
TYPE_VOLATILE (type2) ? "volatile " : "",
TYPE_READONLY (type2) ? "const " : "",
TYPE_RESTRICT (type2) ? "restrict " : "",
@@ -420,14 +422,14 @@ ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
deref_depth == 0 ? "" : " ");
while (deref_depth-- > 0)
pp_star (&pretty_name);
- pp_quote (&pretty_name);
}
else if (pstyle == UBSAN_PRINT_ARRAY)
{
/* Pretty print the array dimensions. */
gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
tree t = type;
- pp_printf (&pretty_name, "'%s ", tname);
+ pp_string (&pretty_name, tname);
+ pp_space (&pretty_name);
while (deref_depth-- > 0)
pp_star (&pretty_name);
while (TREE_CODE (t) == ARRAY_TYPE)
@@ -453,13 +455,14 @@ ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
pp_right_bracket (&pretty_name);
t = TREE_TYPE (t);
}
- pp_quote (&pretty_name);
/* Save the tree with stripped types. */
eltype = t;
}
else
- pp_printf (&pretty_name, "'%s'", tname);
+ pp_string (&pretty_name, tname);
+
+ pp_quote (&pretty_name);
switch (TREE_CODE (eltype))
{
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index f83a824..2b82dfe 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -249,9 +249,13 @@ irange::set (tree min, tree max, value_range_kind kind)
return;
}
- if (kind != VR_VARYING
- && (POLY_INT_CST_P (min) || POLY_INT_CST_P (max)))
- kind = VR_VARYING;
+ if (kind == VR_VARYING
+ || POLY_INT_CST_P (min)
+ || POLY_INT_CST_P (max))
+ {
+ set_varying (TREE_TYPE (min));
+ return;
+ }
// Nothing to canonicalize for symbolic ranges.
if (TREE_CODE (min) != INTEGER_CST
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 435c7b3..961d2d6 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -289,6 +289,10 @@ get_section (const char *name, unsigned int flags, tree decl,
slot = section_htab->find_slot_with_hash (name, htab_hash_string (name),
INSERT);
flags |= SECTION_NAMED;
+ if (HAVE_GAS_SHF_GNU_RETAIN
+ && decl != nullptr
+ && DECL_PRESERVE_P (decl))
+ flags |= SECTION_RETAIN;
if (*slot == NULL)
{
sect = ggc_alloc<section> ();
@@ -469,6 +473,7 @@ resolve_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED,
if (DECL_SECTION_NAME (decl) == NULL
&& targetm_common.have_named_sections
&& (flag_function_or_data_sections
+ || (HAVE_GAS_SHF_GNU_RETAIN && DECL_PRESERVE_P (decl))
|| DECL_COMDAT_GROUP (decl)))
{
targetm.asm_out.unique_section (decl, reloc);
@@ -732,12 +737,26 @@ switch_to_other_text_partition (void)
switch_to_section (current_function_section ());
}
-/* Return the read-only data section associated with function DECL. */
+/* Return the read-only or relocated read-only data section
+ associated with function DECL. */
section *
-default_function_rodata_section (tree decl)
+default_function_rodata_section (tree decl, bool relocatable)
{
- if (decl != NULL_TREE && DECL_SECTION_NAME (decl))
+ const char* sname;
+ unsigned int flags;
+
+ flags = 0;
+
+ if (relocatable)
+ {
+ sname = ".data.rel.ro.local";
+ flags = (SECTION_WRITE | SECTION_RELRO);
+ }
+ else
+ sname = ".rodata";
+
+ if (decl && DECL_SECTION_NAME (decl))
{
const char *name = DECL_SECTION_NAME (decl);
@@ -750,38 +769,56 @@ default_function_rodata_section (tree decl)
dot = strchr (name + 1, '.');
if (!dot)
dot = name;
- len = strlen (dot) + 8;
+ len = strlen (dot) + strlen (sname) + 1;
rname = (char *) alloca (len);
- strcpy (rname, ".rodata");
+ strcpy (rname, sname);
strcat (rname, dot);
- return get_section (rname, SECTION_LINKONCE, decl);
+ return get_section (rname, (SECTION_LINKONCE | flags), decl);
}
- /* For .gnu.linkonce.t.foo we want to use .gnu.linkonce.r.foo. */
+ /* For .gnu.linkonce.t.foo we want to use .gnu.linkonce.r.foo or
+ .gnu.linkonce.d.rel.ro.local.foo if the jump table is relocatable. */
else if (DECL_COMDAT_GROUP (decl)
&& strncmp (name, ".gnu.linkonce.t.", 16) == 0)
{
- size_t len = strlen (name) + 1;
- char *rname = (char *) alloca (len);
+ size_t len;
+ char *rname;
- memcpy (rname, name, len);
- rname[14] = 'r';
- return get_section (rname, SECTION_LINKONCE, decl);
+ if (relocatable)
+ {
+ len = strlen (name) + strlen (".rel.ro.local") + 1;
+ rname = (char *) alloca (len);
+
+ strcpy (rname, ".gnu.linkonce.d.rel.ro.local");
+ strcat (rname, name + 15);
+ }
+ else
+ {
+ len = strlen (name) + 1;
+ rname = (char *) alloca (len);
+
+ memcpy (rname, name, len);
+ rname[14] = 'r';
+ }
+ return get_section (rname, (SECTION_LINKONCE | flags), decl);
}
/* For .text.foo we want to use .rodata.foo. */
else if (flag_function_sections && flag_data_sections
&& strncmp (name, ".text.", 6) == 0)
{
size_t len = strlen (name) + 1;
- char *rname = (char *) alloca (len + 2);
+ char *rname = (char *) alloca (len + strlen (sname) - 5);
- memcpy (rname, ".rodata", 7);
- memcpy (rname + 7, name + 5, len - 5);
- return get_section (rname, 0, decl);
+ memcpy (rname, sname, strlen (sname));
+ memcpy (rname + strlen (sname), name + 5, len - 5);
+ return get_section (rname, flags, decl);
}
}
- return readonly_data_section;
+ if (relocatable)
+ return get_section (sname, flags, decl);
+ else
+ return readonly_data_section;
}
/* Return the read-only data section associated with function DECL
@@ -789,7 +826,7 @@ default_function_rodata_section (tree decl)
readonly data section. */
section *
-default_no_function_rodata_section (tree decl ATTRIBUTE_UNUSED)
+default_no_function_rodata_section (tree, bool)
{
return readonly_data_section;
}
@@ -799,7 +836,8 @@ default_no_function_rodata_section (tree decl ATTRIBUTE_UNUSED)
static const char *
function_mergeable_rodata_prefix (void)
{
- section *s = targetm.asm_out.function_rodata_section (current_function_decl);
+ section *s = targetm.asm_out.function_rodata_section (current_function_decl,
+ false);
if (SECTION_STYLE (s) == SECTION_NAMED)
return s->named.name;
else
@@ -1024,7 +1062,11 @@ bss_initializer_p (const_tree decl, bool named)
|| (DECL_INITIAL (decl) == error_mark_node
&& !in_lto_p)
|| (flag_zero_initialized_in_bss
- && initializer_zerop (DECL_INITIAL (decl)))));
+ && initializer_zerop (DECL_INITIAL (decl))
+ /* A decl with the "persistent" attribute applied and
+ explicitly initialized to 0 should not be treated as a BSS
+ variable. */
+ && !DECL_PERSISTENT_P (decl))));
}
/* Compute the alignment of variable specified by DECL.
@@ -1170,7 +1212,8 @@ get_variable_section (tree decl, bool prefer_noswitch_p)
if (vnode)
vnode->get_constructor ();
- if (DECL_COMMON (decl))
+ if (DECL_COMMON (decl)
+ && !(HAVE_GAS_SHF_GNU_RETAIN && DECL_PRESERVE_P (decl)))
{
/* If the decl has been given an explicit section name, or it resides
in a non-generic address space, then it isn't common, and shouldn't
@@ -1208,6 +1251,7 @@ get_variable_section (tree decl, bool prefer_noswitch_p)
if (ADDR_SPACE_GENERIC_P (as)
&& !DECL_THREAD_LOCAL_P (decl)
+ && !DECL_NOINIT_P (decl)
&& !(prefer_noswitch_p && targetm.have_switchable_bss_sections)
&& bss_initializer_p (decl))
{
@@ -6646,6 +6690,9 @@ default_section_type_flags (tree decl, const char *name, int reloc)
if (strcmp (name, ".noinit") == 0)
flags |= SECTION_WRITE | SECTION_BSS | SECTION_NOTYPE;
+ if (strcmp (name, ".persistent") == 0)
+ flags |= SECTION_WRITE | 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
@@ -6704,9 +6751,10 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
/* If we have already declared this section, we can use an
abbreviated form to switch back to it -- unless this section is
- part of a COMDAT groups, in which case GAS requires the full
- declaration every time. */
+ part of a COMDAT groups or with SHF_GNU_RETAIN, in which case GAS
+ requires the full declaration every time. */
if (!(HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
+ && !(flags & SECTION_RETAIN)
&& (flags & SECTION_DECLARED))
{
fprintf (asm_out_file, "\t.section\t%s\n", name);
@@ -6739,6 +6787,10 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
*f++ = TLS_SECTION_ASM_FLAG;
if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
*f++ = 'G';
+ if (flags & SECTION_RETAIN)
+ *f++ = 'R';
+ if (flags & SECTION_LINK_ORDER)
+ *f++ = 'o';
#ifdef MACH_DEP_SECTION_ASM_FLAG
if (flags & SECTION_MACH_DEP)
*f++ = MACH_DEP_SECTION_ASM_FLAG;
@@ -6771,6 +6823,14 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
if (flags & SECTION_ENTSIZE)
fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE);
+ if (flags & SECTION_LINK_ORDER)
+ {
+ tree id = DECL_ASSEMBLER_NAME (decl);
+ ultimate_transparent_alias_target (&id);
+ const char *name = IDENTIFIER_POINTER (id);
+ name = targetm.strip_name_encoding (name);
+ fprintf (asm_out_file, ",%s", name);
+ }
if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
{
if (TREE_CODE (decl) == IDENTIFIER_NODE)
@@ -6989,6 +7049,11 @@ default_elf_select_section (tree decl, int reloc,
sname = ".sdata2";
break;
case SECCAT_DATA:
+ if (DECL_P (decl) && DECL_PERSISTENT_P (decl))
+ {
+ sname = ".persistent";
+ break;
+ }
return data_section;
case SECCAT_DATA_REL:
sname = ".data.rel";
@@ -7009,13 +7074,11 @@ 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)
+ if (DECL_P (decl) && DECL_NOINIT_P (decl))
{
sname = ".noinit";
break;
}
-
if (bss_section)
return bss_section;
sname = ".bss";
@@ -7061,6 +7124,11 @@ default_unique_section (tree decl, int reloc)
break;
case SECCAT_DATA:
prefix = one_only ? ".d" : ".data";
+ if (DECL_P (decl) && DECL_PERSISTENT_P (decl))
+ {
+ prefix = one_only ? ".p" : ".persistent";
+ break;
+ }
break;
case SECCAT_DATA_REL:
prefix = one_only ? ".d.rel" : ".data.rel";
@@ -7078,6 +7146,11 @@ default_unique_section (tree decl, int reloc)
prefix = one_only ? ".s" : ".sdata";
break;
case SECCAT_BSS:
+ if (DECL_P (decl) && DECL_NOINIT_P (decl))
+ {
+ prefix = one_only ? ".n" : ".noinit";
+ break;
+ }
prefix = one_only ? ".b" : ".bss";
break;
case SECCAT_SBSS:
diff --git a/gcc/vec.h b/gcc/vec.h
index 14d77e8..9090451 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -1602,7 +1602,7 @@ class auto_delete_vec : public auto_vec <T *>
~auto_delete_vec ();
private:
- DISABLE_COPY_AND_ASSIGN(auto_delete_vec<T>);
+ DISABLE_COPY_AND_ASSIGN(auto_delete_vec);
};
/* Conditionally allocate heap memory for VEC and its internal vector. */
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index 9f5943a..3db72a3 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -1159,188 +1159,16 @@ check_for_binary_op_overflow (range_query *query,
successful. */
bool
-vr_values::extract_range_builtin (value_range_equiv *vr, gimple *stmt)
+vr_values::extract_range_from_ubsan_builtin (value_range_equiv *vr, gimple *stmt)
{
gcc_assert (is_gimple_call (stmt));
tree type = gimple_expr_type (stmt);
- tree arg;
- int mini, maxi, zerov = 0, prec;
enum tree_code subcode = ERROR_MARK;
combined_fn cfn = gimple_call_combined_fn (stmt);
scalar_int_mode mode;
switch (cfn)
{
- case CFN_BUILT_IN_CONSTANT_P:
- /* Resolve calls to __builtin_constant_p after inlining. */
- if (cfun->after_inlining)
- {
- vr->set_zero (type);
- vr->equiv_clear ();
- return true;
- }
- break;
- /* Both __builtin_ffs* and __builtin_popcount return
- [0, prec]. */
- CASE_CFN_FFS:
- CASE_CFN_POPCOUNT:
- arg = gimple_call_arg (stmt, 0);
- prec = TYPE_PRECISION (TREE_TYPE (arg));
- mini = 0;
- maxi = prec;
- if (TREE_CODE (arg) == SSA_NAME)
- {
- const value_range_equiv *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;
- /* If some high bits are known to be zero,
- we can decrease the maximum. */
- if (vr0->kind () == VR_RANGE
- && TREE_CODE (vr0->max ()) == INTEGER_CST
- && !operand_less_p (vr0->min (),
- build_zero_cst (TREE_TYPE (vr0->min ()))))
- maxi = tree_floor_log2 (vr0->max ()) + 1;
- }
- goto bitop_builtin;
- /* __builtin_parity* returns [0, 1]. */
- CASE_CFN_PARITY:
- mini = 0;
- maxi = 1;
- goto bitop_builtin;
- /* __builtin_clz* return [0, prec-1], except for
- when the argument is 0, but that is undefined behavior.
- Always handle __builtin_clz* which can be only written
- by user as UB on 0 and so [0, prec-1] range, and the internal-fn
- calls depending on how CLZ_DEFINED_VALUE_AT_ZERO is defined. */
- CASE_CFN_CLZ:
- arg = gimple_call_arg (stmt, 0);
- prec = TYPE_PRECISION (TREE_TYPE (arg));
- mini = 0;
- maxi = prec - 1;
- mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg));
- if (gimple_call_internal_p (stmt))
- {
- if (optab_handler (clz_optab, mode) != CODE_FOR_nothing
- && CLZ_DEFINED_VALUE_AT_ZERO (mode, zerov) == 2)
- {
- /* Handle only the single common value. */
- if (zerov == prec)
- maxi = prec;
- /* Magic value to give up, unless vr0 proves
- arg is non-zero. */
- else
- mini = -2;
- }
- }
- if (TREE_CODE (arg) == SSA_NAME)
- {
- const value_range_equiv *vr0 = get_value_range (arg);
- /* From clz of VR_RANGE minimum we can compute
- result maximum. */
- if (vr0->kind () == VR_RANGE
- && TREE_CODE (vr0->min ()) == INTEGER_CST
- && integer_nonzerop (vr0->min ()))
- {
- maxi = prec - 1 - tree_floor_log2 (vr0->min ());
- if (mini == -2)
- mini = 0;
- }
- else if (vr0->kind () == VR_ANTI_RANGE
- && integer_zerop (vr0->min ()))
- {
- maxi = prec - 1;
- mini = 0;
- }
- if (mini == -2)
- break;
- /* From clz of VR_RANGE maximum we can compute
- result minimum. */
- if (vr0->kind () == VR_RANGE
- && TREE_CODE (vr0->max ()) == INTEGER_CST)
- {
- int newmini = prec - 1 - tree_floor_log2 (vr0->max ());
- if (newmini == prec)
- {
- if (maxi == prec)
- mini = prec;
- }
- else
- mini = newmini;
- }
- }
- if (mini == -2)
- break;
- goto bitop_builtin;
- /* __builtin_ctz* return [0, prec-1], except for
- when the argument is 0, but that is undefined behavior.
- Always handle __builtin_ctz* which can be only written
- by user as UB on 0 and so [0, prec-1] range, and the internal-fn
- calls depending on how CTZ_DEFINED_VALUE_AT_ZERO is defined. */
- CASE_CFN_CTZ:
- arg = gimple_call_arg (stmt, 0);
- prec = TYPE_PRECISION (TREE_TYPE (arg));
- mini = 0;
- maxi = prec - 1;
- mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg));
- if (gimple_call_internal_p (stmt))
- {
- if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing
- && CTZ_DEFINED_VALUE_AT_ZERO (mode, zerov) == 2)
- {
- /* Handle only the two common values. */
- if (zerov == -1)
- mini = -1;
- else if (zerov == prec)
- maxi = prec;
- else
- /* Magic value to give up, unless vr0 proves
- arg is non-zero. */
- mini = -2;
- }
- }
- if (TREE_CODE (arg) == SSA_NAME)
- {
- const value_range_equiv *vr0 = get_value_range (arg);
- /* If arg is non-zero, then use [0, prec - 1]. */
- if ((vr0->kind () == VR_RANGE
- && integer_nonzerop (vr0->min ()))
- || (vr0->kind () == VR_ANTI_RANGE
- && integer_zerop (vr0->min ())))
- {
- mini = 0;
- maxi = prec - 1;
- }
- /* If some high bits are known to be zero,
- we can decrease the result maximum. */
- if (vr0->kind () == VR_RANGE
- && TREE_CODE (vr0->max ()) == INTEGER_CST)
- {
- int newmaxi = tree_floor_log2 (vr0->max ());
- if (newmaxi == -1)
- {
- if (mini == -1)
- maxi = -1;
- else if (maxi == prec)
- mini = prec;
- }
- else if (maxi != prec)
- maxi = newmaxi;
- }
- }
- if (mini == -2)
- break;
- goto bitop_builtin;
- /* __builtin_clrsb* returns [0, prec-1]. */
- CASE_CFN_CLRSB:
- arg = gimple_call_arg (stmt, 0);
- prec = TYPE_PRECISION (TREE_TYPE (arg));
- mini = 0;
- maxi = prec - 1;
- goto bitop_builtin;
- bitop_builtin:
- vr->set (build_int_cst (type, mini), build_int_cst (type, maxi));
- return true;
case CFN_UBSAN_CHECK_ADD:
subcode = PLUS_EXPR;
break;
@@ -1350,47 +1178,6 @@ vr_values::extract_range_builtin (value_range_equiv *vr, gimple *stmt)
case CFN_UBSAN_CHECK_MUL:
subcode = MULT_EXPR;
break;
- case CFN_GOACC_DIM_SIZE:
- case CFN_GOACC_DIM_POS:
- /* Optimizing these two internal functions helps the loop
- optimizer eliminate outer comparisons. Size is [1,N]
- and pos is [0,N-1]. */
- {
- bool is_pos = cfn == CFN_GOACC_DIM_POS;
- int axis = oacc_get_ifn_dim_arg (stmt);
- int size = oacc_get_fn_dim_size (current_function_decl, axis);
-
- if (!size)
- /* If it's dynamic, the backend might know a hardware
- limitation. */
- size = targetm.goacc.dim_limit (axis);
-
- tree type = TREE_TYPE (gimple_call_lhs (stmt));
- vr->set(build_int_cst (type, is_pos ? 0 : 1),
- size
- ? build_int_cst (type, size - is_pos) : vrp_val_max (type));
- }
- return true;
- case CFN_BUILT_IN_STRLEN:
- if (tree lhs = gimple_call_lhs (stmt))
- if (ptrdiff_type_node
- && (TYPE_PRECISION (ptrdiff_type_node)
- == TYPE_PRECISION (TREE_TYPE (lhs))))
- {
- tree type = TREE_TYPE (lhs);
- tree max = vrp_val_max (ptrdiff_type_node);
- wide_int wmax = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max)));
- tree range_min = build_zero_cst (type);
- /* To account for the terminating NUL, the maximum length
- is one less than the maximum array size, which in turn
- is one less than PTRDIFF_MAX (or SIZE_MAX where it's
- smaller than the former type).
- FIXME: Use max_object_size() - 1 here. */
- tree range_max = wide_int_to_tree (type, wmax - 2);
- vr->set (range_min, range_max);
- return true;
- }
- break;
default:
break;
}
@@ -1430,20 +1217,27 @@ vr_values::extract_range_basic (value_range_equiv *vr, gimple *stmt)
bool sop;
tree type = gimple_expr_type (stmt);
- if (is_gimple_call (stmt) && extract_range_builtin (vr, stmt))
+ if (is_gimple_call (stmt))
{
combined_fn cfn = gimple_call_combined_fn (stmt);
- if (cfn == CFN_UBSAN_CHECK_ADD
- || cfn == CFN_UBSAN_CHECK_SUB
- || cfn == CFN_UBSAN_CHECK_MUL)
- return;
-
- value_range_equiv tmp;
- /* Assert that any ranges vr_values::extract_range_builtin gets
- are also handled by the ranger counterpart. */
- gcc_assert (range_of_builtin_call (*this, tmp, as_a<gcall *> (stmt)));
- gcc_assert (tmp.equal_p (*vr, /*ignore_equivs=*/false));
- return;
+ switch (cfn)
+ {
+ case CFN_UBSAN_CHECK_ADD:
+ case CFN_UBSAN_CHECK_SUB:
+ case CFN_UBSAN_CHECK_MUL:
+ if (extract_range_from_ubsan_builtin (vr, stmt))
+ return;
+ break;
+ default:
+ if (range_of_builtin_call (*this, *vr, as_a<gcall *> (stmt)))
+ {
+ /* The original code nuked equivalences every time a
+ range was found, so do the same here. */
+ vr->equiv_clear ();
+ return;
+ }
+ break;
+ }
}
/* Handle extraction of the two results (result of arithmetics and
a flag whether arithmetics overflowed) from {ADD,SUB,MUL}_OVERFLOW
diff --git a/gcc/vr-values.h b/gcc/vr-values.h
index 59fac0c..712d029 100644
--- a/gcc/vr-values.h
+++ b/gcc/vr-values.h
@@ -148,7 +148,7 @@ class vr_values : public range_query
void extract_range_from_comparison (value_range_equiv *, gimple *);
void vrp_visit_assignment_or_call (gimple*, tree *, value_range_equiv *);
void vrp_visit_switch_stmt (gswitch *, edge *);
- bool extract_range_builtin (value_range_equiv *, gimple *);
+ bool extract_range_from_ubsan_builtin (value_range_equiv *, gimple *);
/* This probably belongs in the lattice rather than in here. */
bool values_propagated;
diff --git a/libatomic/ChangeLog b/libatomic/ChangeLog
index b78355f..b30c2eb 100644
--- a/libatomic/ChangeLog
+++ b/libatomic/ChangeLog
@@ -1,3 +1,7 @@
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ * configure: Regenerate.
+
2020-10-11 Clement Chigot <clement.chigot@atos.net>
* config/t-aix: Delete and recreate libatomic before creating
diff --git a/libatomic/configure b/libatomic/configure
index 2acaffe..5fd4ea3 100755
--- a/libatomic/configure
+++ b/libatomic/configure
@@ -9672,7 +9672,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -9684,7 +9684,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog
index 528b2b0..a4de7ba 100644
--- a/libbacktrace/ChangeLog
+++ b/libbacktrace/ChangeLog
@@ -1,3 +1,13 @@
+2020-12-02 Ian Lance Taylor <iant@golang.org>
+
+ * dwarf.c (resolve_string): Use > rather than >= to check whether
+ string index extends past buffer.
+ (resolve_addr_index): Similarly for address index.
+
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ * configure: Regenerate.
+
2020-10-20 Ian Lance Taylor <iant@golang.org>
* internal.h (ATTRIBUTE_FALLTHROUGH): Define.
diff --git a/libbacktrace/configure b/libbacktrace/configure
index 8c8c34d..79324b5 100755
--- a/libbacktrace/configure
+++ b/libbacktrace/configure
@@ -9801,7 +9801,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -9813,7 +9813,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index 582f34b..0c913c9 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -1053,7 +1053,7 @@ resolve_string (const struct dwarf_sections *dwarf_sections, int is_dwarf64,
offset = val->u.uint * (is_dwarf64 ? 8 : 4) + str_offsets_base;
if (offset + (is_dwarf64 ? 8 : 4)
- >= dwarf_sections->size[DEBUG_STR_OFFSETS])
+ > dwarf_sections->size[DEBUG_STR_OFFSETS])
{
error_callback (data, "DW_FORM_strx value out of range", 0);
return 0;
@@ -1097,7 +1097,7 @@ resolve_addr_index (const struct dwarf_sections *dwarf_sections,
struct dwarf_buf addr_buf;
offset = addr_index * addrsize + addr_base;
- if (offset + addrsize >= dwarf_sections->size[DEBUG_ADDR])
+ if (offset + addrsize > dwarf_sections->size[DEBUG_ADDR])
{
error_callback (data, "DW_FORM_addrx value out of range", 0);
return 0;
diff --git a/libcc1/ChangeLog b/libcc1/ChangeLog
index 696635e..1611f73 100644
--- a/libcc1/ChangeLog
+++ b/libcc1/ChangeLog
@@ -1,3 +1,19 @@
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ * configure: Regenerate.
+
+2020-11-11 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/88115
+ * libcp1plugin.cc (plugin_build_unary_expr): Pass true to
+ cxx_sizeof_or_alignof_expr.
+
+2020-11-10 Marek Polacek <polacek@redhat.com>
+
+ PR c++/97518
+ * libcp1plugin.cc (plugin_add_static_assert): Pass false to
+ finish_static_assert.
+
2020-11-06 Nathan Sidwell <nathan@acm.org>
* libcc1plugin.cc (address_rewriter): Rename
diff --git a/libcc1/configure b/libcc1/configure
index 3610219..4e2ca41 100755
--- a/libcc1/configure
+++ b/libcc1/configure
@@ -9067,7 +9067,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -9079,7 +9079,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -12317,7 +12317,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
aCC*)
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
@@ -12341,7 +12341,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test $with_gnu_ld = no; then
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc
index bab2751..6483683 100644
--- a/libcc1/libcp1plugin.cc
+++ b/libcc1/libcp1plugin.cc
@@ -2806,7 +2806,7 @@ plugin_build_unary_expr (cc1_plugin::connection *self,
case SIZEOF_EXPR:
case ALIGNOF_EXPR:
result = cxx_sizeof_or_alignof_expr (input_location,
- op0, opcode, true);
+ op0, opcode, true, true);
break;
case DELETE_EXPR:
@@ -3642,7 +3642,7 @@ plugin_add_static_assert (cc1_plugin::connection *self,
bool member_p = at_class_scope_p ();
- finish_static_assert (condition, message, loc, member_p);
+ finish_static_assert (condition, message, loc, member_p, false);
return 1;
}
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index a84169e..83cbde3 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,173 @@
+2020-12-01 JeanHeyd Meneide <phdofthehouse@gmail.com>
+
+ * charset.c (init_iconv_desc): Initialize "to" and "from" fields.
+ * directives.c (cpp_get_narrow_charset_name): New function.
+ (cpp_get_wide_charset_name): Likewise.
+ * include/cpplib.h (cpp_get_narrow_charset_name): Prototype.
+ (cpp_get_wide_charset_name): Likewise.
+ * internal.h (cset_converter): Add "to" and "from" fields.
+
+2020-11-27 Joseph Myers <joseph@codesourcery.com>
+
+ PR preprocessor/97602
+ * directives.c (strtolinenum): Check for overflow before it
+ occurs. Correct comment.
+
+2020-11-24 Nathan Sidwell <nathan@acm.org>
+
+ * include/cpplib.h (struct cpp_hashnode): Add deferred field.
+ (cpp_set_deferred_macro): Define.
+ (cpp_get_deferred_macro): Declare.
+ (cpp_macro_definition): Reformat, add overload.
+ (cpp_macro_definition_location): Deal with deferred macro.
+ (cpp_alloc_token_string, cpp_compare_macro): Declare.
+ * internal.h (_cpp_notify_macro_use): Return bool
+ (_cpp_maybe_notify_macro_use): Likewise.
+ * directives.c (do_undef): Check macro is not undef before
+ warning.
+ (do_ifdef, do_ifndef): Deal with deferred macro.
+ * expr.c (parse_defined): Likewise.
+ * lex.c (cpp_allocate_token_string): Break out of ...
+ (create_literal): ... here. Call it.
+ (cpp_maybe_module_directive): Deal with deferred macro.
+ * macro.c (cpp_get_token_1): Deal with deferred macro.
+ (warn_of_redefinition): Deal with deferred macro.
+ (compare_macros): Rename to ...
+ (cpp_compare_macro): ... here. Make extern.
+ (cpp_get_deferred_macro): New.
+ (_cpp_notify_macro_use): Deal with deferred macro, return bool
+ indicating definedness.
+ (cpp_macro_definition): Deal with deferred macro.
+
+2020-11-19 Nathan Sidwell <nathan@acm.org>
+
+ * include/cpplib.h (enum cpp_main_search): New.
+ (struct cpp_options): Add main_search field.
+ (cpp_main_loc): Declare.
+ (cpp_retrofit_as_include): Declare.
+ * internal.h (struct cpp_reader): Add main_loc field.
+ (_cpp_in_main_source_file): Not main if main is a header.
+ * init.c (cpp_read_main_file): Use main_search option to locate
+ main file. Set main_loc
+ * files.c (cpp_retrofit_as_include): New.
+
+2020-11-19 Nathan Sidwell <nathan@acm.org>
+
+ * internal.h (cpp_in_system_header): Rename to ...
+ (_cpp_in_system_header): ... here.
+ (cpp_in_primary_file): Rename to ...
+ (_cpp_in_main_source_file): ... here. Compare main_file equality
+ and check main_search value.
+ * lex.c (maybe_va_opt_error, _cpp_lex_direct): Adjust for rename.
+ * macro.c (_cpp_builtin_macro_text): Likewise.
+ (replace_args): Likewise.
+ * directives.c (do_include_next): Likewise.
+ (do_pragma_once, do_pragma_system_header): Likewise.
+ * files.c (struct _cpp_file): Delete main_file field.
+ (pch_open): Check pfile->main_file equality.
+ (make_cpp_file): Drop cpp_reader parm, don't set main_file.
+ (_cpp_find_file): Adjust.
+ (_cpp_stack_file): Check pfile->main_file equality.
+ (struct report_missing_guard_data): Add cpp_reader field.
+ (report_missing_guard): Check pfile->main_file equality.
+ (_cpp_report_missing_guards): Adjust.
+
+2020-11-18 Nathan Sidwell <nathan@acm.org>
+
+ * include/cpplib.h (struct cpp_options): Add module_directives
+ option.
+ (NODE_MODULE): New node flag.
+ (struct cpp_hashnode): Make rid-code a bitfield, increase bits in
+ flags and swap with type field.
+ * init.c (post_options): Create module-directive identifier nodes.
+ * internal.h (struct lexer_state): Add directive_file_token &
+ n_modules fields. Add module node enumerator.
+ * lex.c (cpp_maybe_module_directive): New.
+ (_cpp_lex_token): Call it.
+ (cpp_output_token): Add '"' around CPP_HEADER_NAME token.
+ (do_peek_ident, do_peek_module): New.
+ (cpp_directives_only): Detect module-directive lines.
+ * macro.c (cpp_get_token_1): Deal with directive_file_token
+ triggering.
+
+2020-11-18 Nathan Sidwell <nathan@acm.org>
+
+ * files.c (struct _cpp_file): Add header_unit field.
+ (_cpp_stack_file): Add header unit support.
+ (cpp_find_header_unit): New.
+ * include/cpplib.h (cpp_find_header_unit): Declare.
+
+2020-11-18 Nathan Sidwell <nathan@acm.org>
+
+ * include/cpplib.h (struct cpp_options): Add modules to
+ dep-options.
+ * include/mkdeps.h (deps_add_module_target): Declare.
+ (deps_add_module_dep): Declare.
+ * mkdeps.c (class mkdeps): Add modules, module_name, cmi_name,
+ is_header_unit fields. Adjust cdtors.
+ (deps_add_module_target, deps_add_module_dep): New.
+ (make_write): Write module dependencies, if enabled.
+
+2020-11-17 Nathan Sidwell <nathan@acm.org>
+
+ * include/cpplib.h (struct cpp_callbacks): Add
+ user_deferred_macro & translate_include.
+
+2020-11-17 Nathan Sidwell <nathan@acm.org>
+
+ * include/line-map.h (enum lc_reason): Add LC_MODULE.
+ (MAP_MODULE_P): New.
+ (line_map_new_raw): Declare.
+ (linemap_enter_macro): Move declaration from internal.h
+ (linemap_module_loc, linemap_module_reparent)
+ (linemap_module_restore): Declare.
+ (linemap_lookup_macro_indec): Declare.
+ * internal.h (linemap_enter_macro): Moved to line-map.h.
+ * line-map.c (linemap_new_raw): New, broken out of ...
+ (new_linemap): ... here. Call it.
+ (LAST_SOURCE_LINE_LOCATION): New.
+ (liemap_module_loc, linemap_module_reparent)
+ (linemap_module_restore): New.
+ (linemap_lookup_macro_index): New, broken out of ...
+ (linemap_macro_map_lookup): ... here. Call it.
+ (linemap_dump): Add module dump.
+
+2020-11-17 Nathan Sidwell <nathan@acm.org>
+
+ PR preprocessor/97858
+ * mkdeps.c (munge): Drop varadic args, we only ever use one.
+
+2020-11-13 Joseph Myers <joseph@codesourcery.com>
+
+ * expr.c (cpp_classify_number): Update diagnostic for binary
+ constants for C. Also diagnose binary constants for
+ -Wc11-c2x-compat.
+ * init.c (lang_defaults): Enable binary constants for GNUC2X and
+ STDC2X.
+
+2020-11-13 Piotr H. Dabrowski <phd@phd.re>
+
+ PR c++/91318
+ * include/cpplib.h: Added cpp_define_unused(), cpp_define_formatted_unused()
+ * directives.c: Likewise.
+
+2020-11-12 Joseph Myers <joseph@codesourcery.com>
+
+ * include/cpplib.h (struct cpp_callbacks): Add bool argument to
+ has_attribute.
+ (enum cpp_builtin_type): Add BT_HAS_STD_ATTRIBUTE.
+ * init.c (builtin_array): Add __has_c_attribute.
+ (cpp_init_special_builtins): Handle BT_HAS_STD_ATTRIBUTE.
+ * macro.c (_cpp_builtin_macro_text): Handle BT_HAS_STD_ATTRIBUTE.
+ Update call to has_attribute for BT_HAS_ATTRIBUTE.
+ * traditional.c (fun_like_macro): Handle BT_HAS_STD_ATTRIBUTE.
+
+2020-11-12 Nicholas Guriev <guriev-ns@ya.ru>
+
+ PR pch/86674
+ * files.c (_cpp_find_file): Use CPP_DL_NOTE not CPP_DL_ERROR in call to
+ cpp_error.
+
2020-11-07 Lewis Hyatt <lhyatt@gmail.com>
* generated_cpp_wcwidth.h: Regenerated from Unicode 13.0.0 data.
diff --git a/libcpp/charset.c b/libcpp/charset.c
index 28b81c9c..3e5578b 100644
--- a/libcpp/charset.c
+++ b/libcpp/charset.c
@@ -638,6 +638,9 @@ init_iconv_desc (cpp_reader *pfile, const char *to, const char *from)
char *pair;
size_t i;
+ ret.to = to;
+ ret.from = from;
+
if (!strcasecmp (to, from))
{
ret.func = convert_no_conversion;
diff --git a/libcpp/directives.c b/libcpp/directives.c
index 4295a67..0d09da7 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -667,7 +667,8 @@ do_undef (cpp_reader *pfile)
pfile->directive_line, 0,
"undefining \"%s\"", NODE_NAME (node));
- if (CPP_OPTION (pfile, warn_unused_macros))
+ if (node->value.macro
+ && CPP_OPTION (pfile, warn_unused_macros))
_cpp_warn_if_unused_macro (pfile, node, NULL);
_cpp_free_definition (node);
@@ -877,7 +878,7 @@ do_include_next (cpp_reader *pfile)
/* If this is the primary source file, warn and use the normal
search logic. */
- if (cpp_in_primary_file (pfile))
+ if (_cpp_in_main_source_file (pfile))
{
cpp_error (pfile, CPP_DL_WARNING,
"#include_next in primary source file");
@@ -914,12 +915,11 @@ read_flag (cpp_reader *pfile, unsigned int last)
/* Subroutine of do_line and do_linemarker. Convert a number in STR,
of length LEN, to binary; store it in NUMP, and return false if the
number was well-formed, true if not. WRAPPED is set to true if the
- number did not fit into 'unsigned long'. */
+ number did not fit into 'linenum_type'. */
static bool
strtolinenum (const uchar *str, size_t len, linenum_type *nump, bool *wrapped)
{
linenum_type reg = 0;
- linenum_type reg_prev = 0;
uchar c;
*wrapped = false;
@@ -928,11 +928,12 @@ strtolinenum (const uchar *str, size_t len, linenum_type *nump, bool *wrapped)
c = *str++;
if (!ISDIGIT (c))
return true;
+ if (reg > ((linenum_type) -1) / 10)
+ *wrapped = true;
reg *= 10;
- reg += c - '0';
- if (reg < reg_prev)
+ if (reg > ((linenum_type) -1) - (c - '0'))
*wrapped = true;
- reg_prev = reg;
+ reg += c - '0';
}
*nump = reg;
return false;
@@ -1546,7 +1547,7 @@ do_pragma (cpp_reader *pfile)
static void
do_pragma_once (cpp_reader *pfile)
{
- if (cpp_in_primary_file (pfile))
+ if (_cpp_in_main_source_file (pfile))
cpp_error (pfile, CPP_DL_WARNING, "#pragma once in main file");
check_eol (pfile, false);
@@ -1708,7 +1709,7 @@ do_pragma_poison (cpp_reader *pfile)
static void
do_pragma_system_header (cpp_reader *pfile)
{
- if (cpp_in_primary_file (pfile))
+ if (_cpp_in_main_source_file (pfile))
cpp_error (pfile, CPP_DL_WARNING,
"#pragma system_header ignored outside include file");
else
@@ -1981,8 +1982,10 @@ do_ifdef (cpp_reader *pfile)
if (node)
{
skip = !_cpp_defined_macro_p (node);
+ if (!_cpp_maybe_notify_macro_use (pfile, node, pfile->directive_line))
+ /* It wasn't a macro after all. */
+ skip = true;
_cpp_mark_macro_used (node);
- _cpp_maybe_notify_macro_use (pfile, node, pfile->directive_line);
if (pfile->cb.used)
pfile->cb.used (pfile, pfile->directive_line, node);
check_eol (pfile, false);
@@ -2006,8 +2009,10 @@ do_ifndef (cpp_reader *pfile)
if (node)
{
skip = _cpp_defined_macro_p (node);
+ if (!_cpp_maybe_notify_macro_use (pfile, node, pfile->directive_line))
+ /* It wasn't a macro after all. */
+ skip = false;
_cpp_mark_macro_used (node);
- _cpp_maybe_notify_macro_use (pfile, node, pfile->directive_line);
if (pfile->cb.used)
pfile->cb.used (pfile, pfile->directive_line, node);
check_eol (pfile, false);
@@ -2412,6 +2417,15 @@ cpp_define (cpp_reader *pfile, const char *str)
run_directive (pfile, T_DEFINE, buf, count);
}
+/* Like cpp_define, but does not warn about unused macro. */
+void
+cpp_define_unused (cpp_reader *pfile, const char *str)
+{
+ unsigned char warn_unused_macros = CPP_OPTION (pfile, warn_unused_macros);
+ CPP_OPTION (pfile, warn_unused_macros) = 0;
+ cpp_define (pfile, str);
+ CPP_OPTION (pfile, warn_unused_macros) = warn_unused_macros;
+}
/* Use to build macros to be run through cpp_define() as
described above.
@@ -2431,6 +2445,20 @@ cpp_define_formatted (cpp_reader *pfile, const char *fmt, ...)
free (ptr);
}
+/* Like cpp_define_formatted, but does not warn about unused macro. */
+void
+cpp_define_formatted_unused (cpp_reader *pfile, const char *fmt, ...)
+{
+ char *ptr;
+
+ va_list ap;
+ va_start (ap, fmt);
+ ptr = xvasprintf (fmt, ap);
+ va_end (ap);
+
+ cpp_define_unused (pfile, ptr);
+ free (ptr);
+}
/* Slight variant of the above for use by initialize_builtins. */
void
@@ -2568,6 +2596,20 @@ cpp_set_callbacks (cpp_reader *pfile, cpp_callbacks *cb)
pfile->cb = *cb;
}
+/* The narrow character set identifier. */
+const char *
+cpp_get_narrow_charset_name (cpp_reader *pfile)
+{
+ return pfile->narrow_cset_desc.to;
+}
+
+/* The wide character set identifier. */
+const char *
+cpp_get_wide_charset_name (cpp_reader *pfile)
+{
+ return pfile->wide_cset_desc.to;
+}
+
/* The dependencies structure. (Creates one if it hasn't already been.) */
class mkdeps *
cpp_get_deps (cpp_reader *pfile)
diff --git a/libcpp/expr.c b/libcpp/expr.c
index e01a47a..2ba7726 100644
--- a/libcpp/expr.c
+++ b/libcpp/expr.c
@@ -812,14 +812,21 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token,
if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile))
cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
"imaginary constants are a GCC extension");
- if (radix == 2
- && !CPP_OPTION (pfile, binary_constants)
- && CPP_PEDANTIC (pfile))
- cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
- CPP_OPTION (pfile, cplusplus)
- ? N_("binary constants are a C++14 feature "
- "or GCC extension")
- : N_("binary constants are a GCC extension"));
+ if (radix == 2)
+ {
+ if (!CPP_OPTION (pfile, binary_constants)
+ && CPP_PEDANTIC (pfile))
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
+ CPP_OPTION (pfile, cplusplus)
+ ? N_("binary constants are a C++14 feature "
+ "or GCC extension")
+ : N_("binary constants are a C2X feature "
+ "or GCC extension"));
+ else if (CPP_OPTION (pfile, cpp_warn_c11_c2x_compat) > 0)
+ cpp_warning_with_line (pfile, CPP_W_C11_C2X_COMPAT,
+ virtual_location, 0,
+ "binary constants are a C2X feature");
+ }
if (radix == 10)
result |= CPP_N_DECIMAL;
@@ -1061,6 +1068,7 @@ parse_defined (cpp_reader *pfile)
}
}
+ bool is_defined = false;
if (node)
{
if ((pfile->context != initial_context
@@ -1068,9 +1076,11 @@ parse_defined (cpp_reader *pfile)
&& CPP_OPTION (pfile, warn_expansion_to_defined))
cpp_pedwarning (pfile, CPP_W_EXPANSION_TO_DEFINED,
"this use of \"defined\" may not be portable");
-
+ is_defined = _cpp_defined_macro_p (node);
+ if (!_cpp_maybe_notify_macro_use (pfile, node, token->src_loc))
+ /* It wasn't a macro after all. */
+ is_defined = false;
_cpp_mark_macro_used (node);
- _cpp_maybe_notify_macro_use (pfile, node, token->src_loc);
/* A possible controlling macro of the form #if !defined ().
_cpp_parse_expr checks there was no other junk on the line. */
@@ -1086,7 +1096,7 @@ parse_defined (cpp_reader *pfile)
result.unsignedp = false;
result.high = 0;
result.overflow = false;
- result.low = node && _cpp_defined_macro_p (node);
+ result.low = is_defined;
return result;
}
diff --git a/libcpp/files.c b/libcpp/files.c
index 5af4136..301b237 100644
--- a/libcpp/files.c
+++ b/libcpp/files.c
@@ -103,14 +103,14 @@ struct _cpp_file
/* If read() failed before. */
bool dont_read : 1;
- /* If this file is the main file. */
- bool main_file : 1;
-
/* If BUFFER above contains the true contents of the file. */
bool buffer_valid : 1;
/* If this file is implicitly preincluded. */
bool implicit_preinclude : 1;
+
+ /* > 0: Known C++ Module header unit, <0: known not. ==0, unknown */
+ int header_unit : 2;
};
/* A singly-linked list for all searches for a given file name, with
@@ -183,7 +183,7 @@ static void open_file_failed (cpp_reader *pfile, _cpp_file *file, int,
location_t);
static struct cpp_file_hash_entry *search_cache (struct cpp_file_hash_entry *head,
const cpp_dir *start_dir);
-static _cpp_file *make_cpp_file (cpp_reader *, cpp_dir *, const char *fname);
+static _cpp_file *make_cpp_file (cpp_dir *, const char *fname);
static void destroy_cpp_file (_cpp_file *);
static cpp_dir *make_cpp_dir (cpp_reader *, const char *dir_name, int sysp);
static void allocate_file_hash_entries (cpp_reader *pfile);
@@ -296,7 +296,7 @@ pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
for (_cpp_file *f = pfile->all_files; f; f = f->next_file)
if (f->implicit_preinclude)
continue;
- else if (f->main_file)
+ else if (pfile->main_file == f)
break;
else
return false;
@@ -525,7 +525,7 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir,
if (entry)
return entry->u.file;
- _cpp_file *file = make_cpp_file (pfile, start_dir, fname);
+ _cpp_file *file = make_cpp_file (start_dir, fname);
file->implicit_preinclude
= (kind == _cpp_FFK_PRE_INCLUDE
|| (pfile->buffer && pfile->buffer->file->implicit_preinclude));
@@ -571,7 +571,7 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir,
"one or more PCH files were found,"
" but they were invalid");
if (!cpp_get_options (pfile)->warn_invalid_pch)
- cpp_error (pfile, CPP_DL_ERROR,
+ cpp_error (pfile, CPP_DL_NOTE,
"use -Winvalid-pch for more information");
}
@@ -862,7 +862,7 @@ has_unique_contents (cpp_reader *pfile, _cpp_file *file, bool import,
{
/* We already have a buffer but it is not valid, because
the file is still stacked. Make a new one. */
- ref_file = make_cpp_file (pfile, f->dir, f->name);
+ ref_file = make_cpp_file (f->dir, f->name);
ref_file->path = f->path;
}
else
@@ -891,9 +891,9 @@ has_unique_contents (cpp_reader *pfile, _cpp_file *file, bool import,
}
/* Place the file referenced by FILE into a new buffer on the buffer
- stack if possible. IMPORT is true if this stacking attempt is
- because of a #import directive. Returns true if a buffer is
- stacked. Use LOC for any diagnostics. */
+ stack if possible. Returns true if a buffer is stacked. Use LOC
+ for any diagnostics. */
+
bool
_cpp_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type,
location_t loc)
@@ -901,39 +901,74 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type,
if (is_known_idempotent_file (pfile, file, type == IT_IMPORT))
return false;
- if (!read_file (pfile, file, loc))
- return false;
-
- if (!has_unique_contents (pfile, file, type == IT_IMPORT, loc))
- return false;
-
int sysp = 0;
- if (pfile->buffer && file->dir)
- sysp = MAX (pfile->buffer->sysp, file->dir->sysp);
-
- /* Add the file to the dependencies on its first inclusion. */
- if (CPP_OPTION (pfile, deps.style) > (sysp != 0)
- && !file->stack_count
- && file->path[0]
- && !(file->main_file && CPP_OPTION (pfile, deps.ignore_main_file)))
- deps_add_dep (pfile->deps, file->path);
-
- /* Clear buffer_valid since _cpp_clean_line messes it up. */
- file->buffer_valid = false;
- file->stack_count++;
-
- /* Stack the buffer. */
- cpp_buffer *buffer
- = cpp_push_buffer (pfile, file->buffer, file->st.st_size,
- CPP_OPTION (pfile, preprocessed)
- && !CPP_OPTION (pfile, directives_only));
- buffer->file = file;
- buffer->sysp = sysp;
- buffer->to_free = file->buffer_start;
+ char *buf = nullptr;
- /* Initialize controlling macro state. */
- pfile->mi_valid = true;
- pfile->mi_cmacro = 0;
+ /* Check C++ module include translation. */
+ if (!file->header_unit && type < IT_HEADER_HWM
+ /* Do not include translate include-next. */
+ && type != IT_INCLUDE_NEXT
+ && pfile->cb.translate_include)
+ buf = (pfile->cb.translate_include
+ (pfile, pfile->line_table, loc, file->path));
+
+ if (buf)
+ {
+ /* We don't increment the line number at the end of a buffer,
+ because we don't usually need that location (we're popping an
+ include file). However in this case we do want to do the
+ increment. So push a writable buffer of two newlines to acheive
+ that. */
+ static uchar newlines[] = "\n\n";
+ cpp_push_buffer (pfile, newlines, 2, true);
+
+ cpp_buffer *buffer
+ = cpp_push_buffer (pfile, reinterpret_cast<unsigned char *> (buf),
+ strlen (buf), true);
+ buffer->to_free = buffer->buf;
+
+ file->header_unit = +1;
+ _cpp_mark_file_once_only (pfile, file);
+ }
+ else
+ {
+ /* Not a header unit, and we know it. */
+ file->header_unit = -1;
+
+ if (!read_file (pfile, file, loc))
+ return false;
+
+ if (!has_unique_contents (pfile, file, type == IT_IMPORT, loc))
+ return false;
+
+ if (pfile->buffer && file->dir)
+ sysp = MAX (pfile->buffer->sysp, file->dir->sysp);
+
+ /* Add the file to the dependencies on its first inclusion. */
+ if (CPP_OPTION (pfile, deps.style) > (sysp != 0)
+ && !file->stack_count
+ && file->path[0]
+ && !(pfile->main_file == file
+ && CPP_OPTION (pfile, deps.ignore_main_file)))
+ deps_add_dep (pfile->deps, file->path);
+
+ /* Clear buffer_valid since _cpp_clean_line messes it up. */
+ file->buffer_valid = false;
+ file->stack_count++;
+
+ /* Stack the buffer. */
+ cpp_buffer *buffer
+ = cpp_push_buffer (pfile, file->buffer, file->st.st_size,
+ CPP_OPTION (pfile, preprocessed)
+ && !CPP_OPTION (pfile, directives_only));
+ buffer->file = file;
+ buffer->sysp = sysp;
+ buffer->to_free = file->buffer_start;
+
+ /* Initialize controlling macro state. */
+ pfile->mi_valid = true;
+ pfile->mi_cmacro = 0;
+ }
/* In the case of a normal #include, we're now at the start of the
line *following* the #include. A separate location_t for this
@@ -941,19 +976,30 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type,
This does not apply if we found a PCH file, we're not a regular
include, or we ran out of locations. */
- if (file->pchname == NULL
- && type < IT_DIRECTIVE_HWM
- && pfile->line_table->highest_location != LINE_MAP_MAX_LOCATION - 1)
+ bool decrement = (file->pchname == NULL
+ && type < IT_DIRECTIVE_HWM
+ && (pfile->line_table->highest_location
+ != LINE_MAP_MAX_LOCATION - 1));
+ if (decrement)
pfile->line_table->highest_location--;
- /* Add line map and do callbacks. */
- _cpp_do_file_change (pfile, LC_ENTER, file->path,
+ if (file->header_unit <= 0)
+ /* Add line map and do callbacks. */
+ _cpp_do_file_change (pfile, LC_ENTER, file->path,
/* With preamble injection, start on line zero,
so the preamble doesn't appear to have been
included from line 1. Likewise when
starting preprocessed, we expect an initial
locating line. */
- type == IT_PRE_MAIN ? 0 : 1, sysp);
+ type == IT_PRE_MAIN ? 0 : 1, sysp);
+ else if (decrement)
+ {
+ /* Adjust the line back one so we appear on the #include line itself. */
+ const line_map_ordinary *map
+ = LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table);
+ linenum_type line = SOURCE_LINE (map, pfile->line_table->highest_line);
+ linemap_line_start (pfile->line_table, line - 1, 0);
+ }
return true;
}
@@ -1058,6 +1104,64 @@ _cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets,
return _cpp_stack_file (pfile, file, type, loc);
}
+/* NAME is a header file name, find the path we'll use to open it. */
+
+const char *
+cpp_find_header_unit (cpp_reader *pfile, const char *name, bool angle,
+ location_t loc)
+{
+ cpp_dir *dir = search_path_head (pfile, name, angle, IT_INCLUDE);
+ if (!dir)
+ return NULL;
+
+ _cpp_file *file = _cpp_find_file (pfile, name, dir, angle,
+ _cpp_FFK_NORMAL, loc);
+ if (!file)
+ return NULL;
+
+ if (file->fd > 0)
+ {
+ /* Don't leave it open. */
+ close (file->fd);
+ file->fd = 0;
+ }
+
+ file->header_unit = +1;
+ _cpp_mark_file_once_only (pfile, file);
+ return file->path;
+}
+
+/* Retrofit the just-entered main file asif it was an include. This
+ will permit correct include_next use, and mark it as a system
+ header if that's where it resides. We use filesystem-appropriate
+ prefix matching of the include path to locate the main file. */
+void
+cpp_retrofit_as_include (cpp_reader *pfile)
+{
+ /* We should be the outermost. */
+ gcc_assert (!pfile->buffer->prev);
+
+ if (const char *name = pfile->main_file->name)
+ {
+ /* Locate name on the include dir path, using a prefix match. */
+ size_t name_len = strlen (name);
+ for (cpp_dir *dir = pfile->quote_include; dir; dir = dir->next)
+ if (dir->len < name_len
+ && IS_DIR_SEPARATOR (name[dir->len])
+ && !filename_ncmp (name, dir->name, dir->len))
+ {
+ pfile->main_file->dir = dir;
+ if (dir->sysp)
+ cpp_make_system_header (pfile, 1, 0);
+ break;
+ }
+ }
+
+ /* Initialize controlling macro state. */
+ pfile->mi_valid = true;
+ pfile->mi_cmacro = 0;
+}
+
/* Could not open FILE. The complication is dependency output. */
static void
open_file_failed (cpp_reader *pfile, _cpp_file *file, int angle_brackets,
@@ -1112,12 +1216,9 @@ search_cache (struct cpp_file_hash_entry *head, const cpp_dir *start_dir)
/* Allocate a new _cpp_file structure. */
static _cpp_file *
-make_cpp_file (cpp_reader *pfile, cpp_dir *dir, const char *fname)
+make_cpp_file (cpp_dir *dir, const char *fname)
{
- _cpp_file *file;
-
- file = XCNEW (_cpp_file);
- file->main_file = !pfile->buffer;
+ _cpp_file *file = XCNEW (_cpp_file);
file->fd = -1;
file->dir = dir;
file->name = xstrdup (fname);
@@ -1377,6 +1478,7 @@ cpp_change_file (cpp_reader *pfile, enum lc_reason reason,
struct report_missing_guard_data
{
+ cpp_reader *pfile;
const char **paths;
size_t count;
};
@@ -1395,8 +1497,10 @@ report_missing_guard (void **slot, void *d)
_cpp_file *file = entry->u.file;
/* We don't want MI guard advice for the main file. */
- if (!file->once_only && file->cmacro == NULL
- && file->stack_count == 1 && !file->main_file)
+ if (!file->once_only
+ && file->cmacro == NULL
+ && file->stack_count == 1
+ && data->pfile->main_file != file)
{
if (data->paths == NULL)
{
@@ -1426,6 +1530,7 @@ _cpp_report_missing_guards (cpp_reader *pfile)
{
struct report_missing_guard_data data;
+ data.pfile = pfile;
data.paths = NULL;
data.count = htab_elements (pfile->file_hash);
htab_traverse (pfile->file_hash, report_missing_guard, &data);
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index c4d7cc5..692aee5 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -308,6 +308,15 @@ enum cpp_normalize_level {
normalized_none
};
+enum cpp_main_search
+{
+ CMS_none, /* A regular source file. */
+ CMS_header, /* Is a directly-specified header file (eg PCH or
+ header-unit). */
+ CMS_user, /* Search the user INCLUDE path. */
+ CMS_system, /* Search the system INCLUDE path. */
+};
+
/* This structure is nested inside struct cpp_reader, and
carries all the options visible to the command line. */
struct cpp_options
@@ -487,6 +496,9 @@ struct cpp_options
/* Nonzero for the '::' token. */
unsigned char scope;
+ /* Nonzero means tokenize C++20 module directives. */
+ unsigned char module_directives;
+
/* Holds the name of the target (execution) character set. */
const char *narrow_charset;
@@ -528,6 +540,9 @@ struct cpp_options
one. */
bool phony_targets;
+ /* Generate dependency info for modules. */
+ bool modules;
+
/* If true, no dependency is generated on the main file. */
bool ignore_main_file;
@@ -560,6 +575,8 @@ struct cpp_options
/* The maximum depth of the nested #include. */
unsigned int max_include_depth;
+
+ cpp_main_search main_search : 8;
};
/* Diagnostic levels. To get a diagnostic without associating a
@@ -672,7 +689,7 @@ struct cpp_callbacks
void (*used) (cpp_reader *, location_t, cpp_hashnode *);
/* Callback to identify whether an attribute exists. */
- int (*has_attribute) (cpp_reader *);
+ int (*has_attribute) (cpp_reader *, bool);
/* Callback to determine whether a built-in function is recognized. */
int (*has_builtin) (cpp_reader *);
@@ -680,6 +697,9 @@ struct cpp_callbacks
/* Callback that can change a user lazy into normal macro. */
void (*user_lazy_macro) (cpp_reader *, cpp_macro *, unsigned);
+ /* Callback to handle deferred cpp_macros. */
+ cpp_macro *(*user_deferred_macro) (cpp_reader *, location_t, cpp_hashnode *);
+
/* Callback to parse SOURCE_DATE_EPOCH from environment. */
time_t (*get_source_date_epoch) (cpp_reader *);
@@ -698,6 +718,11 @@ struct cpp_callbacks
/* Callback for filename remapping in __FILE__ and __BASE_FILE__ macro
expansions. */
const char *(*remap_filename) (const char*);
+
+ /* Maybe translate a #include into something else. Return a
+ cpp_buffer containing the translation if translating. */
+ char *(*translate_include) (cpp_reader *, line_maps *, location_t,
+ const char *path);
};
#ifdef VMS
@@ -831,6 +856,7 @@ struct GTY(()) cpp_macro {
#define NODE_USED (1 << 5) /* Dumped with -dU. */
#define NODE_CONDITIONAL (1 << 6) /* Conditional macro */
#define NODE_WARN_OPERATOR (1 << 7) /* Warn about C++ named operator. */
+#define NODE_MODULE (1 << 8) /* C++-20 module-related name. */
/* Different flavors of hash node. */
enum node_type
@@ -857,6 +883,7 @@ enum cpp_builtin_type
BT_TIMESTAMP, /* `__TIMESTAMP__' */
BT_COUNTER, /* `__COUNTER__' */
BT_HAS_ATTRIBUTE, /* `__has_attribute(x)' */
+ BT_HAS_STD_ATTRIBUTE, /* `__has_c_attribute(x)' */
BT_HAS_BUILTIN, /* `__has_builtin(x)' */
BT_HAS_INCLUDE, /* `__has_include(x)' */
BT_HAS_INCLUDE_NEXT /* `__has_include_next(x)' */
@@ -874,7 +901,7 @@ enum cpp_builtin_type
union GTY(()) _cpp_hashnode_value {
/* Assert (maybe NULL) */
cpp_macro * GTY((tag ("NT_VOID"))) answers;
- /* Macro (never NULL) */
+ /* Macro (maybe NULL) */
cpp_macro * GTY((tag ("NT_USER_MACRO"))) macro;
/* Code for a builtin macro. */
enum cpp_builtin_type GTY ((tag ("NT_BUILTIN_MACRO"))) builtin;
@@ -888,11 +915,15 @@ struct GTY(()) cpp_hashnode {
unsigned int directive_index : 7; /* If is_directive,
then index into directive table.
Otherwise, a NODE_OPERATOR. */
- unsigned char rid_code; /* Rid code - for front ends. */
+ unsigned int rid_code : 8; /* Rid code - for front ends. */
+ unsigned int flags : 9; /* CPP flags. */
ENUM_BITFIELD(node_type) type : 2; /* CPP node type. */
- unsigned int flags : 8; /* CPP flags. */
- /* 6 bits spare (plus another 32 on 64-bit hosts). */
+ /* 5 bits spare. */
+
+ /* On a 64-bit system there would be 32-bits of padding to the value
+ field. So placing the deferred index here is not costly. */
+ unsigned deferred; /* Deferred index, (unless zero). */
union _cpp_hashnode_value GTY ((desc ("%1.type"))) value;
};
@@ -971,6 +1002,14 @@ extern cpp_callbacks *cpp_get_callbacks (cpp_reader *) ATTRIBUTE_PURE;
extern void cpp_set_callbacks (cpp_reader *, cpp_callbacks *);
extern class mkdeps *cpp_get_deps (cpp_reader *) ATTRIBUTE_PURE;
+extern const char *cpp_find_header_unit (cpp_reader *, const char *file,
+ bool angle_p, location_t);
+
+/* Call these to get name data about the various compile-time
+ charsets. */
+extern const char *cpp_get_narrow_charset_name (cpp_reader *) ATTRIBUTE_PURE;
+extern const char *cpp_get_wide_charset_name (cpp_reader *) ATTRIBUTE_PURE;
+
/* This function reads the file, but does not start preprocessing. It
returns the name of the original file; this is the same as the
input file, except for preprocessed input. This will generate at
@@ -978,6 +1017,10 @@ extern class mkdeps *cpp_get_deps (cpp_reader *) ATTRIBUTE_PURE;
too. If there was an error opening the file, it returns NULL. */
extern const char *cpp_read_main_file (cpp_reader *, const char *,
bool injecting = false);
+extern location_t cpp_main_loc (const cpp_reader *);
+
+/* Adjust for the main file to be an include. */
+extern void cpp_retrofit_as_include (cpp_reader *);
/* Set up built-ins with special behavior. Use cpp_init_builtins()
instead unless your know what you are doing. */
@@ -1027,6 +1070,18 @@ inline bool cpp_macro_p (const cpp_hashnode *node)
{
return node->type & NT_MACRO_MASK;
}
+inline cpp_macro *cpp_set_deferred_macro (cpp_hashnode *node,
+ cpp_macro *forced = NULL)
+{
+ cpp_macro *old = node->value.macro;
+
+ node->value.macro = forced;
+ node->type = NT_USER_MACRO;
+ node->flags &= ~NODE_USED;
+
+ return old;
+}
+cpp_macro *cpp_get_deferred_macro (cpp_reader *, cpp_hashnode *, location_t);
/* Returns true if NODE is a function-like user macro. */
inline bool cpp_fun_like_macro_p (cpp_hashnode *node)
@@ -1034,11 +1089,13 @@ inline bool cpp_fun_like_macro_p (cpp_hashnode *node)
return cpp_user_macro_p (node) && node->value.macro->fun_like;
}
-extern const unsigned char *cpp_macro_definition (cpp_reader *,
- cpp_hashnode *);
+extern const unsigned char *cpp_macro_definition (cpp_reader *, cpp_hashnode *);
+extern const unsigned char *cpp_macro_definition (cpp_reader *, cpp_hashnode *,
+ const cpp_macro *);
inline location_t cpp_macro_definition_location (cpp_hashnode *node)
{
- return node->value.macro->line;
+ const cpp_macro *macro = node->value.macro;
+ return macro ? macro->line : 0;
}
/* Return an idempotent time stamp (possibly from SOURCE_DATE_EPOCH). */
enum class CPP_time_kind
@@ -1075,8 +1132,12 @@ extern cppchar_t cpp_host_to_exec_charset (cpp_reader *, cppchar_t);
/* Used to register macros and assertions, perhaps from the command line.
The text is the same as the command line argument. */
extern void cpp_define (cpp_reader *, const char *);
+extern void cpp_define_unused (cpp_reader *, const char *);
extern void cpp_define_formatted (cpp_reader *pfile,
const char *fmt, ...) ATTRIBUTE_PRINTF_2;
+extern void cpp_define_formatted_unused (cpp_reader *pfile,
+ const char *fmt,
+ ...) ATTRIBUTE_PRINTF_2;
extern void cpp_assert (cpp_reader *, const char *);
extern void cpp_undef (cpp_reader *, const char *);
extern void cpp_unassert (cpp_reader *, const char *);
@@ -1228,6 +1289,8 @@ extern int cpp_ideq (const cpp_token *, const char *);
extern void cpp_output_line (cpp_reader *, FILE *);
extern unsigned char *cpp_output_line_to_string (cpp_reader *,
const unsigned char *);
+extern const unsigned char *cpp_alloc_token_string
+ (cpp_reader *, const unsigned char *, unsigned);
extern void cpp_output_token (const cpp_token *, FILE *);
extern const char *cpp_type2name (enum cpp_ttype, unsigned char flags);
/* Returns the value of an escape sequence, truncated to the correct
@@ -1283,6 +1346,8 @@ extern void cpp_scan_nooutput (cpp_reader *);
extern int cpp_sys_macro_p (cpp_reader *);
extern unsigned char *cpp_quote_string (unsigned char *, const unsigned char *,
unsigned int);
+extern bool cpp_compare_macros (const cpp_macro *macro1,
+ const cpp_macro *macro2);
/* In files.c */
extern bool cpp_included (cpp_reader *, const char *);
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index 44008be..50b2e4f 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -72,6 +72,7 @@ enum lc_reason
LC_RENAME, /* Other reason for name change. */
LC_RENAME_VERBATIM, /* Likewise, but "" != stdin. */
LC_ENTER_MACRO, /* Begin macro expansion. */
+ LC_MODULE, /* A (C++) Module. */
/* FIXME: add support for stringize and paste. */
LC_HWM /* High Water Mark. */
};
@@ -439,7 +440,8 @@ struct GTY((tag ("1"))) line_map_ordinary : public line_map {
/* Location from whence this line map was included. For regular
#includes, this location will be the last location of a map. For
- outermost file, this is 0. */
+ outermost file, this is 0. For modules it could be anywhere
+ within a map. */
location_t included_from;
/* Size is 20 or 24 bytes, no padding */
@@ -662,6 +664,15 @@ ORDINARY_MAP_IN_SYSTEM_HEADER_P (const line_map_ordinary *ord_map)
return ord_map->sysp;
}
+/* TRUE if this line map is for a module (not a source file). */
+
+inline bool
+MAP_MODULE_P (const line_map *map)
+{
+ return (MAP_ORDINARY_P (map)
+ && linemap_check_ordinary (map)->reason == LC_MODULE);
+}
+
/* Get the filename of ordinary map MAP. */
inline const char *
@@ -1076,6 +1087,9 @@ extern void linemap_check_files_exited (class line_maps *);
extern location_t linemap_line_start
(class line_maps *set, linenum_type to_line, unsigned int max_column_hint);
+/* Allocate a raw block of line maps, zero initialized. */
+extern line_map *line_map_new_raw (line_maps *, bool, unsigned);
+
/* Add a mapping of logical source line to physical source file and
line number. This function creates an "ordinary map", which is a
map that records locations of tokens that are not part of macro
@@ -1093,6 +1107,39 @@ extern const line_map *linemap_add
(class line_maps *, enum lc_reason, unsigned int sysp,
const char *to_file, linenum_type to_line);
+/* Create a macro map. A macro map encodes source locations of tokens
+ that are part of a macro replacement-list, at a macro expansion
+ point. See the extensive comments of struct line_map and struct
+ line_map_macro, in line-map.h.
+
+ This map shall be created when the macro is expanded. The map
+ encodes the source location of the expansion point of the macro as
+ well as the "original" source location of each token that is part
+ of the macro replacement-list. If a macro is defined but never
+ expanded, it has no macro map. SET is the set of maps the macro
+ map should be part of. MACRO_NODE is the macro which the new macro
+ map should encode source locations for. EXPANSION is the location
+ of the expansion point of MACRO. For function-like macros
+ invocations, it's best to make it point to the closing parenthesis
+ of the macro, rather than the the location of the first character
+ of the macro. NUM_TOKENS is the number of tokens that are part of
+ the replacement-list of MACRO. */
+const line_map_macro *linemap_enter_macro (line_maps *, cpp_hashnode *,
+ location_t, unsigned int);
+
+/* Create a source location for a module. The creator must either do
+ this after the TU is tokenized, or deal with saving and restoring
+ map state. */
+
+extern location_t linemap_module_loc
+ (line_maps *, location_t from, const char *name);
+extern void linemap_module_reparent
+ (line_maps *, location_t loc, location_t new_parent);
+
+/* Restore the linemap state such that the map at LWM-1 continues. */
+extern void linemap_module_restore
+ (line_maps *, unsigned lwm);
+
/* Given a logical source location, returns the map which the
corresponding (source file, line, column) triplet can be deduced
from. Since the set is built chronologically, the logical lines are
@@ -1102,6 +1149,8 @@ extern const line_map *linemap_add
extern const line_map *linemap_lookup
(const line_maps *, location_t);
+unsigned linemap_lookup_macro_index (const line_maps *, location_t);
+
/* Returns TRUE if the line table set tracks token locations across
macro expansion, FALSE otherwise. */
bool linemap_tracks_macro_expansion_locs_p (class line_maps *);
diff --git a/libcpp/include/mkdeps.h b/libcpp/include/mkdeps.h
index 593b718..9f10327 100644
--- a/libcpp/include/mkdeps.h
+++ b/libcpp/include/mkdeps.h
@@ -51,6 +51,13 @@ extern void deps_add_target (class mkdeps *, const char *, int);
string as the default target is interpreted as stdin. */
extern void deps_add_default_target (class mkdeps *, const char *);
+/* Adds a module target. The module name and cmi name are copied. */
+extern void deps_add_module_target (struct mkdeps *, const char *module,
+ const char *cmi, bool is_header);
+
+/* Adds a module dependency. The module name is copied. */
+extern void deps_add_module_dep (struct mkdeps *, const char *module);
+
/* Add a dependency (appears on the right side of the colon) to the
deps list. Dependencies will be printed in the order that they
were entered with this function. By convention, the first
diff --git a/libcpp/init.c b/libcpp/init.c
index dcf1d4b..f77dc26 100644
--- a/libcpp/init.c
+++ b/libcpp/init.c
@@ -102,13 +102,13 @@ static const struct lang_flags lang_defaults[] =
/* GNUC99 */ { 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0 },
/* GNUC11 */ { 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0 },
/* GNUC17 */ { 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0 },
- /* GNUC2X */ { 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 },
+ /* GNUC2X */ { 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1 },
/* STDC89 */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
/* STDC94 */ { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
/* STDC99 */ { 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
/* STDC11 */ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
/* STDC17 */ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
- /* STDC2X */ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1 },
+ /* STDC2X */ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1 },
/* GNUCXX */ { 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 },
/* CXX98 */ { 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 },
/* GNUCXX11 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0 },
@@ -407,6 +407,7 @@ static const struct builtin_macro builtin_array[] =
function-like macros in traditional.c:
fun_like_macro() when adding more following */
B("__has_attribute", BT_HAS_ATTRIBUTE, true),
+ B("__has_c_attribute", BT_HAS_STD_ATTRIBUTE, true),
B("__has_cpp_attribute", BT_HAS_ATTRIBUTE, true),
B("__has_builtin", BT_HAS_BUILTIN, true),
B("__has_include", BT_HAS_INCLUDE, true),
@@ -492,6 +493,7 @@ cpp_init_special_builtins (cpp_reader *pfile)
for (b = builtin_array; b < builtin_array + n; b++)
{
if ((b->value == BT_HAS_ATTRIBUTE
+ || b->value == BT_HAS_STD_ATTRIBUTE
|| b->value == BT_HAS_BUILTIN)
&& (CPP_OPTION (pfile, lang) == CLK_ASM
|| pfile->cb.has_attribute == NULL))
@@ -673,8 +675,14 @@ cpp_read_main_file (cpp_reader *pfile, const char *fname, bool injecting)
deps_add_default_target (deps, fname);
pfile->main_file
- = _cpp_find_file (pfile, fname, &pfile->no_search_path, /*angle=*/0,
- _cpp_FFK_NORMAL, 0);
+ = _cpp_find_file (pfile, fname,
+ CPP_OPTION (pfile, preprocessed) ? &pfile->no_search_path
+ : CPP_OPTION (pfile, main_search) == CMS_user
+ ? pfile->quote_include
+ : CPP_OPTION (pfile, main_search) == CMS_system
+ ? pfile->bracket_include : &pfile->no_search_path,
+ /*angle=*/0, _cpp_FFK_NORMAL, 0);
+
if (_cpp_find_failed (pfile->main_file))
return NULL;
@@ -696,7 +704,16 @@ cpp_read_main_file (cpp_reader *pfile, const char *fname, bool injecting)
LINEMAP_LINE (last), LINEMAP_SYSP (last));
}
- return ORDINARY_MAP_FILE_NAME (LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table));
+ auto *map = LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table);
+ pfile->main_loc = MAP_START_LOCATION (map);
+
+ return ORDINARY_MAP_FILE_NAME (map);
+}
+
+location_t
+cpp_main_loc (const cpp_reader *pfile)
+{
+ return pfile->main_loc;
}
/* For preprocessed files, if the very first characters are
@@ -841,4 +858,27 @@ post_options (cpp_reader *pfile)
CPP_OPTION (pfile, trigraphs) = 0;
CPP_OPTION (pfile, warn_trigraphs) = 0;
}
+
+ if (CPP_OPTION (pfile, module_directives))
+ {
+ /* These unspellable tokens have a leading space. */
+ const char *const inits[spec_nodes::M_HWM]
+ = {"export ", "module ", "import ", "__import"};
+
+ for (int ix = 0; ix != spec_nodes::M_HWM; ix++)
+ {
+ cpp_hashnode *node = cpp_lookup (pfile, UC (inits[ix]),
+ strlen (inits[ix]));
+
+ /* Token we pass to the compiler. */
+ pfile->spec_nodes.n_modules[ix][1] = node;
+
+ if (ix != spec_nodes::M__IMPORT)
+ /* Token we recognize when lexing, drop the trailing ' '. */
+ node = cpp_lookup (pfile, NODE_NAME (node), NODE_LEN (node) - 1);
+
+ node->flags |= NODE_MODULE;
+ pfile->spec_nodes.n_modules[ix][0] = node;
+ }
+ }
}
diff --git a/libcpp/internal.h b/libcpp/internal.h
index d7780e4..4010af8 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -48,6 +48,8 @@ struct cset_converter
convert_f func;
iconv_t cd;
int width;
+ const char* from;
+ const char* to;
};
#define BITS_PER_CPPCHAR_T (CHAR_BIT * sizeof (cppchar_t))
@@ -280,6 +282,9 @@ struct lexer_state
/* Nonzero when tokenizing a deferred pragma. */
unsigned char in_deferred_pragma;
+ /* Count to token that is a header-name. */
+ unsigned char directive_file_token;
+
/* Nonzero if the deferred pragma being handled allows macro expansion. */
unsigned char pragma_allow_expansion;
};
@@ -292,6 +297,12 @@ struct spec_nodes
cpp_hashnode *n_false; /* C++ keyword false */
cpp_hashnode *n__VA_ARGS__; /* C99 vararg macros */
cpp_hashnode *n__VA_OPT__; /* C++ vararg macros */
+
+ enum {M_EXPORT, M_MODULE, M_IMPORT, M__IMPORT, M_HWM};
+
+ /* C++20 modules, only set when module_directives is in effect.
+ incoming variants [0], outgoing ones [1] */
+ cpp_hashnode *n_modules[M_HWM][2];
};
typedef struct _cpp_line_note _cpp_line_note;
@@ -582,6 +593,10 @@ struct cpp_reader
/* If non-zero, the lexer will use this location for the next token
instead of getting a location from the linemap. */
location_t forced_token_location;
+
+ /* Location identifying the main source file -- intended to be line
+ zero of said file. */
+ location_t main_loc;
};
/* Character classes. Based on the more primitive macros in safe-ctype.h.
@@ -619,22 +634,23 @@ typedef unsigned char uchar;
#define UC (const uchar *) /* Intended use: UC"string" */
-/* Macros. */
+/* Accessors. */
-static inline int cpp_in_system_header (cpp_reader *);
-static inline int
-cpp_in_system_header (cpp_reader *pfile)
+inline int
+_cpp_in_system_header (cpp_reader *pfile)
{
return pfile->buffer ? pfile->buffer->sysp : 0;
}
#define CPP_PEDANTIC(PF) CPP_OPTION (PF, cpp_pedantic)
#define CPP_WTRADITIONAL(PF) CPP_OPTION (PF, cpp_warn_traditional)
-static inline int cpp_in_primary_file (cpp_reader *);
-static inline int
-cpp_in_primary_file (cpp_reader *pfile)
+/* Return true if we're in the main file (unless it's considered to be
+ an include file in its own right. */
+inline int
+_cpp_in_main_source_file (cpp_reader *pfile)
{
- return pfile->line_table->depth == 1;
+ return (!CPP_OPTION (pfile, main_search)
+ && pfile->buffer->file == pfile->main_file);
}
/* True if NODE is a macro for the purposes of ifdef, defined etc. */
@@ -648,13 +664,14 @@ inline bool _cpp_defined_macro_p (cpp_hashnode *node)
}
/* In macro.c */
-extern void _cpp_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node,
- location_t loc);
-inline void _cpp_maybe_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node,
+extern bool _cpp_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node,
+ location_t);
+inline bool _cpp_maybe_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node,
location_t loc)
{
if (!(node->flags & NODE_USED))
- _cpp_notify_macro_use (pfile, node, loc);
+ return _cpp_notify_macro_use (pfile, node, loc);
+ return true;
}
extern cpp_macro *_cpp_new_macro (cpp_reader *, cpp_macro_kind, void *);
extern void _cpp_free_definition (cpp_hashnode *);
@@ -868,29 +885,7 @@ ufputs (const unsigned char *s, FILE *f)
return fputs ((const char *)s, f);
}
- /* In line-map.c. */
-
-/* Create a macro map. A macro map encodes source locations of tokens
- that are part of a macro replacement-list, at a macro expansion
- point. See the extensive comments of struct line_map and struct
- line_map_macro, in line-map.h.
-
- This map shall be created when the macro is expanded. The map
- encodes the source location of the expansion point of the macro as
- well as the "original" source location of each token that is part
- of the macro replacement-list. If a macro is defined but never
- expanded, it has no macro map. SET is the set of maps the macro
- map should be part of. MACRO_NODE is the macro which the new macro
- map should encode source locations for. EXPANSION is the location
- of the expansion point of MACRO. For function-like macros
- invocations, it's best to make it point to the closing parenthesis
- of the macro, rather than the the location of the first character
- of the macro. NUM_TOKENS is the number of tokens that are part of
- the replacement-list of MACRO. */
-const line_map_macro *linemap_enter_macro (class line_maps *,
- struct cpp_hashnode*,
- location_t,
- unsigned int);
+/* In line-map.c. */
/* Create and return a virtual location for a token that is part of a
macro expansion-list at a macro expansion point. See the comment
diff --git a/libcpp/lex.c b/libcpp/lex.c
index f58a882..07d5a4f 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -1370,7 +1370,7 @@ maybe_va_opt_error (cpp_reader *pfile)
{
/* __VA_OPT__ should not be accepted at all, but allow it in
system headers. */
- if (!cpp_in_system_header (pfile))
+ if (!_cpp_in_system_header (pfile))
cpp_error (pfile, CPP_DL_PEDWARN,
"__VA_OPT__ is not available until C++20");
}
@@ -1577,13 +1577,20 @@ static void
create_literal (cpp_reader *pfile, cpp_token *token, const uchar *base,
unsigned int len, enum cpp_ttype type)
{
- uchar *dest = _cpp_unaligned_alloc (pfile, len + 1);
-
- memcpy (dest, base, len);
- dest[len] = '\0';
token->type = type;
token->val.str.len = len;
- token->val.str.text = dest;
+ token->val.str.text = cpp_alloc_token_string (pfile, base, len);
+}
+
+const uchar *
+cpp_alloc_token_string (cpp_reader *pfile,
+ const unsigned char *ptr, unsigned len)
+{
+ uchar *dest = _cpp_unaligned_alloc (pfile, len + 1);
+
+ dest[len] = 0;
+ memcpy (dest, ptr, len);
+ return dest;
}
/* A pair of raw buffer pointers. The currently open one is [1], the
@@ -2615,6 +2622,151 @@ _cpp_temp_token (cpp_reader *pfile)
return result;
}
+/* We're at the beginning of a logical line (so not in
+ directives-mode) and RESULT is a CPP_NAME with NODE_MODULE set. See
+ if we should enter deferred_pragma mode to tokenize the rest of the
+ line as a module control-line. */
+
+static void
+cpp_maybe_module_directive (cpp_reader *pfile, cpp_token *result)
+{
+ unsigned backup = 0; /* Tokens we peeked. */
+ cpp_hashnode *node = result->val.node.node;
+ cpp_token *peek = result;
+ cpp_token *keyword = peek;
+ cpp_hashnode *(&n_modules)[spec_nodes::M_HWM][2] = pfile->spec_nodes.n_modules;
+ int header_count = 0;
+
+ /* Make sure the incoming state is as we expect it. This way we
+ can restore it using constants. */
+ gcc_checking_assert (!pfile->state.in_deferred_pragma
+ && !pfile->state.skipping
+ && !pfile->state.parsing_args
+ && !pfile->state.angled_headers
+ && (pfile->state.save_comments
+ == !CPP_OPTION (pfile, discard_comments)));
+
+ /* Enter directives mode sufficiently for peeking. We don't have
+ to actually set in_directive. */
+ pfile->state.in_deferred_pragma = true;
+
+ /* These two fields are needed to process tokenization in deferred
+ pragma mode. They are not used outside deferred pragma mode or
+ directives mode. */
+ pfile->state.pragma_allow_expansion = true;
+ pfile->directive_line = result->src_loc;
+
+ /* Saving comments is incompatible with directives mode. */
+ pfile->state.save_comments = 0;
+
+ if (node == n_modules[spec_nodes::M_EXPORT][0])
+ {
+ peek = _cpp_lex_direct (pfile);
+ keyword = peek;
+ backup++;
+ if (keyword->type != CPP_NAME)
+ goto not_module;
+ node = keyword->val.node.node;
+ if (!(node->flags & NODE_MODULE))
+ goto not_module;
+ }
+
+ if (node == n_modules[spec_nodes::M__IMPORT][0])
+ /* __import */
+ header_count = backup + 2 + 16;
+ else if (node == n_modules[spec_nodes::M_IMPORT][0])
+ /* import */
+ header_count = backup + 2 + (CPP_OPTION (pfile, preprocessed) ? 16 : 0);
+ else if (node == n_modules[spec_nodes::M_MODULE][0])
+ ; /* module */
+ else
+ goto not_module;
+
+ /* We've seen [export] {module|import|__import}. Check the next token. */
+ if (header_count)
+ /* After '{,__}import' a header name may appear. */
+ pfile->state.angled_headers = true;
+ peek = _cpp_lex_direct (pfile);
+ backup++;
+
+ /* ... import followed by identifier, ':', '<' or
+ header-name preprocessing tokens, or module
+ followed by cpp-identifier, ':' or ';' preprocessing
+ tokens. C++ keywords are not yet relevant. */
+ if (peek->type == CPP_NAME
+ || peek->type == CPP_COLON
+ || (header_count
+ ? (peek->type == CPP_LESS
+ || (peek->type == CPP_STRING && peek->val.str.text[0] != 'R')
+ || peek->type == CPP_HEADER_NAME)
+ : peek->type == CPP_SEMICOLON))
+ {
+ pfile->state.pragma_allow_expansion = !CPP_OPTION (pfile, preprocessed);
+ if (!pfile->state.pragma_allow_expansion)
+ pfile->state.prevent_expansion++;
+
+ if (!header_count && linemap_included_from
+ (LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table)))
+ cpp_error_with_line (pfile, CPP_DL_ERROR, keyword->src_loc, 0,
+ "module control-line cannot be in included file");
+
+ /* The first one or two tokens cannot be macro names. */
+ for (int ix = backup; ix--;)
+ {
+ cpp_token *tok = ix ? keyword : result;
+ cpp_hashnode *node = tok->val.node.node;
+
+ /* Don't attempt to expand the token. */
+ tok->flags |= NO_EXPAND;
+ if (_cpp_defined_macro_p (node)
+ && _cpp_maybe_notify_macro_use (pfile, node, tok->src_loc)
+ && !cpp_fun_like_macro_p (node))
+ cpp_error_with_line (pfile, CPP_DL_ERROR, tok->src_loc, 0,
+ "module control-line \"%s\" cannot be"
+ " an object-like macro",
+ NODE_NAME (node));
+ }
+
+ /* Map to underbar variants. */
+ keyword->val.node.node = n_modules[header_count
+ ? spec_nodes::M_IMPORT
+ : spec_nodes::M_MODULE][1];
+ if (backup != 1)
+ result->val.node.node = n_modules[spec_nodes::M_EXPORT][1];
+
+ /* Maybe tell the tokenizer we expect a header-name down the
+ road. */
+ pfile->state.directive_file_token = header_count;
+ }
+ else
+ {
+ not_module:
+ /* Drop out of directive mode. */
+ /* We aaserted save_comments had this value upon entry. */
+ pfile->state.save_comments
+ = !CPP_OPTION (pfile, discard_comments);
+ pfile->state.in_deferred_pragma = false;
+ /* Do not let this remain on. */
+ pfile->state.angled_headers = false;
+ }
+
+ /* In either case we want to backup the peeked tokens. */
+ if (backup)
+ {
+ /* If we saw EOL, we should drop it, because this isn't a module
+ control-line after all. */
+ bool eol = peek->type == CPP_PRAGMA_EOL;
+ if (!eol || backup > 1)
+ {
+ /* Put put the peeked tokens back */
+ _cpp_backup_tokens_direct (pfile, backup);
+ /* But if the last one was an EOL, forget it. */
+ if (eol)
+ pfile->lookaheads--;
+ }
+ }
+}
+
/* Lex a token into RESULT (external interface). Takes care of issues
like directive handling, token lookahead, multiple include
optimization and skipping. */
@@ -2663,6 +2815,21 @@ _cpp_lex_token (cpp_reader *pfile)
}
else if (pfile->state.in_deferred_pragma)
result = &pfile->directive_result;
+ else if (result->type == CPP_NAME
+ && (result->val.node.node->flags & NODE_MODULE)
+ && !pfile->state.skipping
+ /* Unlike regular directives, we do not deal with
+ tokenizing module directives as macro arguments.
+ That's not permitted. */
+ && !pfile->state.parsing_args)
+ {
+ /* P1857. Before macro expansion, At start of logical
+ line ... */
+ /* We don't have to consider lookaheads at this point. */
+ gcc_checking_assert (!pfile->lookaheads);
+
+ cpp_maybe_module_directive (pfile, result);
+ }
if (pfile->cb.line_change && !pfile->state.skipping)
pfile->cb.line_change (pfile, result, pfile->state.parsing_args);
@@ -2934,7 +3101,7 @@ _cpp_lex_direct (cpp_reader *pfile)
else if (c == '/' && ! CPP_OPTION (pfile, traditional))
{
/* Don't warn for system headers. */
- if (cpp_in_system_header (pfile))
+ if (_cpp_in_system_header (pfile))
;
/* Warn about comments if pedantically GNUC89, and not
in system headers. */
@@ -3461,7 +3628,11 @@ cpp_output_token (const cpp_token *token, FILE *fp)
break;
case SPELL_LITERAL:
+ if (token->type == CPP_HEADER_NAME)
+ fputc ('"', fp);
fwrite (token->val.str.text, 1, token->val.str.len, fp);
+ if (token->type == CPP_HEADER_NAME)
+ fputc ('"', fp);
break;
case SPELL_NONE:
@@ -3947,6 +4118,188 @@ do_peek_prev (const unsigned char *peek, const unsigned char *bound)
return peek;
}
+/* If PEEK[-1] is identifier MATCH, scan past it and trailing white
+ space. Otherwise return NULL. */
+
+static const unsigned char *
+do_peek_ident (const char *match, const unsigned char *peek,
+ const unsigned char *limit)
+{
+ for (; *++match; peek++)
+ if (*peek != *match)
+ {
+ peek = do_peek_next (peek, limit);
+ if (*peek != *match)
+ return NULL;
+ }
+
+ /* Must now not be looking at an identifier char. */
+ peek = do_peek_next (peek, limit);
+ if (ISIDNUM (*peek))
+ return NULL;
+
+ /* Skip control-line whitespace. */
+ ws:
+ while (*peek == ' ' || *peek == '\t')
+ peek++;
+ if (__builtin_expect (*peek == '\\', false))
+ {
+ peek = do_peek_backslash (peek, limit);
+ if (*peek != '\\')
+ goto ws;
+ }
+
+ return peek;
+}
+
+/* Are we looking at a module control line starting as PEEK - 1? */
+
+static bool
+do_peek_module (cpp_reader *pfile, unsigned char c,
+ const unsigned char *peek, const unsigned char *limit)
+{
+ bool import = false;
+
+ if (__builtin_expect (c == 'e', false))
+ {
+ if (!((peek[0] == 'x' || peek[0] == '\\')
+ && (peek = do_peek_ident ("export", peek, limit))))
+ return false;
+
+ /* export, peek for import or module. No need to peek __import
+ here. */
+ if (peek[0] == 'i')
+ {
+ if (!((peek[1] == 'm' || peek[1] == '\\')
+ && (peek = do_peek_ident ("import", peek + 1, limit))))
+ return false;
+ import = true;
+ }
+ else if (peek[0] == 'm')
+ {
+ if (!((peek[1] == 'o' || peek[1] == '\\')
+ && (peek = do_peek_ident ("module", peek + 1, limit))))
+ return false;
+ }
+ else
+ return false;
+ }
+ else if (__builtin_expect (c == 'i', false))
+ {
+ if (!((peek[0] == 'm' || peek[0] == '\\')
+ && (peek = do_peek_ident ("import", peek, limit))))
+ return false;
+ import = true;
+ }
+ else if (__builtin_expect (c == '_', false))
+ {
+ /* Needed for translated includes. */
+ if (!((peek[0] == '_' || peek[0] == '\\')
+ && (peek = do_peek_ident ("__import", peek, limit))))
+ return false;
+ import = true;
+ }
+ else if (__builtin_expect (c == 'm', false))
+ {
+ if (!((peek[0] == 'o' || peek[0] == '\\')
+ && (peek = do_peek_ident ("module", peek, limit))))
+ return false;
+ }
+ else
+ return false;
+
+ /* Peek the next character to see if it's good enough. We'll be at
+ the first non-whitespace char, including skipping an escaped
+ newline. */
+ /* ... import followed by identifier, ':', '<' or header-name
+ preprocessing tokens, or module followed by identifier, ':' or
+ ';' preprocessing tokens. */
+ unsigned char p = *peek++;
+
+ /* A character literal is ... single quotes, ... optionally preceded
+ by u8, u, U, or L */
+ /* A string-literal is a ... double quotes, optionally prefixed by
+ R, u8, u8R, u, uR, U, UR, L, or LR */
+ if (p == 'u')
+ {
+ peek = do_peek_next (peek, limit);
+ if (*peek == '8')
+ {
+ peek++;
+ goto peek_u8;
+ }
+ goto peek_u;
+ }
+ else if (p == 'U' || p == 'L')
+ {
+ peek_u8:
+ peek = do_peek_next (peek, limit);
+ peek_u:
+ if (*peek == '\"' || *peek == '\'')
+ return false;
+
+ if (*peek == 'R')
+ goto peek_R;
+ /* Identifier. Ok. */
+ }
+ else if (p == 'R')
+ {
+ peek_R:
+ if (CPP_OPTION (pfile, rliterals))
+ {
+ peek = do_peek_next (peek, limit);
+ if (*peek == '\"')
+ return false;
+ }
+ /* Identifier. Ok. */
+ }
+ else if ('Z' - 'A' == 25
+ ? ((p >= 'A' && p <= 'Z') || (p >= 'a' && p <= 'z') || p == '_')
+ : ISIDST (p))
+ {
+ /* Identifier. Ok. */
+ }
+ else if (p == '<')
+ {
+ /* Maybe angle header, ok for import. Reject
+ '<=', '<<' digraph:'<:'. */
+ if (!import)
+ return false;
+ peek = do_peek_next (peek, limit);
+ if (*peek == '=' || *peek == '<'
+ || (*peek == ':' && CPP_OPTION (pfile, digraphs)))
+ return false;
+ }
+ else if (p == ';')
+ {
+ /* SEMICOLON, ok for module. */
+ if (import)
+ return false;
+ }
+ else if (p == '"')
+ {
+ /* STRING, ok for import. */
+ if (!import)
+ return false;
+ }
+ else if (p == ':')
+ {
+ /* Maybe COLON, ok. Reject '::', digraph:':>'. */
+ peek = do_peek_next (peek, limit);
+ if (*peek == ':' || (*peek == '>' && CPP_OPTION (pfile, digraphs)))
+ return false;
+ }
+ else
+ /* FIXME: Detect a unicode character, excluding those not
+ permitted as the initial character. [lex.name]/1. I presume
+ we need to check the \[uU] spellings, and directly using
+ Unicode in say UTF8 form? Or perhaps we do the phase-1
+ conversion of UTF8 to universal-character-names? */
+ return false;
+
+ return true;
+}
+
/* Directives-only scanning. Somewhat more relaxed than correct
parsing -- some ill-formed programs will not be rejected. */
@@ -3955,6 +4308,8 @@ cpp_directive_only_process (cpp_reader *pfile,
void *data,
void (*cb) (cpp_reader *, CPP_DO_task, void *, ...))
{
+ bool module_p = CPP_OPTION (pfile, module_directives);
+
do
{
restart:
@@ -4347,6 +4702,51 @@ cpp_directive_only_process (cpp_reader *pfile,
}
goto dflt;
+ case '_':
+ case 'e':
+ case 'i':
+ case 'm':
+ if (bol && module_p && !pfile->state.skipping
+ && do_peek_module (pfile, c, pos, limit))
+ {
+ /* We've seen the start of a module control line.
+ Start up the tokenizer. */
+ pos--; /* Backup over the first character. */
+
+ /* Backup over whitespace to start of line. */
+ while (pos > line_start
+ && (pos[-1] == ' ' || pos[-1] == '\t'))
+ pos--;
+
+ if (pos > base)
+ cb (pfile, CPP_DO_print, data, line_count, base, pos - base);
+
+ /* Prep things for directive handling. */
+ buffer->next_line = pos;
+ buffer->need_line = true;
+
+ /* Now get tokens until the PRAGMA_EOL. */
+ do
+ {
+ location_t spelling;
+ const cpp_token *tok
+ = cpp_get_token_with_location (pfile, &spelling);
+
+ gcc_assert (pfile->state.in_deferred_pragma
+ || tok->type == CPP_PRAGMA_EOL);
+ cb (pfile, CPP_DO_token, data, tok, spelling);
+ }
+ while (pfile->state.in_deferred_pragma);
+
+ if (pfile->buffer->next_line < pfile->buffer->rlimit)
+ cb (pfile, CPP_DO_location, data,
+ pfile->line_table->highest_line);
+
+ pfile->mi_valid = false;
+ goto restart;
+ }
+ goto dflt;
+
default:
dflt:
bol = false;
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index 5a74174..bbb6963 100644
--- a/libcpp/line-map.c
+++ b/libcpp/line-map.c
@@ -378,23 +378,21 @@ linemap_check_files_exited (line_maps *set)
ORDINARY_MAP_FILE_NAME (map));
}
-/* Create a new line map in the line map set SET, and return it.
- REASON is the reason of creating the map. It determines the type
- of map created (ordinary or macro map). Note that ordinary maps and
- macro maps are allocated in different memory location. */
+/* Create NUM zero-initialized maps of type MACRO_P. */
-static struct line_map *
-new_linemap (line_maps *set, location_t start_location)
+line_map *
+line_map_new_raw (line_maps *set, bool macro_p, unsigned num)
{
- bool macro_p = start_location >= LINE_MAP_MAX_LOCATION;
unsigned num_maps_allocated = LINEMAPS_ALLOCATED (set, macro_p);
unsigned num_maps_used = LINEMAPS_USED (set, macro_p);
-
- if (num_maps_used == num_maps_allocated)
+
+ if (num > num_maps_allocated - num_maps_used)
{
/* We need more space! */
if (!num_maps_allocated)
num_maps_allocated = 128;
+ if (num_maps_allocated < num_maps_used + num)
+ num_maps_allocated = num_maps_used + num;
num_maps_allocated *= 2;
size_t size_of_a_map;
@@ -436,13 +434,39 @@ new_linemap (line_maps *set, location_t start_location)
line_map *result = (macro_p ? (line_map *)&set->info_macro.maps[num_maps_used]
: (line_map *)&set->info_ordinary.maps[num_maps_used]);
- LINEMAPS_USED (set, macro_p)++;
+ LINEMAPS_USED (set, macro_p) += num;
+
+ return result;
+}
+
+/* Create a new line map in the line map set SET, and return it.
+ REASON is the reason of creating the map. It determines the type
+ of map created (ordinary or macro map). Note that ordinary maps and
+ macro maps are allocated in different memory location. */
+
+static struct line_map *
+new_linemap (line_maps *set, location_t start_location)
+{
+ line_map *result = line_map_new_raw (set,
+ start_location >= LINE_MAP_MAX_LOCATION,
+ 1);
result->start_location = start_location;
return result;
}
+/* Return the location of the last source line within an ordinary
+ map. */
+inline location_t
+LAST_SOURCE_LINE_LOCATION (const line_map_ordinary *map)
+{
+ return (((map[1].start_location - 1
+ - map->start_location)
+ & ~((1 << map->m_column_and_range_bits) - 1))
+ + map->start_location);
+}
+
/* Add a mapping of logical source line to physical source file and
line number.
@@ -570,6 +594,56 @@ linemap_add (line_maps *set, enum lc_reason reason,
return map;
}
+/* Create a location for a module NAME imported at FROM. */
+
+location_t
+linemap_module_loc (line_maps *set, location_t from, const char *name)
+{
+ const line_map_ordinary *map
+ = linemap_check_ordinary (linemap_add (set, LC_MODULE, false, name, 0));
+ const_cast <line_map_ordinary *> (map)->included_from = from;
+
+ location_t loc = linemap_line_start (set, 0, 0);
+
+ return loc;
+}
+
+/* The linemap containing LOC is being reparented to be
+ imported/included from ADOPTOR. This can happen when an
+ indirectly imported module is then directly imported, or when
+ partitions are involved. */
+
+void
+linemap_module_reparent (line_maps *set, location_t loc, location_t adoptor)
+{
+ const line_map_ordinary *map = linemap_ordinary_map_lookup (set, loc);
+ const_cast<line_map_ordinary *> (map)->included_from = adoptor;
+}
+
+/* A linemap at LWM-1 was interrupted to insert module locations & imports.
+ Append a new map, continuing the interrupted one. */
+
+void
+linemap_module_restore (line_maps *set, unsigned lwm)
+{
+ if (lwm && lwm != LINEMAPS_USED (set, false))
+ {
+ const line_map_ordinary *pre_map
+ = linemap_check_ordinary (LINEMAPS_MAP_AT (set, false, lwm - 1));
+ unsigned src_line = SOURCE_LINE (pre_map,
+ LAST_SOURCE_LINE_LOCATION (pre_map));
+ location_t inc_at = pre_map->included_from;
+ if (const line_map_ordinary *post_map
+ = (linemap_check_ordinary
+ (linemap_add (set, LC_RENAME_VERBATIM,
+ ORDINARY_MAP_IN_SYSTEM_HEADER_P (pre_map),
+ ORDINARY_MAP_FILE_NAME (pre_map), src_line))))
+ /* linemap_add will think we were included from the same as
+ the preceeding map. */
+ const_cast <line_map_ordinary *> (post_map)->included_from = inc_at;
+ }
+}
+
/* Returns TRUE if the line table set tracks token locations across
macro expansion, FALSE otherwise. */
@@ -1003,14 +1077,25 @@ linemap_macro_map_lookup (const line_maps *set, location_t line)
if (set == NULL)
return NULL;
+ unsigned ix = linemap_lookup_macro_index (set, line);
+ const struct line_map_macro *result = LINEMAPS_MACRO_MAP_AT (set, ix);
+ linemap_assert (MAP_START_LOCATION (result) <= line);
+
+ return result;
+}
+
+unsigned
+linemap_lookup_macro_index (const line_maps *set, location_t line)
+{
unsigned mn = LINEMAPS_MACRO_CACHE (set);
unsigned mx = LINEMAPS_MACRO_USED (set);
const struct line_map_macro *cached = LINEMAPS_MACRO_MAP_AT (set, mn);
if (line >= MAP_START_LOCATION (cached))
{
- if (mn == 0 || line < MAP_START_LOCATION (&cached[-1]))
- return cached;
+ if (line < (MAP_START_LOCATION (cached)
+ + MACRO_MAP_NUM_MACRO_TOKENS (cached)))
+ return mn;
mx = mn - 1;
mn = 0;
}
@@ -1025,10 +1110,7 @@ linemap_macro_map_lookup (const line_maps *set, location_t line)
}
LINEMAPS_MACRO_CACHE (set) = mx;
- const struct line_map_macro *result = LINEMAPS_MACRO_MAP_AT (set, mx);
- linemap_assert (MAP_START_LOCATION (result) <= line);
-
- return result;
+ return mx;
}
/* Return TRUE if MAP encodes locations coming from a macro
@@ -1747,7 +1829,7 @@ linemap_dump (FILE *stream, class line_maps *set, unsigned ix, bool is_macro)
{
const char *const lc_reasons_v[LC_HWM]
= { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
- "LC_ENTER_MACRO" };
+ "LC_ENTER_MACRO", "LC_MODULE" };
const line_map *map;
unsigned reason;
diff --git a/libcpp/macro.c b/libcpp/macro.c
index e2cb89e..0575585 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -268,6 +268,8 @@ class vaopt_state {
/* Macro expansion. */
+static cpp_macro *get_deferred_or_lazy_macro (cpp_reader *, cpp_hashnode *,
+ location_t);
static int enter_macro_context (cpp_reader *, cpp_hashnode *,
const cpp_token *, location_t);
static int builtin_macro (cpp_reader *, cpp_hashnode *,
@@ -338,10 +340,6 @@ static cpp_macro *create_iso_definition (cpp_reader *);
/* #define directive parsing and handling. */
static cpp_macro *lex_expansion_token (cpp_reader *, cpp_macro *);
-static bool warn_of_redefinition (cpp_reader *, cpp_hashnode *,
- const cpp_macro *);
-static bool compare_macros (const cpp_macro *, const cpp_macro *);
-
static bool parse_params (cpp_reader *, unsigned *, bool *);
static void check_trad_stringification (cpp_reader *, const cpp_macro *,
const cpp_string *);
@@ -353,8 +351,6 @@ static const cpp_token* cpp_get_token_1 (cpp_reader *, location_t *);
static cpp_hashnode* macro_of_context (cpp_context *context);
-static bool in_macro_expansion_p (cpp_reader *pfile);
-
/* Statistical counter tracking the number of macros that got
expanded. */
unsigned num_expanded_macros_counter = 0;
@@ -588,7 +584,7 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node,
(c) we are not in strictly conforming mode, then it has the
value 0. (b) and (c) are already checked in cpp_init_builtins. */
case BT_STDC:
- if (cpp_in_system_header (pfile))
+ if (_cpp_in_system_header (pfile))
number = 0;
else
number = 1;
@@ -648,7 +644,11 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node,
break;
case BT_HAS_ATTRIBUTE:
- number = pfile->cb.has_attribute (pfile);
+ number = pfile->cb.has_attribute (pfile, false);
+ break;
+
+ case BT_HAS_STD_ATTRIBUTE:
+ number = pfile->cb.has_attribute (pfile, true);
break;
case BT_HAS_BUILTIN:
@@ -2213,7 +2213,7 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro,
= (const cpp_token **) tokens_buff_last_token_ptr (buff);
}
else if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, c99)
- && ! macro->syshdr && ! cpp_in_system_header (pfile))
+ && ! macro->syshdr && ! _cpp_in_system_header (pfile))
{
if (CPP_OPTION (pfile, cplusplus))
cpp_pedwarning (pfile, CPP_W_PEDANTIC,
@@ -2232,7 +2232,7 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro,
}
else if (CPP_OPTION (pfile, cpp_warn_c90_c99_compat) > 0
&& ! CPP_OPTION (pfile, cplusplus)
- && ! macro->syshdr && ! cpp_in_system_header (pfile))
+ && ! macro->syshdr && ! _cpp_in_system_header (pfile))
cpp_warning (pfile, CPP_W_C90_C99_COMPAT,
"invoking macro %s argument %d: "
"empty macro arguments are undefined"
@@ -2874,6 +2874,12 @@ cpp_get_token_1 (cpp_reader *pfile, location_t *location)
if (node->type == NT_VOID || (result->flags & NO_EXPAND))
break;
+ if (!(node->flags & NODE_USED)
+ && node->type == NT_USER_MACRO
+ && !node->value.macro
+ && !cpp_get_deferred_macro (pfile, node, result->src_loc))
+ break;
+
if (!(node->flags & NODE_DISABLED))
{
int ret = 0;
@@ -2959,6 +2965,85 @@ cpp_get_token_1 (cpp_reader *pfile, location_t *location)
}
pfile->about_to_expand_macro_p = saved_about_to_expand_macro;
+
+ if (pfile->state.directive_file_token
+ && !pfile->state.parsing_args
+ && !(result->type == CPP_PADDING || result->type == CPP_COMMENT)
+ && !(15 & --pfile->state.directive_file_token))
+ {
+ /* Do header-name frobbery. Concatenate < ... > as approprate.
+ Do header search if needed, and finally drop the outer <> or
+ "". */
+ pfile->state.angled_headers = false;
+
+ /* Do angle-header reconstitution. Then do include searching.
+ We'll always end up with a ""-quoted header-name in that
+ case. If searching finds nothing, we emit a diagnostic and
+ an empty string. */
+ size_t len = 0;
+ char *fname = NULL;
+
+ cpp_token *tmp = _cpp_temp_token (pfile);
+ *tmp = *result;
+
+ tmp->type = CPP_HEADER_NAME;
+ bool need_search = !pfile->state.directive_file_token;
+ pfile->state.directive_file_token = 0;
+
+ bool angle = result->type != CPP_STRING;
+ if (result->type == CPP_HEADER_NAME
+ || (result->type == CPP_STRING && result->val.str.text[0] != 'R'))
+ {
+ len = result->val.str.len - 2;
+ fname = XNEWVEC (char, len + 1);
+ memcpy (fname, result->val.str.text + 1, len);
+ fname[len] = 0;
+ }
+ else if (result->type == CPP_LESS)
+ fname = _cpp_bracket_include (pfile);
+
+ if (fname)
+ {
+ /* We have a header-name. Look it up. This will emit an
+ unfound diagnostic. Canonicalize the found name. */
+ const char *found = fname;
+
+ if (need_search)
+ {
+ found = cpp_find_header_unit (pfile, fname, angle, tmp->src_loc);
+ if (!found)
+ found = "";
+ len = strlen (found);
+ }
+ /* Force a leading './' if it's not absolute. */
+ bool dotme = (found[0] == '.' ? !IS_DIR_SEPARATOR (found[1])
+ : found[0] && !IS_ABSOLUTE_PATH (found));
+
+ if (BUFF_ROOM (pfile->u_buff) < len + 1 + dotme * 2)
+ _cpp_extend_buff (pfile, &pfile->u_buff, len + 1 + dotme * 2);
+ unsigned char *buf = BUFF_FRONT (pfile->u_buff);
+ size_t pos = 0;
+
+ if (dotme)
+ {
+ buf[pos++] = '.';
+ /* Apparently '/' is unconditional. */
+ buf[pos++] = '/';
+ }
+ memcpy (&buf[pos], found, len);
+ pos += len;
+ buf[pos] = 0;
+
+ tmp->val.str.len = pos;
+ tmp->val.str.text = buf;
+
+ tmp->type = CPP_HEADER_NAME;
+ XDELETEVEC (fname);
+
+ result = tmp;
+ }
+ }
+
return result;
}
@@ -3133,22 +3218,15 @@ warn_of_redefinition (cpp_reader *pfile, cpp_hashnode *node,
if (node->flags & NODE_CONDITIONAL)
return false;
- cpp_macro *macro1 = node->value.macro;
- if (macro1->lazy)
- {
- /* We don't want to mark MACRO as used, but do need to finalize
- its laziness. */
- pfile->cb.user_lazy_macro (pfile, macro1, macro1->lazy - 1);
- macro1->lazy = 0;
- }
-
- return compare_macros (macro1, macro2);
+ if (cpp_macro *macro1 = get_deferred_or_lazy_macro (pfile, node, macro2->line))
+ return cpp_compare_macros (macro1, macro2);
+ return false;
}
/* Return TRUE if MACRO1 and MACRO2 differ. */
-static bool
-compare_macros (const cpp_macro *macro1, const cpp_macro *macro2)
+bool
+cpp_compare_macros (const cpp_macro *macro1, const cpp_macro *macro2)
{
/* Redefinition of a macro is allowed if and only if the old and new
definitions are the same. (6.10.3 paragraph 2). */
@@ -3707,11 +3785,46 @@ cpp_define_lazily (cpp_reader *pfile, cpp_hashnode *node, unsigned num)
macro->lazy = num + 1;
}
+/* NODE is a deferred macro, resolve it, returning the definition
+ (which may be NULL). */
+cpp_macro *
+cpp_get_deferred_macro (cpp_reader *pfile, cpp_hashnode *node,
+ location_t loc)
+{
+ node->value.macro = pfile->cb.user_deferred_macro (pfile, loc, node);
+
+ if (!node->value.macro)
+ node->type = NT_VOID;
+
+ return node->value.macro;
+}
+
+static cpp_macro *
+get_deferred_or_lazy_macro (cpp_reader *pfile, cpp_hashnode *node,
+ location_t loc)
+{
+ cpp_macro *macro = node->value.macro;
+ if (!macro)
+ {
+ macro = cpp_get_deferred_macro (pfile, node, loc);
+ if (!macro)
+ return NULL;
+ }
+
+ if (macro->lazy)
+ {
+ pfile->cb.user_lazy_macro (pfile, macro, macro->lazy - 1);
+ macro->lazy = 0;
+ }
+
+ return macro;
+}
+
/* Notify the use of NODE in a macro-aware context (i.e. expanding it,
or testing its existance). Also applies any lazy definition.
Return FALSE if the macro isn't really there. */
-extern void
+extern bool
_cpp_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node,
location_t loc)
{
@@ -3719,14 +3832,8 @@ _cpp_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node,
switch (node->type)
{
case NT_USER_MACRO:
- {
- cpp_macro *macro = node->value.macro;
- if (macro->lazy)
- {
- pfile->cb.user_lazy_macro (pfile, macro, macro->lazy - 1);
- macro->lazy = 0;
- }
- }
+ if (!get_deferred_or_lazy_macro (pfile, node, loc))
+ return false;
/* FALLTHROUGH. */
case NT_BUILTIN_MACRO:
@@ -3742,6 +3849,8 @@ _cpp_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node,
default:
abort ();
}
+
+ return true;
}
/* Warn if a token in STRING matches one of a function-like MACRO's
@@ -3794,12 +3903,19 @@ check_trad_stringification (cpp_reader *pfile, const cpp_macro *macro,
const unsigned char *
cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node)
{
- unsigned int i, len;
- unsigned char *buffer;
-
gcc_checking_assert (cpp_user_macro_p (node));
- const cpp_macro *macro = node->value.macro;
+ if (const cpp_macro *macro = get_deferred_or_lazy_macro (pfile, node, 0))
+ return cpp_macro_definition (pfile, node, macro);
+ return NULL;
+}
+
+const unsigned char *
+cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node,
+ const cpp_macro *macro)
+{
+ unsigned int i, len;
+ unsigned char *buffer;
/* Calculate length. */
len = NODE_LEN (node) * 10 + 2; /* ' ' and NUL. */
diff --git a/libcpp/mkdeps.c b/libcpp/mkdeps.c
index ea5f060..4a8e101 100644
--- a/libcpp/mkdeps.c
+++ b/libcpp/mkdeps.c
@@ -81,7 +81,7 @@ public:
};
mkdeps ()
- : quote_lwm (0)
+ : module_name (NULL), cmi_name (NULL), is_header_unit (false), quote_lwm (0)
{
}
~mkdeps ()
@@ -94,34 +94,39 @@ public:
free (const_cast <char *> (deps[i]));
for (i = vpath.size (); i--;)
XDELETEVEC (vpath[i].str);
+ for (i = modules.size (); i--;)
+ XDELETEVEC (modules[i]);
+ XDELETEVEC (module_name);
+ free (const_cast <char *> (cmi_name));
}
public:
vec<const char *> targets;
vec<const char *> deps;
vec<velt> vpath;
+ vec<const char *> modules;
public:
+ const char *module_name;
+ const char *cmi_name;
+ bool is_header_unit;
unsigned short quote_lwm;
};
-/* Apply Make quoting to STR, TRAIL etc. Note that it's not possible
- to quote all such characters - e.g. \n, %, *, ?, [, \ (in some
+/* Apply Make quoting to STR, TRAIL. Note that it's not possible to
+ quote all such characters - e.g. \n, %, *, ?, [, \ (in some
contexts), and ~ are not properly handled. It isn't possible to
get this right in any current version of Make. (??? Still true?
Old comment referred to 3.76.1.) */
static const char *
-munge (const char *str, const char *trail = NULL, ...)
+munge (const char *str, const char *trail = nullptr)
{
static unsigned alloc;
static char *buf;
unsigned dst = 0;
- va_list args;
- if (trail)
- va_start (args, trail);
- for (bool first = true; str; first = false)
+ for (; str; str = trail, trail = nullptr)
{
unsigned slashes = 0;
char c;
@@ -169,14 +174,7 @@ munge (const char *str, const char *trail = NULL, ...)
buf[dst++] = c;
}
-
- if (first)
- str = trail;
- else
- str = va_arg (args, const char *);
}
- if (trail)
- va_end (args);
buf[dst] = 0;
return buf;
@@ -323,6 +321,28 @@ deps_add_vpath (class mkdeps *d, const char *vpath)
}
}
+/* Add a new module target (there can only be one). M is the module
+ name. */
+
+void
+deps_add_module_target (struct mkdeps *d, const char *m,
+ const char *cmi, bool is_header_unit)
+{
+ gcc_assert (!d->module_name);
+
+ d->module_name = xstrdup (m);
+ d->is_header_unit = is_header_unit;
+ d->cmi_name = xstrdup (cmi);
+}
+
+/* Add a new module dependency. M is the module name. */
+
+void
+deps_add_module_dep (struct mkdeps *d, const char *m)
+{
+ d->modules.push (xstrdup (m));
+}
+
/* Write NAME, with a leading space to FP, a Makefile. Advance COL as
appropriate, wrap at COLMAX, returning new column number. Iff
QUOTE apply quoting. Append TRAIL. */
@@ -332,7 +352,7 @@ make_write_name (const char *name, FILE *fp, unsigned col, unsigned colmax,
bool quote = true, const char *trail = NULL)
{
if (quote)
- name = munge (name, trail, NULL);
+ name = munge (name, trail);
unsigned size = strlen (name);
if (col)
@@ -379,6 +399,8 @@ make_write (const cpp_reader *pfile, FILE *fp, unsigned int colmax)
if (d->deps.size ())
{
column = make_write_vec (d->targets, fp, 0, colmax, d->quote_lwm);
+ if (CPP_OPTION (pfile, deps.modules) && d->cmi_name)
+ column = make_write_name (d->cmi_name, fp, column, colmax);
fputs (":", fp);
column++;
make_write_vec (d->deps, fp, column, colmax);
@@ -387,6 +409,59 @@ make_write (const cpp_reader *pfile, FILE *fp, unsigned int colmax)
for (unsigned i = 1; i < d->deps.size (); i++)
fprintf (fp, "%s:\n", munge (d->deps[i]));
}
+
+ if (!CPP_OPTION (pfile, deps.modules))
+ return;
+
+ if (d->modules.size ())
+ {
+ column = make_write_vec (d->targets, fp, 0, colmax, d->quote_lwm);
+ if (d->cmi_name)
+ column = make_write_name (d->cmi_name, fp, column, colmax);
+ fputs (":", fp);
+ column++;
+ column = make_write_vec (d->modules, fp, column, colmax, 0, ".c++m");
+ fputs ("\n", fp);
+ }
+
+ if (d->module_name)
+ {
+ if (d->cmi_name)
+ {
+ /* module-name : cmi-name */
+ column = make_write_name (d->module_name, fp, 0, colmax,
+ true, ".c++m");
+ fputs (":", fp);
+ column++;
+ column = make_write_name (d->cmi_name, fp, column, colmax);
+ fputs ("\n", fp);
+
+ column = fprintf (fp, ".PHONY:");
+ column = make_write_name (d->module_name, fp, column, colmax,
+ true, ".c++m");
+ fputs ("\n", fp);
+ }
+
+ if (d->cmi_name && !d->is_header_unit)
+ {
+ /* An order-only dependency.
+ cmi-name :| first-target
+ We can probably drop this this in favour of Make-4.3's grouped
+ targets '&:' */
+ column = make_write_name (d->cmi_name, fp, 0, colmax);
+ fputs (":|", fp);
+ column++;
+ column = make_write_name (d->targets[0], fp, column, colmax);
+ fputs ("\n", fp);
+ }
+ }
+
+ if (d->modules.size ())
+ {
+ column = fprintf (fp, "CXX_IMPORTS +=");
+ make_write_vec (d->modules, fp, column, colmax, 0, ".c++m");
+ fputs ("\n", fp);
+ }
}
/* Write out dependencies according to the selected format (which is
diff --git a/libcpp/traditional.c b/libcpp/traditional.c
index b087072..225e3c2 100644
--- a/libcpp/traditional.c
+++ b/libcpp/traditional.c
@@ -330,6 +330,7 @@ fun_like_macro (cpp_hashnode *node)
{
if (cpp_builtin_macro_p (node))
return (node->value.builtin == BT_HAS_ATTRIBUTE
+ || node->value.builtin == BT_HAS_STD_ATTRIBUTE
|| node->value.builtin == BT_HAS_BUILTIN
|| node->value.builtin == BT_HAS_INCLUDE
|| node->value.builtin == BT_HAS_INCLUDE_NEXT);
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index 4cf3149..f2e40c4 100644
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,3 +1,7 @@
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ * configure: Regenerate.
+
2020-09-24 Alan Modra <amodra@gmail.com>
* src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Correct
diff --git a/libffi/configure b/libffi/configure
index f005150..ce11ca5 100755
--- a/libffi/configure
+++ b/libffi/configure
@@ -9845,7 +9845,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -9857,7 +9857,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -12689,7 +12689,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
aCC*)
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
@@ -12713,7 +12713,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test $with_gnu_ld = no; then
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index fa70f2f7..20b77fd 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,51 @@
+2020-11-30 Stefan Kanthak <stefan.kanthak@nexgo.de>
+
+ * libgcc2.c (bswapsi2): Make constants unsigned.
+
+2020-11-25 Stefan Kanthak <stefan.kanthak@nexgo.de>
+
+ * libgcc2.c (absvSI2): Simplify/improve implementation by using
+ builtin_add_overflow.
+ (absvsi2, absvDI2): Likewise.
+
+2020-11-20 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * unwind-dw2-fde-dip.c [__OpenBSD__ || __NetBSD__]
+ (USE_PT_GNU_EH_FRAME): Do not define if !TARGET_DL_ITERATE_PHDR.
+
+2020-11-18 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * config/msp430/lib2hw_mul.S (mult64_hw): New.
+ (if MUL_32): Use mult64_hw for __muldi3.
+ (if MUL_F5): Use mult64_hw for __muldi3.
+ * config/msp430/lib2mul.c (__muldi3): New.
+ * config/msp430/t-msp430 (LIB2FUNCS_EXCLUDE): Define.
+
+2020-11-17 Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/t-ppc64-fp (LIB2ADD): Delete.
+ (LIB2_SIDITI_CONV_FUNCS): Define.
+ * config/rs6000/ppc64-fp.c: Delete file.
+
+2020-11-15 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * config/msp430/lib2hw_mul.S: Omit _hw* suffix from GCC names for
+ hwmult library functions.
+
+2020-11-10 Jeff Law <law@redhat.com>
+
+ * libgcc2.c: Fix whitespace issues in most recent change.
+
+2020-11-10 Stefan Kanthak <stefan.kanthak@nexgo.de>
+
+ * libgcc2.c (__addvSI3): Use overflow builtins.
+ (__addvsi3, __addvDI3 ,__subvSI3, __subvsi3): Likewise.
+ (__subvDI3 __mulvSI3, __mulvsi3, __negvSI2): Likewise.
+ (__negvsi2, __negvDI2): Likewise.
+ (__cmpdi2, __ucmpdi2): Adjust implementation to improve
+ generated code.
+ * libgcc2.h (__ucmpdi2): Adjust prototype.
+
2020-11-03 Pat Bernardi <bernardi@adacore.com>
Olivier Hainque <hainque@adacore.com>
diff --git a/libgcc/config/msp430/lib2hw_mul.S b/libgcc/config/msp430/lib2hw_mul.S
index de840d9..855dcd8 100644
--- a/libgcc/config/msp430/lib2hw_mul.S
+++ b/libgcc/config/msp430/lib2hw_mul.S
@@ -207,6 +207,73 @@
MOV.W &\RES3, R15 ; Ready high 16-bits for return
.endm
+.macro mult64_hw MPY32_LO MPY32_HI OP2_LO OP2_HI RES0 RES1 RES2 RES3
+;* * 64-bit hardware multiply with a 64-bit result
+;* int64 = int64 * int64
+;*
+;* - Operand 1 is in R8, R9, R10, R11
+;* - Operand 2 is in R12, R13, R14, R15
+;* - Result is in R12, R13, R14, R15
+;*
+;* 64-bit multiplication is achieved using the 32-bit hardware multiplier with
+;* the following equation:
+;* R12:R15 = (R8:R9 * R12:R13) + ((R8:R9 * R14:R15) << 32) + ((R10:R11 * R12:R13) << 32)
+;*
+;* The left shift by 32 is handled with minimal cost by saving the two low
+;* words and discarding the two high words.
+;*
+;* To ensure that the multiply is performed atomically, interrupts are
+;* disabled upon routine entry. Interrupt state is restored upon exit.
+;*
+;* Registers used: R6, R7, R8, R9, R10, R11, R12, R13, R14, R15
+;*
+;* Macro arguments are the memory locations of the hardware registers.
+;*
+#if defined(__MSP430X_LARGE__)
+ PUSHM.A #5, R10
+#elif defined(__MSP430X__)
+ PUSHM.W #5, R10
+#else
+ PUSH R10 { PUSH R9 { PUSH R8 { PUSH R7 { PUSH R6
+#endif
+ ; Multiply the low 32-bits of op0 and the high 32-bits of op1.
+ MOV.W R8, &\MPY32_LO
+ MOV.W R9, &\MPY32_HI
+ MOV.W R14, &\OP2_LO
+ MOV.W R15, &\OP2_HI
+ ; Save the low 32-bits of the result.
+ MOV.W &\RES0, R6
+ MOV.W &\RES1, R7
+ ; Multiply the high 32-bits of op0 and the low 32-bits of op1.
+ MOV.W R10, &\MPY32_LO
+ MOV.W R11, &\MPY32_HI
+ MOV.W R12, &\OP2_LO
+ MOV.W R13, &\OP2_HI
+ ; Add the low 32-bits of the result to the previously saved result.
+ ADD.W &\RES0, R6
+ ADDC.W &\RES1, R7
+ ; Multiply the low 32-bits of op0 and op1.
+ MOV.W R8, &\MPY32_LO
+ MOV.W R9, &\MPY32_HI
+ MOV.W R12, &\OP2_LO
+ MOV.W R13, &\OP2_HI
+ ; Write the return values
+ MOV.W &\RES0, R12
+ MOV.W &\RES1, R13
+ MOV.W &\RES2, R14
+ MOV.W &\RES3, R15
+ ; Add the saved low 32-bit results from earlier to the high 32-bits of
+ ; this result, effectively shifting those two results left by 32 bits.
+ ADD.W R6, R14
+ ADDC.W R7, R15
+#if defined(__MSP430X_LARGE__)
+ POPM.A #5, R10
+#elif defined(__MSP430X__)
+ POPM.W #5, R10
+#else
+ POP R6 { POP R7 { POP R8 { POP R9 { POP R10
+#endif
+.endm
;; EABI mandated names:
;;
@@ -353,9 +420,9 @@
mult1632 MPY, OP2, RESLO, RESHI
end_func __umulhisi2
- start_func __mulsi2_hw32 __mspabi_mpyl __mspabi_mpyl_hw32
+ start_func __mulsi2 __mspabi_mpyl __mspabi_mpyl_hw32
mult32_hw MPY32L, MPY32H, OP2L, OP2H, RES0, RES1
- end_func __mulsi2_hw32
+ end_func __mulsi2
start_func __mulsidi2 __mspabi_mpysll __mspabi_mpysll_hw32
mult3264_hw MPYS32L, MPYS32H, OP2L, OP2H, RES0, RES1, RES2, RES3
@@ -365,17 +432,18 @@
mult3264_hw MPY32L, MPY32H, OP2L, OP2H, RES0, RES1, RES2, RES3
end_func __umulsidi2
- ;; FIXME: Add a hardware version of this function.
- fake_func __muldi3 __mspabi_mpyll __mspabi_mpyll_hw32
+ start_func __muldi3 __mspabi_mpyll __mspabi_mpyll_hw32
+ mult64_hw MPY32L, MPY32H, OP2L, OP2H, RES0, RES1, RES2, RES3
+ end_func __muldi3
#elif defined MUL_F5
/* The F5xxx series of MCUs support the same 16-bit and 32-bit multiply
as the second generation hardware, but they are accessed from different
memory registers. */
- start_func __mulhi2_f5 __mspabi_mpyi __mspabi_mpyi_f5hw
+ start_func __mulhi2 __mspabi_mpyi __mspabi_mpyi_f5hw
mult16 MPY_F5, OP2_F5, RESLO_F5
- end_func __mulhi2_f5
+ end_func __mulhi2
start_func __mulhisi2 __mspabi_mpysl __mspabi_mpysl_f5hw
mult1632 MPYS_F5, OP2_F5, RESLO_F5, RESHI_F5
@@ -385,9 +453,9 @@
mult1632 MPY_F5, OP2_F5, RESLO_F5, RESHI_F5
end_func __umulhisi2
- start_func __mulsi2_f5 __mspabi_mpyl __mspabi_mpyl_f5hw
+ start_func __mulsi2 __mspabi_mpyl __mspabi_mpyl_f5hw
mult32_hw MPY32L_F5, MPY32H_F5, OP2L_F5, OP2H_F5, RES0_F5, RES1_F5
- end_func __mulsi2_f5
+ end_func __mulsi2
start_func __mulsidi2 __mspabi_mpysll __mspabi_mpysll_f5hw
mult3264_hw MPYS32L_F5, MPYS32H_F5, OP2L_F5, OP2H_F5, RES0_F5, RES1_F5, RES2_F5, RES3_F5
@@ -397,8 +465,9 @@
mult3264_hw MPY32L_F5, MPY32H_F5, OP2L_F5, OP2H_F5, RES0_F5, RES1_F5, RES2_F5, RES3_F5
end_func __umulsidi2
- ;; FIXME: Add a hardware version of this function.
- fake_func __muldi3 __mspabi_mpyll __mspabi_mpyll_f5hw
+ start_func __muldi3 __mspabi_mpyll __mspabi_mpyll_f5hw
+ mult64_hw MPY32L_F5, MPY32H_F5, OP2L_F5, OP2H_F5, RES0_F5, RES1_F5, RES2_F5, RES3_F5
+ end_func __muldi3
#else
#error MUL type not defined
diff --git a/libgcc/config/msp430/lib2mul.c b/libgcc/config/msp430/lib2mul.c
index 955e7bb..ca022b9 100644
--- a/libgcc/config/msp430/lib2mul.c
+++ b/libgcc/config/msp430/lib2mul.c
@@ -30,6 +30,58 @@ typedef unsigned int uint08_type __attribute__ ((mode (QI)));
#define C3B(a,b,c) a##b##c
#define C3(a,b,c) C3B(a,b,c)
+#if defined (MUL_NONE) || defined (MUL_16)
+/* __muldi3 must be excluded from libgcc.a to prevent multiple-definition
+ errors for the hwmult configurations that have their own definition.
+ However, for MUL_NONE and MUL_16, the software version is still required, so
+ the necessary preprocessed output from libgcc2.c to compile that
+ software version of __muldi3 is below. */
+typedef unsigned int USItype __attribute__ ((mode (SI)));
+typedef int DItype __attribute__ ((mode (DI)));
+typedef int SItype __attribute__ ((mode (SI)));
+struct DWstruct {SItype low, high;};
+
+typedef union
+{
+ struct DWstruct s;
+ DItype ll;
+} DWunion;
+
+DItype __muldi3 (DItype u, DItype v);
+
+DItype
+__muldi3 (DItype u, DItype v)
+{
+ const DWunion uu = {.ll = u};
+ const DWunion vv = {.ll = v};
+ /* The next block of code is expanded from the following line:
+ DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)}; */
+ DWunion w;
+ USItype __x0, __x1, __x2, __x3;
+ USItype __ul, __vl, __uh, __vh;
+ __ul = ((USItype) (uu.s.low) & (((USItype) 1 << ((4 * 8) / 2)) - 1));
+ __uh = ((USItype) (uu.s.low) >> ((4 * 8) / 2));
+ __vl = ((USItype) (vv.s.low) & (((USItype) 1 << ((4 * 8) / 2)) - 1));
+ __vh = ((USItype) (vv.s.low) >> ((4 * 8) / 2));
+ __x0 = (USItype) __ul * __vl;
+ __x1 = (USItype) __ul * __vh;
+ __x2 = (USItype) __uh * __vl;
+ __x3 = (USItype) __uh * __vh;
+ __x1 += ((USItype) (__x0) >> ((4 * 8) / 2));
+ __x1 += __x2;
+ if (__x1 < __x2)
+ __x3 += ((USItype) 1 << ((4 * 8) / 2));
+ (w.s.high) = __x3 + ((USItype) (__x1) >> ((4 * 8) / 2));
+ (w.s.low) = ((USItype) (__x1) & (((USItype) 1 << ((4 * 8) / 2)) - 1))
+ * ((USItype) 1 << ((4 * 8) / 2))
+ + ((USItype) (__x0) & (((USItype) 1 << ((4 * 8) / 2)) - 1));
+
+ w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
+ + (USItype) uu.s.high * (USItype) vv.s.low);
+ return w.ll;
+}
+#endif
+
#if defined MUL_NONE
/* The software multiply library needs __mspabi_mpyll. */
diff --git a/libgcc/config/msp430/t-msp430 b/libgcc/config/msp430/t-msp430
index be56e88..9a79b5b 100644
--- a/libgcc/config/msp430/t-msp430
+++ b/libgcc/config/msp430/t-msp430
@@ -40,6 +40,11 @@ LIB2ADD = \
$(srcdir)/config/msp430/floathisf.c \
$(srcdir)/config/msp430/cmpd.c
+# 32-bit and F5series hardware multiply have their own version of this function.
+# To handle the case when there is no hardware multiply or only 16-bit hardware
+# multiply, the libgcc version has been copied to lib2mul.c.
+LIB2FUNCS_EXCLUDE += _muldi3
+
HOST_LIBGCC2_CFLAGS += -Os -ffunction-sections -fdata-sections -mhwmult=none
crtbegin_no_eh.o: $(srcdir)/crtstuff.c
diff --git a/libgcc/config/rs6000/ppc64-fp.c b/libgcc/config/rs6000/ppc64-fp.c
deleted file mode 100644
index 9ca3c71..0000000
--- a/libgcc/config/rs6000/ppc64-fp.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/* Functions needed for soft-float on powerpc64-linux, copied from
- libgcc2.c with macros expanded to force the use of specific types.
-
- Copyright (C) 1989-2020 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.
-
-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/>. */
-
-#if defined(__powerpc64__) || defined (__64BIT__) || defined(__ppc64__)
-#define TMODES
-#include "fp-bit.h"
-
-extern DItype __fixtfdi (TFtype);
-extern DItype __fixdfdi (DFtype);
-extern DItype __fixsfdi (SFtype);
-extern USItype __fixunsdfsi (DFtype);
-extern USItype __fixunssfsi (SFtype);
-extern TFtype __floatditf (DItype);
-extern TFtype __floatunditf (UDItype);
-extern DFtype __floatdidf (DItype);
-extern DFtype __floatundidf (UDItype);
-extern SFtype __floatdisf (DItype);
-extern SFtype __floatundisf (UDItype);
-extern DItype __fixunstfdi (TFtype);
-
-static DItype local_fixunssfdi (SFtype);
-static DItype local_fixunsdfdi (DFtype);
-
-DItype
-__fixtfdi (TFtype a)
-{
- if (a < 0)
- return - __fixunstfdi (-a);
- return __fixunstfdi (a);
-}
-
-DItype
-__fixdfdi (DFtype a)
-{
- if (a < 0)
- return - local_fixunsdfdi (-a);
- return local_fixunsdfdi (a);
-}
-
-DItype
-__fixsfdi (SFtype a)
-{
- if (a < 0)
- return - local_fixunssfdi (-a);
- return local_fixunssfdi (a);
-}
-
-USItype
-__fixunsdfsi (DFtype a)
-{
- if (a >= - (DFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
- return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
- - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1);
- return (SItype) a;
-}
-
-USItype
-__fixunssfsi (SFtype a)
-{
- if (a >= - (SFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
- return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
- - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1);
- return (SItype) a;
-}
-
-TFtype
-__floatditf (DItype u)
-{
- DFtype dh, dl;
-
- dh = (SItype) (u >> (sizeof (SItype) * 8));
- dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
- dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
-
- return (TFtype) dh + (TFtype) dl;
-}
-
-TFtype
-__floatunditf (UDItype u)
-{
- DFtype dh, dl;
-
- dh = (USItype) (u >> (sizeof (SItype) * 8));
- dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
- dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
-
- return (TFtype) dh + (TFtype) dl;
-}
-
-DFtype
-__floatdidf (DItype u)
-{
- DFtype d;
-
- d = (SItype) (u >> (sizeof (SItype) * 8));
- d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
- d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
-
- return d;
-}
-
-DFtype
-__floatundidf (UDItype u)
-{
- DFtype d;
-
- d = (USItype) (u >> (sizeof (SItype) * 8));
- d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
- d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
-
- return d;
-}
-
-SFtype
-__floatdisf (DItype u)
-{
- DFtype f;
-
- if (53 < (sizeof (DItype) * 8)
- && 53 > ((sizeof (DItype) * 8) - 53 + 24))
- {
- if (! (- ((DItype) 1 << 53) < u
- && u < ((DItype) 1 << 53)))
- {
- if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1))
- {
- u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1);
- u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53));
- }
- }
- }
- f = (SItype) (u >> (sizeof (SItype) * 8));
- f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
- f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
-
- return (SFtype) f;
-}
-
-SFtype
-__floatundisf (UDItype u)
-{
- DFtype f;
-
- if (53 < (sizeof (DItype) * 8)
- && 53 > ((sizeof (DItype) * 8) - 53 + 24))
- {
- if (u >= ((UDItype) 1 << 53))
- {
- if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1))
- {
- u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1);
- u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53));
- }
- }
- }
- f = (USItype) (u >> (sizeof (SItype) * 8));
- f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
- f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
-
- return (SFtype) f;
-}
-
-DItype
-__fixunstfdi (TFtype a)
-{
- if (a < 0)
- return 0;
-
- /* Compute high word of result, as a flonum. */
- const TFtype b = (a / (((UDItype) 1) << (sizeof (SItype) * 8)));
- /* Convert that to fixed (but not to DItype!),
- and shift it into the high word. */
- UDItype v = (USItype) b;
- v <<= (sizeof (SItype) * 8);
- /* Remove high part from the TFtype, leaving the low part as flonum. */
- a -= (TFtype) v;
- /* Convert that to fixed (but not to DItype!) and add it in.
- Sometimes A comes out negative. This is significant, since
- A has more bits than a long int does. */
- if (a < 0)
- v -= (USItype) (-a);
- else
- v += (USItype) a;
- return v;
-}
-
-/* This version is needed to prevent recursion; fixunsdfdi in libgcc
- calls fixdfdi, which in turn calls calls fixunsdfdi. */
-
-static DItype
-local_fixunsdfdi (DFtype a)
-{
- USItype hi, lo;
-
- hi = a / (((UDItype) 1) << (sizeof (SItype) * 8));
- lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8)));
- return ((UDItype) hi << (sizeof (SItype) * 8)) | lo;
-}
-
-/* This version is needed to prevent recursion; fixunssfdi in libgcc
- calls fixsfdi, which in turn calls calls fixunssfdi. */
-
-static DItype
-local_fixunssfdi (SFtype original_a)
-{
- DFtype a = original_a;
- USItype hi, lo;
-
- hi = a / (((UDItype) 1) << (sizeof (SItype) * 8));
- lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8)));
- return ((UDItype) hi << (sizeof (SItype) * 8)) | lo;
-}
-
-#endif /* __powerpc64__ */
diff --git a/libgcc/config/rs6000/t-linux b/libgcc/config/rs6000/t-linux
index ed82194..72e9c27 100644
--- a/libgcc/config/rs6000/t-linux
+++ b/libgcc/config/rs6000/t-linux
@@ -6,3 +6,25 @@ HOST_LIBGCC2_CFLAGS += -mlong-double-128
# smaller and faster libgcc code. Directly specifying -mcmodel=small
# would need to take into account targets for which -mcmodel is invalid.
HOST_LIBGCC2_CFLAGS += -mno-minimal-toc
+
+# On the modules that deal with IBM 128-bit values, make sure that TFmode uses
+# the IBM extended double format. Also turn off gnu attributes on the static
+# modules.
+IBM128_STATIC_OBJS = ibm-ldouble$(objext) _powitf2$(objext) \
+ ppc64-fp$(objext) _divtc3$(object) _multc3$(object) \
+ _fixtfdi$(object) _fixunstfdi$(object) \
+ _floatditf$(objext) _floatunsditf$(objext)
+IBM128_SHARED_OBJS = $(IBM128_STATIC_OBJS:$(objext):_s$(objext))
+IBM128_OBJS = $(IBM128_STATIC_OBJS) $(IBM128_SHARED_OBJS)
+
+IBM128_CFLAGS = -Wno-psabi -mabi=ibmlongdouble -mno-gnu-attribute
+
+$(IBM128_OBJS) : INTERNAL_CFLAGS += $(IBM128_CFLAGS)
+
+# Turn off gnu attributes for long double size on all of the shared library
+# modules, but leave it on for the static modules, except for the functions
+# that explicitly process IBM 128-bit floating point. Shared libraries only
+# have one gnu attribute for the whole library, and it can lead to warnings if
+# somebody changes the long double format. We leave it on for the static
+# modules to catch mis-compilation errors.
+gcc_s_compile += -mno-gnu-attribute
diff --git a/libgcc/config/rs6000/t-ppc64-fp b/libgcc/config/rs6000/t-ppc64-fp
index 26d1730..999679f 100644
--- a/libgcc/config/rs6000/t-ppc64-fp
+++ b/libgcc/config/rs6000/t-ppc64-fp
@@ -1,2 +1 @@
-# Can be used unconditionally, wrapped in __powerpc64__ || __64BIT__ __ppc64__.
-LIB2ADD += $(srcdir)/config/rs6000/ppc64-fp.c
+LIB2_SIDITI_CONV_FUNCS = yes
diff --git a/libgcc/config/t-vxworks b/libgcc/config/t-vxworks
index 02e2efa..b4bb85b 100644
--- a/libgcc/config/t-vxworks
+++ b/libgcc/config/t-vxworks
@@ -4,7 +4,6 @@ LIBGCC2_DEBUG_CFLAGS =
# We provide our own implementation for __clear_cache, using a
# VxWorks specific entry point.
LIB2FUNCS_EXCLUDE += _clear_cache
-LIB2ADD += $(srcdir)/config/vxcache.c
# This ensures that the correct target headers are used; some VxWorks
# system headers have names that collide with GCC's internal (host)
diff --git a/libgcc/config/t-vxworks7 b/libgcc/config/t-vxworks7
index 20c72f4..6ddd3e8 100644
--- a/libgcc/config/t-vxworks7
+++ b/libgcc/config/t-vxworks7
@@ -4,7 +4,6 @@ LIBGCC2_DEBUG_CFLAGS =
# We provide our own implementation for __clear_cache, using a
# VxWorks specific entry point.
LIB2FUNCS_EXCLUDE += _clear_cache
-LIB2ADD += $(srcdir)/config/vxcache.c
# This ensures that the correct target headers are used; some VxWorks
# system headers have names that collide with GCC's internal (host)
diff --git a/libgcc/config/vxcache.c b/libgcc/config/vxcache.c
deleted file mode 100644
index e25e0cc..0000000
--- a/libgcc/config/vxcache.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright (C) 2018-2020 Free Software Foundation, Inc.
- Contributed by Alexandre Oliva <oliva@adacore.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.
-
-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/>. */
-
-/* Instruction cache invalidation routine using VxWorks' cacheLib. */
-
-#include <vxWorks.h>
-#include <cacheLib.h>
-
-void
-__clear_cache (char *beg __attribute__((__unused__)),
- char *end __attribute__((__unused__)))
-{
- cacheTextUpdate (beg, end - beg);
-}
diff --git a/libgcc/libgcc2.c b/libgcc/libgcc2.c
index e0a9fd7..61de3b4 100644
--- a/libgcc/libgcc2.c
+++ b/libgcc/libgcc2.c
@@ -75,9 +75,9 @@ __negdi2 (DWtype u)
Wtype
__addvSI3 (Wtype a, Wtype b)
{
- const Wtype w = (UWtype) a + (UWtype) b;
+ Wtype w;
- if (b >= 0 ? w < a : w > a)
+ if (__builtin_add_overflow (a, b, &w))
abort ();
return w;
@@ -86,9 +86,9 @@ __addvSI3 (Wtype a, Wtype b)
SItype
__addvsi3 (SItype a, SItype b)
{
- const SItype w = (USItype) a + (USItype) b;
+ SItype w;
- if (b >= 0 ? w < a : w > a)
+ if (__builtin_add_overflow (a, b, &w))
abort ();
return w;
@@ -100,9 +100,9 @@ __addvsi3 (SItype a, SItype b)
DWtype
__addvDI3 (DWtype a, DWtype b)
{
- const DWtype w = (UDWtype) a + (UDWtype) b;
+ DWtype w;
- if (b >= 0 ? w < a : w > a)
+ if (__builtin_add_overflow (a, b, &w))
abort ();
return w;
@@ -113,9 +113,9 @@ __addvDI3 (DWtype a, DWtype b)
Wtype
__subvSI3 (Wtype a, Wtype b)
{
- const Wtype w = (UWtype) a - (UWtype) b;
+ Wtype w;
- if (b >= 0 ? w > a : w < a)
+ if (__builtin_sub_overflow (a, b, &w))
abort ();
return w;
@@ -124,9 +124,9 @@ __subvSI3 (Wtype a, Wtype b)
SItype
__subvsi3 (SItype a, SItype b)
{
- const SItype w = (USItype) a - (USItype) b;
+ SItype w;
- if (b >= 0 ? w > a : w < a)
+ if (__builtin_sub_overflow (a, b, &w))
abort ();
return w;
@@ -138,9 +138,9 @@ __subvsi3 (SItype a, SItype b)
DWtype
__subvDI3 (DWtype a, DWtype b)
{
- const DWtype w = (UDWtype) a - (UDWtype) b;
+ DWtype w;
- if (b >= 0 ? w > a : w < a)
+ if (__builtin_sub_overflow (a, b, &w))
abort ();
return w;
@@ -151,22 +151,20 @@ __subvDI3 (DWtype a, DWtype b)
Wtype
__mulvSI3 (Wtype a, Wtype b)
{
- const DWtype w = (DWtype) a * (DWtype) b;
+ Wtype w;
- if ((Wtype) (w >> W_TYPE_SIZE) != (Wtype) w >> (W_TYPE_SIZE - 1))
+ if (__builtin_mul_overflow (a, b, &w))
abort ();
return w;
}
#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
-#undef WORD_SIZE
-#define WORD_SIZE (sizeof (SItype) * __CHAR_BIT__)
SItype
__mulvsi3 (SItype a, SItype b)
{
- const DItype w = (DItype) a * (DItype) b;
+ SItype w;
- if ((SItype) (w >> WORD_SIZE) != (SItype) w >> (WORD_SIZE-1))
+ if (__builtin_mul_overflow (a, b, &w))
abort ();
return w;
@@ -178,23 +176,23 @@ __mulvsi3 (SItype a, SItype b)
Wtype
__negvSI2 (Wtype a)
{
- const Wtype w = -(UWtype) a;
+ Wtype w;
- if (a >= 0 ? w > 0 : w < 0)
+ if (__builtin_sub_overflow (0, a, &w))
abort ();
- return w;
+ return w;
}
#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
SItype
__negvsi2 (SItype a)
{
- const SItype w = -(USItype) a;
+ SItype w;
- if (a >= 0 ? w > 0 : w < 0)
+ if (__builtin_sub_overflow (0, a, &w))
abort ();
- return w;
+ return w;
}
#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
#endif
@@ -203,9 +201,9 @@ __negvsi2 (SItype a)
DWtype
__negvDI2 (DWtype a)
{
- const DWtype w = -(UDWtype) a;
+ DWtype w;
- if (a >= 0 ? w > 0 : w < 0)
+ if (__builtin_sub_overflow (0, a, &w))
abort ();
return w;
@@ -216,37 +214,25 @@ __negvDI2 (DWtype a)
Wtype
__absvSI2 (Wtype a)
{
- Wtype w = a;
-
- if (a < 0)
-#ifdef L_negvsi2
- w = __negvSI2 (a);
-#else
- w = -(UWtype) a;
+ const Wtype v = 0 - (a < 0);
+ Wtype w;
- if (w < 0)
+ if (__builtin_add_overflow (a, v, &w))
abort ();
-#endif
- return w;
+ return v ^ w;
}
#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
SItype
__absvsi2 (SItype a)
{
- SItype w = a;
-
- if (a < 0)
-#ifdef L_negvsi2
- w = __negvsi2 (a);
-#else
- w = -(USItype) a;
+ const SItype v = 0 - (a < 0);
+ SItype w;
- if (w < 0)
+ if (__builtin_add_overflow (a, v, &w))
abort ();
-#endif
- return w;
+ return v ^ w;
}
#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
#endif
@@ -255,19 +241,13 @@ __absvsi2 (SItype a)
DWtype
__absvDI2 (DWtype a)
{
- DWtype w = a;
-
- if (a < 0)
-#ifdef L_negvdi2
- w = __negvDI2 (a);
-#else
- w = -(UDWtype) a;
+ const DWtype v = 0 - (a < 0);
+ DWtype w;
- if (w < 0)
+ if (__builtin_add_overflow (a, v, &w))
abort ();
-#endif
- return w;
+ return v ^ w;
}
#endif
@@ -488,10 +468,10 @@ __ashrdi3 (DWtype u, shift_count_type b)
SItype
__bswapsi2 (SItype u)
{
- return ((((u) & 0xff000000) >> 24)
- | (((u) & 0x00ff0000) >> 8)
- | (((u) & 0x0000ff00) << 8)
- | (((u) & 0x000000ff) << 24));
+ return ((((u) & 0xff000000u) >> 24)
+ | (((u) & 0x00ff0000u) >> 8)
+ | (((u) & 0x0000ff00u) << 8)
+ | (((u) & 0x000000ffu) << 24));
}
#endif
#ifdef L_bswapdi2
@@ -953,7 +933,7 @@ __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
aligns the divisor under the dividend and then perform number of
test-subtract iterations which shift the dividend left. Number of
iterations is k + 1 where k is the number of bit positions the
- divisor must be shifted left to align it under the dividend.
+ divisor must be shifted left to align it under the dividend.
quotient bits can be saved in the rightmost positions of the dividend
as it shifts left on each test-subtract iteration. */
@@ -965,7 +945,7 @@ __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
k = lz1 - lz2;
y = (y << k);
- /* Dividend can exceed 2 ^ (width − 1) − 1 but still be less than the
+ /* Dividend can exceed 2 ^ (width - 1) - 1 but still be less than the
aligned divisor. Normal iteration can drops the high order bit
of the dividend. Therefore, first test-subtract iteration is a
special case, saving its quotient bit in a separate location and
@@ -1325,37 +1305,15 @@ __udivdi3 (UDWtype n, UDWtype d)
cmp_return_type
__cmpdi2 (DWtype a, DWtype b)
{
- const DWunion au = {.ll = a};
- const DWunion bu = {.ll = b};
-
- if (au.s.high < bu.s.high)
- return 0;
- else if (au.s.high > bu.s.high)
- return 2;
- if ((UWtype) au.s.low < (UWtype) bu.s.low)
- return 0;
- else if ((UWtype) au.s.low > (UWtype) bu.s.low)
- return 2;
- return 1;
+ return (a > b) - (a < b) + 1;
}
#endif
#ifdef L_ucmpdi2
cmp_return_type
-__ucmpdi2 (DWtype a, DWtype b)
+__ucmpdi2 (UDWtype a, UDWtype b)
{
- const DWunion au = {.ll = a};
- const DWunion bu = {.ll = b};
-
- if ((UWtype) au.s.high < (UWtype) bu.s.high)
- return 0;
- else if ((UWtype) au.s.high > (UWtype) bu.s.high)
- return 2;
- if ((UWtype) au.s.low < (UWtype) bu.s.low)
- return 0;
- else if ((UWtype) au.s.low > (UWtype) bu.s.low)
- return 2;
- return 1;
+ return (a > b) - (a < b) + 1;
}
#endif
diff --git a/libgcc/libgcc2.h b/libgcc/libgcc2.h
index 1c20ffc..22a2706 100644
--- a/libgcc/libgcc2.h
+++ b/libgcc/libgcc2.h
@@ -402,7 +402,7 @@ extern UWtype __udiv_w_sdiv (UWtype *, UWtype, UWtype, UWtype);
#endif
extern cmp_return_type __cmpdi2 (DWtype, DWtype);
-extern cmp_return_type __ucmpdi2 (DWtype, DWtype);
+extern cmp_return_type __ucmpdi2 (UDWtype, UDWtype);
#if MIN_UNITS_PER_WORD > 1
extern SItype __bswapsi2 (SItype);
diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c
index 6e50405..e60c9fe 100644
--- a/libgcc/unwind-dw2-fde-dip.c
+++ b/libgcc/unwind-dw2-fde-dip.c
@@ -71,6 +71,7 @@
#endif
#if !defined(inhibit_libc) && defined(HAVE_LD_EH_FRAME_HDR) \
+ && defined(TARGET_DL_ITERATE_PHDR) \
&& (defined(__OpenBSD__) || defined(__NetBSD__))
# define ElfW(type) Elf_##type
# define USE_PT_GNU_EH_FRAME
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index a4af74b..07e1e94 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,34 @@
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ * configure: Regenerate.
+
+2020-11-26 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * io/io.h [HAVE_NEWLOCALE]: Also check for HAVE_FREELOCALE and
+ HAVE_USELOCALE.
+ [HAVE_FREELOCALE && HAVE_NEWLOCALE && HAVE_USELOCALE]
+ (HAVE_POSIX_2008_LOCALE): New macro.
+ (st_parameter_dt) [HAVE_NEWLOCALE]: Check for
+ HAVE_POSIX_2008_LOCALE instead.
+ * io/transfer.c (data_transfer_init_worker, finalize_transfer)
+ [HAVE_USELOCALE]: Check for HAVE_POSIX_2008_LOCALE instead.
+ * io/unit.c [HAVE_NEWLOCALE]: Likewise.
+ (init_units) [HAVE_NEWLOCALE]: Likewise.
+ (close_units) [HAVE_FREELOCALE]: Likewise.
+ * runtime/error.c (gf_strerror) [HAVE_USELOCALE]: Likewise.
+
+2020-11-26 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * libgfortran.h: Use #if rather than #ifdef with
+ __FLT_HAS_INFINITY__, __DBL_HAS_INFINITY__,
+ __LDBL_HAS_INFINITY__, __FLT_HAS_QUIET_NAN__,
+ __DBL_HAS_QUIET_NAN__, and __LDBL_HAS_QUIET_NAN__.
+
+2020-11-21 Iain Sandoe <iain@sandoe.co.uk>
+
+ * intrinsics/execute_command_line.c (environ): Use
+ _NSGetEnviron to get the environment pointer on Darwin.
+
2020-10-30 Harald Anlauf <anlauf@gmx.de>
* intrinsics/random.c (SZ_IN_INT_4): Define size of state in int32_t.
diff --git a/libgfortran/configure b/libgfortran/configure
index 99cca96..9ec0158 100755
--- a/libgfortran/configure
+++ b/libgfortran/configure
@@ -11002,7 +11002,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -11014,7 +11014,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -14849,7 +14849,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds_FC='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds_FC='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds_FC='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -14861,7 +14861,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds_FC='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds_FC='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds_FC='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
diff --git a/libgfortran/intrinsics/execute_command_line.c b/libgfortran/intrinsics/execute_command_line.c
index 71d61a7..6d7b8fc 100644
--- a/libgfortran/intrinsics/execute_command_line.c
+++ b/libgfortran/intrinsics/execute_command_line.c
@@ -34,7 +34,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#endif
#ifdef HAVE_POSIX_SPAWN
#include <spawn.h>
+# ifdef __APPLE__
+# include <crt_externs.h>
+# define environ (*_NSGetEnviron ())
+# else
extern char **environ;
+# endif
#endif
#if defined(HAVE_POSIX_SPAWN) || defined(HAVE_FORK)
#include <signal.h>
diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h
index ab4a103..b4a8113 100644
--- a/libgfortran/io/io.h
+++ b/libgfortran/io/io.h
@@ -52,8 +52,12 @@ struct format_data;
typedef struct fnode fnode;
struct gfc_unit;
-#ifdef HAVE_NEWLOCALE
-/* We have POSIX 2008 extended locale stuff. */
+#if defined (HAVE_FREELOCALE) && defined (HAVE_NEWLOCALE) \
+ && defined (HAVE_USELOCALE)
+/* We have POSIX 2008 extended locale stuff. We only choose to use it
+ if all the functions required are present as some systems, e.g. NetBSD
+ do not have `uselocale'. */
+#define HAVE_POSIX_2008_LOCALE
extern locale_t c_locale;
internal_proto(c_locale);
#else
@@ -562,7 +566,7 @@ typedef struct st_parameter_dt
char *line_buffer;
struct format_data *fmt;
namelist_info *ionml;
-#ifdef HAVE_NEWLOCALE
+#ifdef HAVE_POSIX_2008_LOCALE
locale_t old_locale;
#endif
/* Current position within the look-ahead line buffer. */
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index dc18bc3..c36d8bc 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -3410,7 +3410,7 @@ data_transfer_init_worker (st_parameter_dt *dtp, int read_flag)
if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED)
{
-#ifdef HAVE_USELOCALE
+#ifdef HAVE_POSIX_2008_LOCALE
dtp->u.p.old_locale = uselocale (c_locale);
#else
__gthread_mutex_lock (&old_locale_lock);
@@ -4243,7 +4243,7 @@ finalize_transfer (st_parameter_dt *dtp)
}
}
-#ifdef HAVE_USELOCALE
+#ifdef HAVE_POSIX_2008_LOCALE
if (dtp->u.p.old_locale != (locale_t) 0)
{
uselocale (dtp->u.p.old_locale);
diff --git a/libgfortran/io/unit.c b/libgfortran/io/unit.c
index a3b0656..faf6299 100644
--- a/libgfortran/io/unit.c
+++ b/libgfortran/io/unit.c
@@ -114,7 +114,7 @@ static char stdout_name[] = "stdout";
static char stderr_name[] = "stderr";
-#ifdef HAVE_NEWLOCALE
+#ifdef HAVE_POSIX_2008_LOCALE
locale_t c_locale;
#else
/* If we don't have POSIX 2008 per-thread locales, we need to use the
@@ -586,7 +586,7 @@ init_units (void)
{
gfc_unit *u;
-#ifdef HAVE_NEWLOCALE
+#ifdef HAVE_POSIX_2008_LOCALE
c_locale = newlocale (0, "C", 0);
#else
#ifndef __GTHREAD_MUTEX_INIT
@@ -803,7 +803,7 @@ close_units (void)
free (newunits);
-#ifdef HAVE_FREELOCALE
+#ifdef HAVE_POSIX_2008_LOCALE
freelocale (c_locale);
#endif
}
diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
index 8c539e0..e9c5481 100644
--- a/libgfortran/libgfortran.h
+++ b/libgfortran/libgfortran.h
@@ -288,13 +288,13 @@ typedef GFC_UINTEGER_4 gfc_char4_t;
/* M{IN,AX}{LOC,VAL} need also infinities and NaNs if supported. */
-#ifdef __FLT_HAS_INFINITY__
+#if __FLT_HAS_INFINITY__
# define GFC_REAL_4_INFINITY __builtin_inff ()
#endif
-#ifdef __DBL_HAS_INFINITY__
+#if __DBL_HAS_INFINITY__
# define GFC_REAL_8_INFINITY __builtin_inf ()
#endif
-#ifdef __LDBL_HAS_INFINITY__
+#if __LDBL_HAS_INFINITY__
# ifdef HAVE_GFC_REAL_10
# define GFC_REAL_10_INFINITY __builtin_infl ()
# endif
@@ -306,13 +306,13 @@ typedef GFC_UINTEGER_4 gfc_char4_t;
# endif
# endif
#endif
-#ifdef __FLT_HAS_QUIET_NAN__
+#if __FLT_HAS_QUIET_NAN__
# define GFC_REAL_4_QUIET_NAN __builtin_nanf ("")
#endif
-#ifdef __DBL_HAS_QUIET_NAN__
+#if __DBL_HAS_QUIET_NAN__
# define GFC_REAL_8_QUIET_NAN __builtin_nan ("")
#endif
-#ifdef __LDBL_HAS_QUIET_NAN__
+#if __LDBL_HAS_QUIET_NAN__
# ifdef HAVE_GFC_REAL_10
# define GFC_REAL_10_QUIET_NAN __builtin_nanl ("")
# endif
diff --git a/libgfortran/runtime/error.c b/libgfortran/runtime/error.c
index ff6b852..a401dba 100644
--- a/libgfortran/runtime/error.c
+++ b/libgfortran/runtime/error.c
@@ -272,7 +272,7 @@ gf_strerror (int errnum,
p = strerror (errnum);
return p;
#elif defined(HAVE_STRERROR_R)
-#ifdef HAVE_USELOCALE
+#ifdef HAVE_POSIX_2008_LOCALE
/* Some targets (Darwin at least) have the POSIX 2008 extended
locale functions, but not strerror_l. So reset the per-thread
locale here. */
diff --git a/libgo/MERGE b/libgo/MERGE
index ad239c9..b753907 100644
--- a/libgo/MERGE
+++ b/libgo/MERGE
@@ -1,4 +1,4 @@
-0e953add9656c32a788e06438cd7b533e968b7f8
+c53315d6cf1b4bfea6ff356b4a1524778c683bb9
The first line of this file holds the git revision number of the
last merge done from the master library sources.
diff --git a/libgo/Makefile.am b/libgo/Makefile.am
index f7a163e..4d3e54e 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -439,7 +439,6 @@ runtime_files = \
runtime/go-assert.c \
runtime/go-caller.c \
runtime/go-callers.c \
- runtime/go-cdiv.c \
runtime/go-cgo.c \
runtime/go-construct-map.c \
runtime/go-ffi.c \
diff --git a/libgo/Makefile.in b/libgo/Makefile.in
index ba202a6..d6ac066 100644
--- a/libgo/Makefile.in
+++ b/libgo/Makefile.in
@@ -240,12 +240,11 @@ am__objects_2 = $(am__objects_1)
@LIBGO_IS_RTEMS_TRUE@am__objects_3 = \
@LIBGO_IS_RTEMS_TRUE@ runtime/rtems-task-variable-add.lo
am__objects_4 = runtime/aeshash.lo runtime/go-assert.lo \
- runtime/go-caller.lo runtime/go-callers.lo runtime/go-cdiv.lo \
- runtime/go-cgo.lo runtime/go-construct-map.lo \
- runtime/go-ffi.lo runtime/go-fieldtrack.lo \
- runtime/go-matherr.lo runtime/go-memclr.lo \
- runtime/go-memequal.lo runtime/go-nanotime.lo \
- runtime/go-now.lo runtime/go-nosys.lo \
+ runtime/go-caller.lo runtime/go-callers.lo runtime/go-cgo.lo \
+ runtime/go-construct-map.lo runtime/go-ffi.lo \
+ runtime/go-fieldtrack.lo runtime/go-matherr.lo \
+ runtime/go-memclr.lo runtime/go-memequal.lo \
+ runtime/go-nanotime.lo runtime/go-now.lo runtime/go-nosys.lo \
runtime/go-reflect-call.lo runtime/go-setenv.lo \
runtime/go-signal.lo runtime/go-unsafe-pointer.lo \
runtime/go-unsetenv.lo runtime/go-unwind.lo \
@@ -892,7 +891,6 @@ runtime_files = \
runtime/go-assert.c \
runtime/go-caller.c \
runtime/go-callers.c \
- runtime/go-cdiv.c \
runtime/go-cgo.c \
runtime/go-construct-map.c \
runtime/go-ffi.c \
@@ -1343,8 +1341,6 @@ runtime/go-caller.lo: runtime/$(am__dirstamp) \
runtime/$(DEPDIR)/$(am__dirstamp)
runtime/go-callers.lo: runtime/$(am__dirstamp) \
runtime/$(DEPDIR)/$(am__dirstamp)
-runtime/go-cdiv.lo: runtime/$(am__dirstamp) \
- runtime/$(DEPDIR)/$(am__dirstamp)
runtime/go-cgo.lo: runtime/$(am__dirstamp) \
runtime/$(DEPDIR)/$(am__dirstamp)
runtime/go-construct-map.lo: runtime/$(am__dirstamp) \
@@ -1417,7 +1413,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-assert.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-caller.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-callers.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-cdiv.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-cgo.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-construct-map.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-context.Plo@am__quote@
diff --git a/libgo/VERSION b/libgo/VERSION
index baff222..7014547 100644
--- a/libgo/VERSION
+++ b/libgo/VERSION
@@ -1 +1 @@
-go1.15.4
+go1.15.5
diff --git a/libgo/check-packages.txt b/libgo/check-packages.txt
index efa7d19..da77e84 100644
--- a/libgo/check-packages.txt
+++ b/libgo/check-packages.txt
@@ -22,6 +22,7 @@ cmd/go/internal/work
cmd/internal/buildid
cmd/internal/edit
cmd/internal/objabi
+cmd/internal/pkgpath
cmd/internal/test2json
compress/bzip2
compress/flate
diff --git a/libgo/configure b/libgo/configure
index e7379f8..1d7d007 100755
--- a/libgo/configure
+++ b/libgo/configure
@@ -2551,7 +2551,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
ac_config_headers="$ac_config_headers config.h"
-libtool_VERSION=17:0:0
+libtool_VERSION=18:0:0
# Default to --enable-multilib
diff --git a/libgo/configure.ac b/libgo/configure.ac
index 80537f5..5013f41 100644
--- a/libgo/configure.ac
+++ b/libgo/configure.ac
@@ -10,7 +10,7 @@ AC_INIT(package-unused, version-unused,, libgo)
AC_CONFIG_SRCDIR(Makefile.am)
AC_CONFIG_HEADER(config.h)
-libtool_VERSION=17:0:0
+libtool_VERSION=18:0:0
AC_SUBST(libtool_VERSION)
AM_ENABLE_MULTILIB(, ..)
diff --git a/libgo/go/cmd/cgo/main.go b/libgo/go/cmd/cgo/main.go
index 7fc2508..4952118 100644
--- a/libgo/go/cmd/cgo/main.go
+++ b/libgo/go/cmd/cgo/main.go
@@ -244,8 +244,7 @@ var exportHeader = flag.String("exportheader", "", "where to write export header
var gccgo = flag.Bool("gccgo", false, "generate files for use with gccgo")
var gccgoprefix = flag.String("gccgoprefix", "", "-fgo-prefix option used with gccgo")
var gccgopkgpath = flag.String("gccgopkgpath", "", "-fgo-pkgpath option used with gccgo")
-var gccgoMangleCheckDone bool
-var gccgoNewmanglingInEffect bool
+var gccgoMangler func(string) string
var importRuntimeCgo = flag.Bool("import_runtime_cgo", true, "import runtime/cgo in generated code")
var importSyscall = flag.Bool("import_syscall", true, "import syscall in generated code")
var goarch, goos string
diff --git a/libgo/go/cmd/cgo/out.go b/libgo/go/cmd/cgo/out.go
index dd03f7d..1c143d7 100644
--- a/libgo/go/cmd/cgo/out.go
+++ b/libgo/go/cmd/cgo/out.go
@@ -6,6 +6,7 @@ package main
import (
"bytes"
+ "cmd/internal/pkgpath"
"debug/elf"
"debug/macho"
"debug/pe"
@@ -15,7 +16,6 @@ import (
"go/token"
"internal/xcoff"
"io"
- "io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -191,7 +191,7 @@ func (p *Package) writeDefs() {
panic(fmt.Errorf("invalid var kind %q", n.Kind))
}
if *gccgo {
- fmt.Fprintf(fc, `extern void *%s __asm__("%s.%s");`, n.Mangle, gccgoSymbolPrefix, n.Mangle)
+ fmt.Fprintf(fc, `extern void *%s __asm__("%s.%s");`, n.Mangle, gccgoSymbolPrefix, gccgoToSymbol(n.Mangle))
fmt.Fprintf(&gccgoInit, "\t%s = &%s;\n", n.Mangle, n.C)
fmt.Fprintf(fc, "\n")
}
@@ -341,6 +341,8 @@ func dynimport(obj string) {
if s.Version != "" {
targ += "#" + s.Version
}
+ checkImportSymName(s.Name)
+ checkImportSymName(targ)
fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", s.Name, targ, s.Library)
}
lib, _ := f.ImportedLibraries()
@@ -356,6 +358,7 @@ func dynimport(obj string) {
if len(s) > 0 && s[0] == '_' {
s = s[1:]
}
+ checkImportSymName(s)
fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", s, s, "")
}
lib, _ := f.ImportedLibraries()
@@ -370,6 +373,8 @@ func dynimport(obj string) {
for _, s := range sym {
ss := strings.Split(s, ":")
name := strings.Split(ss[0], "@")[0]
+ checkImportSymName(name)
+ checkImportSymName(ss[0])
fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", name, ss[0], strings.ToLower(ss[1]))
}
return
@@ -387,6 +392,7 @@ func dynimport(obj string) {
// Go symbols.
continue
}
+ checkImportSymName(s.Name)
fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", s.Name, s.Name, s.Library)
}
lib, err := f.ImportedLibraries()
@@ -402,6 +408,23 @@ func dynimport(obj string) {
fatalf("cannot parse %s as ELF, Mach-O, PE or XCOFF", obj)
}
+// checkImportSymName checks a symbol name we are going to emit as part
+// of a //go:cgo_import_dynamic pragma. These names come from object
+// files, so they may be corrupt. We are going to emit them unquoted,
+// so while they don't need to be valid symbol names (and in some cases,
+// involving symbol versions, they won't be) they must contain only
+// graphic characters and must not contain Go comments.
+func checkImportSymName(s string) {
+ for _, c := range s {
+ if !unicode.IsGraphic(c) || unicode.IsSpace(c) {
+ fatalf("dynamic symbol %q contains unsupported character", s)
+ }
+ }
+ if strings.Index(s, "//") >= 0 || strings.Index(s, "/*") >= 0 {
+ fatalf("dynamic symbol %q contains Go comment")
+ }
+}
+
// Construct a gcc struct matching the gc argument frame.
// Assumes that in gcc, char is 1 byte, short 2 bytes, int 4 bytes, long long 8 bytes.
// These assumptions are checked by the gccProlog.
@@ -1168,7 +1191,7 @@ func (p *Package) writeGccgoExports(fgo2, fm, fgcc, fgcch io.Writer) {
// will not be able to link against it from the C
// code.
goName := "Cgoexp_" + exp.ExpName
- fmt.Fprintf(fgcc, `extern %s %s %s __asm__("%s.%s");`, cRet, goName, cParams, gccgoSymbolPrefix, goName)
+ fmt.Fprintf(fgcc, `extern %s %s %s __asm__("%s.%s");`, cRet, goName, cParams, gccgoSymbolPrefix, gccgoToSymbol(goName))
fmt.Fprint(fgcc, "\n")
fmt.Fprint(fgcc, "\nCGO_NO_SANITIZE_THREAD\n")
@@ -1202,7 +1225,7 @@ func (p *Package) writeGccgoExports(fgo2, fm, fgcc, fgcch io.Writer) {
fmt.Fprint(fgcc, "}\n")
// Dummy declaration for _cgo_main.c
- fmt.Fprintf(fm, `char %s[1] __asm__("%s.%s");`, goName, gccgoSymbolPrefix, goName)
+ fmt.Fprintf(fm, `char %s[1] __asm__("%s.%s");`, goName, gccgoSymbolPrefix, gccgoToSymbol(goName))
fmt.Fprint(fm, "\n")
// For gccgo we use a wrapper function in Go, in order
@@ -1286,112 +1309,23 @@ func (p *Package) writeExportHeader(fgcch io.Writer) {
fmt.Fprintf(fgcch, "%s\n", p.gccExportHeaderProlog())
}
-// gccgoUsesNewMangling reports whether gccgo uses the new collision-free
-// packagepath mangling scheme (see determineGccgoManglingScheme for more
-// info).
-func gccgoUsesNewMangling() bool {
- if !gccgoMangleCheckDone {
- gccgoNewmanglingInEffect = determineGccgoManglingScheme()
- gccgoMangleCheckDone = true
- }
- return gccgoNewmanglingInEffect
-}
-
-const mangleCheckCode = `
-package läufer
-func Run(x int) int {
- return 1
-}
-`
-
-// determineGccgoManglingScheme performs a runtime test to see which
-// flavor of packagepath mangling gccgo is using. Older versions of
-// gccgo use a simple mangling scheme where there can be collisions
-// between packages whose paths are different but mangle to the same
-// string. More recent versions of gccgo use a new mangler that avoids
-// these collisions. Return value is whether gccgo uses the new mangling.
-func determineGccgoManglingScheme() bool {
-
- // Emit a small Go file for gccgo to compile.
- filepat := "*_gccgo_manglecheck.go"
- var f *os.File
- var err error
- if f, err = ioutil.TempFile(*objDir, filepat); err != nil {
- fatalf("%v", err)
- }
- gofilename := f.Name()
- defer os.Remove(gofilename)
-
- if err = ioutil.WriteFile(gofilename, []byte(mangleCheckCode), 0666); err != nil {
- fatalf("%v", err)
- }
-
- // Compile with gccgo, capturing generated assembly.
- gccgocmd := os.Getenv("GCCGO")
- if gccgocmd == "" {
- gpath, gerr := exec.LookPath("gccgo")
- if gerr != nil {
- fatalf("unable to locate gccgo: %v", gerr)
- }
- gccgocmd = gpath
- }
- cmd := exec.Command(gccgocmd, "-S", "-o", "-", gofilename)
- buf, cerr := cmd.CombinedOutput()
- if cerr != nil {
- fatalf("%s", cerr)
- }
-
- // New mangling: expect go.l..u00e4ufer.Run
- // Old mangling: expect go.l__ufer.Run
- return regexp.MustCompile(`go\.l\.\.u00e4ufer\.Run`).Match(buf)
-}
-
-// gccgoPkgpathToSymbolNew converts a package path to a gccgo-style
-// package symbol.
-func gccgoPkgpathToSymbolNew(ppath string) string {
- bsl := []byte{}
- changed := false
- for _, c := range []byte(ppath) {
- switch {
- case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z',
- '0' <= c && c <= '9', c == '_':
- bsl = append(bsl, c)
- case c == '.':
- bsl = append(bsl, ".x2e"...)
- default:
- changed = true
- encbytes := []byte(fmt.Sprintf("..z%02x", c))
- bsl = append(bsl, encbytes...)
+// gccgoToSymbol converts a name to a mangled symbol for gccgo.
+func gccgoToSymbol(ppath string) string {
+ if gccgoMangler == nil {
+ var err error
+ cmd := os.Getenv("GCCGO")
+ if cmd == "" {
+ cmd, err = exec.LookPath("gccgo")
+ if err != nil {
+ fatalf("unable to locate gccgo: %v", err)
+ }
}
- }
- if !changed {
- return ppath
- }
- return string(bsl)
-}
-
-// gccgoPkgpathToSymbolOld converts a package path to a gccgo-style
-// package symbol using the older mangling scheme.
-func gccgoPkgpathToSymbolOld(ppath string) string {
- clean := func(r rune) rune {
- switch {
- case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
- '0' <= r && r <= '9':
- return r
+ gccgoMangler, err = pkgpath.ToSymbolFunc(cmd, *objDir)
+ if err != nil {
+ fatalf("%v", err)
}
- return '_'
- }
- return strings.Map(clean, ppath)
-}
-
-// gccgoPkgpathToSymbol converts a package path to a mangled packagepath
-// symbol.
-func gccgoPkgpathToSymbol(ppath string) string {
- if gccgoUsesNewMangling() {
- return gccgoPkgpathToSymbolNew(ppath)
- } else {
- return gccgoPkgpathToSymbolOld(ppath)
}
+ return gccgoMangler(ppath)
}
// Return the package prefix when using gccgo.
@@ -1401,12 +1335,12 @@ func (p *Package) gccgoSymbolPrefix() string {
}
if *gccgopkgpath != "" {
- return gccgoPkgpathToSymbol(*gccgopkgpath)
+ return gccgoToSymbol(*gccgopkgpath)
}
if *gccgoprefix == "" && p.PackageName == "main" {
return "main"
}
- prefix := gccgoPkgpathToSymbol(*gccgoprefix)
+ prefix := gccgoToSymbol(*gccgoprefix)
if prefix == "" {
prefix = "go"
}
@@ -1798,8 +1732,12 @@ void _cgoPREFIX_Cfunc__Cmalloc(void *v) {
`
func (p *Package) cPrologGccgo() string {
- return strings.Replace(strings.Replace(cPrologGccgo, "PREFIX", cPrefix, -1),
- "GCCGOSYMBOLPREF", p.gccgoSymbolPrefix(), -1)
+ r := strings.NewReplacer(
+ "PREFIX", cPrefix,
+ "GCCGOSYMBOLPREF", p.gccgoSymbolPrefix(),
+ "_cgoCheckPointer", gccgoToSymbol("_cgoCheckPointer"),
+ "_cgoCheckResult", gccgoToSymbol("_cgoCheckResult"))
+ return r.Replace(cPrologGccgo)
}
const cPrologGccgo = `
diff --git a/libgo/go/cmd/go/internal/work/exec.go b/libgo/go/cmd/go/internal/work/exec.go
index 65f3011..4f68943 100644
--- a/libgo/go/cmd/go/internal/work/exec.go
+++ b/libgo/go/cmd/go/internal/work/exec.go
@@ -2723,6 +2723,66 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo
noCompiler()
}
+ // Double check the //go:cgo_ldflag comments in the generated files.
+ // The compiler only permits such comments in files whose base name
+ // starts with "_cgo_". Make sure that the comments in those files
+ // are safe. This is a backstop against people somehow smuggling
+ // such a comment into a file generated by cgo.
+ if cfg.BuildToolchainName == "gc" && !cfg.BuildN {
+ var flags []string
+ for _, f := range outGo {
+ if !strings.HasPrefix(filepath.Base(f), "_cgo_") {
+ continue
+ }
+
+ src, err := ioutil.ReadFile(f)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ const cgoLdflag = "//go:cgo_ldflag"
+ idx := bytes.Index(src, []byte(cgoLdflag))
+ for idx >= 0 {
+ // We are looking at //go:cgo_ldflag.
+ // Find start of line.
+ start := bytes.LastIndex(src[:idx], []byte("\n"))
+ if start == -1 {
+ start = 0
+ }
+
+ // Find end of line.
+ end := bytes.Index(src[idx:], []byte("\n"))
+ if end == -1 {
+ end = len(src)
+ } else {
+ end += idx
+ }
+
+ // Check for first line comment in line.
+ // We don't worry about /* */ comments,
+ // which normally won't appear in files
+ // generated by cgo.
+ commentStart := bytes.Index(src[start:], []byte("//"))
+ commentStart += start
+ // If that line comment is //go:cgo_ldflag,
+ // it's a match.
+ if bytes.HasPrefix(src[commentStart:], []byte(cgoLdflag)) {
+ // Pull out the flag, and unquote it.
+ // This is what the compiler does.
+ flag := string(src[idx+len(cgoLdflag) : end])
+ flag = strings.TrimSpace(flag)
+ flag = strings.Trim(flag, `"`)
+ flags = append(flags, flag)
+ }
+ src = src[end:]
+ idx = bytes.Index(src, []byte(cgoLdflag))
+ }
+ }
+ if err := checkLinkerFlags("LDFLAGS", "go:cgo_ldflag", flags); err != nil {
+ return nil, nil, err
+ }
+ }
+
return outGo, outObj, nil
}
diff --git a/libgo/go/cmd/go/internal/work/gccgo.go b/libgo/go/cmd/go/internal/work/gccgo.go
index 63d5c62..dbaff70 100644
--- a/libgo/go/cmd/go/internal/work/gccgo.go
+++ b/libgo/go/cmd/go/internal/work/gccgo.go
@@ -11,11 +11,13 @@ import (
"os/exec"
"path/filepath"
"strings"
+ "sync"
"cmd/go/internal/base"
"cmd/go/internal/cfg"
"cmd/go/internal/load"
"cmd/go/internal/str"
+ "cmd/internal/pkgpath"
)
// The Gccgo toolchain.
@@ -174,7 +176,7 @@ func (tools gccgoToolchain) asm(b *Builder, a *Action, sfiles []string) ([]strin
ofiles = append(ofiles, ofile)
sfile = mkAbs(p.Dir, sfile)
defs := []string{"-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch}
- if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
+ if pkgpath := tools.gccgoCleanPkgpath(b, p); pkgpath != "" {
defs = append(defs, `-D`, `GOPKGPATH=`+pkgpath)
}
defs = tools.maybePIC(defs)
@@ -556,7 +558,7 @@ func (tools gccgoToolchain) cc(b *Builder, a *Action, ofile, cfile string) error
cfile = mkAbs(p.Dir, cfile)
defs := []string{"-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch}
defs = append(defs, b.gccArchArgs()...)
- if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
+ if pkgpath := tools.gccgoCleanPkgpath(b, p); pkgpath != "" {
defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
}
compiler := envList("CC", cfg.DefaultCC(cfg.Goos, cfg.Goarch))
@@ -596,28 +598,23 @@ func gccgoPkgpath(p *load.Package) string {
return p.ImportPath
}
-// gccgoCleanPkgpath returns the form of p's pkgpath that gccgo uses
-// for symbol names. This is like gccgoPkgpathToSymbolNew in cmd/cgo/out.go.
-func gccgoCleanPkgpath(p *load.Package) string {
- ppath := gccgoPkgpath(p)
- bsl := []byte{}
- changed := false
- for _, c := range []byte(ppath) {
- switch {
- case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z',
- '0' <= c && c <= '9', c == '_':
- bsl = append(bsl, c)
- case c == '.':
- bsl = append(bsl, ".x2e"...)
- changed = true
- default:
- encbytes := []byte(fmt.Sprintf("..z%02x", c))
- bsl = append(bsl, encbytes...)
- changed = true
+var gccgoToSymbolFuncOnce sync.Once
+var gccgoToSymbolFunc func(string) string
+
+func (tools gccgoToolchain) gccgoCleanPkgpath(b *Builder, p *load.Package) string {
+ gccgoToSymbolFuncOnce.Do(func() {
+ if cfg.BuildN {
+ gccgoToSymbolFunc = func(s string) string { return s }
+ return
}
- }
- if !changed {
- return ppath
- }
- return string(bsl)
+ fn, err := pkgpath.ToSymbolFunc(tools.compiler(), b.WorkDir)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "cmd/go: %v\n", err)
+ base.SetExitStatus(2)
+ base.Exit()
+ }
+ gccgoToSymbolFunc = fn
+ })
+
+ return gccgoToSymbolFunc(gccgoPkgpath(p))
}
diff --git a/libgo/go/cmd/go/internal/work/security.go b/libgo/go/cmd/go/internal/work/security.go
index 3ee68ac..0d96282 100644
--- a/libgo/go/cmd/go/internal/work/security.go
+++ b/libgo/go/cmd/go/internal/work/security.go
@@ -42,8 +42,8 @@ import (
var re = lazyregexp.New
var validCompilerFlags = []*lazyregexp.Regexp{
- re(`-D([A-Za-z_].*)`),
- re(`-U([A-Za-z_]*)`),
+ re(`-D([A-Za-z_][A-Za-z0-9_]*)(=[^@\-]*)?`),
+ re(`-U([A-Za-z_][A-Za-z0-9_]*)`),
re(`-F([^@\-].*)`),
re(`-I([^@\-].*)`),
re(`-O`),
@@ -51,8 +51,8 @@ var validCompilerFlags = []*lazyregexp.Regexp{
re(`-W`),
re(`-W([^@,]+)`), // -Wall but not -Wa,-foo.
re(`-Wa,-mbig-obj`),
- re(`-Wp,-D([A-Za-z_].*)`),
- re(`-Wp,-U([A-Za-z_]*)`),
+ re(`-Wp,-D([A-Za-z_][A-Za-z0-9_]*)(=[^@,\-]*)?`),
+ re(`-Wp,-U([A-Za-z_][A-Za-z0-9_]*)`),
re(`-ansi`),
re(`-f(no-)?asynchronous-unwind-tables`),
re(`-f(no-)?blocks`),
diff --git a/libgo/go/cmd/go/internal/work/security_test.go b/libgo/go/cmd/go/internal/work/security_test.go
index 11e74f2..aec9789 100644
--- a/libgo/go/cmd/go/internal/work/security_test.go
+++ b/libgo/go/cmd/go/internal/work/security_test.go
@@ -13,6 +13,7 @@ var goodCompilerFlags = [][]string{
{"-DFOO"},
{"-Dfoo=bar"},
{"-Ufoo"},
+ {"-Ufoo1"},
{"-F/Qt"},
{"-I/"},
{"-I/etc/passwd"},
@@ -24,6 +25,8 @@ var goodCompilerFlags = [][]string{
{"-Wall"},
{"-Wp,-Dfoo=bar"},
{"-Wp,-Ufoo"},
+ {"-Wp,-Dfoo1"},
+ {"-Wp,-Ufoo1"},
{"-fobjc-arc"},
{"-fno-objc-arc"},
{"-fomit-frame-pointer"},
@@ -78,6 +81,8 @@ var badCompilerFlags = [][]string{
{"-O@1"},
{"-Wa,-foo"},
{"-W@foo"},
+ {"-Wp,-DX,-D@X"},
+ {"-Wp,-UX,-U@X"},
{"-g@gdb"},
{"-g-gdb"},
{"-march=@dawn"},
diff --git a/libgo/go/cmd/internal/pkgpath/pkgpath.go b/libgo/go/cmd/internal/pkgpath/pkgpath.go
new file mode 100644
index 0000000..40a040a
--- /dev/null
+++ b/libgo/go/cmd/internal/pkgpath/pkgpath.go
@@ -0,0 +1,174 @@
+// Copyright 2020 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 pkgpath determines the package path used by gccgo/GoLLVM symbols.
+// This package is not used for the gc compiler.
+package pkgpath
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "strings"
+)
+
+// ToSymbolFunc returns a function that may be used to convert a
+// package path into a string suitable for use as a symbol.
+// cmd is the gccgo/GoLLVM compiler in use, and tmpdir is a temporary
+// directory to pass to ioutil.TempFile.
+// For example, this returns a function that converts "net/http"
+// into a string like "net..z2fhttp". The actual string varies for
+// different gccgo/GoLLVM versions, which is why this returns a function
+// that does the conversion appropriate for the compiler in use.
+func ToSymbolFunc(cmd, tmpdir string) (func(string) string, error) {
+ // To determine the scheme used by cmd, we compile a small
+ // file and examine the assembly code. Older versions of gccgo
+ // use a simple mangling scheme where there can be collisions
+ // between packages whose paths are different but mangle to
+ // the same string. More recent versions use a new mangler
+ // that avoids these collisions.
+ const filepat = "*_gccgo_manglechck.go"
+ f, err := ioutil.TempFile(tmpdir, filepat)
+ if err != nil {
+ return nil, err
+ }
+ gofilename := f.Name()
+ f.Close()
+ defer os.Remove(gofilename)
+
+ if err := ioutil.WriteFile(gofilename, []byte(mangleCheckCode), 0644); err != nil {
+ return nil, err
+ }
+
+ command := exec.Command(cmd, "-S", "-o", "-", gofilename)
+ buf, err := command.Output()
+ if err != nil {
+ return nil, err
+ }
+
+ // Original mangling: go.l__ufer.Run
+ // Mangling v2: go.l..u00e4ufer.Run
+ // Mangling v3: go_0l_u00e4ufer.Run
+ if bytes.Contains(buf, []byte("go_0l_u00e4ufer.Run")) {
+ return toSymbolV3, nil
+ } else if bytes.Contains(buf, []byte("go.l..u00e4ufer.Run")) {
+ return toSymbolV2, nil
+ } else if bytes.Contains(buf, []byte("go.l__ufer.Run")) {
+ return toSymbolV1, nil
+ } else {
+ return nil, errors.New(cmd + ": unrecognized mangling scheme")
+ }
+}
+
+// mangleCheckCode is the package we compile to determine the mangling scheme.
+const mangleCheckCode = `
+package läufer
+func Run(x int) int {
+ return 1
+}
+`
+
+// toSymbolV1 converts a package path using the original mangling scheme.
+func toSymbolV1(ppath string) string {
+ clean := func(r rune) rune {
+ switch {
+ case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
+ '0' <= r && r <= '9':
+ return r
+ }
+ return '_'
+ }
+ return strings.Map(clean, ppath)
+}
+
+// toSymbolV2 converts a package path using the second mangling scheme.
+func toSymbolV2(ppath string) string {
+ // This has to build at boostrap time, so it has to build
+ // with Go 1.4, so we don't use strings.Builder.
+ bsl := make([]byte, 0, len(ppath))
+ changed := false
+ for _, c := range ppath {
+ if ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') || c == '_' {
+ bsl = append(bsl, byte(c))
+ continue
+ }
+ var enc string
+ switch {
+ case c == '.':
+ enc = ".x2e"
+ case c < 0x80:
+ enc = fmt.Sprintf("..z%02x", c)
+ case c < 0x10000:
+ enc = fmt.Sprintf("..u%04x", c)
+ default:
+ enc = fmt.Sprintf("..U%08x", c)
+ }
+ bsl = append(bsl, enc...)
+ changed = true
+ }
+ if !changed {
+ return ppath
+ }
+ return string(bsl)
+}
+
+// v3UnderscoreCodes maps from a character that supports an underscore
+// encoding to the underscore encoding character.
+var v3UnderscoreCodes = map[byte]byte{
+ '_': '_',
+ '.': '0',
+ '/': '1',
+ '*': '2',
+ ',': '3',
+ '{': '4',
+ '}': '5',
+ '[': '6',
+ ']': '7',
+ '(': '8',
+ ')': '9',
+ '"': 'a',
+ ' ': 'b',
+ ';': 'c',
+}
+
+// toSymbolV3 converts a package path using the third mangling scheme.
+func toSymbolV3(ppath string) string {
+ // This has to build at boostrap time, so it has to build
+ // with Go 1.4, so we don't use strings.Builder.
+ bsl := make([]byte, 0, len(ppath))
+ changed := false
+ for _, c := range ppath {
+ if ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') {
+ bsl = append(bsl, byte(c))
+ continue
+ }
+
+ if c < 0x80 {
+ if u, ok := v3UnderscoreCodes[byte(c)]; ok {
+ bsl = append(bsl, '_', u)
+ changed = true
+ continue
+ }
+ }
+
+ var enc string
+ switch {
+ case c < 0x80:
+ enc = fmt.Sprintf("_x%02x", c)
+ case c < 0x10000:
+ enc = fmt.Sprintf("_u%04x", c)
+ default:
+ enc = fmt.Sprintf("_U%08x", c)
+ }
+ bsl = append(bsl, enc...)
+ changed = true
+ }
+ if !changed {
+ return ppath
+ }
+ return string(bsl)
+}
diff --git a/libgo/go/cmd/internal/pkgpath/pkgpath_test.go b/libgo/go/cmd/internal/pkgpath/pkgpath_test.go
new file mode 100644
index 0000000..232e803
--- /dev/null
+++ b/libgo/go/cmd/internal/pkgpath/pkgpath_test.go
@@ -0,0 +1,141 @@
+// Copyright 2020 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 pkgpath
+
+import (
+ "os"
+ "testing"
+)
+
+const testEnvName = "GO_PKGPATH_TEST_COMPILER"
+
+// This init function supports TestToSymbolFunc. For simplicity,
+// we use the test binary itself as a sample gccgo driver.
+// We set an environment variable to specify how it should behave.
+func init() {
+ switch os.Getenv(testEnvName) {
+ case "":
+ return
+ case "v1":
+ os.Stdout.WriteString(`.string "go.l__ufer.Run"`)
+ os.Exit(0)
+ case "v2":
+ os.Stdout.WriteString(`.string "go.l..u00e4ufer.Run"`)
+ os.Exit(0)
+ case "v3":
+ os.Stdout.WriteString(`.string "go_0l_u00e4ufer.Run"`)
+ os.Exit(0)
+ case "error":
+ os.Stdout.WriteString(`unknown string`)
+ os.Exit(0)
+ }
+}
+
+func TestToSymbolFunc(t *testing.T) {
+ const input = "pä世🜃"
+ tests := []struct {
+ env string
+ fail bool
+ mangled string
+ }{
+ {
+ env: "v1",
+ mangled: "p___",
+ },
+ {
+ env: "v2",
+ mangled: "p..u00e4..u4e16..U0001f703",
+ },
+ {
+ env: "v3",
+ mangled: "p_u00e4_u4e16_U0001f703",
+ },
+ {
+ env: "error",
+ fail: true,
+ },
+ }
+
+ cmd := os.Args[0]
+ tmpdir := t.TempDir()
+
+ defer os.Unsetenv(testEnvName)
+
+ for _, test := range tests {
+ t.Run(test.env, func(t *testing.T) {
+ os.Setenv(testEnvName, test.env)
+
+ fn, err := ToSymbolFunc(cmd, tmpdir)
+ if err != nil {
+ if !test.fail {
+ t.Errorf("ToSymbolFunc(%q, %q): unexpected error %v", cmd, tmpdir, err)
+ }
+ } else if test.fail {
+ t.Errorf("ToSymbolFunc(%q, %q) succeeded but expected to fail", cmd, tmpdir)
+ } else if got, want := fn(input), test.mangled; got != want {
+ t.Errorf("ToSymbolFunc(%q, %q)(%q) = %q, want %q", cmd, tmpdir, input, got, want)
+ }
+ })
+ }
+}
+
+var symbolTests = []struct {
+ input, v1, v2, v3 string
+}{
+ {
+ "",
+ "",
+ "",
+ "",
+ },
+ {
+ "bytes",
+ "bytes",
+ "bytes",
+ "bytes",
+ },
+ {
+ "net/http",
+ "net_http",
+ "net..z2fhttp",
+ "net_1http",
+ },
+ {
+ "golang.org/x/net/http",
+ "golang_org_x_net_http",
+ "golang.x2eorg..z2fx..z2fnet..z2fhttp",
+ "golang_0org_1x_1net_1http",
+ },
+ {
+ "pä世.🜃",
+ "p____",
+ "p..u00e4..u4e16.x2e..U0001f703",
+ "p_u00e4_u4e16_0_U0001f703",
+ },
+}
+
+func TestV1(t *testing.T) {
+ for _, test := range symbolTests {
+ if got, want := toSymbolV1(test.input), test.v1; got != want {
+ t.Errorf("toSymbolV1(%q) = %q, want %q", test.input, got, want)
+ }
+ }
+}
+
+func TestV2(t *testing.T) {
+ for _, test := range symbolTests {
+ if got, want := toSymbolV2(test.input), test.v2; got != want {
+ t.Errorf("toSymbolV2(%q) = %q, want %q", test.input, got, want)
+ }
+ }
+}
+
+func TestV3(t *testing.T) {
+ for _, test := range symbolTests {
+ if got, want := toSymbolV3(test.input), test.v3; got != want {
+ t.Errorf("toSymbolV3(%q) = %q, want %q", test.input, got, want)
+ }
+ }
+}
diff --git a/libgo/go/go/internal/srcimporter/srcimporter.go b/libgo/go/go/internal/srcimporter/srcimporter.go
index 90bb3a9..3a2ca9a 100644
--- a/libgo/go/go/internal/srcimporter/srcimporter.go
+++ b/libgo/go/go/internal/srcimporter/srcimporter.go
@@ -262,5 +262,5 @@ func (p *Importer) joinPath(elem ...string) string {
return filepath.Join(elem...)
}
-//go:linkname setUsesCgo go/types.srcimporter_setUsesCgo
+//go:linkname setUsesCgo go_1types.srcimporter__setUsesCgo
func setUsesCgo(conf *types.Config)
diff --git a/libgo/go/internal/bytealg/bytealg.c b/libgo/go/internal/bytealg/bytealg.c
index 969732d..6c08340 100644
--- a/libgo/go/internal/bytealg/bytealg.c
+++ b/libgo/go/internal/bytealg/bytealg.c
@@ -38,7 +38,7 @@ static const void *goMemmem(const void *in, size_t inl, const void *s, size_t sl
#endif
intgo Compare(struct __go_open_array, struct __go_open_array)
- __asm__(GOSYM_PREFIX "internal..z2fbytealg.Compare")
+ __asm__(GOSYM_PREFIX "internal_1bytealg.Compare")
__attribute__((no_split_stack));
intgo Compare(struct __go_open_array a, struct __go_open_array b)
@@ -69,7 +69,7 @@ intgo Compare(struct __go_open_array a, struct __go_open_array b)
}
intgo IndexByte(struct __go_open_array, byte)
- __asm__(GOSYM_PREFIX "internal..z2fbytealg.IndexByte")
+ __asm__(GOSYM_PREFIX "internal_1bytealg.IndexByte")
__attribute__((no_split_stack));
intgo IndexByte(struct __go_open_array b, byte c)
@@ -85,7 +85,7 @@ intgo IndexByte(struct __go_open_array b, byte c)
intgo IndexByteString(String, byte)
- __asm__(GOSYM_PREFIX "internal..z2fbytealg.IndexByteString")
+ __asm__(GOSYM_PREFIX "internal_1bytealg.IndexByteString")
__attribute__((no_split_stack));
intgo IndexByteString(String s, byte c)
@@ -100,7 +100,7 @@ intgo IndexByteString(String s, byte c)
}
intgo Index(struct __go_open_array, struct __go_open_array)
- __asm__(GOSYM_PREFIX "internal..z2fbytealg.Index")
+ __asm__(GOSYM_PREFIX "internal_1bytealg.Index")
__attribute__((no_split_stack));
intgo Index(struct __go_open_array a, struct __go_open_array b)
@@ -115,7 +115,7 @@ intgo Index(struct __go_open_array a, struct __go_open_array b)
}
intgo IndexString(String, String)
- __asm__(GOSYM_PREFIX "internal..z2fbytealg.IndexString")
+ __asm__(GOSYM_PREFIX "internal_1bytealg.IndexString")
__attribute__((no_split_stack));
intgo IndexString(String a, String b)
diff --git a/libgo/go/internal/cpu/cpu_gccgo.c b/libgo/go/internal/cpu/cpu_gccgo.c
index 6b40f01..da26f4d 100644
--- a/libgo/go/internal/cpu/cpu_gccgo.c
+++ b/libgo/go/internal/cpu/cpu_gccgo.c
@@ -21,7 +21,7 @@ struct cpuid_ret {
};
struct cpuid_ret cpuid(uint32_t, uint32_t)
- __asm__(GOSYM_PREFIX "internal..z2fcpu.cpuid")
+ __asm__(GOSYM_PREFIX "internal_1cpu.cpuid")
__attribute__((no_split_stack));
struct cpuid_ret cpuid(uint32_t eaxArg, uint32_t ecxArg) {
@@ -45,7 +45,7 @@ struct xgetbv_ret {
};
struct xgetbv_ret xgetbv(void)
- __asm__(GOSYM_PREFIX "internal..z2fcpu.xgetbv")
+ __asm__(GOSYM_PREFIX "internal_1cpu.xgetbv")
__attribute__((no_split_stack));
#pragma GCC push_options
@@ -82,7 +82,7 @@ struct queryResult {
};
struct facilityList stfle(void)
- __asm__(GOSYM_PREFIX "internal..z2fcpu.stfle")
+ __asm__(GOSYM_PREFIX "internal_1cpu.stfle")
__attribute__((no_split_stack));
struct facilityList stfle(void) {
@@ -96,7 +96,7 @@ struct facilityList stfle(void) {
}
struct queryResult kmQuery(void)
- __asm__(GOSYM_PREFIX "internal..z2fcpu.kmQuery")
+ __asm__(GOSYM_PREFIX "internal_1cpu.kmQuery")
__attribute__((no_split_stack));
struct queryResult kmQuery() {
@@ -110,7 +110,7 @@ struct queryResult kmQuery() {
}
struct queryResult kmcQuery(void)
- __asm__(GOSYM_PREFIX "internal..z2fcpu.kmcQuery")
+ __asm__(GOSYM_PREFIX "internal_1cpu.kmcQuery")
__attribute__((no_split_stack));
struct queryResult kmcQuery() {
@@ -125,7 +125,7 @@ struct queryResult kmcQuery() {
}
struct queryResult kmctrQuery(void)
- __asm__(GOSYM_PREFIX "internal..z2fcpu.kmctrQuery")
+ __asm__(GOSYM_PREFIX "internal_1cpu.kmctrQuery")
__attribute__((no_split_stack));
struct queryResult kmctrQuery() {
@@ -140,7 +140,7 @@ struct queryResult kmctrQuery() {
}
struct queryResult kmaQuery(void)
- __asm__(GOSYM_PREFIX "internal..z2fcpu.kmaQuery")
+ __asm__(GOSYM_PREFIX "internal_1cpu.kmaQuery")
__attribute__((no_split_stack));
struct queryResult kmaQuery() {
@@ -155,7 +155,7 @@ struct queryResult kmaQuery() {
}
struct queryResult kimdQuery(void)
- __asm__(GOSYM_PREFIX "internal..z2fcpu.kimdQuery")
+ __asm__(GOSYM_PREFIX "internal_1cpu.kimdQuery")
__attribute__((no_split_stack));
struct queryResult kimdQuery() {
@@ -170,7 +170,7 @@ struct queryResult kimdQuery() {
}
struct queryResult klmdQuery(void)
- __asm__(GOSYM_PREFIX "internal..z2fcpu.klmdQuery")
+ __asm__(GOSYM_PREFIX "internal_1cpu.klmdQuery")
__attribute__((no_split_stack));
struct queryResult klmdQuery() {
@@ -185,7 +185,7 @@ struct queryResult klmdQuery() {
}
struct queryResult kdsaQuery(void)
- __asm__(GOSYM_PREFIX "internal..z2fcpu.kdsaQuery")
+ __asm__(GOSYM_PREFIX "internal_1cpu.kdsaQuery")
__attribute__((no_split_stack));
struct queryResult kdsaQuery() {
diff --git a/libgo/go/internal/cpu/cpu_mips64x.go b/libgo/go/internal/cpu/cpu_mips64x.go
index 0c4794a..af10a50 100644
--- a/libgo/go/internal/cpu/cpu_mips64x.go
+++ b/libgo/go/internal/cpu/cpu_mips64x.go
@@ -6,8 +6,6 @@
package cpu
-const CacheLinePadSize = 32
-
// This is initialized by archauxv and should not be changed after it is
// initialized.
var HWCap uint
diff --git a/libgo/go/log/syslog/syslog_c.c b/libgo/go/log/syslog/syslog_c.c
index 36e7694..acfee6e 100644
--- a/libgo/go/log/syslog/syslog_c.c
+++ b/libgo/go/log/syslog/syslog_c.c
@@ -12,7 +12,7 @@
can't represent a C varargs function in Go. */
void syslog_c(intgo, const char*)
- __asm__ (GOSYM_PREFIX "log..z2fsyslog.syslog_c");
+ __asm__ (GOSYM_PREFIX "log_1syslog.syslog__c");
void
syslog_c (intgo priority, const char *msg)
diff --git a/libgo/go/math/big/nat.go b/libgo/go/math/big/nat.go
index 6a3989b..8c43de6 100644
--- a/libgo/go/math/big/nat.go
+++ b/libgo/go/math/big/nat.go
@@ -928,7 +928,7 @@ func (z nat) divRecursiveStep(u, v nat, depth int, tmp *nat, temps []*nat) {
// Now u < (v<<B), compute lower bits in the same way.
// Choose shift = B-1 again.
- s := B
+ s := B - 1
qhat := *temps[depth]
qhat.clear()
qhat.divRecursiveStep(u[s:].norm(), v[s:], depth+1, tmp, temps)
diff --git a/libgo/go/runtime/atomic_pointer.go b/libgo/go/runtime/atomic_pointer.go
index 49b0f2b..0295913 100644
--- a/libgo/go/runtime/atomic_pointer.go
+++ b/libgo/go/runtime/atomic_pointer.go
@@ -39,10 +39,10 @@ func atomicstorep(ptr unsafe.Pointer, new unsafe.Pointer) {
// We cannot just call the runtime routines, because the race detector expects
// to be able to intercept the sync/atomic forms but not the runtime forms.
-//go:linkname sync_atomic_StoreUintptr sync..z2fatomic.StoreUintptr
+//go:linkname sync_atomic_StoreUintptr sync_1atomic.StoreUintptr
func sync_atomic_StoreUintptr(ptr *uintptr, new uintptr)
-//go:linkname sync_atomic_StorePointer sync..z2fatomic.StorePointer
+//go:linkname sync_atomic_StorePointer sync_1atomic.StorePointer
//go:nosplit
func sync_atomic_StorePointer(ptr *unsafe.Pointer, new unsafe.Pointer) {
if writeBarrier.enabled {
@@ -51,10 +51,10 @@ func sync_atomic_StorePointer(ptr *unsafe.Pointer, new unsafe.Pointer) {
sync_atomic_StoreUintptr((*uintptr)(unsafe.Pointer(ptr)), uintptr(new))
}
-//go:linkname sync_atomic_SwapUintptr sync..z2fatomic.SwapUintptr
+//go:linkname sync_atomic_SwapUintptr sync_1atomic.SwapUintptr
func sync_atomic_SwapUintptr(ptr *uintptr, new uintptr) uintptr
-//go:linkname sync_atomic_SwapPointer sync..z2fatomic.SwapPointer
+//go:linkname sync_atomic_SwapPointer sync_1atomic.SwapPointer
//go:nosplit
func sync_atomic_SwapPointer(ptr *unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer {
if writeBarrier.enabled {
@@ -64,10 +64,10 @@ func sync_atomic_SwapPointer(ptr *unsafe.Pointer, new unsafe.Pointer) unsafe.Poi
return old
}
-//go:linkname sync_atomic_CompareAndSwapUintptr sync..z2fatomic.CompareAndSwapUintptr
+//go:linkname sync_atomic_CompareAndSwapUintptr sync_1atomic.CompareAndSwapUintptr
func sync_atomic_CompareAndSwapUintptr(ptr *uintptr, old, new uintptr) bool
-//go:linkname sync_atomic_CompareAndSwapPointer sync..z2fatomic.CompareAndSwapPointer
+//go:linkname sync_atomic_CompareAndSwapPointer sync_1atomic.CompareAndSwapPointer
//go:nosplit
func sync_atomic_CompareAndSwapPointer(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool {
if writeBarrier.enabled {
diff --git a/libgo/go/runtime/chan.go b/libgo/go/runtime/chan.go
index b909d47..8e104f1 100644
--- a/libgo/go/runtime/chan.go
+++ b/libgo/go/runtime/chan.go
@@ -774,7 +774,7 @@ func reflect_chanlen(c *hchan) int {
return int(c.qcount)
}
-//go:linkname reflectlite_chanlen internal..z2freflectlite.chanlen
+//go:linkname reflectlite_chanlen internal_1reflectlite.chanlen
func reflectlite_chanlen(c *hchan) int {
if c == nil {
return 0
diff --git a/libgo/go/runtime/cpuprof.go b/libgo/go/runtime/cpuprof.go
index d395210..43f0a67 100644
--- a/libgo/go/runtime/cpuprof.go
+++ b/libgo/go/runtime/cpuprof.go
@@ -189,7 +189,7 @@ func CPUProfile() []byte {
panic("CPUProfile no longer available")
}
-//go:linkname runtime_pprof_runtime_cyclesPerSecond runtime..z2fpprof.runtime_cyclesPerSecond
+//go:linkname runtime_pprof_runtime_cyclesPerSecond runtime_1pprof.runtime__cyclesPerSecond
func runtime_pprof_runtime_cyclesPerSecond() int64 {
return tickspersecond()
}
@@ -200,7 +200,7 @@ func runtime_pprof_runtime_cyclesPerSecond() int64 {
// on has been returned, readProfile returns eof=true.
// The caller must save the returned data and tags before calling readProfile again.
//
-//go:linkname runtime_pprof_readProfile runtime..z2fpprof.readProfile
+//go:linkname runtime_pprof_readProfile runtime_1pprof.readProfile
func runtime_pprof_readProfile() ([]uint64, []unsafe.Pointer, bool) {
lock(&cpuprof.lock)
log := cpuprof.log
diff --git a/libgo/go/runtime/debug.go b/libgo/go/runtime/debug.go
index 1202e36..ff76580 100644
--- a/libgo/go/runtime/debug.go
+++ b/libgo/go/runtime/debug.go
@@ -66,7 +66,7 @@ func NumGoroutine() int {
// added.
func Fieldtrack(map[string]bool)
-//go:linkname debug_modinfo runtime..z2fdebug.modinfo
+//go:linkname debug_modinfo runtime_1debug.modinfo
func debug_modinfo() string {
return modinfo
}
diff --git a/libgo/go/runtime/heapdump.go b/libgo/go/runtime/heapdump.go
index e8f16e9..816d93c 100644
--- a/libgo/go/runtime/heapdump.go
+++ b/libgo/go/runtime/heapdump.go
@@ -16,7 +16,7 @@ import (
"unsafe"
)
-//go:linkname runtime_debug_WriteHeapDump runtime..z2fdebug.WriteHeapDump
+//go:linkname runtime_debug_WriteHeapDump runtime_1debug.WriteHeapDump
func runtime_debug_WriteHeapDump(fd uintptr) {
stopTheWorld("write heap dump")
diff --git a/libgo/go/runtime/iface.go b/libgo/go/runtime/iface.go
index 5667ddb..f9df1e0 100644
--- a/libgo/go/runtime/iface.go
+++ b/libgo/go/runtime/iface.go
@@ -505,7 +505,7 @@ func reflect_ifaceE2I(inter *interfacetype, e eface, dst *iface) {
dst.data = e.data
}
-//go:linkname reflectlite_ifaceE2I internal..z2freflectlite.ifaceE2I
+//go:linkname reflectlite_ifaceE2I internal_1reflectlite.ifaceE2I
func reflectlite_ifaceE2I(inter *interfacetype, e eface, dst *iface) {
t := e._type
if t == nil {
diff --git a/libgo/go/runtime/internal/atomic/atomic.c b/libgo/go/runtime/internal/atomic/atomic.c
index 8ae4d7b..9fed1a8 100644
--- a/libgo/go/runtime/internal/atomic/atomic.c
+++ b/libgo/go/runtime/internal/atomic/atomic.c
@@ -7,7 +7,7 @@
#include "runtime.h"
uint32_t Load (uint32_t *ptr)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Load")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Load")
__attribute__ ((no_split_stack));
uint32_t
@@ -17,7 +17,7 @@ Load (uint32_t *ptr)
}
void *Loadp (void *ptr)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Loadp")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Loadp")
__attribute__ ((no_split_stack));
void *
@@ -27,7 +27,7 @@ Loadp (void *ptr)
}
uint8_t Load8 (uint8_t *ptr)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Load8")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Load8")
__attribute__ ((no_split_stack));
uint8_t
@@ -37,7 +37,7 @@ Load8 (uint8_t *ptr)
}
uint64_t Load64 (uint64_t *ptr)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Load64")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Load64")
__attribute__ ((no_split_stack));
uint64_t
@@ -49,7 +49,7 @@ Load64 (uint64_t *ptr)
}
uint32_t LoadAcq (uint32_t *ptr)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.LoadAcq")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.LoadAcq")
__attribute__ ((no_split_stack));
uint32_t
@@ -59,7 +59,7 @@ LoadAcq (uint32_t *ptr)
}
uintptr_t Loaduintptr (uintptr_t *ptr)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Loaduintptr")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Loaduintptr")
__attribute__ ((no_split_stack));
uintptr_t
@@ -69,7 +69,7 @@ Loaduintptr (uintptr_t *ptr)
}
uintgo Loaduint (uintgo *ptr)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Loaduint")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Loaduint")
__attribute__ ((no_split_stack));
uintgo
@@ -79,7 +79,7 @@ Loaduint (uintgo *ptr)
}
int64_t Loadint64 (int64_t *ptr)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Loadint64")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Loadint64")
__attribute__ ((no_split_stack));
int64_t
@@ -91,7 +91,7 @@ Loadint64 (int64_t *ptr)
}
uint32_t Xadd (uint32_t *ptr, int32_t delta)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xadd")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xadd")
__attribute__ ((no_split_stack));
uint32_t
@@ -101,7 +101,7 @@ Xadd (uint32_t *ptr, int32_t delta)
}
uint64_t Xadd64 (uint64_t *ptr, int64_t delta)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xadd64")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xadd64")
__attribute__ ((no_split_stack));
uint64_t
@@ -113,7 +113,7 @@ Xadd64 (uint64_t *ptr, int64_t delta)
}
uintptr_t Xadduintptr (uintptr_t *ptr, uintptr_t delta)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xadduintptr")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xadduintptr")
__attribute__ ((no_split_stack));
uintptr_t
@@ -123,7 +123,7 @@ Xadduintptr (uintptr_t *ptr, uintptr_t delta)
}
int64_t Xaddint64 (int64_t *ptr, int64_t delta)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xaddint64")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xaddint64")
__attribute__ ((no_split_stack));
int64_t
@@ -135,7 +135,7 @@ Xaddint64 (int64_t *ptr, int64_t delta)
}
uint32_t Xchg (uint32_t *ptr, uint32_t new)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xchg")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xchg")
__attribute__ ((no_split_stack));
uint32_t
@@ -145,7 +145,7 @@ Xchg (uint32_t *ptr, uint32_t new)
}
uint64_t Xchg64 (uint64_t *ptr, uint64_t new)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xchg64")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xchg64")
__attribute__ ((no_split_stack));
uint64_t
@@ -157,7 +157,7 @@ Xchg64 (uint64_t *ptr, uint64_t new)
}
uintptr_t Xchguintptr (uintptr_t *ptr, uintptr_t new)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xchguintptr")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xchguintptr")
__attribute__ ((no_split_stack));
uintptr_t
@@ -167,7 +167,7 @@ Xchguintptr (uintptr_t *ptr, uintptr_t new)
}
void And8 (uint8_t *ptr, uint8_t val)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.And8")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.And8")
__attribute__ ((no_split_stack));
void
@@ -177,7 +177,7 @@ And8 (uint8_t *ptr, uint8_t val)
}
void Or8 (uint8_t *ptr, uint8_t val)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Or8")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Or8")
__attribute__ ((no_split_stack));
void
@@ -187,7 +187,7 @@ Or8 (uint8_t *ptr, uint8_t val)
}
_Bool Cas (uint32_t *ptr, uint32_t old, uint32_t new)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Cas")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Cas")
__attribute__ ((no_split_stack));
_Bool
@@ -197,7 +197,7 @@ Cas (uint32_t *ptr, uint32_t old, uint32_t new)
}
_Bool Cas64 (uint64_t *ptr, uint64_t old, uint64_t new)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Cas64")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Cas64")
__attribute__ ((no_split_stack));
_Bool
@@ -209,7 +209,7 @@ Cas64 (uint64_t *ptr, uint64_t old, uint64_t new)
}
_Bool CasRel (uint32_t *ptr, uint32_t old, uint32_t new)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.CasRel")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.CasRel")
__attribute__ ((no_split_stack));
_Bool
@@ -219,7 +219,7 @@ CasRel (uint32_t *ptr, uint32_t old, uint32_t new)
}
_Bool Casp1 (void **ptr, void *old, void *new)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Casp1")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Casp1")
__attribute__ ((no_split_stack));
_Bool
@@ -229,7 +229,7 @@ Casp1 (void **ptr, void *old, void *new)
}
_Bool Casuintptr (uintptr_t *ptr, uintptr_t old, uintptr_t new)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Casuintptr")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Casuintptr")
__attribute__ ((no_split_stack));
_Bool
@@ -239,7 +239,7 @@ Casuintptr (uintptr_t *ptr, uintptr_t old, uintptr_t new)
}
void Store (uint32_t *ptr, uint32_t val)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Store")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Store")
__attribute__ ((no_split_stack));
void
@@ -249,7 +249,7 @@ Store (uint32_t *ptr, uint32_t val)
}
void Store8 (uint8_t *ptr, uint8_t val)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Store8")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Store8")
__attribute__ ((no_split_stack));
void
@@ -259,7 +259,7 @@ Store8 (uint8_t *ptr, uint8_t val)
}
void Store64 (uint64_t *ptr, uint64_t val)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Store64")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Store64")
__attribute__ ((no_split_stack));
void
@@ -271,7 +271,7 @@ Store64 (uint64_t *ptr, uint64_t val)
}
void StoreRel (uint32_t *ptr, uint32_t val)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.StoreRel")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.StoreRel")
__attribute__ ((no_split_stack));
void
@@ -281,7 +281,7 @@ StoreRel (uint32_t *ptr, uint32_t val)
}
void Storeuintptr (uintptr_t *ptr, uintptr_t val)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Storeuintptr")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Storeuintptr")
__attribute__ ((no_split_stack));
void
@@ -291,7 +291,7 @@ Storeuintptr (uintptr_t *ptr, uintptr_t val)
}
void StorepNoWB (void *ptr, void *val)
- __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.StorepNoWB")
+ __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.StorepNoWB")
__attribute__ ((no_split_stack));
void
diff --git a/libgo/go/runtime/malloc.go b/libgo/go/runtime/malloc.go
index 81351ee..feb043a 100644
--- a/libgo/go/runtime/malloc.go
+++ b/libgo/go/runtime/malloc.go
@@ -1220,12 +1220,12 @@ func newobject(typ *_type) unsafe.Pointer {
return mallocgc(typ.size, typ, true)
}
-//go:linkname reflect_unsafe_New reflect.unsafe_New
+//go:linkname reflect_unsafe_New reflect.unsafe__New
func reflect_unsafe_New(typ *_type) unsafe.Pointer {
return mallocgc(typ.size, typ, true)
}
-//go:linkname reflectlite_unsafe_New internal..z2freflectlite.unsafe_New
+//go:linkname reflectlite_unsafe_New internal_1reflectlite.unsafe__New
func reflectlite_unsafe_New(typ *_type) unsafe.Pointer {
return mallocgc(typ.size, typ, true)
}
@@ -1242,7 +1242,7 @@ func newarray(typ *_type, n int) unsafe.Pointer {
return mallocgc(mem, typ, true)
}
-//go:linkname reflect_unsafe_NewArray reflect.unsafe_NewArray
+//go:linkname reflect_unsafe_NewArray reflect.unsafe__NewArray
func reflect_unsafe_NewArray(typ *_type, n int) unsafe.Pointer {
return newarray(typ, n)
}
diff --git a/libgo/go/runtime/map.go b/libgo/go/runtime/map.go
index b829771..1155fee 100644
--- a/libgo/go/runtime/map.go
+++ b/libgo/go/runtime/map.go
@@ -1417,7 +1417,7 @@ func reflect_maplen(h *hmap) int {
return h.count
}
-//go:linkname reflectlite_maplen internal..z2freflectlite.maplen
+//go:linkname reflectlite_maplen internal_1reflectlite.maplen
func reflectlite_maplen(h *hmap) int {
if h == nil {
return 0
diff --git a/libgo/go/runtime/mbarrier.go b/libgo/go/runtime/mbarrier.go
index 836f85a..3bd8b34 100644
--- a/libgo/go/runtime/mbarrier.go
+++ b/libgo/go/runtime/mbarrier.go
@@ -192,7 +192,7 @@ func reflect_typedmemmove(typ *_type, dst, src unsafe.Pointer) {
typedmemmove(typ, dst, src)
}
-//go:linkname reflectlite_typedmemmove internal..z2freflectlite.typedmemmove
+//go:linkname reflectlite_typedmemmove internal_1reflectlite.typedmemmove
func reflectlite_typedmemmove(typ *_type, dst, src unsafe.Pointer) {
reflect_typedmemmove(typ, dst, src)
}
diff --git a/libgo/go/runtime/mgc.go b/libgo/go/runtime/mgc.go
index 9dd7bff..72479c2 100644
--- a/libgo/go/runtime/mgc.go
+++ b/libgo/go/runtime/mgc.go
@@ -223,7 +223,7 @@ func gcenable() {
memstats.enablegc = true // now that runtime is initialized, GC is okay
}
-//go:linkname setGCPercent runtime..z2fdebug.setGCPercent
+//go:linkname setGCPercent runtime_1debug.setGCPercent
func setGCPercent(in int32) (out int32) {
// Run on the system stack since we grab the heap lock.
systemstack(func() {
@@ -2238,7 +2238,7 @@ func gcResetMarkState() {
var poolcleanup func()
-//go:linkname sync_runtime_registerPoolCleanup sync.runtime_registerPoolCleanup
+//go:linkname sync_runtime_registerPoolCleanup sync.runtime__registerPoolCleanup
func sync_runtime_registerPoolCleanup(f func()) {
poolcleanup = f
}
diff --git a/libgo/go/runtime/mheap.go b/libgo/go/runtime/mheap.go
index e73ee32..755efd1 100644
--- a/libgo/go/runtime/mheap.go
+++ b/libgo/go/runtime/mheap.go
@@ -1502,7 +1502,7 @@ func (h *mheap) scavengeAll() {
}
}
-//go:linkname runtime_debug_freeOSMemory runtime..z2fdebug.freeOSMemory
+//go:linkname runtime_debug_freeOSMemory runtime_1debug.freeOSMemory
func runtime_debug_freeOSMemory() {
GC()
systemstack(func() { mheap_.scavengeAll() })
diff --git a/libgo/go/runtime/mprof.go b/libgo/go/runtime/mprof.go
index a4b135d..afacf8f 100644
--- a/libgo/go/runtime/mprof.go
+++ b/libgo/go/runtime/mprof.go
@@ -942,7 +942,7 @@ func ThreadCreateProfile(p []StackRecord) (n int, ok bool) {
return
}
-//go:linkname runtime_goroutineProfileWithLabels runtime..z2fpprof.runtime_goroutineProfileWithLabels
+//go:linkname runtime_goroutineProfileWithLabels runtime_1pprof.runtime__goroutineProfileWithLabels
func runtime_goroutineProfileWithLabels(p []StackRecord, labels []unsafe.Pointer) (n int, ok bool) {
return goroutineProfileWithLabels(p, labels)
}
diff --git a/libgo/go/runtime/mstats.go b/libgo/go/runtime/mstats.go
index 4e2c66ce..85a0861 100644
--- a/libgo/go/runtime/mstats.go
+++ b/libgo/go/runtime/mstats.go
@@ -468,7 +468,7 @@ func readmemstats_m(stats *MemStats) {
stats.StackSys += stats.StackInuse
}
-//go:linkname readGCStats runtime..z2fdebug.readGCStats
+//go:linkname readGCStats runtime_1debug.readGCStats
func readGCStats(pauses *[]uint64) {
systemstack(func() {
readGCStats_m(pauses)
diff --git a/libgo/go/runtime/net_plan9.go b/libgo/go/runtime/net_plan9.go
index 907c319..38ff5a4 100644
--- a/libgo/go/runtime/net_plan9.go
+++ b/libgo/go/runtime/net_plan9.go
@@ -8,12 +8,12 @@ import (
_ "unsafe"
)
-//go:linkname runtime_ignoreHangup internal..z2fpoll.runtime_ignoreHangup
+//go:linkname runtime_ignoreHangup internal_1poll.runtime__ignoreHangup
func runtime_ignoreHangup() {
getg().m.ignoreHangup = true
}
-//go:linkname runtime_unignoreHangup internal..z2fpoll.runtime_unignoreHangup
+//go:linkname runtime_unignoreHangup internal_1poll.runtime__unignoreHangup
func runtime_unignoreHangup(sig string) {
getg().m.ignoreHangup = false
}
diff --git a/libgo/go/runtime/netpoll.go b/libgo/go/runtime/netpoll.go
index 72a136d..da00b57 100644
--- a/libgo/go/runtime/netpoll.go
+++ b/libgo/go/runtime/netpoll.go
@@ -113,7 +113,7 @@ var (
netpollWaiters uint32
)
-//go:linkname poll_runtime_pollServerInit internal..z2fpoll.runtime_pollServerInit
+//go:linkname poll_runtime_pollServerInit internal_1poll.runtime__pollServerInit
func poll_runtime_pollServerInit() {
netpollGenericInit()
}
@@ -134,7 +134,7 @@ func netpollinited() bool {
return atomic.Load(&netpollInited) != 0
}
-//go:linkname poll_runtime_isPollServerDescriptor internal..z2fpoll.runtime_isPollServerDescriptor
+//go:linkname poll_runtime_isPollServerDescriptor internal_1poll.runtime__isPollServerDescriptor
// poll_runtime_isPollServerDescriptor reports whether fd is a
// descriptor being used by netpoll.
@@ -142,7 +142,7 @@ func poll_runtime_isPollServerDescriptor(fd uintptr) bool {
return netpollIsPollDescriptor(fd)
}
-//go:linkname poll_runtime_pollOpen internal..z2fpoll.runtime_pollOpen
+//go:linkname poll_runtime_pollOpen internal_1poll.runtime__pollOpen
func poll_runtime_pollOpen(fd uintptr) (uintptr, int) {
pd := pollcache.alloc()
lock(&pd.lock)
@@ -169,7 +169,7 @@ func poll_runtime_pollOpen(fd uintptr) (uintptr, int) {
return uintptr(unsafe.Pointer(pd)), int(errno)
}
-//go:linkname poll_runtime_pollClose internal..z2fpoll.runtime_pollClose
+//go:linkname poll_runtime_pollClose internal_1poll.runtime__pollClose
func poll_runtime_pollClose(ctx uintptr) {
pd := (*pollDesc)(unsafe.Pointer(ctx))
if !pd.closing {
@@ -195,7 +195,7 @@ func (c *pollCache) free(pd *pollDesc) {
// poll_runtime_pollReset, which is internal/poll.runtime_pollReset,
// prepares a descriptor for polling in mode, which is 'r' or 'w'.
// This returns an error code; the codes are defined above.
-//go:linkname poll_runtime_pollReset internal..z2fpoll.runtime_pollReset
+//go:linkname poll_runtime_pollReset internal_1poll.runtime__pollReset
func poll_runtime_pollReset(ctx uintptr, mode int) int {
pd := (*pollDesc)(unsafe.Pointer(ctx))
errcode := netpollcheckerr(pd, int32(mode))
@@ -214,7 +214,7 @@ func poll_runtime_pollReset(ctx uintptr, mode int) int {
// waits for a descriptor to be ready for reading or writing,
// according to mode, which is 'r' or 'w'.
// This returns an error code; the codes are defined above.
-//go:linkname poll_runtime_pollWait internal..z2fpoll.runtime_pollWait
+//go:linkname poll_runtime_pollWait internal_1poll.runtime__pollWait
func poll_runtime_pollWait(ctx uintptr, mode int) int {
pd := (*pollDesc)(unsafe.Pointer(ctx))
errcode := netpollcheckerr(pd, int32(mode))
@@ -237,7 +237,7 @@ func poll_runtime_pollWait(ctx uintptr, mode int) int {
return pollNoError
}
-//go:linkname poll_runtime_pollWaitCanceled internal..z2fpoll.runtime_pollWaitCanceled
+//go:linkname poll_runtime_pollWaitCanceled internal_1poll.runtime__pollWaitCanceled
func poll_runtime_pollWaitCanceled(ctx uintptr, mode int) {
pd := (*pollDesc)(unsafe.Pointer(ctx))
// This function is used only on windows after a failed attempt to cancel
@@ -246,7 +246,7 @@ func poll_runtime_pollWaitCanceled(ctx uintptr, mode int) {
}
}
-//go:linkname poll_runtime_pollSetDeadline internal..z2fpoll.runtime_pollSetDeadline
+//go:linkname poll_runtime_pollSetDeadline internal_1poll.runtime__pollSetDeadline
func poll_runtime_pollSetDeadline(ctx uintptr, d int64, mode int) {
pd := (*pollDesc)(unsafe.Pointer(ctx))
lock(&pd.lock)
@@ -330,7 +330,7 @@ func poll_runtime_pollSetDeadline(ctx uintptr, d int64, mode int) {
}
}
-//go:linkname poll_runtime_pollUnblock internal..z2fpoll.runtime_pollUnblock
+//go:linkname poll_runtime_pollUnblock internal_1poll.runtime__pollUnblock
func poll_runtime_pollUnblock(ctx uintptr) {
pd := (*pollDesc)(unsafe.Pointer(ctx))
lock(&pd.lock)
diff --git a/libgo/go/runtime/pprof/mprof_test.go b/libgo/go/runtime/pprof/mprof_test.go
index 625ab7d..83bf572 100644
--- a/libgo/go/runtime/pprof/mprof_test.go
+++ b/libgo/go/runtime/pprof/mprof_test.go
@@ -91,35 +91,35 @@ func TestMemoryProfiler(t *testing.T) {
stk []string
legacy string
}{{
- stk: []string{"pprof.allocatePersistent1K", "runtime/pprof.TestMemoryProfiler"},
+ stk: []string{"runtime/pprof.allocatePersistent1K", "runtime/pprof.TestMemoryProfiler"},
legacy: fmt.Sprintf(`%v: %v \[%v: %v\] @ 0x[0-9,a-f x]+
-# 0x[0-9,a-f]+ pprof\.allocatePersistent1K\+0x[0-9,a-f]+ .*/mprof_test\.go:47
+# 0x[0-9,a-f]+ runtime/pprof\.allocatePersistent1K\+0x[0-9,a-f]+ .*/mprof_test\.go:47
# 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test\.go:82
`, 32*memoryProfilerRun, 1024*memoryProfilerRun, 32*memoryProfilerRun, 1024*memoryProfilerRun),
}, {
- stk: []string{"pprof.allocateTransient1M", "runtime/pprof.TestMemoryProfiler"},
+ stk: []string{"runtime/pprof.allocateTransient1M", "runtime/pprof.TestMemoryProfiler"},
legacy: fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @ 0x[0-9,a-f x]+
-# 0x[0-9,a-f]+ pprof\.allocateTransient1M\+0x[0-9,a-f]+ .*/mprof_test.go:24
+# 0x[0-9,a-f]+ runtime/pprof\.allocateTransient1M\+0x[0-9,a-f]+ .*/mprof_test.go:24
# 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test.go:79
`, (1<<10)*memoryProfilerRun, (1<<20)*memoryProfilerRun, (1<<10)*memoryProfilerRun, (1<<20)*memoryProfilerRun),
}, {
- stk: []string{"pprof.allocateTransient2M", "runtime/pprof.TestMemoryProfiler"},
+ stk: []string{"runtime/pprof.allocateTransient2M", "runtime/pprof.TestMemoryProfiler"},
// This should start with "0: 0" but gccgo's imprecise
// GC means that sometimes the value is not collected.
legacy: fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @ 0x[0-9,a-f x]+
-# 0x[0-9,a-f]+ pprof\.allocateTransient2M\+0x[0-9,a-f]+ .*/mprof_test.go:30
+# 0x[0-9,a-f]+ runtime/pprof\.allocateTransient2M\+0x[0-9,a-f]+ .*/mprof_test.go:30
# 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test.go:80
`, memoryProfilerRun, (2<<20)*memoryProfilerRun, memoryProfilerRun, (2<<20)*memoryProfilerRun),
}, {
- stk: []string{"pprof.allocateTransient2MInline", "runtime/pprof.TestMemoryProfiler"},
+ stk: []string{"runtime/pprof.allocateTransient2MInline", "runtime/pprof.TestMemoryProfiler"},
legacy: fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @ 0x[0-9,a-f x]+
-# 0x[0-9,a-f]+ pprof\.allocateTransient2MInline\+0x[0-9,a-f]+ .*/mprof_test.go:34
+# 0x[0-9,a-f]+ runtime/pprof\.allocateTransient2MInline\+0x[0-9,a-f]+ .*/mprof_test.go:34
# 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test.go:81
`, memoryProfilerRun, (4<<20)*memoryProfilerRun, memoryProfilerRun, (4<<20)*memoryProfilerRun),
}, {
- stk: []string{"pprof.allocateReflectTransient"},
+ stk: []string{"runtime/pprof.allocateReflectTransient"},
legacy: fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @( 0x[0-9,a-f]+)+
-# 0x[0-9,a-f]+ pprof\.allocateReflectTransient\+0x[0-9,a-f]+ .*/mprof_test.go:55
+# 0x[0-9,a-f]+ runtime/pprof\.allocateReflectTransient\+0x[0-9,a-f]+ .*/mprof_test.go:55
`, memoryProfilerRun, (3<<20)*memoryProfilerRun, memoryProfilerRun, (3<<20)*memoryProfilerRun),
}}
diff --git a/libgo/go/runtime/pprof/pprof_test.go b/libgo/go/runtime/pprof/pprof_test.go
index ff86bce..7adf891 100644
--- a/libgo/go/runtime/pprof/pprof_test.go
+++ b/libgo/go/runtime/pprof/pprof_test.go
@@ -958,8 +958,8 @@ func TestMutexProfile(t *testing.T) {
stks := stacks(p)
for _, want := range [][]string{
- // {"sync.(*Mutex).Unlock", "pprof.blockMutex.func1"},
- {"sync.Mutex.Unlock", "pprof.blockMutex..func1"},
+ // {"sync.(*Mutex).Unlock", "runtime/pprof.blockMutex.func1"},
+ {"sync.Mutex.Unlock", "runtime/pprof.blockMutex..func1"},
} {
if !containsStack(stks, want) {
t.Errorf("No matching stack entry for %+v", want)
diff --git a/libgo/go/runtime/preempt.go b/libgo/go/runtime/preempt.go
index 9a78bcf..8452076 100644
--- a/libgo/go/runtime/preempt.go
+++ b/libgo/go/runtime/preempt.go
@@ -360,7 +360,7 @@ func isAsyncSafePoint(gp *g, pc uintptr) (bool, uintptr) {
}
name := f.Name()
if hasPrefix(name, "runtime.") ||
- hasPrefix(name, "runtime..z2finternal..z2f") ||
+ hasPrefix(name, "runtime_1internal_1") ||
hasPrefix(name, "reflect.") {
// For now we never async preempt the runtime or
// anything closely tied to the runtime. Known issues
diff --git a/libgo/go/runtime/proc.go b/libgo/go/runtime/proc.go
index 0ca6c02..6c72050 100644
--- a/libgo/go/runtime/proc.go
+++ b/libgo/go/runtime/proc.go
@@ -263,7 +263,7 @@ func main(unsafe.Pointer) {
}
// os_beforeExit is called from os.Exit(0).
-//go:linkname os_beforeExit os.runtime_beforeExit
+//go:linkname os_beforeExit os.runtime__beforeExit
func os_beforeExit() {
if raceenabled {
racefini()
@@ -3305,7 +3305,7 @@ func beforefork() {
}
// Called from syscall package before fork.
-//go:linkname syscall_runtime_BeforeFork syscall.runtime_BeforeFork
+//go:linkname syscall_runtime_BeforeFork syscall.runtime__BeforeFork
//go:nosplit
func syscall_runtime_BeforeFork() {
systemstack(beforefork)
@@ -3320,7 +3320,7 @@ func afterfork() {
}
// Called from syscall package after fork in parent.
-//go:linkname syscall_runtime_AfterFork syscall.runtime_AfterFork
+//go:linkname syscall_runtime_AfterFork syscall.runtime__AfterFork
//go:nosplit
func syscall_runtime_AfterFork() {
systemstack(afterfork)
@@ -3338,7 +3338,7 @@ var inForkedChild bool
// temporarily sharing address space with the parent process, this must
// not change any global variables or calling into C code that may do so.
//
-//go:linkname syscall_runtime_AfterForkInChild syscall.runtime_AfterForkInChild
+//go:linkname syscall_runtime_AfterForkInChild syscall.runtime__AfterForkInChild
//go:nosplit
//go:nowritebarrierrec
func syscall_runtime_AfterForkInChild() {
@@ -3363,7 +3363,7 @@ func syscall_runtime_AfterForkInChild() {
var pendingPreemptSignals uint32
// Called from syscall package before Exec.
-//go:linkname syscall_runtime_BeforeExec syscall.runtime_BeforeExec
+//go:linkname syscall_runtime_BeforeExec syscall.runtime__BeforeExec
func syscall_runtime_BeforeExec() {
// Prevent thread creation during exec.
execLock.lock()
@@ -3378,7 +3378,7 @@ func syscall_runtime_BeforeExec() {
}
// Called from syscall package after Exec.
-//go:linkname syscall_runtime_AfterExec syscall.runtime_AfterExec
+//go:linkname syscall_runtime_AfterExec syscall.runtime__AfterExec
func syscall_runtime_AfterExec() {
execLock.unlock()
}
@@ -5165,7 +5165,7 @@ func (l *gList) pop() *g {
return gp
}
-//go:linkname setMaxThreads runtime..z2fdebug.setMaxThreads
+//go:linkname setMaxThreads runtime_1debug.setMaxThreads
func setMaxThreads(in int) (out int) {
lock(&sched.lock)
out = int(sched.maxmcount)
@@ -5199,32 +5199,32 @@ func procUnpin() {
_g_.m.locks--
}
-//go:linkname sync_runtime_procPin sync.runtime_procPin
+//go:linkname sync_runtime_procPin sync.runtime__procPin
//go:nosplit
func sync_runtime_procPin() int {
return procPin()
}
-//go:linkname sync_runtime_procUnpin sync.runtime_procUnpin
+//go:linkname sync_runtime_procUnpin sync.runtime__procUnpin
//go:nosplit
func sync_runtime_procUnpin() {
procUnpin()
}
-//go:linkname sync_atomic_runtime_procPin sync..z2fatomic.runtime_procPin
+//go:linkname sync_atomic_runtime_procPin sync_1atomic.runtime__procPin
//go:nosplit
func sync_atomic_runtime_procPin() int {
return procPin()
}
-//go:linkname sync_atomic_runtime_procUnpin sync..z2fatomic.runtime_procUnpin
+//go:linkname sync_atomic_runtime_procUnpin sync_1atomic.runtime__procUnpin
//go:nosplit
func sync_atomic_runtime_procUnpin() {
procUnpin()
}
// Active spinning for sync.Mutex.
-//go:linkname sync_runtime_canSpin sync.runtime_canSpin
+//go:linkname sync_runtime_canSpin sync.runtime__canSpin
//go:nosplit
func sync_runtime_canSpin(i int) bool {
// sync.Mutex is cooperative, so we are conservative with spinning.
@@ -5241,7 +5241,7 @@ func sync_runtime_canSpin(i int) bool {
return true
}
-//go:linkname sync_runtime_doSpin sync.runtime_doSpin
+//go:linkname sync_runtime_doSpin sync.runtime__doSpin
//go:nosplit
func sync_runtime_doSpin() {
procyield(active_spin_cnt)
diff --git a/libgo/go/runtime/proflabel.go b/libgo/go/runtime/proflabel.go
index fc655cc..1e1f3bf 100644
--- a/libgo/go/runtime/proflabel.go
+++ b/libgo/go/runtime/proflabel.go
@@ -8,7 +8,7 @@ import "unsafe"
var labelSync uintptr
-//go:linkname runtime_setProfLabel runtime..z2fpprof.runtime_setProfLabel
+//go:linkname runtime_setProfLabel runtime_1pprof.runtime__setProfLabel
func runtime_setProfLabel(labels unsafe.Pointer) {
// Introduce race edge for read-back via profile.
// This would more properly use &getg().labels as the sync address,
@@ -34,7 +34,7 @@ func runtime_setProfLabel(labels unsafe.Pointer) {
getg().labels = labels
}
-//go:linkname runtime_getProfLabel runtime..z2fpprof.runtime_getProfLabel
+//go:linkname runtime_getProfLabel runtime_1pprof.runtime__getProfLabel
func runtime_getProfLabel() unsafe.Pointer {
return getg().labels
}
diff --git a/libgo/go/runtime/rdebug.go b/libgo/go/runtime/rdebug.go
index 358df11..9c43ce5 100644
--- a/libgo/go/runtime/rdebug.go
+++ b/libgo/go/runtime/rdebug.go
@@ -11,14 +11,14 @@ import _ "unsafe" // for go:linkname
// maxstacksize.
var maxstacksize uintptr = 1 << 20 // enough until runtime.main sets it for real
-//go:linkname setMaxStack runtime..z2fdebug.setMaxStack
+//go:linkname setMaxStack runtime_1debug.setMaxStack
func setMaxStack(in int) (out int) {
out = int(maxstacksize)
maxstacksize = uintptr(in)
return out
}
-//go:linkname setPanicOnFault runtime..z2fdebug.setPanicOnFault
+//go:linkname setPanicOnFault runtime_1debug.setPanicOnFault
func setPanicOnFault(new bool) (old bool) {
_g_ := getg()
old = _g_.paniconfault
diff --git a/libgo/go/runtime/runtime.go b/libgo/go/runtime/runtime.go
index abc5eab..5af28ae 100644
--- a/libgo/go/runtime/runtime.go
+++ b/libgo/go/runtime/runtime.go
@@ -51,13 +51,13 @@ func tickspersecond() int64 {
var envs []string
var argslice []string
-//go:linkname syscall_runtime_envs syscall.runtime_envs
+//go:linkname syscall_runtime_envs syscall.runtime__envs
func syscall_runtime_envs() []string { return append([]string{}, envs...) }
//go:linkname syscall_Getpagesize syscall.Getpagesize
func syscall_Getpagesize() int { return int(physPageSize) }
-//go:linkname os_runtime_args os.runtime_args
+//go:linkname os_runtime_args os.runtime__args
func os_runtime_args() []string { return append([]string{}, argslice...) }
//go:linkname syscall_Exit syscall.Exit
diff --git a/libgo/go/runtime/runtime1.go b/libgo/go/runtime/runtime1.go
index a8a53d3..39969d1 100644
--- a/libgo/go/runtime/runtime1.go
+++ b/libgo/go/runtime/runtime1.go
@@ -398,7 +398,7 @@ func parsedebugvars() {
traceback_env = traceback_cache
}
-//go:linkname setTraceback runtime..z2fdebug.SetTraceback
+//go:linkname setTraceback runtime_1debug.SetTraceback
func setTraceback(level string) {
var t uint32
switch level {
diff --git a/libgo/go/runtime/sema.go b/libgo/go/runtime/sema.go
index c1418b3..9a28880 100644
--- a/libgo/go/runtime/sema.go
+++ b/libgo/go/runtime/sema.go
@@ -51,27 +51,27 @@ var semtable [semTabSize]struct {
pad [cpu.CacheLinePadSize - unsafe.Sizeof(semaRoot{})]byte
}
-//go:linkname sync_runtime_Semacquire sync.runtime_Semacquire
+//go:linkname sync_runtime_Semacquire sync.runtime__Semacquire
func sync_runtime_Semacquire(addr *uint32) {
semacquire1(addr, false, semaBlockProfile, 0)
}
-//go:linkname poll_runtime_Semacquire internal..z2fpoll.runtime_Semacquire
+//go:linkname poll_runtime_Semacquire internal_1poll.runtime__Semacquire
func poll_runtime_Semacquire(addr *uint32) {
semacquire1(addr, false, semaBlockProfile, 0)
}
-//go:linkname sync_runtime_Semrelease sync.runtime_Semrelease
+//go:linkname sync_runtime_Semrelease sync.runtime__Semrelease
func sync_runtime_Semrelease(addr *uint32, handoff bool, skipframes int) {
semrelease1(addr, handoff, skipframes)
}
-//go:linkname sync_runtime_SemacquireMutex sync.runtime_SemacquireMutex
+//go:linkname sync_runtime_SemacquireMutex sync.runtime__SemacquireMutex
func sync_runtime_SemacquireMutex(addr *uint32, lifo bool, skipframes int) {
semacquire1(addr, lifo, semaBlockProfile|semaMutexProfile, skipframes)
}
-//go:linkname poll_runtime_Semrelease internal..z2fpoll.runtime_Semrelease
+//go:linkname poll_runtime_Semrelease internal_1poll.runtime__Semrelease
func poll_runtime_Semrelease(addr *uint32) {
semrelease(addr)
}
@@ -475,7 +475,7 @@ func less(a, b uint32) bool {
// notifyListAdd adds the caller to a notify list such that it can receive
// notifications. The caller must eventually call notifyListWait to wait for
// such a notification, passing the returned ticket number.
-//go:linkname notifyListAdd sync.runtime_notifyListAdd
+//go:linkname notifyListAdd sync.runtime__notifyListAdd
func notifyListAdd(l *notifyList) uint32 {
// This may be called concurrently, for example, when called from
// sync.Cond.Wait while holding a RWMutex in read mode.
@@ -484,7 +484,7 @@ func notifyListAdd(l *notifyList) uint32 {
// notifyListWait waits for a notification. If one has been sent since
// notifyListAdd was called, it returns immediately. Otherwise, it blocks.
-//go:linkname notifyListWait sync.runtime_notifyListWait
+//go:linkname notifyListWait sync.runtime__notifyListWait
func notifyListWait(l *notifyList, t uint32) {
lockWithRank(&l.lock, lockRankNotifyList)
@@ -518,7 +518,7 @@ func notifyListWait(l *notifyList, t uint32) {
}
// notifyListNotifyAll notifies all entries in the list.
-//go:linkname notifyListNotifyAll sync.runtime_notifyListNotifyAll
+//go:linkname notifyListNotifyAll sync.runtime__notifyListNotifyAll
func notifyListNotifyAll(l *notifyList) {
// Fast-path: if there are no new waiters since the last notification
// we don't need to acquire the lock.
@@ -550,7 +550,7 @@ func notifyListNotifyAll(l *notifyList) {
}
// notifyListNotifyOne notifies one entry in the list.
-//go:linkname notifyListNotifyOne sync.runtime_notifyListNotifyOne
+//go:linkname notifyListNotifyOne sync.runtime__notifyListNotifyOne
func notifyListNotifyOne(l *notifyList) {
// Fast-path: if there are no new waiters since the last notification
// we don't need to acquire the lock at all.
@@ -603,7 +603,7 @@ func notifyListNotifyOne(l *notifyList) {
unlock(&l.lock)
}
-//go:linkname notifyListCheck sync.runtime_notifyListCheck
+//go:linkname notifyListCheck sync.runtime__notifyListCheck
func notifyListCheck(sz uintptr) {
if sz != unsafe.Sizeof(notifyList{}) {
print("runtime: bad notifyList size - sync=", sz, " runtime=", unsafe.Sizeof(notifyList{}), "\n")
@@ -611,7 +611,7 @@ func notifyListCheck(sz uintptr) {
}
}
-//go:linkname sync_nanotime sync.runtime_nanotime
+//go:linkname sync_nanotime sync.runtime__nanotime
func sync_nanotime() int64 {
return nanotime()
}
diff --git a/libgo/go/runtime/sigqueue.go b/libgo/go/runtime/sigqueue.go
index 7d1028e..ed024e1 100644
--- a/libgo/go/runtime/sigqueue.go
+++ b/libgo/go/runtime/sigqueue.go
@@ -121,7 +121,7 @@ Send:
// Called to receive the next queued signal.
// Must only be called from a single goroutine at a time.
-//go:linkname signal_recv os..z2fsignal.signal_recv
+//go:linkname signal_recv os_1signal.signal__recv
func signal_recv() uint32 {
for {
// Serve any signals from local copy.
@@ -169,7 +169,7 @@ func signal_recv() uint32 {
// the signal(s) in question, and here we are just waiting to make sure
// that all the signals have been delivered to the user channels
// by the os/signal package.
-//go:linkname signalWaitUntilIdle os..z2fsignal.signalWaitUntilIdle
+//go:linkname signalWaitUntilIdle os_1signal.signalWaitUntilIdle
func signalWaitUntilIdle() {
// Although the signals we care about have been removed from
// sig.wanted, it is possible that another thread has received
@@ -189,7 +189,7 @@ func signalWaitUntilIdle() {
}
// Must only be called from a single goroutine at a time.
-//go:linkname signal_enable os..z2fsignal.signal_enable
+//go:linkname signal_enable os_1signal.signal__enable
func signal_enable(s uint32) {
if !sig.inuse {
// This is the first call to signal_enable. Initialize.
@@ -217,7 +217,7 @@ func signal_enable(s uint32) {
}
// Must only be called from a single goroutine at a time.
-//go:linkname signal_disable os..z2fsignal.signal_disable
+//go:linkname signal_disable os_1signal.signal__disable
func signal_disable(s uint32) {
if s >= uint32(len(sig.wanted)*32) {
return
@@ -230,7 +230,7 @@ func signal_disable(s uint32) {
}
// Must only be called from a single goroutine at a time.
-//go:linkname signal_ignore os..z2fsignal.signal_ignore
+//go:linkname signal_ignore os_1signal.signal__ignore
func signal_ignore(s uint32) {
if s >= uint32(len(sig.wanted)*32) {
return
@@ -257,7 +257,7 @@ func sigInitIgnored(s uint32) {
}
// Checked by signal handlers.
-//go:linkname signal_ignored os..z2fsignal.signal_ignored
+//go:linkname signal_ignored os_1signal.signal__ignored
func signal_ignored(s uint32) bool {
i := atomic.Load(&sig.ignored[s/32])
return i&(1<<(s&31)) != 0
diff --git a/libgo/go/runtime/slice.go b/libgo/go/runtime/slice.go
index 97b2659..ddd588e 100644
--- a/libgo/go/runtime/slice.go
+++ b/libgo/go/runtime/slice.go
@@ -15,6 +15,7 @@ import (
//go:linkname panicmakeslicelen
//go:linkname panicmakeslicecap
//go:linkname makeslice
+//go:linkname checkMakeSlice
//go:linkname makeslice64
//go:linkname growslice
//go:linkname slicecopy
@@ -91,6 +92,13 @@ func makeslicecopy(et *_type, tolen int, fromlen int, from unsafe.Pointer) unsaf
}
func makeslice(et *_type, len, cap int) unsafe.Pointer {
+ mem := checkMakeSlice(et, len, cap)
+ return mallocgc(mem, et, true)
+}
+
+// checkMakeSlice is called for append(s, make([]T, len, cap)...) to check
+// the values of len and cap.
+func checkMakeSlice(et *_type, len, cap int) uintptr {
mem, overflow := math.MulUintptr(et.size, uintptr(cap))
if overflow || mem > maxAlloc || len < 0 || len > cap {
// NOTE: Produce a 'len out of range' error instead of a
@@ -104,8 +112,7 @@ func makeslice(et *_type, len, cap int) unsafe.Pointer {
}
panicmakeslicecap()
}
-
- return mallocgc(mem, et, true)
+ return mem
}
func makeslice64(et *_type, len64, cap64 int64) unsafe.Pointer {
diff --git a/libgo/go/runtime/symtab.go b/libgo/go/runtime/symtab.go
index bb0b61d..22a2b13 100644
--- a/libgo/go/runtime/symtab.go
+++ b/libgo/go/runtime/symtab.go
@@ -5,6 +5,7 @@
package runtime
import (
+ "internal/bytealg"
_ "unsafe" // for go:linkname
)
@@ -119,7 +120,7 @@ func pcInlineCallers(pc uintptr, locbuf *location, max int32) int32
// runtime_expandFinalInlineFrame expands the final pc in stk to include all
// "callers" if pc is inline.
//
-//go:linkname runtime_expandFinalInlineFrame runtime..z2fpprof.runtime_expandFinalInlineFrame
+//go:linkname runtime_expandFinalInlineFrame runtime_1pprof.runtime__expandFinalInlineFrame
func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr {
if len(stk) == 0 {
return stk
@@ -210,42 +211,62 @@ func hexDigitsToRune(digits []byte, ndig int) rune {
return rune(result)
}
-// Perform an in-place decoding on the input byte slice. This looks
-// for "..z<hex 2 >", "..u<hex x 4>" and "..U<hex x 8>" and overwrites
-// with the encoded bytes corresponding to the unicode in question.
-// Return value is the number of bytes taken by the result.
-
+// decodeIdentifier performs an in-place decoding on the input byte slice.
+// This undoes the compiler underscore mangling.
+// Returns the number of bytes used by the result.
func decodeIdentifier(bsl []byte) int {
+ underscoreCodes := map[byte]byte{
+ '_': '_',
+ '0': '.',
+ '1': '/',
+ '2': '*',
+ '3': ',',
+ '4': '{',
+ '5': '}',
+ '6': '[',
+ '7': ']',
+ '8': '(',
+ '9': ')',
+ 'a': '"',
+ 'b': ' ',
+ 'c': ';',
+ }
+
j := 0
for i := 0; i < len(bsl); i++ {
b := bsl[i]
+ if b != '_' || i+1 >= len(bsl) {
+ bsl[j] = b
+ j++
+ continue
+ }
+
+ if d, ok := underscoreCodes[bsl[i+1]]; ok {
+ i++
+ bsl[j] = d
+ j++
+ continue
+ }
+
+ rlen := 0
+ switch bsl[i+1] {
+ case 'x':
+ rlen = 2
+ case 'u':
+ rlen = 4
+ case 'U':
+ rlen = 8
+ }
- if i+1 < len(bsl) && bsl[i] == '.' && bsl[i+1] == '.' {
- if i+4 < len(bsl) && bsl[i+2] == 'z' {
- digits := bsl[i+3:]
- r := hexDigitsToRune(digits, 2)
- nc := encoderune(bsl[j:], r)
- j += nc
- i += 4
- continue
- } else if i+6 < len(bsl) && bsl[i+2] == 'u' {
- digits := bsl[i+3:]
- r := hexDigitsToRune(digits, 4)
- nc := encoderune(bsl[j:], r)
- j += nc
- i += 6
- continue
- } else if i+10 < len(bsl) && bsl[i+2] == 'U' {
- digits := bsl[i+3:]
- r := hexDigitsToRune(digits, 8)
- nc := encoderune(bsl[j:], r)
- j += nc
- i += 10
- continue
- }
+ if rlen > 0 && i+1+rlen < len(bsl) {
+ r := hexDigitsToRune(bsl[i+2:], rlen)
+ nc := encoderune(bsl[j:], r)
+ j += nc
+ i += rlen + 1
+ } else {
+ bsl[j] = b
+ j++
}
- bsl[j] = b
- j += 1
}
return j
}
@@ -254,6 +275,11 @@ func decodeIdentifier(bsl []byte) int {
// as used in the compiler.
func demangleSymbol(s string) string {
+ if bytealg.IndexByteString(s, '.') < 0 {
+ // A symbol with no '.' is not a Go symbol.
+ return s
+ }
+
bsl := []byte(s)
nchars := decodeIdentifier(bsl)
bsl = bsl[:nchars]
diff --git a/libgo/go/runtime/trace.go b/libgo/go/runtime/trace.go
index ce185fc..b05f30a 100644
--- a/libgo/go/runtime/trace.go
+++ b/libgo/go/runtime/trace.go
@@ -1152,7 +1152,7 @@ func traceNextGC() {
// To access runtime functions from runtime/trace.
// See runtime/trace/annotation.go
-//go:linkname trace_userTaskCreate runtime..z2ftrace.userTaskCreate
+//go:linkname trace_userTaskCreate runtime_1trace.userTaskCreate
func trace_userTaskCreate(id, parentID uint64, taskType string) {
if !trace.enabled {
return
@@ -1170,12 +1170,12 @@ func trace_userTaskCreate(id, parentID uint64, taskType string) {
traceReleaseBuffer(pid)
}
-//go:linkname trace_userTaskEnd runtime..z2ftrace.userTaskEnd
+//go:linkname trace_userTaskEnd runtime_1trace.userTaskEnd
func trace_userTaskEnd(id uint64) {
traceEvent(traceEvUserTaskEnd, 2, id)
}
-//go:linkname trace_userRegion runtime..z2ftrace.userRegion
+//go:linkname trace_userRegion runtime_1trace.userRegion
func trace_userRegion(id, mode uint64, name string) {
if !trace.enabled {
return
@@ -1192,7 +1192,7 @@ func trace_userRegion(id, mode uint64, name string) {
traceReleaseBuffer(pid)
}
-//go:linkname trace_userLog runtime..z2ftrace.userLog
+//go:linkname trace_userLog runtime_1trace.userLog
func trace_userLog(id uint64, category, message string) {
if !trace.enabled {
return
diff --git a/libgo/go/runtime/traceback_gccgo.go b/libgo/go/runtime/traceback_gccgo.go
index 1ba91af..ebdbefc 100644
--- a/libgo/go/runtime/traceback_gccgo.go
+++ b/libgo/go/runtime/traceback_gccgo.go
@@ -184,10 +184,10 @@ func showfuncinfo(name string, firstFrame bool) bool {
// isExportedRuntime reports whether name is an exported runtime function.
// It is only for runtime functions, so ASCII A-Z is fine. Here also check
// for mangled functions from runtime/<...>, which will be prefixed with
-// "runtime..z2f".
+// "runtime_1".
func isExportedRuntime(name string) bool {
const n = len("runtime.")
- if hasPrefix(name, "runtime..z2f") {
+ if hasPrefix(name, "runtime_1") {
return true
}
return len(name) > n && name[:n] == "runtime." && 'A' <= name[n] && name[n] <= 'Z'
diff --git a/libgo/go/sync/atomic/atomic.c b/libgo/go/sync/atomic/atomic.c
index 90a4ff3..71d51aa 100644
--- a/libgo/go/sync/atomic/atomic.c
+++ b/libgo/go/sync/atomic/atomic.c
@@ -9,7 +9,7 @@
#include "runtime.h"
int32_t SwapInt32 (int32_t *, int32_t)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.SwapInt32")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.SwapInt32")
__attribute__ ((no_split_stack));
int32_t
@@ -19,7 +19,7 @@ SwapInt32 (int32_t *addr, int32_t new)
}
int64_t SwapInt64 (int64_t *, int64_t)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.SwapInt64")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.SwapInt64")
__attribute__ ((no_split_stack));
int64_t
@@ -31,7 +31,7 @@ SwapInt64 (int64_t *addr, int64_t new)
}
uint32_t SwapUint32 (uint32_t *, uint32_t)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.SwapUint32")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.SwapUint32")
__attribute__ ((no_split_stack));
uint32_t
@@ -41,7 +41,7 @@ SwapUint32 (uint32_t *addr, uint32_t new)
}
uint64_t SwapUint64 (uint64_t *, uint64_t)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.SwapUint64")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.SwapUint64")
__attribute__ ((no_split_stack));
uint64_t
@@ -53,7 +53,7 @@ SwapUint64 (uint64_t *addr, uint64_t new)
}
uintptr_t SwapUintptr (uintptr_t *, uintptr_t)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.SwapUintptr")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.SwapUintptr")
__attribute__ ((no_split_stack));
uintptr_t
@@ -63,7 +63,7 @@ SwapUintptr (uintptr_t *addr, uintptr_t new)
}
_Bool CompareAndSwapInt32 (int32_t *, int32_t, int32_t)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.CompareAndSwapInt32")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.CompareAndSwapInt32")
__attribute__ ((no_split_stack));
_Bool
@@ -74,7 +74,7 @@ CompareAndSwapInt32 (int32_t *val, int32_t old, int32_t new)
}
_Bool CompareAndSwapInt64 (int64_t *, int64_t, int64_t)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.CompareAndSwapInt64")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.CompareAndSwapInt64")
__attribute__ ((no_split_stack));
_Bool
@@ -87,7 +87,7 @@ CompareAndSwapInt64 (int64_t *val, int64_t old, int64_t new)
}
_Bool CompareAndSwapUint32 (uint32_t *, uint32_t, uint32_t)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.CompareAndSwapUint32")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.CompareAndSwapUint32")
__attribute__ ((no_split_stack));
_Bool
@@ -98,7 +98,7 @@ CompareAndSwapUint32 (uint32_t *val, uint32_t old, uint32_t new)
}
_Bool CompareAndSwapUint64 (uint64_t *, uint64_t, uint64_t)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.CompareAndSwapUint64")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.CompareAndSwapUint64")
__attribute__ ((no_split_stack));
_Bool
@@ -111,7 +111,7 @@ CompareAndSwapUint64 (uint64_t *val, uint64_t old, uint64_t new)
}
_Bool CompareAndSwapUintptr (uintptr_t *, uintptr_t, uintptr_t)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.CompareAndSwapUintptr")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.CompareAndSwapUintptr")
__attribute__ ((no_split_stack));
_Bool
@@ -122,7 +122,7 @@ CompareAndSwapUintptr (uintptr_t *val, uintptr_t old, uintptr_t new)
}
int32_t AddInt32 (int32_t *, int32_t)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.AddInt32")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.AddInt32")
__attribute__ ((no_split_stack));
int32_t
@@ -132,7 +132,7 @@ AddInt32 (int32_t *val, int32_t delta)
}
uint32_t AddUint32 (uint32_t *, uint32_t)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.AddUint32")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.AddUint32")
__attribute__ ((no_split_stack));
uint32_t
@@ -142,7 +142,7 @@ AddUint32 (uint32_t *val, uint32_t delta)
}
int64_t AddInt64 (int64_t *, int64_t)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.AddInt64")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.AddInt64")
__attribute__ ((no_split_stack));
int64_t
@@ -154,7 +154,7 @@ AddInt64 (int64_t *val, int64_t delta)
}
uint64_t AddUint64 (uint64_t *, uint64_t)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.AddUint64")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.AddUint64")
__attribute__ ((no_split_stack));
uint64_t
@@ -166,7 +166,7 @@ AddUint64 (uint64_t *val, uint64_t delta)
}
uintptr_t AddUintptr (uintptr_t *, uintptr_t)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.AddUintptr")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.AddUintptr")
__attribute__ ((no_split_stack));
uintptr_t
@@ -176,7 +176,7 @@ AddUintptr (uintptr_t *val, uintptr_t delta)
}
int32_t LoadInt32 (int32_t *addr)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.LoadInt32")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.LoadInt32")
__attribute__ ((no_split_stack));
int32_t
@@ -186,7 +186,7 @@ LoadInt32 (int32_t *addr)
}
int64_t LoadInt64 (int64_t *addr)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.LoadInt64")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.LoadInt64")
__attribute__ ((no_split_stack));
int64_t
@@ -198,7 +198,7 @@ LoadInt64 (int64_t *addr)
}
uint32_t LoadUint32 (uint32_t *addr)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.LoadUint32")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.LoadUint32")
__attribute__ ((no_split_stack));
uint32_t
@@ -208,7 +208,7 @@ LoadUint32 (uint32_t *addr)
}
uint64_t LoadUint64 (uint64_t *addr)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.LoadUint64")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.LoadUint64")
__attribute__ ((no_split_stack));
uint64_t
@@ -220,7 +220,7 @@ LoadUint64 (uint64_t *addr)
}
uintptr_t LoadUintptr (uintptr_t *addr)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.LoadUintptr")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.LoadUintptr")
__attribute__ ((no_split_stack));
uintptr_t
@@ -230,7 +230,7 @@ LoadUintptr (uintptr_t *addr)
}
void *LoadPointer (void **addr)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.LoadPointer")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.LoadPointer")
__attribute__ ((no_split_stack));
void *
@@ -240,7 +240,7 @@ LoadPointer (void **addr)
}
void StoreInt32 (int32_t *addr, int32_t val)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.StoreInt32")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.StoreInt32")
__attribute__ ((no_split_stack));
void
@@ -250,7 +250,7 @@ StoreInt32 (int32_t *addr, int32_t val)
}
void StoreInt64 (int64_t *addr, int64_t val)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.StoreInt64")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.StoreInt64")
__attribute__ ((no_split_stack));
void
@@ -262,7 +262,7 @@ StoreInt64 (int64_t *addr, int64_t val)
}
void StoreUint32 (uint32_t *addr, uint32_t val)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.StoreUint32")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.StoreUint32")
__attribute__ ((no_split_stack));
void
@@ -272,7 +272,7 @@ StoreUint32 (uint32_t *addr, uint32_t val)
}
void StoreUint64 (uint64_t *addr, uint64_t val)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.StoreUint64")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.StoreUint64")
__attribute__ ((no_split_stack));
void
@@ -284,7 +284,7 @@ StoreUint64 (uint64_t *addr, uint64_t val)
}
void StoreUintptr (uintptr_t *addr, uintptr_t val)
- __asm__ (GOSYM_PREFIX "sync..z2fatomic.StoreUintptr")
+ __asm__ (GOSYM_PREFIX "sync_1atomic.StoreUintptr")
__attribute__ ((no_split_stack));
void
diff --git a/libgo/gotool-packages.txt b/libgo/gotool-packages.txt
index 745c34c..c11df02 100644
--- a/libgo/gotool-packages.txt
+++ b/libgo/gotool-packages.txt
@@ -43,6 +43,7 @@ cmd/internal/buildid
cmd/internal/diff
cmd/internal/edit
cmd/internal/objabi
+cmd/internal/pkgpath
cmd/internal/sys
cmd/internal/test2json
golang.org/x/crypto/ed25519
diff --git a/libgo/misc/cgo/errors/badsym_test.go b/libgo/misc/cgo/errors/badsym_test.go
new file mode 100644
index 0000000..b2701bf
--- /dev/null
+++ b/libgo/misc/cgo/errors/badsym_test.go
@@ -0,0 +1,216 @@
+// Copyright 2020 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 errorstest
+
+import (
+ "bytes"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+ "testing"
+ "unicode"
+)
+
+// A manually modified object file could pass unexpected characters
+// into the files generated by cgo.
+
+const magicInput = "abcdefghijklmnopqrstuvwxyz0123"
+const magicReplace = "\n//go:cgo_ldflag \"-badflag\"\n//"
+
+const cSymbol = "BadSymbol" + magicInput + "Name"
+const cDefSource = "int " + cSymbol + " = 1;"
+const cRefSource = "extern int " + cSymbol + "; int F() { return " + cSymbol + "; }"
+
+// goSource is the source code for the trivial Go file we use.
+// We will replace TMPDIR with the temporary directory name.
+const goSource = `
+package main
+
+// #cgo LDFLAGS: TMPDIR/cbad.o TMPDIR/cbad.so
+// extern int F();
+import "C"
+
+func main() {
+ println(C.F())
+}
+`
+
+func TestBadSymbol(t *testing.T) {
+ dir := t.TempDir()
+
+ mkdir := func(base string) string {
+ ret := filepath.Join(dir, base)
+ if err := os.Mkdir(ret, 0755); err != nil {
+ t.Fatal(err)
+ }
+ return ret
+ }
+
+ cdir := mkdir("c")
+ godir := mkdir("go")
+
+ makeFile := func(mdir, base, source string) string {
+ ret := filepath.Join(mdir, base)
+ if err := ioutil.WriteFile(ret, []byte(source), 0644); err != nil {
+ t.Fatal(err)
+ }
+ return ret
+ }
+
+ cDefFile := makeFile(cdir, "cdef.c", cDefSource)
+ cRefFile := makeFile(cdir, "cref.c", cRefSource)
+
+ ccCmd := cCompilerCmd(t)
+
+ cCompile := func(arg, base, src string) string {
+ out := filepath.Join(cdir, base)
+ run := append(ccCmd, arg, "-o", out, src)
+ output, err := exec.Command(run[0], run[1:]...).CombinedOutput()
+ if err != nil {
+ t.Log(run)
+ t.Logf("%s", output)
+ t.Fatal(err)
+ }
+ if err := os.Remove(src); err != nil {
+ t.Fatal(err)
+ }
+ return out
+ }
+
+ // Build a shared library that defines a symbol whose name
+ // contains magicInput.
+
+ cShared := cCompile("-shared", "c.so", cDefFile)
+
+ // Build an object file that refers to the symbol whose name
+ // contains magicInput.
+
+ cObj := cCompile("-c", "c.o", cRefFile)
+
+ // Rewrite the shared library and the object file, replacing
+ // magicInput with magicReplace. This will have the effect of
+ // introducing a symbol whose name looks like a cgo command.
+ // The cgo tool will use that name when it generates the
+ // _cgo_import.go file, thus smuggling a magic //go:cgo_ldflag
+ // pragma into a Go file. We used to not check the pragmas in
+ // _cgo_import.go.
+
+ rewrite := func(from, to string) {
+ obj, err := ioutil.ReadFile(from)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if bytes.Count(obj, []byte(magicInput)) == 0 {
+ t.Fatalf("%s: did not find magic string", from)
+ }
+
+ if len(magicInput) != len(magicReplace) {
+ t.Fatalf("internal test error: different magic lengths: %d != %d", len(magicInput), len(magicReplace))
+ }
+
+ obj = bytes.ReplaceAll(obj, []byte(magicInput), []byte(magicReplace))
+
+ if err := ioutil.WriteFile(to, obj, 0644); err != nil {
+ t.Fatal(err)
+ }
+ }
+
+ cBadShared := filepath.Join(godir, "cbad.so")
+ rewrite(cShared, cBadShared)
+
+ cBadObj := filepath.Join(godir, "cbad.o")
+ rewrite(cObj, cBadObj)
+
+ goSourceBadObject := strings.ReplaceAll(goSource, "TMPDIR", godir)
+ makeFile(godir, "go.go", goSourceBadObject)
+
+ makeFile(godir, "go.mod", "module badsym")
+
+ // Try to build our little package.
+ cmd := exec.Command("go", "build", "-ldflags=-v")
+ cmd.Dir = godir
+ output, err := cmd.CombinedOutput()
+
+ // The build should fail, but we want it to fail because we
+ // detected the error, not because we passed a bad flag to the
+ // C linker.
+
+ if err == nil {
+ t.Errorf("go build succeeded unexpectedly")
+ }
+
+ t.Logf("%s", output)
+
+ for _, line := range bytes.Split(output, []byte("\n")) {
+ if bytes.Contains(line, []byte("dynamic symbol")) && bytes.Contains(line, []byte("contains unsupported character")) {
+ // This is the error from cgo.
+ continue
+ }
+
+ // We passed -ldflags=-v to see the external linker invocation,
+ // which should not include -badflag.
+ if bytes.Contains(line, []byte("-badflag")) {
+ t.Error("output should not mention -badflag")
+ }
+
+ // Also check for compiler errors, just in case.
+ // GCC says "unrecognized command line option".
+ // clang says "unknown argument".
+ if bytes.Contains(line, []byte("unrecognized")) || bytes.Contains(output, []byte("unknown")) {
+ t.Error("problem should have been caught before invoking C linker")
+ }
+ }
+}
+
+func cCompilerCmd(t *testing.T) []string {
+ cc := []string{goEnv(t, "CC")}
+
+ out := goEnv(t, "GOGCCFLAGS")
+ quote := '\000'
+ start := 0
+ lastSpace := true
+ backslash := false
+ s := string(out)
+ for i, c := range s {
+ if quote == '\000' && unicode.IsSpace(c) {
+ if !lastSpace {
+ cc = append(cc, s[start:i])
+ lastSpace = true
+ }
+ } else {
+ if lastSpace {
+ start = i
+ lastSpace = false
+ }
+ if quote == '\000' && !backslash && (c == '"' || c == '\'') {
+ quote = c
+ backslash = false
+ } else if !backslash && quote == c {
+ quote = '\000'
+ } else if (quote == '\000' || quote == '"') && !backslash && c == '\\' {
+ backslash = true
+ } else {
+ backslash = false
+ }
+ }
+ }
+ if !lastSpace {
+ cc = append(cc, s[start:])
+ }
+ return cc
+}
+
+func goEnv(t *testing.T, key string) string {
+ out, err := exec.Command("go", "env", key).CombinedOutput()
+ if err != nil {
+ t.Logf("go env %s\n", key)
+ t.Logf("%s", out)
+ t.Fatal(err)
+ }
+ return strings.TrimSpace(string(out))
+}
diff --git a/libgo/mksysinfo.sh b/libgo/mksysinfo.sh
index deac5ce..b32a026 100755
--- a/libgo/mksysinfo.sh
+++ b/libgo/mksysinfo.sh
@@ -194,6 +194,7 @@ fi
# Networking constants.
egrep '^const _(AF|ARPHRD|ETH|IN|SOCK|SOL|SO|IPPROTO|TCP|IP|IPV6)_' gen-sysinfo.go |
+ grep -v '_val =' |
sed -e 's/^\(const \)_\([^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
grep '^const _SOMAXCONN' gen-sysinfo.go |
sed -e 's/^\(const \)_\(SOMAXCONN[^= ]*\)\(.*\)$/\1\2 = _\2/' \
@@ -213,6 +214,14 @@ for m in SOCK_CLOEXEC SOCK_NONBLOCK; do
fi
done
+# On 32-bit GNU/Linux the expression for SO_RCVTIMEO is too complicated
+# for -fdump-go-spec.
+if ! grep '^const SO_RCVTIMEO ' ${OUT} >/dev/null 2>&1; then
+ if grep '^const _SO_RCVTIMEO_val' ${OUT} >/dev/null 2>&1; then
+ echo 'const SO_RCVTIMEO = _SO_RCVTIMEO_val' >> ${OUT}
+ fi
+fi
+
# The syscall package requires AF_LOCAL.
if ! grep '^const AF_LOCAL ' ${OUT} >/dev/null 2>&1; then
if grep '^const AF_UNIX ' ${OUT} >/dev/null 2>&1; then
diff --git a/libgo/runtime/go-cdiv.c b/libgo/runtime/go-cdiv.c
deleted file mode 100644
index 0355e26..0000000
--- a/libgo/runtime/go-cdiv.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* go-cdiv.c -- complex division routines
-
- Copyright 2013 The Go Authors. All rights reserved.
- Use of this source code is governed by a BSD-style
- license that can be found in the LICENSE file. */
-
-#include <complex.h>
-#include <math.h>
-
-/* Calls to these functions are generated by the Go frontend for
- division of complex64 or complex128. We use these because Go's
- complex division expects slightly different results from the GCC
- default. When dividing NaN+1.0i / 0+0i, Go expects NaN+NaNi but
- GCC generates NaN+Infi. NaN+Infi seems wrong seems the rules of
- C99 Annex G specify that if either side of a complex number is Inf,
- the the whole number is Inf, but an operation involving NaN ought
- to result in NaN, not Inf. */
-
-complex float
-__go_complex64_div (complex float a, complex float b)
-{
- if (__builtin_expect (b == 0, 0))
- {
- if (!isinf (crealf (a))
- && !isinf (cimagf (a))
- && (isnan (crealf (a)) || isnan (cimagf (a))))
- {
- /* Pass "1" to nanf to match math/bits.go. */
- return nanf("1") + nanf("1")*I;
- }
- }
- return a / b;
-}
-
-complex double
-__go_complex128_div (complex double a, complex double b)
-{
- if (__builtin_expect (b == 0, 0))
- {
- if (!isinf (creal (a))
- && !isinf (cimag (a))
- && (isnan (creal (a)) || isnan (cimag (a))))
- {
- /* Pass "1" to nan to match math/bits.go. */
- return nan("1") + nan("1")*I;
- }
- }
- return a / b;
-}
diff --git a/libgo/runtime/go-ffi.c b/libgo/runtime/go-ffi.c
index b030f5e..1ec5f87 100644
--- a/libgo/runtime/go-ffi.c
+++ b/libgo/runtime/go-ffi.c
@@ -16,36 +16,36 @@
the libffi type values. */
ffi_type *go_ffi_type_pointer(void) __attribute__ ((no_split_stack));
-ffi_type *go_ffi_type_pointer(void) __asm__ ("runtime.ffi_type_pointer");
+ffi_type *go_ffi_type_pointer(void) __asm__ ("runtime.ffi__type__pointer");
ffi_type *go_ffi_type_sint8(void) __attribute__ ((no_split_stack));
-ffi_type *go_ffi_type_sint8(void) __asm__ ("runtime.ffi_type_sint8");
+ffi_type *go_ffi_type_sint8(void) __asm__ ("runtime.ffi__type__sint8");
ffi_type *go_ffi_type_sint16(void) __attribute__ ((no_split_stack));
-ffi_type *go_ffi_type_sint16(void) __asm__ ("runtime.ffi_type_sint16");
+ffi_type *go_ffi_type_sint16(void) __asm__ ("runtime.ffi__type__sint16");
ffi_type *go_ffi_type_sint32(void) __attribute__ ((no_split_stack));
-ffi_type *go_ffi_type_sint32(void) __asm__ ("runtime.ffi_type_sint32");
+ffi_type *go_ffi_type_sint32(void) __asm__ ("runtime.ffi__type__sint32");
ffi_type *go_ffi_type_sint64(void) __attribute__ ((no_split_stack));
-ffi_type *go_ffi_type_sint64(void) __asm__ ("runtime.ffi_type_sint64");
+ffi_type *go_ffi_type_sint64(void) __asm__ ("runtime.ffi__type__sint64");
ffi_type *go_ffi_type_uint8(void) __attribute__ ((no_split_stack));
-ffi_type *go_ffi_type_uint8(void) __asm__ ("runtime.ffi_type_uint8");
+ffi_type *go_ffi_type_uint8(void) __asm__ ("runtime.ffi__type__uint8");
ffi_type *go_ffi_type_uint16(void) __attribute__ ((no_split_stack));
-ffi_type *go_ffi_type_uint16(void) __asm__ ("runtime.ffi_type_uint16");
+ffi_type *go_ffi_type_uint16(void) __asm__ ("runtime.ffi__type__uint16");
ffi_type *go_ffi_type_uint32(void) __attribute__ ((no_split_stack));
-ffi_type *go_ffi_type_uint32(void) __asm__ ("runtime.ffi_type_uint32");
+ffi_type *go_ffi_type_uint32(void) __asm__ ("runtime.ffi__type__uint32");
ffi_type *go_ffi_type_uint64(void) __attribute__ ((no_split_stack));
-ffi_type *go_ffi_type_uint64(void) __asm__ ("runtime.ffi_type_uint64");
+ffi_type *go_ffi_type_uint64(void) __asm__ ("runtime.ffi__type__uint64");
ffi_type *go_ffi_type_float(void) __attribute__ ((no_split_stack));
-ffi_type *go_ffi_type_float(void) __asm__ ("runtime.ffi_type_float");
+ffi_type *go_ffi_type_float(void) __asm__ ("runtime.ffi__type__float");
ffi_type *go_ffi_type_double(void) __attribute__ ((no_split_stack));
-ffi_type *go_ffi_type_double(void) __asm__ ("runtime.ffi_type_double");
+ffi_type *go_ffi_type_double(void) __asm__ ("runtime.ffi__type__double");
ffi_type *go_ffi_type_complex_float(void) __attribute__ ((no_split_stack));
-ffi_type *go_ffi_type_complex_float(void) __asm__ ("runtime.ffi_type_complex_float");
+ffi_type *go_ffi_type_complex_float(void) __asm__ ("runtime.ffi__type__complex__float");
ffi_type *go_ffi_type_complex_double(void) __attribute__ ((no_split_stack));
-ffi_type *go_ffi_type_complex_double(void) __asm__ ("runtime.ffi_type_complex_double");
+ffi_type *go_ffi_type_complex_double(void) __asm__ ("runtime.ffi__type__complex__double");
ffi_type *go_ffi_type_void(void) __attribute__ ((no_split_stack));
-ffi_type *go_ffi_type_void(void) __asm__ ("runtime.ffi_type_void");
+ffi_type *go_ffi_type_void(void) __asm__ ("runtime.ffi__type__void");
_Bool go_ffi_supports_complex(void) __attribute__ ((no_split_stack));
-_Bool go_ffi_supports_complex(void) __asm__ ("runtime.ffi_supports_complex");
+_Bool go_ffi_supports_complex(void) __asm__ ("runtime.ffi__supports__complex");
ffi_type *
go_ffi_type_pointer(void)
diff --git a/libgo/runtime/go-setenv.c b/libgo/runtime/go-setenv.c
index 81b1775..08987de 100644
--- a/libgo/runtime/go-setenv.c
+++ b/libgo/runtime/go-setenv.c
@@ -13,7 +13,7 @@
/* Set the C environment from Go. This is called by syscall.Setenv. */
-void setenv_c (String, String) __asm__ (GOSYM_PREFIX "syscall.setenv_c");
+void setenv_c (String, String) __asm__ (GOSYM_PREFIX "syscall.setenv__c");
void
setenv_c (String k, String v)
diff --git a/libgo/runtime/go-unsafe-pointer.c b/libgo/runtime/go-unsafe-pointer.c
index 364878e..e24bfb2 100644
--- a/libgo/runtime/go-unsafe-pointer.c
+++ b/libgo/runtime/go-unsafe-pointer.c
@@ -72,7 +72,7 @@ const struct _type unsafe_Pointer =
it to be defined elsewhere. */
extern const struct ptrtype pointer_unsafe_Pointer
- __asm__ (GOSYM_PREFIX "type...1unsafe.Pointer");
+ __asm__ (GOSYM_PREFIX "unsafe.Pointer..p");
/* The reflection string. */
#define PREFLECTION "*unsafe.Pointer"
@@ -83,7 +83,7 @@ static const String preflection_string =
};
extern const byte pointer_unsafe_Pointer_gc[]
- __asm__ (GOSYM_PREFIX "type...1unsafe.Pointer..g");
+ __asm__ (GOSYM_PREFIX "unsafe.Pointer..p..g");
const byte pointer_unsafe_Pointer_gc[] = { 1 };
diff --git a/libgo/runtime/go-unsetenv.c b/libgo/runtime/go-unsetenv.c
index 2135997..4b5058a 100644
--- a/libgo/runtime/go-unsetenv.c
+++ b/libgo/runtime/go-unsetenv.c
@@ -14,7 +14,7 @@
/* Unset an environment variable from Go. This is called by
syscall.Unsetenv. */
-void unsetenv_c (String) __asm__ (GOSYM_PREFIX "syscall.unsetenv_c");
+void unsetenv_c (String) __asm__ (GOSYM_PREFIX "syscall.unsetenv__c");
void
unsetenv_c (String k)
diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h
index f46eaea..3a65d44 100644
--- a/libgo/runtime/runtime.h
+++ b/libgo/runtime/runtime.h
@@ -440,7 +440,7 @@ void runtime_freedefer(Defer*);
extern void _cgo_wait_runtime_init_done (void);
extern void _cgo_notify_runtime_init_done (void)
- __asm__ (GOSYM_PREFIX "runtime._cgo_notify_runtime_init_done");
+ __asm__ (GOSYM_PREFIX "runtime.__cgo__notify__runtime__init__done");
extern _Bool runtime_iscgo;
extern uintptr __go_end __attribute__ ((weak));
extern void *getitab(const struct _type *, const struct _type *, _Bool)
diff --git a/libgo/sysinfo.c b/libgo/sysinfo.c
index 7086381..a060ea8 100644
--- a/libgo/sysinfo.c
+++ b/libgo/sysinfo.c
@@ -337,6 +337,9 @@ enum {
#ifdef BIOCVERSION
BIOCVERSION_val = BIOCVERSION,
#endif
+#ifdef SO_RCVTIMEO
+ SO_RCVTIMEO_val = SO_RCVTIMEO,
+#endif
};
// SIOCGIFMTU can't be added in the above enum as it might
diff --git a/libgo/testsuite/gotest b/libgo/testsuite/gotest
index 0fd6419..8c3c5ca 100755
--- a/libgo/testsuite/gotest
+++ b/libgo/testsuite/gotest
@@ -496,7 +496,8 @@ testname() {
localname() {
# The package main has been renamed to __main__ when imported.
# Adjust its uses.
- echo $1 | sed 's/^main\./__main__./'
+ # Also demangle underscores.
+ echo $1 | sed 's/^main\./__main__./' | sed 's/__/_/'
}
# Takes a list of tests derived from 'nm' output (whose symbols are mangled)
@@ -504,7 +505,7 @@ localname() {
# Example:
#
# Original symbol: foo/bar/leaf.Mumble
-# Mangled symbol: foo..z2fbar..z2fleaf.Mumble
+# Mangled symbol: foo_1fbar_1leaf.Mumble
# Returned: leaf.Mumble
#
symtogo() {
@@ -522,7 +523,7 @@ symtogo() {
if expr "$tp" : '^type\.\.' >/dev/null 2>&1; then
continue
fi
- s=$(echo "$tp" | sed -e 's/\.\.z2f/%/g' | sed -e 's/.*%//')
+ s=$(echo "$tp" | sed -e 's/_1/%/g' | sed -e 's/.*%//')
# Screen out methods (X.Y.Z).
if ! expr "$s" : '^[^.]*\.[^.]*$' >/dev/null 2>&1; then
continue
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 83f4ad7..5cc423c 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,135 @@
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ * configure: Regenerate.
+
+2020-11-25 Thomas Schwinge <thomas@codesourcery.com>
+
+ * testsuite/libgomp.oacc-c++/cache-1.C: New.
+ * testsuite/libgomp.oacc-c-c++-common/cache-1.c: Update.
+
+2020-11-25 Andrew Stubbs <ams@codesourcery.com>
+
+ * testsuite/libgomp.oacc-fortran/atomic_capture-1.f90 (main): Adjust
+ expected results.
+
+2020-11-24 Andrew Stubbs <ams@codesourcery.com>
+
+ * plugin/plugin-gcn.c: Don't redefine relocations if elf.h has them.
+ (reserved): Delete unused define.
+
+2020-11-24 Thomas Schwinge <thomas@codesourcery.com>
+
+ * testsuite/libgomp.oacc-c-c++-common/kernels-decompose-1.c: Avoid
+ Tcl 8.5-specific behavior.
+ * testsuite/libgomp.oacc-fortran/pr94358-1.f90: Likewise.
+
+2020-11-18 Kwok Cheung Yeung <kcy@codesourcery.com>
+
+ * env.c (gomp_global_icv): Remove nest_var field. Add
+ max_active_levels_var field.
+ (gomp_max_active_levels_var): Remove.
+ (parse_boolean): Return true on success.
+ (handle_omp_display_env): Express OMP_NESTED in terms of
+ max_active_levels_var. Change format specifier for
+ max_active_levels_var.
+ (initialize_env): Set max_active_levels_var from
+ OMP_MAX_ACTIVE_LEVELS, OMP_NESTED, OMP_NUM_THREADS and
+ OMP_PROC_BIND.
+ * icv.c (omp_set_nested): Express in terms of
+ max_active_levels_var.
+ (omp_get_nested): Likewise.
+ (omp_set_max_active_levels): Use max_active_levels_var field instead
+ of gomp_max_active_levels_var.
+ (omp_get_max_active_levels): Likewise.
+ * libgomp.h (struct gomp_task_icv): Remove nest_var field. Add
+ max_active_levels_var field.
+ (gomp_supported_active_levels): Set to UCHAR_MAX.
+ (gomp_max_active_levels_var): Delete.
+ * libgomp.texi (omp_get_nested): Update documentation.
+ (omp_set_nested): Likewise.
+ (OMP_MAX_ACTIVE_LEVELS): Likewise.
+ (OMP_NESTED): Likewise.
+ (OMP_NUM_THREADS): Likewise.
+ (OMP_PROC_BIND): Likewise.
+ * parallel.c (gomp_resolve_num_threads): Replace reference
+ to nest_var with max_active_levels_var. Use max_active_levels_var
+ field instead of gomp_max_active_levels_var.
+
+2020-11-18 Tobias Burnus <tobias@codesourcery.com>
+
+ * testsuite/libgomp.c/usleep.h (fallback_usleep): Renamed from
+ nvptx_usleep; use also for device={arch(gcn)}.
+
+2020-11-14 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c-c++-common/allocate-1.c (struct S): New type.
+ (foo): Add tests for non-VLA private and firstprivate clauses on
+ omp task.
+ (bar): Likewise. Remove taking of address from private/firstprivate
+ variables.
+ * testsuite/libgomp.c++/allocate-1.C (struct S): New type.
+ (foo): Add p, q, px and s arguments. Add tests for array reductions
+ and for non-VLA private and firstprivate clauses on omp task.
+ (bar): Removed.
+ (main): Adjust foo caller. Don't call bar.
+
+2020-11-13 Gergö Barany <gergo@codesourcery.com>
+ Thomas Schwinge <thomas@codesourcery.com>
+
+ * testsuite/libgomp.oacc-c-c++-common/declare-vla-kernels-decompose-ice-1.c:
+ New.
+ * testsuite/libgomp.oacc-c-c++-common/declare-vla-kernels-decompose.c:
+ Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/kernels-decompose-1.c:
+ Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/declare-vla.c: Adjust.
+ * testsuite/libgomp.oacc-fortran/pr94358-1.f90: Likewise.
+
+2020-11-13 Gergö Barany <gergo@codesourcery.com>
+ Thomas Schwinge <thomas@codesourcery.com>
+
+ PR fortran/94358
+ * testsuite/libgomp.oacc-fortran/pr94358-1.f90: New.
+
+2020-11-13 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c-c++-common/allocate-1.c (foo): Add tests
+ for array reductions.
+ (main): Adjust foo callers.
+
+2020-11-12 Jakub Jelinek <jakub@redhat.com>
+
+ * libgomp.map (GOMP_alloc, GOMP_free): Export at GOMP_5.0.1.
+ * omp.h.in (omp_alloc): Add malloc and alloc_size attributes.
+ * libgomp_g.h (GOMP_alloc, GOMP_free): Declare.
+ * allocator.c (omp_aligned_alloc): New for now static function,
+ add alignment argument and handle it.
+ (omp_alloc): Reimplement using omp_aligned_alloc.
+ (GOMP_alloc, GOMP_free): New functions.
+ (omp_free): Add ialias.
+ * testsuite/libgomp.c-c++-common/allocate-1.c: New test.
+ * testsuite/libgomp.c++/allocate-1.C: New test.
+
+2020-11-12 Thomas Schwinge <thomas@codesourcery.com>
+
+ PR fortran/97782
+ * testsuite/libgomp.oacc-fortran/attach-descriptor-1.f90: Adjust.
+
+2020-11-10 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * libgomp.h (enum gomp_map_vars_kind): Adjust enum values to be bit-flag
+ usable.
+ * oacc-mem.c (acc_map_data): Adjust gomp_map_vars argument flags to
+ 'GOMP_MAP_VARS_OPENACC | GOMP_MAP_VARS_ENTER_DATA'.
+ (goacc_enter_datum): Likewise for call to gomp_map_vars_async.
+ (goacc_enter_data_internal): Likewise.
+ * target.c (gomp_map_vars_internal):
+ Change checks of GOMP_MAP_VARS_ENTER_DATA to use bit-and (&). Adjust use
+ of gomp_attach_pointer for OpenMP cases.
+ (gomp_exit_data): Add handling of GOMP_MAP_DETACH.
+ (GOMP_target_enter_exit_data): Add handling of GOMP_MAP_ATTACH.
+ * testsuite/libgomp.c-c++-common/ptr-attach-1.c: New testcase.
+
2020-11-05 Ulrich Drepper <drepper@redhat.com>
Kwok Cheung Yeung <kcy@codesourcery.com>
diff --git a/libgomp/allocator.c b/libgomp/allocator.c
index 7166538..2790733 100644
--- a/libgomp/allocator.c
+++ b/libgomp/allocator.c
@@ -205,11 +205,12 @@ omp_destroy_allocator (omp_allocator_handle_t allocator)
ialias (omp_init_allocator)
ialias (omp_destroy_allocator)
-void *
-omp_alloc (size_t size, omp_allocator_handle_t allocator)
+static void *
+omp_aligned_alloc (size_t alignment, size_t size,
+ omp_allocator_handle_t allocator)
{
struct omp_allocator_data *allocator_data;
- size_t alignment, new_size;
+ size_t new_size;
void *ptr, *ret;
if (__builtin_expect (size == 0, 0))
@@ -227,12 +228,14 @@ retry:
if (allocator > omp_max_predefined_alloc)
{
allocator_data = (struct omp_allocator_data *) allocator;
- alignment = allocator_data->alignment;
+ if (alignment < allocator_data->alignment)
+ alignment = allocator_data->alignment;
}
else
{
allocator_data = NULL;
- alignment = sizeof (void *);
+ if (alignment < sizeof (void *))
+ alignment = sizeof (void *);
}
new_size = sizeof (struct omp_mem_header);
@@ -339,6 +342,27 @@ fail:
return NULL;
}
+void *
+omp_alloc (size_t size, omp_allocator_handle_t allocator)
+{
+ return omp_aligned_alloc (1, size, allocator);
+}
+
+/* Like omp_aligned_alloc, but apply on top of that:
+ "For allocations that arise from this ... the null_fb value of the
+ fallback allocator trait behaves as if the abort_fb had been specified." */
+
+void *
+GOMP_alloc (size_t alignment, size_t size, uintptr_t allocator)
+{
+ void *ret = omp_aligned_alloc (alignment, size,
+ (omp_allocator_handle_t) allocator);
+ if (__builtin_expect (ret == NULL, 0) && size)
+ gomp_fatal ("Out of memory allocating %lu bytes",
+ (unsigned long) size);
+ return ret;
+}
+
void
omp_free (void *ptr, omp_allocator_handle_t allocator)
{
@@ -366,3 +390,11 @@ omp_free (void *ptr, omp_allocator_handle_t allocator)
}
free (data->ptr);
}
+
+ialias (omp_free)
+
+void
+GOMP_free (void *ptr, uintptr_t allocator)
+{
+ return omp_free (ptr, (omp_allocator_handle_t) allocator);
+}
diff --git a/libgomp/configure b/libgomp/configure
index e48371d..5bff6e5 100755
--- a/libgomp/configure
+++ b/libgomp/configure
@@ -9713,7 +9713,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -9725,7 +9725,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -13571,7 +13571,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds_FC='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds_FC='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds_FC='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -13583,7 +13583,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds_FC='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds_FC='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds_FC='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
diff --git a/libgomp/env.c b/libgomp/env.c
index ab22525..5a49ae6 100644
--- a/libgomp/env.c
+++ b/libgomp/env.c
@@ -68,12 +68,11 @@ struct gomp_task_icv gomp_global_icv = {
.run_sched_chunk_size = 1,
.default_device_var = 0,
.dyn_var = false,
- .nest_var = false,
+ .max_active_levels_var = 1,
.bind_var = omp_proc_bind_false,
.target_data = NULL
};
-unsigned long gomp_max_active_levels_var = gomp_supported_active_levels;
bool gomp_cancel_var = false;
enum gomp_target_offload_t gomp_target_offload_var
= GOMP_TARGET_OFFLOAD_DEFAULT;
@@ -959,16 +958,17 @@ parse_spincount (const char *name, unsigned long long *pvalue)
}
/* Parse a boolean value for environment variable NAME and store the
- result in VALUE. */
+ result in VALUE. Return true if one was present and it was
+ successfully parsed. */
-static void
+static bool
parse_boolean (const char *name, bool *value)
{
const char *env;
env = getenv (name);
if (env == NULL)
- return;
+ return false;
while (isspace ((unsigned char) *env))
++env;
@@ -987,7 +987,11 @@ parse_boolean (const char *name, bool *value)
while (isspace ((unsigned char) *env))
++env;
if (*env != '\0')
- gomp_error ("Invalid value for environment variable %s", name);
+ {
+ gomp_error ("Invalid value for environment variable %s", name);
+ return false;
+ }
+ return true;
}
/* Parse the OMP_WAIT_POLICY environment variable and return the value. */
@@ -1252,7 +1256,7 @@ handle_omp_display_env (unsigned long stacksize, int wait_policy)
fprintf (stderr, " OMP_DYNAMIC = '%s'\n",
gomp_global_icv.dyn_var ? "TRUE" : "FALSE");
fprintf (stderr, " OMP_NESTED = '%s'\n",
- gomp_global_icv.nest_var ? "TRUE" : "FALSE");
+ gomp_global_icv.max_active_levels_var > 1 ? "TRUE" : "FALSE");
fprintf (stderr, " OMP_NUM_THREADS = '%lu", gomp_global_icv.nthreads_var);
for (i = 1; i < gomp_nthreads_var_list_len; i++)
@@ -1344,8 +1348,8 @@ handle_omp_display_env (unsigned long stacksize, int wait_policy)
wait_policy > 0 ? "ACTIVE" : "PASSIVE");
fprintf (stderr, " OMP_THREAD_LIMIT = '%u'\n",
gomp_global_icv.thread_limit_var);
- fprintf (stderr, " OMP_MAX_ACTIVE_LEVELS = '%lu'\n",
- gomp_max_active_levels_var);
+ fprintf (stderr, " OMP_MAX_ACTIVE_LEVELS = '%u'\n",
+ gomp_global_icv.max_active_levels_var);
fprintf (stderr, " OMP_CANCELLATION = '%s'\n",
gomp_cancel_var ? "TRUE" : "FALSE");
@@ -1410,6 +1414,7 @@ static void __attribute__((constructor))
initialize_env (void)
{
unsigned long thread_limit_var, stacksize = GOMP_DEFAULT_STACKSIZE;
+ unsigned long max_active_levels_var;
int wait_policy;
/* Do a compile time check that mkomp_h.pl did good job. */
@@ -1417,16 +1422,11 @@ initialize_env (void)
parse_schedule ();
parse_boolean ("OMP_DYNAMIC", &gomp_global_icv.dyn_var);
- parse_boolean ("OMP_NESTED", &gomp_global_icv.nest_var);
parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var);
parse_boolean ("OMP_DISPLAY_AFFINITY", &gomp_display_affinity_var);
parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv.default_device_var, true);
parse_target_offload ("OMP_TARGET_OFFLOAD", &gomp_target_offload_var);
parse_int ("OMP_MAX_TASK_PRIORITY", &gomp_max_task_priority_var, true);
- parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var,
- true);
- if (gomp_max_active_levels_var > gomp_supported_active_levels)
- gomp_max_active_levels_var = gomp_supported_active_levels;
gomp_def_allocator = parse_allocator ();
if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var, false))
{
@@ -1451,6 +1451,22 @@ initialize_env (void)
&gomp_bind_var_list_len)
&& gomp_global_icv.bind_var == omp_proc_bind_false)
ignore = true;
+ if (parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS",
+ &max_active_levels_var, true))
+ gomp_global_icv.max_active_levels_var
+ = (max_active_levels_var > gomp_supported_active_levels)
+ ? gomp_supported_active_levels : max_active_levels_var;
+ else
+ {
+ bool nested = true;
+
+ /* OMP_NESTED is deprecated in OpenMP 5.0. */
+ if (parse_boolean ("OMP_NESTED", &nested))
+ gomp_global_icv.max_active_levels_var
+ = nested ? gomp_supported_active_levels : 1;
+ else if (gomp_nthreads_var_list_len > 1 || gomp_bind_var_list_len > 1)
+ gomp_global_icv.max_active_levels_var = gomp_supported_active_levels;
+ }
/* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
parsed if present in the environment. If OMP_PROC_BIND was set
explicitly to false, don't populate places list though. If places
diff --git a/libgomp/icv.c b/libgomp/icv.c
index 8df15e3..c0c0305 100644
--- a/libgomp/icv.c
+++ b/libgomp/icv.c
@@ -57,14 +57,18 @@ void
omp_set_nested (int val)
{
struct gomp_task_icv *icv = gomp_icv (true);
- icv->nest_var = val;
+ if (val)
+ icv->max_active_levels_var = gomp_supported_active_levels;
+ else if (icv->max_active_levels_var > 1)
+ icv->max_active_levels_var = 1;
}
int
omp_get_nested (void)
{
struct gomp_task_icv *icv = gomp_icv (false);
- return icv->nest_var;
+ return (icv->max_active_levels_var > 1
+ && icv->max_active_levels_var > omp_get_active_level ());
}
#pragma GCC diagnostic pop
@@ -120,17 +124,20 @@ omp_set_max_active_levels (int max_levels)
{
if (max_levels >= 0)
{
+ struct gomp_task_icv *icv = gomp_icv (true);
+
if (max_levels <= gomp_supported_active_levels)
- gomp_max_active_levels_var = max_levels;
+ icv->max_active_levels_var = max_levels;
else
- gomp_max_active_levels_var = gomp_supported_active_levels;
+ icv->max_active_levels_var = gomp_supported_active_levels;
}
}
int
omp_get_max_active_levels (void)
{
- return gomp_max_active_levels_var;
+ struct gomp_task_icv *icv = gomp_icv (false);
+ return icv->max_active_levels_var;
}
int
diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h
index 0cc3f4d..070d29c 100644
--- a/libgomp/libgomp.h
+++ b/libgomp/libgomp.h
@@ -428,7 +428,7 @@ struct gomp_task_icv
int default_device_var;
unsigned int thread_limit_var;
bool dyn_var;
- bool nest_var;
+ unsigned char max_active_levels_var;
char bind_var;
/* Internal ICV. */
struct target_mem_desc *target_data;
@@ -441,13 +441,12 @@ enum gomp_target_offload_t
GOMP_TARGET_OFFLOAD_DISABLED
};
-#define gomp_supported_active_levels INT_MAX
+#define gomp_supported_active_levels UCHAR_MAX
extern struct gomp_task_icv gomp_global_icv;
#ifndef HAVE_SYNC_BUILTINS
extern gomp_mutex_t gomp_managed_threads_lock;
#endif
-extern unsigned long gomp_max_active_levels_var;
extern bool gomp_cancel_var;
extern enum gomp_target_offload_t gomp_target_offload_var;
extern int gomp_max_task_priority_var;
diff --git a/libgomp/libgomp.map b/libgomp/libgomp.map
index c5f52f7..2c95f78 100644
--- a/libgomp/libgomp.map
+++ b/libgomp/libgomp.map
@@ -359,6 +359,12 @@ GOMP_5.0 {
GOMP_workshare_task_reduction_unregister;
} GOMP_4.5;
+GOMP_5.0.1 {
+ global:
+ GOMP_alloc;
+ GOMP_free;
+} GOMP_5.0;
+
OACC_2.0 {
global:
acc_get_num_devices;
diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index 6937063..473b191 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -487,10 +487,20 @@ This function returns @code{true} if nested parallel regions are
enabled, @code{false} otherwise. Here, @code{true} and @code{false}
represent their language-specific counterparts.
-Nested parallel regions may be initialized at startup by the
-@env{OMP_NESTED} environment variable or at runtime using
-@code{omp_set_nested}. If undefined, nested parallel regions are
-disabled by default.
+The state of nested parallel regions at startup depends on several
+environment variables. If @env{OMP_MAX_ACTIVE_LEVELS} is defined
+and is set to greater than one, then nested parallel regions will be
+enabled. If not defined, then the value of the @env{OMP_NESTED}
+environment variable will be followed if defined. If neither are
+defined, then if either @env{OMP_NUM_THREADS} or @env{OMP_PROC_BIND}
+are defined with a list of more than one value, then nested parallel
+regions are enabled. If none of these are defined, then nested parallel
+regions are disabled by default.
+
+Nested parallel regions can be enabled or disabled at runtime using
+@code{omp_set_nested}, or by setting the maximum number of nested
+regions with @code{omp_set_max_active_levels} to one to disable, or
+above one to enable.
@item @emph{C/C++}:
@multitable @columnfractions .20 .80
@@ -503,7 +513,8 @@ disabled by default.
@end multitable
@item @emph{See also}:
-@ref{omp_set_nested}, @ref{OMP_NESTED}
+@ref{omp_set_max_active_levels}, @ref{omp_set_nested},
+@ref{OMP_MAX_ACTIVE_LEVELS}, @ref{OMP_NESTED}
@item @emph{Reference}:
@uref{https://www.openmp.org, OpenMP specification v4.5}, Section 3.2.11.
@@ -964,6 +975,10 @@ are allowed to create new teams. The function takes the language-specific
equivalent of @code{true} and @code{false}, where @code{true} enables
dynamic adjustment of team sizes and @code{false} disables it.
+Enabling nested parallel regions will also set the maximum number of
+active nested regions to the maximum supported. Disabling nested parallel
+regions will set the maximum number of active nested regions to one.
+
@item @emph{C/C++}:
@multitable @columnfractions .20 .80
@item @emph{Prototype}: @tab @code{void omp_set_nested(int nested);}
@@ -976,7 +991,8 @@ dynamic adjustment of team sizes and @code{false} disables it.
@end multitable
@item @emph{See also}:
-@ref{OMP_NESTED}, @ref{omp_get_nested}
+@ref{omp_get_nested}, @ref{omp_set_max_active_levels},
+@ref{OMP_MAX_ACTIVE_LEVELS}, @ref{OMP_NESTED}
@item @emph{Reference}:
@uref{https://www.openmp.org, OpenMP specification v4.5}, Section 3.2.10.
@@ -1502,10 +1518,14 @@ disabled by default.
@item @emph{Description}:
Specifies the initial value for the maximum number of nested parallel
regions. The value of this variable shall be a positive integer.
-If undefined, the number of active levels is unlimited.
+If undefined, then if @env{OMP_NESTED} is defined and set to true, or
+if @env{OMP_NUM_THREADS} or @env{OMP_PROC_BIND} are defined and set to
+a list with more than one item, the maximum number of nested parallel
+regions will be initialized to the largest number supported, otherwise
+it will be set to one.
@item @emph{See also}:
-@ref{omp_set_max_active_levels}
+@ref{omp_set_max_active_levels}, @ref{OMP_NESTED}
@item @emph{Reference}:
@uref{https://www.openmp.org, OpenMP specification v4.5}, Section 4.9
@@ -1541,11 +1561,16 @@ integer, and zero is allowed. If undefined, the default priority is
@item @emph{Description}:
Enable or disable nested parallel regions, i.e., whether team members
are allowed to create new teams. The value of this environment variable
-shall be @code{TRUE} or @code{FALSE}. If undefined, nested parallel
-regions are disabled by default.
+shall be @code{TRUE} or @code{FALSE}. If set to @code{TRUE}, the number
+of maximum active nested regions supported will by default be set to the
+maximum supported, otherwise it will be set to one. If
+@env{OMP_MAX_ACTIVE_LEVELS} is defined, its setting will override this
+setting. If both are undefined, nested parallel regions are enabled if
+@env{OMP_NUM_THREADS} or @env{OMP_PROC_BINDS} are defined to a list with
+more than one item, otherwise they are disabled by default.
@item @emph{See also}:
-@ref{omp_set_nested}
+@ref{omp_set_max_active_levels}, @ref{omp_set_nested}
@item @emph{Reference}:
@uref{https://www.openmp.org, OpenMP specification v4.5}, Section 4.6
@@ -1561,11 +1586,12 @@ regions are disabled by default.
@item @emph{Description}:
Specifies the default number of threads to use in parallel regions. The
value of this variable shall be a comma-separated list of positive integers;
-the value specified the number of threads to use for the corresponding nested
-level. If undefined one thread per CPU is used.
+the value specifies the number of threads to use for the corresponding nested
+level. Specifying more than one item in the list will automatically enable
+nesting by default. If undefined one thread per CPU is used.
@item @emph{See also}:
-@ref{omp_set_num_threads}
+@ref{omp_set_num_threads}, @ref{OMP_NESTED}
@item @emph{Reference}:
@uref{https://www.openmp.org, OpenMP specification v4.5}, Section 4.2
@@ -1586,13 +1612,15 @@ the thread affinity policy for the corresponding nesting level. With
@code{MASTER} the worker threads are in the same place partition as the
master thread. With @code{CLOSE} those are kept close to the master thread
in contiguous place partitions. And with @code{SPREAD} a sparse distribution
-across the place partitions is used.
+across the place partitions is used. Specifying more than one item in the
+list will automatically enable nesting by default.
When undefined, @env{OMP_PROC_BIND} defaults to @code{TRUE} when
@env{OMP_PLACES} or @env{GOMP_CPU_AFFINITY} is set and @code{FALSE} otherwise.
@item @emph{See also}:
-@ref{OMP_PLACES}, @ref{GOMP_CPU_AFFINITY}, @ref{omp_get_proc_bind}
+@ref{omp_get_proc_bind}, @ref{GOMP_CPU_AFFINITY},
+@ref{OMP_NESTED}, @ref{OMP_PLACES}
@item @emph{Reference}:
@uref{https://www.openmp.org, OpenMP specification v4.5}, Section 4.4
diff --git a/libgomp/libgomp_g.h b/libgomp/libgomp_g.h
index 59e3697..b20e186 100644
--- a/libgomp/libgomp_g.h
+++ b/libgomp/libgomp_g.h
@@ -357,6 +357,11 @@ extern void GOMP_teams (unsigned int, unsigned int);
extern void GOMP_teams_reg (void (*) (void *), void *, unsigned, unsigned,
unsigned);
+/* allocator.c */
+
+extern void *GOMP_alloc (size_t, size_t, uintptr_t);
+extern void GOMP_free (void *, uintptr_t);
+
/* oacc-async.c */
extern void GOACC_wait (int, int, ...);
diff --git a/libgomp/omp.h.in b/libgomp/omp.h.in
index be7df6d..4424a16 100644
--- a/libgomp/omp.h.in
+++ b/libgomp/omp.h.in
@@ -281,7 +281,7 @@ extern void omp_set_default_allocator (omp_allocator_handle_t) __GOMP_NOTHROW;
extern omp_allocator_handle_t omp_get_default_allocator (void) __GOMP_NOTHROW;
extern void *omp_alloc (__SIZE_TYPE__,
omp_allocator_handle_t __GOMP_DEFAULT_NULL_ALLOCATOR)
- __GOMP_NOTHROW;
+ __GOMP_NOTHROW __attribute__((__malloc__, __alloc_size__ (1)));
extern void omp_free (void *,
omp_allocator_handle_t __GOMP_DEFAULT_NULL_ALLOCATOR)
__GOMP_NOTHROW;
diff --git a/libgomp/parallel.c b/libgomp/parallel.c
index 2fe4f573..ebce492 100644
--- a/libgomp/parallel.c
+++ b/libgomp/parallel.c
@@ -53,11 +53,11 @@ gomp_resolve_num_threads (unsigned specified, unsigned count)
/* Accelerators with fixed thread counts require this to return 1 for
nested parallel regions. */
#if !defined(__AMDGCN__) && !defined(__nvptx__)
- && !icv->nest_var
+ && icv->max_active_levels_var <= 1
#endif
)
return 1;
- else if (thr->ts.active_level >= gomp_max_active_levels_var)
+ else if (thr->ts.active_level >= icv->max_active_levels_var)
return 1;
/* If NUM_THREADS not specified, use nthreads_var. */
diff --git a/libgomp/plugin/plugin-gcn.c b/libgomp/plugin/plugin-gcn.c
index 0be350b..ebb6fbc 100644
--- a/libgomp/plugin/plugin-gcn.c
+++ b/libgomp/plugin/plugin-gcn.c
@@ -52,6 +52,7 @@
#define HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT 0xA002
/* These probably won't be in elf.h for a while. */
+#ifndef R_AMDGPU_NONE
#define R_AMDGPU_NONE 0
#define R_AMDGPU_ABS32_LO 1 /* (S + A) & 0xFFFFFFFF */
#define R_AMDGPU_ABS32_HI 2 /* (S + A) >> 32 */
@@ -64,8 +65,8 @@
#define R_AMDGPU_GOTPCREL32_HI 9 /* (G + GOT + A - P) >> 32 */
#define R_AMDGPU_REL32_LO 10 /* (S + A - P) & 0xFFFFFFFF */
#define R_AMDGPU_REL32_HI 11 /* (S + A - P) >> 32 */
-#define reserved 12
#define R_AMDGPU_RELATIVE64 13 /* B + A */
+#endif
/* GCN specific definitions for asynchronous queues. */
diff --git a/libgomp/testsuite/libgomp.c++/allocate-1.C b/libgomp/testsuite/libgomp.c++/allocate-1.C
new file mode 100644
index 0000000..0876719
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/allocate-1.C
@@ -0,0 +1,207 @@
+#include <omp.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+struct S { int a, b; };
+
+void
+foo (int &x, int &y, int &r, int &l, int (&l2)[4], int &l3, int &n, int *&p,
+ int *&q, int &px, struct S &s, omp_allocator_handle_t h, int fl)
+{
+ int i;
+ typedef int T[x];
+ T v, w;
+ T &v2 = v;
+ T &w2 = w;
+ int r1[4] = { 0, 0, 0, 0 };
+ int (&r2)[4] = r1;
+ int xo = x;
+ for (i = 0; i < x; i++)
+ w[i] = i;
+ for (i = 0; i < 4; i++)
+ p[i] = 0;
+ for (i = 0; i < 3; i++)
+ q[i] = 0;
+ #pragma omp parallel private (y, v2) firstprivate (x) allocate (x, y, v2)
+ {
+ int *volatile p1 = &x;
+ int *volatile p2 = &y;
+ if (x != 42)
+ abort ();
+ #pragma omp barrier
+ *p2 = 1;
+ p1[0]++;
+ v2[0] = 7;
+ v2[41] = 8;
+ #pragma omp barrier
+ if (x != 43 || y != 1)
+ abort ();
+ if (v2[0] != 7 || v2[41] != 8)
+ abort ();
+ if ((fl & 2) && (((uintptr_t) p1 | (uintptr_t) p2
+ | (uintptr_t) &v2[0]) & 63) != 0)
+ abort ();
+ }
+ x = xo;
+ #pragma omp teams
+ #pragma omp parallel private (y) firstprivate (x, w2) allocate (h: x, y, w2)
+ {
+ int *volatile p1 = &x;
+ int *volatile p2 = &y;
+ if (x != 42 || w2[17] != 17 || w2[41] != 41)
+ abort ();
+ #pragma omp barrier
+ *p2 = 1;
+ p1[0]++;
+ w2[19]++;
+ #pragma omp barrier
+ if (x != 43 || y != 1 || w2[19] != 20)
+ abort ();
+ if ((fl & 1) && (((uintptr_t) p1 | (uintptr_t) p2
+ | (uintptr_t) &w2[0]) & 63) != 0)
+ abort ();
+ }
+ x = xo;
+ #pragma omp parallel for private (y) firstprivate (x) allocate (h: x, y, r, l, n) reduction(+: r) lastprivate (l) linear (n: 16)
+ for (i = 0; i < 64; i++)
+ {
+ if (x != 42)
+ abort ();
+ y = 1;
+ l = i;
+ n += y + 15;
+ r += i;
+ if ((fl & 1) && (((uintptr_t) &x | (uintptr_t) &y | (uintptr_t) &r
+ | (uintptr_t) &l | (uintptr_t) &n) & 63) != 0)
+ abort ();
+ }
+ x = xo;
+ #pragma omp parallel
+ {
+ #pragma omp for lastprivate (l2) allocate (h: l2, l3) lastprivate (conditional: l3)
+ for (i = 0; i < 64; i++)
+ {
+ l2[0] = i;
+ l2[1] = i + 1;
+ l2[2] = i + 2;
+ l2[3] = i + 3;
+ if (i < 37)
+ l3 = i;
+ if ((fl & 1) && (((uintptr_t) &l2[0] | (uintptr_t) &l3) & 63) != 0)
+ abort ();
+ }
+ #pragma omp for reduction(+:p[2:px], q[:3], r2) allocate(h: p, q, r2)
+ for (i = 0; i < 32; i++)
+ {
+ p[2] += i;
+ p[3] += 2 * i;
+ q[0] += 3 * i;
+ q[2] += 4 * i;
+ r2[0] += 5 * i;
+ r2[3] += 6 * i;
+ /* Can't really rely on alignment of &p[0], the implementation could
+ allocate the whole array or do what GCC does and allocate only part
+ of it. */
+ if ((fl & 1) && (((uintptr_t) &q[0] | (uintptr_t) &r2[0]) & 63) != 0)
+ abort ();
+ }
+ #pragma omp task private(y) firstprivate(x) allocate(x, y)
+ {
+ int *volatile p1 = &x;
+ int *volatile p2 = &y;
+ if (x != 42)
+ abort ();
+ p1[0]++;
+ p2[0] = 21;
+ if (x != 43 || y != 21)
+ abort ();
+ if ((fl & 2) && (((uintptr_t) p1 | (uintptr_t) p2) & 63) != 0)
+ abort ();
+ }
+ #pragma omp task private(y) firstprivate(x) allocate(h: x, y)
+ {
+ int *volatile p1 = &x;
+ int *volatile p2 = &y;
+ if (x != 42)
+ abort ();
+ p1[0]++;
+ p2[0] = 21;
+ if (x != 43 || y != 21)
+ abort ();
+ if ((fl & 1) && (((uintptr_t) p1 | (uintptr_t) p2) & 63) != 0)
+ abort ();
+ }
+ #pragma omp task private(y) firstprivate(s) allocate(s, y)
+ {
+ int *volatile p1 = &s.a;
+ int *volatile p2 = &s.b;
+ int *volatile p3 = &y;
+ if (s.a != 27 || s.b != 29)
+ abort ();
+ p1[0]++;
+ p2[0]++;
+ p3[0] = 21;
+ if (s.a != 28 || s.b != 30 || y != 21)
+ abort ();
+ if ((fl & 2) && (((uintptr_t) p1 | (uintptr_t) p3) & 63) != 0)
+ abort ();
+ }
+ #pragma omp task private(y) firstprivate(s) allocate(h: s, y)
+ {
+ int *volatile p1 = &s.a;
+ int *volatile p2 = &s.b;
+ int *volatile p3 = &y;
+ if (s.a != 27 || s.b != 29)
+ abort ();
+ p1[0]++;
+ p2[0]++;
+ p3[0] = 21;
+ if (s.a != 28 || s.b != 30 || y != 21)
+ abort ();
+ if ((fl & 1) && (((uintptr_t) p1 | (uintptr_t) p3) & 63) != 0)
+ abort ();
+ }
+ }
+ if (r != 64 * 63 / 2 || l != 63 || n != 8 + 16 * 64)
+ abort ();
+ if (l2[0] != 63 || l2[1] != 63 + 1 || l2[2] != 63 + 2 || l2[3] != 63 + 3 || l3 != 36)
+ abort ();
+ if (p[2] != (32 * 31) / 2 || p[3] != 2 * (32 * 31) / 2
+ || q[0] != 3 * (32 * 31) / 2 || q[2] != 4 * (32 * 31) / 2
+ || r2[0] != 5 * (32 * 31) / 2 || r2[3] != 6 * (32 * 31) / 2)
+ abort ();
+}
+
+int
+main ()
+{
+ omp_alloctrait_t traits[3]
+ = { { omp_atk_alignment, 64 },
+ { omp_atk_fallback, omp_atv_null_fb } };
+ omp_allocator_handle_t a
+ = omp_init_allocator (omp_default_mem_space, 2, traits);
+ if (a == omp_null_allocator)
+ abort ();
+ omp_set_default_allocator (omp_default_mem_alloc);
+ struct S s = { 27, 29 };
+ int p1[4], q1[3], px = 2;
+ int *p = p1;
+ int *q = q1;
+ int x = 42, y = 0, r = 0, l, l2[4], l3, n = 8;
+ foo (x, y, r, l, l2, l3, n, p, q, px, s, omp_null_allocator, 0);
+ x = 42; y = 0; r = 0; l = -1; l2[0] = -1; l2[1] = -1;
+ l2[2] = -1; l2[3] = -1; n = 8;
+ foo (x, y, r, l, l2, l3, n, p, q, px, s, omp_default_mem_alloc, 0);
+ x = 42; y = 0; r = 0; l = -1; l2[0] = -1; l2[1] = -1;
+ l2[2] = -1; l2[3] = -1; n = 8;
+ foo (x, y, r, l, l2, l3, n, p, q, px, s, a, 1);
+ x = 42; y = 0; r = 0; l = -1; l2[0] = -1; l2[1] = -1;
+ l2[2] = -1; l2[3] = -1; n = 8;
+ omp_set_default_allocator (a);
+ foo (x, y, r, l, l2, l3, n, p, q, px, s, omp_null_allocator, 3);
+ x = 42; y = 0; r = 0; l = -1; l2[0] = -1; l2[1] = -1;
+ l2[2] = -1; l2[3] = -1; n = 8;
+ foo (x, y, r, l, l2, l3, n, p, q, px, s, omp_default_mem_alloc, 2);
+ omp_destroy_allocator (a);
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/allocate-1.c b/libgomp/testsuite/libgomp.c-c++-common/allocate-1.c
new file mode 100644
index 0000000..4398ff9
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/allocate-1.c
@@ -0,0 +1,375 @@
+#include <omp.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+struct S { int a, b; };
+
+void
+foo (int x, int *p, int *q, int px, omp_allocator_handle_t h, int fl)
+{
+ int y = 0, r = 0, i, i1, l, l2[4], l3, n = 8;
+ int i2, j2, n2 = 9, l4;
+ int i3, j3, n3 = 10, l5;
+ int i4, j4, n4 = 11, l6;
+ int i5;
+ int v[x], w[x];
+ int r2[4] = { 0, 0, 0, 0 };
+ int xo = x;
+ struct S s = { 27, 29 };
+ for (i = 0; i < 4; i++)
+ p[i] = 0;
+ for (i = 0; i < 3; i++)
+ q[i] = 0;
+ for (i = 0; i < x; i++)
+ w[i] = i;
+ #pragma omp parallel private (y, v) firstprivate (x) allocate (x, y, v)
+ {
+ int *volatile p1 = &x;
+ int *volatile p2 = &y;
+ if (x != 42)
+ abort ();
+ #pragma omp barrier
+ *p2 = 1;
+ p1[0]++;
+ v[0] = 7;
+ v[41] = 8;
+ #pragma omp barrier
+ if (x != 43 || y != 1)
+ abort ();
+ if (v[0] != 7 || v[41] != 8)
+ abort ();
+ if ((fl & 2) && (((uintptr_t) p1 | (uintptr_t) p2
+ | (uintptr_t) &v[0]) & 63) != 0)
+ abort ();
+ }
+ x = xo;
+ #pragma omp teams
+ #pragma omp parallel private (y) firstprivate (x, w) allocate (h: x, y, w)
+ {
+ int *volatile p1 = &x;
+ int *volatile p2 = &y;
+ if (x != 42 || w[17] != 17 || w[41] != 41)
+ abort ();
+ #pragma omp barrier
+ *p2 = 1;
+ p1[0]++;
+ w[19]++;
+ #pragma omp barrier
+ if (x != 43 || y != 1 || w[19] != 20)
+ abort ();
+ if ((fl & 1) && (((uintptr_t) p1 | (uintptr_t) p2
+ | (uintptr_t) &w[0]) & 63) != 0)
+ abort ();
+ }
+ x = xo;
+ #pragma omp parallel for private (y) firstprivate (x) allocate (h: x, y, r, l, n) reduction(+: r) lastprivate (l) linear (n: 16)
+ for (i = 0; i < 64; i++)
+ {
+ if (x != 42)
+ abort ();
+ y = 1;
+ l = i;
+ n += y + 15;
+ r += i;
+ if ((fl & 1) && (((uintptr_t) &x | (uintptr_t) &y | (uintptr_t) &r
+ | (uintptr_t) &l | (uintptr_t) &n) & 63) != 0)
+ abort ();
+ }
+ x = xo;
+ #pragma omp parallel
+ {
+ #pragma omp for lastprivate (l2) private (i1) allocate (h: l2, l3, i1) lastprivate (conditional: l3)
+ for (i1 = 0; i1 < 64; i1++)
+ {
+ l2[0] = i1;
+ l2[1] = i1 + 1;
+ l2[2] = i1 + 2;
+ l2[3] = i1 + 3;
+ if (i1 < 37)
+ l3 = i1;
+ if ((fl & 1) && (((uintptr_t) &l2[0] | (uintptr_t) &l3 | (uintptr_t) &i1) & 63) != 0)
+ abort ();
+ }
+ #pragma omp for collapse(2) lastprivate(l4, i2, j2) linear (n2:17) allocate (h: n2, l4, i2, j2)
+ for (i2 = 3; i2 < 5; i2++)
+ for (j2 = 17; j2 < 22; j2 += 2)
+ {
+ n2 += 17;
+ l4 = i2 * 31 + j2;
+ if ((fl & 1) && (((uintptr_t) &l4 | (uintptr_t) &n2
+ | (uintptr_t) &i2 | (uintptr_t) &j2) & 63) != 0)
+ abort ();
+ }
+ #pragma omp for collapse(2) lastprivate(l5, i3, j3) linear (n3:17) schedule (static, 3) allocate (n3, l5, i3, j3)
+ for (i3 = 3; i3 < 5; i3++)
+ for (j3 = 17; j3 < 23; j3 += 2)
+ {
+ n3 += 17;
+ l5 = i3 * 31 + j3;
+ if ((fl & 2) && (((uintptr_t) &l5 | (uintptr_t) &n3
+ | (uintptr_t) &i3 | (uintptr_t) &j3) & 63) != 0)
+ abort ();
+ }
+ #pragma omp for collapse(2) lastprivate(l6, i4, j4) linear (n4:17) schedule (dynamic) allocate (h: n4, l6, i4, j4)
+ for (i4 = 3; i4 < 5; i4++)
+ for (j4 = 17; j4 < 22; j4 += 2)
+ {
+ n4 += 17;
+ l6 = i4 * 31 + j4;
+ if ((fl & 1) && (((uintptr_t) &l6 | (uintptr_t) &n4
+ | (uintptr_t) &i4 | (uintptr_t) &j4) & 63) != 0)
+ abort ();
+ }
+ #pragma omp for lastprivate (i5) allocate (i5)
+ for (i5 = 1; i5 < 17; i5 += 3)
+ {
+ if ((fl & 2) && (((uintptr_t) &i5) & 63) != 0)
+ abort ();
+ }
+ #pragma omp for reduction(+:p[2:px], q[:3], r2) allocate(h: p, q, r2)
+ for (i = 0; i < 32; i++)
+ {
+ p[2] += i;
+ p[3] += 2 * i;
+ q[0] += 3 * i;
+ q[2] += 4 * i;
+ r2[0] += 5 * i;
+ r2[3] += 6 * i;
+ /* Can't really rely on alignment of &p[0], the implementation could
+ allocate the whole array or do what GCC does and allocate only part
+ of it. */
+ if ((fl & 1) && (((uintptr_t) &q[0] | (uintptr_t) &r2[0]) & 63) != 0)
+ abort ();
+ }
+ #pragma omp task private(y) firstprivate(x) allocate(x, y)
+ {
+ int *volatile p1 = &x;
+ int *volatile p2 = &y;
+ if (x != 42)
+ abort ();
+ p1[0]++;
+ p2[0] = 21;
+ if (x != 43 || y != 21)
+ abort ();
+ if ((fl & 2) && (((uintptr_t) p1 | (uintptr_t) p2) & 63) != 0)
+ abort ();
+ }
+ #pragma omp task private(y) firstprivate(x) allocate(h: x, y)
+ {
+ int *volatile p1 = &x;
+ int *volatile p2 = &y;
+ if (x != 42)
+ abort ();
+ p1[0]++;
+ p2[0] = 21;
+ if (x != 43 || y != 21)
+ abort ();
+ if ((fl & 1) && (((uintptr_t) p1 | (uintptr_t) p2) & 63) != 0)
+ abort ();
+ }
+ #pragma omp task private(y) firstprivate(s) allocate(s, y)
+ {
+ int *volatile p1 = &s.a;
+ int *volatile p2 = &s.b;
+ int *volatile p3 = &y;
+ if (s.a != 27 || s.b != 29)
+ abort ();
+ p1[0]++;
+ p2[0]++;
+ p3[0] = 21;
+ if (s.a != 28 || s.b != 30 || y != 21)
+ abort ();
+ if ((fl & 2) && (((uintptr_t) p1 | (uintptr_t) p3) & 63) != 0)
+ abort ();
+ }
+ #pragma omp task private(y) firstprivate(s) allocate(h: s, y)
+ {
+ int *volatile p1 = &s.a;
+ int *volatile p2 = &s.b;
+ int *volatile p3 = &y;
+ if (s.a != 27 || s.b != 29)
+ abort ();
+ p1[0]++;
+ p2[0]++;
+ p3[0] = 21;
+ if (s.a != 28 || s.b != 30 || y != 21)
+ abort ();
+ if ((fl & 1) && (((uintptr_t) p1 | (uintptr_t) p3) & 63) != 0)
+ abort ();
+ }
+ }
+ if (r != 64 * 63 / 2 || l != 63 || n != 8 + 16 * 64)
+ abort ();
+ if (l2[0] != 63 || l2[1] != 63 + 1 || l2[2] != 63 + 2 || l2[3] != 63 + 3 || l3 != 36)
+ abort ();
+ if (i2 != 5 || j2 != 23 || n2 != 9 + 6 * 17 || l4 != 4 * 31 + 21)
+ abort ();
+ if (i3 != 5 || j3 != 23 || n3 != 10 + 6 * 17 || l5 != 4 * 31 + 21)
+ abort ();
+ if (i4 != 5 || j4 != 23 || n4 != 11 + 6 * 17 || l6 != 4 * 31 + 21)
+ abort ();
+ if (i5 != 19)
+ abort ();
+ if (p[2] != (32 * 31) / 2 || p[3] != 2 * (32 * 31) / 2
+ || q[0] != 3 * (32 * 31) / 2 || q[2] != 4 * (32 * 31) / 2
+ || r2[0] != 5 * (32 * 31) / 2 || r2[3] != 6 * (32 * 31) / 2)
+ abort ();
+}
+
+void
+bar (int x, omp_allocator_handle_t h)
+{
+ int y = 0, r = 0, i, i1, l, l2[4], l3, n = 8;
+ int i2, j2, n2 = 9, l4;
+ int i3, j3, n3 = 10, l5;
+ int i4, j4, n4 = 11, l6;
+ int i5;
+ struct S s = { 27, 29 };
+ int xo = x;
+ #pragma omp parallel private (y) firstprivate (x) allocate (x, y)
+ {
+ if (x != 42)
+ abort ();
+ #pragma omp barrier
+ y = 1;
+ x++;
+ #pragma omp barrier
+ if (x != 43 || y != 1)
+ abort ();
+ }
+ x = xo;
+ #pragma omp teams
+ #pragma omp parallel private (y) firstprivate (x) allocate (h: x, y)
+ {
+ if (x != 42)
+ abort ();
+ #pragma omp barrier
+ y = 1;
+ x++;
+ #pragma omp barrier
+ if (x != 43 || y != 1)
+ abort ();
+ }
+ x = xo;
+ #pragma omp parallel for private (y) firstprivate (x) allocate (h: x, y, r, l, n) reduction(+: r) lastprivate (l) linear (n: 16)
+ for (i = 0; i < 64; i++)
+ {
+ if (x != 42)
+ abort ();
+ y = 1;
+ l = i;
+ n += y + 15;
+ r += i;
+ }
+ x = xo;
+ #pragma omp parallel
+ {
+ #pragma omp for lastprivate (l2) private (i1) allocate (h: l2, l3, i1) lastprivate (conditional: l3)
+ for (i1 = 0; i1 < 64; i1++)
+ {
+ l2[0] = i1;
+ l2[1] = i1 + 1;
+ l2[2] = i1 + 2;
+ l2[3] = i1 + 3;
+ if (i1 < 37)
+ l3 = i1;
+ }
+ #pragma omp for collapse(2) lastprivate(l4, i2, j2) linear (n2:17) allocate (h: n2, l4, i2, j2)
+ for (i2 = 3; i2 < 5; i2++)
+ for (j2 = 17; j2 < 22; j2 += 2)
+ {
+ n2 += 17;
+ l4 = i2 * 31 + j2;
+ }
+ #pragma omp for collapse(2) lastprivate(l5, i3, j3) linear (n3:17) schedule (static, 3) allocate (n3, l5, i3, j3)
+ for (i3 = 3; i3 < 5; i3++)
+ for (j3 = 17; j3 < 23; j3 += 2)
+ {
+ n3 += 17;
+ l5 = i3 * 31 + j3;
+ }
+ #pragma omp for collapse(2) lastprivate(l6, i4, j4) linear (n4:17) schedule (dynamic) allocate (h: n4, l6, i4, j4)
+ for (i4 = 3; i4 < 5; i4++)
+ for (j4 = 17; j4 < 22; j4 += 2)
+ {
+ n4 += 17;
+ l6 = i4 * 31 + j4;
+ }
+ #pragma omp for lastprivate (i5) allocate (i5)
+ for (i5 = 1; i5 < 17; i5 += 3)
+ ;
+ #pragma omp task private(y) firstprivate(x) allocate(x, y)
+ {
+ if (x != 42)
+ abort ();
+ x++;
+ y = 21;
+ if (x != 43 || y != 21)
+ abort ();
+ }
+ #pragma omp task private(y) firstprivate(x) allocate(h: x, y)
+ {
+ if (x != 42)
+ abort ();
+ x++;
+ y = 21;
+ if (x != 43 || y != 21)
+ abort ();
+ }
+ #pragma omp task private(y) firstprivate(s) allocate(s, y)
+ {
+ if (s.a != 27 || s.b != 29)
+ abort ();
+ s.a++;
+ s.b++;
+ y = 21;
+ if (s.a != 28 || s.b != 30 || y != 21)
+ abort ();
+ }
+ #pragma omp task private(y) firstprivate(s) allocate(h: s, y)
+ {
+ if (s.a != 27 || s.b != 29)
+ abort ();
+ s.a++;
+ s.b++;
+ y = 21;
+ if (s.a != 28 || s.b != 30 || y != 21)
+ abort ();
+ }
+ }
+ if (r != 64 * 63 / 2 || l != 63 || n != 8 + 16 * 64)
+ abort ();
+ if (l2[0] != 63 || l2[1] != 63 + 1 || l2[2] != 63 + 2 || l2[3] != 63 + 3 || l3 != 36)
+ abort ();
+ if (i2 != 5 || j2 != 23 || n2 != 9 + 6 * 17 || l4 != 4 * 31 + 21)
+ abort ();
+ if (i3 != 5 || j3 != 23 || n3 != 10 + 6 * 17 || l5 != 4 * 31 + 21)
+ abort ();
+ if (i4 != 5 || j4 != 23 || n4 != 11 + 6 * 17 || l6 != 4 * 31 + 21)
+ abort ();
+ if (i5 != 19)
+ abort ();
+}
+
+int
+main ()
+{
+ omp_alloctrait_t traits[3]
+ = { { omp_atk_alignment, 64 },
+ { omp_atk_fallback, omp_atv_null_fb } };
+ omp_allocator_handle_t a
+ = omp_init_allocator (omp_default_mem_space, 2, traits);
+ int p[4], q[3];
+ if (a == omp_null_allocator)
+ abort ();
+ omp_set_default_allocator (omp_default_mem_alloc);
+ foo (42, p, q, 2, omp_null_allocator, 0);
+ foo (42, p, q, 2, omp_default_mem_alloc, 0);
+ foo (42, p, q, 2, a, 1);
+ omp_set_default_allocator (a);
+ foo (42, p, q, 2, omp_null_allocator, 3);
+ foo (42, p, q, 2, omp_default_mem_alloc, 2);
+ bar (42, a);
+ omp_destroy_allocator (a);
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/usleep.h b/libgomp/testsuite/libgomp.c/usleep.h
index c01aaa0..669b41c 100644
--- a/libgomp/testsuite/libgomp.c/usleep.h
+++ b/libgomp/testsuite/libgomp.c/usleep.h
@@ -1,7 +1,7 @@
#include <unistd.h>
int
-nvptx_usleep (useconds_t d)
+fallback_usleep (useconds_t d)
{
/* This function serves as a replacement for usleep in
this test case. It does not even attempt to be functionally
@@ -13,7 +13,8 @@ nvptx_usleep (useconds_t d)
return 0;
}
-#pragma omp declare variant (nvptx_usleep) match(construct={target},device={arch(nvptx)})
+#pragma omp declare variant (fallback_usleep) match(construct={target},device={arch(nvptx)})
+#pragma omp declare variant (fallback_usleep) match(construct={target},device={arch(gcn)})
#pragma omp declare variant (usleep) match(user={condition(1)})
int
tgt_usleep (useconds_t d)
@@ -21,4 +22,4 @@ tgt_usleep (useconds_t d)
return 0;
}
-#pragma omp declare target to (nvptx_usleep, tgt_usleep)
+#pragma omp declare target to (fallback_usleep, tgt_usleep)
diff --git a/libgomp/testsuite/libgomp.oacc-c++/cache-1.C b/libgomp/testsuite/libgomp.oacc-c++/cache-1.C
new file mode 100644
index 0000000..fcb1f84
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c++/cache-1.C
@@ -0,0 +1,13 @@
+/* OpenACC 'cache' directive. */
+
+/* See also corresponding C/C++ variant '../libgomp.oacc-c-c++-common/cache-1.c'. */
+
+#include "../../../gcc/testsuite/g++.dg/goacc/cache-1.C"
+
+int
+main (int argc, char *argv[])
+{
+ test<0> ();
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/cache-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/cache-1.c
index 16aaed5..c0dddb3 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/cache-1.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/cache-1.c
@@ -1,3 +1,13 @@
-/* OpenACC cache directive. */
+/* OpenACC 'cache' directive. */
+
+/* See also corresponding C++ variant '../libgomp.oacc-c++/cache-1.C'. */
#include "../../../gcc/testsuite/c-c++-common/goacc/cache-1.c"
+
+int
+main (int argc, char *argv[])
+{
+ test ();
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla-kernels-decompose-ice-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla-kernels-decompose-ice-1.c
new file mode 100644
index 0000000..c7eae12
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla-kernels-decompose-ice-1.c
@@ -0,0 +1,8 @@
+/* { dg-additional-options "-fopenacc-kernels=decompose" } */
+/* Hopefully, this is the same issue as '../../../gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-1.c'.
+ { dg-ice "TODO" }
+ TODO { dg-prune-output "during GIMPLE pass: omplower" }
+ TODO { dg-do link } */
+
+#undef KERNELS_DECOMPOSE_ICE_HACK
+#include "declare-vla.c"
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla-kernels-decompose.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla-kernels-decompose.c
new file mode 100644
index 0000000..dd8a1c1
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla-kernels-decompose.c
@@ -0,0 +1,6 @@
+/* { dg-additional-options "-fopenacc-kernels=decompose" } */
+
+/* See also 'declare-vla-kernels-decompose-ice-1.c'. */
+
+#define KERNELS_DECOMPOSE_ICE_HACK
+#include "declare-vla.c"
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla.c
index 7149357..3bd6331 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla.c
@@ -38,6 +38,12 @@ f_data (void)
for (i = 0; i < N; i++)
A[i] = -i;
+ /* See 'declare-vla-kernels-decompose.c'. */
+#ifdef KERNELS_DECOMPOSE_ICE_HACK
+ (volatile int *) &i;
+ (volatile int *) &N;
+#endif
+
# pragma acc kernels
for (i = 0; i < N; i++)
A[i] = i;
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/kernels-decompose-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/kernels-decompose-1.c
new file mode 100644
index 0000000..e76e409
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/kernels-decompose-1.c
@@ -0,0 +1,46 @@
+/* Test OpenACC 'kernels' construct decomposition. */
+
+/* { dg-additional-options "-fopt-info-omp-all" } */
+/* { dg-additional-options "-fopenacc-kernels=decompose" } */
+
+/* It's only with Tcl 8.5 (released in 2007) that "the variable 'varName'
+ passed to 'incr' may be unset, and in that case, it will be set to [...]",
+ so to maintain compatibility with earlier Tcl releases, we manually
+ initialize counter variables:
+ { dg-line l_dummy[variable c_loop_i 0] }
+ { dg-message "dummy" "" { target iN-VAl-Id } l_dummy } to avoid
+ "WARNING: dg-line var l_dummy defined, but not used". */
+
+#undef NDEBUG
+#include <assert.h>
+
+int main()
+{
+ int a = 0;
+ /*TODO Without making 'a' addressable, for GCN offloading we will not see the expected value copied out. (But it does work for nvptx offloading, strange...) */
+ (volatile int *) &a;
+#define N 123
+ int b[N] = { 0 };
+
+#pragma acc kernels
+ {
+ int c = 234; /* { dg-message "note: beginning 'gang-single' part in OpenACC 'kernels' region" } */
+
+ /*TODO Hopefully, this is the same issue as '../../../gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-1.c'. */
+ (volatile int *) &c;
+
+#pragma acc loop independent gang /* { dg-line l_loop_i[incr c_loop_i] } */
+ /* { dg-message "note: parallelized loop nest in OpenACC 'kernels' region" "" { target *-*-* } l_loop_i$c_loop_i } */
+ /* { dg-optimized "assigned OpenACC gang loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i } */
+ for (int i = 0; i < N; ++i)
+ b[i] = c;
+
+ a = c; /* { dg-message "note: beginning 'gang-single' part in OpenACC 'kernels' region" } */
+ }
+
+ for (int i = 0; i < N; ++i)
+ assert (b[i] == 234);
+ assert (a == 234);
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/atomic_capture-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/atomic_capture-1.f90
index 536b3f0..0b923d5 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/atomic_capture-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/atomic_capture-1.f90
@@ -299,7 +299,7 @@ program main
! At most one iarr element can be 0.
do i = 1, N
if ((iarr(i) == 0 .and. i /= itmp) &
- .or. iarr(i) < 0 .or. iarr(i) >= N) STOP 35
+ .or. iarr(i) < 0 .or. iarr(i) > N) STOP 35
end do
if (igot /= iexp) STOP 36
@@ -336,7 +336,7 @@ program main
!$acc parallel loop copy (igot, itmp)
do i = 0, N - 1
- iexpr = ibclr (-2, i)
+ iexpr = ibclr (-1, i)
!$acc atomic capture
iarr(i) = igot
igot = iand (igot, iexpr)
@@ -345,7 +345,7 @@ program main
!$acc end parallel loop
do i = 1, N
- if (.not. (iarr(i - 1) < 0)) STOP 39
+ if (.not. (popcnt(iarr(i - 1)) > 0)) STOP 39
end do
if (igot /= iexp) STOP 40
@@ -363,7 +363,7 @@ program main
!$acc end parallel loop
do i = 1, N
- if (.not. (iarr(i - 1) >= 0)) STOP 41
+ if (.not. (popcnt(iarr(i - 1)) < 32)) STOP 41
end do
if (igot /= iexp) STOP 42
@@ -381,7 +381,7 @@ program main
!$acc end parallel loop
do i = 1, N
- if (.not. (iarr(i - 1) < 0)) STOP 43
+ if (.not. (popcnt(iarr(i - 1)) > 0)) STOP 43
end do
if (igot /= iexp) STOP 44
@@ -398,7 +398,7 @@ program main
!$acc end parallel loop
do i = 1, N
- if (.not. (1 <= iarr(i) .and. iarr(i) < iexp)) STOP 45
+ if (.not. (1 <= iarr(i) .and. iarr(i) <= iexp)) STOP 45
end do
if (igot /= iexp) STOP 46
@@ -415,7 +415,7 @@ program main
!$acc end parallel loop
do i = 1, N
- if (.not. (iarr(i) == 1 .or. iarr(i) == N)) STOP 47
+ if (.not. (iarr(i) >= 1 .or. iarr(i) <= N)) STOP 47
end do
if (igot /= iexp) STOP 48
@@ -424,7 +424,7 @@ program main
!$acc parallel loop copy (igot, itmp)
do i = 0, N - 1
- iexpr = ibclr (-2, i)
+ iexpr = ibclr (-1, i)
!$acc atomic capture
iarr(i) = igot
igot = iand (iexpr, igot)
@@ -433,7 +433,7 @@ program main
!$acc end parallel loop
do i = 1, N
- if (.not. (iarr(i - 1) < 0)) STOP 49
+ if (.not. (popcnt(iarr(i - 1)) > 0)) STOP 49
end do
if (igot /= iexp) STOP 50
@@ -451,7 +451,7 @@ program main
!$acc end parallel loop
do i = 1, N
- if (.not. (iarr(i - 1) >= 0)) STOP 51
+ if (.not. (popcnt(iarr(i - 1)) < 32)) STOP 51
end do
if (igot /= iexp) STOP 52
@@ -469,7 +469,7 @@ program main
!$acc end parallel loop
do i = 1, N
- if (.not. (iarr(i - 1) < 0)) STOP 53
+ if (.not. (popcnt(iarr(i - 1)) > 0)) STOP 53
end do
if (igot /= iexp) STOP 54
@@ -755,7 +755,7 @@ program main
!$acc end parallel loop
do i = 1, N
- if (.not. (iarr(i) == iexp)) STOP 89
+ if (.not. (iarr(i) <= i)) STOP 89
end do
if (igot /= iexp) STOP 90
@@ -773,7 +773,7 @@ program main
!$acc end parallel loop
do i = 1, N
- if (.not. (iarr(i - 1) <= 0)) STOP 91
+ if (.not. (popcnt(iarr(i - 1)) < 32)) STOP 91
end do
if (igot /= iexp) STOP 92
@@ -791,7 +791,7 @@ program main
!$acc end parallel loop
do i = 1, N
- if (.not. (iarr(i - 1) >= -1)) STOP 93
+ if (.not. (popcnt(iarr(i - 1)) > 0)) STOP 93
end do
if (igot /= iexp) STOP 94
@@ -809,7 +809,7 @@ program main
!$acc end parallel loop
do i = 1, N
- if (.not. (iarr(i - 1) <= 0)) STOP 95
+ if (.not. (popcnt(iarr(i - 1)) < 32)) STOP 95
end do
if (igot /= iexp) STOP 96
@@ -843,7 +843,7 @@ program main
!$acc end parallel loop
do i = 1, N
- if (.not. (iarr(i) == iexp )) STOP 99
+ if (.not. (iarr(i) <= i)) STOP 99
end do
if (igot /= iexp) STOP 100
@@ -861,7 +861,7 @@ program main
!$acc end parallel loop
do i = 1, N
- if (.not. (iarr(i - 1) <= 0)) STOP 101
+ if (.not. (popcnt(iarr(i - 1)) < 32)) STOP 101
end do
if (igot /= iexp) STOP 102
@@ -879,7 +879,7 @@ program main
!$acc end parallel loop
do i = 1, N
- if (.not. (iarr(i - 1) >= iexp)) STOP 103
+ if (.not. (popcnt(iarr(i - 1)) > 0)) STOP 103
end do
if (igot /= iexp) STOP 104
@@ -897,7 +897,7 @@ program main
!$acc end parallel loop
do i = 1, N
- if (.not. (iarr(i - 1) <= iexp)) STOP 105
+ if (.not. (popcnt(iarr(i - 1)) < 32)) STOP 105
end do
if (igot /= iexp) STOP 106
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/attach-descriptor-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/attach-descriptor-1.f90
index 960b9f9..2701192 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/attach-descriptor-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/attach-descriptor-1.f90
@@ -42,9 +42,8 @@ subroutine test(variant)
stop 1
end if
- ! FIXME: This warning is emitted on the wrong line number.
- ! { dg-warning "using vector_length \\(32\\), ignoring 1" "" { target openacc_nvidia_accel_selected } 52 }
!$acc serial present(myvar%arr2)
+ ! { dg-warning "using vector_length \\(32\\), ignoring 1" "" { target openacc_nvidia_accel_selected } .-1 }
do i=1,10
myvar%arr1(i) = i + variant
myvar%arr2(i) = i - variant
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/pr94358-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/pr94358-1.f90
new file mode 100644
index 0000000..99a7041
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/pr94358-1.f90
@@ -0,0 +1,47 @@
+! { dg-do run }
+! { dg-additional-options "-fopt-info-omp-all" }
+! { dg-additional-options "-fopenacc-kernels=decompose" }
+
+! It's only with Tcl 8.5 (released in 2007) that "the variable 'varName'
+! passed to 'incr' may be unset, and in that case, it will be set to [...]",
+! so to maintain compatibility with earlier Tcl releases, we manually
+! initialize counter variables:
+! { dg-line l_dummy[variable c_loop_i 0] }
+! { dg-message "dummy" "" { target iN-VAl-Id } l_dummy } to avoid
+! "WARNING: dg-line var l_dummy defined, but not used".
+
+subroutine kernel(lo, hi, a, b, c)
+ implicit none
+ integer :: lo, hi, i
+ real, dimension(lo:hi) :: a, b, c
+
+ !$acc kernels copyin(lo, hi)
+ !$acc loop independent ! { dg-line l_loop_i[incr c_loop_i] }
+ ! { dg-message "note: parallelized loop nest in OpenACC 'kernels' region" "" { target *-*-* } l_loop_i$c_loop_i }
+ ! { dg-optimized "assigned OpenACC gang vector loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i }
+ do i = lo, hi
+ b(i) = a(i)
+ end do
+ !$acc loop independent ! { dg-line l_loop_i[incr c_loop_i] }
+ ! { dg-message "note: parallelized loop nest in OpenACC 'kernels' region" "" { target *-*-* } l_loop_i$c_loop_i }
+ ! { dg-optimized "assigned OpenACC gang vector loop parallelism" "" { target *-*-* } l_loop_i$c_loop_i }
+ do i = lo, hi
+ c(i) = b(i)
+ end do
+ !$acc end kernels
+end subroutine kernel
+
+program main
+ integer :: n = 20
+ real, dimension(1:20) :: a, b, c
+
+ a(:) = 1
+ b(:) = 2
+ c(:) = 3
+
+ call kernel(1, n, a, b, c)
+
+ do i = 1, n
+ if (c(i) .ne. 1) call abort
+ end do
+end program main
diff --git a/libhsail-rt/ChangeLog b/libhsail-rt/ChangeLog
index 5f32d42..578e880 100644
--- a/libhsail-rt/ChangeLog
+++ b/libhsail-rt/ChangeLog
@@ -1,3 +1,7 @@
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ * configure: Regenerate.
+
2020-01-24 Maciej W. Rozycki <macro@wdc.com>
* configure.ac: Handle `--with-toolexeclibdir='.
diff --git a/libhsail-rt/configure b/libhsail-rt/configure
index 49d529c..8bda2d2 100755
--- a/libhsail-rt/configure
+++ b/libhsail-rt/configure
@@ -9523,7 +9523,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -9535,7 +9535,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -12367,7 +12367,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
aCC*)
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
@@ -12391,7 +12391,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test $with_gnu_ld = no; then
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 642b959..ccc8a0e 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,50 @@
+2020-11-25 Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * configure: Regenerate.
+ * configure.ac: Avoid using sanitizer.
+
+2020-11-13 Eduard-Mihai Burtescu <eddyb@lyken.rs>
+
+ * rust-demangle.c (struct rust_demangler): Add
+ skipping_printing and bound_lifetime_depth fields.
+ (eat): Add (v0-only).
+ (parse_integer_62): Add (v0-only).
+ (parse_opt_integer_62): Add (v0-only).
+ (parse_disambiguator): Add (v0-only).
+ (struct rust_mangled_ident): Add punycode{,_len} fields.
+ (parse_ident): Support v0 identifiers.
+ (print_str): Respect skipping_printing.
+ (print_uint64): Add (v0-only).
+ (print_uint64_hex): Add (v0-only).
+ (print_ident): Respect skipping_printing,
+ Support v0 identifiers.
+ (print_lifetime_from_index): Add (v0-only).
+ (demangle_binder): Add (v0-only).
+ (demangle_path): Add (v0-only).
+ (demangle_generic_arg): Add (v0-only).
+ (demangle_type): Add (v0-only).
+ (demangle_path_maybe_open_generics): Add (v0-only).
+ (demangle_dyn_trait): Add (v0-only).
+ (demangle_const): Add (v0-only).
+ (demangle_const_uint): Add (v0-only).
+ (basic_type): Add (v0-only).
+ (rust_demangle_callback): Support v0 symbols.
+ * testsuite/rust-demangle-expected: Add v0 testcases.
+
+2020-11-13 Seija Kijin <doremylover456@gmail.com>
+
+ * strstr.c (strstr): Make implementation ANSI/POSIX compliant.
+
+2020-11-11 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/88115
+ * cp-demangle.c (d_print_comp_inner)
+ <case DEMANGLE_COMPONENT_EXTENDED_OPERATOR>: Don't print the
+ "operator " prefix for __alignof__.
+ <case DEMANGLE_COMPONENT_UNARY>: Always print parens around the
+ operand of __alignof__.
+ * testsuite/demangle-expected: Test demangling for __alignof__.
+
2020-11-09 Christophe Lyon <christophe.lyon@linaro.org>
* pex-win32.c (pex_win32_exec_child): Initialize orig_err.
diff --git a/libiberty/configure b/libiberty/configure
index ff93c9e..b6af9ba 100755
--- a/libiberty/configure
+++ b/libiberty/configure
@@ -5264,6 +5264,7 @@ fi
NOASANFLAG=
case " ${CFLAGS} " in
*\ -fsanitize=address\ *) NOASANFLAG=-fno-sanitize=address ;;
+ *\ -fsanitize=hwaddress\ *) NOASANFLAG=-fno-sanitize=hwaddress ;;
esac
diff --git a/libiberty/configure.ac b/libiberty/configure.ac
index 4e2599c..ad95296 100644
--- a/libiberty/configure.ac
+++ b/libiberty/configure.ac
@@ -240,6 +240,7 @@ AC_SUBST(PICFLAG)
NOASANFLAG=
case " ${CFLAGS} " in
*\ -fsanitize=address\ *) NOASANFLAG=-fno-sanitize=address ;;
+ *\ -fsanitize=hwaddress\ *) NOASANFLAG=-fno-sanitize=hwaddress ;;
esac
AC_SUBST(NOASANFLAG)
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index aede23f..a9f8e75 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -5458,9 +5458,18 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
}
case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
- d_append_string (dpi, "operator ");
- d_print_comp (dpi, options, dc->u.s_extended_operator.name);
- return;
+ {
+ struct demangle_component *name = dc->u.s_extended_operator.name;
+ if (name->type == DEMANGLE_COMPONENT_NAME
+ && !strncmp (name->u.s_name.s, "__alignof__", name->u.s_name.len))
+ d_print_comp (dpi, options, dc->u.s_extended_operator.name);
+ else
+ {
+ d_append_string (dpi, "operator ");
+ d_print_comp (dpi, options, dc->u.s_extended_operator.name);
+ }
+ return;
+ }
case DEMANGLE_COMPONENT_CONVERSION:
d_append_string (dpi, "operator ");
@@ -5525,8 +5534,14 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
if (code && !strcmp (code, "gs"))
/* Avoid parens after '::'. */
d_print_comp (dpi, options, operand);
- else if (code && !strcmp (code, "st"))
- /* Always print parens for sizeof (type). */
+ else if ((code && !strcmp (code, "st"))
+ || (op->type == DEMANGLE_COMPONENT_EXTENDED_OPERATOR
+ && (op->u.s_extended_operator.name->type
+ == DEMANGLE_COMPONENT_NAME)
+ && !strncmp (op->u.s_extended_operator.name->u.s_name.s,
+ "__alignof__",
+ op->u.s_extended_operator.name->u.s_name.len)))
+ /* Always print parens for sizeof (type) and __alignof__. */
{
d_append_char (dpi, '(');
d_print_comp (dpi, options, operand);
diff --git a/libiberty/rust-demangle.c b/libiberty/rust-demangle.c
index b87365c..08c615f 100644
--- a/libiberty/rust-demangle.c
+++ b/libiberty/rust-demangle.c
@@ -1,6 +1,7 @@
/* Demangler for the Rust programming language
Copyright (C) 2016-2020 Free Software Foundation, Inc.
Written by David Tolnay (dtolnay@gmail.com).
+ Rewritten by Eduard-Mihai Burtescu (eddyb@lyken.rs) for v0 support.
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
@@ -64,11 +65,16 @@ struct rust_demangler
/* Non-zero if any error occurred. */
int errored;
+ /* Non-zero if nothing should be printed. */
+ int skipping_printing;
+
/* Non-zero if printing should be verbose (e.g. include hashes). */
int verbose;
/* Rust mangling version, with legacy mangling being -1. */
int version;
+
+ uint64_t bound_lifetime_depth;
};
/* Parsing functions. */
@@ -81,6 +87,18 @@ peek (const struct rust_demangler *rdm)
return 0;
}
+static int
+eat (struct rust_demangler *rdm, char c)
+{
+ if (peek (rdm) == c)
+ {
+ rdm->next++;
+ return 1;
+ }
+ else
+ return 0;
+}
+
static char
next (struct rust_demangler *rdm)
{
@@ -92,11 +110,87 @@ next (struct rust_demangler *rdm)
return c;
}
+static uint64_t
+parse_integer_62 (struct rust_demangler *rdm)
+{
+ char c;
+ uint64_t x;
+
+ if (eat (rdm, '_'))
+ return 0;
+
+ x = 0;
+ while (!eat (rdm, '_'))
+ {
+ c = next (rdm);
+ x *= 62;
+ if (ISDIGIT (c))
+ x += c - '0';
+ else if (ISLOWER (c))
+ x += 10 + (c - 'a');
+ else if (ISUPPER (c))
+ x += 10 + 26 + (c - 'A');
+ else
+ {
+ rdm->errored = 1;
+ return 0;
+ }
+ }
+ return x + 1;
+}
+
+static uint64_t
+parse_opt_integer_62 (struct rust_demangler *rdm, char tag)
+{
+ if (!eat (rdm, tag))
+ return 0;
+ return 1 + parse_integer_62 (rdm);
+}
+
+static uint64_t
+parse_disambiguator (struct rust_demangler *rdm)
+{
+ return parse_opt_integer_62 (rdm, 's');
+}
+
+static size_t
+parse_hex_nibbles (struct rust_demangler *rdm, uint64_t *value)
+{
+ char c;
+ size_t hex_len;
+
+ hex_len = 0;
+ *value = 0;
+
+ while (!eat (rdm, '_'))
+ {
+ *value <<= 4;
+
+ c = next (rdm);
+ if (ISDIGIT (c))
+ *value |= c - '0';
+ else if (c >= 'a' && c <= 'f')
+ *value |= 10 + (c - 'a');
+ else
+ {
+ rdm->errored = 1;
+ return 0;
+ }
+ hex_len++;
+ }
+
+ return hex_len;
+}
+
struct rust_mangled_ident
{
/* ASCII part of the identifier. */
const char *ascii;
size_t ascii_len;
+
+ /* Punycode insertion codes for Unicode codepoints, if any. */
+ const char *punycode;
+ size_t punycode_len;
};
static struct rust_mangled_ident
@@ -104,10 +198,16 @@ parse_ident (struct rust_demangler *rdm)
{
char c;
size_t start, len;
+ int is_punycode = 0;
struct rust_mangled_ident ident;
ident.ascii = NULL;
ident.ascii_len = 0;
+ ident.punycode = NULL;
+ ident.punycode_len = 0;
+
+ if (rdm->version != -1)
+ is_punycode = eat (rdm, 'u');
c = next (rdm);
if (!ISDIGIT (c))
@@ -121,6 +221,10 @@ parse_ident (struct rust_demangler *rdm)
while (ISDIGIT (peek (rdm)))
len = len * 10 + (next (rdm) - '0');
+ /* Skip past the optional `_` separator (v0). */
+ if (rdm->version != -1)
+ eat (rdm, '_');
+
start = rdm->next;
rdm->next += len;
/* Check for overflows. */
@@ -133,6 +237,27 @@ parse_ident (struct rust_demangler *rdm)
ident.ascii = rdm->sym + start;
ident.ascii_len = len;
+ if (is_punycode)
+ {
+ ident.punycode_len = 0;
+ while (ident.ascii_len > 0)
+ {
+ ident.ascii_len--;
+
+ /* The last '_' is a separator between ascii & punycode. */
+ if (ident.ascii[ident.ascii_len] == '_')
+ break;
+
+ ident.punycode_len++;
+ }
+ if (!ident.punycode_len)
+ {
+ rdm->errored = 1;
+ return ident;
+ }
+ ident.punycode = ident.ascii + (len - ident.punycode_len);
+ }
+
if (ident.ascii_len == 0)
ident.ascii = NULL;
@@ -144,12 +269,28 @@ parse_ident (struct rust_demangler *rdm)
static void
print_str (struct rust_demangler *rdm, const char *data, size_t len)
{
- if (!rdm->errored)
+ if (!rdm->errored && !rdm->skipping_printing)
rdm->callback (data, len, rdm->callback_opaque);
}
#define PRINT(s) print_str (rdm, s, strlen (s))
+static void
+print_uint64 (struct rust_demangler *rdm, uint64_t x)
+{
+ char s[21];
+ snprintf (s, 21, "%" PRIu64, x);
+ PRINT (s);
+}
+
+static void
+print_uint64_hex (struct rust_demangler *rdm, uint64_t x)
+{
+ char s[17];
+ snprintf (s, 17, "%" PRIx64, x);
+ PRINT (s);
+}
+
/* Return a 0x0-0xf value if the char is 0-9a-f, and -1 otherwise. */
static int
decode_lower_hex_nibble (char nibble)
@@ -230,9 +371,14 @@ static void
print_ident (struct rust_demangler *rdm, struct rust_mangled_ident ident)
{
char unescaped;
- size_t len;
-
- if (rdm->errored)
+ uint8_t *out, *p, d;
+ size_t len, cap, punycode_pos, j;
+ /* Punycode parameters and state. */
+ uint32_t c;
+ size_t base, t_min, t_max, skew, damp, bias, i;
+ size_t delta, w, k, t;
+
+ if (rdm->errored || rdm->skipping_printing)
return;
if (rdm->version == -1)
@@ -273,8 +419,7 @@ print_ident (struct rust_demangler *rdm, struct rust_mangled_ident ident)
}
else
{
- /* "." becomes "-" */
- PRINT ("-");
+ PRINT (".");
len = 1;
}
}
@@ -294,6 +439,830 @@ print_ident (struct rust_demangler *rdm, struct rust_mangled_ident ident)
return;
}
+
+ if (!ident.punycode)
+ {
+ print_str (rdm, ident.ascii, ident.ascii_len);
+ return;
+ }
+
+ len = 0;
+ cap = 4;
+ while (cap < ident.ascii_len)
+ {
+ cap *= 2;
+ /* Check for overflows. */
+ if ((cap * 4) / 4 != cap)
+ {
+ rdm->errored = 1;
+ return;
+ }
+ }
+
+ /* Store the output codepoints as groups of 4 UTF-8 bytes. */
+ out = (uint8_t *)malloc (cap * 4);
+ if (!out)
+ {
+ rdm->errored = 1;
+ return;
+ }
+
+ /* Populate initial output from ASCII fragment. */
+ for (len = 0; len < ident.ascii_len; len++)
+ {
+ p = out + 4 * len;
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ p[3] = ident.ascii[len];
+ }
+
+ /* Punycode parameters and initial state. */
+ base = 36;
+ t_min = 1;
+ t_max = 26;
+ skew = 38;
+ damp = 700;
+ bias = 72;
+ i = 0;
+ c = 0x80;
+
+ punycode_pos = 0;
+ while (punycode_pos < ident.punycode_len)
+ {
+ /* Read one delta value. */
+ delta = 0;
+ w = 1;
+ k = 0;
+ do
+ {
+ k += base;
+ t = k < bias ? 0 : (k - bias);
+ if (t < t_min)
+ t = t_min;
+ if (t > t_max)
+ t = t_max;
+
+ if (punycode_pos >= ident.punycode_len)
+ goto cleanup;
+ d = ident.punycode[punycode_pos++];
+
+ if (ISLOWER (d))
+ d = d - 'a';
+ else if (ISDIGIT (d))
+ d = 26 + (d - '0');
+ else
+ {
+ rdm->errored = 1;
+ goto cleanup;
+ }
+
+ delta += d * w;
+ w *= base - t;
+ }
+ while (d >= t);
+
+ /* Compute the new insert position and character. */
+ len++;
+ i += delta;
+ c += i / len;
+ i %= len;
+
+ /* Ensure enough space is available. */
+ if (cap < len)
+ {
+ cap *= 2;
+ /* Check for overflows. */
+ if ((cap * 4) / 4 != cap || cap < len)
+ {
+ rdm->errored = 1;
+ goto cleanup;
+ }
+ }
+ p = (uint8_t *)realloc (out, cap * 4);
+ if (!p)
+ {
+ rdm->errored = 1;
+ goto cleanup;
+ }
+ out = p;
+
+ /* Move the characters after the insert position. */
+ p = out + i * 4;
+ memmove (p + 4, p, (len - i - 1) * 4);
+
+ /* Insert the new character, as UTF-8 bytes. */
+ p[0] = c >= 0x10000 ? 0xf0 | (c >> 18) : 0;
+ p[1] = c >= 0x800 ? (c < 0x10000 ? 0xe0 : 0x80) | ((c >> 12) & 0x3f) : 0;
+ p[2] = (c < 0x800 ? 0xc0 : 0x80) | ((c >> 6) & 0x3f);
+ p[3] = 0x80 | (c & 0x3f);
+
+ /* If there are no more deltas, decoding is complete. */
+ if (punycode_pos == ident.punycode_len)
+ break;
+
+ i++;
+
+ /* Perform bias adaptation. */
+ delta /= damp;
+ damp = 2;
+
+ delta += delta / len;
+ k = 0;
+ while (delta > ((base - t_min) * t_max) / 2)
+ {
+ delta /= base - t_min;
+ k += base;
+ }
+ bias = k + ((base - t_min + 1) * delta) / (delta + skew);
+ }
+
+ /* Remove all the 0 bytes to leave behind an UTF-8 string. */
+ for (i = 0, j = 0; i < len * 4; i++)
+ if (out[i] != 0)
+ out[j++] = out[i];
+
+ print_str (rdm, (const char *)out, j);
+
+cleanup:
+ free (out);
+}
+
+/* Print the lifetime according to the previously decoded index.
+ An index of `0` always refers to `'_`, but starting with `1`,
+ indices refer to late-bound lifetimes introduced by a binder. */
+static void
+print_lifetime_from_index (struct rust_demangler *rdm, uint64_t lt)
+{
+ char c;
+ uint64_t depth;
+
+ PRINT ("'");
+ if (lt == 0)
+ {
+ PRINT ("_");
+ return;
+ }
+
+ depth = rdm->bound_lifetime_depth - lt;
+ /* Try to print lifetimes alphabetically first. */
+ if (depth < 26)
+ {
+ c = 'a' + depth;
+ print_str (rdm, &c, 1);
+ }
+ else
+ {
+ /* Use `'_123` after running out of letters. */
+ PRINT ("_");
+ print_uint64 (rdm, depth);
+ }
+}
+
+/* Demangling functions. */
+
+static void demangle_binder (struct rust_demangler *rdm);
+static void demangle_path (struct rust_demangler *rdm, int in_value);
+static void demangle_generic_arg (struct rust_demangler *rdm);
+static void demangle_type (struct rust_demangler *rdm);
+static int demangle_path_maybe_open_generics (struct rust_demangler *rdm);
+static void demangle_dyn_trait (struct rust_demangler *rdm);
+static void demangle_const (struct rust_demangler *rdm);
+static void demangle_const_uint (struct rust_demangler *rdm);
+static void demangle_const_int (struct rust_demangler *rdm);
+static void demangle_const_bool (struct rust_demangler *rdm);
+static void demangle_const_char (struct rust_demangler *rdm);
+
+/* Optionally enter a binder ('G') for late-bound lifetimes,
+ printing e.g. `for<'a, 'b> `, and make those lifetimes visible
+ to the caller (via depth level, which the caller should reset). */
+static void
+demangle_binder (struct rust_demangler *rdm)
+{
+ uint64_t i, bound_lifetimes;
+
+ if (rdm->errored)
+ return;
+
+ bound_lifetimes = parse_opt_integer_62 (rdm, 'G');
+ if (bound_lifetimes > 0)
+ {
+ PRINT ("for<");
+ for (i = 0; i < bound_lifetimes; i++)
+ {
+ if (i > 0)
+ PRINT (", ");
+ rdm->bound_lifetime_depth++;
+ print_lifetime_from_index (rdm, 1);
+ }
+ PRINT ("> ");
+ }
+}
+
+static void
+demangle_path (struct rust_demangler *rdm, int in_value)
+{
+ char tag, ns;
+ int was_skipping_printing;
+ size_t i, backref, old_next;
+ uint64_t dis;
+ struct rust_mangled_ident name;
+
+ if (rdm->errored)
+ return;
+
+ switch (tag = next (rdm))
+ {
+ case 'C':
+ dis = parse_disambiguator (rdm);
+ name = parse_ident (rdm);
+
+ print_ident (rdm, name);
+ if (rdm->verbose)
+ {
+ PRINT ("[");
+ print_uint64_hex (rdm, dis);
+ PRINT ("]");
+ }
+ break;
+ case 'N':
+ ns = next (rdm);
+ if (!ISLOWER (ns) && !ISUPPER (ns))
+ {
+ rdm->errored = 1;
+ return;
+ }
+
+ demangle_path (rdm, in_value);
+
+ dis = parse_disambiguator (rdm);
+ name = parse_ident (rdm);
+
+ if (ISUPPER (ns))
+ {
+ /* Special namespaces, like closures and shims. */
+ PRINT ("::{");
+ switch (ns)
+ {
+ case 'C':
+ PRINT ("closure");
+ break;
+ case 'S':
+ PRINT ("shim");
+ break;
+ default:
+ print_str (rdm, &ns, 1);
+ }
+ if (name.ascii || name.punycode)
+ {
+ PRINT (":");
+ print_ident (rdm, name);
+ }
+ PRINT ("#");
+ print_uint64 (rdm, dis);
+ PRINT ("}");
+ }
+ else
+ {
+ /* Implementation-specific/unspecified namespaces. */
+
+ if (name.ascii || name.punycode)
+ {
+ PRINT ("::");
+ print_ident (rdm, name);
+ }
+ }
+ break;
+ case 'M':
+ case 'X':
+ /* Ignore the `impl`'s own path.*/
+ parse_disambiguator (rdm);
+ was_skipping_printing = rdm->skipping_printing;
+ rdm->skipping_printing = 1;
+ demangle_path (rdm, in_value);
+ rdm->skipping_printing = was_skipping_printing;
+ /* fallthrough */
+ case 'Y':
+ PRINT ("<");
+ demangle_type (rdm);
+ if (tag != 'M')
+ {
+ PRINT (" as ");
+ demangle_path (rdm, 0);
+ }
+ PRINT (">");
+ break;
+ case 'I':
+ demangle_path (rdm, in_value);
+ if (in_value)
+ PRINT ("::");
+ PRINT ("<");
+ for (i = 0; !rdm->errored && !eat (rdm, 'E'); i++)
+ {
+ if (i > 0)
+ PRINT (", ");
+ demangle_generic_arg (rdm);
+ }
+ PRINT (">");
+ break;
+ case 'B':
+ backref = parse_integer_62 (rdm);
+ if (!rdm->skipping_printing)
+ {
+ old_next = rdm->next;
+ rdm->next = backref;
+ demangle_path (rdm, in_value);
+ rdm->next = old_next;
+ }
+ break;
+ default:
+ rdm->errored = 1;
+ return;
+ }
+}
+
+static void
+demangle_generic_arg (struct rust_demangler *rdm)
+{
+ uint64_t lt;
+ if (eat (rdm, 'L'))
+ {
+ lt = parse_integer_62 (rdm);
+ print_lifetime_from_index (rdm, lt);
+ }
+ else if (eat (rdm, 'K'))
+ demangle_const (rdm);
+ else
+ demangle_type (rdm);
+}
+
+static const char *
+basic_type (char tag)
+{
+ switch (tag)
+ {
+ case 'b':
+ return "bool";
+ case 'c':
+ return "char";
+ case 'e':
+ return "str";
+ case 'u':
+ return "()";
+ case 'a':
+ return "i8";
+ case 's':
+ return "i16";
+ case 'l':
+ return "i32";
+ case 'x':
+ return "i64";
+ case 'n':
+ return "i128";
+ case 'i':
+ return "isize";
+ case 'h':
+ return "u8";
+ case 't':
+ return "u16";
+ case 'm':
+ return "u32";
+ case 'y':
+ return "u64";
+ case 'o':
+ return "u128";
+ case 'j':
+ return "usize";
+ case 'f':
+ return "f32";
+ case 'd':
+ return "f64";
+ case 'z':
+ return "!";
+ case 'p':
+ return "_";
+ case 'v':
+ return "...";
+
+ default:
+ return NULL;
+ }
+}
+
+static void
+demangle_type (struct rust_demangler *rdm)
+{
+ char tag;
+ size_t i, old_next, backref;
+ uint64_t lt, old_bound_lifetime_depth;
+ const char *basic;
+ struct rust_mangled_ident abi;
+
+ if (rdm->errored)
+ return;
+
+ tag = next (rdm);
+
+ basic = basic_type (tag);
+ if (basic)
+ {
+ PRINT (basic);
+ return;
+ }
+
+ switch (tag)
+ {
+ case 'R':
+ case 'Q':
+ PRINT ("&");
+ if (eat (rdm, 'L'))
+ {
+ lt = parse_integer_62 (rdm);
+ if (lt)
+ {
+ print_lifetime_from_index (rdm, lt);
+ PRINT (" ");
+ }
+ }
+ if (tag != 'R')
+ PRINT ("mut ");
+ demangle_type (rdm);
+ break;
+ case 'P':
+ case 'O':
+ PRINT ("*");
+ if (tag != 'P')
+ PRINT ("mut ");
+ else
+ PRINT ("const ");
+ demangle_type (rdm);
+ break;
+ case 'A':
+ case 'S':
+ PRINT ("[");
+ demangle_type (rdm);
+ if (tag == 'A')
+ {
+ PRINT ("; ");
+ demangle_const (rdm);
+ }
+ PRINT ("]");
+ break;
+ case 'T':
+ PRINT ("(");
+ for (i = 0; !rdm->errored && !eat (rdm, 'E'); i++)
+ {
+ if (i > 0)
+ PRINT (", ");
+ demangle_type (rdm);
+ }
+ if (i == 1)
+ PRINT (",");
+ PRINT (")");
+ break;
+ case 'F':
+ old_bound_lifetime_depth = rdm->bound_lifetime_depth;
+ demangle_binder (rdm);
+
+ if (eat (rdm, 'U'))
+ PRINT ("unsafe ");
+
+ if (eat (rdm, 'K'))
+ {
+ if (eat (rdm, 'C'))
+ {
+ abi.ascii = "C";
+ abi.ascii_len = 1;
+ }
+ else
+ {
+ abi = parse_ident (rdm);
+ if (!abi.ascii || abi.punycode)
+ {
+ rdm->errored = 1;
+ goto restore;
+ }
+ }
+
+ PRINT ("extern \"");
+
+ /* If the ABI had any `-`, they were replaced with `_`,
+ so the parts between `_` have to be re-joined with `-`. */
+ for (i = 0; i < abi.ascii_len; i++)
+ {
+ if (abi.ascii[i] == '_')
+ {
+ print_str (rdm, abi.ascii, i);
+ PRINT ("-");
+ abi.ascii += i + 1;
+ abi.ascii_len -= i + 1;
+ i = 0;
+ }
+ }
+ print_str (rdm, abi.ascii, abi.ascii_len);
+
+ PRINT ("\" ");
+ }
+
+ PRINT ("fn(");
+ for (i = 0; !rdm->errored && !eat (rdm, 'E'); i++)
+ {
+ if (i > 0)
+ PRINT (", ");
+ demangle_type (rdm);
+ }
+ PRINT (")");
+
+ if (eat (rdm, 'u'))
+ {
+ /* Skip printing the return type if it's 'u', i.e. `()`. */
+ }
+ else
+ {
+ PRINT (" -> ");
+ demangle_type (rdm);
+ }
+
+ /* Restore `bound_lifetime_depth` to outside the binder. */
+ restore:
+ rdm->bound_lifetime_depth = old_bound_lifetime_depth;
+ break;
+ case 'D':
+ PRINT ("dyn ");
+
+ old_bound_lifetime_depth = rdm->bound_lifetime_depth;
+ demangle_binder (rdm);
+
+ for (i = 0; !rdm->errored && !eat (rdm, 'E'); i++)
+ {
+ if (i > 0)
+ PRINT (" + ");
+ demangle_dyn_trait (rdm);
+ }
+
+ /* Restore `bound_lifetime_depth` to outside the binder. */
+ rdm->bound_lifetime_depth = old_bound_lifetime_depth;
+
+ if (!eat (rdm, 'L'))
+ {
+ rdm->errored = 1;
+ return;
+ }
+ lt = parse_integer_62 (rdm);
+ if (lt)
+ {
+ PRINT (" + ");
+ print_lifetime_from_index (rdm, lt);
+ }
+ break;
+ case 'B':
+ backref = parse_integer_62 (rdm);
+ if (!rdm->skipping_printing)
+ {
+ old_next = rdm->next;
+ rdm->next = backref;
+ demangle_type (rdm);
+ rdm->next = old_next;
+ }
+ break;
+ default:
+ /* Go back to the tag, so `demangle_path` also sees it. */
+ rdm->next--;
+ demangle_path (rdm, 0);
+ }
+}
+
+/* A trait in a trait object may have some "existential projections"
+ (i.e. associated type bindings) after it, which should be printed
+ in the `<...>` of the trait, e.g. `dyn Trait<T, U, Assoc=X>`.
+ To this end, this method will keep the `<...>` of an 'I' path
+ open, by omitting the `>`, and return `Ok(true)` in that case. */
+static int
+demangle_path_maybe_open_generics (struct rust_demangler *rdm)
+{
+ int open;
+ size_t i, old_next, backref;
+
+ open = 0;
+
+ if (rdm->errored)
+ return open;
+
+ if (eat (rdm, 'B'))
+ {
+ backref = parse_integer_62 (rdm);
+ if (!rdm->skipping_printing)
+ {
+ old_next = rdm->next;
+ rdm->next = backref;
+ open = demangle_path_maybe_open_generics (rdm);
+ rdm->next = old_next;
+ }
+ }
+ else if (eat (rdm, 'I'))
+ {
+ demangle_path (rdm, 0);
+ PRINT ("<");
+ open = 1;
+ for (i = 0; !rdm->errored && !eat (rdm, 'E'); i++)
+ {
+ if (i > 0)
+ PRINT (", ");
+ demangle_generic_arg (rdm);
+ }
+ }
+ else
+ demangle_path (rdm, 0);
+ return open;
+}
+
+static void
+demangle_dyn_trait (struct rust_demangler *rdm)
+{
+ int open;
+ struct rust_mangled_ident name;
+
+ if (rdm->errored)
+ return;
+
+ open = demangle_path_maybe_open_generics (rdm);
+
+ while (eat (rdm, 'p'))
+ {
+ if (!open)
+ PRINT ("<");
+ else
+ PRINT (", ");
+ open = 1;
+
+ name = parse_ident (rdm);
+ print_ident (rdm, name);
+ PRINT (" = ");
+ demangle_type (rdm);
+ }
+
+ if (open)
+ PRINT (">");
+}
+
+static void
+demangle_const (struct rust_demangler *rdm)
+{
+ char ty_tag;
+ size_t old_next, backref;
+
+ if (rdm->errored)
+ return;
+
+ if (eat (rdm, 'B'))
+ {
+ backref = parse_integer_62 (rdm);
+ if (!rdm->skipping_printing)
+ {
+ old_next = rdm->next;
+ rdm->next = backref;
+ demangle_const (rdm);
+ rdm->next = old_next;
+ }
+ return;
+ }
+
+ ty_tag = next (rdm);
+ switch (ty_tag)
+ {
+ /* Placeholder. */
+ case 'p':
+ PRINT ("_");
+ return;
+
+ /* Unsigned integer types. */
+ case 'h':
+ case 't':
+ case 'm':
+ case 'y':
+ case 'o':
+ case 'j':
+ demangle_const_uint (rdm);
+ break;
+
+ /* Signed integer types. */
+ case 'a':
+ case 's':
+ case 'l':
+ case 'x':
+ case 'n':
+ case 'i':
+ demangle_const_int (rdm);
+ break;
+
+ /* Boolean. */
+ case 'b':
+ demangle_const_bool (rdm);
+ break;
+
+ /* Character. */
+ case 'c':
+ demangle_const_char (rdm);
+ break;
+
+ default:
+ rdm->errored = 1;
+ return;
+ }
+
+ if (rdm->errored)
+ return;
+
+ if (rdm->verbose)
+ {
+ PRINT (": ");
+ PRINT (basic_type (ty_tag));
+ }
+}
+
+static void
+demangle_const_uint (struct rust_demangler *rdm)
+{
+ size_t hex_len;
+ uint64_t value;
+
+ if (rdm->errored)
+ return;
+
+ hex_len = parse_hex_nibbles (rdm, &value);
+
+ if (hex_len > 16)
+ {
+ /* Print anything that doesn't fit in `uint64_t` verbatim. */
+ PRINT ("0x");
+ print_str (rdm, rdm->sym + (rdm->next - hex_len), hex_len);
+ }
+ else if (hex_len > 0)
+ print_uint64 (rdm, value);
+ else
+ rdm->errored = 1;
+}
+
+static void
+demangle_const_int (struct rust_demangler *rdm)
+{
+ if (eat (rdm, 'n'))
+ PRINT ("-");
+ demangle_const_uint (rdm);
+}
+
+static void
+demangle_const_bool (struct rust_demangler *rdm)
+{
+ uint64_t value;
+
+ if (parse_hex_nibbles (rdm, &value) != 1)
+ {
+ rdm->errored = 1;
+ return;
+ }
+
+ if (value == 0)
+ PRINT ("false");
+ else if (value == 1)
+ PRINT ("true");
+ else
+ rdm->errored = 1;
+}
+
+static void
+demangle_const_char (struct rust_demangler *rdm)
+{
+ size_t hex_len;
+ uint64_t value;
+
+ hex_len = parse_hex_nibbles (rdm, &value);
+
+ if (hex_len == 0 || hex_len > 8)
+ {
+ rdm->errored = 1;
+ return;
+ }
+
+ /* Match Rust's character "debug" output as best as we can. */
+ PRINT ("'");
+ if (value == '\t')
+ PRINT ("\\t");
+ else if (value == '\r')
+ PRINT ("\\r");
+ else if (value == '\n')
+ PRINT ("\\n");
+ else if (value > ' ' && value < '~')
+ /* Rust also considers many non-ASCII codepoints to be printable, but
+ that logic is not easily ported to C. */
+ print_str (rdm, (char *) &value, 1);
+ else
+ {
+ PRINT ("\\u{");
+ print_uint64_hex (rdm, value);
+ PRINT ("}");
+ }
+ PRINT ("'");
}
/* A legacy hash is the prefix "h" followed by 16 lowercase hex digits.
@@ -345,11 +1314,15 @@ rust_demangle_callback (const char *mangled, int options,
rdm.next = 0;
rdm.errored = 0;
+ rdm.skipping_printing = 0;
rdm.verbose = (options & DMGL_VERBOSE) != 0;
rdm.version = 0;
+ rdm.bound_lifetime_depth = 0;
- /* Rust symbols always start with _ZN (legacy). */
- if (rdm.sym[0] == '_' && rdm.sym[1] == 'Z' && rdm.sym[2] == 'N')
+ /* Rust symbols always start with _R (v0) or _ZN (legacy). */
+ if (rdm.sym[0] == '_' && rdm.sym[1] == 'R')
+ rdm.sym += 2;
+ else if (rdm.sym[0] == '_' && rdm.sym[1] == 'Z' && rdm.sym[2] == 'N')
{
rdm.sym += 3;
rdm.version = -1;
@@ -357,7 +1330,11 @@ rust_demangle_callback (const char *mangled, int options,
else
return 0;
- /* Legacy Rust symbols use only [_0-9a-zA-Z.:$] characters. */
+ /* Paths (v0) always start with uppercase characters. */
+ if (rdm.version != -1 && !ISUPPER (rdm.sym[0]))
+ return 0;
+
+ /* Rust symbols (v0) use only [_0-9a-zA-Z] characters. */
for (p = rdm.sym; *p; p++)
{
rdm.sym_len++;
@@ -365,6 +1342,7 @@ rust_demangle_callback (const char *mangled, int options,
if (*p == '_' || ISALNUM (*p))
continue;
+ /* Legacy Rust symbols can also contain [.:$] characters. */
if (rdm.version == -1 && (*p == '$' || *p == '.' || *p == ':'))
continue;
@@ -418,7 +1396,19 @@ rust_demangle_callback (const char *mangled, int options,
while (rdm.next < rdm.sym_len);
}
else
- return 0;
+ {
+ demangle_path (&rdm, 1);
+
+ /* Skip instantiating crate. */
+ if (!rdm.errored && rdm.next < rdm.sym_len)
+ {
+ rdm.skipping_printing = 1;
+ demangle_path (&rdm, 0);
+ }
+
+ /* It's an error to not reach the end. */
+ rdm.errored |= rdm.next != rdm.sym_len;
+ }
return !rdm.errored;
}
diff --git a/libiberty/strstr.c b/libiberty/strstr.c
index 60902ea..c6f6849 100644
--- a/libiberty/strstr.c
+++ b/libiberty/strstr.c
@@ -16,26 +16,20 @@ length, the function returns @var{string}.
*/
-
-/* FIXME: The above description is ANSI compiliant. This routine has not
- been validated to comply with it. -fnf */
-
#include <stddef.h>
-extern char *strchr (const char *, int);
-extern int strncmp (const void *, const void *, size_t);
+extern int memcmp (const void *, const void *, size_t);
extern size_t strlen (const char *);
char *
strstr (const char *s1, const char *s2)
{
- const char *p = s1;
const size_t len = strlen (s2);
-
- for (; (p = strchr (p, *s2)) != 0; p++)
+ while (*s1)
{
- if (strncmp (p, s2, len) == 0)
- return (char *)p;
+ if (!memcmp (s1, s2, len))
+ return (char *)s1;
+ ++s1;
}
return (0);
}
diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected
index 0850db3..4ad9da8 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -1469,3 +1469,10 @@ f(A<X{.a.b[3 ... 4]=(1)}>)
# PR 96143
_Z2F2IZ1FvEUlvE_EN1AIT_E1XES2_
A<F()::{lambda()#1}>::X F2<F()::{lambda()#1}>(F()::{lambda()#1})
+
+# PR 88115
+_Z1fIiEvDTv111__alignof__T_E
+void f<int>(decltype (__alignof__(int)))
+
+_Z1fIiEvDTv111__alignof__tlT_EE
+void f<int>(decltype (__alignof__(int{})))
diff --git a/libiberty/testsuite/rust-demangle-expected b/libiberty/testsuite/rust-demangle-expected
index 7477479..7dca315 100644
--- a/libiberty/testsuite/rust-demangle-expected
+++ b/libiberty/testsuite/rust-demangle-expected
@@ -11,7 +11,7 @@
#
############
#
-# Coverage Tests
+# Coverage Tests (legacy)
#
#
# Demangles as rust symbol.
@@ -163,3 +163,135 @@ _ZN63_$LT$core..ptr..Unique$LT$T$GT$$u20$as$u20$core..ops..Deref$GT$5deref17h19f
--format=rust
_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h059a991a004536adE
issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo
+--format=rust
+_ZN4core3ops8function6FnOnce40call_once$u7b$$u7b$vtable.shim$u7d$$u7d$17h000b1ad6c4f30bd6E
+core::ops::function::FnOnce::call_once{{vtable.shim}}
+#
+############
+#
+# Coverage Tests (v0)
+#
+#
+# Crate with a leading digit.
+--format=rust
+_RNvC6_123foo3bar
+123foo::bar
+# UTF-8 identifiers.
+--format=rust
+_RNqCs4fqI2P2rA04_11utf8_identsu30____7hkackfecea1cbdathfdh9hlq6y
+utf8_idents::საჭმელად_გემრიელი_სადილი
+# Closure path elements.
+--format=rust
+_RNCNCNgCs6DXkGYLi8lr_2cc5spawn00B5_
+cc::spawn::{closure#0}::{closure#0}
+#
+--format=rust
+_RNCINkXs25_NgCsbmNqQUJIY6D_4core5sliceINyB9_4IterhENuNgNoBb_4iter8iterator8Iterator9rpositionNCNgNpB9_6memchr7memrchrs_0E0Bb_
+<core::slice::Iter<u8> as core::iter::iterator::Iterator>::rposition::<core::slice::memchr::memrchr::{closure#1}>::{closure#0}
+# dyn Trait ("trait object") types.
+--format=rust
+_RINbNbCskIICzLVDPPb_5alloc5alloc8box_freeDINbNiB4_5boxed5FnBoxuEp6OutputuEL_ECs1iopQbuBiw2_3std
+alloc::alloc::box_free::<dyn alloc::boxed::FnBox<(), Output = ()>>
+# Types with const generics parameters.
+--format=rust
+_RNvMC0INtC8arrayvec8ArrayVechKj7b_E3new
+<arrayvec::ArrayVec<u8, 123>>::new
+#
+--format=rust
+_RMCs4fqI2P2rA04_13const_genericINtB0_8UnsignedKhb_E
+<const_generic::Unsigned<11>>
+#
+--format=rust
+_RMCs4fqI2P2rA04_13const_genericINtB0_6SignedKs98_E
+<const_generic::Signed<152>>
+#
+--format=rust
+_RMCs4fqI2P2rA04_13const_genericINtB0_6SignedKanb_E
+<const_generic::Signed<-11>>
+#
+--format=rust
+_RMCs4fqI2P2rA04_13const_genericINtB0_4BoolKb0_E
+<const_generic::Bool<false>>
+#
+--format=rust
+_RMCs4fqI2P2rA04_13const_genericINtB0_4BoolKb1_E
+<const_generic::Bool<true>>
+#
+--format=rust
+_RMCs4fqI2P2rA04_13const_genericINtB0_4CharKc76_E
+<const_generic::Char<'v'>>
+#
+--format=rust
+_RMCs4fqI2P2rA04_13const_genericINtB0_4CharKca_E
+<const_generic::Char<'\n'>>
+#
+--format=rust
+_RMCs4fqI2P2rA04_13const_genericINtB0_4CharKc2202_E
+<const_generic::Char<'\u{2202}'>>
+#
+--format=rust
+_RNvNvMCs4fqI2P2rA04_13const_genericINtB4_3FooKpE3foo3FOO
+<const_generic::Foo<_>>::foo::FOO
+#
+# All of the tests above but in auto mode instead:
+#
+# Crate with a leading digit.
+--format=auto
+_RNvC6_123foo3bar
+123foo::bar
+# UTF-8 identifiers.
+--format=auto
+_RNqCs4fqI2P2rA04_11utf8_identsu30____7hkackfecea1cbdathfdh9hlq6y
+utf8_idents::საჭმელად_გემრიელი_სადილი
+# Closure path elements.
+--format=auto
+_RNCNCNgCs6DXkGYLi8lr_2cc5spawn00B5_
+cc::spawn::{closure#0}::{closure#0}
+#
+--format=auto
+_RNCINkXs25_NgCsbmNqQUJIY6D_4core5sliceINyB9_4IterhENuNgNoBb_4iter8iterator8Iterator9rpositionNCNgNpB9_6memchr7memrchrs_0E0Bb_
+<core::slice::Iter<u8> as core::iter::iterator::Iterator>::rposition::<core::slice::memchr::memrchr::{closure#1}>::{closure#0}
+# dyn Trait ("trait object") types.
+--format=auto
+_RINbNbCskIICzLVDPPb_5alloc5alloc8box_freeDINbNiB4_5boxed5FnBoxuEp6OutputuEL_ECs1iopQbuBiw2_3std
+alloc::alloc::box_free::<dyn alloc::boxed::FnBox<(), Output = ()>>
+# Types with const generics parameters.
+--format=auto
+_RNvMC0INtC8arrayvec8ArrayVechKj7b_E3new
+<arrayvec::ArrayVec<u8, 123>>::new
+#
+--format=auto
+_RMCs4fqI2P2rA04_13const_genericINtB0_8UnsignedKhb_E
+<const_generic::Unsigned<11>>
+#
+--format=auto
+_RMCs4fqI2P2rA04_13const_genericINtB0_6SignedKs98_E
+<const_generic::Signed<152>>
+#
+--format=auto
+_RMCs4fqI2P2rA04_13const_genericINtB0_6SignedKanb_E
+<const_generic::Signed<-11>>
+#
+--format=auto
+_RMCs4fqI2P2rA04_13const_genericINtB0_4BoolKb0_E
+<const_generic::Bool<false>>
+#
+--format=auto
+_RMCs4fqI2P2rA04_13const_genericINtB0_4BoolKb1_E
+<const_generic::Bool<true>>
+#
+--format=auto
+_RMCs4fqI2P2rA04_13const_genericINtB0_4CharKc76_E
+<const_generic::Char<'v'>>
+#
+--format=auto
+_RMCs4fqI2P2rA04_13const_genericINtB0_4CharKca_E
+<const_generic::Char<'\n'>>
+#
+--format=auto
+_RMCs4fqI2P2rA04_13const_genericINtB0_4CharKc2202_E
+<const_generic::Char<'\u{2202}'>>
+#
+--format=auto
+_RNvNvMCs4fqI2P2rA04_13const_genericINtB4_3FooKpE3foo3FOO
+<const_generic::Foo<_>>::foo::FOO
diff --git a/libitm/ChangeLog b/libitm/ChangeLog
index 02aadfe..f42819a 100644
--- a/libitm/ChangeLog
+++ b/libitm/ChangeLog
@@ -1,3 +1,7 @@
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ * configure: Regenerate.
+
2020-10-01 Alan Modra <amodra@gmail.com>
* config/powerpc/sjlj.S: Support __PCREL__ code.
diff --git a/libitm/configure b/libitm/configure
index 90965f3..5a9596d 100755
--- a/libitm/configure
+++ b/libitm/configure
@@ -10348,7 +10348,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -10360,7 +10360,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -13192,7 +13192,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
aCC*)
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
@@ -13216,7 +13216,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test $with_gnu_ld = no; then
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog
index 43578a0..7cd7e4b 100644
--- a/libobjc/ChangeLog
+++ b/libobjc/ChangeLog
@@ -1,3 +1,7 @@
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ * configure: Regenerate.
+
2020-10-11 Iain Sandoe <iain@sandoe.co.uk>
* encoding.c (_darwin_rs6000_special_round_type_align):
diff --git a/libobjc/configure b/libobjc/configure
index c4f6688..4c7a503 100755
--- a/libobjc/configure
+++ b/libobjc/configure
@@ -9042,7 +9042,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -9054,7 +9054,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
diff --git a/liboffloadmic/ChangeLog b/liboffloadmic/ChangeLog
index c45f937..28adb0d 100644
--- a/liboffloadmic/ChangeLog
+++ b/liboffloadmic/ChangeLog
@@ -1,3 +1,8 @@
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ * configure: Regenerate.
+ * plugin/configure: Regenerate.
+
2020-05-05 Martin Liska <mliska@suse.cz>
PR other/89860
diff --git a/liboffloadmic/configure b/liboffloadmic/configure
index cd01179..a40ac96 100644
--- a/liboffloadmic/configure
+++ b/liboffloadmic/configure
@@ -9714,7 +9714,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -9726,7 +9726,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -12558,7 +12558,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
aCC*)
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
@@ -12582,7 +12582,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test $with_gnu_ld = no; then
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
diff --git a/liboffloadmic/plugin/configure b/liboffloadmic/plugin/configure
index cf48522..0cf0295 100644
--- a/liboffloadmic/plugin/configure
+++ b/liboffloadmic/plugin/configure
@@ -9361,7 +9361,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -9373,7 +9373,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -12205,7 +12205,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
aCC*)
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
@@ -12229,7 +12229,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test $with_gnu_ld = no; then
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog
index 56a796b..2596478c 100644
--- a/libphobos/ChangeLog
+++ b/libphobos/ChangeLog
@@ -1,3 +1,54 @@
+2020-11-30 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/87818
+ * configure.tgt: Add x86_64-*-freebsd* and i?86-*-freebsd* as
+ supported targets.
+
+2020-11-27 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/98025
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * configure.ac (DCFG_ENABLE_CET): Substitute.
+ * libdruntime/MERGE: Merge upstream druntime 0fe7974c.
+ * libdruntime/Makefile.in: Regenerate.
+ * libdruntime/core/thread.d: Import gcc.config.
+ (class Fiber): Add ucontext_t fields when GNU_Enable_CET is true.
+ * libdruntime/gcc/config.d.in (GNU_Enable_CET): Define.
+ * src/Makefile.in: Regenerate.
+ * testsuite/Makefile.in: Regenerate.
+
+2020-11-27 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * libdruntime/MERGE: Merge upstream druntime d37ef985.
+ * libdruntime/Makefile.am (DRUNTIME_DSOURCES_FREEBSD): Add
+ core/sys/freebsd/config.d
+ * libdruntime/Makefile.in: Regenerate.
+
+2020-11-27 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * src/MERGE: Merge upstream phobos 38873fe6e.
+
+2020-11-27 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * libdruntime/MERGE: Merge upstream druntime 5e4492c4.
+
+2020-11-18 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * configure.tgt: Add *-*-dragonfly* as a supported target.
+ * configure: Regenerate.
+ * m4/druntime/os.m4 (DRUNTIME_OS_SOURCES): Add dragonfly* as a posix
+ target.
+
+2020-11-18 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * src/MERGE: Merge upstream phobos 7948e0967.
+
+2020-11-13 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * configure: Regenerate.
+ * configure.ac (libtool_VERSION): Update to 2:0.0.
+
2020-10-27 Iain Buclaw <ibuclaw@gdcproject.org>
* libdruntime/MERGE: Merge upstream druntime 58560d51.
diff --git a/libphobos/Makefile.in b/libphobos/Makefile.in
index f692b2f..a139592 100644
--- a/libphobos/Makefile.in
+++ b/libphobos/Makefile.in
@@ -217,6 +217,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DCFG_ARM_EABI_UNWINDER = @DCFG_ARM_EABI_UNWINDER@
DCFG_DLPI_TLS_MODID = @DCFG_DLPI_TLS_MODID@
+DCFG_ENABLE_CET = @DCFG_ENABLE_CET@
DCFG_HAVE_64BIT_ATOMICS = @DCFG_HAVE_64BIT_ATOMICS@
DCFG_HAVE_ATOMIC_BUILTINS = @DCFG_HAVE_ATOMIC_BUILTINS@
DCFG_HAVE_LIBATOMIC = @DCFG_HAVE_LIBATOMIC@
diff --git a/libphobos/configure b/libphobos/configure
index 4c1116d..77a3125 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -722,6 +722,7 @@ LIBTOOL
CFLAGS_FOR_BUILD
CC_FOR_BUILD
AR
+DCFG_ENABLE_CET
CET_DFLAGS
CET_FLAGS
RANLIB
@@ -5652,11 +5653,20 @@ fi
# To ensure that runtime code for CET is compiled in, add in D version flags.
-if test "$enable_cet" = yes; then
+if test x$enable_cet = xyes; then :
+
CET_DFLAGS="$CET_FLAGS -fversion=CET"
+ DCFG_ENABLE_CET=true
+
+else
+
+ CET_DFLAGS=
+ DCFG_ENABLE_CET=false
fi
+
+
# This should be inherited in the recursive make, but ensure it is defined.
test "$AR" || AR=ar
@@ -11744,7 +11754,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11747 "configure"
+#line 11757 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11850,7 +11860,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11853 "configure"
+#line 11863 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -14283,7 +14293,7 @@ fi
druntime_target_posix="no"
case "$druntime_cv_target_os" in
- aix*|*bsd*|cygwin*|darwin*|gnu*|linux*|skyos*|*solaris*|sysv*)
+ aix*|*bsd*|cygwin*|darwin*|dragonfly*|gnu*|linux*|skyos*|*solaris*|sysv*)
druntime_target_posix="yes"
;;
esac
@@ -15501,7 +15511,7 @@ SPEC_PHOBOS_DEPS="$LIBS"
# Libdruntime / phobos soname version
-libtool_VERSION=1:0:0
+libtool_VERSION=2:0:0
# Set default flags (after DRUNTIME_WERROR!)
diff --git a/libphobos/configure.ac b/libphobos/configure.ac
index bf21128..2d51e46 100644
--- a/libphobos/configure.ac
+++ b/libphobos/configure.ac
@@ -69,10 +69,15 @@ AC_PROG_MAKE_SET
GCC_CET_FLAGS(CET_FLAGS)
AC_SUBST(CET_FLAGS)
# To ensure that runtime code for CET is compiled in, add in D version flags.
-if test "$enable_cet" = yes; then
+AS_IF([test x$enable_cet = xyes], [
CET_DFLAGS="$CET_FLAGS -fversion=CET"
- AC_SUBST(CET_DFLAGS)
-fi
+ DCFG_ENABLE_CET=true
+], [
+ CET_DFLAGS=
+ DCFG_ENABLE_CET=false
+])
+AC_SUBST(CET_DFLAGS)
+AC_SUBST(DCFG_ENABLE_CET)
# This should be inherited in the recursive make, but ensure it is defined.
test "$AR" || AR=ar
@@ -256,7 +261,7 @@ SPEC_PHOBOS_DEPS="$LIBS"
AC_SUBST(SPEC_PHOBOS_DEPS)
# Libdruntime / phobos soname version
-libtool_VERSION=1:0:0
+libtool_VERSION=2:0:0
AC_SUBST(libtool_VERSION)
# Set default flags (after DRUNTIME_WERROR!)
diff --git a/libphobos/configure.tgt b/libphobos/configure.tgt
index 94e42bf..7d9c6bc 100644
--- a/libphobos/configure.tgt
+++ b/libphobos/configure.tgt
@@ -24,6 +24,9 @@
LIBPHOBOS_SUPPORTED=no
LIBDRUNTIME_ONLY=auto
case "${target}" in
+ *-*-dragonfly*)
+ LIBPHOBOS_SUPPORTED=yes
+ ;;
aarch64*-*-linux*)
LIBPHOBOS_SUPPORTED=yes
;;
@@ -46,6 +49,9 @@ case "${target}" in
s390*-linux*)
LIBPHOBOS_SUPPORTED=yes
;;
+ x86_64-*-freebsd* | i?86-*-freebsd*)
+ LIBPHOBOS_SUPPORTED=yes
+ ;;
x86_64-*-kfreebsd*-gnu | i?86-*-kfreebsd*-gnu)
LIBPHOBOS_SUPPORTED=yes
;;
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 485f8e9..7162844 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-58560d5163381b0f1c893bd0d035b7a0a1631f92
+0fe7974cf53b75db59461de2a3d6e53ce933d297
The first line of this file holds the git revision number of the last
merge done from the dlang/druntime repository.
diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 4136642..4798bdf 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -237,16 +237,16 @@ DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
core/sys/dragonflybsd/sys/mman.d core/sys/dragonflybsd/sys/socket.d \
core/sys/dragonflybsd/time.d
-DRUNTIME_DSOURCES_FREEBSD = core/sys/freebsd/dlfcn.d \
- core/sys/freebsd/execinfo.d core/sys/freebsd/netinet/in_.d \
- core/sys/freebsd/pthread_np.d core/sys/freebsd/string.d \
- core/sys/freebsd/sys/_bitset.d core/sys/freebsd/sys/_cpuset.d \
- core/sys/freebsd/sys/cdefs.d core/sys/freebsd/sys/elf.d \
- core/sys/freebsd/sys/elf32.d core/sys/freebsd/sys/elf64.d \
- core/sys/freebsd/sys/elf_common.d core/sys/freebsd/sys/event.d \
- core/sys/freebsd/sys/link_elf.d core/sys/freebsd/sys/mman.d \
- core/sys/freebsd/sys/mount.d core/sys/freebsd/time.d \
- core/sys/freebsd/unistd.d
+DRUNTIME_DSOURCES_FREEBSD = core/sys/freebsd/config.d \
+ core/sys/freebsd/dlfcn.d core/sys/freebsd/execinfo.d \
+ core/sys/freebsd/netinet/in_.d core/sys/freebsd/pthread_np.d \
+ core/sys/freebsd/string.d core/sys/freebsd/sys/_bitset.d \
+ core/sys/freebsd/sys/_cpuset.d core/sys/freebsd/sys/cdefs.d \
+ core/sys/freebsd/sys/elf.d core/sys/freebsd/sys/elf32.d \
+ core/sys/freebsd/sys/elf64.d core/sys/freebsd/sys/elf_common.d \
+ core/sys/freebsd/sys/event.d core/sys/freebsd/sys/link_elf.d \
+ core/sys/freebsd/sys/mman.d core/sys/freebsd/sys/mount.d \
+ core/sys/freebsd/time.d core/sys/freebsd/unistd.d
DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \
core/sys/linux/dlfcn.d core/sys/linux/elf.d core/sys/linux/epoll.d \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index d0bb324..99ee8b9 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -299,7 +299,7 @@ am__objects_7 = core/sys/dragonflybsd/dlfcn.lo \
am__objects_9 = core/sys/bionic/fcntl.lo core/sys/bionic/string.lo \
core/sys/bionic/unistd.lo
@DRUNTIME_OS_ANDROID_TRUE@am__objects_10 = $(am__objects_9)
-am__objects_11 = core/sys/freebsd/dlfcn.lo \
+am__objects_11 = core/sys/freebsd/config.lo core/sys/freebsd/dlfcn.lo \
core/sys/freebsd/execinfo.lo core/sys/freebsd/netinet/in_.lo \
core/sys/freebsd/pthread_np.lo core/sys/freebsd/string.lo \
core/sys/freebsd/sys/_bitset.lo \
@@ -577,6 +577,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DCFG_ARM_EABI_UNWINDER = @DCFG_ARM_EABI_UNWINDER@
DCFG_DLPI_TLS_MODID = @DCFG_DLPI_TLS_MODID@
+DCFG_ENABLE_CET = @DCFG_ENABLE_CET@
DCFG_HAVE_64BIT_ATOMICS = @DCFG_HAVE_64BIT_ATOMICS@
DCFG_HAVE_ATOMIC_BUILTINS = @DCFG_HAVE_ATOMIC_BUILTINS@
DCFG_HAVE_LIBATOMIC = @DCFG_HAVE_LIBATOMIC@
@@ -861,16 +862,16 @@ DRUNTIME_DSOURCES_DRAGONFLYBSD = core/sys/dragonflybsd/dlfcn.d \
core/sys/dragonflybsd/sys/mman.d core/sys/dragonflybsd/sys/socket.d \
core/sys/dragonflybsd/time.d
-DRUNTIME_DSOURCES_FREEBSD = core/sys/freebsd/dlfcn.d \
- core/sys/freebsd/execinfo.d core/sys/freebsd/netinet/in_.d \
- core/sys/freebsd/pthread_np.d core/sys/freebsd/string.d \
- core/sys/freebsd/sys/_bitset.d core/sys/freebsd/sys/_cpuset.d \
- core/sys/freebsd/sys/cdefs.d core/sys/freebsd/sys/elf.d \
- core/sys/freebsd/sys/elf32.d core/sys/freebsd/sys/elf64.d \
- core/sys/freebsd/sys/elf_common.d core/sys/freebsd/sys/event.d \
- core/sys/freebsd/sys/link_elf.d core/sys/freebsd/sys/mman.d \
- core/sys/freebsd/sys/mount.d core/sys/freebsd/time.d \
- core/sys/freebsd/unistd.d
+DRUNTIME_DSOURCES_FREEBSD = core/sys/freebsd/config.d \
+ core/sys/freebsd/dlfcn.d core/sys/freebsd/execinfo.d \
+ core/sys/freebsd/netinet/in_.d core/sys/freebsd/pthread_np.d \
+ core/sys/freebsd/string.d core/sys/freebsd/sys/_bitset.d \
+ core/sys/freebsd/sys/_cpuset.d core/sys/freebsd/sys/cdefs.d \
+ core/sys/freebsd/sys/elf.d core/sys/freebsd/sys/elf32.d \
+ core/sys/freebsd/sys/elf64.d core/sys/freebsd/sys/elf_common.d \
+ core/sys/freebsd/sys/event.d core/sys/freebsd/sys/link_elf.d \
+ core/sys/freebsd/sys/mman.d core/sys/freebsd/sys/mount.d \
+ core/sys/freebsd/time.d core/sys/freebsd/unistd.d
DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \
core/sys/linux/dlfcn.d core/sys/linux/elf.d core/sys/linux/epoll.d \
@@ -1435,6 +1436,7 @@ core/sys/bionic/unistd.lo: core/sys/bionic/$(am__dirstamp)
core/sys/freebsd/$(am__dirstamp):
@$(MKDIR_P) core/sys/freebsd
@: > core/sys/freebsd/$(am__dirstamp)
+core/sys/freebsd/config.lo: core/sys/freebsd/$(am__dirstamp)
core/sys/freebsd/dlfcn.lo: core/sys/freebsd/$(am__dirstamp)
core/sys/freebsd/execinfo.lo: core/sys/freebsd/$(am__dirstamp)
core/sys/freebsd/netinet/$(am__dirstamp):
diff --git a/libphobos/libdruntime/core/demangle.d b/libphobos/libdruntime/core/demangle.d
index 86cfcad..4458b70 100644
--- a/libphobos/libdruntime/core/demangle.d
+++ b/libphobos/libdruntime/core/demangle.d
@@ -1009,7 +1009,6 @@ pure @safe:
F // D
U // C
W // Windows
- V // Pascal
R // C++
FuncAttrs:
@@ -1089,10 +1088,6 @@ pure @safe:
popFront();
put( "extern (Windows) " );
break;
- case 'V': // Pascal
- popFront();
- put( "extern (Pascal) " );
- break;
case 'R': // C++
popFront();
put( "extern (C++) " );
@@ -2380,15 +2375,14 @@ private template isExternCPP(FT) if (is(FT == function))
private template hasPlainMangling(FT) if (is(FT == function))
{
enum lnk = __traits(getLinkage, FT);
- // C || Pascal || Windows
- enum hasPlainMangling = lnk == "C" || lnk == "Pascal" || lnk == "Windows";
+ // C || Windows
+ enum hasPlainMangling = lnk == "C" || lnk == "Windows";
}
@safe pure nothrow unittest
{
static extern(D) void fooD();
static extern(C) void fooC();
- static extern(Pascal) void fooP();
static extern(Windows) void fooW();
static extern(C++) void fooCPP();
@@ -2399,13 +2393,11 @@ private template hasPlainMangling(FT) if (is(FT == function))
}
static assert(check!(typeof(fooD))(true, false, false));
static assert(check!(typeof(fooC))(false, false, true));
- static assert(check!(typeof(fooP))(false, false, true));
static assert(check!(typeof(fooW))(false, false, true));
static assert(check!(typeof(fooCPP))(false, true, false));
static assert(__traits(compiles, mangleFunc!(typeof(&fooD))("")));
static assert(__traits(compiles, mangleFunc!(typeof(&fooC))("")));
- static assert(__traits(compiles, mangleFunc!(typeof(&fooP))("")));
static assert(__traits(compiles, mangleFunc!(typeof(&fooW))("")));
static assert(!__traits(compiles, mangleFunc!(typeof(&fooCPP))("")));
}
@@ -2505,7 +2497,8 @@ version (unittest)
"pure @safe void testexpansion.s!(testexpansion.s!(int).s(int).Result).s(testexpansion.s!(int).s(int).Result).Result.foo()"],
["_D13testexpansion__T1sTSQw__TQjTiZQoFiZ6ResultZQBbFQBcZQq3fooMFNaNfZv",
"pure @safe void testexpansion.s!(testexpansion.s!(int).s(int).Result).s(testexpansion.s!(int).s(int).Result).Result.foo()"],
- // ambiguity on 'V', template value argument or pascal function
+ // formerly ambiguous on 'V', template value argument or pascal function
+ // pascal functions have now been removed (in v2.095.0)
["_D3std4conv__T7enumRepTyAaTEQBa12experimental9allocator15building_blocks15stats_collector7OptionsVQCti64ZQDnyQDh",
"immutable(char[]) std.conv.enumRep!(immutable(char[]), std.experimental.allocator.building_blocks.stats_collector.Options, 64).enumRep"],
// symbol back reference to location with symbol back reference
diff --git a/libphobos/libdruntime/core/internal/convert.d b/libphobos/libdruntime/core/internal/convert.d
index 8010ad7..d922049 100644
--- a/libphobos/libdruntime/core/internal/convert.d
+++ b/libphobos/libdruntime/core/internal/convert.d
@@ -39,7 +39,7 @@ const(ubyte)[] toUbyte(T)(const ref T val) if (is(Unqual!T == float) || is(Unqua
{
if (__ctfe)
{
- static if (T.mant_dig == float.mant_dig || T.mant_dig == double.mant_dig)
+ static if (floatFormat!T == FloatFormat.Float || floatFormat!T == FloatFormat.Double)
{
static if (is(T : ireal)) // https://issues.dlang.org/show_bug.cgi?id=19932
const f = val.im;
@@ -628,7 +628,14 @@ template floatFormat(T) if (is(T:real) || is(T:ireal))
static if (T.mant_dig == 24)
enum floatFormat = FloatFormat.Float;
else static if (T.mant_dig == 53)
- enum floatFormat = FloatFormat.Double;
+ {
+ // Double precision, or real == double
+ static if (T.sizeof == double.sizeof)
+ enum floatFormat = FloatFormat.Double;
+ // 80-bit real with rounding precision set to 53 bits.
+ else static if (T.sizeof == real.sizeof)
+ enum floatFormat = FloatFormat.Real80;
+ }
else static if (T.mant_dig == 64)
enum floatFormat = FloatFormat.Real80;
else static if (T.mant_dig == 106)
diff --git a/libphobos/libdruntime/core/math.d b/libphobos/libdruntime/core/math.d
index 219b426..4d46b67 100644
--- a/libphobos/libdruntime/core/math.d
+++ b/libphobos/libdruntime/core/math.d
@@ -1,4 +1,4 @@
-// Written in the D programming language.
+// Written in the D programming language.
/**
* Builtin mathematical intrinsics
@@ -19,15 +19,26 @@
* GT = &gt;
*
* Copyright: Copyright Digital Mars 2000 - 2011.
- * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
- * Authors: $(WEB digitalmars.com, Walter Bright),
+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
+ * Authors: $(HTTP digitalmars.com, Walter Bright),
* Don Clugston
*/
module core.math;
public:
@nogc:
+nothrow:
+@safe:
+/*****************************************
+ * Returns x rounded to a long value using the FE_TONEAREST rounding mode.
+ * If the integer value of x is
+ * greater than long.max, the result is
+ * indeterminate.
+ */
+extern (C) real rndtonl(real x);
+
+pure:
/***********************************
* Returns cosine of x. x is in radians.
*
@@ -40,7 +51,9 @@ public:
* Results are undefined if |x| >= $(POWER 2,64).
*/
-real cos(real x) @safe pure nothrow; /* intrinsic */
+float cos(float x); /* intrinsic */
+double cos(double x); /* intrinsic */ /// ditto
+real cos(real x); /* intrinsic */ /// ditto
/***********************************
* Returns sine of x. x is in radians.
@@ -55,7 +68,9 @@ real cos(real x) @safe pure nothrow; /* intrinsic */
* Results are undefined if |x| >= $(POWER 2,64).
*/
-real sin(real x) @safe pure nothrow; /* intrinsic */
+float sin(float x); /* intrinsic */
+double sin(double x); /* intrinsic */ /// ditto
+real sin(real x); /* intrinsic */ /// ditto
/*****************************************
* Returns x rounded to a long value using the current rounding mode.
@@ -63,16 +78,10 @@ real sin(real x) @safe pure nothrow; /* intrinsic */
* greater than long.max, the result is
* indeterminate.
*/
-long rndtol(real x) @safe pure nothrow; /* intrinsic */
-
-/*****************************************
- * Returns x rounded to a long value using the FE_TONEAREST rounding mode.
- * If the integer value of x is
- * greater than long.max, the result is
- * indeterminate.
- */
-extern (C) real rndtonl(real x);
+long rndtol(float x); /* intrinsic */
+long rndtol(double x); /* intrinsic */ /// ditto
+long rndtol(real x); /* intrinsic */ /// ditto
/***************************************
* Compute square root of x.
@@ -85,57 +94,65 @@ extern (C) real rndtonl(real x);
* )
*/
-@safe pure nothrow
-{
- float sqrt(float x); /* intrinsic */
- double sqrt(double x); /* intrinsic */ /// ditto
- real sqrt(real x); /* intrinsic */ /// ditto
-}
+float sqrt(float x); /* intrinsic */
+double sqrt(double x); /* intrinsic */ /// ditto
+real sqrt(real x); /* intrinsic */ /// ditto
/*******************************************
* Compute n * 2$(SUPERSCRIPT exp)
* References: frexp
*/
-real ldexp(real n, int exp) @safe pure nothrow; /* intrinsic */
+float ldexp(float n, int exp); /* intrinsic */
+double ldexp(double n, int exp); /* intrinsic */ /// ditto
+real ldexp(real n, int exp); /* intrinsic */ /// ditto
unittest {
static if (real.mant_dig == 113)
{
- assert(ldexp(1, -16384) == 0x1p-16384L);
- assert(ldexp(1, -16382) == 0x1p-16382L);
+ assert(ldexp(1.0L, -16384) == 0x1p-16384L);
+ assert(ldexp(1.0L, -16382) == 0x1p-16382L);
}
else static if (real.mant_dig == 106)
{
- assert(ldexp(1, 1023) == 0x1p1023L);
- assert(ldexp(1, -1022) == 0x1p-1022L);
- assert(ldexp(1, -1021) == 0x1p-1021L);
+ assert(ldexp(1.0L, 1023) == 0x1p1023L);
+ assert(ldexp(1.0L, -1022) == 0x1p-1022L);
+ assert(ldexp(1.0L, -1021) == 0x1p-1021L);
}
else static if (real.mant_dig == 64)
{
- assert(ldexp(1, -16384) == 0x1p-16384L);
- assert(ldexp(1, -16382) == 0x1p-16382L);
+ assert(ldexp(1.0L, -16384) == 0x1p-16384L);
+ assert(ldexp(1.0L, -16382) == 0x1p-16382L);
}
else static if (real.mant_dig == 53)
{
- assert(ldexp(1, 1023) == 0x1p1023L);
- assert(ldexp(1, -1022) == 0x1p-1022L);
- assert(ldexp(1, -1021) == 0x1p-1021L);
+ assert(ldexp(1.0L, 1023) == 0x1p1023L);
+ assert(ldexp(1.0L, -1022) == 0x1p-1022L);
+ assert(ldexp(1.0L, -1021) == 0x1p-1021L);
}
else
assert(false, "Only 128bit, 80bit and 64bit reals expected here");
}
/*******************************
- * Returns |x|
- *
+ * Compute the absolute value.
* $(TABLE_SV
* $(TR $(TH x) $(TH fabs(x)))
* $(TR $(TD $(PLUSMN)0.0) $(TD +0.0) )
* $(TR $(TD $(PLUSMN)$(INFIN)) $(TD +$(INFIN)) )
* )
+ * It is implemented as a compiler intrinsic.
+ * Params:
+ * x = floating point value
+ * Returns: |x|
+ * References: equivalent to `std.math.fabs`
*/
-real fabs(real x) @safe pure nothrow; /* intrinsic */
+@safe pure nothrow @nogc
+{
+ float fabs(float x);
+ double fabs(double x); /// ditto
+ real fabs(real x); /// ditto
+}
/**********************************
* Rounds x to the nearest integer value, using the current rounding
@@ -145,22 +162,29 @@ real fabs(real x) @safe pure nothrow; /* intrinsic */
* $(B nearbyint) performs
* the same operation, but does not set the FE_INEXACT exception.
*/
-real rint(real x) @safe pure nothrow; /* intrinsic */
+float rint(float x); /* intrinsic */
+double rint(double x); /* intrinsic */ /// ditto
+real rint(real x); /* intrinsic */ /// ditto
/***********************************
* Building block functions, they
* translate to a single x87 instruction.
*/
-
-real yl2x(real x, real y) @safe pure nothrow; // y * log2(x)
-real yl2xp1(real x, real y) @safe pure nothrow; // y * log2(x + 1)
+// y * log2(x)
+float yl2x(float x, float y); /* intrinsic */
+double yl2x(double x, double y); /* intrinsic */ /// ditto
+real yl2x(real x, real y); /* intrinsic */ /// ditto
+// y * log2(x +1)
+float yl2xp1(float x, float y); /* intrinsic */
+double yl2xp1(double x, double y); /* intrinsic */ /// ditto
+real yl2xp1(real x, real y); /* intrinsic */ /// ditto
unittest
{
version (INLINE_YL2X)
{
- assert(yl2x(1024, 1) == 10);
- assert(yl2xp1(1023, 1) == 10);
+ assert(yl2x(1024.0L, 1) == 10);
+ assert(yl2xp1(1023.0L, 1) == 10);
}
}
@@ -179,31 +203,22 @@ unittest
* Returns:
* f in precision of type `T`
*/
-@safe pure nothrow
T toPrec(T:float)(float f) { pragma(inline, false); return f; }
/// ditto
-@safe pure nothrow
T toPrec(T:float)(double f) { pragma(inline, false); return cast(T) f; }
/// ditto
-@safe pure nothrow
T toPrec(T:float)(real f) { pragma(inline, false); return cast(T) f; }
/// ditto
-@safe pure nothrow
T toPrec(T:double)(float f) { pragma(inline, false); return f; }
/// ditto
-@safe pure nothrow
T toPrec(T:double)(double f) { pragma(inline, false); return f; }
/// ditto
-@safe pure nothrow
T toPrec(T:double)(real f) { pragma(inline, false); return cast(T) f; }
/// ditto
-@safe pure nothrow
T toPrec(T:real)(float f) { pragma(inline, false); return f; }
/// ditto
-@safe pure nothrow
T toPrec(T:real)(double f) { pragma(inline, false); return f; }
/// ditto
-@safe pure nothrow
T toPrec(T:real)(real f) { pragma(inline, false); return f; }
@safe unittest
diff --git a/libphobos/libdruntime/core/sys/freebsd/config.d b/libphobos/libdruntime/core/sys/freebsd/config.d
new file mode 100644
index 0000000..4eda066
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/freebsd/config.d
@@ -0,0 +1,24 @@
+/**
+ * D header file for FreeBSD
+ *
+ * Authors: Iain Buclaw
+ */
+module core.sys.freebsd.config;
+
+version (FreeBSD):
+
+public import core.sys.posix.config;
+
+// https://svnweb.freebsd.org/base/head/sys/sys/param.h?view=markup
+// __FreeBSD_version numbers are documented in the Porter's Handbook.
+// NOTE: When adding newer versions of FreeBSD, verify all current versioned
+// bindings are still compatible with the release.
+ version (FreeBSD_12) enum __FreeBSD_version = 1202000;
+else version (FreeBSD_11) enum __FreeBSD_version = 1104000;
+else version (FreeBSD_10) enum __FreeBSD_version = 1004000;
+else version (FreeBSD_9) enum __FreeBSD_version = 903000;
+else version (FreeBSD_8) enum __FreeBSD_version = 804000;
+else static assert(false, "Unsupported version of FreeBSD");
+
+// First version of FreeBSD to support 64-bit stat buffer.
+enum INO64_FIRST = 1200031;
diff --git a/libphobos/libdruntime/core/sys/freebsd/sys/event.d b/libphobos/libdruntime/core/sys/freebsd/sys/event.d
index 2ae10b3..8ac7c3b 100644
--- a/libphobos/libdruntime/core/sys/freebsd/sys/event.d
+++ b/libphobos/libdruntime/core/sys/freebsd/sys/event.d
@@ -18,6 +18,7 @@ extern (C):
nothrow:
@nogc:
+import core.sys.freebsd.config;
import core.stdc.stdint; // intptr_t, uintptr_t
import core.sys.posix.time; // timespec
@@ -38,19 +39,35 @@ enum
EVFILT_SYSCOUNT = 11,
}
-extern(D) void EV_SET(kevent_t* kevp, typeof(kevent_t.tupleof) args)
+static if (__FreeBSD_version >= 1200000)
{
- *kevp = kevent_t(args);
+ struct kevent_t
+ {
+ uintptr_t ident;
+ short filter;
+ ushort flags;
+ uint fflags;
+ long data;
+ void* udata;
+ ulong[4] ext;
+ }
+}
+else
+{
+ struct kevent_t
+ {
+ uintptr_t ident; /* identifier for this event */
+ short filter; /* filter for event */
+ ushort flags;
+ uint fflags;
+ intptr_t data;
+ void *udata; /* opaque user data identifier */
+ }
}
-struct kevent_t
+extern(D) void EV_SET(kevent_t* kevp, typeof(kevent_t.tupleof) args)
{
- uintptr_t ident; /* identifier for this event */
- short filter; /* filter for event */
- ushort flags;
- uint fflags;
- intptr_t data;
- void *udata; /* opaque user data identifier */
+ *kevp = kevent_t(args);
}
enum
diff --git a/libphobos/libdruntime/core/sys/freebsd/sys/mount.d b/libphobos/libdruntime/core/sys/freebsd/sys/mount.d
index 66c69a4..e45c460 100644
--- a/libphobos/libdruntime/core/sys/freebsd/sys/mount.d
+++ b/libphobos/libdruntime/core/sys/freebsd/sys/mount.d
@@ -11,6 +11,7 @@ module core.sys.freebsd.sys.mount;
version (FreeBSD):
+import core.sys.freebsd.config;
import core.stdc.config : c_long;
import core.sys.posix.sys.stat : stat_t;
import core.sys.posix.sys.types : uid_t;
@@ -32,8 +33,17 @@ struct fid
}
enum MFSNAMELEN = 16;
-enum MNAMELEN = 88;
-enum STATFS_VERSION = 0x20030518;
+
+static if (__FreeBSD_version >= 1200000)
+{
+ enum MNAMELEN = 1024;
+ enum STATFS_VERSION = 0x20140518;
+}
+else
+{
+ enum MNAMELEN = 88;
+ enum STATFS_VERSION = 0x20030518;
+}
struct statfs_t
{
diff --git a/libphobos/libdruntime/core/sys/posix/dirent.d b/libphobos/libdruntime/core/sys/posix/dirent.d
index cea22d2..b12d6b1 100644
--- a/libphobos/libdruntime/core/sys/posix/dirent.d
+++ b/libphobos/libdruntime/core/sys/posix/dirent.d
@@ -135,6 +135,8 @@ else version (Darwin)
}
else version (FreeBSD)
{
+ import core.sys.freebsd.config;
+
// https://github.com/freebsd/freebsd/blob/master/sys/sys/dirent.h
enum
{
@@ -149,14 +151,31 @@ else version (FreeBSD)
DT_WHT = 14
}
- align(4)
- struct dirent
+ static if (__FreeBSD_version >= 1200000)
{
- uint d_fileno;
- ushort d_reclen;
- ubyte d_type;
- ubyte d_namlen;
- char[256] d_name = 0;
+ struct dirent
+ {
+ ino_t d_fileno;
+ off_t d_off;
+ ushort d_reclen;
+ ubyte d_type;
+ ubyte d_pad0;
+ ushort d_namlen;
+ ushort d_pad1;
+ char[256] d_name = 0;
+ }
+ }
+ else
+ {
+ align(4)
+ struct dirent
+ {
+ uint d_fileno;
+ ushort d_reclen;
+ ubyte d_type;
+ ubyte d_namlen;
+ char[256] d_name = 0;
+ }
}
alias void* DIR;
diff --git a/libphobos/libdruntime/core/sys/posix/sys/stat.d b/libphobos/libdruntime/core/sys/posix/sys/stat.d
index b154e14..35b1f1c 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/stat.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/stat.d
@@ -1060,36 +1060,82 @@ else version (Darwin)
}
else version (FreeBSD)
{
- // https://github.com/freebsd/freebsd/blob/master/sys/sys/stat.h
+ import core.sys.freebsd.config;
- struct stat_t
+ // https://github.com/freebsd/freebsd/blob/master/sys/sys/stat.h
+ static if (__FreeBSD_version >= INO64_FIRST)
{
- dev_t st_dev;
- ino_t st_ino;
- mode_t st_mode;
- nlink_t st_nlink;
- uid_t st_uid;
- gid_t st_gid;
- dev_t st_rdev;
+ struct stat_t
+ {
+ dev_t st_dev;
+ ino_t st_ino;
+ nlink_t st_nlink;
+ mode_t st_mode;
+ short st_padding0;
+ uid_t st_uid;
+ gid_t st_gid;
+ int st_padding1;
+ dev_t st_rdev;
- time_t st_atime;
- c_long __st_atimensec;
- time_t st_mtime;
- c_long __st_mtimensec;
- time_t st_ctime;
- c_long __st_ctimensec;
+ version (X86) int st_atim_ext;
+ timespec st_atim;
- off_t st_size;
- blkcnt_t st_blocks;
- blksize_t st_blksize;
- fflags_t st_flags;
- uint st_gen;
- int st_lspare;
+ version (X86) int st_mtim_ext;
+ timespec st_mtim;
+
+ version (X86) int st_ctim_ext;
+ timespec st_ctim;
- time_t st_birthtime;
- c_long st_birthtimensec;
+ version (X86) int st_btim_ext;
+ timespec st_birthtim;
- ubyte[16 - timespec.sizeof] padding;
+ off_t st_size;
+ blkcnt_t st_blocks;
+ blksize_t st_blksize;
+ fflags_t st_flags;
+ ulong st_gen;
+ ulong[10] st_spare;
+
+ extern(D) @safe @property inout pure nothrow
+ {
+ ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
+ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
+ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
+ ref inout(time_t) st_birthtime() return { return st_birthtim.tv_sec; }
+ }
+ }
+ }
+ else
+ {
+ struct stat_t
+ {
+ uint st_dev;
+ uint st_ino;
+ mode_t st_mode;
+ ushort st_nlink;
+ uid_t st_uid;
+ gid_t st_gid;
+ uint st_rdev;
+ timespec st_atim;
+ timespec st_mtim;
+ timespec st_ctim;
+ off_t st_size;
+ blkcnt_t st_blocks;
+ blksize_t st_blksize;
+ fflags_t st_flags;
+ uint st_gen;
+ int st_lspare;
+ timespec st_birthtim;
+ ubyte[16 - timespec.sizeof] padding;
+
+ extern(D) @safe @property inout pure nothrow
+ {
+ ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
+ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
+ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
+ ref inout(time_t) st_birthtime() return { return st_birthtim.tv_sec; }
+ }
+ }
}
enum S_IRUSR = 0x100; // octal 0000400
diff --git a/libphobos/libdruntime/core/sys/posix/sys/types.d b/libphobos/libdruntime/core/sys/posix/sys/types.d
index 451c8b4..2d8ef92 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/types.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/types.d
@@ -168,14 +168,27 @@ else version (Darwin)
}
else version (FreeBSD)
{
+ import core.sys.freebsd.config;
+
// https://github.com/freebsd/freebsd/blob/master/sys/sys/_types.h
alias long blkcnt_t;
alias uint blksize_t;
- alias uint dev_t;
+
+ static if (__FreeBSD_version >= 1200000)
+ {
+ alias ulong dev_t;
+ alias ulong ino_t;
+ alias ulong nlink_t;
+ }
+ else
+ {
+ alias uint dev_t;
+ alias uint ino_t;
+ alias ushort nlink_t;
+ }
+
alias uint gid_t;
- alias uint ino_t;
alias ushort mode_t;
- alias ushort nlink_t;
alias long off_t;
alias int pid_t;
//size_t (defined in core.stdc.stddef)
diff --git a/libphobos/libdruntime/core/sys/posix/ucontext.d b/libphobos/libdruntime/core/sys/posix/ucontext.d
index 49a7c3e..2e518ae 100644
--- a/libphobos/libdruntime/core/sys/posix/ucontext.d
+++ b/libphobos/libdruntime/core/sys/posix/ucontext.d
@@ -114,7 +114,7 @@ version (CRuntime_Glibc)
enum NGREG = 23;
- alias c_long greg_t;
+ alias long greg_t;
alias greg_t[NGREG] gregset_t;
alias _libc_fpstate* fpregset_t;
}
@@ -123,7 +123,7 @@ version (CRuntime_Glibc)
{
gregset_t gregs;
fpregset_t fpregs;
- c_ulong[8] __reserved1;
+ ulong[8] __reserved1;
}
struct ucontext_t
@@ -134,6 +134,7 @@ version (CRuntime_Glibc)
mcontext_t uc_mcontext;
sigset_t uc_sigmask;
_libc_fpstate __fpregs_mem;
+ ulong[4] __ssp;
}
}
else version (X86)
@@ -205,6 +206,7 @@ version (CRuntime_Glibc)
mcontext_t uc_mcontext;
sigset_t uc_sigmask;
_libc_fpstate __fpregs_mem;
+ c_ulong[4] __ssp;
}
}
else version (HPPA)
diff --git a/libphobos/libdruntime/core/thread.d b/libphobos/libdruntime/core/thread.d
index eaf088d..7506a8b 100644
--- a/libphobos/libdruntime/core/thread.d
+++ b/libphobos/libdruntime/core/thread.d
@@ -52,6 +52,7 @@ version (Solaris)
version (GNU)
{
import gcc.builtins;
+ import gcc.config;
version (GNU_StackGrowsDown)
version = StackGrowsDown;
}
@@ -5123,6 +5124,15 @@ private:
ucontext_t m_utxt = void;
ucontext_t* m_ucur = null;
}
+ else static if (GNU_Enable_CET)
+ {
+ // When libphobos was built with --enable-cet, these fields need to
+ // always be present in the Fiber class layout.
+ import core.sys.posix.ucontext;
+ static ucontext_t sm_utxt = void;
+ ucontext_t m_utxt = void;
+ ucontext_t* m_ucur = null;
+ }
private:
diff --git a/libphobos/libdruntime/gcc/config.d.in b/libphobos/libdruntime/gcc/config.d.in
index 6301aaf..9ac7d05 100644
--- a/libphobos/libdruntime/gcc/config.d.in
+++ b/libphobos/libdruntime/gcc/config.d.in
@@ -49,3 +49,6 @@ enum GNU_Have_LibAtomic = @DCFG_HAVE_LIBATOMIC@;
// Do we have qsort_r function
enum Have_Qsort_R = @DCFG_HAVE_QSORT_R@;
+
+// Whether libphobos been configured with --enable-cet.
+enum GNU_Enable_CET = @DCFG_ENABLE_CET@;
diff --git a/libphobos/libdruntime/rt/critical_.d b/libphobos/libdruntime/rt/critical_.d
index 40030ad..15c460a 100644
--- a/libphobos/libdruntime/rt/critical_.d
+++ b/libphobos/libdruntime/rt/critical_.d
@@ -43,7 +43,7 @@ extern (C) void _d_criticalenter2(D_CRITICAL_SECTION** pcs)
lockMutex(cast(Mutex*)&gcs.mtx);
if (atomicLoad!(MemoryOrder.raw)(*cast(shared) pcs) is null)
{
- auto cs = new shared D_CRITICAL_SECTION;
+ auto cs = new shared(D_CRITICAL_SECTION);
initMutex(cast(Mutex*)&cs.mtx);
atomicStore!(MemoryOrder.rel)(*cast(shared) pcs, cs);
}
diff --git a/libphobos/libdruntime/rt/dmain2.d b/libphobos/libdruntime/rt/dmain2.d
index 32635c4..3d5ba29 100644
--- a/libphobos/libdruntime/rt/dmain2.d
+++ b/libphobos/libdruntime/rt/dmain2.d
@@ -9,9 +9,6 @@
* Source: $(DRUNTIMESRC src/rt/_dmain2.d)
*/
-/* NOTE: This file has been patched from the original DMD distribution to
- * work with the GDC compiler.
- */
module rt.dmain2;
private
@@ -340,15 +337,8 @@ extern (C) int _d_run_main(int argc, char **argv, MainFunc mainFunc)
version (CRuntime_Microsoft)
{
// enable full precision for reals
- version (GNU)
+ version (D_InlineAsm_X86_64)
{
- size_t fpu_cw;
- asm { "fstcw %0" : "=m" (fpu_cw); }
- fpu_cw |= 0b11_00_111111; // 11: use 64 bit extended-precision
- // 111111: mask all FP exceptions
- asm { "fldcw %0" : "=m" (fpu_cw); }
- }
- else version (Win64)
asm
{
push RAX;
@@ -358,7 +348,8 @@ extern (C) int _d_run_main(int argc, char **argv, MainFunc mainFunc)
fldcw word ptr [RSP];
pop RAX;
}
- else version (Win32)
+ }
+ else version (D_InlineAsm_X86)
{
asm
{
@@ -455,12 +446,6 @@ extern (C) int _d_run_main(int argc, char **argv, MainFunc mainFunc)
{
if (IsDebuggerPresent())
trapExceptions = false;
- version (GNU)
- {
- /* IsDebuggerPresent doesn't detect GDC. Would be nice to have
- some way of detecting valid console output */
- trapExceptions = true;
- }
}
void tryExec(scope void delegate() dg)
diff --git a/libphobos/m4/druntime/os.m4 b/libphobos/m4/druntime/os.m4
index 47d4c6a..ed93e30 100644
--- a/libphobos/m4/druntime/os.m4
+++ b/libphobos/m4/druntime/os.m4
@@ -112,7 +112,7 @@ AC_DEFUN([DRUNTIME_OS_SOURCES],
druntime_target_posix="no"
case "$druntime_cv_target_os" in
- aix*|*bsd*|cygwin*|darwin*|gnu*|linux*|skyos*|*solaris*|sysv*)
+ aix*|*bsd*|cygwin*|darwin*|dragonfly*|gnu*|linux*|skyos*|*solaris*|sysv*)
druntime_target_posix="yes"
;;
esac
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index 1562f74..cd620c9 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-021ae0df76727a32809a29887095ab7093489ea3
+38873fe6ee70fe8e2b7a41b7c3663e090e27d61b
The first line of this file holds the git revision number of the last
merge done from the dlang/phobos repository.
diff --git a/libphobos/src/Makefile.in b/libphobos/src/Makefile.in
index 4a0612a..2e72178 100644
--- a/libphobos/src/Makefile.in
+++ b/libphobos/src/Makefile.in
@@ -333,6 +333,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DCFG_ARM_EABI_UNWINDER = @DCFG_ARM_EABI_UNWINDER@
DCFG_DLPI_TLS_MODID = @DCFG_DLPI_TLS_MODID@
+DCFG_ENABLE_CET = @DCFG_ENABLE_CET@
DCFG_HAVE_64BIT_ATOMICS = @DCFG_HAVE_64BIT_ATOMICS@
DCFG_HAVE_ATOMIC_BUILTINS = @DCFG_HAVE_ATOMIC_BUILTINS@
DCFG_HAVE_LIBATOMIC = @DCFG_HAVE_LIBATOMIC@
diff --git a/libphobos/src/std/complex.d b/libphobos/src/std/complex.d
index b078051..8e488db 100644
--- a/libphobos/src/std/complex.d
+++ b/libphobos/src/std/complex.d
@@ -832,8 +832,13 @@ Complex!T sin(T)(Complex!T z) @safe pure nothrow @nogc
@safe pure nothrow unittest
{
static import std.math;
+ import std.math : feqrel;
assert(sin(complex(0.0)) == 0.0);
- assert(sin(complex(2.0L, 0)) == std.math.sin(2.0L));
+ assert(sin(complex(2.0, 0)) == std.math.sin(2.0));
+ auto c1 = sin(complex(2.0L, 0));
+ auto c2 = complex(std.math.sin(2.0L), 0);
+ assert(feqrel(c1.re, c2.re) >= real.mant_dig - 1 &&
+ feqrel(c1.im, c2.im) >= real.mant_dig - 1);
}
@@ -849,17 +854,20 @@ Complex!T cos(T)(Complex!T z) @safe pure nothrow @nogc
///
@safe pure nothrow unittest
{
- import std.complex;
- import std.math;
+ static import std.math;
+ import std.math : feqrel;
assert(cos(complex(0.0)) == 1.0);
- assert(cos(complex(1.3L)) == std.math.cos(1.3L));
+ assert(cos(complex(1.3)) == std.math.cos(1.3));
auto c1 = cos(complex(0, 5.2L));
- auto c2 = cosh(5.2L);
+ auto c2 = complex(std.math.cosh(5.2L), 0.0L);
assert(feqrel(c1.re, c2.re) >= real.mant_dig - 1 &&
feqrel(c1.im, c2.im) >= real.mant_dig - 1);
+ auto c3 = cos(complex(1.3L));
+ auto c4 = complex(std.math.cos(1.3L), 0.0L);
+ assert(feqrel(c3.re, c4.re) >= real.mant_dig - 1 &&
+ feqrel(c3.im, c4.im) >= real.mant_dig - 1);
}
-
/**
Params: y = A real number.
Returns: The value of cos(y) + i sin(y).
diff --git a/libphobos/src/std/conv.d b/libphobos/src/std/conv.d
index eaee62f..743d203 100644
--- a/libphobos/src/std/conv.d
+++ b/libphobos/src/std/conv.d
@@ -1629,6 +1629,8 @@ private void testIntegralToFloating(Integral, Floating)()
private void testFloatingToIntegral(Floating, Integral)()
{
+ import std.math : floatTraits, RealFormat;
+
bool convFails(Source, Target, E)(Source src)
{
try
@@ -1660,18 +1662,23 @@ private void testFloatingToIntegral(Floating, Integral)()
{
a = -a; // -Integral.min not representable as an Integral
assert(convFails!(Floating, Integral, ConvOverflowException)(a)
- || Floating.sizeof <= Integral.sizeof);
+ || Floating.sizeof <= Integral.sizeof
+ || floatTraits!Floating.realFormat == RealFormat.ieeeExtended53);
}
a = 0.0 + Integral.min;
assert(to!Integral(a) == Integral.min);
--a; // no more representable as an Integral
assert(convFails!(Floating, Integral, ConvOverflowException)(a)
- || Floating.sizeof <= Integral.sizeof);
+ || Floating.sizeof <= Integral.sizeof
+ || floatTraits!Floating.realFormat == RealFormat.ieeeExtended53);
a = 0.0 + Integral.max;
- assert(to!Integral(a) == Integral.max || Floating.sizeof <= Integral.sizeof);
+ assert(to!Integral(a) == Integral.max
+ || Floating.sizeof <= Integral.sizeof
+ || floatTraits!Floating.realFormat == RealFormat.ieeeExtended53);
++a; // no more representable as an Integral
assert(convFails!(Floating, Integral, ConvOverflowException)(a)
- || Floating.sizeof <= Integral.sizeof);
+ || Floating.sizeof <= Integral.sizeof
+ || floatTraits!Floating.realFormat == RealFormat.ieeeExtended53);
// convert a value with a fractional part
a = 3.14;
assert(to!Integral(a) == 3);
@@ -3016,7 +3023,9 @@ if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum
@system unittest
{
// @system because strtod is not @safe.
- static if (real.mant_dig == 53)
+ import std.math : floatTraits, RealFormat;
+
+ static if (floatTraits!real.realFormat == RealFormat.ieeeDouble)
{
import core.stdc.stdlib, std.exception, std.math;
@@ -3099,7 +3108,8 @@ if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum
{
ushort[8] value;
}
- else static if (floatTraits!real.realFormat == RealFormat.ieeeExtended)
+ else static if (floatTraits!real.realFormat == RealFormat.ieeeExtended ||
+ floatTraits!real.realFormat == RealFormat.ieeeExtended53)
{
ushort[5] value;
}
@@ -3122,6 +3132,8 @@ if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum
enum s = "0x1.FFFFFFFFFFFFFFFEp-16382";
else static if (floatTraits!real.realFormat == RealFormat.ieeeExtended)
enum s = "0x1.FFFFFFFFFFFFFFFEp-16382";
+ else static if (floatTraits!real.realFormat == RealFormat.ieeeExtended53)
+ enum s = "0x1.FFFFFFFFFFFFFFFEp-16382";
else static if (floatTraits!real.realFormat == RealFormat.ieeeDouble)
enum s = "0x1.FFFFFFFFFFFFFFFEp-1000";
else
@@ -3141,6 +3153,8 @@ if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum
else
ld1 = strtold(s.ptr, null);
}
+ else static if (floatTraits!real.realFormat == RealFormat.ieeeExtended53)
+ ld1 = 0x1.FFFFFFFFFFFFFFFEp-16382L; // strtold rounds to 53 bits.
else
ld1 = strtold(s.ptr, null);
diff --git a/libphobos/src/std/internal/math/gammafunction.d b/libphobos/src/std/internal/math/gammafunction.d
index dd20691..c9677c7 100644
--- a/libphobos/src/std/internal/math/gammafunction.d
+++ b/libphobos/src/std/internal/math/gammafunction.d
@@ -253,6 +253,8 @@ static if (floatTraits!(real).realFormat == RealFormat.ieeeQuadruple)
enum real MAXGAMMA = 1755.5483429L;
else static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended)
enum real MAXGAMMA = 1755.5483429L;
+else static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended53)
+ enum real MAXGAMMA = 1755.5483429L;
else static if (floatTraits!(real).realFormat == RealFormat.ieeeDouble)
enum real MAXGAMMA = 171.6243769L;
else
@@ -603,6 +605,11 @@ else static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended)
enum real MAXLOG = 0x1.62e42fefa39ef358p+13L; // log(real.max)
enum real MINLOG = -0x1.6436716d5406e6d8p+13L; // log(real.min_normal*real.epsilon) = log(smallest denormal)
}
+else static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended53)
+{
+ enum real MAXLOG = 0x1.62e42fefa39ef358p+13L; // log(real.max)
+ enum real MINLOG = -0x1.6436716d5406e6d8p+13L; // log(real.min_normal*real.epsilon) = log(smallest denormal)
+}
else static if (floatTraits!(real).realFormat == RealFormat.ieeeDouble)
{
enum real MAXLOG = 0x1.62e42fefa39efp+9L; // log(real.max)
diff --git a/libphobos/src/std/math.d b/libphobos/src/std/math.d
index 5cc3a85..3d18cfa 100644
--- a/libphobos/src/std/math.d
+++ b/libphobos/src/std/math.d
@@ -495,7 +495,8 @@ T floorImpl(T)(const T x) @trusted pure nothrow @nogc
else
int pos = 3;
}
- else static if (F.realFormat == RealFormat.ieeeExtended)
+ else static if (F.realFormat == RealFormat.ieeeExtended ||
+ F.realFormat == RealFormat.ieeeExtended53)
{
int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
@@ -542,7 +543,10 @@ T floorImpl(T)(const T x) @trusted pure nothrow @nogc
}
else
{
- exp = (T.mant_dig - 1) - exp;
+ static if (F.realFormat == RealFormat.ieeeExtended53)
+ exp = (T.mant_dig + 11 - 1) - exp; // mant_dig is really 64
+ else
+ exp = (T.mant_dig - 1) - exp;
// Zero 16 bits at a time.
while (exp >= 16)
@@ -1079,13 +1083,13 @@ Lret: {}
real t = tan(x);
//printf("tan(%Lg) = %Lg, should be %Lg\n", x, t, r);
- if (!isIdentical(r, t)) assert(fabs(r-t) <= .0000001);
+ assert(approxEqual(r, t));
x = -x;
r = -r;
t = tan(x);
//printf("tan(%Lg) = %Lg, should be %Lg\n", x, t, r);
- if (!isIdentical(r, t) && !(r != r && t != t)) assert(fabs(r-t) <= .0000001);
+ assert(approxEqual(r, t));
}
// overflow
assert(isNaN(tan(real.infinity)));
@@ -1150,7 +1154,7 @@ float asin(float x) @safe pure nothrow @nogc { return asin(cast(real) x); }
@system unittest
{
- assert(equalsDigit(asin(0.5), PI / 6, useDigits));
+ assert(asin(0.5).approxEqual(PI / 6));
}
/***************
@@ -1379,7 +1383,7 @@ float atan2(float y, float x) @safe pure nothrow @nogc
@system unittest
{
- assert(equalsDigit(atan2(1.0L, std.math.sqrt(3.0L)), PI / 6, useDigits));
+ assert(atan2(1.0, sqrt(3.0)).approxEqual(PI / 6));
}
/***********************************
@@ -1441,7 +1445,7 @@ float sinh(float x) @safe pure nothrow @nogc { return sinh(cast(real) x); }
@system unittest
{
- assert(equalsDigit(sinh(1.0), (E - 1.0 / E) / 2, useDigits));
+ assert(sinh(1.0).approxEqual((E - 1.0 / E) / 2));
}
/***********************************
@@ -1791,7 +1795,8 @@ real exp(real x) @trusted pure nothrow @nogc
enum real OF = 7.09782712893383996732E2; // ln((1-2^-53) * 2^1024)
enum real UF = -7.451332191019412076235E2; // ln(2^-1075)
}
- else static if (F.realFormat == RealFormat.ieeeExtended)
+ else static if (F.realFormat == RealFormat.ieeeExtended ||
+ F.realFormat == RealFormat.ieeeExtended53)
{
// Coefficients for exp(x)
static immutable real[3] P = [
@@ -1882,7 +1887,7 @@ float exp(float x) @safe pure nothrow @nogc { return exp(cast(real) x); }
@system unittest
{
- assert(equalsDigit(exp(3.0L), E * E * E, useDigits));
+ assert(exp(3.0).feqrel(E * E * E) > 16);
}
/**
@@ -2468,7 +2473,8 @@ private real exp2Impl(real x) @nogc @trusted pure nothrow
ctrl.rounding = FloatingPointControl.roundToNearest;
}
- static if (real.mant_dig == 113)
+ enum realFormat = floatTraits!real.realFormat;
+ static if (realFormat == RealFormat.ieeeQuadruple)
{
static immutable real[2][] exptestpoints =
[ // x exp(x)
@@ -2487,7 +2493,8 @@ private real exp2Impl(real x) @nogc @trusted pure nothrow
[-0x1p+30L, 0 ], // far underflow
];
}
- else static if (real.mant_dig == 64) // 80-bit reals
+ else static if (realFormat == RealFormat.ieeeExtended ||
+ realFormat == RealFormat.ieeeExtended53)
{
static immutable real[2][] exptestpoints =
[ // x exp(x)
@@ -2506,7 +2513,7 @@ private real exp2Impl(real x) @nogc @trusted pure nothrow
[-0x1p+30L, 0 ], // far underflow
];
}
- else static if (real.mant_dig == 53) // 64-bit reals
+ else static if (realFormat == RealFormat.ieeeDouble)
{
static immutable real[2][] exptestpoints =
[ // x, exp(x)
@@ -2527,14 +2534,14 @@ private real exp2Impl(real x) @nogc @trusted pure nothrow
else
static assert(0, "No exp() tests for real type!");
- const minEqualDecimalDigits = real.dig - 3;
+ const minEqualMantissaBits = real.mant_dig - 13;
real x;
version (IeeeFlagsSupport) IeeeFlags f;
foreach (ref pair; exptestpoints)
{
version (IeeeFlagsSupport) resetIeeeFlags();
x = exp(pair[0]);
- assert(equalsDigit(x, pair[1], minEqualDecimalDigits));
+ assert(feqrel(x, pair[1]) >= minEqualMantissaBits);
}
// Ideally, exp(0) would not set the inexact flag.
@@ -2650,7 +2657,8 @@ if (isFloatingPoint!T)
alias F = floatTraits!T;
ex = vu[F.EXPPOS_SHORT] & F.EXPMASK;
- static if (F.realFormat == RealFormat.ieeeExtended)
+ static if (F.realFormat == RealFormat.ieeeExtended ||
+ F.realFormat == RealFormat.ieeeExtended53)
{
if (ex)
{ // If exponent is non-zero
@@ -2938,7 +2946,8 @@ if (isFloatingPoint!T)
y.rv = x;
int ex = y.vu[F.EXPPOS_SHORT] & F.EXPMASK;
- static if (F.realFormat == RealFormat.ieeeExtended)
+ static if (F.realFormat == RealFormat.ieeeExtended ||
+ F.realFormat == RealFormat.ieeeExtended53)
{
if (ex)
{
@@ -3184,6 +3193,7 @@ float ldexp(float n, int exp) @safe pure nothrow @nogc { return ldexp(cast(real)
@safe pure nothrow @nogc unittest
{
static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended ||
+ floatTraits!(real).realFormat == RealFormat.ieeeExtended53 ||
floatTraits!(real).realFormat == RealFormat.ieeeQuadruple)
{
assert(ldexp(1.0L, -16384) == 0x1p-16384L);
@@ -4428,12 +4438,16 @@ long lrint(real x) @trusted pure nothrow @nogc
return sign ? -result : result;
}
- else static if (F.realFormat == RealFormat.ieeeExtended)
+ else static if (F.realFormat == RealFormat.ieeeExtended ||
+ F.realFormat == RealFormat.ieeeExtended53)
{
long result;
// Rounding limit when casting from real(80-bit) to ulong.
- enum real OF = 9.22337203685477580800E18L;
+ static if (F.realFormat == RealFormat.ieeeExtended)
+ enum real OF = 9.22337203685477580800E18L;
+ else
+ enum real OF = 4.50359962737049600000E15L;
ushort* vu = cast(ushort*)(&x);
uint* vi = cast(uint*)(&x);
@@ -5904,7 +5918,8 @@ bool isSubnormal(X)(X x) @trusted pure nothrow @nogc
return (e == 0 &&
((ps[MANTISSA_LSB]|(ps[MANTISSA_MSB]& 0x0000_FFFF_FFFF_FFFF)) != 0));
}
- else static if (F.realFormat == RealFormat.ieeeExtended)
+ else static if (F.realFormat == RealFormat.ieeeExtended ||
+ F.realFormat == RealFormat.ieeeExtended53)
{
ushort* pe = cast(ushort *)&x;
long* ps = cast(long *)&x;
@@ -5954,7 +5969,8 @@ if (isFloatingPoint!(X))
return ((*cast(ulong *)&x) & 0x7FFF_FFFF_FFFF_FFFF)
== 0x7FF0_0000_0000_0000;
}
- else static if (F.realFormat == RealFormat.ieeeExtended)
+ else static if (F.realFormat == RealFormat.ieeeExtended ||
+ F.realFormat == RealFormat.ieeeExtended53)
{
const ushort e = cast(ushort)(F.EXPMASK & (cast(ushort *)&x)[F.EXPPOS_SHORT]);
const ulong ps = *cast(ulong *)&x;
@@ -6217,7 +6233,8 @@ F sgn(F)(F x) @safe pure nothrow @nogc
real NaN(ulong payload) @trusted pure nothrow @nogc
{
alias F = floatTraits!(real);
- static if (F.realFormat == RealFormat.ieeeExtended)
+ static if (F.realFormat == RealFormat.ieeeExtended ||
+ F.realFormat == RealFormat.ieeeExtended53)
{
// real80 (in x86 real format, the implied bit is actually
// not implied but a real bit which is stored in the real)
@@ -6423,11 +6440,14 @@ real nextUp(real x) @trusted pure nothrow @nogc
}
return x;
}
- else static if (F.realFormat == RealFormat.ieeeExtended)
+ else static if (F.realFormat == RealFormat.ieeeExtended ||
+ F.realFormat == RealFormat.ieeeExtended53)
{
// For 80-bit reals, the "implied bit" is a nuisance...
ushort *pe = cast(ushort *)&x;
ulong *ps = cast(ulong *)&x;
+ // EPSILON is 1 for 64-bit, and 2048 for 53-bit precision reals.
+ enum ulong EPSILON = 2UL ^^ (64 - real.mant_dig);
if ((pe[F.EXPPOS_SHORT] & F.EXPMASK) == F.EXPMASK)
{
@@ -6438,7 +6458,7 @@ real nextUp(real x) @trusted pure nothrow @nogc
if (pe[F.EXPPOS_SHORT] & 0x8000)
{
// Negative number -- need to decrease the significand
- --*ps;
+ *ps -= EPSILON;
// Need to mask with 0x7FFF... so subnormals are treated correctly.
if ((*ps & 0x7FFF_FFFF_FFFF_FFFF) == 0x7FFF_FFFF_FFFF_FFFF)
{
@@ -6463,7 +6483,7 @@ real nextUp(real x) @trusted pure nothrow @nogc
{
// Positive number -- need to increase the significand.
// Works automatically for positive zero.
- ++*ps;
+ *ps += EPSILON;
if ((*ps & 0x7FFF_FFFF_FFFF_FFFF) == 0)
{
// change in exponent
@@ -7228,6 +7248,7 @@ if (isFloatingPoint!(X))
static assert(F.realFormat == RealFormat.ieeeSingle
|| F.realFormat == RealFormat.ieeeDouble
|| F.realFormat == RealFormat.ieeeExtended
+ || F.realFormat == RealFormat.ieeeExtended53
|| F.realFormat == RealFormat.ieeeQuadruple);
if (x == y)
@@ -7367,7 +7388,8 @@ body
alias F = floatTraits!(T);
T u;
- static if (F.realFormat == RealFormat.ieeeExtended)
+ static if (F.realFormat == RealFormat.ieeeExtended ||
+ F.realFormat == RealFormat.ieeeExtended53)
{
// There's slight additional complexity because they are actually
// 79-bit reals...
diff --git a/libphobos/src/std/string.d b/libphobos/src/std/string.d
index 5b61cde..1128a09 100644
--- a/libphobos/src/std/string.d
+++ b/libphobos/src/std/string.d
@@ -5174,273 +5174,6 @@ body
assert(buffer.data == "h5 rd");
}
-//@@@DEPRECATED_2.086@@@
-deprecated("This function is obsolete. It is available in https://github.com/dlang/undeaD if necessary.")
-bool inPattern(S)(dchar c, in S pattern) @safe pure @nogc
-if (isSomeString!S)
-{
- bool result = false;
- int range = 0;
- dchar lastc;
-
- foreach (size_t i, dchar p; pattern)
- {
- if (p == '^' && i == 0)
- {
- result = true;
- if (i + 1 == pattern.length)
- return (c == p); // or should this be an error?
- }
- else if (range)
- {
- range = 0;
- if (lastc <= c && c <= p || c == p)
- return !result;
- }
- else if (p == '-' && i > result && i + 1 < pattern.length)
- {
- range = 1;
- continue;
- }
- else if (c == p)
- return !result;
- lastc = p;
- }
- return result;
-}
-
-
-deprecated
-@safe pure @nogc unittest
-{
- import std.conv : to;
- import std.exception : assertCTFEable;
-
- assertCTFEable!(
- {
- assert(inPattern('x', "x") == 1);
- assert(inPattern('x', "y") == 0);
- assert(inPattern('x', string.init) == 0);
- assert(inPattern('x', "^y") == 1);
- assert(inPattern('x', "yxxy") == 1);
- assert(inPattern('x', "^yxxy") == 0);
- assert(inPattern('x', "^abcd") == 1);
- assert(inPattern('^', "^^") == 0);
- assert(inPattern('^', "^") == 1);
- assert(inPattern('^', "a^") == 1);
- assert(inPattern('x', "a-z") == 1);
- assert(inPattern('x', "A-Z") == 0);
- assert(inPattern('x', "^a-z") == 0);
- assert(inPattern('x', "^A-Z") == 1);
- assert(inPattern('-', "a-") == 1);
- assert(inPattern('-', "^A-") == 0);
- assert(inPattern('a', "z-a") == 1);
- assert(inPattern('z', "z-a") == 1);
- assert(inPattern('x', "z-a") == 0);
- });
-}
-
-//@@@DEPRECATED_2.086@@@
-deprecated("This function is obsolete. It is available in https://github.com/dlang/undeaD if necessary.")
-bool inPattern(S)(dchar c, S[] patterns) @safe pure @nogc
-if (isSomeString!S)
-{
- foreach (string pattern; patterns)
- {
- if (!inPattern(c, pattern))
- {
- return false;
- }
- }
- return true;
-}
-
-//@@@DEPRECATED_2.086@@@
-deprecated("This function is obsolete. It is available in https://github.com/dlang/undeaD if necessary.")
-size_t countchars(S, S1)(S s, in S1 pattern) @safe pure @nogc
-if (isSomeString!S && isSomeString!S1)
-{
- size_t count;
- foreach (dchar c; s)
- {
- count += inPattern(c, pattern);
- }
- return count;
-}
-
-deprecated
-@safe pure @nogc unittest
-{
- import std.conv : to;
- import std.exception : assertCTFEable;
-
- assertCTFEable!(
- {
- assert(countchars("abc", "a-c") == 3);
- assert(countchars("hello world", "or") == 3);
- });
-}
-
-//@@@DEPRECATED_2.086@@@
-deprecated("This function is obsolete. It is available in https://github.com/dlang/undeaD if necessary.")
-S removechars(S)(S s, in S pattern) @safe pure
-if (isSomeString!S)
-{
- import std.utf : encode;
-
- Unqual!(typeof(s[0]))[] r;
- bool changed = false;
-
- foreach (size_t i, dchar c; s)
- {
- if (inPattern(c, pattern))
- {
- if (!changed)
- {
- changed = true;
- r = s[0 .. i].dup;
- }
- continue;
- }
- if (changed)
- {
- encode(r, c);
- }
- }
- if (changed)
- return r;
- else
- return s;
-}
-
-deprecated
-@safe pure unittest
-{
- import std.conv : to;
- import std.exception : assertCTFEable;
-
- assertCTFEable!(
- {
- assert(removechars("abc", "a-c").length == 0);
- assert(removechars("hello world", "or") == "hell wld");
- assert(removechars("hello world", "d") == "hello worl");
- assert(removechars("hah", "h") == "a");
- });
-}
-
-deprecated
-@safe pure unittest
-{
- assert(removechars("abc", "x") == "abc");
-}
-
-//@@@DEPRECATED_2.086@@@
-deprecated("This function is obsolete. It is available in https://github.com/dlang/undeaD if necessary.")
-S squeeze(S)(S s, in S pattern = null)
-{
- import std.utf : encode, stride;
-
- Unqual!(typeof(s[0]))[] r;
- dchar lastc;
- size_t lasti;
- int run;
- bool changed;
-
- foreach (size_t i, dchar c; s)
- {
- if (run && lastc == c)
- {
- changed = true;
- }
- else if (pattern is null || inPattern(c, pattern))
- {
- run = 1;
- if (changed)
- {
- if (r is null)
- r = s[0 .. lasti].dup;
- encode(r, c);
- }
- else
- lasti = i + stride(s, i);
- lastc = c;
- }
- else
- {
- run = 0;
- if (changed)
- {
- if (r is null)
- r = s[0 .. lasti].dup;
- encode(r, c);
- }
- }
- }
- return changed ? ((r is null) ? s[0 .. lasti] : cast(S) r) : s;
-}
-
-deprecated
-@system pure unittest
-{
- import std.conv : to;
- import std.exception : assertCTFEable;
-
- assertCTFEable!(
- {
- string s;
-
- assert(squeeze("hello") == "helo");
-
- s = "abcd";
- assert(squeeze(s) is s);
- s = "xyzz";
- assert(squeeze(s).ptr == s.ptr); // should just be a slice
-
- assert(squeeze("hello goodbyee", "oe") == "hello godbye");
- });
-}
-
-//@@@DEPRECATED_2.086@@@
-deprecated("This function is obsolete. It is available in https://github.com/dlang/undeaD if necessary.")
-S1 munch(S1, S2)(ref S1 s, S2 pattern) @safe pure @nogc
-{
- size_t j = s.length;
- foreach (i, dchar c; s)
- {
- if (!inPattern(c, pattern))
- {
- j = i;
- break;
- }
- }
- scope(exit) s = s[j .. $];
- return s[0 .. j];
-}
-
-///
-deprecated
-@safe pure @nogc unittest
-{
- string s = "123abc";
- string t = munch(s, "0123456789");
- assert(t == "123" && s == "abc");
- t = munch(s, "0123456789");
- assert(t == "" && s == "abc");
-}
-
-deprecated
-@safe pure @nogc unittest
-{
- string s = "123€abc";
- string t = munch(s, "0123456789");
- assert(t == "123" && s == "€abc");
- t = munch(s, "0123456789");
- assert(t == "" && s == "€abc");
- t = munch(s, "£$€¥");
- assert(t == "€" && s == "abc");
-}
-
-
/**********************************************
* Return string that is the 'successor' to s[].
* If the rightmost character is a-zA-Z0-9, it is incremented within
diff --git a/libphobos/src/std/traits.d b/libphobos/src/std/traits.d
index 4359dfb..7badab42 100644
--- a/libphobos/src/std/traits.d
+++ b/libphobos/src/std/traits.d
@@ -1927,7 +1927,7 @@ Determine the linkage attribute of the function.
Params:
func = the function symbol, or the type of a function, delegate, or pointer to function
Returns:
- one of the strings "D", "C", "Windows", "Pascal", or "Objective-C"
+ one of the strings "D", "C", "Windows", or "Objective-C"
*/
template functionLinkage(func...)
if (func.length == 1 && isCallable!func)
@@ -2148,7 +2148,7 @@ template SetFunctionAttributes(T, string linkage, uint attrs)
!(attrs & FunctionAttribute.safe),
"Cannot have a function/delegate that is both trusted and safe.");
- static immutable linkages = ["D", "C", "Windows", "Pascal", "C++", "System"];
+ static immutable linkages = ["D", "C", "Windows", "C++", "System"];
static assert(canFind(linkages, linkage), "Invalid linkage '" ~
linkage ~ "', must be one of " ~ linkages.stringof ~ ".");
@@ -2263,7 +2263,7 @@ version (unittest)
// Check that all linkage types work (D-style variadics require D linkage).
static if (variadicFunctionStyle!T != Variadic.d)
{
- foreach (newLinkage; AliasSeq!("D", "C", "Windows", "Pascal", "C++"))
+ foreach (newLinkage; AliasSeq!("D", "C", "Windows", "C++"))
{
alias New = SetFunctionAttributes!(T, newLinkage, attrs);
static assert(functionLinkage!New == newLinkage,
diff --git a/libphobos/testsuite/Makefile.in b/libphobos/testsuite/Makefile.in
index 2f6911d..c38a468 100644
--- a/libphobos/testsuite/Makefile.in
+++ b/libphobos/testsuite/Makefile.in
@@ -161,6 +161,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DCFG_ARM_EABI_UNWINDER = @DCFG_ARM_EABI_UNWINDER@
DCFG_DLPI_TLS_MODID = @DCFG_DLPI_TLS_MODID@
+DCFG_ENABLE_CET = @DCFG_ENABLE_CET@
DCFG_HAVE_64BIT_ATOMICS = @DCFG_HAVE_64BIT_ATOMICS@
DCFG_HAVE_ATOMIC_BUILTINS = @DCFG_HAVE_ATOMIC_BUILTINS@
DCFG_HAVE_LIBATOMIC = @DCFG_HAVE_LIBATOMIC@
diff --git a/libquadmath/ChangeLog b/libquadmath/ChangeLog
index 9f23bbc..f104ad9 100644
--- a/libquadmath/ChangeLog
+++ b/libquadmath/ChangeLog
@@ -1,3 +1,7 @@
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ * configure: Regenerate.
+
2020-05-29 H.J. Lu <hjl.tools@gmail.com>
PR bootstrap/95413
diff --git a/libquadmath/configure b/libquadmath/configure
index a28788a..12b6fe1 100755
--- a/libquadmath/configure
+++ b/libquadmath/configure
@@ -9077,7 +9077,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -9089,7 +9089,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog
index 90e1f05..eb111bc 100644
--- a/libsanitizer/ChangeLog
+++ b/libsanitizer/ChangeLog
@@ -1,3 +1,46 @@
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ * configure: Regenerate.
+
+2020-11-25 Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * LOCAL_PATCHES: Add one commit.
+
+2020-11-25 Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * Makefile.am: Condition Build hwasan directory.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * configure.ac: Set HWASAN_SUPPORTED based on target
+ architecture.
+ * configure.tgt: Likewise.
+
+2020-11-25 Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * Makefile.am: Build libhwasan.
+ * Makefile.in: Build libhwasan.
+ * asan/Makefile.in: Build libhwasan.
+ * configure: Build libhwasan.
+ * configure.ac: Build libhwasan.
+ * hwasan/Makefile.am: New file.
+ * hwasan/Makefile.in: New file.
+ * hwasan/libtool-version: New file.
+ * interception/Makefile.in: Build libhwasan.
+ * libbacktrace/Makefile.in: Build libhwasan.
+ * libsanitizer.spec.in: Build libhwasan.
+ * lsan/Makefile.in: Build libhwasan.
+ * sanitizer_common/Makefile.in: Build libhwasan.
+ * tsan/Makefile.in: Build libhwasan.
+ * ubsan/Makefile.in: Build libhwasan.
+
+2020-11-21 Iain Sandoe <iain@sandoe.co.uk>
+
+ * configure.tgt: Allow x86_64 Darwin2x.
+
+2020-11-13 Martin Liska <mliska@suse.cz>
+
+ * LOCAL_PATCHES: Update to the latest commit.
+
2020-10-19 Martin Liska <mliska@suse.cz>
* LOCAL_PATCHES: Add one commit.
diff --git a/libsanitizer/LOCAL_PATCHES b/libsanitizer/LOCAL_PATCHES
index 298fa34..09a1100 100644
--- a/libsanitizer/LOCAL_PATCHES
+++ b/libsanitizer/LOCAL_PATCHES
@@ -1,2 +1,2 @@
-b040b1ce1ff146c1d2067dd010e7ca753882685d
-476036b35c5e9203735b19b9967ff0e9932c8c31
+d72227e29a083d7a8929d84894ba024651a1c3a7
+8eb12742e8ae5a16e05be627c701234dc7c13504
diff --git a/libsanitizer/MERGE b/libsanitizer/MERGE
index d2a2592..0fb64a9 100644
--- a/libsanitizer/MERGE
+++ b/libsanitizer/MERGE
@@ -1,4 +1,4 @@
-51ff04567b2f8d06b2062bd3ed72eab2e93e4466
+6e7dd1e3e1170080b76b5dcc5716bdd974343233
The first line of this file holds the git revision number of the
last merge done from the master library sources.
diff --git a/libsanitizer/Makefile.am b/libsanitizer/Makefile.am
index 65ed1e7..065a65e 100644
--- a/libsanitizer/Makefile.am
+++ b/libsanitizer/Makefile.am
@@ -18,10 +18,14 @@ SUBDIRS += lsan asan ubsan
nodist_saninclude_HEADERS += \
include/sanitizer/lsan_interface.h \
include/sanitizer/asan_interface.h \
- include/sanitizer/tsan_interface.h
+ include/sanitizer/tsan_interface.h \
+ include/sanitizer/hwasan_interface.h
if TSAN_SUPPORTED
SUBDIRS += tsan
endif
+if HWASAN_SUPPORTED
+SUBDIRS += hwasan
+endif
endif
## May be used by toolexeclibdir.
diff --git a/libsanitizer/Makefile.in b/libsanitizer/Makefile.in
index 02c7f70..3873ea4 100644
--- a/libsanitizer/Makefile.in
+++ b/libsanitizer/Makefile.in
@@ -92,10 +92,12 @@ target_triplet = @target@
@SANITIZER_SUPPORTED_TRUE@am__append_1 = include/sanitizer/common_interface_defs.h \
@SANITIZER_SUPPORTED_TRUE@ include/sanitizer/lsan_interface.h \
@SANITIZER_SUPPORTED_TRUE@ include/sanitizer/asan_interface.h \
-@SANITIZER_SUPPORTED_TRUE@ include/sanitizer/tsan_interface.h
+@SANITIZER_SUPPORTED_TRUE@ include/sanitizer/tsan_interface.h \
+@SANITIZER_SUPPORTED_TRUE@ include/sanitizer/hwasan_interface.h
@SANITIZER_SUPPORTED_TRUE@@USING_MAC_INTERPOSE_FALSE@am__append_2 = interception
@LIBBACKTRACE_SUPPORTED_TRUE@@SANITIZER_SUPPORTED_TRUE@am__append_3 = libbacktrace
@SANITIZER_SUPPORTED_TRUE@@TSAN_SUPPORTED_TRUE@am__append_4 = tsan
+@HWASAN_SUPPORTED_TRUE@@SANITIZER_SUPPORTED_TRUE@am__append_5 = hwasan
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
@@ -207,7 +209,7 @@ ETAGS = etags
CTAGS = ctags
CSCOPE = cscope
DIST_SUBDIRS = sanitizer_common interception libbacktrace lsan asan \
- ubsan tsan
+ ubsan tsan hwasan
ACLOCAL = @ACLOCAL@
ALLOC_FILE = @ALLOC_FILE@
AMTAR = @AMTAR@
@@ -329,6 +331,7 @@ install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
link_libasan = @link_libasan@
+link_libhwasan = @link_libhwasan@
link_liblsan = @link_liblsan@
link_libtsan = @link_libtsan@
link_libubsan = @link_libubsan@
@@ -362,7 +365,7 @@ sanincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include/sanitizer
nodist_saninclude_HEADERS = $(am__append_1)
@SANITIZER_SUPPORTED_TRUE@SUBDIRS = sanitizer_common $(am__append_2) \
@SANITIZER_SUPPORTED_TRUE@ $(am__append_3) lsan asan ubsan \
-@SANITIZER_SUPPORTED_TRUE@ $(am__append_4)
+@SANITIZER_SUPPORTED_TRUE@ $(am__append_4) $(am__append_5)
gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
# Work around what appears to be a GNU make bug handling MAKEFLAGS
diff --git a/libsanitizer/README.gcc b/libsanitizer/README.gcc
index fdb0ec5..07defc5 100644
--- a/libsanitizer/README.gcc
+++ b/libsanitizer/README.gcc
@@ -11,6 +11,7 @@ https://github.com/llvm/llvm-project in the following directories:
compiler-rt/lib/tsan
compiler-rt/lib/lsan
compiler-rt/lib/ubsan
+ compiler-rt/lib/hwasan
Trivial and urgent fixes (portability, build fixes, etc.) may go directly to the
GCC tree. All non-trivial changes, functionality improvements, etc. should go
diff --git a/libsanitizer/asan/Makefile.in b/libsanitizer/asan/Makefile.in
index 29622bf..25c7fd7 100644
--- a/libsanitizer/asan/Makefile.in
+++ b/libsanitizer/asan/Makefile.in
@@ -383,6 +383,7 @@ install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
link_libasan = @link_libasan@
+link_libhwasan = @link_libhwasan@
link_liblsan = @link_liblsan@
link_libtsan = @link_libtsan@
link_libubsan = @link_libubsan@
diff --git a/libsanitizer/asan/asan_fuchsia.cpp b/libsanitizer/asan/asan_fuchsia.cpp
index ec15abf..6c61344 100644
--- a/libsanitizer/asan/asan_fuchsia.cpp
+++ b/libsanitizer/asan/asan_fuchsia.cpp
@@ -91,8 +91,7 @@ struct AsanThread::InitOptions {
// Shared setup between thread creation and startup for the initial thread.
static AsanThread *CreateAsanThread(StackTrace *stack, u32 parent_tid,
uptr user_id, bool detached,
- const char *name, uptr stack_bottom,
- uptr stack_size) {
+ const char *name) {
// In lieu of AsanThread::Create.
AsanThread *thread = (AsanThread *)MmapOrDie(AsanThreadMmapSize(), __func__);
@@ -101,12 +100,6 @@ static AsanThread *CreateAsanThread(StackTrace *stack, u32 parent_tid,
asanThreadRegistry().CreateThread(user_id, detached, parent_tid, &args);
asanThreadRegistry().SetThreadName(tid, name);
- // On other systems, AsanThread::Init() is called from the new
- // thread itself. But on Fuchsia we already know the stack address
- // range beforehand, so we can do most of the setup right now.
- const AsanThread::InitOptions options = {stack_bottom, stack_size};
- thread->Init(&options);
-
return thread;
}
@@ -135,9 +128,16 @@ AsanThread *CreateMainThread() {
_zx_object_get_property(thrd_get_zx_handle(self), ZX_PROP_NAME, name,
sizeof(name)) == ZX_OK
? name
- : nullptr,
- __sanitizer::MainThreadStackBase, __sanitizer::MainThreadStackSize);
+ : nullptr);
+ // We need to set the current thread before calling AsanThread::Init() below,
+ // since it reads the thread ID.
SetCurrentThread(t);
+ DCHECK_EQ(t->tid(), 0);
+
+ const AsanThread::InitOptions options = {__sanitizer::MainThreadStackBase,
+ __sanitizer::MainThreadStackSize};
+ t->Init(&options);
+
return t;
}
@@ -153,8 +153,15 @@ static void *BeforeThreadCreateHook(uptr user_id, bool detached,
GET_STACK_TRACE_THREAD;
u32 parent_tid = GetCurrentTidOrInvalid();
- return CreateAsanThread(&stack, parent_tid, user_id, detached, name,
- stack_bottom, stack_size);
+ AsanThread *thread =
+ CreateAsanThread(&stack, parent_tid, user_id, detached, name);
+
+ // On other systems, AsanThread::Init() is called from the new
+ // thread itself. But on Fuchsia we already know the stack address
+ // range beforehand, so we can do most of the setup right now.
+ const AsanThread::InitOptions options = {stack_bottom, stack_size};
+ thread->Init(&options);
+ return thread;
}
// This is called after creating a new thread (in the creating thread),
diff --git a/libsanitizer/asan/asan_report.cpp b/libsanitizer/asan/asan_report.cpp
index 4b4db1d..03f1ed2 100644
--- a/libsanitizer/asan/asan_report.cpp
+++ b/libsanitizer/asan/asan_report.cpp
@@ -151,7 +151,8 @@ class ScopedInErrorReport {
if (common_flags()->print_cmdline)
PrintCmdline();
- if (common_flags()->print_module_map == 2) PrintModuleMap();
+ if (common_flags()->print_module_map == 2)
+ DumpProcessMap();
// Copy the message buffer so that we could start logging without holding a
// lock that gets aquired during printing.
diff --git a/libsanitizer/asan/asan_rtl.cpp b/libsanitizer/asan/asan_rtl.cpp
index 115733c..7b5a929 100644
--- a/libsanitizer/asan/asan_rtl.cpp
+++ b/libsanitizer/asan/asan_rtl.cpp
@@ -45,7 +45,8 @@ static void AsanDie() {
// Don't die twice - run a busy loop.
while (1) { }
}
- if (common_flags()->print_module_map >= 1) PrintModuleMap();
+ if (common_flags()->print_module_map >= 1)
+ DumpProcessMap();
if (flags()->sleep_before_dying) {
Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying);
SleepForSeconds(flags()->sleep_before_dying);
diff --git a/libsanitizer/asan/asan_thread.cpp b/libsanitizer/asan/asan_thread.cpp
index 58cdc29..fb09af0 100644
--- a/libsanitizer/asan/asan_thread.cpp
+++ b/libsanitizer/asan/asan_thread.cpp
@@ -188,7 +188,7 @@ uptr AsanThread::stack_size() {
return bounds.top - bounds.bottom;
}
-// We want to create the FakeStack lazyly on the first use, but not eralier
+// We want to create the FakeStack lazily on the first use, but not earlier
// than the stack size is known and the procedure has to be async-signal safe.
FakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() {
uptr stack_size = this->stack_size();
@@ -211,6 +211,7 @@ FakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() {
stack_size_log =
Max(stack_size_log, static_cast<uptr>(flags()->min_uar_stack_size_log));
fake_stack_ = FakeStack::Create(stack_size_log);
+ DCHECK_EQ(GetCurrentThread(), this);
SetTLSFakeStack(fake_stack_);
return fake_stack_;
}
@@ -218,6 +219,7 @@ FakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() {
}
void AsanThread::Init(const InitOptions *options) {
+ DCHECK_NE(tid(), ThreadRegistry::kUnknownTid);
next_stack_top_ = next_stack_bottom_ = 0;
atomic_store(&stack_switching_, false, memory_order_release);
CHECK_EQ(this->stack_size(), 0U);
@@ -229,8 +231,17 @@ void AsanThread::Init(const InitOptions *options) {
}
ClearShadowForThreadStackAndTLS();
fake_stack_ = nullptr;
- if (__asan_option_detect_stack_use_after_return)
+ if (__asan_option_detect_stack_use_after_return &&
+ tid() == GetCurrentTidOrInvalid()) {
+ // AsyncSignalSafeLazyInitFakeStack makes use of threadlocals and must be
+ // called from the context of the thread it is initializing, not its parent.
+ // Most platforms call AsanThread::Init on the newly-spawned thread, but
+ // Fuchsia calls this function from the parent thread. To support that
+ // approach, we avoid calling AsyncSignalSafeLazyInitFakeStack here; it will
+ // be called by the new thread when it first attempts to access the fake
+ // stack.
AsyncSignalSafeLazyInitFakeStack();
+ }
int local = 0;
VReport(1, "T%d: stack [%p,%p) size 0x%zx; local=%p\n", tid(),
(void *)stack_bottom_, (void *)stack_top_, stack_top_ - stack_bottom_,
diff --git a/libsanitizer/asan/asan_thread.h b/libsanitizer/asan/asan_thread.h
index c503f50..ea58de4 100644
--- a/libsanitizer/asan/asan_thread.h
+++ b/libsanitizer/asan/asan_thread.h
@@ -35,7 +35,7 @@ class AsanThread;
// These objects are created for every thread and are never deleted,
// so we can find them by tid even if the thread is long dead.
-class AsanThreadContext : public ThreadContextBase {
+class AsanThreadContext final : public ThreadContextBase {
public:
explicit AsanThreadContext(int tid)
: ThreadContextBase(tid), announced(false),
diff --git a/libsanitizer/configure b/libsanitizer/configure
index 04eca04..a425e3f 100755
--- a/libsanitizer/configure
+++ b/libsanitizer/configure
@@ -657,7 +657,10 @@ USING_MAC_INTERPOSE_TRUE
link_liblsan
link_libubsan
link_libtsan
+link_libhwasan
link_libasan
+HWASAN_SUPPORTED_FALSE
+HWASAN_SUPPORTED_TRUE
LSAN_SUPPORTED_FALSE
LSAN_SUPPORTED_TRUE
TSAN_SUPPORTED_FALSE
@@ -10645,7 +10648,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -10657,7 +10660,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -12361,7 +12364,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 12364 "configure"
+#line 12367 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12467,7 +12470,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 12470 "configure"
+#line 12473 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -13489,7 +13492,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
aCC*)
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
@@ -13513,7 +13516,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test $with_gnu_ld = no; then
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
@@ -15818,6 +15821,7 @@ fi
# Get target configury.
unset TSAN_SUPPORTED
unset LSAN_SUPPORTED
+unset HWASAN_SUPPORTED
. ${srcdir}/configure.tgt
if test "x$TSAN_SUPPORTED" = "xyes"; then
TSAN_SUPPORTED_TRUE=
@@ -15835,6 +15839,14 @@ else
LSAN_SUPPORTED_FALSE=
fi
+ if test "x$HWASAN_SUPPORTED" = "xyes"; then
+ HWASAN_SUPPORTED_TRUE=
+ HWASAN_SUPPORTED_FALSE='#'
+else
+ HWASAN_SUPPORTED_TRUE='#'
+ HWASAN_SUPPORTED_FALSE=
+fi
+
# Check for functions needed.
for ac_func in clock_getres clock_gettime clock_settime lstat readlink
@@ -15943,6 +15955,10 @@ fi
link_libasan=$link_sanitizer_common
+# Set up the set of additional libraries that we need to link against for libhwasan.
+link_libhwasan=$link_sanitizer_common
+
+
# Set up the set of additional libraries that we need to link against for libtsan.
link_libtsan=$link_sanitizer_common
@@ -16821,6 +16837,11 @@ if test "x$TSAN_SUPPORTED" = "xyes"; then
fi
+if test "x$HWASAN_SUPPORTED" = "xyes"; then
+ ac_config_files="$ac_config_files hwasan/Makefile"
+
+fi
+
@@ -16862,7 +16883,7 @@ case "$host" in
case "$enable_cet" in
auto)
# Check if target supports multi-byte NOPs
- # and if assembler supports CET insn.
+ # and if compiler and assembler support CET insn.
cet_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -fcf-protection"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -17085,6 +17106,10 @@ if test -z "${LSAN_SUPPORTED_TRUE}" && test -z "${LSAN_SUPPORTED_FALSE}"; then
as_fn_error $? "conditional \"LSAN_SUPPORTED\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${HWASAN_SUPPORTED_TRUE}" && test -z "${HWASAN_SUPPORTED_FALSE}"; then
+ as_fn_error $? "conditional \"HWASAN_SUPPORTED\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
if test -z "${USING_MAC_INTERPOSE_TRUE}" && test -z "${USING_MAC_INTERPOSE_FALSE}"; then
as_fn_error $? "conditional \"USING_MAC_INTERPOSE\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -18096,6 +18121,7 @@ do
"asan/Makefile") CONFIG_FILES="$CONFIG_FILES asan/Makefile" ;;
"ubsan/Makefile") CONFIG_FILES="$CONFIG_FILES ubsan/Makefile" ;;
"tsan/Makefile") CONFIG_FILES="$CONFIG_FILES tsan/Makefile" ;;
+ "hwasan/Makefile") CONFIG_FILES="$CONFIG_FILES hwasan/Makefile" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
@@ -20051,6 +20077,17 @@ _EOF
. ${multi_basedir}/config-ml.in
{ ml_norecursion=; unset ml_norecursion;}
;;
+ "hwasan/Makefile":F) cat > vpsed$$ << \_EOF
+s!`test -f '$<' || echo '$(srcdir)/'`!!
+_EOF
+ sed -f vpsed$$ $ac_file > tmp$$
+ mv tmp$$ $ac_file
+ rm vpsed$$
+ echo 'MULTISUBDIR =' >> $ac_file
+ ml_norecursion=yes
+ . ${multi_basedir}/config-ml.in
+ { ml_norecursion=; unset ml_norecursion;}
+ ;;
esac
done # for ac_tag
diff --git a/libsanitizer/configure.ac b/libsanitizer/configure.ac
index a0950c29e..13cd302 100644
--- a/libsanitizer/configure.ac
+++ b/libsanitizer/configure.ac
@@ -96,9 +96,11 @@ fi
# Get target configury.
unset TSAN_SUPPORTED
unset LSAN_SUPPORTED
+unset HWASAN_SUPPORTED
. ${srcdir}/configure.tgt
AM_CONDITIONAL(TSAN_SUPPORTED, [test "x$TSAN_SUPPORTED" = "xyes"])
AM_CONDITIONAL(LSAN_SUPPORTED, [test "x$LSAN_SUPPORTED" = "xyes"])
+AM_CONDITIONAL(HWASAN_SUPPORTED, [test "x$HWASAN_SUPPORTED" = "xyes"])
# Check for functions needed.
AC_CHECK_FUNCS(clock_getres clock_gettime clock_settime lstat readlink)
@@ -120,6 +122,10 @@ AC_CHECK_LIB(dl, dlsym,
link_libasan=$link_sanitizer_common
AC_SUBST(link_libasan)
+# Set up the set of additional libraries that we need to link against for libhwasan.
+link_libhwasan=$link_sanitizer_common
+AC_SUBST(link_libhwasan)
+
# Set up the set of additional libraries that we need to link against for libtsan.
link_libtsan=$link_sanitizer_common
AC_SUBST(link_libtsan)
@@ -376,6 +382,21 @@ _EOF
])
fi
+if test "x$HWASAN_SUPPORTED" = "xyes"; then
+ AC_CONFIG_FILES(AC_FOREACH([DIR], [hwasan], [DIR/Makefile ]),
+ [cat > vpsed$$ << \_EOF
+s!`test -f '$<' || echo '$(srcdir)/'`!!
+_EOF
+ sed -f vpsed$$ $ac_file > tmp$$
+ mv tmp$$ $ac_file
+ rm vpsed$$
+ echo 'MULTISUBDIR =' >> $ac_file
+ ml_norecursion=yes
+ . ${multi_basedir}/config-ml.in
+ AS_UNSET([ml_norecursion])
+])
+fi
+
AC_SUBST([TSAN_TARGET_DEPENDENT_OBJECTS])
AC_SUBST([SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS])
diff --git a/libsanitizer/configure.tgt b/libsanitizer/configure.tgt
index 52503f1..5d1dba1 100644
--- a/libsanitizer/configure.tgt
+++ b/libsanitizer/configure.tgt
@@ -60,9 +60,10 @@ case "${target}" in
TSAN_SUPPORTED=yes
LSAN_SUPPORTED=yes
TSAN_TARGET_DEPENDENT_OBJECTS=tsan_rtl_aarch64.lo
+ HWASAN_SUPPORTED=yes
fi
;;
- x86_64-*-darwin1[2-9]* | i?86-*-darwin1[2-9]*)
+ x86_64-*-darwin2* | x86_64-*-darwin1[2-9]* | i?86-*-darwin1[2-9]*)
TSAN_SUPPORTED=no
;;
x86_64-*-solaris2.11* | i?86-*-solaris2.11*)
diff --git a/libsanitizer/hwasan/Makefile.am b/libsanitizer/hwasan/Makefile.am
new file mode 100644
index 0000000..2226f68
--- /dev/null
+++ b/libsanitizer/hwasan/Makefile.am
@@ -0,0 +1,89 @@
+AM_CPPFLAGS = -I $(top_srcdir)/include -I $(top_srcdir)
+
+# May be used by toolexeclibdir.
+gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
+
+DEFS = -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -DCAN_SANITIZE_UB=0 -DHWASAN_WITH_INTERCEPTORS=1
+AM_CXXFLAGS = -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic -Wno-long-long -fPIC -fno-builtin -fno-exceptions -fno-rtti -funwind-tables -fvisibility=hidden -Wno-variadic-macros -fno-ipa-icf
+AM_CXXFLAGS += $(LIBSTDCXX_RAW_CXX_CXXFLAGS)
+AM_CXXFLAGS += -std=gnu++14
+AM_CXXFLAGS += $(EXTRA_CXXFLAGS)
+ACLOCAL_AMFLAGS = -I $(top_srcdir) -I $(top_srcdir)/config
+
+toolexeclib_LTLIBRARIES = libhwasan.la
+
+hwasan_files = \
+ hwasan_allocator.cpp \
+ hwasan.cpp \
+ hwasan_dynamic_shadow.cpp \
+ hwasan_exceptions.cpp \
+ hwasan_flags.inc \
+ hwasan_globals.cpp \
+ hwasan_interceptors.cpp \
+ hwasan_interceptors_vfork.S \
+ hwasan_linux.cpp \
+ hwasan_memintrinsics.cpp \
+ hwasan_new_delete.cpp \
+ hwasan_poisoning.cpp \
+ hwasan_report.cpp \
+ hwasan_setjmp.S \
+ hwasan_tag_mismatch_aarch64.S \
+ hwasan_thread.cpp \
+ hwasan_thread_list.cpp \
+ hwasan_type_test.cpp
+
+libhwasan_la_SOURCES = $(hwasan_files)
+libhwasan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la
+if !USING_MAC_INTERPOSE
+libhwasan_la_LIBADD += $(top_builddir)/interception/libinterception.la
+endif
+if LIBBACKTRACE_SUPPORTED
+libhwasan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la
+endif
+libhwasan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS)
+
+libhwasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libhwasan)
+
+# Work around what appears to be a GNU make bug handling MAKEFLAGS
+# values defined in terms of make variables, as is the case for CC and
+# friends when we are called from the top level Makefile.
+AM_MAKEFLAGS = \
+ "AR_FLAGS=$(AR_FLAGS)" \
+ "CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+ "CFLAGS=$(CFLAGS)" \
+ "CXXFLAGS=$(CXXFLAGS)" \
+ "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
+ "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
+ "INSTALL=$(INSTALL)" \
+ "INSTALL_DATA=$(INSTALL_DATA)" \
+ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+ "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
+ "JC1FLAGS=$(JC1FLAGS)" \
+ "LDFLAGS=$(LDFLAGS)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
+ "MAKE=$(MAKE)" \
+ "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
+ "PICFLAG=$(PICFLAG)" \
+ "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
+ "SHELL=$(SHELL)" \
+ "RUNTESTFLAGS=$(RUNTESTFLAGS)" \
+ "exec_prefix=$(exec_prefix)" \
+ "infodir=$(infodir)" \
+ "libdir=$(libdir)" \
+ "prefix=$(prefix)" \
+ "includedir=$(includedir)" \
+ "AR=$(AR)" \
+ "AS=$(AS)" \
+ "LD=$(LD)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "NM=$(NM)" \
+ "PICFLAG=$(PICFLAG)" \
+ "RANLIB=$(RANLIB)" \
+ "DESTDIR=$(DESTDIR)"
+
+MAKEOVERRIDES=
+
+## ################################################################
+
+
diff --git a/libsanitizer/hwasan/Makefile.in b/libsanitizer/hwasan/Makefile.in
new file mode 100644
index 0000000..542af8f
--- /dev/null
+++ b/libsanitizer/hwasan/Makefile.in
@@ -0,0 +1,803 @@
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+@USING_MAC_INTERPOSE_FALSE@am__append_1 = $(top_builddir)/interception/libinterception.la
+@LIBBACKTRACE_SUPPORTED_TRUE@am__append_2 = $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la
+subdir = hwasan
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+ $(top_srcdir)/../config/depstand.m4 \
+ $(top_srcdir)/../config/lead-dot.m4 \
+ $(top_srcdir)/../config/libstdc++-raw-cxx.m4 \
+ $(top_srcdir)/../config/multi.m4 \
+ $(top_srcdir)/../config/override.m4 \
+ $(top_srcdir)/../config/stdint.m4 \
+ $(top_srcdir)/../config/toolexeclibdir.m4 \
+ $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+ $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/../libtool.m4 \
+ $(top_srcdir)/../config/enable.m4 \
+ $(top_srcdir)/../config/cet.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(toolexeclibdir)"
+LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libhwasan_la_DEPENDENCIES = \
+ $(top_builddir)/sanitizer_common/libsanitizer_common.la \
+ $(am__append_1) $(am__append_2) $(am__DEPENDENCIES_1)
+am__objects_1 = hwasan_allocator.lo hwasan.lo hwasan_dynamic_shadow.lo \
+ hwasan_exceptions.lo hwasan_globals.lo hwasan_interceptors.lo \
+ hwasan_interceptors_vfork.lo hwasan_linux.lo \
+ hwasan_memintrinsics.lo hwasan_new_delete.lo \
+ hwasan_poisoning.lo hwasan_report.lo hwasan_setjmp.lo \
+ hwasan_tag_mismatch_aarch64.lo hwasan_thread.lo \
+ hwasan_thread_list.lo hwasan_type_test.lo
+am_libhwasan_la_OBJECTS = $(am__objects_1)
+libhwasan_la_OBJECTS = $(am_libhwasan_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+libhwasan_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(libhwasan_la_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+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) \
+ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo " CXX " $@;
+am__v_CXX_1 =
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+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 = $(libhwasan_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+ACLOCAL = @ACLOCAL@
+ALLOC_FILE = @ALLOC_FILE@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BACKTRACE_SUPPORTED = @BACKTRACE_SUPPORTED@
+BACKTRACE_SUPPORTS_THREADS = @BACKTRACE_SUPPORTS_THREADS@
+BACKTRACE_USES_MALLOC = @BACKTRACE_USES_MALLOC@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -DCAN_SANITIZE_UB=0 -DHWASAN_WITH_INTERCEPTORS=1
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXTRA_ASFLAGS = @EXTRA_ASFLAGS@
+EXTRA_CFLAGS = @EXTRA_CFLAGS@
+EXTRA_CXXFLAGS = @EXTRA_CXXFLAGS@
+FGREP = @FGREP@
+FORMAT_FILE = @FORMAT_FILE@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSTDCXX_RAW_CXX_CXXFLAGS = @LIBSTDCXX_RAW_CXX_CXXFLAGS@
+LIBSTDCXX_RAW_CXX_LDFLAGS = @LIBSTDCXX_RAW_CXX_LDFLAGS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RPC_DEFS = @RPC_DEFS@
+SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS = @SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TSAN_TARGET_DEPENDENT_OBJECTS = @TSAN_TARGET_DEPENDENT_OBJECTS@
+VERSION = @VERSION@
+VIEW_FILE = @VIEW_FILE@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
+exec_prefix = @exec_prefix@
+get_gcc_base_ver = @get_gcc_base_ver@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+link_libasan = @link_libasan@
+link_libhwasan = @link_libhwasan@
+link_liblsan = @link_liblsan@
+link_libtsan = @link_libtsan@
+link_libubsan = @link_libubsan@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+multi_basedir = @multi_basedir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_noncanonical = @target_noncanonical@
+target_os = @target_os@
+target_vendor = @target_vendor@
+toolexecdir = @toolexecdir@
+toolexeclibdir = @toolexeclibdir@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CPPFLAGS = -I $(top_srcdir)/include -I $(top_srcdir)
+
+# May be used by toolexeclibdir.
+gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
+AM_CXXFLAGS = -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic \
+ -Wno-long-long -fPIC -fno-builtin -fno-exceptions -fno-rtti \
+ -funwind-tables -fvisibility=hidden -Wno-variadic-macros \
+ -fno-ipa-icf $(LIBSTDCXX_RAW_CXX_CXXFLAGS) -std=gnu++14 \
+ $(EXTRA_CXXFLAGS)
+ACLOCAL_AMFLAGS = -I $(top_srcdir) -I $(top_srcdir)/config
+toolexeclib_LTLIBRARIES = libhwasan.la
+hwasan_files = \
+ hwasan_allocator.cpp \
+ hwasan.cpp \
+ hwasan_dynamic_shadow.cpp \
+ hwasan_exceptions.cpp \
+ hwasan_flags.inc \
+ hwasan_globals.cpp \
+ hwasan_interceptors.cpp \
+ hwasan_interceptors_vfork.S \
+ hwasan_linux.cpp \
+ hwasan_memintrinsics.cpp \
+ hwasan_new_delete.cpp \
+ hwasan_poisoning.cpp \
+ hwasan_report.cpp \
+ hwasan_setjmp.S \
+ hwasan_tag_mismatch_aarch64.S \
+ hwasan_thread.cpp \
+ hwasan_thread_list.cpp \
+ hwasan_type_test.cpp
+
+libhwasan_la_SOURCES = $(hwasan_files)
+libhwasan_la_LIBADD = \
+ $(top_builddir)/sanitizer_common/libsanitizer_common.la \
+ $(am__append_1) $(am__append_2) $(LIBSTDCXX_RAW_CXX_LDFLAGS)
+libhwasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libhwasan)
+
+# Work around what appears to be a GNU make bug handling MAKEFLAGS
+# values defined in terms of make variables, as is the case for CC and
+# friends when we are called from the top level Makefile.
+AM_MAKEFLAGS = \
+ "AR_FLAGS=$(AR_FLAGS)" \
+ "CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+ "CFLAGS=$(CFLAGS)" \
+ "CXXFLAGS=$(CXXFLAGS)" \
+ "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
+ "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
+ "INSTALL=$(INSTALL)" \
+ "INSTALL_DATA=$(INSTALL_DATA)" \
+ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+ "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
+ "JC1FLAGS=$(JC1FLAGS)" \
+ "LDFLAGS=$(LDFLAGS)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
+ "MAKE=$(MAKE)" \
+ "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
+ "PICFLAG=$(PICFLAG)" \
+ "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
+ "SHELL=$(SHELL)" \
+ "RUNTESTFLAGS=$(RUNTESTFLAGS)" \
+ "exec_prefix=$(exec_prefix)" \
+ "infodir=$(infodir)" \
+ "libdir=$(libdir)" \
+ "prefix=$(prefix)" \
+ "includedir=$(includedir)" \
+ "AR=$(AR)" \
+ "AS=$(AS)" \
+ "LD=$(LD)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "NM=$(NM)" \
+ "PICFLAG=$(PICFLAG)" \
+ "RANLIB=$(RANLIB)" \
+ "DESTDIR=$(DESTDIR)"
+
+MAKEOVERRIDES =
+all: all-am
+
+.SUFFIXES:
+.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 \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign hwasan/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign hwasan/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(toolexeclibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(toolexeclibdir)"; \
+ }
+
+uninstall-toolexeclibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(toolexeclibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(toolexeclibdir)/$$f"; \
+ done
+
+clean-toolexeclibLTLIBRARIES:
+ -test -z "$(toolexeclib_LTLIBRARIES)" || rm -f $(toolexeclib_LTLIBRARIES)
+ @list='$(toolexeclib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libhwasan.la: $(libhwasan_la_OBJECTS) $(libhwasan_la_DEPENDENCIES) $(EXTRA_libhwasan_la_DEPENDENCIES)
+ $(AM_V_CXXLD)$(libhwasan_la_LINK) -rpath $(toolexeclibdir) $(libhwasan_la_OBJECTS) $(libhwasan_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_allocator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_dynamic_shadow.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_exceptions.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_globals.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_interceptors.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_interceptors_vfork.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_linux.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_memintrinsics.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_new_delete.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_poisoning.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_report.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_setjmp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_tag_mismatch_aarch64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_thread.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_thread_list.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_type_test.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 $@ $<
+
+.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 $@ $<
+
+.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) '$<'`
+
+.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@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(toolexeclibdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-toolexeclibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-toolexeclibLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-toolexeclibLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-toolexeclibLTLIBRARIES cscopelist-am ctags \
+ ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags dvi dvi-am html html-am info \
+ info-am install install-am install-data install-data-am \
+ install-dvi install-dvi-am install-exec install-exec-am \
+ install-html install-html-am install-info install-info-am \
+ install-man install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip install-toolexeclibLTLIBRARIES \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am \
+ uninstall-toolexeclibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libsanitizer/hwasan/hwasan.cpp b/libsanitizer/hwasan/hwasan.cpp
new file mode 100644
index 0000000..c532211
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan.cpp
@@ -0,0 +1,522 @@
+//===-- hwasan.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 HWAddressSanitizer.
+//
+// HWAddressSanitizer runtime.
+//===----------------------------------------------------------------------===//
+
+#include "hwasan.h"
+
+#include "hwasan_checks.h"
+#include "hwasan_dynamic_shadow.h"
+#include "hwasan_globals.h"
+#include "hwasan_poisoning.h"
+#include "hwasan_report.h"
+#include "hwasan_thread.h"
+#include "hwasan_thread_list.h"
+#include "sanitizer_common/sanitizer_atomic.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_flag_parser.h"
+#include "sanitizer_common/sanitizer_flags.h"
+#include "sanitizer_common/sanitizer_libc.h"
+#include "sanitizer_common/sanitizer_procmaps.h"
+#include "sanitizer_common/sanitizer_stackdepot.h"
+#include "sanitizer_common/sanitizer_stacktrace.h"
+#include "sanitizer_common/sanitizer_symbolizer.h"
+#include "ubsan/ubsan_flags.h"
+#include "ubsan/ubsan_init.h"
+
+// ACHTUNG! No system header includes in this file.
+
+using namespace __sanitizer;
+
+namespace __hwasan {
+
+static Flags hwasan_flags;
+
+Flags *flags() {
+ return &hwasan_flags;
+}
+
+int hwasan_inited = 0;
+int hwasan_instrumentation_inited = 0;
+bool hwasan_init_is_running;
+
+int hwasan_report_count = 0;
+
+void Flags::SetDefaults() {
+#define HWASAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
+#include "hwasan_flags.inc"
+#undef HWASAN_FLAG
+}
+
+static void RegisterHwasanFlags(FlagParser *parser, Flags *f) {
+#define HWASAN_FLAG(Type, Name, DefaultValue, Description) \
+ RegisterFlag(parser, #Name, Description, &f->Name);
+#include "hwasan_flags.inc"
+#undef HWASAN_FLAG
+}
+
+static void InitializeFlags() {
+ SetCommonFlagsDefaults();
+ {
+ CommonFlags cf;
+ cf.CopyFrom(*common_flags());
+ cf.external_symbolizer_path = GetEnv("HWASAN_SYMBOLIZER_PATH");
+ cf.malloc_context_size = 20;
+ cf.handle_ioctl = true;
+ // FIXME: test and enable.
+ cf.check_printf = false;
+ cf.intercept_tls_get_addr = true;
+ cf.exitcode = 99;
+ // 8 shadow pages ~512kB, small enough to cover common stack sizes.
+ cf.clear_shadow_mmap_threshold = 4096 * (SANITIZER_ANDROID ? 2 : 8);
+ // Sigtrap is used in error reporting.
+ cf.handle_sigtrap = kHandleSignalExclusive;
+
+#if SANITIZER_ANDROID
+ // Let platform handle other signals. It is better at reporting them then we
+ // are.
+ cf.handle_segv = kHandleSignalNo;
+ cf.handle_sigbus = kHandleSignalNo;
+ cf.handle_abort = kHandleSignalNo;
+ cf.handle_sigill = kHandleSignalNo;
+ cf.handle_sigfpe = kHandleSignalNo;
+#endif
+ OverrideCommonFlags(cf);
+ }
+
+ Flags *f = flags();
+ f->SetDefaults();
+
+ FlagParser parser;
+ RegisterHwasanFlags(&parser, f);
+ RegisterCommonFlags(&parser);
+
+#if HWASAN_CONTAINS_UBSAN
+ __ubsan::Flags *uf = __ubsan::flags();
+ uf->SetDefaults();
+
+ FlagParser ubsan_parser;
+ __ubsan::RegisterUbsanFlags(&ubsan_parser, uf);
+ RegisterCommonFlags(&ubsan_parser);
+#endif
+
+ // Override from user-specified string.
+ if (__hwasan_default_options)
+ parser.ParseString(__hwasan_default_options());
+#if HWASAN_CONTAINS_UBSAN
+ const char *ubsan_default_options = __ubsan_default_options();
+ ubsan_parser.ParseString(ubsan_default_options);
+#endif
+
+ parser.ParseStringFromEnv("HWASAN_OPTIONS");
+#if HWASAN_CONTAINS_UBSAN
+ ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS");
+#endif
+
+ InitializeCommonFlags();
+
+ if (Verbosity()) ReportUnrecognizedFlags();
+
+ if (common_flags()->help) parser.PrintFlagDescriptions();
+}
+
+static void HWAsanCheckFailed(const char *file, int line, const char *cond,
+ u64 v1, u64 v2) {
+ Report("HWAddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n", file,
+ line, cond, (uptr)v1, (uptr)v2);
+ PRINT_CURRENT_STACK_CHECK();
+ Die();
+}
+
+static constexpr uptr kMemoryUsageBufferSize = 4096;
+
+static void HwasanFormatMemoryUsage(InternalScopedString &s) {
+ HwasanThreadList &thread_list = hwasanThreadList();
+ auto thread_stats = thread_list.GetThreadStats();
+ auto *sds = StackDepotGetStats();
+ AllocatorStatCounters asc;
+ GetAllocatorStats(asc);
+ s.append(
+ "HWASAN pid: %d rss: %zd threads: %zd stacks: %zd"
+ " thr_aux: %zd stack_depot: %zd uniq_stacks: %zd"
+ " heap: %zd",
+ internal_getpid(), GetRSS(), thread_stats.n_live_threads,
+ thread_stats.total_stack_size,
+ thread_stats.n_live_threads * thread_list.MemoryUsedPerThread(),
+ sds->allocated, sds->n_uniq_ids, asc[AllocatorStatMapped]);
+}
+
+#if SANITIZER_ANDROID
+static char *memory_usage_buffer = nullptr;
+
+static void InitMemoryUsage() {
+ memory_usage_buffer =
+ (char *)MmapOrDie(kMemoryUsageBufferSize, "memory usage string");
+ CHECK(memory_usage_buffer);
+ memory_usage_buffer[0] = '\0';
+ DecorateMapping((uptr)memory_usage_buffer, kMemoryUsageBufferSize,
+ memory_usage_buffer);
+}
+
+void UpdateMemoryUsage() {
+ if (!flags()->export_memory_stats)
+ return;
+ if (!memory_usage_buffer)
+ InitMemoryUsage();
+ InternalScopedString s(kMemoryUsageBufferSize);
+ HwasanFormatMemoryUsage(s);
+ internal_strncpy(memory_usage_buffer, s.data(), kMemoryUsageBufferSize - 1);
+ memory_usage_buffer[kMemoryUsageBufferSize - 1] = '\0';
+}
+#else
+void UpdateMemoryUsage() {}
+#endif
+
+} // namespace __hwasan
+
+using namespace __hwasan;
+
+void __sanitizer::BufferedStackTrace::UnwindImpl(
+ uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
+ Thread *t = GetCurrentThread();
+ if (!t) {
+ // The thread is still being created, or has already been destroyed.
+ size = 0;
+ return;
+ }
+ Unwind(max_depth, pc, bp, context, t->stack_top(), t->stack_bottom(),
+ request_fast);
+}
+
+static bool InitializeSingleGlobal(const hwasan_global &global) {
+ uptr full_granule_size = RoundDownTo(global.size(), 16);
+ TagMemoryAligned(global.addr(), full_granule_size, global.tag());
+ if (global.size() % 16)
+ TagMemoryAligned(global.addr() + full_granule_size, 16, global.size() % 16);
+ return false;
+}
+
+static void InitLoadedGlobals() {
+ dl_iterate_phdr(
+ [](dl_phdr_info *info, size_t /* size */, void * /* data */) -> int {
+ for (const hwasan_global &global : HwasanGlobalsFor(
+ info->dlpi_addr, info->dlpi_phdr, info->dlpi_phnum))
+ InitializeSingleGlobal(global);
+ return 0;
+ },
+ nullptr);
+}
+
+// Prepare to run instrumented code on the main thread.
+static void InitInstrumentation() {
+ if (hwasan_instrumentation_inited) return;
+
+ InitPrctl();
+
+ if (!InitShadow()) {
+ Printf("FATAL: HWAddressSanitizer cannot mmap the shadow memory.\n");
+ DumpProcessMap();
+ Die();
+ }
+
+ InitThreads();
+ hwasanThreadList().CreateCurrentThread();
+
+ hwasan_instrumentation_inited = 1;
+}
+
+// Interface.
+
+uptr __hwasan_shadow_memory_dynamic_address; // Global interface symbol.
+
+// This function was used by the old frame descriptor mechanism. We keep it
+// around to avoid breaking ABI.
+void __hwasan_init_frames(uptr beg, uptr end) {}
+
+void __hwasan_init_static() {
+ InitShadowGOT();
+ InitInstrumentation();
+
+ // In the non-static code path we call dl_iterate_phdr here. But at this point
+ // libc might not have been initialized enough for dl_iterate_phdr to work.
+ // Fortunately, since this is a statically linked executable we can use the
+ // linker-defined symbol __ehdr_start to find the only relevant set of phdrs.
+ extern ElfW(Ehdr) __ehdr_start;
+ for (const hwasan_global &global : HwasanGlobalsFor(
+ /* base */ 0,
+ reinterpret_cast<const ElfW(Phdr) *>(
+ reinterpret_cast<const char *>(&__ehdr_start) +
+ __ehdr_start.e_phoff),
+ __ehdr_start.e_phnum))
+ InitializeSingleGlobal(global);
+}
+
+void __hwasan_init() {
+ CHECK(!hwasan_init_is_running);
+ if (hwasan_inited) return;
+ hwasan_init_is_running = 1;
+ SanitizerToolName = "HWAddressSanitizer";
+
+ InitTlsSize();
+
+ CacheBinaryName();
+ InitializeFlags();
+
+ // Install tool-specific callbacks in sanitizer_common.
+ SetCheckFailedCallback(HWAsanCheckFailed);
+
+ __sanitizer_set_report_path(common_flags()->log_path);
+
+ AndroidTestTlsSlot();
+
+ DisableCoreDumperIfNecessary();
+
+ InitInstrumentation();
+ InitLoadedGlobals();
+
+ // Needs to be called here because flags()->random_tags might not have been
+ // initialized when InitInstrumentation() was called.
+ GetCurrentThread()->InitRandomState();
+
+ SetPrintfAndReportCallback(AppendToErrorMessageBuffer);
+ // This may call libc -> needs initialized shadow.
+ AndroidLogInit();
+
+ InitializeInterceptors();
+ InstallDeadlySignalHandlers(HwasanOnDeadlySignal);
+ InstallAtExitHandler(); // Needs __cxa_atexit interceptor.
+
+ InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
+
+ HwasanTSDInit();
+ HwasanTSDThreadInit();
+
+ HwasanAllocatorInit();
+
+#if HWASAN_CONTAINS_UBSAN
+ __ubsan::InitAsPlugin();
+#endif
+
+ VPrintf(1, "HWAddressSanitizer init done\n");
+
+ hwasan_init_is_running = 0;
+ hwasan_inited = 1;
+}
+
+void __hwasan_library_loaded(ElfW(Addr) base, const ElfW(Phdr) * phdr,
+ ElfW(Half) phnum) {
+ for (const hwasan_global &global : HwasanGlobalsFor(base, phdr, phnum))
+ InitializeSingleGlobal(global);
+}
+
+void __hwasan_library_unloaded(ElfW(Addr) base, const ElfW(Phdr) * phdr,
+ ElfW(Half) phnum) {
+ for (; phnum != 0; ++phdr, --phnum)
+ if (phdr->p_type == PT_LOAD)
+ TagMemory(base + phdr->p_vaddr, phdr->p_memsz, 0);
+}
+
+void __hwasan_print_shadow(const void *p, uptr sz) {
+ uptr ptr_raw = UntagAddr(reinterpret_cast<uptr>(p));
+ uptr shadow_first = MemToShadow(ptr_raw);
+ uptr shadow_last = MemToShadow(ptr_raw + sz - 1);
+ Printf("HWASan shadow map for %zx .. %zx (pointer tag %x)\n", ptr_raw,
+ ptr_raw + sz, GetTagFromPointer((uptr)p));
+ for (uptr s = shadow_first; s <= shadow_last; ++s)
+ Printf(" %zx: %x\n", ShadowToMem(s), *(tag_t *)s);
+}
+
+sptr __hwasan_test_shadow(const void *p, uptr sz) {
+ if (sz == 0)
+ return -1;
+ tag_t ptr_tag = GetTagFromPointer((uptr)p);
+ uptr ptr_raw = UntagAddr(reinterpret_cast<uptr>(p));
+ uptr shadow_first = MemToShadow(ptr_raw);
+ uptr shadow_last = MemToShadow(ptr_raw + sz - 1);
+ for (uptr s = shadow_first; s <= shadow_last; ++s)
+ if (*(tag_t *)s != ptr_tag) {
+ sptr offset = ShadowToMem(s) - ptr_raw;
+ return offset < 0 ? 0 : offset;
+ }
+ return -1;
+}
+
+u16 __sanitizer_unaligned_load16(const uu16 *p) {
+ return *p;
+}
+u32 __sanitizer_unaligned_load32(const uu32 *p) {
+ return *p;
+}
+u64 __sanitizer_unaligned_load64(const uu64 *p) {
+ return *p;
+}
+void __sanitizer_unaligned_store16(uu16 *p, u16 x) {
+ *p = x;
+}
+void __sanitizer_unaligned_store32(uu32 *p, u32 x) {
+ *p = x;
+}
+void __sanitizer_unaligned_store64(uu64 *p, u64 x) {
+ *p = x;
+}
+
+void __hwasan_loadN(uptr p, uptr sz) {
+ CheckAddressSized<ErrorAction::Abort, AccessType::Load>(p, sz);
+}
+void __hwasan_load1(uptr p) {
+ CheckAddress<ErrorAction::Abort, AccessType::Load, 0>(p);
+}
+void __hwasan_load2(uptr p) {
+ CheckAddress<ErrorAction::Abort, AccessType::Load, 1>(p);
+}
+void __hwasan_load4(uptr p) {
+ CheckAddress<ErrorAction::Abort, AccessType::Load, 2>(p);
+}
+void __hwasan_load8(uptr p) {
+ CheckAddress<ErrorAction::Abort, AccessType::Load, 3>(p);
+}
+void __hwasan_load16(uptr p) {
+ CheckAddress<ErrorAction::Abort, AccessType::Load, 4>(p);
+}
+
+void __hwasan_loadN_noabort(uptr p, uptr sz) {
+ CheckAddressSized<ErrorAction::Recover, AccessType::Load>(p, sz);
+}
+void __hwasan_load1_noabort(uptr p) {
+ CheckAddress<ErrorAction::Recover, AccessType::Load, 0>(p);
+}
+void __hwasan_load2_noabort(uptr p) {
+ CheckAddress<ErrorAction::Recover, AccessType::Load, 1>(p);
+}
+void __hwasan_load4_noabort(uptr p) {
+ CheckAddress<ErrorAction::Recover, AccessType::Load, 2>(p);
+}
+void __hwasan_load8_noabort(uptr p) {
+ CheckAddress<ErrorAction::Recover, AccessType::Load, 3>(p);
+}
+void __hwasan_load16_noabort(uptr p) {
+ CheckAddress<ErrorAction::Recover, AccessType::Load, 4>(p);
+}
+
+void __hwasan_storeN(uptr p, uptr sz) {
+ CheckAddressSized<ErrorAction::Abort, AccessType::Store>(p, sz);
+}
+void __hwasan_store1(uptr p) {
+ CheckAddress<ErrorAction::Abort, AccessType::Store, 0>(p);
+}
+void __hwasan_store2(uptr p) {
+ CheckAddress<ErrorAction::Abort, AccessType::Store, 1>(p);
+}
+void __hwasan_store4(uptr p) {
+ CheckAddress<ErrorAction::Abort, AccessType::Store, 2>(p);
+}
+void __hwasan_store8(uptr p) {
+ CheckAddress<ErrorAction::Abort, AccessType::Store, 3>(p);
+}
+void __hwasan_store16(uptr p) {
+ CheckAddress<ErrorAction::Abort, AccessType::Store, 4>(p);
+}
+
+void __hwasan_storeN_noabort(uptr p, uptr sz) {
+ CheckAddressSized<ErrorAction::Recover, AccessType::Store>(p, sz);
+}
+void __hwasan_store1_noabort(uptr p) {
+ CheckAddress<ErrorAction::Recover, AccessType::Store, 0>(p);
+}
+void __hwasan_store2_noabort(uptr p) {
+ CheckAddress<ErrorAction::Recover, AccessType::Store, 1>(p);
+}
+void __hwasan_store4_noabort(uptr p) {
+ CheckAddress<ErrorAction::Recover, AccessType::Store, 2>(p);
+}
+void __hwasan_store8_noabort(uptr p) {
+ CheckAddress<ErrorAction::Recover, AccessType::Store, 3>(p);
+}
+void __hwasan_store16_noabort(uptr p) {
+ CheckAddress<ErrorAction::Recover, AccessType::Store, 4>(p);
+}
+
+void __hwasan_tag_memory(uptr p, u8 tag, uptr sz) {
+ TagMemoryAligned(p, sz, tag);
+}
+
+uptr __hwasan_tag_pointer(uptr p, u8 tag) {
+ return AddTagToPointer(p, tag);
+}
+
+void __hwasan_handle_longjmp(const void *sp_dst) {
+ uptr dst = (uptr)sp_dst;
+ // HWASan does not support tagged SP.
+ CHECK(GetTagFromPointer(dst) == 0);
+
+ uptr sp = (uptr)__builtin_frame_address(0);
+ static const uptr kMaxExpectedCleanupSize = 64 << 20; // 64M
+ if (dst < sp || dst - sp > kMaxExpectedCleanupSize) {
+ Report(
+ "WARNING: HWASan is ignoring requested __hwasan_handle_longjmp: "
+ "stack top: %p; target %p; distance: %p (%zd)\n"
+ "False positive error reports may follow\n",
+ (void *)sp, (void *)dst, dst - sp);
+ return;
+ }
+ TagMemory(sp, dst - sp, 0);
+}
+
+void __hwasan_handle_vfork(const void *sp_dst) {
+ uptr sp = (uptr)sp_dst;
+ Thread *t = GetCurrentThread();
+ CHECK(t);
+ uptr top = t->stack_top();
+ uptr bottom = t->stack_bottom();
+ if (top == 0 || bottom == 0 || sp < bottom || sp >= top) {
+ Report(
+ "WARNING: HWASan is ignoring requested __hwasan_handle_vfork: "
+ "stack top: %zx; current %zx; bottom: %zx \n"
+ "False positive error reports may follow\n",
+ top, sp, bottom);
+ return;
+ }
+ TagMemory(bottom, sp - bottom, 0);
+}
+
+extern "C" void *__hwasan_extra_spill_area() {
+ Thread *t = GetCurrentThread();
+ return &t->vfork_spill();
+}
+
+void __hwasan_print_memory_usage() {
+ InternalScopedString s(kMemoryUsageBufferSize);
+ HwasanFormatMemoryUsage(s);
+ Printf("%s\n", s.data());
+}
+
+static const u8 kFallbackTag = 0xBB;
+
+u8 __hwasan_generate_tag() {
+ Thread *t = GetCurrentThread();
+ if (!t) return kFallbackTag;
+ return t->GenerateRandomTag();
+}
+
+#if !SANITIZER_SUPPORTS_WEAK_HOOKS
+extern "C" {
+SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
+const char* __hwasan_default_options() { return ""; }
+} // extern "C"
+#endif
+
+extern "C" {
+SANITIZER_INTERFACE_ATTRIBUTE
+void __sanitizer_print_stack_trace() {
+ GET_FATAL_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME());
+ stack.Print();
+}
+} // extern "C"
diff --git a/libsanitizer/hwasan/hwasan.h b/libsanitizer/hwasan/hwasan.h
new file mode 100644
index 0000000..d4521ef
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan.h
@@ -0,0 +1,165 @@
+//===-- hwasan.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 HWAddressSanitizer.
+//
+// Private Hwasan header.
+//===----------------------------------------------------------------------===//
+
+#ifndef HWASAN_H
+#define HWASAN_H
+
+#include "sanitizer_common/sanitizer_flags.h"
+#include "sanitizer_common/sanitizer_internal_defs.h"
+#include "sanitizer_common/sanitizer_stacktrace.h"
+#include "hwasan_interface_internal.h"
+#include "hwasan_flags.h"
+#include "ubsan/ubsan_platform.h"
+
+#ifndef HWASAN_CONTAINS_UBSAN
+# define HWASAN_CONTAINS_UBSAN CAN_SANITIZE_UB
+#endif
+
+#ifndef HWASAN_WITH_INTERCEPTORS
+#define HWASAN_WITH_INTERCEPTORS 0
+#endif
+
+#ifndef HWASAN_REPLACE_OPERATORS_NEW_AND_DELETE
+#define HWASAN_REPLACE_OPERATORS_NEW_AND_DELETE HWASAN_WITH_INTERCEPTORS
+#endif
+
+typedef u8 tag_t;
+
+// TBI (Top Byte Ignore) feature of AArch64: bits [63:56] are ignored in address
+// translation and can be used to store a tag.
+const unsigned kAddressTagShift = 56;
+const uptr kAddressTagMask = 0xFFUL << kAddressTagShift;
+
+// Minimal alignment of the shadow base address. Determines the space available
+// for threads and stack histories. This is an ABI constant.
+const unsigned kShadowBaseAlignment = 32;
+
+const unsigned kRecordAddrBaseTagShift = 3;
+const unsigned kRecordFPShift = 48;
+const unsigned kRecordFPLShift = 4;
+const unsigned kRecordFPModulus = 1 << (64 - kRecordFPShift + kRecordFPLShift);
+
+static inline tag_t GetTagFromPointer(uptr p) {
+ return p >> kAddressTagShift;
+}
+
+static inline uptr UntagAddr(uptr tagged_addr) {
+ return tagged_addr & ~kAddressTagMask;
+}
+
+static inline void *UntagPtr(const void *tagged_ptr) {
+ return reinterpret_cast<void *>(
+ UntagAddr(reinterpret_cast<uptr>(tagged_ptr)));
+}
+
+static inline uptr AddTagToPointer(uptr p, tag_t tag) {
+ return (p & ~kAddressTagMask) | ((uptr)tag << kAddressTagShift);
+}
+
+namespace __hwasan {
+
+extern int hwasan_inited;
+extern bool hwasan_init_is_running;
+extern int hwasan_report_count;
+
+bool InitShadow();
+void InitPrctl();
+void InitThreads();
+void InitializeInterceptors();
+
+void HwasanAllocatorInit();
+
+void *hwasan_malloc(uptr size, StackTrace *stack);
+void *hwasan_calloc(uptr nmemb, uptr size, StackTrace *stack);
+void *hwasan_realloc(void *ptr, uptr size, StackTrace *stack);
+void *hwasan_reallocarray(void *ptr, uptr nmemb, uptr size, StackTrace *stack);
+void *hwasan_valloc(uptr size, StackTrace *stack);
+void *hwasan_pvalloc(uptr size, StackTrace *stack);
+void *hwasan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack);
+void *hwasan_memalign(uptr alignment, uptr size, StackTrace *stack);
+int hwasan_posix_memalign(void **memptr, uptr alignment, uptr size,
+ StackTrace *stack);
+void hwasan_free(void *ptr, StackTrace *stack);
+
+void InstallAtExitHandler();
+
+#define GET_MALLOC_STACK_TRACE \
+ BufferedStackTrace stack; \
+ if (hwasan_inited) \
+ stack.Unwind(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME(), \
+ nullptr, common_flags()->fast_unwind_on_malloc, \
+ common_flags()->malloc_context_size)
+
+#define GET_FATAL_STACK_TRACE_PC_BP(pc, bp) \
+ BufferedStackTrace stack; \
+ if (hwasan_inited) \
+ stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal)
+
+#define GET_FATAL_STACK_TRACE_HERE \
+ GET_FATAL_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME())
+
+#define PRINT_CURRENT_STACK_CHECK() \
+ { \
+ GET_FATAL_STACK_TRACE_HERE; \
+ stack.Print(); \
+ }
+
+void HwasanTSDInit();
+void HwasanTSDThreadInit();
+
+void HwasanOnDeadlySignal(int signo, void *info, void *context);
+
+void UpdateMemoryUsage();
+
+void AppendToErrorMessageBuffer(const char *buffer);
+
+void AndroidTestTlsSlot();
+
+} // namespace __hwasan
+
+#define HWASAN_MALLOC_HOOK(ptr, size) \
+ do { \
+ if (&__sanitizer_malloc_hook) { \
+ __sanitizer_malloc_hook(ptr, size); \
+ } \
+ RunMallocHooks(ptr, size); \
+ } while (false)
+#define HWASAN_FREE_HOOK(ptr) \
+ do { \
+ if (&__sanitizer_free_hook) { \
+ __sanitizer_free_hook(ptr); \
+ } \
+ RunFreeHooks(ptr); \
+ } while (false)
+
+#if HWASAN_WITH_INTERCEPTORS && defined(__aarch64__)
+// For both bionic and glibc __sigset_t is an unsigned long.
+typedef unsigned long __hw_sigset_t;
+// Setjmp and longjmp implementations are platform specific, and hence the
+// interception code is platform specific too. As yet we've only implemented
+// the interception for AArch64.
+typedef unsigned long long __hw_register_buf[22];
+struct __hw_jmp_buf_struct {
+ // NOTE: The machine-dependent definition of `__sigsetjmp'
+ // assume that a `__hw_jmp_buf' begins with a `__hw_register_buf' and that
+ // `__mask_was_saved' follows it. Do not move these members or add others
+ // before it.
+ __hw_register_buf __jmpbuf; // Calling environment.
+ int __mask_was_saved; // Saved the signal mask?
+ __hw_sigset_t __saved_mask; // Saved signal mask.
+};
+typedef struct __hw_jmp_buf_struct __hw_jmp_buf[1];
+typedef struct __hw_jmp_buf_struct __hw_sigjmp_buf[1];
+#endif // HWASAN_WITH_INTERCEPTORS && __aarch64__
+
+#endif // HWASAN_H
diff --git a/libsanitizer/hwasan/hwasan_allocator.cpp b/libsanitizer/hwasan/hwasan_allocator.cpp
new file mode 100644
index 0000000..0b6b734
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_allocator.cpp
@@ -0,0 +1,408 @@
+//===-- hwasan_allocator.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 HWAddressSanitizer.
+//
+// HWAddressSanitizer allocator.
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_common/sanitizer_atomic.h"
+#include "sanitizer_common/sanitizer_errno.h"
+#include "sanitizer_common/sanitizer_stackdepot.h"
+#include "hwasan.h"
+#include "hwasan_allocator.h"
+#include "hwasan_checks.h"
+#include "hwasan_mapping.h"
+#include "hwasan_malloc_bisect.h"
+#include "hwasan_thread.h"
+#include "hwasan_report.h"
+
+namespace __hwasan {
+
+static Allocator allocator;
+static AllocatorCache fallback_allocator_cache;
+static SpinMutex fallback_mutex;
+static atomic_uint8_t hwasan_allocator_tagging_enabled;
+
+static const tag_t kFallbackAllocTag = 0xBB;
+static const tag_t kFallbackFreeTag = 0xBC;
+
+enum RightAlignMode {
+ kRightAlignNever,
+ kRightAlignSometimes,
+ kRightAlignAlways
+};
+
+// Initialized in HwasanAllocatorInit, an never changed.
+static ALIGNED(16) u8 tail_magic[kShadowAlignment - 1];
+
+bool HwasanChunkView::IsAllocated() const {
+ return metadata_ && metadata_->alloc_context_id &&
+ metadata_->get_requested_size();
+}
+
+// Aligns the 'addr' right to the granule boundary.
+static uptr AlignRight(uptr addr, uptr requested_size) {
+ uptr tail_size = requested_size % kShadowAlignment;
+ if (!tail_size) return addr;
+ return addr + kShadowAlignment - tail_size;
+}
+
+uptr HwasanChunkView::Beg() const {
+ if (metadata_ && metadata_->right_aligned)
+ return AlignRight(block_, metadata_->get_requested_size());
+ return block_;
+}
+uptr HwasanChunkView::End() const {
+ return Beg() + UsedSize();
+}
+uptr HwasanChunkView::UsedSize() const {
+ return metadata_->get_requested_size();
+}
+u32 HwasanChunkView::GetAllocStackId() const {
+ return metadata_->alloc_context_id;
+}
+
+uptr HwasanChunkView::ActualSize() const {
+ return allocator.GetActuallyAllocatedSize(reinterpret_cast<void *>(block_));
+}
+
+bool HwasanChunkView::FromSmallHeap() const {
+ return allocator.FromPrimary(reinterpret_cast<void *>(block_));
+}
+
+void GetAllocatorStats(AllocatorStatCounters s) {
+ allocator.GetStats(s);
+}
+
+void HwasanAllocatorInit() {
+ atomic_store_relaxed(&hwasan_allocator_tagging_enabled,
+ !flags()->disable_allocator_tagging);
+ SetAllocatorMayReturnNull(common_flags()->allocator_may_return_null);
+ allocator.Init(common_flags()->allocator_release_to_os_interval_ms);
+ for (uptr i = 0; i < sizeof(tail_magic); i++)
+ tail_magic[i] = GetCurrentThread()->GenerateRandomTag();
+}
+
+void AllocatorSwallowThreadLocalCache(AllocatorCache *cache) {
+ allocator.SwallowCache(cache);
+}
+
+static uptr TaggedSize(uptr size) {
+ if (!size) size = 1;
+ uptr new_size = RoundUpTo(size, kShadowAlignment);
+ CHECK_GE(new_size, size);
+ return new_size;
+}
+
+static void *HwasanAllocate(StackTrace *stack, uptr orig_size, uptr alignment,
+ bool zeroise) {
+ if (orig_size > kMaxAllowedMallocSize) {
+ if (AllocatorMayReturnNull()) {
+ Report("WARNING: HWAddressSanitizer failed to allocate 0x%zx bytes\n",
+ orig_size);
+ return nullptr;
+ }
+ ReportAllocationSizeTooBig(orig_size, kMaxAllowedMallocSize, stack);
+ }
+
+ alignment = Max(alignment, kShadowAlignment);
+ uptr size = TaggedSize(orig_size);
+ Thread *t = GetCurrentThread();
+ void *allocated;
+ if (t) {
+ allocated = allocator.Allocate(t->allocator_cache(), size, alignment);
+ } else {
+ SpinMutexLock l(&fallback_mutex);
+ AllocatorCache *cache = &fallback_allocator_cache;
+ allocated = allocator.Allocate(cache, size, alignment);
+ }
+ if (UNLIKELY(!allocated)) {
+ SetAllocatorOutOfMemory();
+ if (AllocatorMayReturnNull())
+ return nullptr;
+ ReportOutOfMemory(size, stack);
+ }
+ Metadata *meta =
+ reinterpret_cast<Metadata *>(allocator.GetMetaData(allocated));
+ meta->set_requested_size(orig_size);
+ meta->alloc_context_id = StackDepotPut(*stack);
+ meta->right_aligned = false;
+ if (zeroise) {
+ internal_memset(allocated, 0, size);
+ } else if (flags()->max_malloc_fill_size > 0) {
+ uptr fill_size = Min(size, (uptr)flags()->max_malloc_fill_size);
+ internal_memset(allocated, flags()->malloc_fill_byte, fill_size);
+ }
+ if (size != orig_size) {
+ internal_memcpy(reinterpret_cast<u8 *>(allocated) + orig_size, tail_magic,
+ size - orig_size - 1);
+ }
+
+ void *user_ptr = allocated;
+ // Tagging can only be skipped when both tag_in_malloc and tag_in_free are
+ // false. When tag_in_malloc = false and tag_in_free = true malloc needs to
+ // retag to 0.
+ if ((flags()->tag_in_malloc || flags()->tag_in_free) &&
+ atomic_load_relaxed(&hwasan_allocator_tagging_enabled)) {
+ if (flags()->tag_in_malloc && malloc_bisect(stack, orig_size)) {
+ tag_t tag = t ? t->GenerateRandomTag() : kFallbackAllocTag;
+ uptr tag_size = orig_size ? orig_size : 1;
+ uptr full_granule_size = RoundDownTo(tag_size, kShadowAlignment);
+ user_ptr =
+ (void *)TagMemoryAligned((uptr)user_ptr, full_granule_size, tag);
+ if (full_granule_size != tag_size) {
+ u8 *short_granule =
+ reinterpret_cast<u8 *>(allocated) + full_granule_size;
+ TagMemoryAligned((uptr)short_granule, kShadowAlignment,
+ tag_size % kShadowAlignment);
+ short_granule[kShadowAlignment - 1] = tag;
+ }
+ } else {
+ user_ptr = (void *)TagMemoryAligned((uptr)user_ptr, size, 0);
+ }
+ }
+
+ HWASAN_MALLOC_HOOK(user_ptr, size);
+ return user_ptr;
+}
+
+static bool PointerAndMemoryTagsMatch(void *tagged_ptr) {
+ CHECK(tagged_ptr);
+ uptr tagged_uptr = reinterpret_cast<uptr>(tagged_ptr);
+ tag_t mem_tag = *reinterpret_cast<tag_t *>(
+ MemToShadow(reinterpret_cast<uptr>(UntagPtr(tagged_ptr))));
+ return PossiblyShortTagMatches(mem_tag, tagged_uptr, 1);
+}
+
+static void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) {
+ CHECK(tagged_ptr);
+ HWASAN_FREE_HOOK(tagged_ptr);
+
+ if (!PointerAndMemoryTagsMatch(tagged_ptr))
+ ReportInvalidFree(stack, reinterpret_cast<uptr>(tagged_ptr));
+
+ void *untagged_ptr = UntagPtr(tagged_ptr);
+ void *aligned_ptr = reinterpret_cast<void *>(
+ RoundDownTo(reinterpret_cast<uptr>(untagged_ptr), kShadowAlignment));
+ Metadata *meta =
+ reinterpret_cast<Metadata *>(allocator.GetMetaData(aligned_ptr));
+ uptr orig_size = meta->get_requested_size();
+ u32 free_context_id = StackDepotPut(*stack);
+ u32 alloc_context_id = meta->alloc_context_id;
+
+ // Check tail magic.
+ uptr tagged_size = TaggedSize(orig_size);
+ if (flags()->free_checks_tail_magic && orig_size &&
+ tagged_size != orig_size) {
+ uptr tail_size = tagged_size - orig_size - 1;
+ CHECK_LT(tail_size, kShadowAlignment);
+ void *tail_beg = reinterpret_cast<void *>(
+ reinterpret_cast<uptr>(aligned_ptr) + orig_size);
+ if (tail_size && internal_memcmp(tail_beg, tail_magic, tail_size))
+ ReportTailOverwritten(stack, reinterpret_cast<uptr>(tagged_ptr),
+ orig_size, tail_magic);
+ }
+
+ meta->set_requested_size(0);
+ meta->alloc_context_id = 0;
+ // This memory will not be reused by anyone else, so we are free to keep it
+ // poisoned.
+ Thread *t = GetCurrentThread();
+ if (flags()->max_free_fill_size > 0) {
+ uptr fill_size =
+ Min(TaggedSize(orig_size), (uptr)flags()->max_free_fill_size);
+ internal_memset(aligned_ptr, flags()->free_fill_byte, fill_size);
+ }
+ if (flags()->tag_in_free && malloc_bisect(stack, 0) &&
+ atomic_load_relaxed(&hwasan_allocator_tagging_enabled))
+ TagMemoryAligned(reinterpret_cast<uptr>(aligned_ptr), TaggedSize(orig_size),
+ t ? t->GenerateRandomTag() : kFallbackFreeTag);
+ if (t) {
+ allocator.Deallocate(t->allocator_cache(), aligned_ptr);
+ if (auto *ha = t->heap_allocations())
+ ha->push({reinterpret_cast<uptr>(tagged_ptr), alloc_context_id,
+ free_context_id, static_cast<u32>(orig_size)});
+ } else {
+ SpinMutexLock l(&fallback_mutex);
+ AllocatorCache *cache = &fallback_allocator_cache;
+ allocator.Deallocate(cache, aligned_ptr);
+ }
+}
+
+static void *HwasanReallocate(StackTrace *stack, void *tagged_ptr_old,
+ uptr new_size, uptr alignment) {
+ if (!PointerAndMemoryTagsMatch(tagged_ptr_old))
+ ReportInvalidFree(stack, reinterpret_cast<uptr>(tagged_ptr_old));
+
+ void *tagged_ptr_new =
+ HwasanAllocate(stack, new_size, alignment, false /*zeroise*/);
+ if (tagged_ptr_old && tagged_ptr_new) {
+ void *untagged_ptr_old = UntagPtr(tagged_ptr_old);
+ Metadata *meta =
+ reinterpret_cast<Metadata *>(allocator.GetMetaData(untagged_ptr_old));
+ internal_memcpy(
+ UntagPtr(tagged_ptr_new), untagged_ptr_old,
+ Min(new_size, static_cast<uptr>(meta->get_requested_size())));
+ HwasanDeallocate(stack, tagged_ptr_old);
+ }
+ return tagged_ptr_new;
+}
+
+static void *HwasanCalloc(StackTrace *stack, uptr nmemb, uptr size) {
+ if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
+ if (AllocatorMayReturnNull())
+ return nullptr;
+ ReportCallocOverflow(nmemb, size, stack);
+ }
+ return HwasanAllocate(stack, nmemb * size, sizeof(u64), true);
+}
+
+HwasanChunkView FindHeapChunkByAddress(uptr address) {
+ void *block = allocator.GetBlockBegin(reinterpret_cast<void*>(address));
+ if (!block)
+ return HwasanChunkView();
+ Metadata *metadata =
+ reinterpret_cast<Metadata*>(allocator.GetMetaData(block));
+ return HwasanChunkView(reinterpret_cast<uptr>(block), metadata);
+}
+
+static uptr AllocationSize(const void *tagged_ptr) {
+ const void *untagged_ptr = UntagPtr(tagged_ptr);
+ if (!untagged_ptr) return 0;
+ const void *beg = allocator.GetBlockBegin(untagged_ptr);
+ Metadata *b = (Metadata *)allocator.GetMetaData(untagged_ptr);
+ if (b->right_aligned) {
+ if (beg != reinterpret_cast<void *>(RoundDownTo(
+ reinterpret_cast<uptr>(untagged_ptr), kShadowAlignment)))
+ return 0;
+ } else {
+ if (beg != untagged_ptr) return 0;
+ }
+ return b->get_requested_size();
+}
+
+void *hwasan_malloc(uptr size, StackTrace *stack) {
+ return SetErrnoOnNull(HwasanAllocate(stack, size, sizeof(u64), false));
+}
+
+void *hwasan_calloc(uptr nmemb, uptr size, StackTrace *stack) {
+ return SetErrnoOnNull(HwasanCalloc(stack, nmemb, size));
+}
+
+void *hwasan_realloc(void *ptr, uptr size, StackTrace *stack) {
+ if (!ptr)
+ return SetErrnoOnNull(HwasanAllocate(stack, size, sizeof(u64), false));
+ if (size == 0) {
+ HwasanDeallocate(stack, ptr);
+ return nullptr;
+ }
+ return SetErrnoOnNull(HwasanReallocate(stack, ptr, size, sizeof(u64)));
+}
+
+void *hwasan_reallocarray(void *ptr, uptr nmemb, uptr size, StackTrace *stack) {
+ if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
+ errno = errno_ENOMEM;
+ if (AllocatorMayReturnNull())
+ return nullptr;
+ ReportReallocArrayOverflow(nmemb, size, stack);
+ }
+ return hwasan_realloc(ptr, nmemb * size, stack);
+}
+
+void *hwasan_valloc(uptr size, StackTrace *stack) {
+ return SetErrnoOnNull(
+ HwasanAllocate(stack, size, GetPageSizeCached(), false));
+}
+
+void *hwasan_pvalloc(uptr size, StackTrace *stack) {
+ uptr PageSize = GetPageSizeCached();
+ if (UNLIKELY(CheckForPvallocOverflow(size, PageSize))) {
+ errno = errno_ENOMEM;
+ if (AllocatorMayReturnNull())
+ return nullptr;
+ ReportPvallocOverflow(size, stack);
+ }
+ // pvalloc(0) should allocate one page.
+ size = size ? RoundUpTo(size, PageSize) : PageSize;
+ return SetErrnoOnNull(HwasanAllocate(stack, size, PageSize, false));
+}
+
+void *hwasan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack) {
+ if (UNLIKELY(!CheckAlignedAllocAlignmentAndSize(alignment, size))) {
+ errno = errno_EINVAL;
+ if (AllocatorMayReturnNull())
+ return nullptr;
+ ReportInvalidAlignedAllocAlignment(size, alignment, stack);
+ }
+ return SetErrnoOnNull(HwasanAllocate(stack, size, alignment, false));
+}
+
+void *hwasan_memalign(uptr alignment, uptr size, StackTrace *stack) {
+ if (UNLIKELY(!IsPowerOfTwo(alignment))) {
+ errno = errno_EINVAL;
+ if (AllocatorMayReturnNull())
+ return nullptr;
+ ReportInvalidAllocationAlignment(alignment, stack);
+ }
+ return SetErrnoOnNull(HwasanAllocate(stack, size, alignment, false));
+}
+
+int hwasan_posix_memalign(void **memptr, uptr alignment, uptr size,
+ StackTrace *stack) {
+ if (UNLIKELY(!CheckPosixMemalignAlignment(alignment))) {
+ if (AllocatorMayReturnNull())
+ return errno_EINVAL;
+ ReportInvalidPosixMemalignAlignment(alignment, stack);
+ }
+ void *ptr = HwasanAllocate(stack, size, alignment, false);
+ if (UNLIKELY(!ptr))
+ // OOM error is already taken care of by HwasanAllocate.
+ return errno_ENOMEM;
+ CHECK(IsAligned((uptr)ptr, alignment));
+ *(void **)UntagPtr(memptr) = ptr;
+ return 0;
+}
+
+void hwasan_free(void *ptr, StackTrace *stack) {
+ return HwasanDeallocate(stack, ptr);
+}
+
+} // namespace __hwasan
+
+using namespace __hwasan;
+
+void __hwasan_enable_allocator_tagging() {
+ atomic_store_relaxed(&hwasan_allocator_tagging_enabled, 1);
+}
+
+void __hwasan_disable_allocator_tagging() {
+ atomic_store_relaxed(&hwasan_allocator_tagging_enabled, 0);
+}
+
+uptr __sanitizer_get_current_allocated_bytes() {
+ uptr stats[AllocatorStatCount];
+ allocator.GetStats(stats);
+ return stats[AllocatorStatAllocated];
+}
+
+uptr __sanitizer_get_heap_size() {
+ uptr stats[AllocatorStatCount];
+ allocator.GetStats(stats);
+ return stats[AllocatorStatMapped];
+}
+
+uptr __sanitizer_get_free_bytes() { return 1; }
+
+uptr __sanitizer_get_unmapped_bytes() { return 1; }
+
+uptr __sanitizer_get_estimated_allocated_size(uptr size) { return size; }
+
+int __sanitizer_get_ownership(const void *p) { return AllocationSize(p) != 0; }
+
+uptr __sanitizer_get_allocated_size(const void *p) { return AllocationSize(p); }
diff --git a/libsanitizer/hwasan/hwasan_allocator.h b/libsanitizer/hwasan/hwasan_allocator.h
new file mode 100644
index 0000000..43670a6
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_allocator.h
@@ -0,0 +1,107 @@
+//===-- hwasan_allocator.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 HWAddressSanitizer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef HWASAN_ALLOCATOR_H
+#define HWASAN_ALLOCATOR_H
+
+#include "sanitizer_common/sanitizer_allocator.h"
+#include "sanitizer_common/sanitizer_allocator_checks.h"
+#include "sanitizer_common/sanitizer_allocator_interface.h"
+#include "sanitizer_common/sanitizer_allocator_report.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_ring_buffer.h"
+#include "hwasan_poisoning.h"
+
+#if !defined(__aarch64__) && !defined(__x86_64__)
+#error Unsupported platform
+#endif
+
+namespace __hwasan {
+
+struct Metadata {
+ u32 requested_size_low;
+ u32 requested_size_high : 31;
+ u32 right_aligned : 1;
+ u32 alloc_context_id;
+ u64 get_requested_size() {
+ return (static_cast<u64>(requested_size_high) << 32) + requested_size_low;
+ }
+ void set_requested_size(u64 size) {
+ requested_size_low = size & ((1ul << 32) - 1);
+ requested_size_high = size >> 32;
+ }
+};
+
+struct HwasanMapUnmapCallback {
+ void OnMap(uptr p, uptr size) const { UpdateMemoryUsage(); }
+ void OnUnmap(uptr p, uptr size) const {
+ // We are about to unmap a chunk of user memory.
+ // It can return as user-requested mmap() or another thread stack.
+ // Make it accessible with zero-tagged pointer.
+ TagMemory(p, size, 0);
+ }
+};
+
+static const uptr kMaxAllowedMallocSize = 1UL << 40; // 1T
+
+struct AP64 {
+ static const uptr kSpaceBeg = ~0ULL;
+ static const uptr kSpaceSize = 0x2000000000ULL;
+ static const uptr kMetadataSize = sizeof(Metadata);
+ typedef __sanitizer::VeryDenseSizeClassMap SizeClassMap;
+ using AddressSpaceView = LocalAddressSpaceView;
+ typedef HwasanMapUnmapCallback MapUnmapCallback;
+ static const uptr kFlags = 0;
+};
+typedef SizeClassAllocator64<AP64> PrimaryAllocator;
+typedef CombinedAllocator<PrimaryAllocator> Allocator;
+typedef Allocator::AllocatorCache AllocatorCache;
+
+void AllocatorSwallowThreadLocalCache(AllocatorCache *cache);
+
+class HwasanChunkView {
+ public:
+ HwasanChunkView() : block_(0), metadata_(nullptr) {}
+ HwasanChunkView(uptr block, Metadata *metadata)
+ : block_(block), metadata_(metadata) {}
+ bool IsAllocated() const; // Checks if the memory is currently allocated
+ uptr Beg() const; // First byte of user memory
+ uptr End() const; // Last byte of user memory
+ uptr UsedSize() const; // Size requested by the user
+ uptr ActualSize() const; // Size allocated by the allocator.
+ u32 GetAllocStackId() const;
+ bool FromSmallHeap() const;
+ private:
+ uptr block_;
+ Metadata *const metadata_;
+};
+
+HwasanChunkView FindHeapChunkByAddress(uptr address);
+
+// Information about one (de)allocation that happened in the past.
+// These are recorded in a thread-local ring buffer.
+// TODO: this is currently 24 bytes (20 bytes + alignment).
+// Compress it to 16 bytes or extend it to be more useful.
+struct HeapAllocationRecord {
+ uptr tagged_addr;
+ u32 alloc_context_id;
+ u32 free_context_id;
+ u32 requested_size;
+};
+
+typedef RingBuffer<HeapAllocationRecord> HeapAllocationsRingBuffer;
+
+void GetAllocatorStats(AllocatorStatCounters s);
+
+} // namespace __hwasan
+
+#endif // HWASAN_ALLOCATOR_H
diff --git a/libsanitizer/hwasan/hwasan_checks.h b/libsanitizer/hwasan/hwasan_checks.h
new file mode 100644
index 0000000..a8de0fe
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_checks.h
@@ -0,0 +1,124 @@
+//===-- hwasan_checks.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 HWAddressSanitizer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef HWASAN_CHECKS_H
+#define HWASAN_CHECKS_H
+
+#include "hwasan_mapping.h"
+#include "sanitizer_common/sanitizer_common.h"
+
+namespace __hwasan {
+template <unsigned X>
+__attribute__((always_inline)) static void SigTrap(uptr p) {
+#if defined(__aarch64__)
+ (void)p;
+ // 0x900 is added to do not interfere with the kernel use of lower values of
+ // brk immediate.
+ register uptr x0 asm("x0") = p;
+ asm("brk %1\n\t" ::"r"(x0), "n"(0x900 + X));
+#elif defined(__x86_64__)
+ // INT3 + NOP DWORD ptr [EAX + X] to pass X to our signal handler, 5 bytes
+ // total. The pointer is passed via rdi.
+ // 0x40 is added as a safeguard, to help distinguish our trap from others and
+ // to avoid 0 offsets in the command (otherwise it'll be reduced to a
+ // different nop command, the three bytes one).
+ asm volatile(
+ "int3\n"
+ "nopl %c0(%%rax)\n" ::"n"(0x40 + X),
+ "D"(p));
+#else
+ // FIXME: not always sigill.
+ __builtin_trap();
+#endif
+ // __builtin_unreachable();
+}
+
+// Version with access size which is not power of 2
+template <unsigned X>
+__attribute__((always_inline)) static void SigTrap(uptr p, uptr size) {
+#if defined(__aarch64__)
+ register uptr x0 asm("x0") = p;
+ register uptr x1 asm("x1") = size;
+ asm("brk %2\n\t" ::"r"(x0), "r"(x1), "n"(0x900 + X));
+#elif defined(__x86_64__)
+ // Size is stored in rsi.
+ asm volatile(
+ "int3\n"
+ "nopl %c0(%%rax)\n" ::"n"(0x40 + X),
+ "D"(p), "S"(size));
+#else
+ __builtin_trap();
+#endif
+ // __builtin_unreachable();
+}
+
+__attribute__((always_inline, nodebug)) static bool PossiblyShortTagMatches(
+ tag_t mem_tag, uptr ptr, uptr sz) {
+ tag_t ptr_tag = GetTagFromPointer(ptr);
+ if (ptr_tag == mem_tag)
+ return true;
+ if (mem_tag >= kShadowAlignment)
+ return false;
+ if ((ptr & (kShadowAlignment - 1)) + sz > mem_tag)
+ return false;
+#ifndef __aarch64__
+ ptr = UntagAddr(ptr);
+#endif
+ return *(u8 *)(ptr | (kShadowAlignment - 1)) == ptr_tag;
+}
+
+enum class ErrorAction { Abort, Recover };
+enum class AccessType { Load, Store };
+
+template <ErrorAction EA, AccessType AT, unsigned LogSize>
+__attribute__((always_inline, nodebug)) static void CheckAddress(uptr p) {
+ uptr ptr_raw = p & ~kAddressTagMask;
+ tag_t mem_tag = *(tag_t *)MemToShadow(ptr_raw);
+ if (UNLIKELY(!PossiblyShortTagMatches(mem_tag, p, 1 << LogSize))) {
+ SigTrap<0x20 * (EA == ErrorAction::Recover) +
+ 0x10 * (AT == AccessType::Store) + LogSize>(p);
+ if (EA == ErrorAction::Abort)
+ __builtin_unreachable();
+ }
+}
+
+template <ErrorAction EA, AccessType AT>
+__attribute__((always_inline, nodebug)) static void CheckAddressSized(uptr p,
+ uptr sz) {
+ if (sz == 0)
+ return;
+ tag_t ptr_tag = GetTagFromPointer(p);
+ uptr ptr_raw = p & ~kAddressTagMask;
+ tag_t *shadow_first = (tag_t *)MemToShadow(ptr_raw);
+ tag_t *shadow_last = (tag_t *)MemToShadow(ptr_raw + sz);
+ for (tag_t *t = shadow_first; t < shadow_last; ++t)
+ if (UNLIKELY(ptr_tag != *t)) {
+ SigTrap<0x20 * (EA == ErrorAction::Recover) +
+ 0x10 * (AT == AccessType::Store) + 0xf>(p, sz);
+ if (EA == ErrorAction::Abort)
+ __builtin_unreachable();
+ }
+ uptr end = p + sz;
+ uptr tail_sz = end & 0xf;
+ if (UNLIKELY(tail_sz != 0 &&
+ !PossiblyShortTagMatches(
+ *shadow_last, end & ~(kShadowAlignment - 1), tail_sz))) {
+ SigTrap<0x20 * (EA == ErrorAction::Recover) +
+ 0x10 * (AT == AccessType::Store) + 0xf>(p, sz);
+ if (EA == ErrorAction::Abort)
+ __builtin_unreachable();
+ }
+}
+
+} // end namespace __hwasan
+
+#endif // HWASAN_CHECKS_H
diff --git a/libsanitizer/hwasan/hwasan_dynamic_shadow.cpp b/libsanitizer/hwasan/hwasan_dynamic_shadow.cpp
new file mode 100644
index 0000000..12730b2
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_dynamic_shadow.cpp
@@ -0,0 +1,126 @@
+//===-- hwasan_dynamic_shadow.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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file is a part of HWAddressSanitizer. It reserves dynamic shadow memory
+/// region and handles ifunc resolver case, when necessary.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hwasan.h"
+#include "hwasan_dynamic_shadow.h"
+#include "hwasan_mapping.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_posix.h"
+
+#include <elf.h>
+#include <link.h>
+
+// The code in this file needs to run in an unrelocated binary. It should not
+// access any external symbol, including its own non-hidden globals.
+
+#if SANITIZER_ANDROID
+extern "C" {
+
+INTERFACE_ATTRIBUTE void __hwasan_shadow();
+decltype(__hwasan_shadow)* __hwasan_premap_shadow();
+
+} // extern "C"
+
+namespace __hwasan {
+
+// Conservative upper limit.
+static uptr PremapShadowSize() {
+ return RoundUpTo(GetMaxVirtualAddress() >> kShadowScale,
+ GetMmapGranularity());
+}
+
+static uptr PremapShadow() {
+ return MapDynamicShadow(PremapShadowSize(), kShadowScale,
+ kShadowBaseAlignment, kHighMemEnd);
+}
+
+static bool IsPremapShadowAvailable() {
+ const uptr shadow = reinterpret_cast<uptr>(&__hwasan_shadow);
+ const uptr resolver = reinterpret_cast<uptr>(&__hwasan_premap_shadow);
+ // shadow == resolver is how Android KitKat and older handles ifunc.
+ // shadow == 0 just in case.
+ return shadow != 0 && shadow != resolver;
+}
+
+static uptr FindPremappedShadowStart(uptr shadow_size_bytes) {
+ const uptr granularity = GetMmapGranularity();
+ const uptr shadow_start = reinterpret_cast<uptr>(&__hwasan_shadow);
+ const uptr premap_shadow_size = PremapShadowSize();
+ const uptr shadow_size = RoundUpTo(shadow_size_bytes, granularity);
+
+ // We may have mapped too much. Release extra memory.
+ UnmapFromTo(shadow_start + shadow_size, shadow_start + premap_shadow_size);
+ return shadow_start;
+}
+
+} // namespace __hwasan
+
+extern "C" {
+
+decltype(__hwasan_shadow)* __hwasan_premap_shadow() {
+ // The resolver might be called multiple times. Map the shadow just once.
+ static __sanitizer::uptr shadow = 0;
+ if (!shadow)
+ shadow = __hwasan::PremapShadow();
+ return reinterpret_cast<decltype(__hwasan_shadow)*>(shadow);
+}
+
+// __hwasan_shadow is a "function" that has the same address as the first byte
+// of the shadow mapping.
+INTERFACE_ATTRIBUTE __attribute__((ifunc("__hwasan_premap_shadow")))
+void __hwasan_shadow();
+
+extern __attribute((weak, visibility("hidden"))) ElfW(Rela) __rela_iplt_start[],
+ __rela_iplt_end[];
+
+} // extern "C"
+
+namespace __hwasan {
+
+void InitShadowGOT() {
+ // Call the ifunc resolver for __hwasan_shadow and fill in its GOT entry. This
+ // needs to be done before other ifunc resolvers (which are handled by libc)
+ // because a resolver might read __hwasan_shadow.
+ typedef ElfW(Addr) (*ifunc_resolver_t)(void);
+ for (ElfW(Rela) *r = __rela_iplt_start; r != __rela_iplt_end; ++r) {
+ ElfW(Addr)* offset = reinterpret_cast<ElfW(Addr)*>(r->r_offset);
+ ElfW(Addr) resolver = r->r_addend;
+ if (resolver == reinterpret_cast<ElfW(Addr)>(&__hwasan_premap_shadow)) {
+ *offset = reinterpret_cast<ifunc_resolver_t>(resolver)();
+ break;
+ }
+ }
+}
+
+uptr FindDynamicShadowStart(uptr shadow_size_bytes) {
+ if (IsPremapShadowAvailable())
+ return FindPremappedShadowStart(shadow_size_bytes);
+ return MapDynamicShadow(shadow_size_bytes, kShadowScale, kShadowBaseAlignment,
+ kHighMemEnd);
+}
+
+} // namespace __hwasan
+#else
+namespace __hwasan {
+
+void InitShadowGOT() {}
+
+uptr FindDynamicShadowStart(uptr shadow_size_bytes) {
+ return MapDynamicShadow(shadow_size_bytes, kShadowScale, kShadowBaseAlignment,
+ kHighMemEnd);
+}
+
+} // namespace __hwasan
+
+#endif // SANITIZER_ANDROID
diff --git a/libsanitizer/hwasan/hwasan_dynamic_shadow.h b/libsanitizer/hwasan/hwasan_dynamic_shadow.h
new file mode 100644
index 0000000..3c2e7c7
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_dynamic_shadow.h
@@ -0,0 +1,27 @@
+//===-- hwasan_dynamic_shadow.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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file is a part of HWAddressSanitizer. It reserves dynamic shadow memory
+/// region.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef HWASAN_PREMAP_SHADOW_H
+#define HWASAN_PREMAP_SHADOW_H
+
+#include "sanitizer_common/sanitizer_internal_defs.h"
+
+namespace __hwasan {
+
+uptr FindDynamicShadowStart(uptr shadow_size_bytes);
+void InitShadowGOT();
+
+} // namespace __hwasan
+
+#endif // HWASAN_PREMAP_SHADOW_H
diff --git a/libsanitizer/hwasan/hwasan_exceptions.cpp b/libsanitizer/hwasan/hwasan_exceptions.cpp
new file mode 100644
index 0000000..169e787
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_exceptions.cpp
@@ -0,0 +1,67 @@
+//===-- hwasan_exceptions.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 HWAddressSanitizer.
+//
+// HWAddressSanitizer runtime.
+//===----------------------------------------------------------------------===//
+
+#include "hwasan_poisoning.h"
+#include "sanitizer_common/sanitizer_common.h"
+
+#include <unwind.h>
+
+using namespace __hwasan;
+using namespace __sanitizer;
+
+typedef _Unwind_Reason_Code PersonalityFn(int version, _Unwind_Action actions,
+ uint64_t exception_class,
+ _Unwind_Exception* unwind_exception,
+ _Unwind_Context* context);
+
+// Pointers to the _Unwind_GetGR and _Unwind_GetCFA functions are passed in
+// instead of being called directly. This is to handle cases where the unwinder
+// is statically linked and the sanitizer runtime and the program are linked
+// against different unwinders. The _Unwind_Context data structure is opaque so
+// it may be incompatible between unwinders.
+typedef _Unwind_Word GetGRFn(_Unwind_Context* context, int index);
+typedef _Unwind_Word GetCFAFn(_Unwind_Context* context);
+
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE _Unwind_Reason_Code
+__hwasan_personality_wrapper(int version, _Unwind_Action actions,
+ uint64_t exception_class,
+ _Unwind_Exception* unwind_exception,
+ _Unwind_Context* context,
+ PersonalityFn* real_personality, GetGRFn* get_gr,
+ GetCFAFn* get_cfa) {
+ _Unwind_Reason_Code rc;
+ if (real_personality)
+ rc = real_personality(version, actions, exception_class, unwind_exception,
+ context);
+ else
+ rc = _URC_CONTINUE_UNWIND;
+
+ // We only untag frames without a landing pad because landing pads are
+ // responsible for untagging the stack themselves if they resume.
+ //
+ // Here we assume that the frame record appears after any locals. This is not
+ // required by AAPCS but is a requirement for HWASAN instrumented functions.
+ if ((actions & _UA_CLEANUP_PHASE) && rc == _URC_CONTINUE_UNWIND) {
+#if defined(__x86_64__)
+ uptr fp = get_gr(context, 6); // rbp
+#elif defined(__aarch64__)
+ uptr fp = get_gr(context, 29); // x29
+#else
+#error Unsupported architecture
+#endif
+ uptr sp = get_cfa(context);
+ TagMemory(sp, fp - sp, 0);
+ }
+
+ return rc;
+}
diff --git a/libsanitizer/hwasan/hwasan_flags.h b/libsanitizer/hwasan/hwasan_flags.h
new file mode 100644
index 0000000..0a6998f
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_flags.h
@@ -0,0 +1,29 @@
+//===-- hwasan_flags.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 HWAddressSanitizer.
+//
+//===----------------------------------------------------------------------===//
+#ifndef HWASAN_FLAGS_H
+#define HWASAN_FLAGS_H
+
+namespace __hwasan {
+
+struct Flags {
+#define HWASAN_FLAG(Type, Name, DefaultValue, Description) Type Name;
+#include "hwasan_flags.inc"
+#undef HWASAN_FLAG
+
+ void SetDefaults();
+};
+
+Flags *flags();
+
+} // namespace __hwasan
+
+#endif // HWASAN_FLAGS_H
diff --git a/libsanitizer/hwasan/hwasan_flags.inc b/libsanitizer/hwasan/hwasan_flags.inc
new file mode 100644
index 0000000..8e431d9
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_flags.inc
@@ -0,0 +1,74 @@
+//===-- hwasan_flags.inc ----------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Hwasan runtime flags.
+//
+//===----------------------------------------------------------------------===//
+#ifndef HWASAN_FLAG
+# error "Define HWASAN_FLAG prior to including this file!"
+#endif
+
+// HWASAN_FLAG(Type, Name, DefaultValue, Description)
+// See COMMON_FLAG in sanitizer_flags.inc for more details.
+
+HWASAN_FLAG(bool, verbose_threads, false,
+ "inform on thread creation/destruction")
+HWASAN_FLAG(bool, tag_in_malloc, true, "")
+HWASAN_FLAG(bool, tag_in_free, true, "")
+HWASAN_FLAG(bool, print_stats, false, "")
+HWASAN_FLAG(bool, halt_on_error, true, "")
+HWASAN_FLAG(bool, atexit, false, "")
+
+// Test only flag to disable malloc/realloc/free memory tagging on startup.
+// Tagging can be reenabled with __hwasan_enable_allocator_tagging().
+HWASAN_FLAG(bool, disable_allocator_tagging, false, "")
+
+// If false, use simple increment of a thread local counter to generate new
+// tags.
+HWASAN_FLAG(bool, random_tags, true, "")
+
+HWASAN_FLAG(
+ int, max_malloc_fill_size, 0,
+ "HWASan allocator flag. max_malloc_fill_size is the maximal amount of "
+ "bytes that will be filled with malloc_fill_byte on malloc.")
+
+HWASAN_FLAG(bool, free_checks_tail_magic, 1,
+ "If set, free() will check the magic values "
+ "to the right of the allocated object "
+ "if the allocation size is not a divident of the granule size")
+HWASAN_FLAG(
+ int, max_free_fill_size, 0,
+ "HWASan allocator flag. max_free_fill_size is the maximal amount of "
+ "bytes that will be filled with free_fill_byte during free.")
+HWASAN_FLAG(int, malloc_fill_byte, 0xbe,
+ "Value used to fill the newly allocated memory.")
+HWASAN_FLAG(int, free_fill_byte, 0x55,
+ "Value used to fill deallocated memory.")
+HWASAN_FLAG(int, heap_history_size, 1023,
+ "The number of heap (de)allocations remembered per thread. "
+ "Affects the quality of heap-related reports, but not the ability "
+ "to find bugs.")
+HWASAN_FLAG(bool, export_memory_stats, true,
+ "Export up-to-date memory stats through /proc")
+HWASAN_FLAG(int, stack_history_size, 1024,
+ "The number of stack frames remembered per thread. "
+ "Affects the quality of stack-related reports, but not the ability "
+ "to find bugs.")
+
+// Malloc / free bisection. Only tag malloc and free calls when a hash of
+// allocation size and stack trace is between malloc_bisect_left and
+// malloc_bisect_right (both inclusive). [0, 0] range is special and disables
+// bisection (i.e. everything is tagged). Once the range is narrowed down
+// enough, use malloc_bisect_dump to see interesting allocations.
+HWASAN_FLAG(uptr, malloc_bisect_left, 0,
+ "Left bound of malloc bisection, inclusive.")
+HWASAN_FLAG(uptr, malloc_bisect_right, 0,
+ "Right bound of malloc bisection, inclusive.")
+HWASAN_FLAG(bool, malloc_bisect_dump, false,
+ "Print all allocations within [malloc_bisect_left, "
+ "malloc_bisect_right] range ")
diff --git a/libsanitizer/hwasan/hwasan_globals.cpp b/libsanitizer/hwasan/hwasan_globals.cpp
new file mode 100644
index 0000000..d71bcd7
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_globals.cpp
@@ -0,0 +1,91 @@
+//===-- hwasan_globals.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 HWAddressSanitizer.
+//
+// HWAddressSanitizer globals-specific runtime.
+//===----------------------------------------------------------------------===//
+
+#include "hwasan_globals.h"
+
+namespace __hwasan {
+
+enum { NT_LLVM_HWASAN_GLOBALS = 3 };
+struct hwasan_global_note {
+ s32 begin_relptr;
+ s32 end_relptr;
+};
+
+// Check that the given library meets the code model requirements for tagged
+// globals. These properties are not checked at link time so they need to be
+// checked at runtime.
+static void CheckCodeModel(ElfW(Addr) base, const ElfW(Phdr) * phdr,
+ ElfW(Half) phnum) {
+ ElfW(Addr) min_addr = -1ull, max_addr = 0;
+ for (unsigned i = 0; i != phnum; ++i) {
+ if (phdr[i].p_type != PT_LOAD)
+ continue;
+ ElfW(Addr) lo = base + phdr[i].p_vaddr, hi = lo + phdr[i].p_memsz;
+ if (min_addr > lo)
+ min_addr = lo;
+ if (max_addr < hi)
+ max_addr = hi;
+ }
+
+ if (max_addr - min_addr > 1ull << 32) {
+ Report("FATAL: HWAddressSanitizer: library size exceeds 2^32\n");
+ Die();
+ }
+ if (max_addr > 1ull << 48) {
+ Report("FATAL: HWAddressSanitizer: library loaded above address 2^48\n");
+ Die();
+ }
+}
+
+ArrayRef<const hwasan_global> HwasanGlobalsFor(ElfW(Addr) base,
+ const ElfW(Phdr) * phdr,
+ ElfW(Half) phnum) {
+ // Read the phdrs from this DSO.
+ for (unsigned i = 0; i != phnum; ++i) {
+ if (phdr[i].p_type != PT_NOTE)
+ continue;
+
+ const char *note = reinterpret_cast<const char *>(base + phdr[i].p_vaddr);
+ const char *nend = note + phdr[i].p_memsz;
+
+ // Traverse all the notes until we find a HWASan note.
+ while (note < nend) {
+ auto *nhdr = reinterpret_cast<const ElfW(Nhdr) *>(note);
+ const char *name = note + sizeof(ElfW(Nhdr));
+ const char *desc = name + RoundUpTo(nhdr->n_namesz, 4);
+
+ // Discard non-HWASan-Globals notes.
+ if (nhdr->n_type != NT_LLVM_HWASAN_GLOBALS ||
+ internal_strcmp(name, "LLVM") != 0) {
+ note = desc + RoundUpTo(nhdr->n_descsz, 4);
+ continue;
+ }
+
+ // Only libraries with instrumented globals need to be checked against the
+ // code model since they use relocations that aren't checked at link time.
+ CheckCodeModel(base, phdr, phnum);
+
+ auto *global_note = reinterpret_cast<const hwasan_global_note *>(desc);
+ auto *globals_begin = reinterpret_cast<const hwasan_global *>(
+ note + global_note->begin_relptr);
+ auto *globals_end = reinterpret_cast<const hwasan_global *>(
+ note + global_note->end_relptr);
+
+ return {globals_begin, globals_end};
+ }
+ }
+
+ return {};
+}
+
+} // namespace __hwasan
diff --git a/libsanitizer/hwasan/hwasan_globals.h b/libsanitizer/hwasan/hwasan_globals.h
new file mode 100644
index 0000000..fd7adf7
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_globals.h
@@ -0,0 +1,49 @@
+//===-- hwasan_globals.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 HWAddressSanitizer.
+//
+// Private Hwasan header.
+//===----------------------------------------------------------------------===//
+
+#ifndef HWASAN_GLOBALS_H
+#define HWASAN_GLOBALS_H
+
+#include <link.h>
+
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_internal_defs.h"
+
+namespace __hwasan {
+// This object should only ever be casted over the global (i.e. not constructed)
+// in the ELF PT_NOTE in order for `addr()` to work correctly.
+struct hwasan_global {
+ // The size of this global variable. Note that the size in the descriptor is
+ // max 1 << 24. Larger globals have multiple descriptors.
+ uptr size() const { return info & 0xffffff; }
+ // The fully-relocated address of this global.
+ uptr addr() const { return reinterpret_cast<uintptr_t>(this) + gv_relptr; }
+ // The static tag of this global.
+ u8 tag() const { return info >> 24; };
+
+ // The relative address between the start of the descriptor for the HWASan
+ // global (in the PT_NOTE), and the fully relocated address of the global.
+ s32 gv_relptr;
+ u32 info;
+};
+
+// Walk through the specific DSO (as specified by the base, phdr, and phnum),
+// and return the range of the [beginning, end) of the HWASan globals descriptor
+// array.
+ArrayRef<const hwasan_global> HwasanGlobalsFor(ElfW(Addr) base,
+ const ElfW(Phdr) * phdr,
+ ElfW(Half) phnum);
+
+} // namespace __hwasan
+
+#endif // HWASAN_GLOBALS_H
diff --git a/libsanitizer/hwasan/hwasan_interceptors.cpp b/libsanitizer/hwasan/hwasan_interceptors.cpp
new file mode 100644
index 0000000..44e569e
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_interceptors.cpp
@@ -0,0 +1,349 @@
+//===-- hwasan_interceptors.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 HWAddressSanitizer.
+//
+// Interceptors for standard library functions.
+//
+// FIXME: move as many interceptors as possible into
+// sanitizer_common/sanitizer_common_interceptors.h
+//===----------------------------------------------------------------------===//
+
+#include "interception/interception.h"
+#include "hwasan.h"
+#include "hwasan_allocator.h"
+#include "hwasan_mapping.h"
+#include "hwasan_thread.h"
+#include "hwasan_poisoning.h"
+#include "hwasan_report.h"
+#include "sanitizer_common/sanitizer_platform_limits_posix.h"
+#include "sanitizer_common/sanitizer_allocator.h"
+#include "sanitizer_common/sanitizer_allocator_interface.h"
+#include "sanitizer_common/sanitizer_allocator_internal.h"
+#include "sanitizer_common/sanitizer_atomic.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_errno.h"
+#include "sanitizer_common/sanitizer_stackdepot.h"
+#include "sanitizer_common/sanitizer_libc.h"
+#include "sanitizer_common/sanitizer_linux.h"
+#include "sanitizer_common/sanitizer_tls_get_addr.h"
+
+#include <stdarg.h>
+// ACHTUNG! No other system header includes in this file.
+// Ideally, we should get rid of stdarg.h as well.
+
+using namespace __hwasan;
+
+using __sanitizer::memory_order;
+using __sanitizer::atomic_load;
+using __sanitizer::atomic_store;
+using __sanitizer::atomic_uintptr_t;
+
+static uptr allocated_for_dlsym;
+static const uptr kDlsymAllocPoolSize = 1024;
+static uptr alloc_memory_for_dlsym[kDlsymAllocPoolSize];
+
+static bool IsInDlsymAllocPool(const void *ptr) {
+ uptr off = (uptr)ptr - (uptr)alloc_memory_for_dlsym;
+ return off < sizeof(alloc_memory_for_dlsym);
+}
+
+static void *AllocateFromLocalPool(uptr size_in_bytes) {
+ uptr size_in_words = RoundUpTo(size_in_bytes, kWordSize) / kWordSize;
+ void *mem = (void *)&alloc_memory_for_dlsym[allocated_for_dlsym];
+ allocated_for_dlsym += size_in_words;
+ CHECK_LT(allocated_for_dlsym, kDlsymAllocPoolSize);
+ return mem;
+}
+
+#define ENSURE_HWASAN_INITED() do { \
+ CHECK(!hwasan_init_is_running); \
+ if (!hwasan_inited) { \
+ __hwasan_init(); \
+ } \
+} while (0)
+
+
+int __sanitizer_posix_memalign(void **memptr, uptr alignment, uptr size) {
+ GET_MALLOC_STACK_TRACE;
+ CHECK_NE(memptr, 0);
+ int res = hwasan_posix_memalign(memptr, alignment, size, &stack);
+ return res;
+}
+
+void * __sanitizer_memalign(uptr alignment, uptr size) {
+ GET_MALLOC_STACK_TRACE;
+ return hwasan_memalign(alignment, size, &stack);
+}
+
+void * __sanitizer_aligned_alloc(uptr alignment, uptr size) {
+ GET_MALLOC_STACK_TRACE;
+ return hwasan_aligned_alloc(alignment, size, &stack);
+}
+
+void * __sanitizer___libc_memalign(uptr alignment, uptr size) {
+ GET_MALLOC_STACK_TRACE;
+ void *ptr = hwasan_memalign(alignment, size, &stack);
+ if (ptr)
+ DTLS_on_libc_memalign(ptr, size);
+ return ptr;
+}
+
+void * __sanitizer_valloc(uptr size) {
+ GET_MALLOC_STACK_TRACE;
+ return hwasan_valloc(size, &stack);
+}
+
+void * __sanitizer_pvalloc(uptr size) {
+ GET_MALLOC_STACK_TRACE;
+ return hwasan_pvalloc(size, &stack);
+}
+
+void __sanitizer_free(void *ptr) {
+ GET_MALLOC_STACK_TRACE;
+ if (!ptr || UNLIKELY(IsInDlsymAllocPool(ptr))) return;
+ hwasan_free(ptr, &stack);
+}
+
+void __sanitizer_cfree(void *ptr) {
+ GET_MALLOC_STACK_TRACE;
+ if (!ptr || UNLIKELY(IsInDlsymAllocPool(ptr))) return;
+ hwasan_free(ptr, &stack);
+}
+
+uptr __sanitizer_malloc_usable_size(const void *ptr) {
+ return __sanitizer_get_allocated_size(ptr);
+}
+
+struct __sanitizer_struct_mallinfo __sanitizer_mallinfo() {
+ __sanitizer_struct_mallinfo sret;
+ internal_memset(&sret, 0, sizeof(sret));
+ return sret;
+}
+
+int __sanitizer_mallopt(int cmd, int value) {
+ return 0;
+}
+
+void __sanitizer_malloc_stats(void) {
+ // FIXME: implement, but don't call REAL(malloc_stats)!
+}
+
+void * __sanitizer_calloc(uptr nmemb, uptr size) {
+ GET_MALLOC_STACK_TRACE;
+ if (UNLIKELY(!hwasan_inited))
+ // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
+ return AllocateFromLocalPool(nmemb * size);
+ return hwasan_calloc(nmemb, size, &stack);
+}
+
+void * __sanitizer_realloc(void *ptr, uptr size) {
+ GET_MALLOC_STACK_TRACE;
+ if (UNLIKELY(IsInDlsymAllocPool(ptr))) {
+ uptr offset = (uptr)ptr - (uptr)alloc_memory_for_dlsym;
+ uptr copy_size = Min(size, kDlsymAllocPoolSize - offset);
+ void *new_ptr;
+ if (UNLIKELY(!hwasan_inited)) {
+ new_ptr = AllocateFromLocalPool(copy_size);
+ } else {
+ copy_size = size;
+ new_ptr = hwasan_malloc(copy_size, &stack);
+ }
+ internal_memcpy(new_ptr, ptr, copy_size);
+ return new_ptr;
+ }
+ return hwasan_realloc(ptr, size, &stack);
+}
+
+void * __sanitizer_reallocarray(void *ptr, uptr nmemb, uptr size) {
+ GET_MALLOC_STACK_TRACE;
+ return hwasan_reallocarray(ptr, nmemb, size, &stack);
+}
+
+void * __sanitizer_malloc(uptr size) {
+ GET_MALLOC_STACK_TRACE;
+ if (UNLIKELY(!hwasan_init_is_running))
+ ENSURE_HWASAN_INITED();
+ if (UNLIKELY(!hwasan_inited))
+ // Hack: dlsym calls malloc before REAL(malloc) is retrieved from dlsym.
+ return AllocateFromLocalPool(size);
+ return hwasan_malloc(size, &stack);
+}
+
+#if HWASAN_WITH_INTERCEPTORS
+#define INTERCEPTOR_ALIAS(RET, FN, ARGS...) \
+ extern "C" SANITIZER_INTERFACE_ATTRIBUTE RET WRAP(FN)(ARGS) \
+ ALIAS("__sanitizer_" #FN); \
+ extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE RET FN( \
+ ARGS) ALIAS("__sanitizer_" #FN)
+
+INTERCEPTOR_ALIAS(int, posix_memalign, void **memptr, SIZE_T alignment,
+ SIZE_T size);
+INTERCEPTOR_ALIAS(void *, aligned_alloc, SIZE_T alignment, SIZE_T size);
+INTERCEPTOR_ALIAS(void *, __libc_memalign, SIZE_T alignment, SIZE_T size);
+INTERCEPTOR_ALIAS(void *, valloc, SIZE_T size);
+INTERCEPTOR_ALIAS(void, free, void *ptr);
+INTERCEPTOR_ALIAS(uptr, malloc_usable_size, const void *ptr);
+INTERCEPTOR_ALIAS(void *, calloc, SIZE_T nmemb, SIZE_T size);
+INTERCEPTOR_ALIAS(void *, realloc, void *ptr, SIZE_T size);
+INTERCEPTOR_ALIAS(void *, reallocarray, void *ptr, SIZE_T nmemb, SIZE_T size);
+INTERCEPTOR_ALIAS(void *, malloc, SIZE_T size);
+
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
+INTERCEPTOR_ALIAS(void *, memalign, SIZE_T alignment, SIZE_T size);
+INTERCEPTOR_ALIAS(void *, pvalloc, SIZE_T size);
+INTERCEPTOR_ALIAS(void, cfree, void *ptr);
+INTERCEPTOR_ALIAS(__sanitizer_struct_mallinfo, mallinfo);
+INTERCEPTOR_ALIAS(int, mallopt, int cmd, int value);
+INTERCEPTOR_ALIAS(void, malloc_stats, void);
+#endif
+
+struct ThreadStartArg {
+ thread_callback_t callback;
+ void *param;
+};
+
+static void *HwasanThreadStartFunc(void *arg) {
+ __hwasan_thread_enter();
+ ThreadStartArg A = *reinterpret_cast<ThreadStartArg*>(arg);
+ UnmapOrDie(arg, GetPageSizeCached());
+ return A.callback(A.param);
+}
+
+INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
+ void * param) {
+ ScopedTaggingDisabler disabler;
+ ThreadStartArg *A = reinterpret_cast<ThreadStartArg *> (MmapOrDie(
+ GetPageSizeCached(), "pthread_create"));
+ *A = {callback, param};
+ int res = REAL(pthread_create)(UntagPtr(th), UntagPtr(attr),
+ &HwasanThreadStartFunc, A);
+ return res;
+}
+
+DEFINE_REAL(int, vfork)
+DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(int, vfork)
+#endif // HWASAN_WITH_INTERCEPTORS
+
+#if HWASAN_WITH_INTERCEPTORS && defined(__aarch64__)
+// Get and/or change the set of blocked signals.
+extern "C" int sigprocmask(int __how, const __hw_sigset_t *__restrict __set,
+ __hw_sigset_t *__restrict __oset);
+#define SIG_BLOCK 0
+#define SIG_SETMASK 2
+extern "C" int __sigjmp_save(__hw_sigjmp_buf env, int savemask) {
+ env[0].__mask_was_saved =
+ (savemask && sigprocmask(SIG_BLOCK, (__hw_sigset_t *)0,
+ &env[0].__saved_mask) == 0);
+ return 0;
+}
+
+static void __attribute__((always_inline))
+InternalLongjmp(__hw_register_buf env, int retval) {
+ // Clear all memory tags on the stack between here and where we're going.
+ unsigned long long stack_pointer = env[13];
+ // The stack pointer should never be tagged, so we don't need to clear the
+ // tag for this function call.
+ __hwasan_handle_longjmp((void *)stack_pointer);
+
+ // Run code for handling a longjmp.
+ // Need to use a register that isn't going to be loaded from the environment
+ // buffer -- hence why we need to specify the register to use.
+ // Must implement this ourselves, since we don't know the order of registers
+ // in different libc implementations and many implementations mangle the
+ // stack pointer so we can't use it without knowing the demangling scheme.
+ register long int retval_tmp asm("x1") = retval;
+ register void *env_address asm("x0") = &env[0];
+ asm volatile("ldp x19, x20, [%0, #0<<3];"
+ "ldp x21, x22, [%0, #2<<3];"
+ "ldp x23, x24, [%0, #4<<3];"
+ "ldp x25, x26, [%0, #6<<3];"
+ "ldp x27, x28, [%0, #8<<3];"
+ "ldp x29, x30, [%0, #10<<3];"
+ "ldp d8, d9, [%0, #14<<3];"
+ "ldp d10, d11, [%0, #16<<3];"
+ "ldp d12, d13, [%0, #18<<3];"
+ "ldp d14, d15, [%0, #20<<3];"
+ "ldr x5, [%0, #13<<3];"
+ "mov sp, x5;"
+ // Return the value requested to return through arguments.
+ // This should be in x1 given what we requested above.
+ "cmp %1, #0;"
+ "mov x0, #1;"
+ "csel x0, %1, x0, ne;"
+ "br x30;"
+ : "+r"(env_address)
+ : "r"(retval_tmp));
+}
+
+INTERCEPTOR(void, siglongjmp, __hw_sigjmp_buf env, int val) {
+ if (env[0].__mask_was_saved)
+ // Restore the saved signal mask.
+ (void)sigprocmask(SIG_SETMASK, &env[0].__saved_mask,
+ (__hw_sigset_t *)0);
+ InternalLongjmp(env[0].__jmpbuf, val);
+}
+
+// Required since glibc libpthread calls __libc_longjmp on pthread_exit, and
+// _setjmp on start_thread. Hence we have to intercept the longjmp on
+// pthread_exit so the __hw_jmp_buf order matches.
+INTERCEPTOR(void, __libc_longjmp, __hw_jmp_buf env, int val) {
+ InternalLongjmp(env[0].__jmpbuf, val);
+}
+
+INTERCEPTOR(void, longjmp, __hw_jmp_buf env, int val) {
+ InternalLongjmp(env[0].__jmpbuf, val);
+}
+#undef SIG_BLOCK
+#undef SIG_SETMASK
+
+#endif // HWASAN_WITH_INTERCEPTORS && __aarch64__
+
+static void BeforeFork() {
+ StackDepotLockAll();
+}
+
+static void AfterFork() {
+ StackDepotUnlockAll();
+}
+
+INTERCEPTOR(int, fork, void) {
+ ENSURE_HWASAN_INITED();
+ BeforeFork();
+ int pid = REAL(fork)();
+ AfterFork();
+ return pid;
+}
+
+namespace __hwasan {
+
+int OnExit() {
+ // FIXME: ask frontend whether we need to return failure.
+ return 0;
+}
+
+} // namespace __hwasan
+
+namespace __hwasan {
+
+void InitializeInterceptors() {
+ static int inited = 0;
+ CHECK_EQ(inited, 0);
+
+ INTERCEPT_FUNCTION(fork);
+
+#if HWASAN_WITH_INTERCEPTORS
+#if defined(__linux__)
+ INTERCEPT_FUNCTION(vfork);
+#endif // __linux__
+ INTERCEPT_FUNCTION(pthread_create);
+#endif
+
+ inited = 1;
+}
+} // namespace __hwasan
diff --git a/libsanitizer/hwasan/hwasan_interceptors_vfork.S b/libsanitizer/hwasan/hwasan_interceptors_vfork.S
new file mode 100644
index 0000000..23d5659
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_interceptors_vfork.S
@@ -0,0 +1,11 @@
+#include "sanitizer_common/sanitizer_asm.h"
+
+#if defined(__linux__) && HWASAN_WITH_INTERCEPTORS
+#define COMMON_INTERCEPTOR_SPILL_AREA __hwasan_extra_spill_area
+#define COMMON_INTERCEPTOR_HANDLE_VFORK __hwasan_handle_vfork
+#include "sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S"
+#include "sanitizer_common/sanitizer_common_interceptors_vfork_riscv64.inc.S"
+#include "sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S"
+#endif
+
+NO_EXEC_STACK_DIRECTIVE
diff --git a/libsanitizer/hwasan/hwasan_interface_internal.h b/libsanitizer/hwasan/hwasan_interface_internal.h
new file mode 100644
index 0000000..aedda31
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_interface_internal.h
@@ -0,0 +1,227 @@
+//===-- hwasan_interface_internal.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 HWAddressSanitizer.
+//
+// Private Hwasan interface header.
+//===----------------------------------------------------------------------===//
+
+#ifndef HWASAN_INTERFACE_INTERNAL_H
+#define HWASAN_INTERFACE_INTERNAL_H
+
+#include "sanitizer_common/sanitizer_internal_defs.h"
+#include "sanitizer_common/sanitizer_platform_limits_posix.h"
+#include <link.h>
+
+extern "C" {
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_init_static();
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_init();
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_library_loaded(ElfW(Addr) base, const ElfW(Phdr) * phdr,
+ ElfW(Half) phnum);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_library_unloaded(ElfW(Addr) base, const ElfW(Phdr) * phdr,
+ ElfW(Half) phnum);
+
+using __sanitizer::uptr;
+using __sanitizer::sptr;
+using __sanitizer::uu64;
+using __sanitizer::uu32;
+using __sanitizer::uu16;
+using __sanitizer::u64;
+using __sanitizer::u32;
+using __sanitizer::u16;
+using __sanitizer::u8;
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_init_frames(uptr, uptr);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+extern uptr __hwasan_shadow_memory_dynamic_address;
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_loadN(uptr, uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_load1(uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_load2(uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_load4(uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_load8(uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_load16(uptr);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_loadN_noabort(uptr, uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_load1_noabort(uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_load2_noabort(uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_load4_noabort(uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_load8_noabort(uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_load16_noabort(uptr);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_storeN(uptr, uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_store1(uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_store2(uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_store4(uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_store8(uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_store16(uptr);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_storeN_noabort(uptr, uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_store1_noabort(uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_store2_noabort(uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_store4_noabort(uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_store8_noabort(uptr);
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_store16_noabort(uptr);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_tag_memory(uptr p, u8 tag, uptr sz);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+uptr __hwasan_tag_pointer(uptr p, u8 tag);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_tag_mismatch(uptr addr, u8 ts);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_tag_mismatch4(uptr addr, uptr access_info, uptr *registers_frame,
+ size_t outsize);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+u8 __hwasan_generate_tag();
+
+// Returns the offset of the first tag mismatch or -1 if the whole range is
+// good.
+SANITIZER_INTERFACE_ATTRIBUTE
+sptr __hwasan_test_shadow(const void *x, uptr size);
+
+SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
+/* OPTIONAL */ const char* __hwasan_default_options();
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_print_shadow(const void *x, uptr size);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_handle_longjmp(const void *sp_dst);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_handle_vfork(const void *sp_dst);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+u16 __sanitizer_unaligned_load16(const uu16 *p);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+u32 __sanitizer_unaligned_load32(const uu32 *p);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+u64 __sanitizer_unaligned_load64(const uu64 *p);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __sanitizer_unaligned_store16(uu16 *p, u16 x);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __sanitizer_unaligned_store32(uu32 *p, u32 x);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __sanitizer_unaligned_store64(uu64 *p, u64 x);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_enable_allocator_tagging();
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_disable_allocator_tagging();
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_thread_enter();
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_thread_exit();
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_print_memory_usage();
+
+SANITIZER_INTERFACE_ATTRIBUTE
+int __sanitizer_posix_memalign(void **memptr, uptr alignment, uptr size);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void * __sanitizer_memalign(uptr alignment, uptr size);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void * __sanitizer_aligned_alloc(uptr alignment, uptr size);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void * __sanitizer___libc_memalign(uptr alignment, uptr size);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void * __sanitizer_valloc(uptr size);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void * __sanitizer_pvalloc(uptr size);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __sanitizer_free(void *ptr);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __sanitizer_cfree(void *ptr);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+uptr __sanitizer_malloc_usable_size(const void *ptr);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+__hwasan::__sanitizer_struct_mallinfo __sanitizer_mallinfo();
+
+SANITIZER_INTERFACE_ATTRIBUTE
+int __sanitizer_mallopt(int cmd, int value);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __sanitizer_malloc_stats(void);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void * __sanitizer_calloc(uptr nmemb, uptr size);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void * __sanitizer_realloc(void *ptr, uptr size);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void * __sanitizer_reallocarray(void *ptr, uptr nmemb, uptr size);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void * __sanitizer_malloc(uptr size);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void *__hwasan_memcpy(void *dst, const void *src, uptr size);
+SANITIZER_INTERFACE_ATTRIBUTE
+void *__hwasan_memset(void *s, int c, uptr n);
+SANITIZER_INTERFACE_ATTRIBUTE
+void *__hwasan_memmove(void *dest, const void *src, uptr n);
+} // extern "C"
+
+#endif // HWASAN_INTERFACE_INTERNAL_H
diff --git a/libsanitizer/hwasan/hwasan_linux.cpp b/libsanitizer/hwasan/hwasan_linux.cpp
new file mode 100644
index 0000000..e99926d
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_linux.cpp
@@ -0,0 +1,455 @@
+//===-- hwasan_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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file is a part of HWAddressSanitizer and contains Linux-, NetBSD- and
+/// FreeBSD-specific code.
+///
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_common/sanitizer_platform.h"
+#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
+
+#include "hwasan.h"
+#include "hwasan_dynamic_shadow.h"
+#include "hwasan_interface_internal.h"
+#include "hwasan_mapping.h"
+#include "hwasan_report.h"
+#include "hwasan_thread.h"
+#include "hwasan_thread_list.h"
+
+#include <dlfcn.h>
+#include <elf.h>
+#include <link.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <unwind.h>
+#include <sys/prctl.h>
+#include <errno.h>
+
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_procmaps.h"
+
+// Configurations of HWASAN_WITH_INTERCEPTORS and SANITIZER_ANDROID.
+//
+// HWASAN_WITH_INTERCEPTORS=OFF, SANITIZER_ANDROID=OFF
+// Not currently tested.
+// HWASAN_WITH_INTERCEPTORS=OFF, SANITIZER_ANDROID=ON
+// Integration tests downstream exist.
+// HWASAN_WITH_INTERCEPTORS=ON, SANITIZER_ANDROID=OFF
+// Tested with check-hwasan on x86_64-linux.
+// HWASAN_WITH_INTERCEPTORS=ON, SANITIZER_ANDROID=ON
+// Tested with check-hwasan on aarch64-linux-android.
+#if !SANITIZER_ANDROID
+SANITIZER_INTERFACE_ATTRIBUTE
+THREADLOCAL uptr __hwasan_tls;
+#endif
+
+namespace __hwasan {
+
+// With the zero shadow base we can not actually map pages starting from 0.
+// This constant is somewhat arbitrary.
+constexpr uptr kZeroBaseShadowStart = 0;
+constexpr uptr kZeroBaseMaxShadowStart = 1 << 18;
+
+static void ProtectGap(uptr addr, uptr size) {
+ __sanitizer::ProtectGap(addr, size, kZeroBaseShadowStart,
+ kZeroBaseMaxShadowStart);
+}
+
+uptr kLowMemStart;
+uptr kLowMemEnd;
+uptr kLowShadowEnd;
+uptr kLowShadowStart;
+uptr kHighShadowStart;
+uptr kHighShadowEnd;
+uptr kHighMemStart;
+uptr kHighMemEnd;
+
+static void PrintRange(uptr start, uptr end, const char *name) {
+ Printf("|| [%p, %p] || %.*s ||\n", (void *)start, (void *)end, 10, name);
+}
+
+static void PrintAddressSpaceLayout() {
+ PrintRange(kHighMemStart, kHighMemEnd, "HighMem");
+ if (kHighShadowEnd + 1 < kHighMemStart)
+ PrintRange(kHighShadowEnd + 1, kHighMemStart - 1, "ShadowGap");
+ else
+ CHECK_EQ(kHighShadowEnd + 1, kHighMemStart);
+ PrintRange(kHighShadowStart, kHighShadowEnd, "HighShadow");
+ if (kLowShadowEnd + 1 < kHighShadowStart)
+ PrintRange(kLowShadowEnd + 1, kHighShadowStart - 1, "ShadowGap");
+ else
+ CHECK_EQ(kLowMemEnd + 1, kHighShadowStart);
+ PrintRange(kLowShadowStart, kLowShadowEnd, "LowShadow");
+ if (kLowMemEnd + 1 < kLowShadowStart)
+ PrintRange(kLowMemEnd + 1, kLowShadowStart - 1, "ShadowGap");
+ else
+ CHECK_EQ(kLowMemEnd + 1, kLowShadowStart);
+ PrintRange(kLowMemStart, kLowMemEnd, "LowMem");
+ CHECK_EQ(0, kLowMemStart);
+}
+
+static uptr GetHighMemEnd() {
+ // HighMem covers the upper part of the address space.
+ uptr max_address = GetMaxUserVirtualAddress();
+ // Adjust max address to make sure that kHighMemEnd and kHighMemStart are
+ // properly aligned:
+ max_address |= (GetMmapGranularity() << kShadowScale) - 1;
+ return max_address;
+}
+
+static void InitializeShadowBaseAddress(uptr shadow_size_bytes) {
+ __hwasan_shadow_memory_dynamic_address =
+ FindDynamicShadowStart(shadow_size_bytes);
+}
+
+void InitPrctl() {
+#define PR_SET_TAGGED_ADDR_CTRL 55
+#define PR_GET_TAGGED_ADDR_CTRL 56
+#define PR_TAGGED_ADDR_ENABLE (1UL << 0)
+ // Check we're running on a kernel that can use the tagged address ABI.
+ if (internal_prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0) == (uptr)-1 &&
+ errno == EINVAL) {
+#if SANITIZER_ANDROID
+ // Some older Android kernels have the tagged pointer ABI on
+ // unconditionally, and hence don't have the tagged-addr prctl while still
+ // allow the ABI.
+ // If targeting Android and the prctl is not around we assume this is the
+ // case.
+ return;
+#else
+ Printf(
+ "FATAL: "
+ "HWAddressSanitizer requires a kernel with tagged address ABI.\n");
+ Die();
+#endif
+ }
+
+ // Turn on the tagged address ABI.
+ if (internal_prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) ==
+ (uptr)-1 ||
+ !internal_prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)) {
+ Printf(
+ "FATAL: HWAddressSanitizer failed to enable tagged address syscall "
+ "ABI.\nSuggest check `sysctl abi.tagged_addr_disabled` "
+ "configuration.\n");
+ Die();
+ }
+#undef PR_SET_TAGGED_ADDR_CTRL
+#undef PR_GET_TAGGED_ADDR_CTRL
+#undef PR_TAGGED_ADDR_ENABLE
+}
+
+bool InitShadow() {
+ // Define the entire memory range.
+ kHighMemEnd = GetHighMemEnd();
+
+ // Determine shadow memory base offset.
+ InitializeShadowBaseAddress(MemToShadowSize(kHighMemEnd));
+
+ // Place the low memory first.
+ kLowMemEnd = __hwasan_shadow_memory_dynamic_address - 1;
+ kLowMemStart = 0;
+
+ // Define the low shadow based on the already placed low memory.
+ kLowShadowEnd = MemToShadow(kLowMemEnd);
+ kLowShadowStart = __hwasan_shadow_memory_dynamic_address;
+
+ // High shadow takes whatever memory is left up there (making sure it is not
+ // interfering with low memory in the fixed case).
+ kHighShadowEnd = MemToShadow(kHighMemEnd);
+ kHighShadowStart = Max(kLowMemEnd, MemToShadow(kHighShadowEnd)) + 1;
+
+ // High memory starts where allocated shadow allows.
+ kHighMemStart = ShadowToMem(kHighShadowStart);
+
+ // Check the sanity of the defined memory ranges (there might be gaps).
+ CHECK_EQ(kHighMemStart % GetMmapGranularity(), 0);
+ CHECK_GT(kHighMemStart, kHighShadowEnd);
+ CHECK_GT(kHighShadowEnd, kHighShadowStart);
+ CHECK_GT(kHighShadowStart, kLowMemEnd);
+ CHECK_GT(kLowMemEnd, kLowMemStart);
+ CHECK_GT(kLowShadowEnd, kLowShadowStart);
+ CHECK_GT(kLowShadowStart, kLowMemEnd);
+
+ if (Verbosity())
+ PrintAddressSpaceLayout();
+
+ // Reserve shadow memory.
+ ReserveShadowMemoryRange(kLowShadowStart, kLowShadowEnd, "low shadow");
+ ReserveShadowMemoryRange(kHighShadowStart, kHighShadowEnd, "high shadow");
+
+ // Protect all the gaps.
+ ProtectGap(0, Min(kLowMemStart, kLowShadowStart));
+ if (kLowMemEnd + 1 < kLowShadowStart)
+ ProtectGap(kLowMemEnd + 1, kLowShadowStart - kLowMemEnd - 1);
+ if (kLowShadowEnd + 1 < kHighShadowStart)
+ ProtectGap(kLowShadowEnd + 1, kHighShadowStart - kLowShadowEnd - 1);
+ if (kHighShadowEnd + 1 < kHighMemStart)
+ ProtectGap(kHighShadowEnd + 1, kHighMemStart - kHighShadowEnd - 1);
+
+ return true;
+}
+
+void InitThreads() {
+ CHECK(__hwasan_shadow_memory_dynamic_address);
+ uptr guard_page_size = GetMmapGranularity();
+ uptr thread_space_start =
+ __hwasan_shadow_memory_dynamic_address - (1ULL << kShadowBaseAlignment);
+ uptr thread_space_end =
+ __hwasan_shadow_memory_dynamic_address - guard_page_size;
+ ReserveShadowMemoryRange(thread_space_start, thread_space_end - 1,
+ "hwasan threads", /*madvise_shadow*/ false);
+ ProtectGap(thread_space_end,
+ __hwasan_shadow_memory_dynamic_address - thread_space_end);
+ InitThreadList(thread_space_start, thread_space_end - thread_space_start);
+}
+
+bool MemIsApp(uptr p) {
+ CHECK(GetTagFromPointer(p) == 0);
+ return p >= kHighMemStart || (p >= kLowMemStart && p <= kLowMemEnd);
+}
+
+static void HwasanAtExit(void) {
+ if (common_flags()->print_module_map)
+ DumpProcessMap();
+ if (flags()->print_stats && (flags()->atexit || hwasan_report_count > 0))
+ ReportStats();
+ if (hwasan_report_count > 0) {
+ // ReportAtExitStatistics();
+ if (common_flags()->exitcode)
+ internal__exit(common_flags()->exitcode);
+ }
+}
+
+void InstallAtExitHandler() {
+ atexit(HwasanAtExit);
+}
+
+// ---------------------- TSD ---------------- {{{1
+
+extern "C" void __hwasan_thread_enter() {
+ hwasanThreadList().CreateCurrentThread()->InitRandomState();
+}
+
+extern "C" void __hwasan_thread_exit() {
+ Thread *t = GetCurrentThread();
+ // Make sure that signal handler can not see a stale current thread pointer.
+ atomic_signal_fence(memory_order_seq_cst);
+ if (t)
+ hwasanThreadList().ReleaseThread(t);
+}
+
+#if HWASAN_WITH_INTERCEPTORS
+static pthread_key_t tsd_key;
+static bool tsd_key_inited = false;
+
+void HwasanTSDThreadInit() {
+ if (tsd_key_inited)
+ CHECK_EQ(0, pthread_setspecific(tsd_key,
+ (void *)GetPthreadDestructorIterations()));
+}
+
+void HwasanTSDDtor(void *tsd) {
+ uptr iterations = (uptr)tsd;
+ if (iterations > 1) {
+ CHECK_EQ(0, pthread_setspecific(tsd_key, (void *)(iterations - 1)));
+ return;
+ }
+ __hwasan_thread_exit();
+}
+
+void HwasanTSDInit() {
+ CHECK(!tsd_key_inited);
+ tsd_key_inited = true;
+ CHECK_EQ(0, pthread_key_create(&tsd_key, HwasanTSDDtor));
+}
+#else
+void HwasanTSDInit() {}
+void HwasanTSDThreadInit() {}
+#endif
+
+#if SANITIZER_ANDROID
+uptr *GetCurrentThreadLongPtr() {
+ return (uptr *)get_android_tls_ptr();
+}
+#else
+uptr *GetCurrentThreadLongPtr() {
+ return &__hwasan_tls;
+}
+#endif
+
+#if SANITIZER_ANDROID
+void AndroidTestTlsSlot() {
+ uptr kMagicValue = 0x010203040A0B0C0D;
+ uptr *tls_ptr = GetCurrentThreadLongPtr();
+ uptr old_value = *tls_ptr;
+ *tls_ptr = kMagicValue;
+ dlerror();
+ if (*(uptr *)get_android_tls_ptr() != kMagicValue) {
+ Printf(
+ "ERROR: Incompatible version of Android: TLS_SLOT_SANITIZER(6) is used "
+ "for dlerror().\n");
+ Die();
+ }
+ *tls_ptr = old_value;
+}
+#else
+void AndroidTestTlsSlot() {}
+#endif
+
+Thread *GetCurrentThread() {
+ uptr *ThreadLongPtr = GetCurrentThreadLongPtr();
+ if (UNLIKELY(*ThreadLongPtr == 0))
+ return nullptr;
+ auto *R = (StackAllocationsRingBuffer *)ThreadLongPtr;
+ return hwasanThreadList().GetThreadByBufferAddress((uptr)R->Next());
+}
+
+struct AccessInfo {
+ uptr addr;
+ uptr size;
+ bool is_store;
+ bool is_load;
+ bool recover;
+};
+
+static AccessInfo GetAccessInfo(siginfo_t *info, ucontext_t *uc) {
+ // Access type is passed in a platform dependent way (see below) and encoded
+ // as 0xXY, where X&1 is 1 for store, 0 for load, and X&2 is 1 if the error is
+ // recoverable. Valid values of Y are 0 to 4, which are interpreted as
+ // log2(access_size), and 0xF, which means that access size is passed via
+ // platform dependent register (see below).
+#if defined(__aarch64__)
+ // Access type is encoded in BRK immediate as 0x900 + 0xXY. For Y == 0xF,
+ // access size is stored in X1 register. Access address is always in X0
+ // register.
+ uptr pc = (uptr)info->si_addr;
+ const unsigned code = ((*(u32 *)pc) >> 5) & 0xffff;
+ if ((code & 0xff00) != 0x900)
+ return AccessInfo{}; // Not ours.
+
+ const bool is_store = code & 0x10;
+ const bool recover = code & 0x20;
+ const uptr addr = uc->uc_mcontext.regs[0];
+ const unsigned size_log = code & 0xf;
+ if (size_log > 4 && size_log != 0xf)
+ return AccessInfo{}; // Not ours.
+ const uptr size = size_log == 0xf ? uc->uc_mcontext.regs[1] : 1U << size_log;
+
+#elif defined(__x86_64__)
+ // Access type is encoded in the instruction following INT3 as
+ // NOP DWORD ptr [EAX + 0x40 + 0xXY]. For Y == 0xF, access size is stored in
+ // RSI register. Access address is always in RDI register.
+ uptr pc = (uptr)uc->uc_mcontext.gregs[REG_RIP];
+ uint8_t *nop = (uint8_t*)pc;
+ if (*nop != 0x0f || *(nop + 1) != 0x1f || *(nop + 2) != 0x40 ||
+ *(nop + 3) < 0x40)
+ return AccessInfo{}; // Not ours.
+ const unsigned code = *(nop + 3);
+
+ const bool is_store = code & 0x10;
+ const bool recover = code & 0x20;
+ const uptr addr = uc->uc_mcontext.gregs[REG_RDI];
+ const unsigned size_log = code & 0xf;
+ if (size_log > 4 && size_log != 0xf)
+ return AccessInfo{}; // Not ours.
+ const uptr size =
+ size_log == 0xf ? uc->uc_mcontext.gregs[REG_RSI] : 1U << size_log;
+
+#else
+# error Unsupported architecture
+#endif
+
+ return AccessInfo{addr, size, is_store, !is_store, recover};
+}
+
+static void HandleTagMismatch(AccessInfo ai, uptr pc, uptr frame,
+ ucontext_t *uc, uptr *registers_frame = nullptr) {
+ InternalMmapVector<BufferedStackTrace> stack_buffer(1);
+ BufferedStackTrace *stack = stack_buffer.data();
+ stack->Reset();
+ stack->Unwind(pc, frame, uc, common_flags()->fast_unwind_on_fatal);
+
+ // The second stack frame contains the failure __hwasan_check function, as
+ // we have a stack frame for the registers saved in __hwasan_tag_mismatch that
+ // we wish to ignore. This (currently) only occurs on AArch64, as x64
+ // implementations use SIGTRAP to implement the failure, and thus do not go
+ // through the stack saver.
+ if (registers_frame && stack->trace && stack->size > 0) {
+ stack->trace++;
+ stack->size--;
+ }
+
+ bool fatal = flags()->halt_on_error || !ai.recover;
+ ReportTagMismatch(stack, ai.addr, ai.size, ai.is_store, fatal,
+ registers_frame);
+}
+
+static bool HwasanOnSIGTRAP(int signo, siginfo_t *info, ucontext_t *uc) {
+ AccessInfo ai = GetAccessInfo(info, uc);
+ if (!ai.is_store && !ai.is_load)
+ return false;
+
+ SignalContext sig{info, uc};
+ HandleTagMismatch(ai, StackTrace::GetNextInstructionPc(sig.pc), sig.bp, uc);
+
+#if defined(__aarch64__)
+ uc->uc_mcontext.pc += 4;
+#elif defined(__x86_64__)
+#else
+# error Unsupported architecture
+#endif
+ return true;
+}
+
+static void OnStackUnwind(const SignalContext &sig, const void *,
+ BufferedStackTrace *stack) {
+ stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context,
+ common_flags()->fast_unwind_on_fatal);
+}
+
+void HwasanOnDeadlySignal(int signo, void *info, void *context) {
+ // Probably a tag mismatch.
+ if (signo == SIGTRAP)
+ if (HwasanOnSIGTRAP(signo, (siginfo_t *)info, (ucontext_t*)context))
+ return;
+
+ HandleDeadlySignal(info, context, GetTid(), &OnStackUnwind, nullptr);
+}
+
+
+} // namespace __hwasan
+
+// Entry point for interoperability between __hwasan_tag_mismatch (ASM) and the
+// rest of the mismatch handling code (C++).
+void __hwasan_tag_mismatch4(uptr addr, uptr access_info, uptr *registers_frame,
+ size_t outsize) {
+ __hwasan::AccessInfo ai;
+ ai.is_store = access_info & 0x10;
+ ai.is_load = !ai.is_store;
+ ai.recover = access_info & 0x20;
+ ai.addr = addr;
+ if ((access_info & 0xf) == 0xf)
+ ai.size = outsize;
+ else
+ ai.size = 1 << (access_info & 0xf);
+
+ __hwasan::HandleTagMismatch(ai, (uptr)__builtin_return_address(0),
+ (uptr)__builtin_frame_address(0), nullptr,
+ registers_frame);
+ __builtin_unreachable();
+}
+
+#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
diff --git a/libsanitizer/hwasan/hwasan_malloc_bisect.h b/libsanitizer/hwasan/hwasan_malloc_bisect.h
new file mode 100644
index 0000000..7d134e8c
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_malloc_bisect.h
@@ -0,0 +1,50 @@
+//===-- hwasan_malloc_bisect.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 HWAddressSanitizer.
+//
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_common/sanitizer_hash.h"
+#include "hwasan.h"
+
+namespace __hwasan {
+
+static u32 malloc_hash(StackTrace *stack, uptr orig_size) {
+ uptr len = Min(stack->size, (unsigned)7);
+ MurMur2HashBuilder H(len);
+ H.add(orig_size);
+ // Start with frame #1 to skip __sanitizer_malloc frame, which is
+ // (a) almost always the same (well, could be operator new or new[])
+ // (b) can change hashes when compiler-rt is rebuilt, invalidating previous
+ // bisection results.
+ // Because of ASLR, use only offset inside the page.
+ for (uptr i = 1; i < len; ++i) H.add(((u32)stack->trace[i]) & 0xFFF);
+ return H.get();
+}
+
+static inline bool malloc_bisect(StackTrace *stack, uptr orig_size) {
+ uptr left = flags()->malloc_bisect_left;
+ uptr right = flags()->malloc_bisect_right;
+ if (LIKELY(left == 0 && right == 0))
+ return true;
+ if (!stack)
+ return true;
+ // Allow malloc_bisect_right > (u32)(-1) to avoid spelling the latter in
+ // decimal.
+ uptr h = (uptr)malloc_hash(stack, orig_size);
+ if (h < left || h > right)
+ return false;
+ if (flags()->malloc_bisect_dump) {
+ Printf("[alloc] %u %zu\n", h, orig_size);
+ stack->Print();
+ }
+ return true;
+}
+
+} // namespace __hwasan
diff --git a/libsanitizer/hwasan/hwasan_mapping.h b/libsanitizer/hwasan/hwasan_mapping.h
new file mode 100644
index 0000000..c149687
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_mapping.h
@@ -0,0 +1,66 @@
+//===-- hwasan_mapping.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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file is a part of HWAddressSanitizer and defines memory mapping.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef HWASAN_MAPPING_H
+#define HWASAN_MAPPING_H
+
+#include "sanitizer_common/sanitizer_internal_defs.h"
+#include "hwasan_interface_internal.h"
+
+// Typical mapping on Linux/x86_64:
+// with dynamic shadow mapped at [0x770d59f40000, 0x7f0d59f40000]:
+// || [0x7f0d59f40000, 0x7fffffffffff] || HighMem ||
+// || [0x7efe2f934000, 0x7f0d59f3ffff] || HighShadow ||
+// || [0x7e7e2f934000, 0x7efe2f933fff] || ShadowGap ||
+// || [0x770d59f40000, 0x7e7e2f933fff] || LowShadow ||
+// || [0x000000000000, 0x770d59f3ffff] || LowMem ||
+
+// Typical mapping on Android/AArch64
+// with dynamic shadow mapped: [0x007477480000, 0x007c77480000]:
+// || [0x007c77480000, 0x007fffffffff] || HighMem ||
+// || [0x007c3ebc8000, 0x007c7747ffff] || HighShadow ||
+// || [0x007bbebc8000, 0x007c3ebc7fff] || ShadowGap ||
+// || [0x007477480000, 0x007bbebc7fff] || LowShadow ||
+// || [0x000000000000, 0x00747747ffff] || LowMem ||
+
+// Reasonable values are 4 (for 1/16th shadow) and 6 (for 1/64th).
+constexpr uptr kShadowScale = 4;
+constexpr uptr kShadowAlignment = 1ULL << kShadowScale;
+
+namespace __hwasan {
+
+extern uptr kLowMemStart;
+extern uptr kLowMemEnd;
+extern uptr kLowShadowEnd;
+extern uptr kLowShadowStart;
+extern uptr kHighShadowStart;
+extern uptr kHighShadowEnd;
+extern uptr kHighMemStart;
+extern uptr kHighMemEnd;
+
+inline uptr MemToShadow(uptr untagged_addr) {
+ return (untagged_addr >> kShadowScale) +
+ __hwasan_shadow_memory_dynamic_address;
+}
+inline uptr ShadowToMem(uptr shadow_addr) {
+ return (shadow_addr - __hwasan_shadow_memory_dynamic_address) << kShadowScale;
+}
+inline uptr MemToShadowSize(uptr size) {
+ return size >> kShadowScale;
+}
+
+bool MemIsApp(uptr p);
+
+} // namespace __hwasan
+
+#endif // HWASAN_MAPPING_H
diff --git a/libsanitizer/hwasan/hwasan_memintrinsics.cpp b/libsanitizer/hwasan/hwasan_memintrinsics.cpp
new file mode 100644
index 0000000..e82d77a
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_memintrinsics.cpp
@@ -0,0 +1,44 @@
+//===-- hwasan_memintrinsics.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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file is a part of HWAddressSanitizer and contains HWASAN versions of
+/// memset, memcpy and memmove
+///
+//===----------------------------------------------------------------------===//
+
+#include <string.h>
+#include "hwasan.h"
+#include "hwasan_checks.h"
+#include "hwasan_flags.h"
+#include "hwasan_interface_internal.h"
+#include "sanitizer_common/sanitizer_libc.h"
+
+using namespace __hwasan;
+
+void *__hwasan_memset(void *block, int c, uptr size) {
+ CheckAddressSized<ErrorAction::Recover, AccessType::Store>(
+ reinterpret_cast<uptr>(block), size);
+ return memset(UntagPtr(block), c, size);
+}
+
+void *__hwasan_memcpy(void *to, const void *from, uptr size) {
+ CheckAddressSized<ErrorAction::Recover, AccessType::Store>(
+ reinterpret_cast<uptr>(to), size);
+ CheckAddressSized<ErrorAction::Recover, AccessType::Load>(
+ reinterpret_cast<uptr>(from), size);
+ return memcpy(UntagPtr(to), UntagPtr(from), size);
+}
+
+void *__hwasan_memmove(void *to, const void *from, uptr size) {
+ CheckAddressSized<ErrorAction::Recover, AccessType::Store>(
+ reinterpret_cast<uptr>(to), size);
+ CheckAddressSized<ErrorAction::Recover, AccessType::Load>(
+ reinterpret_cast<uptr>(from), size);
+ return memmove(UntagPtr(to), UntagPtr(from), size);
+}
diff --git a/libsanitizer/hwasan/hwasan_new_delete.cpp b/libsanitizer/hwasan/hwasan_new_delete.cpp
new file mode 100644
index 0000000..8d01d39
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_new_delete.cpp
@@ -0,0 +1,81 @@
+//===-- hwasan_new_delete.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 HWAddressSanitizer.
+//
+// Interceptors for operators new and delete.
+//===----------------------------------------------------------------------===//
+
+#include "hwasan.h"
+#include "interception/interception.h"
+#include "sanitizer_common/sanitizer_allocator.h"
+#include "sanitizer_common/sanitizer_allocator_report.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#if HWASAN_REPLACE_OPERATORS_NEW_AND_DELETE
+
+// TODO(alekseys): throw std::bad_alloc instead of dying on OOM.
+#define OPERATOR_NEW_BODY(nothrow) \
+ GET_MALLOC_STACK_TRACE; \
+ void *res = hwasan_malloc(size, &stack);\
+ if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\
+ return res
+
+#define OPERATOR_DELETE_BODY \
+ GET_MALLOC_STACK_TRACE; \
+ if (ptr) hwasan_free(ptr, &stack)
+
+#elif defined(__ANDROID__)
+
+// We don't actually want to intercept operator new and delete on Android, but
+// since we previously released a runtime that intercepted these functions,
+// removing the interceptors would break ABI. Therefore we simply forward to
+// malloc and free.
+#define OPERATOR_NEW_BODY(nothrow) return malloc(size)
+#define OPERATOR_DELETE_BODY free(ptr)
+
+#endif
+
+#ifdef OPERATOR_NEW_BODY
+
+using namespace __hwasan;
+
+// Fake std::nothrow_t to avoid including <new>.
+namespace std {
+ struct nothrow_t {};
+} // namespace std
+
+
+
+INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
+void *operator new(size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }
+INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
+void *operator new[](size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }
+INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
+void *operator new(size_t size, std::nothrow_t const&) {
+ OPERATOR_NEW_BODY(true /*nothrow*/);
+}
+INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
+void *operator new[](size_t size, std::nothrow_t const&) {
+ OPERATOR_NEW_BODY(true /*nothrow*/);
+}
+
+INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
+void operator delete(void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }
+INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
+void operator delete[](void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }
+INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
+void operator delete(void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY; }
+INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
+void operator delete[](void *ptr, std::nothrow_t const&) {
+ OPERATOR_DELETE_BODY;
+}
+
+#endif // OPERATOR_NEW_BODY
diff --git a/libsanitizer/hwasan/hwasan_poisoning.cpp b/libsanitizer/hwasan/hwasan_poisoning.cpp
new file mode 100644
index 0000000..2a08164
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_poisoning.cpp
@@ -0,0 +1,52 @@
+//===-- hwasan_poisoning.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 HWAddressSanitizer.
+//
+//===----------------------------------------------------------------------===//
+
+#include "hwasan_poisoning.h"
+
+#include "hwasan_mapping.h"
+#include "interception/interception.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_linux.h"
+
+namespace __hwasan {
+
+uptr TagMemoryAligned(uptr p, uptr size, tag_t tag) {
+ CHECK(IsAligned(p, kShadowAlignment));
+ CHECK(IsAligned(size, kShadowAlignment));
+ uptr shadow_start = MemToShadow(p);
+ uptr shadow_size = MemToShadowSize(size);
+
+ uptr page_size = GetPageSizeCached();
+ uptr page_start = RoundUpTo(shadow_start, page_size);
+ uptr page_end = RoundDownTo(shadow_start + shadow_size, page_size);
+ uptr threshold = common_flags()->clear_shadow_mmap_threshold;
+ if (SANITIZER_LINUX &&
+ UNLIKELY(page_end >= page_start + threshold && tag == 0)) {
+ internal_memset((void *)shadow_start, tag, page_start - shadow_start);
+ internal_memset((void *)page_end, tag,
+ shadow_start + shadow_size - page_end);
+ // For an anonymous private mapping MADV_DONTNEED will return a zero page on
+ // Linux.
+ ReleaseMemoryPagesToOSAndZeroFill(page_start, page_end);
+ } else {
+ internal_memset((void *)shadow_start, tag, shadow_size);
+ }
+ return AddTagToPointer(p, tag);
+}
+
+uptr TagMemory(uptr p, uptr size, tag_t tag) {
+ uptr start = RoundDownTo(p, kShadowAlignment);
+ uptr end = RoundUpTo(p + size, kShadowAlignment);
+ return TagMemoryAligned(start, end - start, tag);
+}
+
+} // namespace __hwasan
diff --git a/libsanitizer/hwasan/hwasan_poisoning.h b/libsanitizer/hwasan/hwasan_poisoning.h
new file mode 100644
index 0000000..61751f7
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_poisoning.h
@@ -0,0 +1,24 @@
+//===-- hwasan_poisoning.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 HWAddressSanitizer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef HWASAN_POISONING_H
+#define HWASAN_POISONING_H
+
+#include "hwasan.h"
+
+namespace __hwasan {
+uptr TagMemory(uptr p, uptr size, tag_t tag);
+uptr TagMemoryAligned(uptr p, uptr size, tag_t tag);
+
+} // namespace __hwasan
+
+#endif // HWASAN_POISONING_H
diff --git a/libsanitizer/hwasan/hwasan_report.cpp b/libsanitizer/hwasan/hwasan_report.cpp
new file mode 100644
index 0000000..894a149
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_report.cpp
@@ -0,0 +1,652 @@
+//===-- hwasan_report.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 HWAddressSanitizer.
+//
+// Error reporting.
+//===----------------------------------------------------------------------===//
+
+#include "hwasan_report.h"
+
+#include <dlfcn.h>
+
+#include "hwasan.h"
+#include "hwasan_allocator.h"
+#include "hwasan_globals.h"
+#include "hwasan_mapping.h"
+#include "hwasan_thread.h"
+#include "hwasan_thread_list.h"
+#include "sanitizer_common/sanitizer_allocator_internal.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_flags.h"
+#include "sanitizer_common/sanitizer_mutex.h"
+#include "sanitizer_common/sanitizer_report_decorator.h"
+#include "sanitizer_common/sanitizer_stackdepot.h"
+#include "sanitizer_common/sanitizer_stacktrace_printer.h"
+#include "sanitizer_common/sanitizer_symbolizer.h"
+
+using namespace __sanitizer;
+
+namespace __hwasan {
+
+class ScopedReport {
+ public:
+ ScopedReport(bool fatal = false) : error_message_(1), fatal(fatal) {
+ BlockingMutexLock lock(&error_message_lock_);
+ error_message_ptr_ = fatal ? &error_message_ : nullptr;
+ ++hwasan_report_count;
+ }
+
+ ~ScopedReport() {
+ {
+ BlockingMutexLock lock(&error_message_lock_);
+ if (fatal)
+ SetAbortMessage(error_message_.data());
+ error_message_ptr_ = nullptr;
+ }
+ if (common_flags()->print_module_map >= 2 ||
+ (fatal && common_flags()->print_module_map))
+ DumpProcessMap();
+ if (fatal)
+ Die();
+ }
+
+ static void MaybeAppendToErrorMessage(const char *msg) {
+ BlockingMutexLock lock(&error_message_lock_);
+ if (!error_message_ptr_)
+ return;
+ uptr len = internal_strlen(msg);
+ uptr old_size = error_message_ptr_->size();
+ error_message_ptr_->resize(old_size + len);
+ // overwrite old trailing '\0', keep new trailing '\0' untouched.
+ internal_memcpy(&(*error_message_ptr_)[old_size - 1], msg, len);
+ }
+ private:
+ ScopedErrorReportLock error_report_lock_;
+ InternalMmapVector<char> error_message_;
+ bool fatal;
+
+ static InternalMmapVector<char> *error_message_ptr_;
+ static BlockingMutex error_message_lock_;
+};
+
+InternalMmapVector<char> *ScopedReport::error_message_ptr_;
+BlockingMutex ScopedReport::error_message_lock_;
+
+// If there is an active ScopedReport, append to its error message.
+void AppendToErrorMessageBuffer(const char *buffer) {
+ ScopedReport::MaybeAppendToErrorMessage(buffer);
+}
+
+static StackTrace GetStackTraceFromId(u32 id) {
+ CHECK(id);
+ StackTrace res = StackDepotGet(id);
+ CHECK(res.trace);
+ return res;
+}
+
+// A RAII object that holds a copy of the current thread stack ring buffer.
+// The actual stack buffer may change while we are iterating over it (for
+// example, Printf may call syslog() which can itself be built with hwasan).
+class SavedStackAllocations {
+ public:
+ SavedStackAllocations(StackAllocationsRingBuffer *rb) {
+ uptr size = rb->size() * sizeof(uptr);
+ void *storage =
+ MmapAlignedOrDieOnFatalError(size, size * 2, "saved stack allocations");
+ new (&rb_) StackAllocationsRingBuffer(*rb, storage);
+ }
+
+ ~SavedStackAllocations() {
+ StackAllocationsRingBuffer *rb = get();
+ UnmapOrDie(rb->StartOfStorage(), rb->size() * sizeof(uptr));
+ }
+
+ StackAllocationsRingBuffer *get() {
+ return (StackAllocationsRingBuffer *)&rb_;
+ }
+
+ private:
+ uptr rb_;
+};
+
+class Decorator: public __sanitizer::SanitizerCommonDecorator {
+ public:
+ Decorator() : SanitizerCommonDecorator() { }
+ const char *Access() { return Blue(); }
+ const char *Allocation() const { return Magenta(); }
+ const char *Origin() const { return Magenta(); }
+ const char *Name() const { return Green(); }
+ const char *Location() { return Green(); }
+ const char *Thread() { return Green(); }
+};
+
+static bool FindHeapAllocation(HeapAllocationsRingBuffer *rb, uptr tagged_addr,
+ HeapAllocationRecord *har, uptr *ring_index,
+ uptr *num_matching_addrs,
+ uptr *num_matching_addrs_4b) {
+ if (!rb) return false;
+
+ *num_matching_addrs = 0;
+ *num_matching_addrs_4b = 0;
+ for (uptr i = 0, size = rb->size(); i < size; i++) {
+ auto h = (*rb)[i];
+ if (h.tagged_addr <= tagged_addr &&
+ h.tagged_addr + h.requested_size > tagged_addr) {
+ *har = h;
+ *ring_index = i;
+ return true;
+ }
+
+ // Measure the number of heap ring buffer entries that would have matched
+ // if we had only one entry per address (e.g. if the ring buffer data was
+ // stored at the address itself). This will help us tune the allocator
+ // implementation for MTE.
+ if (UntagAddr(h.tagged_addr) <= UntagAddr(tagged_addr) &&
+ UntagAddr(h.tagged_addr) + h.requested_size > UntagAddr(tagged_addr)) {
+ ++*num_matching_addrs;
+ }
+
+ // Measure the number of heap ring buffer entries that would have matched
+ // if we only had 4 tag bits, which is the case for MTE.
+ auto untag_4b = [](uptr p) {
+ return p & ((1ULL << 60) - 1);
+ };
+ if (untag_4b(h.tagged_addr) <= untag_4b(tagged_addr) &&
+ untag_4b(h.tagged_addr) + h.requested_size > untag_4b(tagged_addr)) {
+ ++*num_matching_addrs_4b;
+ }
+ }
+ return false;
+}
+
+static void PrintStackAllocations(StackAllocationsRingBuffer *sa,
+ tag_t addr_tag, uptr untagged_addr) {
+ uptr frames = Min((uptr)flags()->stack_history_size, sa->size());
+ bool found_local = false;
+ for (uptr i = 0; i < frames; i++) {
+ const uptr *record_addr = &(*sa)[i];
+ uptr record = *record_addr;
+ if (!record)
+ break;
+ tag_t base_tag =
+ reinterpret_cast<uptr>(record_addr) >> kRecordAddrBaseTagShift;
+ uptr fp = (record >> kRecordFPShift) << kRecordFPLShift;
+ uptr pc_mask = (1ULL << kRecordFPShift) - 1;
+ uptr pc = record & pc_mask;
+ FrameInfo frame;
+ if (Symbolizer::GetOrInit()->SymbolizeFrame(pc, &frame)) {
+ for (LocalInfo &local : frame.locals) {
+ if (!local.has_frame_offset || !local.has_size || !local.has_tag_offset)
+ continue;
+ tag_t obj_tag = base_tag ^ local.tag_offset;
+ if (obj_tag != addr_tag)
+ continue;
+ // Calculate the offset from the object address to the faulting
+ // address. Because we only store bits 4-19 of FP (bits 0-3 are
+ // guaranteed to be zero), the calculation is performed mod 2^20 and may
+ // harmlessly underflow if the address mod 2^20 is below the object
+ // address.
+ uptr obj_offset =
+ (untagged_addr - fp - local.frame_offset) & (kRecordFPModulus - 1);
+ if (obj_offset >= local.size)
+ continue;
+ if (!found_local) {
+ Printf("Potentially referenced stack objects:\n");
+ found_local = true;
+ }
+ Printf(" %s in %s %s:%d\n", local.name, local.function_name,
+ local.decl_file, local.decl_line);
+ }
+ frame.Clear();
+ }
+ }
+
+ if (found_local)
+ return;
+
+ // We didn't find any locals. Most likely we don't have symbols, so dump
+ // the information that we have for offline analysis.
+ InternalScopedString frame_desc(GetPageSizeCached() * 2);
+ Printf("Previously allocated frames:\n");
+ for (uptr i = 0; i < frames; i++) {
+ const uptr *record_addr = &(*sa)[i];
+ uptr record = *record_addr;
+ if (!record)
+ break;
+ uptr pc_mask = (1ULL << 48) - 1;
+ uptr pc = record & pc_mask;
+ frame_desc.append(" record_addr:0x%zx record:0x%zx",
+ reinterpret_cast<uptr>(record_addr), record);
+ if (SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc)) {
+ RenderFrame(&frame_desc, " %F %L\n", 0, frame->info.address, &frame->info,
+ common_flags()->symbolize_vs_style,
+ common_flags()->strip_path_prefix);
+ frame->ClearAll();
+ }
+ Printf("%s", frame_desc.data());
+ frame_desc.clear();
+ }
+}
+
+// Returns true if tag == *tag_ptr, reading tags from short granules if
+// necessary. This may return a false positive if tags 1-15 are used as a
+// regular tag rather than a short granule marker.
+static bool TagsEqual(tag_t tag, tag_t *tag_ptr) {
+ if (tag == *tag_ptr)
+ return true;
+ if (*tag_ptr == 0 || *tag_ptr > kShadowAlignment - 1)
+ return false;
+ uptr mem = ShadowToMem(reinterpret_cast<uptr>(tag_ptr));
+ tag_t inline_tag = *reinterpret_cast<tag_t *>(mem + kShadowAlignment - 1);
+ return tag == inline_tag;
+}
+
+// HWASan globals store the size of the global in the descriptor. In cases where
+// we don't have a binary with symbols, we can't grab the size of the global
+// from the debug info - but we might be able to retrieve it from the
+// descriptor. Returns zero if the lookup failed.
+static uptr GetGlobalSizeFromDescriptor(uptr ptr) {
+ // Find the ELF object that this global resides in.
+ Dl_info info;
+ if (dladdr(reinterpret_cast<void *>(ptr), &info) == 0)
+ return 0;
+ auto *ehdr = reinterpret_cast<const ElfW(Ehdr) *>(info.dli_fbase);
+ auto *phdr_begin = reinterpret_cast<const ElfW(Phdr) *>(
+ reinterpret_cast<const u8 *>(ehdr) + ehdr->e_phoff);
+
+ // Get the load bias. This is normally the same as the dli_fbase address on
+ // position-independent code, but can be different on non-PIE executables,
+ // binaries using LLD's partitioning feature, or binaries compiled with a
+ // linker script.
+ ElfW(Addr) load_bias = 0;
+ for (const auto &phdr :
+ ArrayRef<const ElfW(Phdr)>(phdr_begin, phdr_begin + ehdr->e_phnum)) {
+ if (phdr.p_type != PT_LOAD || phdr.p_offset != 0)
+ continue;
+ load_bias = reinterpret_cast<ElfW(Addr)>(ehdr) - phdr.p_vaddr;
+ break;
+ }
+
+ // Walk all globals in this ELF object, looking for the one we're interested
+ // in. Once we find it, we can stop iterating and return the size of the
+ // global we're interested in.
+ for (const hwasan_global &global :
+ HwasanGlobalsFor(load_bias, phdr_begin, ehdr->e_phnum))
+ if (global.addr() <= ptr && ptr < global.addr() + global.size())
+ return global.size();
+
+ return 0;
+}
+
+void PrintAddressDescription(
+ uptr tagged_addr, uptr access_size,
+ StackAllocationsRingBuffer *current_stack_allocations) {
+ Decorator d;
+ int num_descriptions_printed = 0;
+ uptr untagged_addr = UntagAddr(tagged_addr);
+
+ // Print some very basic information about the address, if it's a heap.
+ HwasanChunkView chunk = FindHeapChunkByAddress(untagged_addr);
+ if (uptr beg = chunk.Beg()) {
+ uptr size = chunk.ActualSize();
+ Printf("%s[%p,%p) is a %s %s heap chunk; "
+ "size: %zd offset: %zd\n%s",
+ d.Location(),
+ beg, beg + size,
+ chunk.FromSmallHeap() ? "small" : "large",
+ chunk.IsAllocated() ? "allocated" : "unallocated",
+ size, untagged_addr - beg,
+ d.Default());
+ }
+
+ // Check if this looks like a heap buffer overflow by scanning
+ // the shadow left and right and looking for the first adjacent
+ // object with a different memory tag. If that tag matches addr_tag,
+ // check the allocator if it has a live chunk there.
+ tag_t addr_tag = GetTagFromPointer(tagged_addr);
+ tag_t *tag_ptr = reinterpret_cast<tag_t*>(MemToShadow(untagged_addr));
+ tag_t *candidate = nullptr, *left = tag_ptr, *right = tag_ptr;
+ for (int i = 0; i < 1000; i++) {
+ if (TagsEqual(addr_tag, left)) {
+ candidate = left;
+ break;
+ }
+ --left;
+ if (TagsEqual(addr_tag, right)) {
+ candidate = right;
+ break;
+ }
+ ++right;
+ }
+
+ if (candidate) {
+ uptr mem = ShadowToMem(reinterpret_cast<uptr>(candidate));
+ HwasanChunkView chunk = FindHeapChunkByAddress(mem);
+ if (chunk.IsAllocated()) {
+ Printf("%s", d.Location());
+ Printf("%p is located %zd bytes to the %s of %zd-byte region [%p,%p)\n",
+ untagged_addr,
+ candidate == left ? untagged_addr - chunk.End()
+ : chunk.Beg() - untagged_addr,
+ candidate == left ? "right" : "left", chunk.UsedSize(),
+ chunk.Beg(), chunk.End());
+ Printf("%s", d.Allocation());
+ Printf("allocated here:\n");
+ Printf("%s", d.Default());
+ GetStackTraceFromId(chunk.GetAllocStackId()).Print();
+ num_descriptions_printed++;
+ } else {
+ // Check whether the address points into a loaded library. If so, this is
+ // most likely a global variable.
+ const char *module_name;
+ uptr module_address;
+ Symbolizer *sym = Symbolizer::GetOrInit();
+ if (sym->GetModuleNameAndOffsetForPC(mem, &module_name,
+ &module_address)) {
+ DataInfo info;
+ if (sym->SymbolizeData(mem, &info) && info.start) {
+ Printf(
+ "%p is located %zd bytes to the %s of %zd-byte global variable "
+ "%s [%p,%p) in %s\n",
+ untagged_addr,
+ candidate == left ? untagged_addr - (info.start + info.size)
+ : info.start - untagged_addr,
+ candidate == left ? "right" : "left", info.size, info.name,
+ info.start, info.start + info.size, module_name);
+ } else {
+ uptr size = GetGlobalSizeFromDescriptor(mem);
+ if (size == 0)
+ // We couldn't find the size of the global from the descriptors.
+ Printf(
+ "%p is located to the %s of a global variable in (%s+0x%x)\n",
+ untagged_addr, candidate == left ? "right" : "left",
+ module_name, module_address);
+ else
+ Printf(
+ "%p is located to the %s of a %zd-byte global variable in "
+ "(%s+0x%x)\n",
+ untagged_addr, candidate == left ? "right" : "left", size,
+ module_name, module_address);
+ }
+ num_descriptions_printed++;
+ }
+ }
+ }
+
+ hwasanThreadList().VisitAllLiveThreads([&](Thread *t) {
+ // Scan all threads' ring buffers to find if it's a heap-use-after-free.
+ HeapAllocationRecord har;
+ uptr ring_index, num_matching_addrs, num_matching_addrs_4b;
+ if (FindHeapAllocation(t->heap_allocations(), tagged_addr, &har,
+ &ring_index, &num_matching_addrs,
+ &num_matching_addrs_4b)) {
+ Printf("%s", d.Location());
+ Printf("%p is located %zd bytes inside of %zd-byte region [%p,%p)\n",
+ untagged_addr, untagged_addr - UntagAddr(har.tagged_addr),
+ har.requested_size, UntagAddr(har.tagged_addr),
+ UntagAddr(har.tagged_addr) + har.requested_size);
+ Printf("%s", d.Allocation());
+ Printf("freed by thread T%zd here:\n", t->unique_id());
+ Printf("%s", d.Default());
+ GetStackTraceFromId(har.free_context_id).Print();
+
+ Printf("%s", d.Allocation());
+ Printf("previously allocated here:\n", t);
+ Printf("%s", d.Default());
+ GetStackTraceFromId(har.alloc_context_id).Print();
+
+ // Print a developer note: the index of this heap object
+ // in the thread's deallocation ring buffer.
+ Printf("hwasan_dev_note_heap_rb_distance: %zd %zd\n", ring_index + 1,
+ flags()->heap_history_size);
+ Printf("hwasan_dev_note_num_matching_addrs: %zd\n", num_matching_addrs);
+ Printf("hwasan_dev_note_num_matching_addrs_4b: %zd\n",
+ num_matching_addrs_4b);
+
+ t->Announce();
+ num_descriptions_printed++;
+ }
+
+ // Very basic check for stack memory.
+ if (t->AddrIsInStack(untagged_addr)) {
+ Printf("%s", d.Location());
+ Printf("Address %p is located in stack of thread T%zd\n", untagged_addr,
+ t->unique_id());
+ Printf("%s", d.Default());
+ t->Announce();
+
+ auto *sa = (t == GetCurrentThread() && current_stack_allocations)
+ ? current_stack_allocations
+ : t->stack_allocations();
+ PrintStackAllocations(sa, addr_tag, untagged_addr);
+ num_descriptions_printed++;
+ }
+ });
+
+ // Print the remaining threads, as an extra information, 1 line per thread.
+ hwasanThreadList().VisitAllLiveThreads([&](Thread *t) { t->Announce(); });
+
+ if (!num_descriptions_printed)
+ // We exhausted our possibilities. Bail out.
+ Printf("HWAddressSanitizer can not describe address in more detail.\n");
+}
+
+void ReportStats() {}
+
+static void PrintTagInfoAroundAddr(tag_t *tag_ptr, uptr num_rows,
+ void (*print_tag)(InternalScopedString &s,
+ tag_t *tag)) {
+ const uptr row_len = 16; // better be power of two.
+ tag_t *center_row_beg = reinterpret_cast<tag_t *>(
+ RoundDownTo(reinterpret_cast<uptr>(tag_ptr), row_len));
+ tag_t *beg_row = center_row_beg - row_len * (num_rows / 2);
+ tag_t *end_row = center_row_beg + row_len * ((num_rows + 1) / 2);
+ InternalScopedString s(GetPageSizeCached() * 8);
+ for (tag_t *row = beg_row; row < end_row; row += row_len) {
+ s.append("%s", row == center_row_beg ? "=>" : " ");
+ s.append("%p:", row);
+ for (uptr i = 0; i < row_len; i++) {
+ s.append("%s", row + i == tag_ptr ? "[" : " ");
+ print_tag(s, &row[i]);
+ s.append("%s", row + i == tag_ptr ? "]" : " ");
+ }
+ s.append("\n");
+ }
+ Printf("%s", s.data());
+}
+
+static void PrintTagsAroundAddr(tag_t *tag_ptr) {
+ Printf(
+ "Memory tags around the buggy address (one tag corresponds to %zd "
+ "bytes):\n", kShadowAlignment);
+ PrintTagInfoAroundAddr(tag_ptr, 17, [](InternalScopedString &s, tag_t *tag) {
+ s.append("%02x", *tag);
+ });
+
+ Printf(
+ "Tags for short granules around the buggy address (one tag corresponds "
+ "to %zd bytes):\n",
+ kShadowAlignment);
+ PrintTagInfoAroundAddr(tag_ptr, 3, [](InternalScopedString &s, tag_t *tag) {
+ if (*tag >= 1 && *tag <= kShadowAlignment) {
+ uptr granule_addr = ShadowToMem(reinterpret_cast<uptr>(tag));
+ s.append("%02x",
+ *reinterpret_cast<u8 *>(granule_addr + kShadowAlignment - 1));
+ } else {
+ s.append("..");
+ }
+ });
+ Printf(
+ "See "
+ "https://clang.llvm.org/docs/"
+ "HardwareAssistedAddressSanitizerDesign.html#short-granules for a "
+ "description of short granule tags\n");
+}
+
+void ReportInvalidFree(StackTrace *stack, uptr tagged_addr) {
+ ScopedReport R(flags()->halt_on_error);
+
+ uptr untagged_addr = UntagAddr(tagged_addr);
+ tag_t ptr_tag = GetTagFromPointer(tagged_addr);
+ tag_t *tag_ptr = reinterpret_cast<tag_t*>(MemToShadow(untagged_addr));
+ tag_t mem_tag = *tag_ptr;
+ Decorator d;
+ Printf("%s", d.Error());
+ uptr pc = stack->size ? stack->trace[0] : 0;
+ const char *bug_type = "invalid-free";
+ Report("ERROR: %s: %s on address %p at pc %p\n", SanitizerToolName, bug_type,
+ untagged_addr, pc);
+ Printf("%s", d.Access());
+ Printf("tags: %02x/%02x (ptr/mem)\n", ptr_tag, mem_tag);
+ Printf("%s", d.Default());
+
+ stack->Print();
+
+ PrintAddressDescription(tagged_addr, 0, nullptr);
+
+ PrintTagsAroundAddr(tag_ptr);
+
+ ReportErrorSummary(bug_type, stack);
+}
+
+void ReportTailOverwritten(StackTrace *stack, uptr tagged_addr, uptr orig_size,
+ const u8 *expected) {
+ uptr tail_size = kShadowAlignment - (orig_size % kShadowAlignment);
+ ScopedReport R(flags()->halt_on_error);
+ Decorator d;
+ uptr untagged_addr = UntagAddr(tagged_addr);
+ Printf("%s", d.Error());
+ const char *bug_type = "allocation-tail-overwritten";
+ Report("ERROR: %s: %s; heap object [%p,%p) of size %zd\n", SanitizerToolName,
+ bug_type, untagged_addr, untagged_addr + orig_size, orig_size);
+ Printf("\n%s", d.Default());
+ stack->Print();
+ HwasanChunkView chunk = FindHeapChunkByAddress(untagged_addr);
+ if (chunk.Beg()) {
+ Printf("%s", d.Allocation());
+ Printf("allocated here:\n");
+ Printf("%s", d.Default());
+ GetStackTraceFromId(chunk.GetAllocStackId()).Print();
+ }
+
+ InternalScopedString s(GetPageSizeCached() * 8);
+ CHECK_GT(tail_size, 0U);
+ CHECK_LT(tail_size, kShadowAlignment);
+ u8 *tail = reinterpret_cast<u8*>(untagged_addr + orig_size);
+ s.append("Tail contains: ");
+ for (uptr i = 0; i < kShadowAlignment - tail_size; i++)
+ s.append(".. ");
+ for (uptr i = 0; i < tail_size; i++)
+ s.append("%02x ", tail[i]);
+ s.append("\n");
+ s.append("Expected: ");
+ for (uptr i = 0; i < kShadowAlignment - tail_size; i++)
+ s.append(".. ");
+ for (uptr i = 0; i < tail_size; i++)
+ s.append("%02x ", expected[i]);
+ s.append("\n");
+ s.append(" ");
+ for (uptr i = 0; i < kShadowAlignment - tail_size; i++)
+ s.append(" ");
+ for (uptr i = 0; i < tail_size; i++)
+ s.append("%s ", expected[i] != tail[i] ? "^^" : " ");
+
+ s.append("\nThis error occurs when a buffer overflow overwrites memory\n"
+ "to the right of a heap object, but within the %zd-byte granule, e.g.\n"
+ " char *x = new char[20];\n"
+ " x[25] = 42;\n"
+ "%s does not detect such bugs in uninstrumented code at the time of write,"
+ "\nbut can detect them at the time of free/delete.\n"
+ "To disable this feature set HWASAN_OPTIONS=free_checks_tail_magic=0\n",
+ kShadowAlignment, SanitizerToolName);
+ Printf("%s", s.data());
+ GetCurrentThread()->Announce();
+
+ tag_t *tag_ptr = reinterpret_cast<tag_t*>(MemToShadow(untagged_addr));
+ PrintTagsAroundAddr(tag_ptr);
+
+ ReportErrorSummary(bug_type, stack);
+}
+
+void ReportTagMismatch(StackTrace *stack, uptr tagged_addr, uptr access_size,
+ bool is_store, bool fatal, uptr *registers_frame) {
+ ScopedReport R(fatal);
+ SavedStackAllocations current_stack_allocations(
+ GetCurrentThread()->stack_allocations());
+
+ Decorator d;
+ Printf("%s", d.Error());
+ uptr untagged_addr = UntagAddr(tagged_addr);
+ // TODO: when possible, try to print heap-use-after-free, etc.
+ const char *bug_type = "tag-mismatch";
+ uptr pc = stack->size ? stack->trace[0] : 0;
+ Report("ERROR: %s: %s on address %p at pc %p\n", SanitizerToolName, bug_type,
+ untagged_addr, pc);
+
+ Thread *t = GetCurrentThread();
+
+ sptr offset =
+ __hwasan_test_shadow(reinterpret_cast<void *>(tagged_addr), access_size);
+ CHECK(offset >= 0 && offset < static_cast<sptr>(access_size));
+ tag_t ptr_tag = GetTagFromPointer(tagged_addr);
+ tag_t *tag_ptr =
+ reinterpret_cast<tag_t *>(MemToShadow(untagged_addr + offset));
+ tag_t mem_tag = *tag_ptr;
+
+ Printf("%s", d.Access());
+ Printf("%s of size %zu at %p tags: %02x/%02x (ptr/mem) in thread T%zd\n",
+ is_store ? "WRITE" : "READ", access_size, untagged_addr, ptr_tag,
+ mem_tag, t->unique_id());
+ if (offset != 0)
+ Printf("Invalid access starting at offset [%zu, %zu)\n", offset,
+ Min(access_size, static_cast<uptr>(offset) + (1 << kShadowScale)));
+ Printf("%s", d.Default());
+
+ stack->Print();
+
+ PrintAddressDescription(tagged_addr, access_size,
+ current_stack_allocations.get());
+ t->Announce();
+
+ PrintTagsAroundAddr(tag_ptr);
+
+ if (registers_frame)
+ ReportRegisters(registers_frame, pc);
+
+ ReportErrorSummary(bug_type, stack);
+}
+
+// See the frame breakdown defined in __hwasan_tag_mismatch (from
+// hwasan_tag_mismatch_aarch64.S).
+void ReportRegisters(uptr *frame, uptr pc) {
+ Printf("Registers where the failure occurred (pc %p):\n", pc);
+
+ // We explicitly print a single line (4 registers/line) each iteration to
+ // reduce the amount of logcat error messages printed. Each Printf() will
+ // result in a new logcat line, irrespective of whether a newline is present,
+ // and so we wish to reduce the number of Printf() calls we have to make.
+ Printf(" x0 %016llx x1 %016llx x2 %016llx x3 %016llx\n",
+ frame[0], frame[1], frame[2], frame[3]);
+ Printf(" x4 %016llx x5 %016llx x6 %016llx x7 %016llx\n",
+ frame[4], frame[5], frame[6], frame[7]);
+ Printf(" x8 %016llx x9 %016llx x10 %016llx x11 %016llx\n",
+ frame[8], frame[9], frame[10], frame[11]);
+ Printf(" x12 %016llx x13 %016llx x14 %016llx x15 %016llx\n",
+ frame[12], frame[13], frame[14], frame[15]);
+ Printf(" x16 %016llx x17 %016llx x18 %016llx x19 %016llx\n",
+ frame[16], frame[17], frame[18], frame[19]);
+ Printf(" x20 %016llx x21 %016llx x22 %016llx x23 %016llx\n",
+ frame[20], frame[21], frame[22], frame[23]);
+ Printf(" x24 %016llx x25 %016llx x26 %016llx x27 %016llx\n",
+ frame[24], frame[25], frame[26], frame[27]);
+ Printf(" x28 %016llx x29 %016llx x30 %016llx\n",
+ frame[28], frame[29], frame[30]);
+}
+
+} // namespace __hwasan
diff --git a/libsanitizer/hwasan/hwasan_report.h b/libsanitizer/hwasan/hwasan_report.h
new file mode 100644
index 0000000..de86c38
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_report.h
@@ -0,0 +1,35 @@
+//===-- hwasan_report.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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file is a part of HWAddressSanitizer. HWASan-private header for error
+/// reporting functions.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef HWASAN_REPORT_H
+#define HWASAN_REPORT_H
+
+#include "sanitizer_common/sanitizer_internal_defs.h"
+#include "sanitizer_common/sanitizer_stacktrace.h"
+
+namespace __hwasan {
+
+void ReportStats();
+void ReportTagMismatch(StackTrace *stack, uptr addr, uptr access_size,
+ bool is_store, bool fatal, uptr *registers_frame);
+void ReportInvalidFree(StackTrace *stack, uptr addr);
+void ReportTailOverwritten(StackTrace *stack, uptr addr, uptr orig_size,
+ const u8 *expected);
+void ReportRegisters(uptr *registers_frame, uptr pc);
+void ReportAtExitStatistics();
+
+
+} // namespace __hwasan
+
+#endif // HWASAN_REPORT_H
diff --git a/libsanitizer/hwasan/hwasan_setjmp.S b/libsanitizer/hwasan/hwasan_setjmp.S
new file mode 100644
index 0000000..0c13543
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_setjmp.S
@@ -0,0 +1,100 @@
+//===-- hwasan_setjmp.S --------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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 HWAddressSanitizer.
+//
+// HWAddressSanitizer runtime.
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_common/sanitizer_asm.h"
+
+#if HWASAN_WITH_INTERCEPTORS && defined(__aarch64__)
+#include "sanitizer_common/sanitizer_platform.h"
+
+// We want to save the context of the calling function.
+// That requires
+// 1) No modification of the link register by this function.
+// 2) No modification of the stack pointer by this function.
+// 3) (no modification of any other saved register, but that's not really going
+// to occur, and hence isn't as much of a worry).
+//
+// There's essentially no way to ensure that the compiler will not modify the
+// stack pointer when compiling a C function.
+// Hence we have to write this function in assembly.
+
+.section .text
+.file "hwasan_setjmp.S"
+
+.global __interceptor_setjmp
+ASM_TYPE_FUNCTION(__interceptor_setjmp)
+__interceptor_setjmp:
+ CFI_STARTPROC
+ mov x1, #0
+ b __interceptor_sigsetjmp
+ CFI_ENDPROC
+ASM_SIZE(__interceptor_setjmp)
+
+#if SANITIZER_ANDROID
+// Bionic also defines a function `setjmp` that calls `sigsetjmp` saving the
+// current signal.
+.global __interceptor_setjmp_bionic
+ASM_TYPE_FUNCTION(__interceptor_setjmp_bionic)
+__interceptor_setjmp_bionic:
+ CFI_STARTPROC
+ mov x1, #1
+ b __interceptor_sigsetjmp
+ CFI_ENDPROC
+ASM_SIZE(__interceptor_setjmp_bionic)
+#endif
+
+.global __interceptor_sigsetjmp
+ASM_TYPE_FUNCTION(__interceptor_sigsetjmp)
+__interceptor_sigsetjmp:
+ CFI_STARTPROC
+ stp x19, x20, [x0, #0<<3]
+ stp x21, x22, [x0, #2<<3]
+ stp x23, x24, [x0, #4<<3]
+ stp x25, x26, [x0, #6<<3]
+ stp x27, x28, [x0, #8<<3]
+ stp x29, x30, [x0, #10<<3]
+ stp d8, d9, [x0, #14<<3]
+ stp d10, d11, [x0, #16<<3]
+ stp d12, d13, [x0, #18<<3]
+ stp d14, d15, [x0, #20<<3]
+ mov x2, sp
+ str x2, [x0, #13<<3]
+ // We always have the second argument to __sigjmp_save (savemask) set, since
+ // the _setjmp function above has set it for us as `false`.
+ // This function is defined in hwasan_interceptors.cc
+ b __sigjmp_save
+ CFI_ENDPROC
+ASM_SIZE(__interceptor_sigsetjmp)
+
+
+.macro ALIAS first second
+ .globl \second
+ .equ \second\(), \first
+.endm
+
+#if SANITIZER_ANDROID
+ALIAS __interceptor_sigsetjmp, sigsetjmp
+.weak sigsetjmp
+
+ALIAS __interceptor_setjmp_bionic, setjmp
+.weak setjmp
+#else
+ALIAS __interceptor_sigsetjmp, __sigsetjmp
+.weak __sigsetjmp
+#endif
+
+ALIAS __interceptor_setjmp, _setjmp
+.weak _setjmp
+#endif
+
+// We do not need executable stack.
+NO_EXEC_STACK_DIRECTIVE
diff --git a/libsanitizer/hwasan/hwasan_tag_mismatch_aarch64.S b/libsanitizer/hwasan/hwasan_tag_mismatch_aarch64.S
new file mode 100644
index 0000000..08df127
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_tag_mismatch_aarch64.S
@@ -0,0 +1,152 @@
+#include "sanitizer_common/sanitizer_asm.h"
+
+// The content of this file is AArch64-only:
+#if defined(__aarch64__)
+
+// The responsibility of the HWASan entry point in compiler-rt is to primarily
+// readjust the stack from the callee and save the current register values to
+// the stack.
+// This entry point function should be called from a __hwasan_check_* symbol.
+// These are generated during a lowering pass in the backend, and are found in
+// AArch64AsmPrinter::EmitHwasanMemaccessSymbols(). Please look there for
+// further information.
+// The __hwasan_check_* caller of this function should have expanded the stack
+// and saved the previous values of x0, x1, x29, and x30. This function will
+// "consume" these saved values and treats it as part of its own stack frame.
+// In this sense, the __hwasan_check_* callee and this function "share" a stack
+// frame. This allows us to omit having unwinding information (.cfi_*) present
+// in every __hwasan_check_* function, therefore reducing binary size. This is
+// particularly important as hwasan_check_* instances are duplicated in every
+// translation unit where HWASan is enabled.
+// This function calls HwasanTagMismatch to step back into the C++ code that
+// completes the stack unwinding and error printing. This function is is not
+// permitted to return.
+
+
+// Frame from __hwasan_check_:
+// | ... |
+// | ... |
+// | Previous stack frames... |
+// +=================================+
+// | Unused 8-bytes for maintaining |
+// | 16-byte SP alignment. |
+// +---------------------------------+
+// | Return address (x30) for caller |
+// | of __hwasan_check_*. |
+// +---------------------------------+
+// | Frame address (x29) for caller |
+// | of __hwasan_check_* |
+// +---------------------------------+ <-- [SP + 232]
+// | ... |
+// | |
+// | Stack frame space for x2 - x28. |
+// | |
+// | ... |
+// +---------------------------------+ <-- [SP + 16]
+// | |
+// | Saved x1, as __hwasan_check_* |
+// | clobbers it. |
+// +---------------------------------+
+// | Saved x0, likewise above. |
+// +---------------------------------+ <-- [x30 / SP]
+
+// This function takes two arguments:
+// * x0: The data address.
+// * x1: The encoded access info for the failing access.
+
+// This function has two entry points. The first, __hwasan_tag_mismatch, is used
+// by clients that were compiled without short tag checks (i.e. binaries built
+// by older compilers and binaries targeting older runtimes). In this case the
+// outlined tag check will be missing the code handling short tags (which won't
+// be used in the binary's own stack variables but may be used on the heap
+// or stack variables in other binaries), so the check needs to be done here.
+//
+// The second, __hwasan_tag_mismatch_v2, is used by binaries targeting newer
+// runtimes. This entry point bypasses the short tag check since it will have
+// already been done as part of the outlined tag check. Since tag mismatches are
+// uncommon, there isn't a significant performance benefit to being able to
+// bypass the check; the main benefits are that we can sometimes avoid
+// clobbering the x17 register in error reports, and that the program will have
+// a runtime dependency on the __hwasan_tag_mismatch_v2 symbol therefore it will
+// fail to start up given an older (i.e. incompatible) runtime.
+.section .text
+.file "hwasan_tag_mismatch_aarch64.S"
+.global __hwasan_tag_mismatch
+.type __hwasan_tag_mismatch, %function
+__hwasan_tag_mismatch:
+ // Compute the granule position one past the end of the access.
+ mov x16, #1
+ and x17, x1, #0xf
+ lsl x16, x16, x17
+ and x17, x0, #0xf
+ add x17, x16, x17
+
+ // Load the shadow byte again and check whether it is a short tag within the
+ // range of the granule position computed above.
+ ubfx x16, x0, #4, #52
+ ldrb w16, [x9, x16]
+ cmp w16, #0xf
+ b.hi __hwasan_tag_mismatch_v2
+ cmp w16, w17
+ b.lo __hwasan_tag_mismatch_v2
+
+ // Load the real tag from the last byte of the granule and compare against
+ // the pointer tag.
+ orr x16, x0, #0xf
+ ldrb w16, [x16]
+ cmp x16, x0, lsr #56
+ b.ne __hwasan_tag_mismatch_v2
+
+ // Restore x0, x1 and sp to their values from before the __hwasan_tag_mismatch
+ // call and resume execution.
+ ldp x0, x1, [sp], #256
+ ret
+
+.global __hwasan_tag_mismatch_v2
+.type __hwasan_tag_mismatch_v2, %function
+__hwasan_tag_mismatch_v2:
+ CFI_STARTPROC
+
+ // Set the CFA to be the return address for caller of __hwasan_check_*. Note
+ // that we do not emit CFI predicates to describe the contents of this stack
+ // frame, as this proxy entry point should never be debugged. The contents
+ // are static and are handled by the unwinder after calling
+ // __hwasan_tag_mismatch. The frame pointer is already correctly setup
+ // by __hwasan_check_*.
+ add x29, sp, #232
+ CFI_DEF_CFA(w29, 24)
+ CFI_OFFSET(w30, -16)
+ CFI_OFFSET(w29, -24)
+
+ // Save the rest of the registers into the preallocated space left by
+ // __hwasan_check.
+ str x28, [sp, #224]
+ stp x26, x27, [sp, #208]
+ stp x24, x25, [sp, #192]
+ stp x22, x23, [sp, #176]
+ stp x20, x21, [sp, #160]
+ stp x18, x19, [sp, #144]
+ stp x16, x17, [sp, #128]
+ stp x14, x15, [sp, #112]
+ stp x12, x13, [sp, #96]
+ stp x10, x11, [sp, #80]
+ stp x8, x9, [sp, #64]
+ stp x6, x7, [sp, #48]
+ stp x4, x5, [sp, #32]
+ stp x2, x3, [sp, #16]
+
+ // Pass the address of the frame to __hwasan_tag_mismatch4, so that it can
+ // extract the saved registers from this frame without having to worry about
+ // finding this frame.
+ mov x2, sp
+
+ bl __hwasan_tag_mismatch4
+ CFI_ENDPROC
+
+.Lfunc_end0:
+ .size __hwasan_tag_mismatch, .Lfunc_end0-__hwasan_tag_mismatch
+
+#endif // defined(__aarch64__)
+
+// We do not need executable stack.
+NO_EXEC_STACK_DIRECTIVE
diff --git a/libsanitizer/hwasan/hwasan_thread.cpp b/libsanitizer/hwasan/hwasan_thread.cpp
new file mode 100644
index 0000000..b81a635
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_thread.cpp
@@ -0,0 +1,133 @@
+
+#include "hwasan.h"
+#include "hwasan_mapping.h"
+#include "hwasan_thread.h"
+#include "hwasan_poisoning.h"
+#include "hwasan_interface_internal.h"
+
+#include "sanitizer_common/sanitizer_file.h"
+#include "sanitizer_common/sanitizer_placement_new.h"
+#include "sanitizer_common/sanitizer_tls_get_addr.h"
+
+
+namespace __hwasan {
+
+static u32 RandomSeed() {
+ u32 seed;
+ do {
+ if (UNLIKELY(!GetRandom(reinterpret_cast<void *>(&seed), sizeof(seed),
+ /*blocking=*/false))) {
+ seed = static_cast<u32>(
+ (NanoTime() >> 12) ^
+ (reinterpret_cast<uptr>(__builtin_frame_address(0)) >> 4));
+ }
+ } while (!seed);
+ return seed;
+}
+
+void Thread::InitRandomState() {
+ random_state_ = flags()->random_tags ? RandomSeed() : unique_id_;
+
+ // Push a random number of zeros onto the ring buffer so that the first stack
+ // tag base will be random.
+ for (tag_t i = 0, e = GenerateRandomTag(); i != e; ++i)
+ stack_allocations_->push(0);
+}
+
+void Thread::Init(uptr stack_buffer_start, uptr stack_buffer_size) {
+ static u64 unique_id;
+ unique_id_ = unique_id++;
+ if (auto sz = flags()->heap_history_size)
+ heap_allocations_ = HeapAllocationsRingBuffer::New(sz);
+
+ HwasanTSDThreadInit(); // Only needed with interceptors.
+ uptr *ThreadLong = GetCurrentThreadLongPtr();
+ // The following implicitly sets (this) as the current thread.
+ stack_allocations_ = new (ThreadLong)
+ StackAllocationsRingBuffer((void *)stack_buffer_start, stack_buffer_size);
+ // Check that it worked.
+ CHECK_EQ(GetCurrentThread(), this);
+
+ // ScopedTaggingDisable needs GetCurrentThread to be set up.
+ ScopedTaggingDisabler disabler;
+
+ uptr tls_size;
+ uptr stack_size;
+ GetThreadStackAndTls(IsMainThread(), &stack_bottom_, &stack_size, &tls_begin_,
+ &tls_size);
+ stack_top_ = stack_bottom_ + stack_size;
+ tls_end_ = tls_begin_ + tls_size;
+
+ if (stack_bottom_) {
+ int local;
+ CHECK(AddrIsInStack((uptr)&local));
+ CHECK(MemIsApp(stack_bottom_));
+ CHECK(MemIsApp(stack_top_ - 1));
+ }
+
+ if (flags()->verbose_threads) {
+ if (IsMainThread()) {
+ Printf("sizeof(Thread): %zd sizeof(HeapRB): %zd sizeof(StackRB): %zd\n",
+ sizeof(Thread), heap_allocations_->SizeInBytes(),
+ stack_allocations_->size() * sizeof(uptr));
+ }
+ Print("Creating : ");
+ }
+}
+
+void Thread::ClearShadowForThreadStackAndTLS() {
+ if (stack_top_ != stack_bottom_)
+ TagMemory(stack_bottom_, stack_top_ - stack_bottom_, 0);
+ if (tls_begin_ != tls_end_)
+ TagMemory(tls_begin_, tls_end_ - tls_begin_, 0);
+}
+
+void Thread::Destroy() {
+ if (flags()->verbose_threads)
+ Print("Destroying: ");
+ AllocatorSwallowThreadLocalCache(allocator_cache());
+ ClearShadowForThreadStackAndTLS();
+ if (heap_allocations_)
+ heap_allocations_->Delete();
+ DTLS_Destroy();
+ // Unregister this as the current thread.
+ // Instrumented code can not run on this thread from this point onwards, but
+ // malloc/free can still be served. Glibc may call free() very late, after all
+ // TSD destructors are done.
+ CHECK_EQ(GetCurrentThread(), this);
+ *GetCurrentThreadLongPtr() = 0;
+}
+
+void Thread::Print(const char *Prefix) {
+ Printf("%sT%zd %p stack: [%p,%p) sz: %zd tls: [%p,%p)\n", Prefix,
+ unique_id_, this, stack_bottom(), stack_top(),
+ stack_top() - stack_bottom(),
+ tls_begin(), tls_end());
+}
+
+static u32 xorshift(u32 state) {
+ state ^= state << 13;
+ state ^= state >> 17;
+ state ^= state << 5;
+ return state;
+}
+
+// Generate a (pseudo-)random non-zero tag.
+tag_t Thread::GenerateRandomTag() {
+ if (tagging_disabled_) return 0;
+ tag_t tag;
+ do {
+ if (flags()->random_tags) {
+ if (!random_buffer_)
+ random_buffer_ = random_state_ = xorshift(random_state_);
+ CHECK(random_buffer_);
+ tag = random_buffer_ & 0xFF;
+ random_buffer_ >>= 8;
+ } else {
+ tag = random_state_ = (random_state_ + 1) & 0xFF;
+ }
+ } while (!tag);
+ return tag;
+}
+
+} // namespace __hwasan
diff --git a/libsanitizer/hwasan/hwasan_thread.h b/libsanitizer/hwasan/hwasan_thread.h
new file mode 100644
index 0000000..ebcdb79
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_thread.h
@@ -0,0 +1,98 @@
+//===-- hwasan_thread.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 HWAddressSanitizer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef HWASAN_THREAD_H
+#define HWASAN_THREAD_H
+
+#include "hwasan_allocator.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_ring_buffer.h"
+
+namespace __hwasan {
+
+typedef __sanitizer::CompactRingBuffer<uptr> StackAllocationsRingBuffer;
+
+class Thread {
+ public:
+ void Init(uptr stack_buffer_start, uptr stack_buffer_size); // Must be called from the thread itself.
+ void InitRandomState();
+ void Destroy();
+
+ uptr stack_top() { return stack_top_; }
+ uptr stack_bottom() { return stack_bottom_; }
+ uptr stack_size() { return stack_top() - stack_bottom(); }
+ uptr tls_begin() { return tls_begin_; }
+ uptr tls_end() { return tls_end_; }
+ bool IsMainThread() { return unique_id_ == 0; }
+
+ bool AddrIsInStack(uptr addr) {
+ return addr >= stack_bottom_ && addr < stack_top_;
+ }
+
+ AllocatorCache *allocator_cache() { return &allocator_cache_; }
+ HeapAllocationsRingBuffer *heap_allocations() { return heap_allocations_; }
+ StackAllocationsRingBuffer *stack_allocations() { return stack_allocations_; }
+
+ tag_t GenerateRandomTag();
+
+ void DisableTagging() { tagging_disabled_++; }
+ void EnableTagging() { tagging_disabled_--; }
+
+ u64 unique_id() const { return unique_id_; }
+ void Announce() {
+ if (announced_) return;
+ announced_ = true;
+ Print("Thread: ");
+ }
+
+ uptr &vfork_spill() { return vfork_spill_; }
+
+ private:
+ // NOTE: There is no Thread constructor. It is allocated
+ // via mmap() and *must* be valid in zero-initialized state.
+ void ClearShadowForThreadStackAndTLS();
+ void Print(const char *prefix);
+ uptr vfork_spill_;
+ uptr stack_top_;
+ uptr stack_bottom_;
+ uptr tls_begin_;
+ uptr tls_end_;
+
+ u32 random_state_;
+ u32 random_buffer_;
+
+ AllocatorCache allocator_cache_;
+ HeapAllocationsRingBuffer *heap_allocations_;
+ StackAllocationsRingBuffer *stack_allocations_;
+
+ Thread *next_; // All live threads form a linked list.
+
+ u64 unique_id_; // counting from zero.
+
+ u32 tagging_disabled_; // if non-zero, malloc uses zero tag in this thread.
+
+ bool announced_;
+
+ friend struct ThreadListHead;
+};
+
+Thread *GetCurrentThread();
+uptr *GetCurrentThreadLongPtr();
+
+struct ScopedTaggingDisabler {
+ ScopedTaggingDisabler() { GetCurrentThread()->DisableTagging(); }
+ ~ScopedTaggingDisabler() { GetCurrentThread()->EnableTagging(); }
+};
+
+} // namespace __hwasan
+
+#endif // HWASAN_THREAD_H
diff --git a/libsanitizer/hwasan/hwasan_thread_list.cpp b/libsanitizer/hwasan/hwasan_thread_list.cpp
new file mode 100644
index 0000000..a31eee8
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_thread_list.cpp
@@ -0,0 +1,15 @@
+#include "hwasan_thread_list.h"
+
+namespace __hwasan {
+static ALIGNED(16) char thread_list_placeholder[sizeof(HwasanThreadList)];
+static HwasanThreadList *hwasan_thread_list;
+
+HwasanThreadList &hwasanThreadList() { return *hwasan_thread_list; }
+
+void InitThreadList(uptr storage, uptr size) {
+ CHECK(hwasan_thread_list == nullptr);
+ hwasan_thread_list =
+ new (thread_list_placeholder) HwasanThreadList(storage, size);
+}
+
+} // namespace
diff --git a/libsanitizer/hwasan/hwasan_thread_list.h b/libsanitizer/hwasan/hwasan_thread_list.h
new file mode 100644
index 0000000..914b632
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_thread_list.h
@@ -0,0 +1,215 @@
+//===-- hwasan_thread_list.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 HWAddressSanitizer.
+//
+//===----------------------------------------------------------------------===//
+
+// HwasanThreadList is a registry for live threads, as well as an allocator for
+// HwasanThread objects and their stack history ring buffers. There are
+// constraints on memory layout of the shadow region and CompactRingBuffer that
+// are part of the ABI contract between compiler-rt and llvm.
+//
+// * Start of the shadow memory region is aligned to 2**kShadowBaseAlignment.
+// * All stack ring buffers are located within (2**kShadowBaseAlignment)
+// sized region below and adjacent to the shadow region.
+// * Each ring buffer has a size of (2**N)*4096 where N is in [0, 8), and is
+// aligned to twice its size. The value of N can be different for each buffer.
+//
+// These constrains guarantee that, given an address A of any element of the
+// ring buffer,
+// A_next = (A + sizeof(uptr)) & ~((1 << (N + 13)) - 1)
+// is the address of the next element of that ring buffer (with wrap-around).
+// And, with K = kShadowBaseAlignment,
+// S = (A | ((1 << K) - 1)) + 1
+// (align up to kShadowBaseAlignment) is the start of the shadow region.
+//
+// These calculations are used in compiler instrumentation to update the ring
+// buffer and obtain the base address of shadow using only two inputs: address
+// of the current element of the ring buffer, and N (i.e. size of the ring
+// buffer). Since the value of N is very limited, we pack both inputs into a
+// single thread-local word as
+// (1 << (N + 56)) | A
+// See the implementation of class CompactRingBuffer, which is what is stored in
+// said thread-local word.
+//
+// Note the unusual way of aligning up the address of the shadow:
+// (A | ((1 << K) - 1)) + 1
+// It is only correct if A is not already equal to the shadow base address, but
+// it saves 2 instructions on AArch64.
+
+#include "hwasan.h"
+#include "hwasan_allocator.h"
+#include "hwasan_flags.h"
+#include "hwasan_thread.h"
+
+#include "sanitizer_common/sanitizer_placement_new.h"
+
+namespace __hwasan {
+
+static uptr RingBufferSize() {
+ uptr desired_bytes = flags()->stack_history_size * sizeof(uptr);
+ // FIXME: increase the limit to 8 once this bug is fixed:
+ // https://bugs.llvm.org/show_bug.cgi?id=39030
+ for (int shift = 1; shift < 7; ++shift) {
+ uptr size = 4096 * (1ULL << shift);
+ if (size >= desired_bytes)
+ return size;
+ }
+ Printf("stack history size too large: %d\n", flags()->stack_history_size);
+ CHECK(0);
+ return 0;
+}
+
+struct ThreadListHead {
+ Thread *list_;
+
+ ThreadListHead() : list_(nullptr) {}
+
+ void Push(Thread *t) {
+ t->next_ = list_;
+ list_ = t;
+ }
+
+ Thread *Pop() {
+ Thread *t = list_;
+ if (t)
+ list_ = t->next_;
+ return t;
+ }
+
+ void Remove(Thread *t) {
+ Thread **cur = &list_;
+ while (*cur != t) cur = &(*cur)->next_;
+ CHECK(*cur && "thread not found");
+ *cur = (*cur)->next_;
+ }
+
+ template <class CB>
+ void ForEach(CB cb) {
+ Thread *t = list_;
+ while (t) {
+ cb(t);
+ t = t->next_;
+ }
+ }
+};
+
+struct ThreadStats {
+ uptr n_live_threads;
+ uptr total_stack_size;
+};
+
+class HwasanThreadList {
+ public:
+ HwasanThreadList(uptr storage, uptr size)
+ : free_space_(storage), free_space_end_(storage + size) {
+ // [storage, storage + size) is used as a vector of
+ // thread_alloc_size_-sized, ring_buffer_size_*2-aligned elements.
+ // Each element contains
+ // * a ring buffer at offset 0,
+ // * a Thread object at offset ring_buffer_size_.
+ ring_buffer_size_ = RingBufferSize();
+ thread_alloc_size_ =
+ RoundUpTo(ring_buffer_size_ + sizeof(Thread), ring_buffer_size_ * 2);
+ }
+
+ Thread *CreateCurrentThread() {
+ Thread *t;
+ {
+ SpinMutexLock l(&list_mutex_);
+ t = free_list_.Pop();
+ if (t) {
+ uptr start = (uptr)t - ring_buffer_size_;
+ internal_memset((void *)start, 0, ring_buffer_size_ + sizeof(Thread));
+ } else {
+ t = AllocThread();
+ }
+ live_list_.Push(t);
+ }
+ t->Init((uptr)t - ring_buffer_size_, ring_buffer_size_);
+ AddThreadStats(t);
+ return t;
+ }
+
+ void DontNeedThread(Thread *t) {
+ uptr start = (uptr)t - ring_buffer_size_;
+ ReleaseMemoryPagesToOS(start, start + thread_alloc_size_);
+ }
+
+ void ReleaseThread(Thread *t) {
+ RemoveThreadStats(t);
+ t->Destroy();
+ SpinMutexLock l(&list_mutex_);
+ live_list_.Remove(t);
+ free_list_.Push(t);
+ DontNeedThread(t);
+ }
+
+ Thread *GetThreadByBufferAddress(uptr p) {
+ return (Thread *)(RoundDownTo(p, ring_buffer_size_ * 2) +
+ ring_buffer_size_);
+ }
+
+ uptr MemoryUsedPerThread() {
+ uptr res = sizeof(Thread) + ring_buffer_size_;
+ if (auto sz = flags()->heap_history_size)
+ res += HeapAllocationsRingBuffer::SizeInBytes(sz);
+ return res;
+ }
+
+ template <class CB>
+ void VisitAllLiveThreads(CB cb) {
+ SpinMutexLock l(&list_mutex_);
+ live_list_.ForEach(cb);
+ }
+
+ void AddThreadStats(Thread *t) {
+ SpinMutexLock l(&stats_mutex_);
+ stats_.n_live_threads++;
+ stats_.total_stack_size += t->stack_size();
+ }
+
+ void RemoveThreadStats(Thread *t) {
+ SpinMutexLock l(&stats_mutex_);
+ stats_.n_live_threads--;
+ stats_.total_stack_size -= t->stack_size();
+ }
+
+ ThreadStats GetThreadStats() {
+ SpinMutexLock l(&stats_mutex_);
+ return stats_;
+ }
+
+ private:
+ Thread *AllocThread() {
+ uptr align = ring_buffer_size_ * 2;
+ CHECK(IsAligned(free_space_, align));
+ Thread *t = (Thread *)(free_space_ + ring_buffer_size_);
+ free_space_ += thread_alloc_size_;
+ CHECK(free_space_ <= free_space_end_ && "out of thread memory");
+ return t;
+ }
+
+ uptr free_space_;
+ uptr free_space_end_;
+ uptr ring_buffer_size_;
+ uptr thread_alloc_size_;
+
+ ThreadListHead free_list_;
+ ThreadListHead live_list_;
+ SpinMutex list_mutex_;
+
+ ThreadStats stats_;
+ SpinMutex stats_mutex_;
+};
+
+void InitThreadList(uptr storage, uptr size);
+HwasanThreadList &hwasanThreadList();
+
+} // namespace
diff --git a/libsanitizer/hwasan/hwasan_type_test.cpp b/libsanitizer/hwasan/hwasan_type_test.cpp
new file mode 100644
index 0000000..8cff495
--- /dev/null
+++ b/libsanitizer/hwasan/hwasan_type_test.cpp
@@ -0,0 +1,25 @@
+//===-- hwasan_type_test.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 HWAddressSanitizer.
+//
+// Compile-time tests of the internal type definitions.
+//===----------------------------------------------------------------------===//
+
+#include "interception/interception.h"
+#include "sanitizer_common/sanitizer_platform_limits_posix.h"
+#include "hwasan.h"
+#include <setjmp.h>
+
+#define CHECK_TYPE_SIZE_FITS(TYPE) \
+ COMPILER_CHECK(sizeof(__hw_##TYPE) <= sizeof(TYPE))
+
+#if HWASAN_WITH_INTERCEPTORS && defined(__aarch64__)
+CHECK_TYPE_SIZE_FITS(jmp_buf);
+CHECK_TYPE_SIZE_FITS(sigjmp_buf);
+#endif
diff --git a/libsanitizer/hwasan/libtool-version b/libsanitizer/hwasan/libtool-version
new file mode 100644
index 0000000..d1f9aa1
--- /dev/null
+++ b/libsanitizer/hwasan/libtool-version
@@ -0,0 +1,6 @@
+# This file is used to maintain libtool version info for libhwasan. See
+# the libtool manual to understand the meaning of the fields. This is
+# a separate file so that version updates don't involve re-running
+# automake.
+# CURRENT:REVISION:AGE
+0:0:0
diff --git a/libsanitizer/include/sanitizer/memprof_interface.h b/libsanitizer/include/sanitizer/memprof_interface.h
new file mode 100644
index 0000000..a721260
--- /dev/null
+++ b/libsanitizer/include/sanitizer/memprof_interface.h
@@ -0,0 +1,60 @@
+//===-- sanitizer/memprof_interface.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 MemProfiler (MemProf).
+//
+// Public interface header.
+//===----------------------------------------------------------------------===//
+#ifndef SANITIZER_MEMPROF_INTERFACE_H
+#define SANITIZER_MEMPROF_INTERFACE_H
+
+#include <sanitizer/common_interface_defs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/// Records access to a memory region (<c>[addr, addr+size)</c>).
+///
+/// This memory must be previously allocated by your program.
+///
+/// \param addr Start of memory region.
+/// \param size Size of memory region.
+void __memprof_record_access_range(void const volatile *addr, size_t size);
+
+/// Records access to a memory address <c><i>addr</i></c>.
+///
+/// This memory must be previously allocated by your program.
+///
+/// \param addr Accessed memory address
+void __memprof_record_access(void const volatile *addr);
+
+/// User-provided callback on MemProf errors.
+///
+/// You can provide a function that would be called immediately when MemProf
+/// detects an error. This is useful in cases when MemProf detects an error but
+/// your program crashes before the MemProf report is printed.
+void __memprof_on_error(void);
+
+/// Prints accumulated statistics to <c>stderr</c> (useful for calling from the
+/// debugger).
+void __memprof_print_accumulated_stats(void);
+
+/// User-provided default option settings.
+///
+/// You can provide your own implementation of this function to return a string
+/// containing MemProf runtime options (for example,
+/// <c>verbosity=1:print_stats=1</c>).
+///
+/// \returns Default options string.
+const char *__memprof_default_options(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // SANITIZER_MEMPROF_INTERFACE_H
diff --git a/libsanitizer/interception/Makefile.in b/libsanitizer/interception/Makefile.in
index a20f52e..4a872cb 100644
--- a/libsanitizer/interception/Makefile.in
+++ b/libsanitizer/interception/Makefile.in
@@ -301,6 +301,7 @@ install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
link_libasan = @link_libasan@
+link_libhwasan = @link_libhwasan@
link_liblsan = @link_liblsan@
link_libtsan = @link_libtsan@
link_libubsan = @link_libubsan@
diff --git a/libsanitizer/interception/interception.h b/libsanitizer/interception/interception.h
index d27a8cc..cb0b528 100644
--- a/libsanitizer/interception/interception.h
+++ b/libsanitizer/interception/interception.h
@@ -17,7 +17,7 @@
#include "sanitizer_common/sanitizer_internal_defs.h"
#if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_MAC && \
- !SANITIZER_NETBSD && !SANITIZER_OPENBSD && !SANITIZER_WINDOWS && \
+ !SANITIZER_NETBSD && !SANITIZER_WINDOWS && \
!SANITIZER_FUCHSIA && !SANITIZER_RTEMS && !SANITIZER_SOLARIS
# error "Interception doesn't work on this operating system."
#endif
@@ -281,7 +281,7 @@ typedef unsigned long uptr;
#define INCLUDED_FROM_INTERCEPTION_LIB
#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
- SANITIZER_OPENBSD || SANITIZER_SOLARIS
+ SANITIZER_SOLARIS
# include "interception_linux.h"
# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
diff --git a/libsanitizer/interception/interception_linux.cpp b/libsanitizer/interception/interception_linux.cpp
index 950cd51..6883608 100644
--- a/libsanitizer/interception/interception_linux.cpp
+++ b/libsanitizer/interception/interception_linux.cpp
@@ -14,7 +14,7 @@
#include "interception.h"
#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
- SANITIZER_OPENBSD || SANITIZER_SOLARIS
+ SANITIZER_SOLARIS
#include <dlfcn.h> // for dlsym() and dlvsym()
@@ -64,7 +64,7 @@ bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
}
// Android and Solaris do not have dlvsym
-#if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD
+#if !SANITIZER_ANDROID && !SANITIZER_SOLARIS
static void *GetFuncAddr(const char *name, const char *ver) {
return dlvsym(RTLD_NEXT, name, ver);
}
@@ -80,4 +80,4 @@ bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real,
} // namespace __interception
#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD ||
- // SANITIZER_OPENBSD || SANITIZER_SOLARIS
+ // SANITIZER_SOLARIS
diff --git a/libsanitizer/interception/interception_linux.h b/libsanitizer/interception/interception_linux.h
index e578da0..097375f 100644
--- a/libsanitizer/interception/interception_linux.h
+++ b/libsanitizer/interception/interception_linux.h
@@ -12,7 +12,7 @@
//===----------------------------------------------------------------------===//
#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
- SANITIZER_OPENBSD || SANITIZER_SOLARIS
+ SANITIZER_SOLARIS
#if !defined(INCLUDED_FROM_INTERCEPTION_LIB)
# error "interception_linux.h should be included from interception library only"
@@ -35,8 +35,8 @@ bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real,
(::__interception::uptr) & (func), \
(::__interception::uptr) & WRAP(func))
-// Android, Solaris and OpenBSD do not have dlvsym
-#if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD
+// Android and Solaris do not have dlvsym
+#if !SANITIZER_ANDROID && !SANITIZER_SOLARIS
#define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
::__interception::InterceptFunction( \
#func, symver, \
@@ -50,4 +50,4 @@ bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real,
#endif // INTERCEPTION_LINUX_H
#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD ||
- // SANITIZER_OPENBSD || SANITIZER_SOLARIS
+ // SANITIZER_SOLARIS
diff --git a/libsanitizer/libbacktrace/Makefile.in b/libsanitizer/libbacktrace/Makefile.in
index c843bce..3f05cdf 100644
--- a/libsanitizer/libbacktrace/Makefile.in
+++ b/libsanitizer/libbacktrace/Makefile.in
@@ -351,6 +351,7 @@ install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
link_libasan = @link_libasan@
+link_libhwasan = @link_libhwasan@
link_liblsan = @link_liblsan@
link_libtsan = @link_libtsan@
link_libubsan = @link_libubsan@
diff --git a/libsanitizer/libsanitizer.spec.in b/libsanitizer/libsanitizer.spec.in
index a4fa87d..70a3357 100644
--- a/libsanitizer/libsanitizer.spec.in
+++ b/libsanitizer/libsanitizer.spec.in
@@ -3,6 +3,8 @@
*link_libasan: @link_libasan@
+*link_libhwasan: @link_libhwasan@
+
*link_libtsan: @link_libtsan@
*link_libubsan: @link_libubsan@
diff --git a/libsanitizer/lsan/Makefile.in b/libsanitizer/lsan/Makefile.in
index 23a6fa6..fbe87cd2 100644
--- a/libsanitizer/lsan/Makefile.in
+++ b/libsanitizer/lsan/Makefile.in
@@ -346,6 +346,7 @@ install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
link_libasan = @link_libasan@
+link_libhwasan = @link_libhwasan@
link_liblsan = @link_liblsan@
link_libtsan = @link_libtsan@
link_libubsan = @link_libubsan@
diff --git a/libsanitizer/lsan/lsan.cpp b/libsanitizer/lsan/lsan.cpp
index c8cc045..2c0a3bf 100644
--- a/libsanitizer/lsan/lsan.cpp
+++ b/libsanitizer/lsan/lsan.cpp
@@ -77,7 +77,7 @@ static void InitializeFlags() {
parser.ParseString(lsan_default_options);
parser.ParseStringFromEnv("LSAN_OPTIONS");
- SetVerbosity(common_flags()->verbosity);
+ InitializeCommonFlags();
if (Verbosity()) ReportUnrecognizedFlags();
diff --git a/libsanitizer/lsan/lsan_common.cpp b/libsanitizer/lsan/lsan_common.cpp
index 107d63a..9e23aa9 100644
--- a/libsanitizer/lsan/lsan_common.cpp
+++ b/libsanitizer/lsan/lsan_common.cpp
@@ -71,17 +71,17 @@ static const char kSuppressionLeak[] = "leak";
static const char *kSuppressionTypes[] = { kSuppressionLeak };
static const char kStdSuppressions[] =
#if SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT
- // For more details refer to the SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT
- // definition.
- "leak:*pthread_exit*\n"
+ // For more details refer to the SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT
+ // definition.
+ "leak:*pthread_exit*\n"
#endif // SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT
#if SANITIZER_MAC
- // For Darwin and os_log/os_trace: https://reviews.llvm.org/D35173
- "leak:*_os_trace*\n"
+ // For Darwin and os_log/os_trace: https://reviews.llvm.org/D35173
+ "leak:*_os_trace*\n"
#endif
- // TLS leak in some glibc versions, described in
- // https://sourceware.org/bugzilla/show_bug.cgi?id=12650.
- "leak:*tls_get_addr*\n";
+ // TLS leak in some glibc versions, described in
+ // https://sourceware.org/bugzilla/show_bug.cgi?id=12650.
+ "leak:*tls_get_addr*\n";
void InitializeSuppressions() {
CHECK_EQ(nullptr, suppression_ctx);
@@ -215,6 +215,12 @@ static void ProcessThreads(SuspendedThreadsList const &, Frontier *) {}
#else
+#if SANITIZER_ANDROID
+// FIXME: Move this out into *libcdep.cpp
+extern "C" SANITIZER_WEAK_ATTRIBUTE void __libc_iterate_dynamic_tls(
+ pid_t, void (*cb)(void *, void *, uptr, void *), void *);
+#endif
+
// Scans thread data (stacks and TLS) for heap pointers.
static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
Frontier *frontier) {
@@ -294,6 +300,20 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
kReachable);
}
}
+#if SANITIZER_ANDROID
+ auto *cb = +[](void *dtls_begin, void *dtls_end, uptr /*dso_idd*/,
+ void *arg) -> void {
+ ScanRangeForPointers(reinterpret_cast<uptr>(dtls_begin),
+ reinterpret_cast<uptr>(dtls_end),
+ reinterpret_cast<Frontier *>(arg), "DTLS",
+ kReachable);
+ };
+
+ // FIXME: There might be a race-condition here (and in Bionic) if the
+ // thread is suspended in the middle of updating its DTLS. IOWs, we
+ // could scan already freed memory. (probably fine for now)
+ __libc_iterate_dynamic_tls(os_id, cb, frontier);
+#else
if (dtls && !DTLSInDestruction(dtls)) {
for (uptr j = 0; j < dtls->dtv_size; ++j) {
uptr dtls_beg = dtls->dtv[j].beg;
@@ -309,6 +329,7 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
// this and continue.
LOG_THREADS("Thread %d has DTLS under destruction.\n", os_id);
}
+#endif
}
}
}
@@ -576,7 +597,7 @@ static void CheckForLeaksCallback(const SuspendedThreadsList &suspended_threads,
static bool CheckForLeaks() {
if (&__lsan_is_turned_off && __lsan_is_turned_off())
- return false;
+ return false;
EnsureMainThreadIDIsCorrect();
CheckForLeaksParam param;
LockStuffAndStopTheWorld(CheckForLeaksCallback, &param);
diff --git a/libsanitizer/lsan/lsan_common.h b/libsanitizer/lsan/lsan_common.h
index 3434bee..1fdce08 100644
--- a/libsanitizer/lsan/lsan_common.h
+++ b/libsanitizer/lsan/lsan_common.h
@@ -29,16 +29,17 @@
// To enable LeakSanitizer on a new architecture, one needs to implement the
// internal_clone function as well as (probably) adjust the TLS machinery for
// the new architecture inside the sanitizer library.
-#if (SANITIZER_LINUX && !SANITIZER_ANDROID || SANITIZER_MAC) && \
- (SANITIZER_WORDSIZE == 64) && \
- (defined(__x86_64__) || defined(__mips64) || defined(__aarch64__) || \
+// Exclude leak-detection on arm32 for Android because `__aeabi_read_tp`
+// is missing. This caused a link error.
+#if SANITIZER_ANDROID && (__ANDROID_API__ < 28 || defined(__arm__))
+#define CAN_SANITIZE_LEAKS 0
+#elif (SANITIZER_LINUX || SANITIZER_MAC) && (SANITIZER_WORDSIZE == 64) && \
+ (defined(__x86_64__) || defined(__mips64) || defined(__aarch64__) || \
defined(__powerpc64__) || defined(__s390x__))
#define CAN_SANITIZE_LEAKS 1
-#elif defined(__i386__) && \
- (SANITIZER_LINUX && !SANITIZER_ANDROID || SANITIZER_MAC)
+#elif defined(__i386__) && (SANITIZER_LINUX || SANITIZER_MAC)
#define CAN_SANITIZE_LEAKS 1
-#elif defined(__arm__) && \
- SANITIZER_LINUX && !SANITIZER_ANDROID
+#elif defined(__arm__) && SANITIZER_LINUX
#define CAN_SANITIZE_LEAKS 1
#elif SANITIZER_NETBSD || SANITIZER_FUCHSIA
#define CAN_SANITIZE_LEAKS 1
diff --git a/libsanitizer/lsan/lsan_common_fuchsia.cpp b/libsanitizer/lsan/lsan_common_fuchsia.cpp
index caedbf1..3c62c94 100644
--- a/libsanitizer/lsan/lsan_common_fuchsia.cpp
+++ b/libsanitizer/lsan/lsan_common_fuchsia.cpp
@@ -19,6 +19,7 @@
#include "lsan_allocator.h"
#include "sanitizer_common/sanitizer_flags.h"
+#include "sanitizer_common/sanitizer_stoptheworld_fuchsia.h"
#include "sanitizer_common/sanitizer_thread_registry.h"
// Ensure that the Zircon system ABI is linked in.
@@ -147,7 +148,7 @@ void LockStuffAndStopTheWorld(StopTheWorldCallback callback,
&params->argument->frontier);
}
- params->callback({}, params->argument);
+ params->callback(SuspendedThreadsListFuchsia(), params->argument);
},
&params);
diff --git a/libsanitizer/lsan/lsan_common_linux.cpp b/libsanitizer/lsan/lsan_common_linux.cpp
index c97ef315..3af586e 100644
--- a/libsanitizer/lsan/lsan_common_linux.cpp
+++ b/libsanitizer/lsan/lsan_common_linux.cpp
@@ -93,6 +93,11 @@ static int ProcessGlobalRegionsCallback(struct dl_phdr_info *info, size_t size,
return 0;
}
+#if SANITIZER_ANDROID && __ANDROID_API__ < 21
+extern "C" __attribute__((weak)) int dl_iterate_phdr(
+ int (*)(struct dl_phdr_info *, size_t, void *), void *);
+#endif
+
// Scans global variables for heap pointers.
void ProcessGlobalRegions(Frontier *frontier) {
if (!flags()->use_globals) return;
diff --git a/libsanitizer/lsan/lsan_interceptors.cpp b/libsanitizer/lsan/lsan_interceptors.cpp
index 39d075d..bf8d316 100644
--- a/libsanitizer/lsan/lsan_interceptors.cpp
+++ b/libsanitizer/lsan/lsan_interceptors.cpp
@@ -115,7 +115,11 @@ INTERCEPTOR(void*, memalign, uptr alignment, uptr size) {
return lsan_memalign(alignment, size, stack);
}
#define LSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign)
+#else
+#define LSAN_MAYBE_INTERCEPT_MEMALIGN
+#endif // SANITIZER_INTERCEPT_MEMALIGN
+#if SANITIZER_INTERCEPT___LIBC_MEMALIGN
INTERCEPTOR(void *, __libc_memalign, uptr alignment, uptr size) {
ENSURE_LSAN_INITED;
GET_STACK_TRACE_MALLOC;
@@ -125,9 +129,8 @@ INTERCEPTOR(void *, __libc_memalign, uptr alignment, uptr size) {
}
#define LSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN INTERCEPT_FUNCTION(__libc_memalign)
#else
-#define LSAN_MAYBE_INTERCEPT_MEMALIGN
#define LSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN
-#endif // SANITIZER_INTERCEPT_MEMALIGN
+#endif // SANITIZER_INTERCEPT___LIBC_MEMALIGN
#if SANITIZER_INTERCEPT_ALIGNED_ALLOC
INTERCEPTOR(void*, aligned_alloc, uptr alignment, uptr size) {
diff --git a/libsanitizer/lsan/lsan_posix.h b/libsanitizer/lsan/lsan_posix.h
index 840e427..b1265f2 100644
--- a/libsanitizer/lsan/lsan_posix.h
+++ b/libsanitizer/lsan/lsan_posix.h
@@ -27,7 +27,7 @@ struct DTLS;
namespace __lsan {
-class ThreadContext : public ThreadContextLsanBase {
+class ThreadContext final : public ThreadContextLsanBase {
public:
explicit ThreadContext(int tid);
void OnStarted(void *arg) override;
diff --git a/libsanitizer/lsan/lsan_thread.h b/libsanitizer/lsan/lsan_thread.h
index e876f9f..3664375 100644
--- a/libsanitizer/lsan/lsan_thread.h
+++ b/libsanitizer/lsan/lsan_thread.h
@@ -32,6 +32,7 @@ class ThreadContextLsanBase : public ThreadContextBase {
void *onstarted_arg);
protected:
+ ~ThreadContextLsanBase() {}
uptr stack_begin_ = 0;
uptr stack_end_ = 0;
uptr cache_begin_ = 0;
diff --git a/libsanitizer/merge.sh b/libsanitizer/merge.sh
index 3f4f162..95ded4f 100755
--- a/libsanitizer/merge.sh
+++ b/libsanitizer/merge.sh
@@ -71,6 +71,7 @@ merge lib/tsan/rtl tsan
merge lib/sanitizer_common sanitizer_common
merge lib/interception interception
merge lib/ubsan ubsan
+merge lib/hwasan hwasan
# Need to merge lib/builtins/assembly.h file:
mkdir -p builtins
diff --git a/libsanitizer/sanitizer_common/Makefile.in b/libsanitizer/sanitizer_common/Makefile.in
index 299de50..7e5555c 100644
--- a/libsanitizer/sanitizer_common/Makefile.in
+++ b/libsanitizer/sanitizer_common/Makefile.in
@@ -338,6 +338,7 @@ install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
link_libasan = @link_libasan@
+link_libhwasan = @link_libhwasan@
link_liblsan = @link_liblsan@
link_libtsan = @link_libtsan@
link_libubsan = @link_libubsan@
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_report.cpp b/libsanitizer/sanitizer_common/sanitizer_allocator_report.cpp
index d74e080..1c65208 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator_report.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator_report.cpp
@@ -134,4 +134,12 @@ void NORETURN ReportOutOfMemory(uptr requested_size, const StackTrace *stack) {
Die();
}
+void NORETURN ReportRssLimitExceeded(const StackTrace *stack) {
+ {
+ ScopedAllocatorErrorReport report("rss-limit-exceeded", stack);
+ Report("ERROR: %s: allocator exceeded the RSS limit\n", SanitizerToolName);
+ }
+ Die();
+}
+
} // namespace __sanitizer
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_report.h b/libsanitizer/sanitizer_common/sanitizer_allocator_report.h
index 0653c36..6e4e6b1 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator_report.h
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator_report.h
@@ -33,6 +33,7 @@ void NORETURN ReportInvalidPosixMemalignAlignment(uptr alignment,
void NORETURN ReportAllocationSizeTooBig(uptr user_size, uptr max_size,
const StackTrace *stack);
void NORETURN ReportOutOfMemory(uptr requested_size, const StackTrace *stack);
+void NORETURN ReportRssLimitExceeded(const StackTrace *stack);
} // namespace __sanitizer
diff --git a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_other.h b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_other.h
index 7580ac2..4a39889 100644
--- a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_other.h
+++ b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_other.h
@@ -50,11 +50,8 @@ inline typename T::Type atomic_load(
__sync_synchronize();
}
} else {
- // 64-bit load on 32-bit platform.
- // Gross, but simple and reliable.
- // Assume that it is not in read-only memory.
- v = __sync_fetch_and_add(
- const_cast<typename T::Type volatile *>(&a->val_dont_use), 0);
+ __atomic_load(const_cast<typename T::Type volatile *>(&a->val_dont_use), &v,
+ __ATOMIC_SEQ_CST);
}
return v;
}
@@ -79,16 +76,7 @@ inline void atomic_store(volatile T *a, typename T::Type v, memory_order mo) {
__sync_synchronize();
}
} else {
- // 64-bit store on 32-bit platform.
- // Gross, but simple and reliable.
- typename T::Type cmp = a->val_dont_use;
- typename T::Type cur;
- for (;;) {
- cur = __sync_val_compare_and_swap(&a->val_dont_use, cmp, v);
- if (cur == cmp || cur == v)
- break;
- cmp = cur;
- }
+ __atomic_store(&a->val_dont_use, &v, __ATOMIC_SEQ_CST);
}
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_common.h b/libsanitizer/sanitizer_common/sanitizer_common.h
index 040db6f..bce24d6 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common.h
+++ b/libsanitizer/sanitizer_common/sanitizer_common.h
@@ -254,7 +254,6 @@ void UpdateProcessName();
void CacheBinaryName();
void DisableCoreDumperIfNecessary();
void DumpProcessMap();
-void PrintModuleMap();
const char *GetEnv(const char *name);
bool SetEnv(const char *name, const char *value);
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
index 5b51078..729eead 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1864,7 +1864,7 @@ UNUSED static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_gecos,
REAL(strlen)(pwd->pw_gecos) + 1);
#endif
-#if SANITIZER_MAC || SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD
+#if SANITIZER_MAC || SANITIZER_FREEBSD || SANITIZER_NETBSD
if (pwd->pw_class)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_class,
REAL(strlen)(pwd->pw_class) + 1);
@@ -3750,7 +3750,7 @@ INTERCEPTOR(char *, strerror, int errnum) {
// static storage.
#if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \
SANITIZER_MAC || SANITIZER_ANDROID || SANITIZER_NETBSD || \
- SANITIZER_FREEBSD || SANITIZER_OPENBSD
+ SANITIZER_FREEBSD
// POSIX version. Spec is not clear on whether buf is NULL-terminated.
// At least on OSX, buf contents are valid even when the call fails.
INTERCEPTOR(int, strerror_r, int errnum, char *buf, SIZE_T buflen) {
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cpp b/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cpp
index 3b278e0..487a634 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cpp
@@ -10,9 +10,10 @@
// libc in no-libcdep sources.
//===----------------------------------------------------------------------===//
-#include "sanitizer_platform.h"
#include "sanitizer_common.h"
+#include "sanitizer_flags.h"
#include "sanitizer_libc.h"
+#include "sanitizer_platform.h"
namespace __sanitizer {
@@ -29,6 +30,7 @@ void SleepForSeconds(int seconds) { internal_sleep(seconds); }
#if !SANITIZER_WINDOWS && !SANITIZER_MAC
void ListOfModules::init() {}
+void InitializePlatformCommonFlags(CommonFlags *cf) {}
#endif
} // namespace __sanitizer
diff --git a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector1.cpp b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector1.cpp
index d4a325b..2c924f5 100644
--- a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector1.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector1.cpp
@@ -32,7 +32,7 @@ struct DDLogicalThread {
bool report_pending;
};
-struct DD : public DDetector {
+struct DD final : public DDetector {
SpinMutex mtx;
DeadlockDetector<DDBV> dd;
DDFlags flags;
diff --git a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cpp b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cpp
index 4026739..e3f8e1b 100644
--- a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cpp
@@ -80,7 +80,7 @@ struct Mutex {
Link link[kMaxLink];
};
-struct DD : public DDetector {
+struct DD final : public DDetector {
explicit DD(const DDFlags *flags);
DDPhysicalThread* CreatePhysicalThread();
diff --git a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector_interface.h b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector_interface.h
index a4722b0..7f461c9 100644
--- a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector_interface.h
+++ b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector_interface.h
@@ -66,6 +66,9 @@ struct DDCallback {
virtual u32 Unwind() { return 0; }
virtual int UniqueTid() { return 0; }
+
+ protected:
+ ~DDCallback() {}
};
struct DDetector {
@@ -85,6 +88,9 @@ struct DDetector {
virtual void MutexDestroy(DDCallback *cb, DDMutex *m) {}
virtual DDReport *GetReport(DDCallback *cb) { return nullptr; }
+
+ protected:
+ ~DDetector() {}
};
} // namespace __sanitizer
diff --git a/libsanitizer/sanitizer_common/sanitizer_errno.h b/libsanitizer/sanitizer_common/sanitizer_errno.h
index 584e66e..94f16b6 100644
--- a/libsanitizer/sanitizer_common/sanitizer_errno.h
+++ b/libsanitizer/sanitizer_common/sanitizer_errno.h
@@ -23,7 +23,7 @@
#if SANITIZER_FREEBSD || SANITIZER_MAC
# define __errno_location __error
-#elif SANITIZER_ANDROID || SANITIZER_NETBSD || SANITIZER_OPENBSD || \
+#elif SANITIZER_ANDROID || SANITIZER_NETBSD || \
SANITIZER_RTEMS
# define __errno_location __errno
#elif SANITIZER_SOLARIS
diff --git a/libsanitizer/sanitizer_common/sanitizer_file.cpp b/libsanitizer/sanitizer_common/sanitizer_file.cpp
index 79930d7..7cce609 100644
--- a/libsanitizer/sanitizer_common/sanitizer_file.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_file.cpp
@@ -58,35 +58,38 @@ void ReportFile::ReopenIfNecessary() {
} else {
internal_snprintf(full_path, kMaxPathLength, "%s.%zu", path_prefix, pid);
}
- fd = OpenFile(full_path, WrOnly);
+ error_t err;
+ fd = OpenFile(full_path, WrOnly, &err);
if (fd == kInvalidFd) {
const char *ErrorMsgPrefix = "ERROR: Can't open file: ";
WriteToFile(kStderrFd, ErrorMsgPrefix, internal_strlen(ErrorMsgPrefix));
WriteToFile(kStderrFd, full_path, internal_strlen(full_path));
+ char errmsg[100];
+ internal_snprintf(errmsg, sizeof(errmsg), " (reason: %d)", err);
+ WriteToFile(kStderrFd, errmsg, internal_strlen(errmsg));
Die();
}
fd_pid = pid;
}
void ReportFile::SetReportPath(const char *path) {
- if (!path)
- return;
- uptr len = internal_strlen(path);
- if (len > sizeof(path_prefix) - 100) {
- Report("ERROR: Path is too long: %c%c%c%c%c%c%c%c...\n",
- path[0], path[1], path[2], path[3],
- path[4], path[5], path[6], path[7]);
- Die();
+ if (path) {
+ uptr len = internal_strlen(path);
+ if (len > sizeof(path_prefix) - 100) {
+ Report("ERROR: Path is too long: %c%c%c%c%c%c%c%c...\n", path[0], path[1],
+ path[2], path[3], path[4], path[5], path[6], path[7]);
+ Die();
+ }
}
SpinMutexLock l(mu);
if (fd != kStdoutFd && fd != kStderrFd && fd != kInvalidFd)
CloseFile(fd);
fd = kInvalidFd;
- if (internal_strcmp(path, "stdout") == 0) {
- fd = kStdoutFd;
- } else if (internal_strcmp(path, "stderr") == 0) {
+ if (!path || internal_strcmp(path, "stderr") == 0) {
fd = kStderrFd;
+ } else if (internal_strcmp(path, "stdout") == 0) {
+ fd = kStdoutFd;
} else {
internal_snprintf(path_prefix, kMaxPathLength, "%s", path);
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_flag_parser.h b/libsanitizer/sanitizer_common/sanitizer_flag_parser.h
index fac5dff..acc71cc 100644
--- a/libsanitizer/sanitizer_common/sanitizer_flag_parser.h
+++ b/libsanitizer/sanitizer_common/sanitizer_flag_parser.h
@@ -42,7 +42,7 @@ class FlagHandlerBase {
};
template <typename T>
-class FlagHandler : public FlagHandlerBase {
+class FlagHandler final : public FlagHandlerBase {
T *t_;
public:
diff --git a/libsanitizer/sanitizer_common/sanitizer_flags.cpp b/libsanitizer/sanitizer_common/sanitizer_flags.cpp
index d329049..21048be 100644
--- a/libsanitizer/sanitizer_common/sanitizer_flags.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_flags.cpp
@@ -13,9 +13,10 @@
#include "sanitizer_flags.h"
#include "sanitizer_common.h"
+#include "sanitizer_flag_parser.h"
#include "sanitizer_libc.h"
+#include "sanitizer_linux.h"
#include "sanitizer_list.h"
-#include "sanitizer_flag_parser.h"
namespace __sanitizer {
@@ -72,7 +73,7 @@ void SubstituteForFlagValue(const char *s, char *out, uptr out_size) {
*out = '\0';
}
-class FlagHandlerInclude : public FlagHandlerBase {
+class FlagHandlerInclude final : public FlagHandlerBase {
FlagParser *parser_;
bool ignore_missing_;
const char *original_path_;
@@ -124,6 +125,8 @@ void InitializeCommonFlags(CommonFlags *cf) {
// need to record coverage to generate coverage report.
cf->coverage |= cf->html_cov_report;
SetVerbosity(cf->verbosity);
+
+ InitializePlatformCommonFlags(cf);
}
} // namespace __sanitizer
diff --git a/libsanitizer/sanitizer_common/sanitizer_flags.h b/libsanitizer/sanitizer_common/sanitizer_flags.h
index 8f5e987..5b59e58 100644
--- a/libsanitizer/sanitizer_common/sanitizer_flags.h
+++ b/libsanitizer/sanitizer_common/sanitizer_flags.h
@@ -62,6 +62,10 @@ void RegisterIncludeFlags(FlagParser *parser, CommonFlags *cf);
// and perform initializations common to all sanitizers (e.g. setting
// verbosity).
void InitializeCommonFlags(CommonFlags *cf = &common_flags_dont_use);
+
+// Platform specific flags initialization.
+void InitializePlatformCommonFlags(CommonFlags *cf);
+
} // namespace __sanitizer
#endif // SANITIZER_FLAGS_H
diff --git a/libsanitizer/sanitizer_common/sanitizer_flags.inc b/libsanitizer/sanitizer_common/sanitizer_flags.inc
index d141247..cfb5822 100644
--- a/libsanitizer/sanitizer_common/sanitizer_flags.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_flags.inc
@@ -52,9 +52,9 @@ COMMON_FLAG(bool, handle_ioctl, false, "Intercept and handle ioctl requests.")
COMMON_FLAG(int, malloc_context_size, 1,
"Max number of stack frames kept for each allocation/deallocation.")
COMMON_FLAG(
- const char *, log_path, "stderr",
+ const char *, log_path, nullptr,
"Write logs to \"log_path.pid\". The special values are \"stdout\" and "
- "\"stderr\". The default is \"stderr\".")
+ "\"stderr\". If unspecified, defaults to \"stderr\".")
COMMON_FLAG(
bool, log_exe_name, false,
"Mention name of executable when reporting error and "
@@ -82,8 +82,9 @@ COMMON_FLAG(bool, print_summary, true,
"If false, disable printing error summaries in addition to error "
"reports.")
COMMON_FLAG(int, print_module_map, 0,
- "OS X only (0 - don't print, 1 - print only once before process "
- "exits, 2 - print after each report).")
+ "Print the process module map where supported (0 - don't print, "
+ "1 - print only once before process exits, 2 - print after each "
+ "report).")
COMMON_FLAG(bool, check_printf, true, "Check printf arguments.")
#define COMMON_FLAG_HANDLE_SIGNAL_HELP(signal) \
"Controls custom tool's " #signal " handler (0 - do not registers the " \
diff --git a/libsanitizer/sanitizer_common/sanitizer_fuchsia.cpp b/libsanitizer/sanitizer_common/sanitizer_fuchsia.cpp
index 6d1ad79..7200ffd 100644
--- a/libsanitizer/sanitizer_common/sanitizer_fuchsia.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_fuchsia.cpp
@@ -14,10 +14,6 @@
#include "sanitizer_fuchsia.h"
#if SANITIZER_FUCHSIA
-#include "sanitizer_common.h"
-#include "sanitizer_libc.h"
-#include "sanitizer_mutex.h"
-
#include <limits.h>
#include <pthread.h>
#include <stdlib.h>
@@ -25,6 +21,11 @@
#include <zircon/errors.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
+#include <zircon/utc.h>
+
+#include "sanitizer_common.h"
+#include "sanitizer_libc.h"
+#include "sanitizer_mutex.h"
namespace __sanitizer {
@@ -47,8 +48,10 @@ unsigned int internal_sleep(unsigned int seconds) {
}
u64 NanoTime() {
+ zx_handle_t utc_clock = _zx_utc_reference_get();
+ CHECK_NE(utc_clock, ZX_HANDLE_INVALID);
zx_time_t time;
- zx_status_t status = _zx_clock_get(ZX_CLOCK_UTC, &time);
+ zx_status_t status = _zx_clock_read(utc_clock, &time);
CHECK_EQ(status, ZX_OK);
return time;
}
@@ -105,8 +108,6 @@ void SetAlternateSignalStack() {}
void UnsetAlternateSignalStack() {}
void InitTlsSize() {}
-void PrintModuleMap() {}
-
bool SignalContext::IsStackOverflow() const { return false; }
void SignalContext::DumpAllRegisters(void *context) { UNIMPLEMENTED(); }
const char *SignalContext::Describe() const { UNIMPLEMENTED(); }
@@ -504,6 +505,8 @@ u32 GetNumberOfCPUs() {
uptr GetRSS() { UNIMPLEMENTED(); }
+void InitializePlatformCommonFlags(CommonFlags *cf) {}
+
} // namespace __sanitizer
using namespace __sanitizer;
diff --git a/libsanitizer/sanitizer_common/sanitizer_internal_defs.h b/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
index a6c5514..d8f0540 100644
--- a/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
+++ b/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
@@ -39,7 +39,7 @@
// TLS is handled differently on different platforms
#if SANITIZER_LINUX || SANITIZER_NETBSD || \
- SANITIZER_FREEBSD || SANITIZER_OPENBSD
+ SANITIZER_FREEBSD
# define SANITIZER_TLS_INITIAL_EXEC_ATTRIBUTE \
__attribute__((tls_model("initial-exec"))) thread_local
#else
@@ -104,8 +104,7 @@
//
// FIXME: do we have anything like this on Mac?
#ifndef SANITIZER_CAN_USE_PREINIT_ARRAY
-#if ((SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_OPENBSD || \
- SANITIZER_FUCHSIA || SANITIZER_NETBSD) && !defined(PIC)
+#if (SANITIZER_LINUX || SANITIZER_FUCHSIA || SANITIZER_NETBSD) && !defined(PIC)
#define SANITIZER_CAN_USE_PREINIT_ARRAY 1
// Before Solaris 11.4, .preinit_array is fully supported only with GNU ld.
// FIXME: Check for those conditions.
@@ -170,7 +169,7 @@ typedef int pid_t;
#endif
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || \
- SANITIZER_OPENBSD || SANITIZER_MAC || \
+ SANITIZER_MAC || \
(SANITIZER_SOLARIS && (defined(_LP64) || _FILE_OFFSET_BITS == 64)) || \
(SANITIZER_LINUX && defined(__x86_64__))
typedef u64 OFF_T;
@@ -182,7 +181,7 @@ typedef u64 OFF64_T;
#if (SANITIZER_WORDSIZE == 64) || SANITIZER_MAC
typedef uptr operator_new_size_type;
#else
-# if SANITIZER_OPENBSD || defined(__s390__) && !defined(__s390x__)
+# if defined(__s390__) && !defined(__s390x__)
// Special case: 31-bit s390 has unsigned long as size_t.
typedef unsigned long operator_new_size_type;
# else
@@ -448,5 +447,8 @@ using namespace __sanitizer;
namespace __hwasan {
using namespace __sanitizer;
}
+namespace __memprof {
+using namespace __sanitizer;
+}
#endif // SANITIZER_DEFS_H
diff --git a/libsanitizer/sanitizer_common/sanitizer_libignore.cpp b/libsanitizer/sanitizer_common/sanitizer_libignore.cpp
index eb9bb76..9ea19bc 100644
--- a/libsanitizer/sanitizer_common/sanitizer_libignore.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_libignore.cpp
@@ -9,7 +9,7 @@
#include "sanitizer_platform.h"
#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \
- SANITIZER_NETBSD || SANITIZER_OPENBSD
+ SANITIZER_NETBSD
#include "sanitizer_libignore.h"
#include "sanitizer_flags.h"
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.cpp b/libsanitizer/sanitizer_common/sanitizer_linux.cpp
index c84946c..379f6d9 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_linux.cpp
@@ -14,7 +14,7 @@
#include "sanitizer_platform.h"
#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
- SANITIZER_OPENBSD || SANITIZER_SOLARIS
+ SANITIZER_SOLARIS
#include "sanitizer_common.h"
#include "sanitizer_flags.h"
@@ -38,6 +38,14 @@
#include <asm/unistd.h>
#include <sys/types.h>
#define stat kernel_stat
+#if SANITIZER_GO
+#undef st_atime
+#undef st_mtime
+#undef st_ctime
+#define st_atime st_atim
+#define st_mtime st_mtim
+#define st_ctime st_ctim
+#endif
#include <asm/stat.h>
#undef stat
#endif
@@ -59,13 +67,7 @@
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
-#if !SANITIZER_OPENBSD
#include <ucontext.h>
-#endif
-#if SANITIZER_OPENBSD
-#include <sys/futex.h>
-#include <sys/sysctl.h>
-#endif
#include <unistd.h>
#if SANITIZER_LINUX
@@ -129,7 +131,7 @@ const int FUTEX_WAKE_PRIVATE = FUTEX_WAKE | FUTEX_PRIVATE_FLAG;
#endif
// Note : FreeBSD had implemented both
-// Linux and OpenBSD apis, available from
+// Linux apis, available from
// future 12.x version most likely
#if SANITIZER_LINUX && defined(__NR_getrandom)
# if !defined(GRND_NONBLOCK)
@@ -140,15 +142,11 @@ const int FUTEX_WAKE_PRIVATE = FUTEX_WAKE | FUTEX_PRIVATE_FLAG;
# define SANITIZER_USE_GETRANDOM 0
#endif // SANITIZER_LINUX && defined(__NR_getrandom)
-#if SANITIZER_OPENBSD
-# define SANITIZER_USE_GETENTROPY 1
+#if SANITIZER_FREEBSD && __FreeBSD_version >= 1200000
+# define SANITIZER_USE_GETENTROPY 1
#else
-# if SANITIZER_FREEBSD && __FreeBSD_version >= 1200000
-# define SANITIZER_USE_GETENTROPY 1
-# else
-# define SANITIZER_USE_GETENTROPY 0
-# endif
-#endif // SANITIZER_USE_GETENTROPY
+# define SANITIZER_USE_GETENTROPY 0
+#endif
namespace __sanitizer {
@@ -166,7 +164,7 @@ namespace __sanitizer {
// --------------- sanitizer_libc.h
#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD
-#if !SANITIZER_S390 && !SANITIZER_OPENBSD
+#if !SANITIZER_S390
uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
u64 offset) {
#if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS
@@ -179,9 +177,8 @@ uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
offset / 4096);
#endif
}
-#endif // !SANITIZER_S390 && !SANITIZER_OPENBSD
+#endif // !SANITIZER_S390
-#if !SANITIZER_OPENBSD
uptr internal_munmap(void *addr, uptr length) {
return internal_syscall(SYSCALL(munmap), (uptr)addr, length);
}
@@ -193,7 +190,6 @@ int internal_mprotect(void *addr, uptr length, int prot) {
int internal_madvise(uptr addr, uptr length, int advice) {
return internal_syscall(SYSCALL(madvise), addr, length, advice);
}
-#endif
uptr internal_close(fd_t fd) {
return internal_syscall(SYSCALL(close), fd);
@@ -260,9 +256,11 @@ static void stat64_to_stat(struct stat64 *in, struct stat *out) {
// Undefine compatibility macros from <sys/stat.h>
// so that they would not clash with the kernel_stat
// st_[a|m|c]time fields
+#if !SANITIZER_GO
#undef st_atime
#undef st_mtime
#undef st_ctime
+#endif
#if defined(SANITIZER_ANDROID)
// Bionic sys/stat.h defines additional macros
// for compatibility with the old NDKs and
@@ -305,7 +303,7 @@ static void kernel_stat_to_stat(struct kernel_stat *in, struct stat *out) {
#endif
uptr internal_stat(const char *path, void *buf) {
-#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
+#if SANITIZER_FREEBSD
return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf, 0);
#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf,
@@ -329,7 +327,7 @@ uptr internal_stat(const char *path, void *buf) {
}
uptr internal_lstat(const char *path, void *buf) {
-#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
+#if SANITIZER_FREEBSD
return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf,
AT_SYMLINK_NOFOLLOW);
#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
@@ -354,9 +352,8 @@ uptr internal_lstat(const char *path, void *buf) {
}
uptr internal_fstat(fd_t fd, void *buf) {
-#if SANITIZER_FREEBSD || SANITIZER_OPENBSD || \
- SANITIZER_LINUX_USES_64BIT_SYSCALLS
-#if SANITIZER_MIPS64 && !SANITIZER_OPENBSD
+#if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS
+#if SANITIZER_MIPS64
// For mips64, fstat syscall fills buffer in the format of kernel_stat
struct kernel_stat kbuf;
int res = internal_syscall(SYSCALL(fstat), fd, &kbuf);
@@ -396,16 +393,13 @@ uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
return internal_syscall(SYSCALL(readlinkat), AT_FDCWD, (uptr)path, (uptr)buf,
bufsize);
-#elif SANITIZER_OPENBSD
- return internal_syscall(SYSCALL(readlinkat), AT_FDCWD, (uptr)path, (uptr)buf,
- bufsize);
#else
return internal_syscall(SYSCALL(readlink), (uptr)path, (uptr)buf, bufsize);
#endif
}
uptr internal_unlink(const char *path) {
-#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS || SANITIZER_OPENBSD
+#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
return internal_syscall(SYSCALL(unlinkat), AT_FDCWD, (uptr)path, 0);
#else
return internal_syscall(SYSCALL(unlink), (uptr)path);
@@ -416,7 +410,7 @@ uptr internal_rename(const char *oldpath, const char *newpath) {
#if defined(__riscv)
return internal_syscall(SYSCALL(renameat2), AT_FDCWD, (uptr)oldpath, AT_FDCWD,
(uptr)newpath, 0);
-#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS || SANITIZER_OPENBSD
+#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
return internal_syscall(SYSCALL(renameat), AT_FDCWD, (uptr)oldpath, AT_FDCWD,
(uptr)newpath);
#else
@@ -446,7 +440,7 @@ uptr internal_execve(const char *filename, char *const argv[],
#if !SANITIZER_NETBSD
void internal__exit(int exitcode) {
-#if SANITIZER_FREEBSD || SANITIZER_OPENBSD || SANITIZER_SOLARIS
+#if SANITIZER_FREEBSD || SANITIZER_SOLARIS
internal_syscall(SYSCALL(exit), exitcode);
#else
internal_syscall(SYSCALL(exit_group), exitcode);
@@ -476,8 +470,6 @@ tid_t GetTid() {
long Tid;
thr_self(&Tid);
return Tid;
-#elif SANITIZER_OPENBSD
- return internal_syscall(SYSCALL(getthrid));
#elif SANITIZER_SOLARIS
return thr_self();
#else
@@ -490,9 +482,6 @@ int TgKill(pid_t pid, tid_t tid, int sig) {
return internal_syscall(SYSCALL(tgkill), pid, tid, sig);
#elif SANITIZER_FREEBSD
return internal_syscall(SYSCALL(thr_kill2), pid, tid, sig);
-#elif SANITIZER_OPENBSD
- (void)pid;
- return internal_syscall(SYSCALL(thrkill), tid, sig, nullptr);
#elif SANITIZER_SOLARIS
(void)pid;
return thr_kill(tid, sig);
@@ -502,7 +491,7 @@ int TgKill(pid_t pid, tid_t tid, int sig) {
#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD
u64 NanoTime() {
-#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
+#if SANITIZER_FREEBSD
timeval tv;
#else
kernel_timeval tv;
@@ -521,8 +510,7 @@ uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) {
// 'environ' array (on some others) and does not use libc. This function
// should be called first inside __asan_init.
const char *GetEnv(const char *name) {
-#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD || \
- SANITIZER_SOLARIS
+#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_SOLARIS
if (::environ != 0) {
uptr NameLen = internal_strlen(name);
for (char **Env = ::environ; *Env != 0; Env++) {
@@ -560,15 +548,13 @@ const char *GetEnv(const char *name) {
#endif
}
-#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD && !SANITIZER_OPENBSD && \
- !SANITIZER_GO
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD && !SANITIZER_GO
extern "C" {
SANITIZER_WEAK_ATTRIBUTE extern void *__libc_stack_end;
}
#endif
-#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD && \
- !SANITIZER_OPENBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
static void ReadNullSepFileToArray(const char *path, char ***arr,
int arr_size) {
char *buff;
@@ -593,7 +579,6 @@ static void ReadNullSepFileToArray(const char *path, char ***arr,
}
#endif
-#if !SANITIZER_OPENBSD
static void GetArgsAndEnv(char ***argv, char ***envp) {
#if SANITIZER_FREEBSD
// On FreeBSD, retrieving the argument and environment arrays is done via the
@@ -645,8 +630,6 @@ char **GetEnviron() {
return envp;
}
-#endif // !SANITIZER_OPENBSD
-
#if !SANITIZER_SOLARIS
enum MutexState {
MtxUnlocked = 0,
@@ -702,16 +685,6 @@ void BlockingMutex::CheckLocked() {
// 32-bit syscall here.
#if SANITIZER_NETBSD
// Not used
-#elif SANITIZER_OPENBSD
-// struct dirent is different for Linux and us. At this moment, we use only
-// d_fileno (Linux call this d_ino), d_reclen, and d_name.
-struct linux_dirent {
- u64 d_ino; // d_fileno
- u16 d_reclen;
- u16 d_namlen; // not used
- u8 d_type; // not used
- char d_name[NAME_MAX + 1];
-};
#else
struct linux_dirent {
#if SANITIZER_X32 || defined(__aarch64__) || SANITIZER_RISCV64
@@ -789,19 +762,13 @@ int internal_fork() {
#endif
}
-#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
+#if SANITIZER_FREEBSD
int internal_sysctl(const int *name, unsigned int namelen, void *oldp,
uptr *oldlenp, const void *newp, uptr newlen) {
-#if SANITIZER_OPENBSD
- return sysctl(name, namelen, oldp, (size_t *)oldlenp, (void *)newp,
- (size_t)newlen);
-#else
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) {
// Note: this function can be called during startup, so we need to avoid
@@ -829,7 +796,6 @@ int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp,
#endif
}
#endif
-#endif
#if SANITIZER_LINUX
#define SA_RESTORER 0x04000000
@@ -882,7 +848,7 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact) {
uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
__sanitizer_sigset_t *oldset) {
-#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
+#if SANITIZER_FREEBSD
return internal_syscall(SYSCALL(sigprocmask), how, set, oldset);
#else
__sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set;
@@ -1059,7 +1025,7 @@ static uptr GetKernelAreaSize() {
#endif // SANITIZER_WORDSIZE == 32
uptr GetMaxVirtualAddress() {
-#if (SANITIZER_NETBSD || SANITIZER_OPENBSD) && defined(__x86_64__)
+#if SANITIZER_NETBSD && defined(__x86_64__)
return 0x7f7ffffff000ULL; // (0x00007f8000000000 - PAGE_SIZE)
#elif SANITIZER_WORDSIZE == 64
# if defined(__powerpc64__) || defined(__aarch64__)
@@ -1122,7 +1088,6 @@ uptr GetPageSize() {
}
#endif // !SANITIZER_ANDROID
-#if !SANITIZER_OPENBSD
uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
#if SANITIZER_SOLARIS
const char *default_module_name = getexecname();
@@ -1159,7 +1124,6 @@ uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
return module_name_len;
#endif
}
-#endif // !SANITIZER_OPENBSD
uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) {
#if SANITIZER_LINUX
@@ -1192,10 +1156,10 @@ 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)) {
CHECK_NE(map, nullptr);
-#if !SANITIZER_FREEBSD && !SANITIZER_OPENBSD
+#if !SANITIZER_FREEBSD
typedef ElfW(Phdr) Elf_Phdr;
typedef ElfW(Ehdr) Elf_Ehdr;
-#endif // !SANITIZER_FREEBSD && !SANITIZER_OPENBSD
+#endif // !SANITIZER_FREEBSD
char *base = (char *)map->l_addr;
Elf_Ehdr *ehdr = (Elf_Ehdr *)base;
char *phdrs = base + ehdr->e_phoff;
@@ -1845,11 +1809,7 @@ static bool Aarch64GetESR(ucontext_t *ucontext, u64 *esr) {
}
#endif
-#if SANITIZER_OPENBSD
-using Context = sigcontext;
-#else
using Context = ucontext_t;
-#endif
SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
Context *ucontext = (Context *)context;
@@ -1859,8 +1819,6 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
uptr err = ucontext->uc_mcontext.mc_err;
#elif SANITIZER_NETBSD
uptr err = ucontext->uc_mcontext.__gregs[_REG_ERR];
-#elif SANITIZER_OPENBSD
- uptr err = ucontext->sc_err;
#elif SANITIZER_SOLARIS && defined(__i386__)
const int Err = 13;
uptr err = ucontext->uc_mcontext.gregs[Err];
@@ -2086,11 +2044,6 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
*pc = ucontext->uc_mcontext.mc_rip;
*bp = ucontext->uc_mcontext.mc_rbp;
*sp = ucontext->uc_mcontext.mc_rsp;
-#elif SANITIZER_OPENBSD
- sigcontext *ucontext = (sigcontext *)context;
- *pc = ucontext->sc_rip;
- *bp = ucontext->sc_rbp;
- *sp = ucontext->sc_rsp;
# else
ucontext_t *ucontext = (ucontext_t*)context;
*pc = ucontext->uc_mcontext.gregs[REG_RIP];
@@ -2103,11 +2056,6 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
*pc = ucontext->uc_mcontext.mc_eip;
*bp = ucontext->uc_mcontext.mc_ebp;
*sp = ucontext->uc_mcontext.mc_esp;
-#elif SANITIZER_OPENBSD
- sigcontext *ucontext = (sigcontext *)context;
- *pc = ucontext->sc_eip;
- *bp = ucontext->sc_ebp;
- *sp = ucontext->sc_esp;
# else
ucontext_t *ucontext = (ucontext_t*)context;
# if SANITIZER_SOLARIS
@@ -2280,8 +2228,6 @@ void CheckMPROTECT() {
#endif
}
-void PrintModuleMap() { }
-
void CheckNoDeepBind(const char *filename, int flag) {
#ifdef RTLD_DEEPBIND
if (flag & RTLD_DEEPBIND) {
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.h b/libsanitizer/sanitizer_common/sanitizer_linux.h
index a8625ca..24902d1 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux.h
+++ b/libsanitizer/sanitizer_common/sanitizer_linux.h
@@ -14,12 +14,11 @@
#include "sanitizer_platform.h"
#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
- SANITIZER_OPENBSD || SANITIZER_SOLARIS
+ 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"
#include "sanitizer_platform_limits_solaris.h"
#include "sanitizer_posix.h"
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
index af07743..bc10e89 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
@@ -14,7 +14,7 @@
#include "sanitizer_platform.h"
#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
- SANITIZER_OPENBSD || SANITIZER_SOLARIS
+ SANITIZER_SOLARIS
#include "sanitizer_allocator_internal.h"
#include "sanitizer_atomic.h"
@@ -50,11 +50,6 @@
#define pthread_getattr_np pthread_attr_get_np
#endif
-#if SANITIZER_OPENBSD
-#include <pthread_np.h>
-#include <sys/sysctl.h>
-#endif
-
#if SANITIZER_NETBSD
#include <sys/sysctl.h>
#include <sys/tls.h>
@@ -142,11 +137,6 @@ void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
CHECK_EQ(thr_stksegment(&ss), 0);
stacksize = ss.ss_size;
stackaddr = (char *)ss.ss_sp - stacksize;
-#elif SANITIZER_OPENBSD
- stack_t sattr;
- CHECK_EQ(pthread_stackseg_np(pthread_self(), &sattr), 0);
- stackaddr = sattr.ss_sp;
- stacksize = sattr.ss_size;
#else // !SANITIZER_SOLARIS
pthread_attr_t attr;
pthread_attr_init(&attr);
@@ -194,7 +184,7 @@ __attribute__((unused)) static bool GetLibcVersion(int *major, int *minor,
}
#if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO && \
- !SANITIZER_NETBSD && !SANITIZER_OPENBSD && !SANITIZER_SOLARIS
+ !SANITIZER_NETBSD && !SANITIZER_SOLARIS
static uptr g_tls_size;
#ifdef __i386__
@@ -385,12 +375,9 @@ uptr ThreadSelf() {
descr_addr = reinterpret_cast<uptr>(__builtin_thread_pointer()) -
ThreadDescriptorSize();
#elif SANITIZER_RISCV64
- uptr tcb_end;
- asm volatile("mv %0, tp;\n" : "=r"(tcb_end));
// https://github.com/riscv/riscv-elf-psabi-doc/issues/53
- const uptr kTlsTcbOffset = 0x800;
- descr_addr =
- reinterpret_cast<uptr>(tcb_end - kTlsTcbOffset - TlsPreTcbSize());
+ uptr thread_pointer = reinterpret_cast<uptr>(__builtin_thread_pointer());
+ descr_addr = thread_pointer - TlsPreTcbSize();
#elif defined(__s390__)
descr_addr = reinterpret_cast<uptr>(__builtin_thread_pointer());
#elif defined(__powerpc64__)
@@ -458,9 +445,27 @@ int GetSizeFromHdr(struct dl_phdr_info *info, size_t size, void *data) {
}
#endif // SANITIZER_NETBSD
+#if SANITIZER_ANDROID
+// Bionic provides this API since S.
+extern "C" SANITIZER_WEAK_ATTRIBUTE void __libc_get_static_tls_bounds(void **,
+ void **);
+#endif
+
#if !SANITIZER_GO
static void GetTls(uptr *addr, uptr *size) {
-#if SANITIZER_LINUX && !SANITIZER_ANDROID
+#if SANITIZER_ANDROID
+ if (&__libc_get_static_tls_bounds) {
+ void *start_addr;
+ void *end_addr;
+ __libc_get_static_tls_bounds(&start_addr, &end_addr);
+ *addr = reinterpret_cast<uptr>(start_addr);
+ *size =
+ reinterpret_cast<uptr>(end_addr) - reinterpret_cast<uptr>(start_addr);
+ } else {
+ *addr = 0;
+ *size = 0;
+ }
+#elif SANITIZER_LINUX
#if defined(__x86_64__) || defined(__i386__) || defined(__s390__)
*addr = ThreadSelf();
*size = GetTlsSize();
@@ -501,12 +506,6 @@ static void GetTls(uptr *addr, uptr *size) {
*addr = (uptr)tcb->tcb_dtv[1];
}
}
-#elif SANITIZER_OPENBSD
- *addr = 0;
- *size = 0;
-#elif SANITIZER_ANDROID
- *addr = 0;
- *size = 0;
#elif SANITIZER_SOLARIS
// FIXME
*addr = 0;
@@ -520,7 +519,7 @@ static void GetTls(uptr *addr, uptr *size) {
#if !SANITIZER_GO
uptr GetTlsSize() {
#if SANITIZER_FREEBSD || SANITIZER_ANDROID || SANITIZER_NETBSD || \
- SANITIZER_OPENBSD || SANITIZER_SOLARIS
+ SANITIZER_SOLARIS
uptr addr, size;
GetTls(&addr, &size);
return size;
@@ -557,13 +556,13 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
#endif
}
-#if !SANITIZER_FREEBSD && !SANITIZER_OPENBSD
+#if !SANITIZER_FREEBSD
typedef ElfW(Phdr) Elf_Phdr;
#elif SANITIZER_WORDSIZE == 32 && __FreeBSD_version <= 902001 // v9.2
#define Elf_Phdr XElf32_Phdr
#define dl_phdr_info xdl_phdr_info
#define dl_iterate_phdr(c, b) xdl_iterate_phdr((c), (b))
-#endif // !SANITIZER_FREEBSD && !SANITIZER_OPENBSD
+#endif // !SANITIZER_FREEBSD
struct DlIteratePhdrData {
InternalMmapVectorNoCtor<LoadedModule> *modules;
@@ -683,7 +682,7 @@ uptr GetRSS() {
// sysconf(_SC_NPROCESSORS_{CONF,ONLN}) cannot be used on most platforms as
// they allocate memory.
u32 GetNumberOfCPUs() {
-#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD
+#if SANITIZER_FREEBSD || SANITIZER_NETBSD
u32 ncpu;
int req[2];
uptr len = sizeof(ncpu);
@@ -844,7 +843,6 @@ u64 MonotonicNanoTime() {
}
#endif // SANITIZER_LINUX && !SANITIZER_GO
-#if !SANITIZER_OPENBSD
void ReExec() {
const char *pathname = "/proc/self/exe";
@@ -876,7 +874,6 @@ void ReExec() {
Printf("execve failed, errno %d\n", rverrno);
Die();
}
-#endif // !SANITIZER_OPENBSD
void UnmapFromTo(uptr from, uptr to) {
if (to == from)
@@ -913,6 +910,13 @@ uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale,
return shadow_start;
}
+void InitializePlatformCommonFlags(CommonFlags *cf) {
+#if SANITIZER_ANDROID
+ if (&__libc_get_static_tls_bounds == nullptr)
+ cf->detect_leaks = false;
+#endif
+}
+
} // namespace __sanitizer
#endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.cpp b/libsanitizer/sanitizer_common/sanitizer_mac.cpp
index 36a8f79..011ec6f 100644
--- a/libsanitizer/sanitizer_common/sanitizer_mac.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_mac.cpp
@@ -1300,7 +1300,7 @@ void FormatUUID(char *out, uptr size, const u8 *uuid) {
uuid[12], uuid[13], uuid[14], uuid[15]);
}
-void PrintModuleMap() {
+void DumpProcessMap() {
Printf("Process module map:\n");
MemoryMappingLayout memory_mapping(false);
InternalMmapVector<LoadedModule> modules;
@@ -1333,6 +1333,8 @@ u32 GetNumberOfCPUs() {
return (u32)sysconf(_SC_NPROCESSORS_ONLN);
}
+void InitializePlatformCommonFlags(CommonFlags *cf) {}
+
} // namespace __sanitizer
#endif // SANITIZER_MAC
diff --git a/libsanitizer/sanitizer_common/sanitizer_openbsd.cpp b/libsanitizer/sanitizer_common/sanitizer_openbsd.cpp
index 1959017..e69de29 100644
--- a/libsanitizer/sanitizer_common/sanitizer_openbsd.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_openbsd.cpp
@@ -1,119 +0,0 @@
-//===-- sanitizer_openbsd.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 shared between various sanitizers' runtime libraries and
-// implements Solaris-specific functions.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_platform.h"
-#if SANITIZER_OPENBSD
-
-#include <stdio.h>
-
-#include "sanitizer_common.h"
-#include "sanitizer_flags.h"
-#include "sanitizer_internal_defs.h"
-#include "sanitizer_libc.h"
-#include "sanitizer_placement_new.h"
-#include "sanitizer_platform_limits_posix.h"
-#include "sanitizer_procmaps.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <pthread.h>
-#include <sched.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <sys/shm.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-extern char **environ;
-
-namespace __sanitizer {
-
-uptr internal_mmap(void *addr, size_t length, int prot, int flags, int fd,
- u64 offset) {
- return (uptr)mmap(addr, length, prot, flags, fd, offset);
-}
-
-uptr internal_munmap(void *addr, uptr length) { return munmap(addr, length); }
-
-int internal_mprotect(void *addr, uptr length, int prot) {
- return mprotect(addr, length, prot);
-}
-
-int internal_madvise(uptr addr, uptr length, int advice) {
- return madvise((void *)addr, length, advice);
-}
-
-int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp,
- const void *newp, uptr newlen) {
- Printf("internal_sysctlbyname not implemented for OpenBSD");
- Die();
- return 0;
-}
-
-uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
- // On OpenBSD we cannot get the full path
- struct kinfo_proc kp;
- uptr kl;
- const int Mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()};
- if (internal_sysctl(Mib, ARRAY_SIZE(Mib), &kp, &kl, NULL, 0) != -1)
- return internal_snprintf(buf,
- (KI_MAXCOMLEN < buf_len ? KI_MAXCOMLEN : buf_len),
- "%s", kp.p_comm);
- return (uptr)0;
-}
-
-static void GetArgsAndEnv(char ***argv, char ***envp) {
- uptr nargv;
- uptr nenv;
- int argvmib[4] = {CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV};
- int envmib[4] = {CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ENV};
- if (internal_sysctl(argvmib, 4, NULL, &nargv, NULL, 0) == -1) {
- Printf("sysctl KERN_PROC_NARGV failed\n");
- Die();
- }
- if (internal_sysctl(envmib, 4, NULL, &nenv, NULL, 0) == -1) {
- Printf("sysctl KERN_PROC_NENV failed\n");
- Die();
- }
- if (internal_sysctl(argvmib, 4, &argv, &nargv, NULL, 0) == -1) {
- Printf("sysctl KERN_PROC_ARGV failed\n");
- Die();
- }
- if (internal_sysctl(envmib, 4, &envp, &nenv, NULL, 0) == -1) {
- Printf("sysctl KERN_PROC_ENV failed\n");
- Die();
- }
-}
-
-char **GetArgv() {
- char **argv, **envp;
- GetArgsAndEnv(&argv, &envp);
- return argv;
-}
-
-char **GetEnviron() {
- char **argv, **envp;
- GetArgsAndEnv(&argv, &envp);
- return envp;
-}
-
-void ReExec() {
- UNIMPLEMENTED();
-}
-
-} // namespace __sanitizer
-
-#endif // SANITIZER_OPENBSD
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform.h b/libsanitizer/sanitizer_common/sanitizer_platform.h
index 5547c68..b2372a0 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform.h
+++ b/libsanitizer/sanitizer_common/sanitizer_platform.h
@@ -13,7 +13,7 @@
#define SANITIZER_PLATFORM_H
#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \
- !defined(__OpenBSD__) && !defined(__APPLE__) && !defined(_WIN32) && \
+ !defined(__APPLE__) && !defined(_WIN32) && \
!defined(__Fuchsia__) && !defined(__rtems__) && \
!(defined(__sun__) && defined(__svr4__))
# error "This operating system is not supported"
@@ -37,12 +37,6 @@
# define SANITIZER_NETBSD 0
#endif
-#if defined(__OpenBSD__)
-# define SANITIZER_OPENBSD 1
-#else
-# define SANITIZER_OPENBSD 0
-#endif
-
#if defined(__sun__) && defined(__svr4__)
# define SANITIZER_SOLARIS 1
#else
@@ -112,7 +106,7 @@
#define SANITIZER_POSIX \
(SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \
- SANITIZER_NETBSD || SANITIZER_OPENBSD || SANITIZER_SOLARIS)
+ SANITIZER_NETBSD || SANITIZER_SOLARIS)
#if __LP64__ || defined(_WIN64)
# define SANITIZER_WORDSIZE 64
@@ -244,7 +238,11 @@
// FIXME: this value should be different on different platforms. Larger values
// will still work but will consume more memory for TwoLevelByteMap.
#if defined(__mips__)
+#if SANITIZER_GO && defined(__mips64)
+#define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)
+#else
# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 40)
+#endif
#elif SANITIZER_RISCV64
#define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 38)
#elif defined(__aarch64__)
@@ -339,7 +337,7 @@
#endif
#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD || \
- SANITIZER_OPENBSD || SANITIZER_SOLARIS
+ SANITIZER_SOLARIS
# define SANITIZER_MADVISE_DONTNEED MADV_FREE
#else
# define SANITIZER_MADVISE_DONTNEED MADV_DONTNEED
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h
index 37f178a..18bab34 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h
@@ -18,131 +18,124 @@
#include "sanitizer_platform.h"
#if SANITIZER_POSIX
-# define SI_POSIX 1
+#define SI_POSIX 1
#else
-# define SI_POSIX 0
+#define SI_POSIX 0
#endif
#if !SANITIZER_WINDOWS
-# define SI_WINDOWS 0
+#define SI_WINDOWS 0
#else
-# define SI_WINDOWS 1
+#define SI_WINDOWS 1
#endif
#if SI_WINDOWS && SI_POSIX
-# error "Windows is not POSIX!"
+#error "Windows is not POSIX!"
#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_posix.h"
-# include "sanitizer_platform_limits_solaris.h"
+#include "sanitizer_platform_limits_freebsd.h"
+#include "sanitizer_platform_limits_netbsd.h"
+#include "sanitizer_platform_limits_posix.h"
+#include "sanitizer_platform_limits_solaris.h"
#endif
#if SANITIZER_LINUX && !SANITIZER_ANDROID
-# define SI_LINUX_NOT_ANDROID 1
+#define SI_LINUX_NOT_ANDROID 1
#else
-# define SI_LINUX_NOT_ANDROID 0
+#define SI_LINUX_NOT_ANDROID 0
#endif
#if SANITIZER_ANDROID
-# define SI_ANDROID 1
+#define SI_ANDROID 1
#else
-# define SI_ANDROID 0
+#define SI_ANDROID 0
#endif
#if SANITIZER_FREEBSD
-# define SI_FREEBSD 1
+#define SI_FREEBSD 1
#else
-# define SI_FREEBSD 0
+#define SI_FREEBSD 0
#endif
#if SANITIZER_NETBSD
-# define SI_NETBSD 1
+#define SI_NETBSD 1
#else
-# define SI_NETBSD 0
-#endif
-
-#if SANITIZER_OPENBSD
-#define SI_OPENBSD 1
-#else
-#define SI_OPENBSD 0
+#define SI_NETBSD 0
#endif
#if SANITIZER_LINUX
-# define SI_LINUX 1
+#define SI_LINUX 1
#else
-# define SI_LINUX 0
+#define SI_LINUX 0
#endif
#if SANITIZER_MAC
-# define SI_MAC 1
-# define SI_NOT_MAC 0
+#define SI_MAC 1
+#define SI_NOT_MAC 0
#else
-# define SI_MAC 0
-# define SI_NOT_MAC 1
+#define SI_MAC 0
+#define SI_NOT_MAC 1
#endif
#if SANITIZER_IOS
-# define SI_IOS 1
+#define SI_IOS 1
#else
-# define SI_IOS 0
+#define SI_IOS 0
#endif
#if SANITIZER_IOSSIM
-# define SI_IOSSIM 1
+#define SI_IOSSIM 1
#else
-# define SI_IOSSIM 0
+#define SI_IOSSIM 0
#endif
#if SANITIZER_WATCHOS
-# define SI_WATCHOS 1
+#define SI_WATCHOS 1
#else
-# define SI_WATCHOS 0
+#define SI_WATCHOS 0
#endif
#if SANITIZER_TVOS
-# define SI_TVOS 1
+#define SI_TVOS 1
#else
-# define SI_TVOS 0
+#define SI_TVOS 0
#endif
#if SANITIZER_FUCHSIA
-# define SI_NOT_FUCHSIA 0
+#define SI_NOT_FUCHSIA 0
#else
-# define SI_NOT_FUCHSIA 1
+#define SI_NOT_FUCHSIA 1
#endif
#if SANITIZER_RTEMS
-# define SI_NOT_RTEMS 0
+#define SI_NOT_RTEMS 0
#else
-# define SI_NOT_RTEMS 1
+#define SI_NOT_RTEMS 1
#endif
#if SANITIZER_SOLARIS
-# define SI_SOLARIS 1
+#define SI_SOLARIS 1
#else
-# define SI_SOLARIS 0
+#define SI_SOLARIS 0
#endif
#if SANITIZER_SOLARIS32
-# define SI_SOLARIS32 1
+#define SI_SOLARIS32 1
#else
-# define SI_SOLARIS32 0
+#define SI_SOLARIS32 0
#endif
#if SANITIZER_POSIX && !SANITIZER_MAC
-# define SI_POSIX_NOT_MAC 1
+#define SI_POSIX_NOT_MAC 1
#else
-# define SI_POSIX_NOT_MAC 0
+#define SI_POSIX_NOT_MAC 0
#endif
#if SANITIZER_LINUX && !SANITIZER_FREEBSD
-# define SI_LINUX_NOT_FREEBSD 1
-# else
-# define SI_LINUX_NOT_FREEBSD 0
+#define SI_LINUX_NOT_FREEBSD 1
+#else
+#define SI_LINUX_NOT_FREEBSD 0
#endif
#define SANITIZER_INTERCEPT_STRLEN SI_NOT_FUCHSIA
@@ -164,21 +157,20 @@
#define SANITIZER_INTERCEPT_MEMCMP SI_NOT_FUCHSIA
#define SANITIZER_INTERCEPT_BCMP \
SANITIZER_INTERCEPT_MEMCMP && \
- ((SI_POSIX && _GNU_SOURCE) || SI_NETBSD || SI_OPENBSD || SI_FREEBSD)
+ ((SI_POSIX && _GNU_SOURCE) || SI_NETBSD || 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__) && \
__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070
-# define SI_MAC_DEPLOYMENT_BELOW_10_7 1
+#define SI_MAC_DEPLOYMENT_BELOW_10_7 1
#else
-# define SI_MAC_DEPLOYMENT_BELOW_10_7 0
+#define SI_MAC_DEPLOYMENT_BELOW_10_7 0
#endif
// memmem on Darwin doesn't exist on 10.6
// FIXME: enable memmem on Windows.
#define SANITIZER_INTERCEPT_MEMMEM (SI_POSIX && !SI_MAC_DEPLOYMENT_BELOW_10_7)
#define SANITIZER_INTERCEPT_MEMCHR SI_NOT_FUCHSIA
-#define SANITIZER_INTERCEPT_MEMRCHR \
- (SI_FREEBSD || SI_LINUX || SI_NETBSD || SI_OPENBSD)
+#define SANITIZER_INTERCEPT_MEMRCHR (SI_FREEBSD || SI_LINUX || SI_NETBSD)
#define SANITIZER_INTERCEPT_READ SI_POSIX
#define SANITIZER_INTERCEPT_PREAD SI_POSIX
@@ -198,12 +190,12 @@
#define SANITIZER_INTERCEPT_WRITEV SI_POSIX
#define SANITIZER_INTERCEPT_PREADV \
- (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID)
+ (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID)
#define SANITIZER_INTERCEPT_PWRITEV SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_PREADV64 SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_PWRITEV64 SI_LINUX_NOT_ANDROID
-#define SANITIZER_INTERCEPT_PRCTL SI_LINUX
+#define SANITIZER_INTERCEPT_PRCTL SI_LINUX
#define SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS SI_POSIX
#define SANITIZER_INTERCEPT_STRPTIME SI_POSIX
@@ -212,9 +204,9 @@
#define SANITIZER_INTERCEPT_ISOC99_SCANF SI_LINUX_NOT_ANDROID
#ifndef SANITIZER_INTERCEPT_PRINTF
-# define SANITIZER_INTERCEPT_PRINTF SI_POSIX
-# define SANITIZER_INTERCEPT_PRINTF_L (SI_FREEBSD || SI_NETBSD)
-# define SANITIZER_INTERCEPT_ISOC99_PRINTF SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_PRINTF SI_POSIX
+#define SANITIZER_INTERCEPT_PRINTF_L (SI_FREEBSD || SI_NETBSD)
+#define SANITIZER_INTERCEPT_ISOC99_PRINTF SI_LINUX_NOT_ANDROID
#endif
#define SANITIZER_INTERCEPT___PRINTF_CHK \
@@ -224,23 +216,21 @@
#define SANITIZER_INTERCEPT_FREXPF_FREXPL SI_POSIX
#define SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS SI_POSIX
-#define SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS \
- (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \
- SI_SOLARIS)
-#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_GETPWNAM_R_AND_FRIENDS \
+ (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_GETPWENT \
+ (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_FGETGRENT_R \
+ (SI_FREEBSD || 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)
+ (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_FGETPWENT_R \
- (SI_FREEBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+ (SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_SETPWENT \
(SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_CLOCK_GETTIME \
- (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX || SI_SOLARIS)
+ (SI_FREEBSD || SI_NETBSD || SI_LINUX || SI_SOLARIS)
#define SANITIZER_INTERCEPT_CLOCK_GETCPUCLOCKID SI_LINUX
#define SANITIZER_INTERCEPT_GETITIMER SI_POSIX
#define SANITIZER_INTERCEPT_TIME SI_POSIX
@@ -248,7 +238,7 @@
#define SANITIZER_INTERCEPT_GLOB64 SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_WAIT SI_POSIX
#define SANITIZER_INTERCEPT_INET SI_POSIX
-#define SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM (SI_POSIX && !SI_OPENBSD)
+#define SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM SI_POSIX
#define SANITIZER_INTERCEPT_GETADDRINFO SI_POSIX
#define SANITIZER_INTERCEPT_GETNAMEINFO SI_POSIX
#define SANITIZER_INTERCEPT_GETSOCKNAME SI_POSIX
@@ -264,8 +254,7 @@
(SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_GETSOCKOPT SI_POSIX
#define SANITIZER_INTERCEPT_ACCEPT SI_POSIX
-#define SANITIZER_INTERCEPT_ACCEPT4 \
- (SI_LINUX_NOT_ANDROID || SI_NETBSD || SI_OPENBSD)
+#define SANITIZER_INTERCEPT_ACCEPT4 (SI_LINUX_NOT_ANDROID || SI_NETBSD)
#define SANITIZER_INTERCEPT_PACCEPT SI_NETBSD
#define SANITIZER_INTERCEPT_MODF SI_POSIX
#define SANITIZER_INTERCEPT_RECVMSG SI_POSIX
@@ -299,36 +288,32 @@
#define SANITIZER_INTERCEPT___STRXFRM_L SI_LINUX
#define SANITIZER_INTERCEPT_WCSXFRM SI_POSIX
#define SANITIZER_INTERCEPT___WCSXFRM_L SI_LINUX
-#define SANITIZER_INTERCEPT_WCSNRTOMBS \
- (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \
- SI_SOLARIS)
-#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_WCSNRTOMBS \
+ (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_WCRTOMB \
+ (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_WCTOMB \
+ (SI_FREEBSD || SI_NETBSD || 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 \
(SI_LINUX_NOT_ANDROID || SI_SOLARIS)
-#define SANITIZER_INTERCEPT_CONFSTR \
- (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \
- SI_SOLARIS)
+#define SANITIZER_INTERCEPT_CONFSTR \
+ (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_SCHED_GETAFFINITY SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_SCHED_GETPARAM SI_LINUX_NOT_ANDROID || SI_SOLARIS
#define SANITIZER_INTERCEPT_STRERROR SI_POSIX
#define SANITIZER_INTERCEPT_STRERROR_R SI_POSIX
#define SANITIZER_INTERCEPT_XPG_STRERROR_R SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_SCANDIR \
- (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+ (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_SCANDIR64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32
#define SANITIZER_INTERCEPT_GETGROUPS SI_POSIX
#define SANITIZER_INTERCEPT_POLL SI_POSIX
#define SANITIZER_INTERCEPT_PPOLL SI_LINUX_NOT_ANDROID || SI_SOLARIS
-#define SANITIZER_INTERCEPT_WORDEXP \
+#define SANITIZER_INTERCEPT_WORDEXP \
(SI_FREEBSD || SI_NETBSD || (SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID || \
- SI_SOLARIS)
+ SI_SOLARIS) // NOLINT
#define SANITIZER_INTERCEPT_SIGWAIT SI_POSIX
#define SANITIZER_INTERCEPT_SIGWAITINFO SI_LINUX_NOT_ANDROID || SI_SOLARIS
#define SANITIZER_INTERCEPT_SIGTIMEDWAIT SI_LINUX_NOT_ANDROID || SI_SOLARIS
@@ -339,7 +324,7 @@
#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)
+ (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_GETMNTENT SI_LINUX
#define SANITIZER_INTERCEPT_GETMNTENT_R SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_STATFS \
@@ -347,25 +332,25 @@
#define SANITIZER_INTERCEPT_STATFS64 \
(((SI_MAC && !TARGET_CPU_ARM64) && !SI_IOS) || SI_LINUX_NOT_ANDROID)
#define SANITIZER_INTERCEPT_STATVFS \
- (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID)
+ (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID)
#define SANITIZER_INTERCEPT_STATVFS64 SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_INITGROUPS SI_POSIX
-#define SANITIZER_INTERCEPT_ETHER_NTOA_ATON (SI_POSIX && !SI_OPENBSD)
+#define SANITIZER_INTERCEPT_ETHER_NTOA_ATON SI_POSIX
#define SANITIZER_INTERCEPT_ETHER_HOST \
(SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID)
#define SANITIZER_INTERCEPT_ETHER_R (SI_FREEBSD || SI_LINUX_NOT_ANDROID)
#define SANITIZER_INTERCEPT_SHMCTL \
(((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && SANITIZER_WORDSIZE == 64) || \
- SI_NETBSD || SI_OPENBSD || SI_SOLARIS) // NOLINT
+ SI_NETBSD || SI_SOLARIS) // NOLINT
#define SANITIZER_INTERCEPT_RANDOM_R SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET SI_POSIX
#define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED \
(SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP SI_LINUX_NOT_ANDROID
-#define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED (SI_POSIX && !SI_OPENBSD)
+#define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED SI_POSIX
#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED \
- (SI_POSIX && !SI_NETBSD && !SI_OPENBSD)
-#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE (SI_POSIX && !SI_OPENBSD)
+ (SI_POSIX && !SI_NETBSD)
+#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE SI_POSIX
#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL \
(SI_MAC || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING \
@@ -374,14 +359,13 @@
(SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED \
- (SI_POSIX && !SI_NETBSD && !SI_OPENBSD)
+ (SI_POSIX && !SI_NETBSD)
#define SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP SI_LINUX_NOT_ANDROID
-#define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED \
- (SI_POSIX && !SI_NETBSD && !SI_OPENBSD)
+#define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED (SI_POSIX && !SI_NETBSD)
#define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK \
(SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED \
- (SI_LINUX_NOT_ANDROID && !SI_NETBSD && !SI_OPENBSD)
+ (SI_LINUX_NOT_ANDROID && !SI_NETBSD)
#define SANITIZER_INTERCEPT_THR_EXIT SI_FREEBSD
#define SANITIZER_INTERCEPT_TMPNAM SI_POSIX
#define SANITIZER_INTERCEPT_TMPNAM_R SI_LINUX_NOT_ANDROID || SI_SOLARIS
@@ -398,40 +382,37 @@
#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
-#define SANITIZER_INTERCEPT_RAND_R \
- (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \
- SI_SOLARIS)
+#define SANITIZER_INTERCEPT_RAND_R \
+ (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_ICONV \
- (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+ (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_TIMES SI_POSIX
// FIXME: getline seems to be available on OSX 10.7
#define SANITIZER_INTERCEPT_GETLINE \
- (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+ (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT__EXIT \
- (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_SOLARIS)
+ (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_MAC || SI_SOLARIS)
#define SANITIZER_INTERCEPT_PTHREAD_MUTEX SI_POSIX
#define SANITIZER_INTERCEPT___PTHREAD_MUTEX SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT___LIBC_MUTEX SI_NETBSD
#define SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP \
- (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+ (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_PTHREAD_GETNAME_NP \
(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)
+ (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_LISTXATTR SI_LINUX
#define SANITIZER_INTERCEPT_GETXATTR SI_LINUX
#define SANITIZER_INTERCEPT_GETRESID SI_LINUX
-#define SANITIZER_INTERCEPT_GETIFADDRS \
- (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_MAC || \
- SI_SOLARIS)
-#define SANITIZER_INTERCEPT_IF_INDEXTONAME \
- (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_MAC || \
- SI_SOLARIS)
+#define SANITIZER_INTERCEPT_GETIFADDRS \
+ (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_IF_INDEXTONAME \
+ (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC || SI_SOLARIS)
#define SANITIZER_INTERCEPT_CAPGET SI_LINUX_NOT_ANDROID
#if SI_LINUX && defined(__arm__)
#define SANITIZER_INTERCEPT_AEABI_MEM 1
@@ -440,29 +421,27 @@
#endif
#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_FTIME (!SI_FREEBSD && !SI_NETBSD && SI_POSIX)
#define SANITIZER_INTERCEPT_XDR SI_LINUX_NOT_ANDROID || SI_SOLARIS
#define SANITIZER_INTERCEPT_XDRREC SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_TSEARCH \
- (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD || SI_OPENBSD || SI_SOLARIS)
+ (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD || SI_SOLARIS)
#define SANITIZER_INTERCEPT_LIBIO_INTERNALS SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_FOPEN SI_POSIX
#define SANITIZER_INTERCEPT_FOPEN64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32
#define SANITIZER_INTERCEPT_OPEN_MEMSTREAM \
- (SI_LINUX_NOT_ANDROID || SI_NETBSD || SI_OPENBSD || SI_SOLARIS)
+ (SI_LINUX_NOT_ANDROID || SI_NETBSD || SI_SOLARIS)
#define SANITIZER_INTERCEPT_OBSTACK SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_FFLUSH SI_POSIX
#define SANITIZER_INTERCEPT_FCLOSE SI_POSIX
#ifndef SANITIZER_INTERCEPT_DLOPEN_DLCLOSE
-#define SANITIZER_INTERCEPT_DLOPEN_DLCLOSE \
- (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_MAC || \
- SI_SOLARIS)
+#define SANITIZER_INTERCEPT_DLOPEN_DLCLOSE \
+ (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC || SI_SOLARIS)
#endif
#define SANITIZER_INTERCEPT_GETPASS \
- (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD || SI_OPENBSD)
+ (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD)
#define SANITIZER_INTERCEPT_TIMERFD SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_MLOCKX SI_POSIX
@@ -470,11 +449,10 @@
#define SANITIZER_INTERCEPT_SEM \
(SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_SOLARIS)
#define SANITIZER_INTERCEPT_PTHREAD_SETCANCEL SI_POSIX
-#define SANITIZER_INTERCEPT_MINCORE \
- (SI_LINUX || SI_NETBSD || SI_OPENBSD || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_MINCORE (SI_LINUX || SI_NETBSD || SI_SOLARIS)
#define SANITIZER_INTERCEPT_PROCESS_VM_READV SI_LINUX
#define SANITIZER_INTERCEPT_CTERMID \
- (SI_LINUX || SI_MAC || SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_SOLARIS)
+ (SI_LINUX || SI_MAC || SI_FREEBSD || SI_NETBSD || SI_SOLARIS)
#define SANITIZER_INTERCEPT_CTERMID_R (SI_MAC || SI_FREEBSD || SI_SOLARIS)
#define SANITIZER_INTERCEPTOR_HOOKS \
@@ -484,7 +462,7 @@
#define SANITIZER_INTERCEPT_EVENTFD_READ_WRITE SI_LINUX
#define SANITIZER_INTERCEPT_STAT \
- (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_OPENBSD || SI_SOLARIS)
+ (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS)
#define SANITIZER_INTERCEPT_LSTAT (SI_NETBSD || SI_FREEBSD)
#define SANITIZER_INTERCEPT___XSTAT (!SANITIZER_INTERCEPT_STAT && SI_POSIX)
#define SANITIZER_INTERCEPT___XSTAT64 SI_LINUX_NOT_ANDROID
@@ -497,41 +475,43 @@
(SI_LINUX_NOT_ANDROID || SI_MAC || SI_FREEBSD || SI_NETBSD)
#define SANITIZER_INTERCEPT_GETLOADAVG \
- (SI_LINUX_NOT_ANDROID || SI_MAC || SI_FREEBSD || SI_NETBSD || SI_OPENBSD)
+ (SI_LINUX_NOT_ANDROID || SI_MAC || SI_FREEBSD || SI_NETBSD)
#define SANITIZER_INTERCEPT_MMAP SI_POSIX
#define SANITIZER_INTERCEPT_MMAP64 SI_LINUX_NOT_ANDROID
-#define SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO \
- (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_FUCHSIA && \
- SI_NOT_RTEMS && !SI_SOLARIS) // NOLINT
+#define SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO \
+ (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && SI_NOT_FUCHSIA && SI_NOT_RTEMS && \
+ !SI_SOLARIS) // NOLINT
#define SANITIZER_INTERCEPT_MEMALIGN \
- (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_RTEMS)
-#define SANITIZER_INTERCEPT_PVALLOC \
- (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_FUCHSIA && \
- SI_NOT_RTEMS && !SI_SOLARIS) // NOLINT
-#define SANITIZER_INTERCEPT_CFREE \
- (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_FUCHSIA && \
- SI_NOT_RTEMS && !SI_SOLARIS) // NOLINT
+ (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && SI_NOT_RTEMS)
+#define SANITIZER_INTERCEPT___LIBC_MEMALIGN \
+ (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_RTEMS && \
+ !SI_ANDROID) // NOLINT
+#define SANITIZER_INTERCEPT_PVALLOC \
+ (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && SI_NOT_FUCHSIA && SI_NOT_RTEMS && \
+ !SI_SOLARIS) // NOLINT
+#define SANITIZER_INTERCEPT_CFREE \
+ (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && SI_NOT_FUCHSIA && SI_NOT_RTEMS && \
+ !SI_SOLARIS && !SANITIZER_ANDROID) // NOLINT
#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 && !SI_NETBSD)
+#define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE (!SI_MAC && !SI_NETBSD)
#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
-#define SANITIZER_INTERCEPT_ACCT (SI_NETBSD || SI_OPENBSD || SI_FREEBSD)
+#define SANITIZER_INTERCEPT_ACCT (SI_NETBSD || SI_FREEBSD)
#define SANITIZER_INTERCEPT_USER_FROM_UID SI_NETBSD
#define SANITIZER_INTERCEPT_UID_FROM_USER SI_NETBSD
#define SANITIZER_INTERCEPT_GROUP_FROM_GID SI_NETBSD
#define SANITIZER_INTERCEPT_GID_FROM_GROUP SI_NETBSD
-#define SANITIZER_INTERCEPT_ACCESS (SI_NETBSD || SI_OPENBSD || SI_FREEBSD)
-#define SANITIZER_INTERCEPT_FACCESSAT (SI_NETBSD || SI_OPENBSD || SI_FREEBSD)
-#define SANITIZER_INTERCEPT_GETGROUPLIST (SI_NETBSD || SI_OPENBSD)
-#define SANITIZER_INTERCEPT_STRLCPY \
- (SI_NETBSD || SI_FREEBSD || SI_OPENBSD || SI_MAC || SI_ANDROID)
+#define SANITIZER_INTERCEPT_ACCESS (SI_NETBSD || SI_FREEBSD)
+#define SANITIZER_INTERCEPT_FACCESSAT (SI_NETBSD || SI_FREEBSD)
+#define SANITIZER_INTERCEPT_GETGROUPLIST SI_NETBSD
+#define SANITIZER_INTERCEPT_STRLCPY \
+ (SI_NETBSD || SI_FREEBSD || SI_MAC || SI_ANDROID)
#define SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT SI_LINUX_NOT_ANDROID
@@ -539,14 +519,14 @@
#define SANITIZER_INTERCEPT_READLINK SI_POSIX
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101000
-# define SI_MAC_DEPLOYMENT_BELOW_10_10 1
+#define SI_MAC_DEPLOYMENT_BELOW_10_10 1
#else
-# define SI_MAC_DEPLOYMENT_BELOW_10_10 0
+#define SI_MAC_DEPLOYMENT_BELOW_10_10 0
#endif
#define SANITIZER_INTERCEPT_READLINKAT \
(SI_POSIX && !SI_MAC_DEPLOYMENT_BELOW_10_10)
-#define SANITIZER_INTERCEPT_DEVNAME (SI_NETBSD || SI_OPENBSD || SI_FREEBSD)
+#define SANITIZER_INTERCEPT_DEVNAME (SI_NETBSD || SI_FREEBSD)
#define SANITIZER_INTERCEPT_DEVNAME_R (SI_NETBSD || SI_FREEBSD)
#define SANITIZER_INTERCEPT_FGETLN (SI_NETBSD || SI_FREEBSD)
#define SANITIZER_INTERCEPT_STRMODE (SI_NETBSD || SI_FREEBSD)
@@ -554,8 +534,8 @@
#define SANITIZER_INTERCEPT_PROTOENT (SI_NETBSD || SI_LINUX)
#define SANITIZER_INTERCEPT_PROTOENT_R (SI_LINUX_NOT_ANDROID)
#define SANITIZER_INTERCEPT_NETENT SI_NETBSD
-#define SANITIZER_INTERCEPT_SETVBUF (SI_NETBSD || SI_FREEBSD || \
- SI_LINUX || SI_MAC)
+#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
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cpp b/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cpp
index 1420ecb..e69de29 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cpp
@@ -1,279 +0,0 @@
-//===-- sanitizer_platform_limits_openbsd.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 NetBSD data structures.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_platform.h"
-
-#if SANITIZER_OPENBSD
-#include <arpa/inet.h>
-#include <dirent.h>
-#include <glob.h>
-#include <grp.h>
-#include <ifaddrs.h>
-#include <limits.h>
-#include <link_elf.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <net/ppp_defs.h>
-#include <net/route.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <netinet/ip_mroute.h>
-#include <poll.h>
-#include <pthread.h>
-#include <pwd.h>
-#include <semaphore.h>
-#include <signal.h>
-#include <soundcard.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/filio.h>
-#include <sys/ipc.h>
-#include <sys/mman.h>
-#include <sys/mount.h>
-#include <sys/msg.h>
-#include <sys/mtio.h>
-#include <sys/ptrace.h>
-#include <sys/resource.h>
-#include <sys/shm.h>
-#include <sys/signal.h>
-#include <sys/sockio.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <sys/time.h>
-#include <sys/times.h>
-#include <sys/types.h>
-#include <sys/utsname.h>
-#include <term.h>
-#include <time.h>
-#include <utime.h>
-#include <utmp.h>
-#include <wchar.h>
-
-// Include these after system headers to avoid name clashes and ambiguities.
-#include "sanitizer_internal_defs.h"
-#include "sanitizer_platform_limits_openbsd.h"
-
-namespace __sanitizer {
-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_stack_t_sz = sizeof(stack_t);
-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 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_sched_param_sz = sizeof(struct sched_param);
-unsigned struct_sockaddr_sz = sizeof(struct sockaddr);
-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_msqid_ds_sz = sizeof(struct msqid_ds);
-unsigned struct_statvfs_sz = sizeof(struct statvfs);
-
-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;
-
-unsigned struct_utmp_sz = sizeof(struct utmp);
-
-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;
-
-const int si_SEGV_MAPERR = SEGV_MAPERR;
-const int si_SEGV_ACCERR = SEGV_ACCERR;
-} // 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);
-
-CHECK_TYPE_SIZE(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_addrlen);
-CHECK_SIZE_AND_OFFSET(addrinfo, ai_addr);
-CHECK_SIZE_AND_OFFSET(addrinfo, ai_canonname);
-CHECK_SIZE_AND_OFFSET(addrinfo, ai_next);
-
-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_fileno);
-CHECK_SIZE_AND_OFFSET(dirent, d_off);
-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(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(ipc_perm);
-CHECK_SIZE_AND_OFFSET(ipc_perm, cuid);
-CHECK_SIZE_AND_OFFSET(ipc_perm, cgid);
-CHECK_SIZE_AND_OFFSET(ipc_perm, uid);
-CHECK_SIZE_AND_OFFSET(ipc_perm, gid);
-CHECK_SIZE_AND_OFFSET(ipc_perm, mode);
-CHECK_SIZE_AND_OFFSET(ipc_perm, seq);
-CHECK_SIZE_AND_OFFSET(ipc_perm, key);
-
-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_atimensec);
-CHECK_SIZE_AND_OFFSET(shmid_ds, shm_dtime);
-CHECK_SIZE_AND_OFFSET(shmid_ds, __shm_dtimensec);
-CHECK_SIZE_AND_OFFSET(shmid_ds, shm_ctime);
-CHECK_SIZE_AND_OFFSET(shmid_ds, __shm_ctimensec);
-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);
-// Compare against the union, because we can't reach into the union in a
-// compliant way.
-#ifdef ifa_dstaddr
-#undef ifa_dstaddr
-#endif
-CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_dstaddr);
-CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_data);
-
-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);
-
-#endif // SANITIZER_OPENBSD
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.h
index 8a19487..e69de29 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.h
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.h
@@ -1,382 +0,0 @@
-//===-- sanitizer_platform_limits_openbsd.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 OpenBSD data structures.
-//===----------------------------------------------------------------------===//
-
-#ifndef SANITIZER_PLATFORM_LIMITS_OPENBSD_H
-#define SANITIZER_PLATFORM_LIMITS_OPENBSD_H
-
-#if SANITIZER_OPENBSD
-
-#include "sanitizer_internal_defs.h"
-#include "sanitizer_platform.h"
-
-#define _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, shift) \
- ((link_map *)((handle) == nullptr ? nullptr : ((char *)(handle) + (shift))))
-
-#if defined(__x86_64__)
-#define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \
- _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 312)
-#elif defined(__i386__)
-#define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \
- _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 164)
-#endif
-
-#define RLIMIT_AS RLIMIT_DATA
-
-namespace __sanitizer {
-extern unsigned struct_utsname_sz;
-extern unsigned struct_stat_sz;
-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 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_stack_t_sz;
-extern unsigned struct_statfs_sz;
-extern unsigned struct_sockaddr_sz;
-
-extern unsigned struct_rlimit_sz;
-extern unsigned struct_utimbuf_sz;
-extern unsigned struct_timespec_sz;
-
-struct __sanitizer_iocb {
- u64 aio_offset;
- uptr aio_buf;
- long aio_nbytes;
- u32 aio_fildes;
- u32 aio_lio_opcode;
- long aio_reqprio;
-#if SANITIZER_WORDSIZE == 64
- u8 aio_sigevent[32];
-#else
- u8 aio_sigevent[20];
-#endif
- u32 _state;
- u32 _errno;
- long _retval;
-};
-
-struct __sanitizer___sysctl_args {
- int *name;
- int nlen;
- void *oldval;
- uptr *oldlenp;
- void *newval;
- uptr newlen;
-};
-
-struct __sanitizer_sem_t {
- uptr data[5];
-};
-
-struct __sanitizer_ipc_perm {
- u32 cuid;
- u32 cgid;
- u32 uid;
- u32 gid;
- u32 mode;
- unsigned short seq;
- long key;
-};
-
-struct __sanitizer_shmid_ds {
- __sanitizer_ipc_perm shm_perm;
- int shm_segsz;
- u32 shm_lpid;
- u32 shm_cpid;
- short shm_nattch;
- u64 shm_atime;
- long __shm_atimensec;
- u64 shm_dtime;
- long __shm_dtimensec;
- u64 shm_ctime;
- long __shm_ctimensec;
- void *_shm_internal;
-};
-
-extern unsigned struct_msqid_ds_sz;
-extern unsigned struct_mq_attr_sz;
-extern unsigned struct_timex_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;
- struct __sanitizer_sockaddr *ifa_addr; // (struct sockaddr *)
- struct __sanitizer_sockaddr *ifa_netmask; // (struct sockaddr *)
- struct __sanitizer_sockaddr *ifa_dstaddr; // (struct sockaddr *)
- void *ifa_data;
-};
-
-typedef unsigned __sanitizer_pthread_key_t;
-
-typedef long long __sanitizer_time_t;
-typedef int __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_passwd {
- char *pw_name;
- char *pw_passwd;
- int pw_uid;
- int pw_gid;
- __sanitizer_time_t pw_change;
- char *pw_class;
- char *pw_gecos;
- char *pw_dir;
- char *pw_shell;
- __sanitizer_time_t pw_expire;
-};
-
-struct __sanitizer_group {
- char *gr_name;
- char *gr_passwd;
- int gr_gid;
- char **gr_mem;
-};
-
-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 {
- u64 d_fileno;
- u64 d_off;
- u16 d_reclen;
-};
-
-typedef u64 __sanitizer_clock_t;
-typedef u32 __sanitizer_clockid_t;
-
-typedef u32 __sanitizer___kernel_uid_t;
-typedef u32 __sanitizer___kernel_gid_t;
-typedef u64 __sanitizer___kernel_off_t;
-typedef struct {
- u32 fds_bits[8];
-} __sanitizer___kernel_fd_set;
-
-typedef struct {
- unsigned int pta_magic;
- int pta_flags;
- void *pta_private;
-} __sanitizer_pthread_attr_t;
-
-typedef unsigned int __sanitizer_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_sighandler_ptr handler;
- __sanitizer_sigactionhandler_ptr sigaction;
- };
- __sanitizer_sigset_t sa_mask;
- int sa_flags;
-};
-
-typedef __sanitizer_sigset_t __sanitizer_kernel_sigset_t;
-
-struct __sanitizer_kernel_sigaction_t {
- union {
- void (*handler)(int signo);
- void (*sigaction)(int signo, void *info, void *ctx);
- };
- unsigned long sa_flags;
- void (*sa_restorer)(void);
- __sanitizer_kernel_sigset_t sa_mask;
-};
-
-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 {
-#if SANITIZER_WORDSIZE == 64
- u64 dlpi_addr;
-#else
- u32 dlpi_addr;
-#endif
- const char *dlpi_name;
- const void *dlpi_phdr;
-#if SANITIZER_WORDSIZE == 64
- u32 dlpi_phnum;
-#else
- u16 dlpi_phnum;
-#endif
-};
-
-extern unsigned struct_ElfW_Phdr_sz;
-
-struct __sanitizer_addrinfo {
- int ai_flags;
- int ai_family;
- int ai_socktype;
- int ai_protocol;
- unsigned ai_addrlen;
- struct __sanitizer_sockaddr *ai_addr;
- char *ai_canonname;
- 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 {
- int gl_pathc;
- int gl_matchc;
- int gl_offs;
- int gl_flags;
- char **gl_pathv;
- void **gl_statv;
- 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;
-
-typedef char __sanitizer_FILE;
-#define SANITIZER_HAS_STRUCT_FILE 0
-
-extern int shmctl_ipc_stat;
-
-// This simplifies generic code
-#define struct_shminfo_sz -1
-#define struct_shm_info_sz -1
-#define shmctl_shm_stat -1
-#define shmctl_ipc_info -1
-#define shmctl_shm_info -1
-
-extern unsigned struct_utmp_sz;
-extern unsigned struct_utmpx_sz;
-
-extern int map_fixed;
-
-// ioctl arguments
-struct __sanitizer_ifconf {
- int ifc_len;
- union {
- void *ifcu_req;
- } ifc_ifcu;
-};
-
-extern const int si_SEGV_MAPERR;
-extern const int si_SEGV_ACCERR;
-} // 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 __sigaction14
-
-#endif // SANITIZER_OPENBSD
-
-#endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_posix.cpp b/libsanitizer/sanitizer_common/sanitizer_posix.cpp
index b8b75c2..2e08009 100644
--- a/libsanitizer/sanitizer_common/sanitizer_posix.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_posix.cpp
@@ -239,6 +239,7 @@ bool MemoryRangeIsAvailable(uptr range_start, uptr range_end) {
return true;
}
+#if !SANITIZER_MAC
void DumpProcessMap() {
MemoryMappingLayout proc_maps(/*cache_enabled*/true);
const sptr kBufSize = 4095;
@@ -252,6 +253,7 @@ void DumpProcessMap() {
Report("End of process memory map.\n");
UnmapOrDie(filename, kBufSize);
}
+#endif
const char *GetPwd() {
return GetEnv("PWD");
diff --git a/libsanitizer/sanitizer_common/sanitizer_posix.h b/libsanitizer/sanitizer_common/sanitizer_posix.h
index 66bcaf4..e1a2b48 100644
--- a/libsanitizer/sanitizer_common/sanitizer_posix.h
+++ b/libsanitizer/sanitizer_common/sanitizer_posix.h
@@ -17,7 +17,6 @@
#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"
#include "sanitizer_platform_limits_solaris.h"
diff --git a/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp
index 37aaec3..d29438c 100644
--- a/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp
@@ -18,7 +18,6 @@
#include "sanitizer_common.h"
#include "sanitizer_flags.h"
#include "sanitizer_platform_limits_netbsd.h"
-#include "sanitizer_platform_limits_openbsd.h"
#include "sanitizer_platform_limits_posix.h"
#include "sanitizer_platform_limits_solaris.h"
#include "sanitizer_posix.h"
diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps.h b/libsanitizer/sanitizer_common/sanitizer_procmaps.h
index 665ed45..a56640d 100644
--- a/libsanitizer/sanitizer_common/sanitizer_procmaps.h
+++ b/libsanitizer/sanitizer_common/sanitizer_procmaps.h
@@ -16,7 +16,7 @@
#include "sanitizer_platform.h"
#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
- SANITIZER_OPENBSD || SANITIZER_MAC || SANITIZER_SOLARIS || \
+ SANITIZER_MAC || SANITIZER_SOLARIS || \
SANITIZER_FUCHSIA
#include "sanitizer_common.h"
diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cpp b/libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cpp
index 02ff7c0..1f489b7 100644
--- a/libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cpp
@@ -7,11 +7,11 @@
//===----------------------------------------------------------------------===//
//
// Information about the process mappings
-// (FreeBSD, OpenBSD and NetBSD-specific parts).
+// (FreeBSD and NetBSD-specific parts).
//===----------------------------------------------------------------------===//
#include "sanitizer_platform.h"
-#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD
+#if SANITIZER_FREEBSD || SANITIZER_NETBSD
#include "sanitizer_common.h"
#if SANITIZER_FREEBSD
#include "sanitizer_freebsd.h"
@@ -28,11 +28,6 @@
#endif
#include <limits.h>
-#if SANITIZER_OPENBSD
-#define KVME_PROT_READ KVE_PROT_READ
-#define KVME_PROT_WRITE KVE_PROT_WRITE
-#define KVME_PROT_EXEC KVE_PROT_EXEC
-#endif
// Fix 'kinfo_vmentry' definition on FreeBSD prior v9.2 in 32-bit mode.
#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)
@@ -51,10 +46,6 @@ void ReadProcMaps(ProcSelfMapsBuff *proc_maps) {
KERN_PROC,
KERN_PROC_VMMAP,
getpid()
-#elif SANITIZER_OPENBSD
- CTL_KERN,
- KERN_PROC_VMMAP,
- getpid()
#elif SANITIZER_NETBSD
CTL_VM,
VM_PROC,
@@ -71,28 +62,12 @@ void ReadProcMaps(ProcSelfMapsBuff *proc_maps) {
CHECK_EQ(Err, 0);
CHECK_GT(Size, 0);
-#if !SANITIZER_OPENBSD
size_t MmapedSize = Size * 4 / 3;
void *VmMap = MmapOrDie(MmapedSize, "ReadProcMaps()");
Size = MmapedSize;
Err = internal_sysctl(Mib, ARRAY_SIZE(Mib), VmMap, &Size, NULL, 0);
CHECK_EQ(Err, 0);
proc_maps->data = (char *)VmMap;
-#else
- size_t PageSize = GetPageSize();
- size_t MmapedSize = Size;
- MmapedSize = ((MmapedSize - 1) / PageSize + 1) * PageSize;
- char *Mem = (char *)MmapOrDie(MmapedSize, "ReadProcMaps()");
- Size = 2 * Size + 10 * sizeof(struct kinfo_vmentry);
- if (Size > 0x10000)
- Size = 0x10000;
- Size = (Size / sizeof(struct kinfo_vmentry)) * sizeof(struct kinfo_vmentry);
- Err = internal_sysctl(Mib, ARRAY_SIZE(Mib), Mem, &Size, NULL, 0);
- CHECK_EQ(Err, 0);
- MmapedSize = Size;
- proc_maps->data = Mem;
-#endif
-
proc_maps->mmaped_size = MmapedSize;
proc_maps->len = Size;
}
@@ -117,13 +92,11 @@ bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
if ((VmEntry->kve_protection & KVME_PROT_EXEC) != 0)
segment->protection |= kProtectionExecute;
-#if !SANITIZER_OPENBSD
if (segment->filename != NULL && segment->filename_size > 0) {
internal_snprintf(segment->filename,
Min(segment->filename_size, (uptr)PATH_MAX), "%s",
VmEntry->kve_path);
}
-#endif
#if SANITIZER_FREEBSD
data_.current += VmEntry->kve_structsize;
diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_common.cpp b/libsanitizer/sanitizer_common/sanitizer_procmaps_common.cpp
index e0cb47f..f2cfcff 100644
--- a/libsanitizer/sanitizer_common/sanitizer_procmaps_common.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_common.cpp
@@ -12,7 +12,7 @@
#include "sanitizer_platform.h"
#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
- SANITIZER_OPENBSD || SANITIZER_SOLARIS
+ SANITIZER_SOLARIS
#include "sanitizer_common.h"
#include "sanitizer_placement_new.h"
diff --git a/libsanitizer/sanitizer_common/sanitizer_rtems.cpp b/libsanitizer/sanitizer_common/sanitizer_rtems.cpp
index 29bcfcf..d58bd08 100644
--- a/libsanitizer/sanitizer_common/sanitizer_rtems.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_rtems.cpp
@@ -108,8 +108,6 @@ void SetAlternateSignalStack() {}
void UnsetAlternateSignalStack() {}
void InitTlsSize() {}
-void PrintModuleMap() {}
-
void SignalContext::DumpAllRegisters(void *context) {}
const char *DescribeSignalOrException(int signo) { UNIMPLEMENTED(); }
diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.h b/libsanitizer/sanitizer_common/sanitizer_stacktrace.h
index d9fd88d..0350fe8 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.h
+++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.h
@@ -25,8 +25,6 @@ static const u32 kStackTraceMax = 256;
# define SANITIZER_CAN_FAST_UNWIND 0
#elif SANITIZER_WINDOWS
# define SANITIZER_CAN_FAST_UNWIND 0
-#elif SANITIZER_OPENBSD
-# define SANITIZER_CAN_FAST_UNWIND 0
#else
# define SANITIZER_CAN_FAST_UNWIND 1
#endif
@@ -34,7 +32,7 @@ static const u32 kStackTraceMax = 256;
// Fast unwind is the only option on Mac for now; we will need to
// revisit this macro when slow unwind works on Mac, see
// https://github.com/google/sanitizers/issues/137
-#if SANITIZER_MAC || SANITIZER_OPENBSD || SANITIZER_RTEMS
+#if SANITIZER_MAC || SANITIZER_RTEMS
# define SANITIZER_CAN_SLOW_UNWIND 0
#else
# define SANITIZER_CAN_SLOW_UNWIND 1
diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld.h b/libsanitizer/sanitizer_common/sanitizer_stoptheworld.h
index 7eb7c76..7891c10 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld.h
+++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld.h
@@ -40,10 +40,13 @@ class SuspendedThreadsList {
virtual uptr ThreadCount() const { UNIMPLEMENTED(); }
virtual tid_t GetThreadID(uptr index) const { UNIMPLEMENTED(); }
+ protected:
+ ~SuspendedThreadsList() {}
+
private:
// Prohibit copy and assign.
- SuspendedThreadsList(const SuspendedThreadsList&);
- void operator=(const SuspendedThreadsList&);
+ SuspendedThreadsList(const SuspendedThreadsList &) = delete;
+ void operator=(const SuspendedThreadsList &) = delete;
};
typedef void (*StopTheWorldCallback)(
diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_fuchsia.cpp b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_fuchsia.cpp
index 3a24644..91bf19e 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_fuchsia.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_fuchsia.cpp
@@ -17,6 +17,7 @@
#include <zircon/sanitizer.h>
#include "sanitizer_stoptheworld.h"
+#include "sanitizer_stoptheworld_fuchsia.h"
namespace __sanitizer {
@@ -32,7 +33,7 @@ void StopTheWorld(StopTheWorldCallback callback, void *argument) {
nullptr, nullptr, nullptr, nullptr,
[](zx_status_t, void *data) {
auto params = reinterpret_cast<Params *>(data);
- params->callback({}, params->argument);
+ params->callback(SuspendedThreadsListFuchsia(), params->argument);
},
&params);
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_fuchsia.h b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_fuchsia.h
new file mode 100644
index 0000000..6d9ead6
--- /dev/null
+++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_fuchsia.h
@@ -0,0 +1,20 @@
+//===-- sanitizer_stoptheworld_fuchsia.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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SANITIZER_STOPTHEWORLD_FUCHSIA_H
+#define SANITIZER_STOPTHEWORLD_FUCHSIA_H
+
+#include "sanitizer_stoptheworld.h"
+
+namespace __sanitizer {
+
+class SuspendedThreadsListFuchsia final : public SuspendedThreadsList {};
+
+} // namespace __sanitizer
+
+#endif // SANITIZER_STOPTHEWORLD_FUCHSIA_H
diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp
index eb89f1f..0f1cadf 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp
@@ -85,7 +85,7 @@
namespace __sanitizer {
-class SuspendedThreadsListLinux : public SuspendedThreadsList {
+class SuspendedThreadsListLinux final : public SuspendedThreadsList {
public:
SuspendedThreadsListLinux() { thread_ids_.reserve(1024); }
diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_mac.cpp b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_mac.cpp
index a605d5b..5ec3080 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_mac.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_mac.cpp
@@ -27,7 +27,7 @@ typedef struct {
thread_t thread;
} SuspendedThreadInfo;
-class SuspendedThreadsListMac : public SuspendedThreadsList {
+class SuspendedThreadsListMac final : public SuspendedThreadsList {
public:
SuspendedThreadsListMac() : threads_(1024) {}
diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp
index 70df31e..9c7cd64 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp
@@ -48,7 +48,7 @@
namespace __sanitizer {
-class SuspendedThreadsListNetBSD : public SuspendedThreadsList {
+class SuspendedThreadsListNetBSD final : public SuspendedThreadsList {
public:
SuspendedThreadsListNetBSD() { thread_ids_.reserve(1024); }
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_internal.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer_internal.h
index e4c351e..71de175 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_internal.h
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_internal.h
@@ -74,6 +74,9 @@ class SymbolizerTool {
// Usually this is a safe place to call code that might need to use user
// memory allocators.
virtual void LateInitialize() {}
+
+ protected:
+ ~SymbolizerTool() {}
};
// SymbolizerProcess encapsulates communication between the tool and
@@ -85,6 +88,8 @@ class SymbolizerProcess {
const char *SendCommand(const char *command);
protected:
+ ~SymbolizerProcess() {}
+
/// The maximum number of arguments required to invoke a tool process.
static const unsigned kArgVMax = 6;
@@ -128,7 +133,7 @@ class LLVMSymbolizerProcess;
// This tool invokes llvm-symbolizer in a subprocess. It should be as portable
// as the llvm-symbolizer tool is.
-class LLVMSymbolizer : public SymbolizerTool {
+class LLVMSymbolizer final : public SymbolizerTool {
public:
explicit LLVMSymbolizer(const char *path, LowLevelAllocator *allocator);
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.h
index e2a0f71..7b039b8 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.h
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.h
@@ -28,7 +28,7 @@
namespace __sanitizer {
-class LibbacktraceSymbolizer : public SymbolizerTool {
+class LibbacktraceSymbolizer final : public SymbolizerTool {
public:
static LibbacktraceSymbolizer *get(LowLevelAllocator *alloc);
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
index 311d676..710da4c 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
@@ -237,7 +237,7 @@ const LoadedModule *Symbolizer::FindModuleForAddress(uptr address) {
// <file_name>:<line_number>:<column_number>
// ...
// <empty line>
-class LLVMSymbolizerProcess : public SymbolizerProcess {
+class LLVMSymbolizerProcess final : public SymbolizerProcess {
public:
explicit LLVMSymbolizerProcess(const char *path)
: SymbolizerProcess(path, /*use_posix_spawn=*/SANITIZER_MAC) {}
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cpp b/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cpp
index f0f1508..5c25b28 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cpp
@@ -65,7 +65,7 @@ bool DlAddrSymbolizer::SymbolizeData(uptr addr, DataInfo *datainfo) {
// kAsanInternalHeapMagic.
static char kAtosMachPortEnvEntry[] = K_ATOS_ENV_VAR "=000000000000000";
-class AtosSymbolizerProcess : public SymbolizerProcess {
+class AtosSymbolizerProcess final : public SymbolizerProcess {
public:
explicit AtosSymbolizerProcess(const char *path)
: SymbolizerProcess(path, /*use_posix_spawn*/ true) {
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.h
index 8996131..401d30f 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.h
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.h
@@ -21,7 +21,7 @@
namespace __sanitizer {
-class DlAddrSymbolizer : public SymbolizerTool {
+class DlAddrSymbolizer final : public SymbolizerTool {
public:
bool SymbolizePC(uptr addr, SymbolizedStack *stack) override;
bool SymbolizeData(uptr addr, DataInfo *info) override;
@@ -29,7 +29,7 @@ class DlAddrSymbolizer : public SymbolizerTool {
class AtosSymbolizerProcess;
-class AtosSymbolizer : public SymbolizerTool {
+class AtosSymbolizer final : public SymbolizerTool {
public:
explicit AtosSymbolizer(const char *path, LowLevelAllocator *allocator);
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
index 3c379a8..4dd5cc3 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
@@ -201,7 +201,7 @@ bool SymbolizerProcess::StartSymbolizerSubprocess() {
return true;
}
-class Addr2LineProcess : public SymbolizerProcess {
+class Addr2LineProcess final : public SymbolizerProcess {
public:
Addr2LineProcess(const char *path, const char *module_name)
: SymbolizerProcess(path), module_name_(internal_strdup(module_name)) {}
@@ -261,7 +261,7 @@ bool Addr2LineProcess::ReachedEndOfOutput(const char *buffer,
output_terminator_, kTerminatorLen);
}
-class Addr2LinePool : public SymbolizerTool {
+class Addr2LinePool final : public SymbolizerTool {
public:
explicit Addr2LinePool(const char *addr2line_path,
LowLevelAllocator *allocator)
@@ -328,7 +328,7 @@ int __sanitizer_symbolize_demangle(const char *Name, char *Buffer,
int MaxLength);
} // extern "C"
-class InternalSymbolizer : public SymbolizerTool {
+class InternalSymbolizer final : public SymbolizerTool {
public:
static InternalSymbolizer *get(LowLevelAllocator *alloc) {
if (__sanitizer_symbolize_code != 0 &&
@@ -387,7 +387,7 @@ class InternalSymbolizer : public SymbolizerTool {
};
#else // SANITIZER_SUPPORTS_WEAK_HOOKS
-class InternalSymbolizer : public SymbolizerTool {
+class InternalSymbolizer final : public SymbolizerTool {
public:
static InternalSymbolizer *get(LowLevelAllocator *alloc) { return 0; }
};
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cpp b/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cpp
index 373437e..48fa2d1 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cpp
@@ -33,7 +33,7 @@ decltype(::UnDecorateSymbolName) *UnDecorateSymbolName;
namespace {
-class WinSymbolizerTool : public SymbolizerTool {
+class WinSymbolizerTool final : public SymbolizerTool {
public:
// The constructor is provided to avoid synthesized memsets.
WinSymbolizerTool() {}
diff --git a/libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc b/libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc
index a43ce3e..8829985 100644
--- a/libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc
@@ -13,7 +13,7 @@
// NetBSD uses libc calls directly
#if !SANITIZER_NETBSD
-#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_OPENBSD || SANITIZER_SOLARIS
+#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_SOLARIS
# define SYSCALL(name) SYS_ ## name
#else
# define SYSCALL(name) __NR_ ## name
diff --git a/libsanitizer/sanitizer_common/sanitizer_thread_registry.h b/libsanitizer/sanitizer_common/sanitizer_thread_registry.h
index 493aa98..85c522a 100644
--- a/libsanitizer/sanitizer_common/sanitizer_thread_registry.h
+++ b/libsanitizer/sanitizer_common/sanitizer_thread_registry.h
@@ -39,8 +39,6 @@ enum class ThreadType {
class ThreadContextBase {
public:
explicit ThreadContextBase(u32 tid);
- ~ThreadContextBase(); // Should never be called.
-
const u32 tid; // Thread ID. Main thread should have tid = 0.
u64 unique_id; // Unique thread ID.
u32 reuse_count; // Number of times this tid was reused.
@@ -80,6 +78,9 @@ class ThreadContextBase {
virtual void OnCreated(void *arg) {}
virtual void OnReset() {}
virtual void OnDetached(void *arg) {}
+
+ protected:
+ ~ThreadContextBase();
};
typedef ThreadContextBase* (*ThreadContextFactory)(u32 tid);
diff --git a/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cpp b/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cpp
index 9ca898a..10748f9 100644
--- a/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cpp
@@ -80,8 +80,13 @@ void DTLS_Destroy() {
#if defined(__powerpc64__) || defined(__mips__)
// This is glibc's TLS_DTV_OFFSET:
// "Dynamic thread vector pointers point 0x8000 past the start of each
-// TLS block."
+// TLS block." (sysdeps/<arch>/dl-tls.h)
static const uptr kDtvOffset = 0x8000;
+#elif defined(__riscv)
+// This is glibc's TLS_DTV_OFFSET:
+// "Dynamic thread vector pointers point 0x800 past the start of each
+// TLS block." (sysdeps/riscv/dl-tls.h)
+static const uptr kDtvOffset = 0x800;
#else
static const uptr kDtvOffset = 0;
#endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_unwind_win.cpp b/libsanitizer/sanitizer_common/sanitizer_unwind_win.cpp
index 8e06940..e2edf42 100644
--- a/libsanitizer/sanitizer_common/sanitizer_unwind_win.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_unwind_win.cpp
@@ -37,6 +37,10 @@ void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) {
// Skip the RTL frames by searching for the PC in the stacktrace.
uptr pc_location = LocatePcInTrace(pc);
PopStackFrames(pc_location);
+
+ // Replace the first frame with the PC because the frame in the
+ // stacktrace might be incorrect.
+ trace_buffer[0] = pc;
}
void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) {
diff --git a/libsanitizer/sanitizer_common/sanitizer_win.cpp b/libsanitizer/sanitizer_common/sanitizer_win.cpp
index 53a537d..85ac263 100644
--- a/libsanitizer/sanitizer_common/sanitizer_win.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_win.cpp
@@ -491,8 +491,6 @@ void DumpProcessMap() {
}
#endif
-void PrintModuleMap() { }
-
void DisableCoreDumperIfNecessary() {
// Do nothing.
}
@@ -1140,6 +1138,8 @@ void LogFullErrorReport(const char *buffer) {
}
#endif // SANITIZER_WIN_TRACE
+void InitializePlatformCommonFlags(CommonFlags *cf) {}
+
} // namespace __sanitizer
#endif // _WIN32
diff --git a/libsanitizer/tsan/Makefile.in b/libsanitizer/tsan/Makefile.in
index bfbdfe0..ce11d24 100644
--- a/libsanitizer/tsan/Makefile.in
+++ b/libsanitizer/tsan/Makefile.in
@@ -375,6 +375,7 @@ install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
link_libasan = @link_libasan@
+link_libhwasan = @link_libhwasan@
link_liblsan = @link_liblsan@
link_libtsan = @link_libtsan@
link_libubsan = @link_libubsan@
diff --git a/libsanitizer/tsan/tsan_platform.h b/libsanitizer/tsan/tsan_platform.h
index 7256d64..16169ca 100644
--- a/libsanitizer/tsan/tsan_platform.h
+++ b/libsanitizer/tsan/tsan_platform.h
@@ -461,7 +461,7 @@ struct Mapping47 {
#elif SANITIZER_GO && defined(__aarch64__)
-/* Go on linux/aarch64 (48-bit VMA)
+/* Go on linux/aarch64 (48-bit VMA) and darwin/aarch64 (47-bit VMA)
0000 0000 1000 - 0000 1000 0000: executable
0000 1000 0000 - 00c0 0000 0000: -
00c0 0000 0000 - 00e0 0000 0000: heap
@@ -488,6 +488,30 @@ struct Mapping {
// Indicates the runtime will define the memory regions at runtime.
#define TSAN_RUNTIME_VMA 1
+#elif SANITIZER_GO && defined(__mips64)
+/*
+Go on linux/mips64 (47-bit VMA)
+0000 0000 1000 - 0000 1000 0000: executable
+0000 1000 0000 - 00c0 0000 0000: -
+00c0 0000 0000 - 00e0 0000 0000: heap
+00e0 0000 0000 - 2000 0000 0000: -
+2000 0000 0000 - 3000 0000 0000: shadow
+3000 0000 0000 - 3000 0000 0000: -
+3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)
+4000 0000 0000 - 6000 0000 0000: -
+6000 0000 0000 - 6200 0000 0000: traces
+6200 0000 0000 - 8000 0000 0000: -
+*/
+struct Mapping {
+ static const uptr kMetaShadowBeg = 0x300000000000ull;
+ static const uptr kMetaShadowEnd = 0x400000000000ull;
+ static const uptr kTraceMemBeg = 0x600000000000ull;
+ static const uptr kTraceMemEnd = 0x620000000000ull;
+ static const uptr kShadowBeg = 0x200000000000ull;
+ static const uptr kShadowEnd = 0x300000000000ull;
+ static const uptr kAppMemBeg = 0x000000001000ull;
+ static const uptr kAppMemEnd = 0x00e000000000ull;
+};
#else
# error "Unknown platform"
#endif
diff --git a/libsanitizer/tsan/tsan_platform_linux.cpp b/libsanitizer/tsan/tsan_platform_linux.cpp
index 710e7ec..d136dcb 100644
--- a/libsanitizer/tsan/tsan_platform_linux.cpp
+++ b/libsanitizer/tsan/tsan_platform_linux.cpp
@@ -12,14 +12,12 @@
//===----------------------------------------------------------------------===//
#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
- SANITIZER_OPENBSD
+#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_linux.h"
#include "sanitizer_common/sanitizer_platform_limits_netbsd.h"
-#include "sanitizer_common/sanitizer_platform_limits_openbsd.h"
#include "sanitizer_common/sanitizer_platform_limits_posix.h"
#include "sanitizer_common/sanitizer_posix.h"
#include "sanitizer_common/sanitizer_procmaps.h"
@@ -517,5 +515,4 @@ void cur_thread_finalize() {
} // namespace __tsan
-#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD ||
- // SANITIZER_OPENBSD
+#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD
diff --git a/libsanitizer/tsan/tsan_platform_mac.cpp b/libsanitizer/tsan/tsan_platform_mac.cpp
index eea52a3..ec2c5fb 100644
--- a/libsanitizer/tsan/tsan_platform_mac.cpp
+++ b/libsanitizer/tsan/tsan_platform_mac.cpp
@@ -234,7 +234,7 @@ static void my_pthread_introspection_hook(unsigned int event, pthread_t thread,
#endif
void InitializePlatformEarly() {
-#if defined(__aarch64__)
+#if !SANITIZER_GO && defined(__aarch64__)
uptr max_vm = GetMaxUserVirtualAddress() + 1;
if (max_vm != Mapping::kHiAppMemEnd) {
Printf("ThreadSanitizer: unsupported vm address limit %p, expected %p.\n",
diff --git a/libsanitizer/tsan/tsan_report.cpp b/libsanitizer/tsan/tsan_report.cpp
index 4892c44..968c7b9 100644
--- a/libsanitizer/tsan/tsan_report.cpp
+++ b/libsanitizer/tsan/tsan_report.cpp
@@ -386,7 +386,8 @@ void PrintReport(const ReportDesc *rep) {
ReportErrorSummary(rep_typ_str, frame->info);
}
- if (common_flags()->print_module_map == 2) PrintModuleMap();
+ if (common_flags()->print_module_map == 2)
+ DumpProcessMap();
Printf("==================\n");
}
diff --git a/libsanitizer/tsan/tsan_rtl.cpp b/libsanitizer/tsan/tsan_rtl.cpp
index 7b37ed5..3d721eb 100644
--- a/libsanitizer/tsan/tsan_rtl.cpp
+++ b/libsanitizer/tsan/tsan_rtl.cpp
@@ -446,7 +446,8 @@ void MaybeSpawnBackgroundThread() {
int Finalize(ThreadState *thr) {
bool failed = false;
- if (common_flags()->print_module_map == 1) PrintModuleMap();
+ if (common_flags()->print_module_map == 1)
+ DumpProcessMap();
if (flags()->atexit_sleep_ms > 0 && ThreadCount(thr) > 1)
SleepForMillis(flags()->atexit_sleep_ms);
diff --git a/libsanitizer/tsan/tsan_rtl.h b/libsanitizer/tsan/tsan_rtl.h
index efdc53a..04d474e 100644
--- a/libsanitizer/tsan/tsan_rtl.h
+++ b/libsanitizer/tsan/tsan_rtl.h
@@ -477,7 +477,7 @@ inline void cur_thread_finalize() { }
#endif // SANITIZER_MAC || SANITIZER_ANDROID
#endif // SANITIZER_GO
-class ThreadContext : public ThreadContextBase {
+class ThreadContext final : public ThreadContextBase {
public:
explicit ThreadContext(int tid);
~ThreadContext();
diff --git a/libsanitizer/tsan/tsan_rtl_mutex.cpp b/libsanitizer/tsan/tsan_rtl_mutex.cpp
index ebd0d72..27897f0 100644
--- a/libsanitizer/tsan/tsan_rtl_mutex.cpp
+++ b/libsanitizer/tsan/tsan_rtl_mutex.cpp
@@ -24,7 +24,7 @@ namespace __tsan {
void ReportDeadlock(ThreadState *thr, uptr pc, DDReport *r);
-struct Callback : DDCallback {
+struct Callback final : public DDCallback {
ThreadState *thr;
uptr pc;
diff --git a/libsanitizer/ubsan/Makefile.in b/libsanitizer/ubsan/Makefile.in
index 312d6a5..2775c14 100644
--- a/libsanitizer/ubsan/Makefile.in
+++ b/libsanitizer/ubsan/Makefile.in
@@ -340,6 +340,7 @@ install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
link_libasan = @link_libasan@
+link_libhwasan = @link_libhwasan@
link_liblsan = @link_liblsan@
link_libtsan = @link_libtsan@
link_libubsan = @link_libubsan@
diff --git a/libsanitizer/ubsan/ubsan_platform.h b/libsanitizer/ubsan/ubsan_platform.h
index 58aabbe..98542fce 100644
--- a/libsanitizer/ubsan/ubsan_platform.h
+++ b/libsanitizer/ubsan/ubsan_platform.h
@@ -15,7 +15,7 @@
#ifndef CAN_SANITIZE_UB
// Other platforms should be easy to add, and probably work as-is.
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
- defined(__NetBSD__) || defined(__OpenBSD__) || \
+ defined(__NetBSD__) || \
(defined(__sun__) && defined(__svr4__)) || \
defined(_WIN32) || defined(__Fuchsia__) || defined(__rtems__)
# define CAN_SANITIZE_UB 1
diff --git a/libsanitizer/ubsan/ubsan_type_hash_itanium.cpp b/libsanitizer/ubsan/ubsan_type_hash_itanium.cpp
index 4f1708b..d82b542 100644
--- a/libsanitizer/ubsan/ubsan_type_hash_itanium.cpp
+++ b/libsanitizer/ubsan/ubsan_type_hash_itanium.cpp
@@ -12,7 +12,7 @@
#include "sanitizer_common/sanitizer_platform.h"
#include "ubsan_platform.h"
-#if CAN_SANITIZE_UB && !SANITIZER_WINDOWS
+#if CAN_SANITIZE_UB && !defined(_MSC_VER)
#include "ubsan_type_hash.h"
#include "sanitizer_common/sanitizer_common.h"
diff --git a/libsanitizer/ubsan/ubsan_type_hash_win.cpp b/libsanitizer/ubsan/ubsan_type_hash_win.cpp
index 45dcb75..106fa1b 100644
--- a/libsanitizer/ubsan/ubsan_type_hash_win.cpp
+++ b/libsanitizer/ubsan/ubsan_type_hash_win.cpp
@@ -12,7 +12,7 @@
#include "sanitizer_common/sanitizer_platform.h"
#include "ubsan_platform.h"
-#if CAN_SANITIZE_UB && SANITIZER_WINDOWS
+#if CAN_SANITIZE_UB && defined(_MSC_VER)
#include "ubsan_type_hash.h"
#include "sanitizer_common/sanitizer_common.h"
diff --git a/libssp/ChangeLog b/libssp/ChangeLog
index 3891d20..becf73f 100644
--- a/libssp/ChangeLog
+++ b/libssp/ChangeLog
@@ -1,3 +1,7 @@
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ * configure: Regenerate.
+
2020-05-29 H.J. Lu <hjl.tools@gmail.com>
PR bootstrap/95413
diff --git a/libssp/configure b/libssp/configure
index ff342ac..adaa751 100755
--- a/libssp/configure
+++ b/libssp/configure
@@ -9263,7 +9263,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -9275,7 +9275,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 2441dfc..6b1c345 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,879 @@
+2020-12-02 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/65480
+ PR libstdc++/68735
+ * python/libstdcxx/v6/printers.py (function_pointer_to_name):
+ New helper function to get the name of a function from its
+ address.
+ (StdExpAnyPrinter.__init__): Use it.
+
+2020-12-02 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/lib/dg-options.exp (add_options_for_libatomic):
+ Replace powerpc-ibm-aix* and powerpc*-*-darwin* with check for
+ powerpc && ilp32.
+
+2020-12-02 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/27_io/basic_istream/ignore/char/94749.cc: Add
+ dg-timeout-factor for ilp32 targets.
+ * testsuite/27_io/basic_istream/ignore/wchar_t/94749.cc:
+ Likewise.
+
+2020-12-02 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/ext/rope (rope::_S_concat_char_iter)
+ (rope::_S_destr_concat_char_iter): Add allocator parameter.
+ (rope::push_back, rope::append, rope::insert, operator+):
+ Pass allocator.
+ * include/ext/ropeimpl.h (rope::_S_concat_char_iter)
+ (rope::_S_destr_concat_char_iter): Add allocator parameter
+ and use it.
+ (_Rope_char_ref_proxy::operator=(_CharT)): Pass allocator.
+
+2020-12-02 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/ext/rope: Fix indentation of access specifiers.
+
+2020-12-02 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/atomic_timed_wait.h: Use #if instead of #ifdef.
+ * include/bits/semaphore_base.h: Likewise.
+ * include/std/version: Remove trailing whitespace.
+
+2020-12-02 Jonathan Wakely <jwakely@redhat.com>
+
+ * python/libstdcxx/v6/printers.py (StdExpPathPrinter): Store the
+ name of the type and pass it to the iterator.
+ (StdPathPrinter): Likewise.
+ * testsuite/libstdc++-prettyprinters/filesystem-ts.cc: New test.
+
+2020-12-01 Thomas Rodgers <trodgers@redhat.com>
+
+ * include/bits/atomic_base.h: Replace usage of
+ _GLIBCXX_HAVE_ATOMIC_WAIT with __cpp_lib_atomic_wait.
+ * include/bits/atomic_timed_wait.h: Likewise.
+ * include/bits/atomic_wait.h: Define __cpp_lib_atomic_wait
+ feature test macro.
+ * include/bits/semaphore_base.h: Replace usage of
+ _GLIBCXX_HAVE_ATOMIC_WAIT with __cpp_lib_atomic_wait.
+ * include/std/atomic: Likewise.
+ * include/std/latch: Likewise.
+ * include/std/semaphore: Likewise.
+ * include/std/version: Define __cpp_lib_atomic wait
+ feature test macro and replace usage of
+ _GLIBCXX_HAVE_ATOMIC_WAIT.
+ * testsuite/29_atomics/atomic/wait_notify/1.cc: New test.
+ * testsuite/29_atomics/atomic/wait_notify/2.cc: Likewise.
+
+2020-12-01 Michael Weghorn <m.weghorn@posteo.de>
+
+ * python/libstdcxx/v6/printers.py (StdBitIteratorPrinter)
+ (StdBitReferencePrinter): Add pretty-printers for
+ _Bit_reference, _Bit_iterator and _Bit_const_iterator.
+ * testsuite/libstdc++-prettyprinters/simple.cc: Test
+ std::_Bit_reference, std::_Bit_iterator and
+ std::_Bit_const_iterator.
+ * testsuite/libstdc++-prettyprinters/simple11.cc: Likewise.
+
+2020-12-01 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/c++config (_GLIBCXX_HAS_BUILTIN): Define macro to
+ work around different implementations of __has_builtin.
+ (_GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP)
+ (_GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE)
+ (_GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED)
+ (_GLIBCXX_HAVE_BUILTIN_IS_SAME, _GLIBCXX_HAVE_BUILTIN_LAUNDER):
+ Define using _GLIBCXX_HAS_BUILTIN.
+
+2020-12-01 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/27_io/basic_istream/get/char/lwg3464.cc: Add
+ dg-timeout-factor directive.
+ * testsuite/27_io/basic_istream/get/wchar_t/lwg3464.cc:
+ Likewise.
+
+2020-12-01 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/98003
+ * testsuite/27_io/basic_syncbuf/sync_ops/1.cc: Add options for
+ libatomic.
+
+2020-11-30 Jonathan Wakely <jwakely@redhat.com>
+
+ * doc/doxygen/user.cfg.in (INPUT): Add <latch> and <semaphore>.
+
+2020-11-30 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/lib/libstdc++.exp (libstdc++_init): Reduce
+ default tool_timeout to 360.
+
+2020-11-30 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/20_util/specialized_algorithms/pstl/*: Add
+ dg-timeout-factor.
+ * testsuite/25_algorithms/pstl/*: Likewise.
+ * testsuite/26_numerics/pstl/*: Likewise.
+ * testsuite/28_regex/*: Likewise.
+
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ * configure: Regenerate.
+
+2020-11-27 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/lib/libstdc++.exp (v3_try_preprocess): Define
+ new proc to preprocess a chunk of code.
+ (v3_check_preprocessor_condition): Define new proc to test
+ a preprocessor condition depending on GCC or libstdc++ macros.
+ (check_v3_target_debug_mode, check_v3_target_normal_mode):
+ Use v3_try_preprocess.
+ (check_v3_target_normal_namespace)
+ (check_v3_target_parallel_mode, check_v3_target_cstdint)
+ (check_v3_target_cmath, check_v3_target_atomic_builtins)
+ (check_v3_target_gthreads, check_v3_target_gthreads_timed)
+ (check_v3_target_sleep, check_v3_target_sched_yield)
+ (check_v3_target_string_conversions, check_v3_target_swprintf)
+ (check_v3_target_binary_io, check_v3_target_nprocs): Use
+ v3_check_preprocessor_condition.
+ (check_effective_target_cxx11): Likewise.
+ (check_effective_target_random_device): Likewise.
+ (check_effective_target_tbb-backend): Likewise.
+ (check_effective_target_futex): Likewise.
+ (check_v3_target_little_endian) Call check_effective_target_le.
+ (check_effective_target_atomic-builtins): New proc to define
+ new effective-target keyword.
+ (check_effective_target_gthreads-timed): Likewise.
+
+2020-11-27 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/27_io/filesystem/operations/absolute.cc: Avoid
+ -Wrange-loop-construct warning.
+ * testsuite/27_io/filesystem/path/append/source.cc: Likewise.
+ * testsuite/27_io/filesystem/path/assign/copy.cc: Likewise.
+ * testsuite/27_io/filesystem/path/compare/path.cc: Likewise.
+ * testsuite/27_io/filesystem/path/construct/copy.cc: Likewise.
+ * testsuite/27_io/filesystem/path/decompose/extension.cc:
+ Likewise.
+ * testsuite/27_io/filesystem/path/decompose/filename.cc:
+ Likewise.
+ * testsuite/27_io/filesystem/path/decompose/parent_path.cc:
+ Likewise.
+ * testsuite/27_io/filesystem/path/decompose/relative_path.cc:
+ Likewise.
+ * testsuite/27_io/filesystem/path/decompose/root_directory.cc:
+ Likewise.
+ * testsuite/27_io/filesystem/path/decompose/root_path.cc:
+ Likewise.
+ * testsuite/27_io/filesystem/path/itr/traversal.cc: Likewise.
+ * testsuite/27_io/filesystem/path/modifiers/remove_filename.cc:
+ Likewise.
+ * testsuite/27_io/filesystem/path/modifiers/replace_extension.cc:
+ Likewise.
+ * testsuite/27_io/filesystem/path/modifiers/replace_filename.cc:
+ Likewise.
+ * testsuite/27_io/filesystem/path/nonmember/append.cc: Likewise.
+ * testsuite/27_io/filesystem/path/nonmember/cmp.cc: Likewise.
+ * testsuite/27_io/filesystem/path/nonmember/cmp_c++20.cc:
+ Likewise.
+ * testsuite/27_io/filesystem/path/nonmember/hash_value.cc:
+ Likewise.
+ * testsuite/27_io/filesystem/path/query/has_extension.cc:
+ Likewise.
+ * testsuite/27_io/filesystem/path/query/has_filename.cc:
+ Likewise.
+ * testsuite/27_io/filesystem/path/query/has_parent_path.cc:
+ Likewise.
+ * testsuite/27_io/filesystem/path/query/has_relative_path.cc:
+ Likewise.
+ * testsuite/27_io/filesystem/path/query/has_root_directory.cc:
+ Likewise.
+ * testsuite/27_io/filesystem/path/query/has_root_name.cc:
+ Likewise.
+ * testsuite/27_io/filesystem/path/query/has_root_path.cc:
+ Likewise.
+ * testsuite/27_io/filesystem/path/query/has_stem.cc: Likewise.
+ * testsuite/27_io/filesystem/path/query/is_relative.cc: Likewise.
+ * testsuite/experimental/filesystem/operations/absolute.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/assign/copy.cc: Likewise.
+ * testsuite/experimental/filesystem/path/compare/path.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/construct/copy.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/decompose/extension.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/decompose/filename.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/decompose/parent_path.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/decompose/relative_path.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/decompose/root_directory.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/decompose/root_path.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/itr/traversal.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/modifiers/remove_filename.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/modifiers/replace_extension.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/modifiers/replace_filename.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/nonmember/hash_value.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/query/has_extension.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/query/has_filename.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/query/has_parent_path.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/query/has_relative_path.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/query/has_root_directory.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/query/has_root_name.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/query/has_root_path.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/query/has_stem.cc:
+ Likewise.
+ * testsuite/experimental/filesystem/path/query/is_relative.cc:
+ Likewise.
+
+2020-11-27 Jonathan Wakely <jwakely@redhat.com>
+
+ * src/c++98/locale.cc (locale::facet::_S_get_c_locale()):
+ Revert change to use __is_single_threaded.
+ * src/c++98/locale_init.cc (locale::_S_initialize()):
+ Likewise.
+
+2020-11-26 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/atomic_wait.h (_GLIBCXX_HAVE_ATOMIC_WAIT):
+ Define.
+ * include/bits/atomic_base.h: Check _GLIBCXX_HAVE_ATOMIC_WAIT.
+ * include/bits/atomic_timed_wait.h: Likewise.
+ * include/bits/semaphore_base.h: Likewise.
+ * include/std/atomic: Likewise.
+ * include/std/latch: Likewise.
+ * include/std/semaphore: Likewise.
+
+2020-11-26 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/latch: Depend on _GLIBCXX_HAS_GTHREADS and
+ _GLIBCXX_HAVE_LINUX_FUTEX.
+ * include/std/version (__cpp_lib_latch): Define conditionally.
+
+2020-11-26 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/lib/libstdc++.exp (check_effective_target_gthreads):
+ Call check_v3_target_gthreads not check_v3_target_gthreads_timed.
+
+2020-11-26 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/28_regex/algorithms/regex_match/basic/string_range_01_03.cc:
+ Add dg-timeout-factor directive.
+ * testsuite/28_regex/algorithms/regex_match/cstring_bracket_01.cc:
+ Likewise.
+ * testsuite/28_regex/algorithms/regex_match/ecma/char/backref.cc:
+ Likewise.
+ * testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/63199.cc:
+ Likewise.
+ * testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/anymatcher.cc:
+ Likewise.
+ * testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/cjk_match.cc:
+ Likewise.
+ * testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/hex.cc:
+ Likewise.
+ * testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc:
+ Likewise.
+ * testsuite/28_regex/algorithms/regex_search/61720.cc: Likewise.
+ * testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc:
+ Likewise.
+ * testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc:
+ Likewise.
+ * testsuite/28_regex/basic_regex/ctors/deduction.cc: Likewise.
+
+2020-11-26 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/lib/libstdc++.exp (libstdc++_init): Only set
+ tool_timeout if it hasn't been set by the user already.
+
+2020-11-26 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/97936
+ * testsuite/29_atomics/atomic/wait_notify/bool.cc: Fix missed
+ notifications by making the new thread wait until the parent
+ thread is waiting on the condition variable.
+ * testsuite/29_atomics/atomic/wait_notify/pointers.cc: Likewise.
+ * testsuite/29_atomics/atomic_flag/wait_notify/1.cc: Likewise.
+ * testsuite/29_atomics/atomic_ref/wait_notify.cc: Likewise.
+
+2020-11-26 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/18_support/96817.cc: Use new effective-target
+ keywords to select supported targets more effectively.
+ * testsuite/30_threads/call_once/66146.cc: Likewise.
+ * testsuite/lib/libstdc++.exp (check_effective_target_futex):
+ Define new proc.
+ (check_effective_target_gthreads): Define new proc to replace
+ dg-require-gthreads.
+
+2020-11-26 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * acinclude.m4 (GLIBCXX_ENABLE_LIBSTDCXX_TIME): Remove libposix4
+ references.
+ <solaris*>: Don't use -lrt any longer.
+ * configure: Regenerate.
+ * doc/xml/manual/configure.xml (--enable-libstdcxx-time=OPTION):
+ Remove libposix4 reference.
+
+2020-11-26 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/98001
+ * testsuite/ext/stdio_filebuf/char/79820.cc: Do not pass invalid
+ FILE* to constructor.
+
+2020-11-26 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/precompiled/stdc++.h: Add new headers.
+ * include/std/stop_token: Include <semaphore> unconditionally.
+
+2020-11-25 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/atomic_timed_wait.h (__cond_wait_until): Do not
+ perform redundant conversions to the same clock.
+
+2020-11-25 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/atomic_timed_wait.h (__cond_wait_until_impl):
+ Do not define when _GLIBCXX_HAVE_LINUX_FUTEX is defined. Use
+ __condvar and mutex instead of __gthread_cond_t and
+ unique_lock<mutex>.
+ (__cond_wait_until): Likewise. Fix test for return value of
+ __cond_wait_until_impl.
+ (__timed_waiters::_M_do_wait_until): Use __condvar instead
+ of __gthread_cond_t.
+ * include/bits/atomic_wait.h: Remove <bits/unique_lock.h>
+ include. Only include <bits/std_mutex.h> if not using futexes.
+ (__platform_wait_max_value): Remove unused variable.
+ (__waiters::lock_t): Use lock_guard instead of unique_lock.
+ (__waiters::_M_cv): Use __condvar instead of __gthread_cond_t.
+ (__waiters::_M_do_wait(__platform_wait_t)): Likewise.
+ (__waiters::_M_notify()): Likewise. Use notify_one() if not
+ asked to notify all.
+ * include/bits/std_mutex.h (__condvar): New type.
+ * include/std/condition_variable (condition_variable::_M_cond)
+ (condition_variable::wait_until): Use __condvar instead of
+ __gthread_cond_t.
+ * src/c++11/condition_variable.cc (condition_variable): Define
+ default constructor and destructor as defaulted.
+ (condition_variable::wait, condition_variable::notify_one)
+ (condition_variable::notify_all): Forward to corresponding
+ member function of __condvar.
+
+2020-11-25 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/97936
+ * testsuite/29_atomics/atomic/wait_notify/bool.cc: Re-eneable
+ test.
+ * testsuite/29_atomics/atomic/wait_notify/generic.cc: Likewise.
+ * testsuite/29_atomics/atomic/wait_notify/pointers.cc: Likewise.
+ * testsuite/29_atomics/atomic_flag/wait_notify/1.cc: Likewise.
+ * testsuite/29_atomics/atomic_float/wait_notify.cc: Likewise.
+ * testsuite/29_atomics/atomic_integral/wait_notify.cc: Likewise.
+ * testsuite/util/atomic/wait_notify_util.h: Fix missed
+ notifications by making the new thread wait until the parent
+ thread is waiting on the condition variable.
+
+2020-11-25 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/97935
+ * include/bits/iterator_concepts.h (__detail::__iter_without_category):
+ New helper concept.
+ (__iterator_traits::__cat): Use __detail::__iter_without_category.
+ * testsuite/24_iterators/associated_types/iterator.traits.cc: New test.
+
+2020-11-25 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/17_intro/names.cc: Do not test 'v' on AIX.
+
+2020-11-25 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/97936
+ * include/bits/atomic_wait.h (__platform_wait): Check errno,
+ not just the value of EAGAIN.
+ (__waiters::__waiters()): Fix name of data member.
+
+2020-11-25 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/97936
+ * include/bits/atomic_wait.h (__platform_wait): Return if futex
+ sets EAGAIN.
+ * testsuite/30_threads/latch/3.cc: Re-enable test.
+ * testsuite/30_threads/semaphore/try_acquire_until.cc: Likewise.
+
+2020-11-24 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/97936
+ PR libstdc++/97944
+ * testsuite/29_atomics/atomic_integral/wait_notify.cc: Disable.
+ Do not require pthreads, but add -pthread when appropriate.
+ * testsuite/30_threads/jthread/95989.cc: Likewise.
+ * testsuite/30_threads/latch/3.cc: Likewise.
+ * testsuite/30_threads/semaphore/try_acquire_until.cc: Likewise.
+
+2020-11-24 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/30_threads/jthread/95989.cc: Run all three test
+ functions, not just the first one twice.
+
+2020-11-24 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/67791
+ * src/c++11/thread.cc (thread::_M_start_thread(_State_ptr, void (*)())):
+ Check that gthreads is available before calling __gthread_create.
+
+2020-11-24 Jonathan Wakely <jwakely@redhat.com>
+
+ * src/c++98/locale.cc (locale::facet::_S_get_c_locale())
+ (locale::id::_M_id() const): Use __is_single_threaded.
+ * src/c++98/locale_init.cc (locale::_S_initialize()):
+ Likewise.
+
+2020-11-23 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/semaphore_base.h
+ (__platform_semaphore::_M_try_acquire_until): Fix type of
+ variable.
+
+2020-11-23 Stephan Bergmann <sbergman@redhat.com>
+
+ * include/bits/atomic_wait.h (__thread_relax, __thread_yield):
+ Add 'inline'.
+
+2020-11-23 Jonathan Wakely <jwakely@redhat.com>
+
+ * acinclude.m4 (GLIBCXX_CHECK_GTHREADS): Check for
+ * config.h.in: Regenerate.
+ * configure: Regenerate.
+ * include/bits/semaphore_base.h (_GLIBCXX_HAVE_POSIX_SEMAPHORE):
+ Check autoconf macro instead of defining it here.
+
+2020-11-23 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/atomic_wait.h: Do not define anything unless
+ gthreads or futexes are available.
+ * include/bits/atomic_timed_wait.h: Likewise.
+ * include/bits/semaphore_base.h: Likewise.
+ * include/std/semaphore: Likewise.
+ * include/bits/atomic_base.h (atomic_flag::wait)
+ (atomic_flag::notify_one, atomic_flag::notify_all)
+ (__atomic_base<I>::wait, __atomic_base<I>::notify_one)
+ (__atomic_base<I>::notify_all, __atomic_base<P*>::wait)
+ (__atomic_base<P*>::notify_one, __atomic_base<P*>::notify_all)
+ (__atomic_impl::wait, __atomic_impl::notify_one)
+ (__atomic_impl::notify_all, __atomic_float::wait)
+ (__atomic_float::notify_one, __atomic_float::notify_all)
+ (__atomic_ref::wait, __atomic_ref::notify_one)
+ (__atomic_ref::notify_all): Only define if gthreads or futexes
+ are available.
+ * include/std/atomic (atomic::wait, atomic::notify_one)
+ (atomic::notify_all): Likewise.
+ * include/std/version (__cpp_lib_semaphore): Define
+ conditionally.
+
+2020-11-23 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/97948
+ * testsuite/29_atomics/atomic_float/wait_notify.cc: Add options
+ for libatomic.
+ * testsuite/29_atomics/atomic_integral/wait_notify.cc: Likewise.
+ * testsuite/29_atomics/atomic_ref/wait_notify.cc: Likewise.
+
+2020-11-21 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/atomic_base.h (atomic_flag::wait): Use correct
+ type for __atomic_wait call.
+ * include/bits/atomic_timed_wait.h (__atomic_wait_until): Check
+ _GLIBCXX_HAVE_LINUX_FUTEX.
+ * include/bits/atomic_wait.h (__atomic_notify): Likewise.
+ * include/bits/semaphore_base.h (_GLIBCXX_HAVE_POSIX_SEMAPHORE):
+ Only define if SEM_VALUE_MAX or _POSIX_SEM_VALUE_MAX is defined.
+ * testsuite/29_atomics/atomic/wait_notify/bool.cc: Disable on
+ non-linux targes.
+ * testsuite/29_atomics/atomic/wait_notify/generic.cc: Likewise.
+ * testsuite/29_atomics/atomic/wait_notify/pointers.cc: Likewise.
+ * testsuite/29_atomics/atomic_flag/wait_notify/1.cc: Likewise.
+ * testsuite/29_atomics/atomic_float/wait_notify.cc: Likewise.
+
+2020-11-20 Thomas Rodgers <trodgers@redhat.com>
+
+ * include/Makefile.am (bits_headers): Add new header.
+ * include/Makefile.in: Regenerate.
+ * include/bits/atomic_base.h (__atomic_flag::wait): Define.
+ (__atomic_flag::notify_one): Likewise.
+ (__atomic_flag::notify_all): Likewise.
+ (__atomic_base<_Itp>::wait): Likewise.
+ (__atomic_base<_Itp>::notify_one): Likewise.
+ (__atomic_base<_Itp>::notify_all): Likewise.
+ (__atomic_base<_Ptp*>::wait): Likewise.
+ (__atomic_base<_Ptp*>::notify_one): Likewise.
+ (__atomic_base<_Ptp*>::notify_all): Likewise.
+ (__atomic_impl::wait): Likewise.
+ (__atomic_impl::notify_one): Likewise.
+ (__atomic_impl::notify_all): Likewise.
+ (__atomic_float<_Fp>::wait): Likewise.
+ (__atomic_float<_Fp>::notify_one): Likewise.
+ (__atomic_float<_Fp>::notify_all): Likewise.
+ (__atomic_ref<_Tp>::wait): Likewise.
+ (__atomic_ref<_Tp>::notify_one): Likewise.
+ (__atomic_ref<_Tp>::notify_all): Likewise.
+ (atomic_wait<_Tp>): Likewise.
+ (atomic_wait_explicit<_Tp>): Likewise.
+ (atomic_notify_one<_Tp>): Likewise.
+ (atomic_notify_all<_Tp>): Likewise.
+ * include/bits/atomic_wait.h: New file.
+ * include/bits/atomic_timed_wait.h: New file.
+ * include/bits/semaphore_base.h: New file.
+ * include/std/atomic (atomic<bool>::wait): Define.
+ (atomic<bool>::wait_one): Likewise.
+ (atomic<bool>::wait_all): Likewise.
+ (atomic<_Tp>::wait): Likewise.
+ (atomic<_Tp>::wait_one): Likewise.
+ (atomic<_Tp>::wait_all): Likewise.
+ (atomic<_Tp*>::wait): Likewise.
+ (atomic<_Tp*>::wait_one): Likewise.
+ (atomic<_Tp*>::wait_all): Likewise.
+ * include/std/latch: New file.
+ * include/std/semaphore: New file.
+ * include/std/version: Add __cpp_lib_semaphore and
+ __cpp_lib_latch defines.
+ * testsuite/29_atomics/atomic/wait_notify/bool.cc: New test.
+ * testsuite/29_atomics/atomic/wait_notify/pointers.cc: Likewise.
+ * testsuite/29_atomics/atomic/wait_notify/generic.cc: Liekwise.
+ * testsuite/29_atomics/atomic_flag/wait_notify/1.cc: Likewise.
+ * testsuite/29_atomics/atomic_float/wait_notify.cc: Likewise.
+ * testsuite/29_atomics/atomic_integral/wait_notify.cc: Likewise.
+ * testsuite/29_atomics/atomic_ref/wait_notify.cc: Likewise.
+ * testsuite/30_threads/semaphore/1.cc: New test.
+ * testsuite/30_threads/semaphore/2.cc: Likewise.
+ * testsuite/30_threads/semaphore/least_max_value_neg.cc: Likewise.
+ * testsuite/30_threads/semaphore/try_acquire.cc: Likewise.
+ * testsuite/30_threads/semaphore/try_acquire_for.cc: Likewise.
+ * testsuite/30_threads/semaphore/try_acquire_posix.cc: Likewise.
+ * testsuite/30_threads/semaphore/try_acquire_until.cc: Likewise.
+ * testsuite/30_threads/latch/1.cc: New test.
+ * testsuite/30_threads/latch/2.cc: New test.
+ * testsuite/30_threads/latch/3.cc: New test.
+ * testsuite/util/atomic/wait_notify_util.h: New File.
+
+2020-11-20 François Dumont <fdumont@gcc.gnu.org>
+
+ PR libstdc++/83938
+ * include/bits/stl_tempbuf.h (get_temporary_buffer): Change __len
+ computation in the loop to avoid truncation.
+ * include/bits/stl_algo.h:
+ (__inplace_merge): Take temporary buffer length from smallest range.
+ (__stable_sort): Limit temporary buffer length.
+ * testsuite/25_algorithms/inplace_merge/1.cc (test4): New.
+ * testsuite/performance/25_algorithms/stable_sort.cc: Test stable_sort
+ under different heap memory conditions.
+ * testsuite/performance/25_algorithms/inplace_merge.cc: New test.
+
+2020-11-20 François Dumont <fdumont@gcc.gnu.org>
+
+ * include/bits/move.h (_GLIBCXX_FWDREF): New.
+ * include/bits/stl_tree.h: Adapt to use latter.
+ (_Rb_tree<>::_M_clone_node): Add _MoveValue template parameter.
+ (_Rb_tree<>::_M_mbegin): New.
+ (_Rb_tree<>::_M_begin): Use latter.
+ (_Rb_tree<>::_M_copy): Add _MoveValues template parameter.
+ * testsuite/23_containers/map/allocator/move_cons.cc: New test.
+ * testsuite/23_containers/multimap/allocator/move_cons.cc: New test.
+ * testsuite/23_containers/multiset/allocator/move_cons.cc: New test.
+ * testsuite/23_containers/set/allocator/move_cons.cc: New test.
+
+2020-11-20 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/92546
+ * include/std/regex (pmr::smatch, pmr::wsmatch): Declare using
+ underlying __normal_iterator type, not nested typedef
+ basic_string::const_iterator.
+
+2020-11-19 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/95989
+ * config/os/gnu-linux/os_defines.h (_GLIBCXX_NATIVE_THREAD_ID):
+ Define new macro to get reliable thread ID.
+ * include/bits/std_thread.h: (this_thread::get_id): Use new
+ macro if it's defined.
+ * testsuite/30_threads/jthread/95989.cc: New test.
+ * testsuite/30_threads/this_thread/95989.cc: New test.
+
+2020-11-19 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/30_threads/async/async.cc: Include <thread>.
+ * testsuite/30_threads/future/members/93456.cc: Likewise.
+
+2020-11-19 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/92546
+ * include/Makefile.am: Add new <bits/std_thread.h> header.
+ * include/Makefile.in: Regenerate.
+ * include/std/future: Include new header instead of <thread>.
+ * include/std/stop_token: Include new header instead of
+ <bits/gthr.h>.
+ (stop_token::_S_yield()): Use this_thread::yield().
+ (_Stop_state_t::_M_requester): Change type to std::thread::id.
+ (_Stop_state_t::_M_request_stop()): Use this_thread::get_id().
+ (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Likewise.
+ Use __is_single_threaded() to decide whether to synchronize.
+ * include/std/thread (thread, operator==, this_thread::get_id)
+ (this_thread::yield): Move to new header.
+ (operator<=>, operator!=, operator<, operator<=, operator>)
+ (operator>=, hash<thread::id>, operator<<): Define even when
+ gthreads not available.
+ * src/c++11/thread.cc: Include <memory>.
+ * include/bits/std_thread.h: New file.
+ (thread, operator==, this_thread::get_id, this_thread::yield):
+ Define even when gthreads not available.
+ [!_GLIBCXX_HAS_GTHREADS] (thread::join, thread::detach)
+ (thread::hardware_concurrency): Define inline.
+
+2020-11-19 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/93421
+ PR libstdc++/93456
+ * src/c++11/futex.cc (syscall_time_t): New typedef for
+ the type of the syscall_timespec::tv_sec member.
+ (relative_timespec, _M_futex_wait_until)
+ (_M_futex_wait_until_steady): Use syscall_time_t in overflow
+ checks, not time_t.
+
+2020-11-18 Patrick Palka <ppalka@redhat.com>
+
+ * include/std/ranges (join_view::_Iterator::_M_satisfy): Uglify
+ local variable inner.
+ (join_view::_Iterator::operator->): Use _Inner_iter instead of
+ _Outer_iter in the function signature as per LWG 3500.
+ * testsuite/std/ranges/adaptors/join.cc (test08): Test it.
+
+2020-11-17 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/93421
+ * acinclude.m4 (GLIBCXX_ENABLE_LIBSTDCXX_TIME): Fail if struct
+ timespec isn't compatible with SYS_clock_gettime.
+ * configure: Regenerate.
+ * src/c++11/chrono.cc: Revert changes for time64 compatibility.
+ Add static_assert instead.
+ * src/c++11/futex.cc (_M_futex_wait_until_steady): Assume
+ SYS_clock_gettime can use struct timespec.
+
+2020-11-17 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/97869
+ * include/precompiled/stdc++.h: Include <coroutine>.
+ * include/std/version (__cpp_lib_span): Check __cpp_lib_concepts
+ before defining.
+
+2020-11-17 Patrick Palka <ppalka@redhat.com>
+
+ PR libstdc++/97828
+ * include/bits/ranges_algo.h (__search_n_fn::operator()): Check
+ random_access_iterator before using the backtracking
+ implementation. When the backwards scan fails prematurely,
+ reset __remainder appropriately.
+ * testsuite/25_algorithms/search_n/97828.cc: New test.
+
+2020-11-16 Jonathan Wakely <jwakely@redhat.com>
+
+ * src/Makefile.am (libstdc++-symbols.ver-sun): Remove -lrt from
+ arguments passed to make_sunver.pl script.
+ * src/Makefile.in: Regenerate.
+
+2020-11-15 Jason Merrill <jason@redhat.com>
+
+ * testsuite/20_util/result_of/sfinae_friendly_1.cc: Adjust.
+
+2020-11-13 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/93421
+ * src/c++11/chrono.cc [_GLIBCXX_USE_CLOCK_GETTIME_SYSCALL]
+ (syscall_timespec): Define a type suitable for SYS_clock_gettime
+ calls.
+ (system_clock::now(), steady_clock::now()): Use syscall_timespec
+ instead of timespec.
+ * src/c++11/futex.cc (syscall_timespec): Define a type suitable
+ for SYS_futex and SYS_clock_gettime calls.
+ (relative_timespec): Use syscall_timespec instead of timespec.
+ (__atomic_futex_unsigned_base::_M_futex_wait_until): Likewise.
+ (__atomic_futex_unsigned_base::_M_futex_wait_until_steady):
+ Likewise.
+
+2020-11-13 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/93456
+ * src/c++11/futex.cc (relative_timespec): Remove redundant check
+ negative values.
+ * testsuite/30_threads/future/members/wait_until_overflow.cc: Moved to...
+ * testsuite/30_threads/future/members/93456.cc: ...here.
+
+2020-11-13 Jonathan Wakely <jwakely@redhat.com>
+
+ * src/c++11/futex.cc (relative_timespec): Add [[unlikely]]
+ attributes.
+ (__atomic_futex_unsigned_base::_M_futex_wait_until)
+ (__atomic_futex_unsigned_base::_M_futex_wait_until_steady):
+ Check for overflow.
+ * testsuite/30_threads/future/members/wait_until_overflow.cc:
+ New test.
+
+2020-11-13 Jonathan Wakely <jwakely@redhat.com>
+
+ * src/c++11/futex.cc (relative_timespec): New function to
+ create relative time from two absolute times.
+ (__atomic_futex_unsigned_base::_M_futex_wait_until)
+ (__atomic_futex_unsigned_base::_M_futex_wait_until_steady):
+ Use relative_timespec.
+
+2020-11-13 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/30_threads/future/members/poll.cc: Require gthreads
+ and add -pthread for targets that require it. Relax required
+ ratio of wait_for calls before/after the future is ready.
+
+2020-11-12 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/future (future::wait_for): Do not wait for
+ durations less than or equal to zero.
+ * src/c++11/futex.cc (_M_futex_wait_until)
+ (_M_futex_wait_until_steady): Do not wait for timeouts before
+ the epoch.
+ * testsuite/30_threads/future/members/poll.cc: New test.
+
+2020-11-12 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/ext/numeric_traits.h (__numeric_traits): Change
+ primary template to always derive from __numeric_traits_integer.
+ (__numeric_traits<float>, __numeric_traits<double>)
+ (__numeric_traits<long double>): Add explicit specializations.
+
+2020-11-12 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/97798
+ * include/ext/numeric_traits.h (__glibcxx_signed)
+ (__glibcxx_digits, __glibcxx_min, __glibcxx_max): Remove
+ macros.
+ (__is_integer_nonstrict::__width): Define new constant.
+ (__numeric_traits_integer): Define constants in terms of each
+ other and __is_integer_nonstrict::__width, rather than the
+ removed macros.
+ (_GLIBCXX_INT_N_TRAITS): Macro to define explicit
+ specializations for non-standard integer types.
+
+2020-11-11 Jonathan Yong <10walls@gmail.com>
+
+ * acinclude.m4 (GLIBCXX_CHECK_LINKER_FEATURES): Exclude
+ cygwin and mingw from relro linker test.
+ * configure: Regenerate.
+
+2020-11-11 Paul Scharnofske <asynts@gmail.com>
+
+ * include/std/thread (jthread::operator=(jthread&&)): Transfer
+ any existing state to a temporary that will request a stop and
+ then join.
+ * testsuite/30_threads/jthread/jthread.cc: Test move assignment.
+
+2020-11-11 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/stop_token (_Stop_state_t::_M_requester): Define
+ new struct with members to store and check the thread ID.
+ (_Stop_state_t::_M_request_stop()): Use _M_requester._M_set().
+ (_Stop_state_t::_M_remove_callback(_Stop_cb*)): Use
+ _M_requester._M_is_current_thread().
+
+2020-11-11 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/ostream (__syncbuf_base): New class template.
+ (emit_on_flush, noemit_on_flush, flush_emit): New manipulators.
+ * include/std/syncstream (basic_syncbuf): Derive from
+ __syncbuf_base instead of basic_streambuf.
+ (basic_syncbuf::operator=): Remove self-assignment check.
+ (basic_syncbuf::swap): Remove self-swap check.
+ (basic_syncbuf::emit): Do not skip pubsync() call if sequence
+ is empty.
+ (basic_syncbuf::sync): Remove no-op pubsync on stringbuf.
+ (basic_syncbuf::overflow): Define override.
+ * testsuite/27_io/basic_syncstream/basic_ops/1.cc: Test
+ basic_osyncstream::put(char_type).
+ * testsuite/27_io/basic_ostream/emit/1.cc: New test.
+
+2020-11-10 Jonathan Wakely <jwakely@redhat.com>
+
+ * config/locale/generic/c_locale.cc (__set_C_locale()): New function
+ to set the "C" locale and return the name of the previous locale.
+ (__convert_to_v<float>, __convert_to_v<double>)
+ (__convert_to_v<long double>): Use __set_C_locale and set failbit on
+ error.
+
+2020-11-10 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/sstream (basic_stringbug, basic_istringstream)
+ (basic_ostringstream, basic_stringstream): Reorder C++20
+ constructors to be declared next to other constructors.
+
+2020-11-10 Jonathan Wakely <jwakely@redhat.com>
+
+ * config/abi/pre/gnu.ver (GLIBCXX_3.4.21): Tighten patterns.
+ (GLIBCXX_3.4.29): Export new symbols.
+ * include/bits/alloc_traits.h (__allocator_like): New concept.
+ * include/std/sstream (basic_stringbuf::swap): Add exception
+ specification.
+ (basic_stringbuf::str() const): Add ref-qualifier. Use new
+ _M_high_mark function.
+ (basic_stringbuf::str(const SAlloc&) const): Define new function.
+ (basic_stringbuf::str() &&): Likewise.
+ (basic_stringbuf::str(const basic_string<C,T,SAlloc>&)):
+ Likewise.
+ (basic_stringbuf::str(basic_string<C,T,Alloc>&&)): Likewise.
+ (basic_stringbuf::view() const): Use _M_high_mark.
+ (basic_istringstream::str, basic_ostringstream::str)
+ (basic_stringstream::str): Define new overloads.
+ * src/c++20/sstream-inst.cc (basic_stringbuf::str)
+ (basic_istringstream::str, basic_ostringstream::str)
+ (basic_stringstream::str): Explicit instantiation definitions
+ for new overloads.
+ * testsuite/27_io/basic_istringstream/view/char/1.cc: Add more
+ checks.
+ * testsuite/27_io/basic_istringstream/view/wchar_t/1.cc:
+ Likewise.
+ * testsuite/27_io/basic_ostringstream/view/char/1.cc:
+ Likewise.
+ * testsuite/27_io/basic_ostringstream/view/wchar_t/1.cc:
+ Likewise.
+ * testsuite/27_io/basic_stringstream/view/char/1.cc:
+ Likewise.
+ * testsuite/27_io/basic_stringstream/view/wchar_t/1.cc:
+ Likewise.
+ * testsuite/27_io/basic_istringstream/str/char/2.cc: New test.
+ * testsuite/27_io/basic_istringstream/str/wchar_t/2.cc: New test.
+ * testsuite/27_io/basic_ostringstream/str/char/3.cc: New test.
+ * testsuite/27_io/basic_ostringstream/str/wchar_t/3.cc: New test.
+ * testsuite/27_io/basic_stringbuf/str/char/4.cc: New test.
+ * testsuite/27_io/basic_stringbuf/str/wchar_t/4.cc: New test.
+ * testsuite/27_io/basic_stringstream/str/char/5.cc: New test.
+ * testsuite/27_io/basic_stringstream/str/wchar_t/5.cc.cc: New test.
+
+2020-11-10 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/97415
+ * include/std/sstream (basic_stringbuf::_M_update_egptr)
+ (basic_stringbuf::__xfer_bufptrs::__xfer_bufptrs): Check for
+ null before comparing pointers.
+
2020-11-09 François Dumont <fdumont@gcc.gnu.org>
* include/debug/array: Remove.
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index b9452dd..fcd9ea3 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -273,13 +273,22 @@ AC_DEFUN([GLIBCXX_CHECK_LINKER_FEATURES], [
# Note this is only for shared objects.
ac_ld_relro=no
if test x"$with_gnu_ld" = x"yes"; then
- AC_MSG_CHECKING([for ld that supports -Wl,-z,relro])
- cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
- if test -n "$cxx_z_relo"; then
- OPT_LDFLAGS="-Wl,-z,relro"
- ac_ld_relro=yes
- fi
- AC_MSG_RESULT($ac_ld_relro)
+ # cygwin and mingw uses PE, which has no ELF relro support,
+ # multi target ld may confuse configure machinery
+ case "$host" in
+ *-*-cygwin*)
+ ;;
+ *-*-mingw*)
+ ;;
+ *)
+ AC_MSG_CHECKING([for ld that supports -Wl,-z,relro])
+ cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
+ if test -n "$cxx_z_relo"; then
+ OPT_LDFLAGS="-Wl,-z,relro"
+ ac_ld_relro=yes
+ fi
+ AC_MSG_RESULT($ac_ld_relro)
+ esac
fi
# Set linker optimization flags.
@@ -1372,8 +1381,7 @@ dnl
dnl --enable-libstdcxx-time
dnl --enable-libstdcxx-time=yes
dnl checks for the availability of monotonic and realtime clocks,
-dnl nanosleep and sched_yield in libc and libposix4 and, if needed,
-dnl links in the latter.
+dnl nanosleep and sched_yield in libc.
dnl --enable-libstdcxx-time=rt
dnl also searches (and, if needed, links) librt. Note that this is
dnl not always desirable because, in glibc 2.16 and earlier, for
@@ -1446,7 +1454,6 @@ AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_TIME], [
ac_has_nanosleep=yes
;;
solaris*)
- GLIBCXX_LIBS="$GLIBCXX_LIBS -lrt"
ac_has_clock_monotonic=yes
ac_has_clock_realtime=yes
ac_has_nanosleep=yes
@@ -1460,11 +1467,11 @@ AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_TIME], [
elif test x"$enable_libstdcxx_time" != x"no"; then
if test x"$enable_libstdcxx_time" = x"rt"; then
- AC_SEARCH_LIBS(clock_gettime, [rt posix4])
- AC_SEARCH_LIBS(nanosleep, [rt posix4])
+ AC_SEARCH_LIBS(clock_gettime, [rt])
+ AC_SEARCH_LIBS(nanosleep, [rt])
else
- AC_SEARCH_LIBS(clock_gettime, [posix4])
- AC_SEARCH_LIBS(nanosleep, [posix4])
+ AC_CHECK_FUNC(clock_gettime)
+ AC_CHECK_FUNC(nanosleep)
fi
case "$ac_cv_search_clock_gettime" in
@@ -1476,13 +1483,9 @@ AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_TIME], [
;;
esac
- AC_SEARCH_LIBS(sched_yield, [rt posix4])
+ AC_SEARCH_LIBS(sched_yield, [rt])
case "$ac_cv_search_sched_yield" in
- -lposix4*)
- GLIBCXX_LIBS="$GLIBCXX_LIBS $ac_cv_search_sched_yield"
- ac_has_sched_yield=yes
- ;;
-lrt*)
if test x"$enable_libstdcxx_time" = x"rt"; then
GLIBCXX_LIBS="$GLIBCXX_LIBS $ac_cv_search_sched_yield"
@@ -1552,13 +1555,34 @@ AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_TIME], [
#endif
syscall(SYS_clock_gettime, CLOCK_MONOTONIC, &tp);
syscall(SYS_clock_gettime, CLOCK_REALTIME, &tp);
- ], [ac_has_clock_monotonic_syscall=yes], [ac_has_clock_monotonic_syscall=no])
- AC_MSG_RESULT($ac_has_clock_monotonic_syscall)
- if test x"$ac_has_clock_monotonic_syscall" = x"yes"; then
+ ], [ac_has_clock_gettime_syscall=yes], [ac_has_clock_gettime_syscall=no])
+ AC_MSG_RESULT($ac_has_clock_gettime_syscall)
+ if test x"$ac_has_clock_gettime_syscall" = x"yes"; then
AC_DEFINE(_GLIBCXX_USE_CLOCK_GETTIME_SYSCALL, 1,
- [ Defined if clock_gettime syscall has monotonic and realtime clock support. ])
+ [Defined if clock_gettime syscall has monotonic and realtime clock support. ])
ac_has_clock_monotonic=yes
ac_has_clock_realtime=yes
+ AC_MSG_CHECKING([for struct timespec that matches syscall])
+ AC_TRY_COMPILE(
+ [#include <time.h>
+ #include <sys/syscall.h>
+ ],
+ [#ifdef SYS_clock_gettime64
+ #if SYS_clock_gettime64 != SYS_clock_gettime
+ // We need to use SYS_clock_gettime and libc appears to
+ // also know about the SYS_clock_gettime64 syscall.
+ // Check that userspace doesn't use time64 version of timespec.
+ static_assert(sizeof(timespec::tv_sec) == sizeof(long),
+ "struct timespec must be compatible with SYS_clock_gettime");
+ #endif
+ #endif
+ ],
+ [ac_timespec_matches_syscall=yes],
+ [ac_timespec_matches_syscall=no])
+ AC_MSG_RESULT($ac_timespec_matches_syscall)
+ if test x"$ac_timespec_matches_syscall" = no; then
+ AC_MSG_ERROR([struct timespec is not compatible with SYS_clock_gettime, please report a bug to http://gcc.gnu.org/bugzilla])
+ fi
fi;;
esac
fi
@@ -4059,6 +4083,43 @@ AC_DEFUN([GLIBCXX_CHECK_GTHREADS], [
fi
fi
+ AC_CHECK_HEADER(semaphore.h, [
+ AC_MSG_CHECKING([for POSIX Semaphores and sem_timedwait])
+ AC_TRY_COMPILE([
+ #include <unistd.h>
+ #include <semaphore.h>
+ #include <limits.h>
+ ],
+ [
+ #if !defined _POSIX_TIMEOUTS || _POSIX_TIMEOUTS <= 0
+ # error "POSIX Timeouts option not supported"
+ #elif !defined _POSIX_SEMAPHORES || _POSIX_SEMAPHORES <= 0
+ # error "POSIX Semaphores option not supported"
+ #else
+ #if defined SEM_VALUE_MAX
+ constexpr int sem_value_max = SEM_VALUE_MAX;
+ #elif defined _POSIX_SEM_VALUE_MAX
+ constexpr int sem_value_max = _POSIX_SEM_VALUE_MAX;
+ #else
+ # error "SEM_VALUE_MAX not available"
+ #endif
+ sem_t sem;
+ sem_init(&sem, 0, sem_value_max);
+ struct timespec ts = { 0 };
+ sem_timedwait(&sem, &ts);
+ #endif
+ ],
+ [ac_have_posix_semaphore=yes],
+ [ac_have_posix_semaphore=no])],
+ [ac_have_posix_semaphore=no])
+
+ if test $ac_have_posix_semaphore = yes ; then
+ AC_DEFINE(_GLIBCXX_HAVE_POSIX_SEMAPHORE,
+ 1,
+ [Define to 1 if POSIX Semaphores with sem_timedwait are available in <semaphore.h>.])
+ fi
+ AC_MSG_RESULT([$ac_have_posix_semaphore])
+
CXXFLAGS="$ac_save_CXXFLAGS"
AC_LANG_RESTORE
])
diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
index 8ae3e0f..72faabf 100644
--- a/libstdc++-v3/config.h.in
+++ b/libstdc++-v3/config.h.in
@@ -872,6 +872,10 @@
/* Define if gthreads library is available. */
#undef _GLIBCXX_HAS_GTHREADS
+/* Define to 1 if POSIX Semaphores with sem_timedwait are available in
+ <semaphore.h>. */
+#undef _GLIBCXX_HAVE_POSIX_SEMAPHORE
+
/* Define to 1 if a full hosted library is built, or 0 if freestanding. */
#undef _GLIBCXX_HOSTED
diff --git a/libstdc++-v3/config/abi/post/powerpc-linux-gnu/baseline_symbols.txt b/libstdc++-v3/config/abi/post/powerpc-linux-gnu/baseline_symbols.txt
index 5cb72bb..63a58b0 100644
--- a/libstdc++-v3/config/abi/post/powerpc-linux-gnu/baseline_symbols.txt
+++ b/libstdc++-v3/config/abi/post/powerpc-linux-gnu/baseline_symbols.txt
@@ -2208,16 +2208,20 @@ 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_policyE2EEC2EOS5_@@GLIBCXX_3.4.28
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_policyE2EEC2EOS4_@@GLIBCXX_3.4.28
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_policyE2EEC2EOS6_@@GLIBCXX_3.4.28
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_policyE2EEC2EOS5_@@GLIBCXX_3.4.28
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
@@ -3191,12 +3195,18 @@ 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:_ZNSt3pmr15memory_resourceD0Ev@@GLIBCXX_3.4.28
+FUNC:_ZNSt3pmr15memory_resourceD1Ev@@GLIBCXX_3.4.28
+FUNC:_ZNSt3pmr15memory_resourceD2Ev@@GLIBCXX_3.4.28
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_bufferEjj@@GLIBCXX_3.4.26
FUNC:_ZNSt3pmr25monotonic_buffer_resource18_M_release_buffersEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr25monotonic_buffer_resourceD0Ev@@GLIBCXX_3.4.28
+FUNC:_ZNSt3pmr25monotonic_buffer_resourceD1Ev@@GLIBCXX_3.4.28
+FUNC:_ZNSt3pmr25monotonic_buffer_resourceD2Ev@@GLIBCXX_3.4.28
FUNC:_ZNSt3pmr26synchronized_pool_resource11do_allocateEjj@@GLIBCXX_3.4.26
FUNC:_ZNSt3pmr26synchronized_pool_resource13do_deallocateEPvjj@@GLIBCXX_3.4.26
FUNC:_ZNSt3pmr26synchronized_pool_resource7releaseEv@@GLIBCXX_3.4.26
@@ -4642,6 +4652,7 @@ 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.28
OBJECT:0:GLIBCXX_3.4.3
OBJECT:0:GLIBCXX_3.4.4
OBJECT:0:GLIBCXX_3.4.5
@@ -4680,6 +4691,7 @@ OBJECT:12:_ZTINSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11cha
OBJECT:12:_ZTINSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4
OBJECT:12:_ZTINSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_LDBL_3.4
OBJECT:12:_ZTINSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4
+OBJECT:12:_ZTINSt3pmr25monotonic_buffer_resourceE@@GLIBCXX_3.4.28
OBJECT:12:_ZTINSt3pmr26synchronized_pool_resourceE@@GLIBCXX_3.4.26
OBJECT:12:_ZTINSt3pmr28unsynchronized_pool_resourceE@@GLIBCXX_3.4.26
OBJECT:12:_ZTINSt7__cxx1114collate_bynameIcEE@@GLIBCXX_3.4.21
@@ -5320,6 +5332,7 @@ OBJECT:25:_ZTSNSt7__cxx118messagesIwEE@@GLIBCXX_3.4.21
OBJECT:25:_ZTSNSt7__cxx118numpunctIcEE@@GLIBCXX_3.4.21
OBJECT:25:_ZTSNSt7__cxx118numpunctIwEE@@GLIBCXX_3.4.21
OBJECT:25:_ZTSSt20bad_array_new_length@@CXXABI_1.3.8
+OBJECT:26:_ZTSNSt3pmr15memory_resourceE@@GLIBCXX_3.4.28
OBJECT:27:_ZTSSt19__codecvt_utf8_baseIwE@@GLIBCXX_3.4.21
OBJECT:28:_ZTSSt19__codecvt_utf8_baseIDiE@@GLIBCXX_3.4.21
OBJECT:28:_ZTSSt19__codecvt_utf8_baseIDsE@@GLIBCXX_3.4.21
@@ -5332,6 +5345,8 @@ OBJECT:28:_ZTVNSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11cha
OBJECT:28:_ZTVNSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4
OBJECT:28:_ZTVNSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_LDBL_3.4
OBJECT:28:_ZTVNSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4
+OBJECT:28:_ZTVNSt3pmr15memory_resourceE@@GLIBCXX_3.4.28
+OBJECT:28:_ZTVNSt3pmr25monotonic_buffer_resourceE@@GLIBCXX_3.4.28
OBJECT:28:_ZTVNSt7__cxx1114collate_bynameIcEE@@GLIBCXX_3.4.21
OBJECT:28:_ZTVNSt7__cxx1114collate_bynameIwEE@@GLIBCXX_3.4.21
OBJECT:28:_ZTVNSt7__cxx1115messages_bynameIcEE@@GLIBCXX_3.4.21
@@ -5439,6 +5454,7 @@ OBJECT:34:_ZTSSt25__codecvt_utf8_utf16_baseIDsE@@GLIBCXX_3.4.21
OBJECT:34:_ZTSSt9basic_iosIcSt11char_traitsIcEE@@GLIBCXX_3.4
OBJECT:34:_ZTSSt9basic_iosIwSt11char_traitsIwEE@@GLIBCXX_3.4
OBJECT:36:_ZTSN10__cxxabiv119__pointer_type_infoE@@CXXABI_1.3
+OBJECT:36:_ZTSNSt3pmr25monotonic_buffer_resourceE@@GLIBCXX_3.4.28
OBJECT:36:_ZTSSt14codecvt_bynameIcc11__mbstate_tE@@GLIBCXX_3.4
OBJECT:36:_ZTSSt14codecvt_bynameIwc11__mbstate_tE@@GLIBCXX_3.4
OBJECT:36:_ZTVN10__cxxabiv117__pbase_type_infoE@@CXXABI_1.3
@@ -6053,6 +6069,7 @@ OBJECT:8:_ZTIN10__cxxabiv119__foreign_exceptionE@@CXXABI_1.3.2
OBJECT:8:_ZTINSt13__future_base11_State_baseE@@GLIBCXX_3.4.15
OBJECT:8:_ZTINSt13__future_base12_Result_baseE@@GLIBCXX_3.4.15
OBJECT:8:_ZTINSt3_V214error_categoryE@@GLIBCXX_3.4.21
+OBJECT:8:_ZTINSt3pmr15memory_resourceE@@GLIBCXX_3.4.28
OBJECT:8:_ZTINSt6locale5facetE@@GLIBCXX_3.4
OBJECT:8:_ZTINSt6thread6_StateE@@GLIBCXX_3.4.22
OBJECT:8:_ZTISt10ctype_base@@GLIBCXX_3.4
diff --git a/libstdc++-v3/config/abi/post/powerpc64-linux-gnu/32/baseline_symbols.txt b/libstdc++-v3/config/abi/post/powerpc64-linux-gnu/32/baseline_symbols.txt
index 5cb72bb..63a58b0 100644
--- a/libstdc++-v3/config/abi/post/powerpc64-linux-gnu/32/baseline_symbols.txt
+++ b/libstdc++-v3/config/abi/post/powerpc64-linux-gnu/32/baseline_symbols.txt
@@ -2208,16 +2208,20 @@ 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_policyE2EEC2EOS5_@@GLIBCXX_3.4.28
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_policyE2EEC2EOS4_@@GLIBCXX_3.4.28
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_policyE2EEC2EOS6_@@GLIBCXX_3.4.28
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_policyE2EEC2EOS5_@@GLIBCXX_3.4.28
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
@@ -3191,12 +3195,18 @@ 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:_ZNSt3pmr15memory_resourceD0Ev@@GLIBCXX_3.4.28
+FUNC:_ZNSt3pmr15memory_resourceD1Ev@@GLIBCXX_3.4.28
+FUNC:_ZNSt3pmr15memory_resourceD2Ev@@GLIBCXX_3.4.28
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_bufferEjj@@GLIBCXX_3.4.26
FUNC:_ZNSt3pmr25monotonic_buffer_resource18_M_release_buffersEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr25monotonic_buffer_resourceD0Ev@@GLIBCXX_3.4.28
+FUNC:_ZNSt3pmr25monotonic_buffer_resourceD1Ev@@GLIBCXX_3.4.28
+FUNC:_ZNSt3pmr25monotonic_buffer_resourceD2Ev@@GLIBCXX_3.4.28
FUNC:_ZNSt3pmr26synchronized_pool_resource11do_allocateEjj@@GLIBCXX_3.4.26
FUNC:_ZNSt3pmr26synchronized_pool_resource13do_deallocateEPvjj@@GLIBCXX_3.4.26
FUNC:_ZNSt3pmr26synchronized_pool_resource7releaseEv@@GLIBCXX_3.4.26
@@ -4642,6 +4652,7 @@ 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.28
OBJECT:0:GLIBCXX_3.4.3
OBJECT:0:GLIBCXX_3.4.4
OBJECT:0:GLIBCXX_3.4.5
@@ -4680,6 +4691,7 @@ OBJECT:12:_ZTINSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11cha
OBJECT:12:_ZTINSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4
OBJECT:12:_ZTINSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_LDBL_3.4
OBJECT:12:_ZTINSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4
+OBJECT:12:_ZTINSt3pmr25monotonic_buffer_resourceE@@GLIBCXX_3.4.28
OBJECT:12:_ZTINSt3pmr26synchronized_pool_resourceE@@GLIBCXX_3.4.26
OBJECT:12:_ZTINSt3pmr28unsynchronized_pool_resourceE@@GLIBCXX_3.4.26
OBJECT:12:_ZTINSt7__cxx1114collate_bynameIcEE@@GLIBCXX_3.4.21
@@ -5320,6 +5332,7 @@ OBJECT:25:_ZTSNSt7__cxx118messagesIwEE@@GLIBCXX_3.4.21
OBJECT:25:_ZTSNSt7__cxx118numpunctIcEE@@GLIBCXX_3.4.21
OBJECT:25:_ZTSNSt7__cxx118numpunctIwEE@@GLIBCXX_3.4.21
OBJECT:25:_ZTSSt20bad_array_new_length@@CXXABI_1.3.8
+OBJECT:26:_ZTSNSt3pmr15memory_resourceE@@GLIBCXX_3.4.28
OBJECT:27:_ZTSSt19__codecvt_utf8_baseIwE@@GLIBCXX_3.4.21
OBJECT:28:_ZTSSt19__codecvt_utf8_baseIDiE@@GLIBCXX_3.4.21
OBJECT:28:_ZTSSt19__codecvt_utf8_baseIDsE@@GLIBCXX_3.4.21
@@ -5332,6 +5345,8 @@ OBJECT:28:_ZTVNSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11cha
OBJECT:28:_ZTVNSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4
OBJECT:28:_ZTVNSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_LDBL_3.4
OBJECT:28:_ZTVNSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4
+OBJECT:28:_ZTVNSt3pmr15memory_resourceE@@GLIBCXX_3.4.28
+OBJECT:28:_ZTVNSt3pmr25monotonic_buffer_resourceE@@GLIBCXX_3.4.28
OBJECT:28:_ZTVNSt7__cxx1114collate_bynameIcEE@@GLIBCXX_3.4.21
OBJECT:28:_ZTVNSt7__cxx1114collate_bynameIwEE@@GLIBCXX_3.4.21
OBJECT:28:_ZTVNSt7__cxx1115messages_bynameIcEE@@GLIBCXX_3.4.21
@@ -5439,6 +5454,7 @@ OBJECT:34:_ZTSSt25__codecvt_utf8_utf16_baseIDsE@@GLIBCXX_3.4.21
OBJECT:34:_ZTSSt9basic_iosIcSt11char_traitsIcEE@@GLIBCXX_3.4
OBJECT:34:_ZTSSt9basic_iosIwSt11char_traitsIwEE@@GLIBCXX_3.4
OBJECT:36:_ZTSN10__cxxabiv119__pointer_type_infoE@@CXXABI_1.3
+OBJECT:36:_ZTSNSt3pmr25monotonic_buffer_resourceE@@GLIBCXX_3.4.28
OBJECT:36:_ZTSSt14codecvt_bynameIcc11__mbstate_tE@@GLIBCXX_3.4
OBJECT:36:_ZTSSt14codecvt_bynameIwc11__mbstate_tE@@GLIBCXX_3.4
OBJECT:36:_ZTVN10__cxxabiv117__pbase_type_infoE@@CXXABI_1.3
@@ -6053,6 +6069,7 @@ OBJECT:8:_ZTIN10__cxxabiv119__foreign_exceptionE@@CXXABI_1.3.2
OBJECT:8:_ZTINSt13__future_base11_State_baseE@@GLIBCXX_3.4.15
OBJECT:8:_ZTINSt13__future_base12_Result_baseE@@GLIBCXX_3.4.15
OBJECT:8:_ZTINSt3_V214error_categoryE@@GLIBCXX_3.4.21
+OBJECT:8:_ZTINSt3pmr15memory_resourceE@@GLIBCXX_3.4.28
OBJECT:8:_ZTINSt6locale5facetE@@GLIBCXX_3.4
OBJECT:8:_ZTINSt6thread6_StateE@@GLIBCXX_3.4.22
OBJECT:8:_ZTISt10ctype_base@@GLIBCXX_3.4
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index 2d0f87a..46769db 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -1776,14 +1776,16 @@ GLIBCXX_3.4.21 {
_ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EED[012]Ev;
_ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]EOS4_ONS4_14__xfer_bufptrsE;
_ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]14__xfer_bufptrs[CD][12]*;
- _ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE[a1346789]*;
+ _ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE[a146789]*;
+ _ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE3strERK*;
# _ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]*;
_ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]EOS4_;
_ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]EOSa*;
_ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ERKNS_12basic_stringI[cw]S2_S3_EESt13_Ios_Openmode;
_ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ESt13_Ios_Openmode;
_ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EED[012]Ev;
- _ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE[a34]*;
+ _ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE[a4]*;
+ _ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3strERK*;
# _ZNSt7__cxx1119basic_istringstreamI[cw]St11char_traitsI[cw]*;
# _ZNSt7__cxx1119basic_ostringstreamI[cw]St11char_traitsI[cw]*;
_ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]EOS4_;
@@ -1791,7 +1793,8 @@ GLIBCXX_3.4.21 {
_ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ERKNS_12basic_stringI[cw]S2_S3_EESt13_Ios_Openmode;
_ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ESt13_Ios_Openmode;
_ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EED[012]Ev;
- _ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE[a34]*;
+ _ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE[a4]*;
+ _ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3strERK*;
_ZNKSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEv;
_ZNKSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEv;
_ZNKSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE5rdbufEv;
@@ -2354,6 +2357,10 @@ GLIBCXX_3.4.29 {
# basic_stringbuf::view()
_ZNKSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE4viewEv;
+ # basic_stringbuf::str
+ _ZNOSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEv;
+ _ZNKRSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEv;
+ _ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEONS_12basic_stringI[cw]S2_S3_EE;
# basic_[io]stringstream::basic_[io]stringstream(basic_string&&, ios_base::openmode)
_ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]EONS_12basic_stringI[cw]S2_S3_EESt13_Ios_Openmode;
@@ -2363,6 +2370,10 @@ GLIBCXX_3.4.29 {
# basic_[io]stringstream::view()
_ZNKSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE4viewEv;
+ # basic_[io]stringstream::str
+ _ZNOSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEv;
+ _ZNKRSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEv;
+ _ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEONS_12basic_stringI[cw]S2_S3_EE;
# basic_stringstream::basic_stringstream(basic_string&&, ios_base::openmode)
_ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]EONS_12basic_stringI[cw]S2_S3_EESt13_Ios_Openmode;
@@ -2372,6 +2383,10 @@ GLIBCXX_3.4.29 {
# basic_stringstream::view()
_ZNKSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE4viewEv;
+ # basic_stringstream::str
+ _ZNOSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEv;
+ _ZNKRSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEv;
+ _ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEONS_12basic_stringI[cw]S2_S3_EE;
# std::once_flag::_M_activate()
_ZNSt9once_flag11_M_activateEv;
diff --git a/libstdc++-v3/config/locale/generic/c_locale.cc b/libstdc++-v3/config/locale/generic/c_locale.cc
index 61ead91..648b8e1 100644
--- a/libstdc++-v3/config/locale/generic/c_locale.cc
+++ b/libstdc++-v3/config/locale/generic/c_locale.cc
@@ -52,6 +52,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
~_Save_errno() { if (errno == 0) errno = _M_errno; }
int _M_errno;
};
+
+ // calls setlocale(LC_ALL, "C") and returns a string containing the old
+ // locale name. Caller must delete[] the string. Returns NULL on error.
+ const char*
+ __set_C_locale()
+ {
+ char* __old = setlocale(LC_ALL, 0);
+ const size_t __len = strlen(__old) + 1;
+ char* __sav = new(nothrow) char[__len];
+ if (__sav)
+ {
+ memcpy(__sav, __old, __len);
+ setlocale(LC_ALL, "C");
+ }
+ return __sav;
+ }
}
template<>
@@ -60,11 +76,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const __c_locale&) throw()
{
// Assumes __s formatted for "C" locale.
- char* __old = setlocale(LC_ALL, 0);
- const size_t __len = strlen(__old) + 1;
- char* __sav = new char[__len];
- memcpy(__sav, __old, __len);
- setlocale(LC_ALL, "C");
+ const char* __sav = __set_C_locale();
+ if (!__sav)
+ {
+ __err = ios_base::failbit;
+ return;
+ }
char* __sanity;
bool __overflow = false;
@@ -125,11 +142,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const __c_locale&) throw()
{
// Assumes __s formatted for "C" locale.
- char* __old = setlocale(LC_ALL, 0);
- const size_t __len = strlen(__old) + 1;
- char* __sav = new char[__len];
- memcpy(__sav, __old, __len);
- setlocale(LC_ALL, "C");
+ const char* __sav = __set_C_locale();
+ if (!__sav)
+ {
+ __err = ios_base::failbit;
+ return;
+ }
char* __sanity;
#if !__DBL_HAS_INFINITY__
@@ -170,11 +188,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
ios_base::iostate& __err, const __c_locale&) throw()
{
// Assumes __s formatted for "C" locale.
- char* __old = setlocale(LC_ALL, 0);
- const size_t __len = strlen(__old) + 1;
- char* __sav = new char[__len];
- memcpy(__sav, __old, __len);
- setlocale(LC_ALL, "C");
+ const char* __sav = __set_C_locale();
+ if (!__sav)
+ {
+ __err = ios_base::failbit;
+ return;
+ }
#if !__LDBL_HAS_INFINITY__
const _Save_errno __save_errno;
diff --git a/libstdc++-v3/config/os/gnu-linux/os_defines.h b/libstdc++-v3/config/os/gnu-linux/os_defines.h
index f821486..01bfa9d 100644
--- a/libstdc++-v3/config/os/gnu-linux/os_defines.h
+++ b/libstdc++-v3/config/os/gnu-linux/os_defines.h
@@ -49,4 +49,16 @@
// version dynamically in case it has changed since libstdc++ was configured.
#define _GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC __GLIBC_PREREQ(2,23)
+#if __GLIBC_PREREQ(2, 27)
+// Since glibc 2.27 pthread_self() is usable without linking to libpthread.
+# define _GLIBCXX_NATIVE_THREAD_ID pthread_self()
+#else
+// Before then it was in libc.so.6 but not libc.a, and always returns 0,
+// which breaks the invariant this_thread::get_id() != thread::id{}.
+// So only use it if we know the libpthread version is available.
+// Otherwise use (__gthread_t)1 as the ID of the main (and only) thread.
+# define _GLIBCXX_NATIVE_THREAD_ID \
+ (__gthread_active_p() ? __gthread_self() : (__gthread_t)1)
+#endif
+
#endif
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index efdec6e..e390e39 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -2520,6 +2520,76 @@ rm -f conftest.val
} # ac_fn_c_compute_int
+# ac_fn_cxx_check_func LINENO FUNC VAR
+# ------------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_cxx_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test x$gcc_no_link = xyes; then
+ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_func
+
# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
# -------------------------------------------
# Tests whether TYPE exists after having included INCLUDES, setting cache
@@ -10327,7 +10397,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -10339,7 +10409,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -12064,7 +12134,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 12067 "configure"
+#line 12137 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12170,7 +12240,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 12173 "configure"
+#line 12243 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -13198,7 +13268,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
aCC*)
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
@@ -13222,7 +13292,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test $with_gnu_ld = no; then
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
@@ -15862,7 +15932,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; }
# Fake what AC_TRY_COMPILE does.
cat > conftest.$ac_ext << EOF
-#line 15865 "configure"
+#line 15935 "configure"
int main()
{
typedef bool atomic_type;
@@ -15897,7 +15967,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15900 "configure"
+#line 15970 "configure"
int main()
{
typedef short atomic_type;
@@ -15932,7 +16002,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15935 "configure"
+#line 16005 "configure"
int main()
{
// NB: _Atomic_word not necessarily int.
@@ -15968,7 +16038,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15971 "configure"
+#line 16041 "configure"
int main()
{
typedef long long atomic_type;
@@ -16121,7 +16191,7 @@ $as_echo "mutex" >&6; }
# unnecessary for this test.
cat > conftest.$ac_ext << EOF
-#line 16124 "configure"
+#line 16194 "configure"
int main()
{
_Decimal32 d1;
@@ -16163,7 +16233,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
# unnecessary for this test.
cat > conftest.$ac_ext << EOF
-#line 16166 "configure"
+#line 16236 "configure"
template<typename T1, typename T2>
struct same
{ typedef T2 type; };
@@ -16197,7 +16267,7 @@ $as_echo "$enable_int128" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 16200 "configure"
+#line 16270 "configure"
template<typename T1, typename T2>
struct same
{ typedef T2 type; };
@@ -21181,7 +21251,6 @@ fi
ac_has_nanosleep=yes
;;
solaris*)
- GLIBCXX_LIBS="$GLIBCXX_LIBS -lrt"
ac_has_clock_monotonic=yes
ac_has_clock_realtime=yes
ac_has_nanosleep=yes
@@ -21219,7 +21288,7 @@ return clock_gettime ();
return 0;
}
_ACEOF
-for ac_lib in '' rt posix4; do
+for ac_lib in '' rt; do
if test -z "$ac_lib"; then
ac_res="none required"
else
@@ -21278,7 +21347,7 @@ return nanosleep ();
return 0;
}
_ACEOF
-for ac_lib in '' rt posix4; do
+for ac_lib in '' rt; do
if test -z "$ac_lib"; then
ac_res="none required"
else
@@ -21314,121 +21383,13 @@ if test "$ac_res" != no; then :
fi
else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5
-$as_echo_n "checking for library containing clock_gettime... " >&6; }
-if ${ac_cv_search_clock_gettime+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
+ ac_fn_cxx_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime"
+if test "x$ac_cv_func_clock_gettime" = xyes; then :
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char clock_gettime ();
-int
-main ()
-{
-return clock_gettime ();
- ;
- return 0;
-}
-_ACEOF
-for ac_lib in '' posix4; do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- if test x$gcc_no_link = xyes; then
- as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
-fi
-if ac_fn_cxx_try_link "$LINENO"; then :
- ac_cv_search_clock_gettime=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext
- if ${ac_cv_search_clock_gettime+:} false; then :
- break
-fi
-done
-if ${ac_cv_search_clock_gettime+:} false; then :
-
-else
- ac_cv_search_clock_gettime=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5
-$as_echo "$ac_cv_search_clock_gettime" >&6; }
-ac_res=$ac_cv_search_clock_gettime
-if test "$ac_res" != no; then :
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing nanosleep" >&5
-$as_echo_n "checking for library containing nanosleep... " >&6; }
-if ${ac_cv_search_nanosleep+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char nanosleep ();
-int
-main ()
-{
-return nanosleep ();
- ;
- return 0;
-}
-_ACEOF
-for ac_lib in '' posix4; do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- if test x$gcc_no_link = xyes; then
- as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
-fi
-if ac_fn_cxx_try_link "$LINENO"; then :
- ac_cv_search_nanosleep=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext
- if ${ac_cv_search_nanosleep+:} false; then :
- break
fi
-done
-if ${ac_cv_search_nanosleep+:} false; then :
-else
- ac_cv_search_nanosleep=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_nanosleep" >&5
-$as_echo "$ac_cv_search_nanosleep" >&6; }
-ac_res=$ac_cv_search_nanosleep
-if test "$ac_res" != no; then :
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+ ac_fn_cxx_check_func "$LINENO" "nanosleep" "ac_cv_func_nanosleep"
+if test "x$ac_cv_func_nanosleep" = xyes; then :
fi
@@ -21467,7 +21428,7 @@ return sched_yield ();
return 0;
}
_ACEOF
-for ac_lib in '' rt posix4; do
+for ac_lib in '' rt; do
if test -z "$ac_lib"; then
ac_res="none required"
else
@@ -21504,10 +21465,6 @@ fi
case "$ac_cv_search_sched_yield" in
- -lposix4*)
- GLIBCXX_LIBS="$GLIBCXX_LIBS $ac_cv_search_sched_yield"
- ac_has_sched_yield=yes
- ;;
-lrt*)
if test x"$enable_libstdcxx_time" = x"rt"; then
GLIBCXX_LIBS="$GLIBCXX_LIBS $ac_cv_search_sched_yield"
@@ -21661,19 +21618,54 @@ main ()
}
_ACEOF
if ac_fn_cxx_try_compile "$LINENO"; then :
- ac_has_clock_monotonic_syscall=yes
+ ac_has_clock_gettime_syscall=yes
else
- ac_has_clock_monotonic_syscall=no
+ ac_has_clock_gettime_syscall=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_has_clock_monotonic_syscall" >&5
-$as_echo "$ac_has_clock_monotonic_syscall" >&6; }
- if test x"$ac_has_clock_monotonic_syscall" = x"yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_has_clock_gettime_syscall" >&5
+$as_echo "$ac_has_clock_gettime_syscall" >&6; }
+ if test x"$ac_has_clock_gettime_syscall" = x"yes"; then
$as_echo "#define _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL 1" >>confdefs.h
ac_has_clock_monotonic=yes
ac_has_clock_realtime=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct timespec that matches syscall" >&5
+$as_echo_n "checking for struct timespec that matches syscall... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <time.h>
+ #include <sys/syscall.h>
+
+int
+main ()
+{
+#ifdef SYS_clock_gettime64
+ #if SYS_clock_gettime64 != SYS_clock_gettime
+ // We need to use SYS_clock_gettime and libc appears to
+ // also know about the SYS_clock_gettime64 syscall.
+ // Check that userspace doesn't use time64 version of timespec.
+ static_assert(sizeof(timespec::tv_sec) == sizeof(long),
+ "struct timespec must be compatible with SYS_clock_gettime");
+ #endif
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_timespec_matches_syscall=yes
+else
+ ac_timespec_matches_syscall=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_timespec_matches_syscall" >&5
+$as_echo "$ac_timespec_matches_syscall" >&6; }
+ if test x"$ac_timespec_matches_syscall" = no; then
+ as_fn_error $? "struct timespec is not compatible with SYS_clock_gettime, please report a bug to http://gcc.gnu.org/bugzilla" "$LINENO" 5
+ fi
fi;;
esac
fi
@@ -22936,15 +22928,24 @@ $as_echo "$ac_gcsections" >&6; }
# Note this is only for shared objects.
ac_ld_relro=no
if test x"$with_gnu_ld" = x"yes"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
+ # cygwin and mingw uses PE, which has no ELF relro support,
+ # multi target ld may confuse configure machinery
+ case "$host" in
+ *-*-cygwin*)
+ ;;
+ *-*-mingw*)
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
$as_echo_n "checking for ld that supports -Wl,-z,relro... " >&6; }
- cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
- if test -n "$cxx_z_relo"; then
- OPT_LDFLAGS="-Wl,-z,relro"
- ac_ld_relro=yes
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
+ cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
+ if test -n "$cxx_z_relo"; then
+ OPT_LDFLAGS="-Wl,-z,relro"
+ ac_ld_relro=yes
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
$as_echo "$ac_ld_relro" >&6; }
+ esac
fi
# Set linker optimization flags.
@@ -30131,15 +30132,24 @@ $as_echo "$ac_gcsections" >&6; }
# Note this is only for shared objects.
ac_ld_relro=no
if test x"$with_gnu_ld" = x"yes"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
+ # cygwin and mingw uses PE, which has no ELF relro support,
+ # multi target ld may confuse configure machinery
+ case "$host" in
+ *-*-cygwin*)
+ ;;
+ *-*-mingw*)
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
$as_echo_n "checking for ld that supports -Wl,-z,relro... " >&6; }
- cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
- if test -n "$cxx_z_relo"; then
- OPT_LDFLAGS="-Wl,-z,relro"
- ac_ld_relro=yes
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
+ cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
+ if test -n "$cxx_z_relo"; then
+ OPT_LDFLAGS="-Wl,-z,relro"
+ ac_ld_relro=yes
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
$as_echo "$ac_ld_relro" >&6; }
+ esac
fi
# Set linker optimization flags.
@@ -36054,15 +36064,24 @@ $as_echo "$ac_gcsections" >&6; }
# Note this is only for shared objects.
ac_ld_relro=no
if test x"$with_gnu_ld" = x"yes"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
+ # cygwin and mingw uses PE, which has no ELF relro support,
+ # multi target ld may confuse configure machinery
+ case "$host" in
+ *-*-cygwin*)
+ ;;
+ *-*-mingw*)
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
$as_echo_n "checking for ld that supports -Wl,-z,relro... " >&6; }
- cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
- if test -n "$cxx_z_relo"; then
- OPT_LDFLAGS="-Wl,-z,relro"
- ac_ld_relro=yes
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
+ cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
+ if test -n "$cxx_z_relo"; then
+ OPT_LDFLAGS="-Wl,-z,relro"
+ ac_ld_relro=yes
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
$as_echo "$ac_ld_relro" >&6; }
+ esac
fi
# Set linker optimization flags.
@@ -47976,15 +47995,24 @@ $as_echo "$ac_gcsections" >&6; }
# Note this is only for shared objects.
ac_ld_relro=no
if test x"$with_gnu_ld" = x"yes"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
+ # cygwin and mingw uses PE, which has no ELF relro support,
+ # multi target ld may confuse configure machinery
+ case "$host" in
+ *-*-cygwin*)
+ ;;
+ *-*-mingw*)
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
$as_echo_n "checking for ld that supports -Wl,-z,relro... " >&6; }
- cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
- if test -n "$cxx_z_relo"; then
- OPT_LDFLAGS="-Wl,-z,relro"
- ac_ld_relro=yes
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
+ cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
+ if test -n "$cxx_z_relo"; then
+ OPT_LDFLAGS="-Wl,-z,relro"
+ ac_ld_relro=yes
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
$as_echo "$ac_ld_relro" >&6; }
+ esac
fi
# Set linker optimization flags.
@@ -48252,15 +48280,24 @@ $as_echo "$ac_gcsections" >&6; }
# Note this is only for shared objects.
ac_ld_relro=no
if test x"$with_gnu_ld" = x"yes"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
+ # cygwin and mingw uses PE, which has no ELF relro support,
+ # multi target ld may confuse configure machinery
+ case "$host" in
+ *-*-cygwin*)
+ ;;
+ *-*-mingw*)
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
$as_echo_n "checking for ld that supports -Wl,-z,relro... " >&6; }
- cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
- if test -n "$cxx_z_relo"; then
- OPT_LDFLAGS="-Wl,-z,relro"
- ac_ld_relro=yes
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
+ cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
+ if test -n "$cxx_z_relo"; then
+ OPT_LDFLAGS="-Wl,-z,relro"
+ ac_ld_relro=yes
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
$as_echo "$ac_ld_relro" >&6; }
+ esac
fi
# Set linker optimization flags.
@@ -48719,15 +48756,24 @@ $as_echo "$ac_gcsections" >&6; }
# Note this is only for shared objects.
ac_ld_relro=no
if test x"$with_gnu_ld" = x"yes"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
+ # cygwin and mingw uses PE, which has no ELF relro support,
+ # multi target ld may confuse configure machinery
+ case "$host" in
+ *-*-cygwin*)
+ ;;
+ *-*-mingw*)
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
$as_echo_n "checking for ld that supports -Wl,-z,relro... " >&6; }
- cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
- if test -n "$cxx_z_relo"; then
- OPT_LDFLAGS="-Wl,-z,relro"
- ac_ld_relro=yes
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
+ cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
+ if test -n "$cxx_z_relo"; then
+ OPT_LDFLAGS="-Wl,-z,relro"
+ ac_ld_relro=yes
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
$as_echo "$ac_ld_relro" >&6; }
+ esac
fi
# Set linker optimization flags.
@@ -55098,15 +55144,24 @@ $as_echo "$ac_gcsections" >&6; }
# Note this is only for shared objects.
ac_ld_relro=no
if test x"$with_gnu_ld" = x"yes"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
+ # cygwin and mingw uses PE, which has no ELF relro support,
+ # multi target ld may confuse configure machinery
+ case "$host" in
+ *-*-cygwin*)
+ ;;
+ *-*-mingw*)
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
$as_echo_n "checking for ld that supports -Wl,-z,relro... " >&6; }
- cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
- if test -n "$cxx_z_relo"; then
- OPT_LDFLAGS="-Wl,-z,relro"
- ac_ld_relro=yes
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
+ cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
+ if test -n "$cxx_z_relo"; then
+ OPT_LDFLAGS="-Wl,-z,relro"
+ ac_ld_relro=yes
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
$as_echo "$ac_ld_relro" >&6; }
+ esac
fi
# Set linker optimization flags.
@@ -61029,15 +61084,24 @@ $as_echo "$ac_gcsections" >&6; }
# Note this is only for shared objects.
ac_ld_relro=no
if test x"$with_gnu_ld" = x"yes"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
+ # cygwin and mingw uses PE, which has no ELF relro support,
+ # multi target ld may confuse configure machinery
+ case "$host" in
+ *-*-cygwin*)
+ ;;
+ *-*-mingw*)
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
$as_echo_n "checking for ld that supports -Wl,-z,relro... " >&6; }
- cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
- if test -n "$cxx_z_relo"; then
- OPT_LDFLAGS="-Wl,-z,relro"
- ac_ld_relro=yes
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
+ cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
+ if test -n "$cxx_z_relo"; then
+ OPT_LDFLAGS="-Wl,-z,relro"
+ ac_ld_relro=yes
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
$as_echo "$ac_ld_relro" >&6; }
+ esac
fi
# Set linker optimization flags.
@@ -61230,15 +61294,24 @@ $as_echo "$ac_gcsections" >&6; }
# Note this is only for shared objects.
ac_ld_relro=no
if test x"$with_gnu_ld" = x"yes"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
+ # cygwin and mingw uses PE, which has no ELF relro support,
+ # multi target ld may confuse configure machinery
+ case "$host" in
+ *-*-cygwin*)
+ ;;
+ *-*-mingw*)
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
$as_echo_n "checking for ld that supports -Wl,-z,relro... " >&6; }
- cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
- if test -n "$cxx_z_relo"; then
- OPT_LDFLAGS="-Wl,-z,relro"
- ac_ld_relro=yes
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
+ cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
+ if test -n "$cxx_z_relo"; then
+ OPT_LDFLAGS="-Wl,-z,relro"
+ ac_ld_relro=yes
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
$as_echo "$ac_ld_relro" >&6; }
+ esac
fi
# Set linker optimization flags.
@@ -61450,15 +61523,24 @@ $as_echo "$ac_gcsections" >&6; }
# Note this is only for shared objects.
ac_ld_relro=no
if test x"$with_gnu_ld" = x"yes"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
+ # cygwin and mingw uses PE, which has no ELF relro support,
+ # multi target ld may confuse configure machinery
+ case "$host" in
+ *-*-cygwin*)
+ ;;
+ *-*-mingw*)
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
$as_echo_n "checking for ld that supports -Wl,-z,relro... " >&6; }
- cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
- if test -n "$cxx_z_relo"; then
- OPT_LDFLAGS="-Wl,-z,relro"
- ac_ld_relro=yes
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
+ cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
+ if test -n "$cxx_z_relo"; then
+ OPT_LDFLAGS="-Wl,-z,relro"
+ ac_ld_relro=yes
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
$as_echo "$ac_ld_relro" >&6; }
+ esac
fi
# Set linker optimization flags.
@@ -76238,6 +76320,64 @@ fi
fi
fi
+ ac_fn_cxx_check_header_mongrel "$LINENO" "semaphore.h" "ac_cv_header_semaphore_h" "$ac_includes_default"
+if test "x$ac_cv_header_semaphore_h" = xyes; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for POSIX Semaphores and sem_timedwait" >&5
+$as_echo_n "checking for POSIX Semaphores and sem_timedwait... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <unistd.h>
+ #include <semaphore.h>
+ #include <limits.h>
+
+int
+main ()
+{
+
+ #if !defined _POSIX_TIMEOUTS || _POSIX_TIMEOUTS <= 0
+ # error "POSIX Timeouts option not supported"
+ #elif !defined _POSIX_SEMAPHORES || _POSIX_SEMAPHORES <= 0
+ # error "POSIX Semaphores option not supported"
+ #else
+ #if defined SEM_VALUE_MAX
+ constexpr int sem_value_max = SEM_VALUE_MAX;
+ #elif defined _POSIX_SEM_VALUE_MAX
+ constexpr int sem_value_max = _POSIX_SEM_VALUE_MAX;
+ #else
+ # error "SEM_VALUE_MAX not available"
+ #endif
+ sem_t sem;
+ sem_init(&sem, 0, sem_value_max);
+ struct timespec ts = { 0 };
+ sem_timedwait(&sem, &ts);
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_have_posix_semaphore=yes
+else
+ ac_have_posix_semaphore=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ ac_have_posix_semaphore=no
+fi
+
+
+
+ if test $ac_have_posix_semaphore = yes ; then
+
+$as_echo "#define _GLIBCXX_HAVE_POSIX_SEMAPHORE 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_have_posix_semaphore" >&5
+$as_echo "$ac_have_posix_semaphore" >&6; }
+
CXXFLAGS="$ac_save_CXXFLAGS"
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in b/libstdc++-v3/doc/doxygen/user.cfg.in
index 320f6de..2261d57 100644
--- a/libstdc++-v3/doc/doxygen/user.cfg.in
+++ b/libstdc++-v3/doc/doxygen/user.cfg.in
@@ -870,6 +870,7 @@ INPUT = @srcdir@/doc/doxygen/doxygroups.cc \
include/iostream \
include/istream \
include/iterator \
+ include/latch \
include/limits \
include/list \
include/locale \
@@ -887,8 +888,10 @@ INPUT = @srcdir@/doc/doxygen/doxygroups.cc \
include/ratio \
include/regex \
include/scoped_allocator \
+ include/semaphore \
include/set \
include/shared_mutex \
+ include/source_location \
include/span \
include/sstream \
include/stack \
diff --git a/libstdc++-v3/doc/html/manual/configure.html b/libstdc++-v3/doc/html/manual/configure.html
index 0024e63..9e2e9dc 100644
--- a/libstdc++-v3/doc/html/manual/configure.html
+++ b/libstdc++-v3/doc/html/manual/configure.html
@@ -93,8 +93,7 @@
<code class="function">sched_yield</code> functions, used in the
implementation of [thread.thread.this] of the 2011 ISO C++ standard.
The choice OPTION=yes checks for the availability of the facilities
- in libc and libposix4. In case it's needed the latter is also linked
- to libstdc++ as part of the build process. OPTION=rt also checks in
+ in libc. OPTION=rt also checks in
librt (and, if it's needed, links to it). Note that linking to librt
is not always desirable because for glibc it requires linking to
libpthread too, which causes all reference counting to use atomic
diff --git a/libstdc++-v3/doc/html/manual/status.html b/libstdc++-v3/doc/html/manual/status.html
index d3f2eda1..c5b8185 100644
--- a/libstdc++-v3/doc/html/manual/status.html
+++ b/libstdc++-v3/doc/html/manual/status.html
@@ -1194,13 +1194,13 @@ or any notes about the implementation.
</td><td align="center"> 10.1 </td><td align="left"> <code class="code">__cpp_lib_atomic_ref &gt;= 201806L</code> </td></tr><tr><td align="left"> Floating Point Atomic </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0020r6.html" target="_top">
P0020R6 </a>
- </td><td align="center"> 10.1 </td><td align="left"> <code class="code">__cpp_lib_atomic_float &gt;= 201711L</code> </td></tr><tr bgcolor="#C8B0B0"><td align="left"> C++ Synchronized Buffered Ostream </td><td align="left">
+ </td><td align="center"> 10.1 </td><td align="left"> <code class="code">__cpp_lib_atomic_float &gt;= 201711L</code> </td></tr><tr><td align="left"> C++ Synchronized Buffered Ostream </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0053r7.pdf" target="_top">
P0053R7 </a>
- </td><td align="center"> </td><td align="left"> <code class="code">__cpp_lib_syncbuf &gt;= 201711L</code> </td></tr><tr bgcolor="#C8B0B0"><td align="left"> Manipulators for C++ Synchronized Buffered Ostream </td><td align="left">
+ </td><td align="center"> 11 </td><td align="left"> <code class="code">__cpp_lib_syncbuf &gt;= 201711L</code> </td></tr><tr><td align="left"> Manipulators for C++ Synchronized Buffered Ostream </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0753r2.pdf" target="_top">
P0753R2 </a>
- </td><td align="center"> </td><td align="left"> <code class="code">__cpp_lib_syncbuf &gt;= 201803L</code> </td></tr><tr><td align="left"> Make <code class="code">std::memory_order</code> a scoped enumeration </td><td align="left">
+ </td><td align="center"> 11 </td><td align="left"> <code class="code">__cpp_lib_syncbuf &gt;= 201803L</code> </td></tr><tr><td align="left"> Make <code class="code">std::memory_order</code> a scoped enumeration </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0439r0.html" target="_top">
P0439R0 </a>
</td><td align="center"> 9.1 </td><td align="left"> </td></tr><tr bgcolor="#C8B0B0"><td align="left"> The Curious Case of Padding Bits, Featuring Atomic Compare-and-Exchange </td><td align="left">
@@ -1399,10 +1399,10 @@ or any notes about the implementation.
</td><td align="center"> 9.1 </td><td align="left"> </td></tr><tr bgcolor="#C8B0B0"><td align="left"> Thou Shalt Not Specialize std Function Templates! </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0551r3.pdf" target="_top">
P0551R3 </a>
- </td><td align="center"> </td><td align="left"> </td></tr><tr bgcolor="#C8B0B0"><td align="left"> Bit-casting object representations </td><td align="left">
+ </td><td align="center"> </td><td align="left"> </td></tr><tr><td align="left"> Bit-casting object representations </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0476r2.html" target="_top">
P0476R2 </a>
- </td><td align="center"> </td><td align="left"> <code class="code">__cpp_lib_bit_cast &gt;= 201806L</code> </td></tr><tr><td align="left"> Integral power-of-2 operations </td><td align="left">
+ </td><td align="center"> 11 </td><td align="left"> <code class="code">__cpp_lib_bit_cast &gt;= 201806L</code> </td></tr><tr><td align="left"> Integral power-of-2 operations </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0556r3.html" target="_top">
P0556R3 </a>
</td><td align="center"> 9.1 </td><td align="left"> <code class="code">__cpp_lib_int_pow2 &gt;= 201806L</code> (since 9.4, see Note 1) </td></tr><tr><td align="left"> On the names of low-level bit manipulation functions </td><td align="left">
@@ -1528,15 +1528,15 @@ or any notes about the implementation.
</td><td align="center"> 9.1 </td><td align="left"> <code class="code">__cpp_lib_interpolate &gt;= 201902L</code> </td></tr><tr><td align="left"> Mathematical constants </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0631r8.pdf" target="_top">
P0631R8 </a>
- </td><td align="center"> 10.1 </td><td align="left"> <code class="code">__cpp_lib_math_constants &gt;= 201907L</code> </td></tr><tr bgcolor="#C8B0B0"><td align="left"> std::source_location </td><td align="left">
+ </td><td align="center"> 10.1 </td><td align="left"> <code class="code">__cpp_lib_math_constants &gt;= 201907L</code> </td></tr><tr><td align="left"> std::source_location </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1208r6.pdf" target="_top">
P1208R6 </a>
- </td><td align="center"> </td><td align="left">
+ </td><td align="center"> 11 </td><td align="left">
<code class="code">__cpp_lib_source_location &gt;= 201907L</code>
- </td></tr><tr bgcolor="#C8B0B0"><td align="left"> Efficient access to std::basic_stringbuf's Buffer </td><td align="left">
+ </td></tr><tr><td align="left"> Efficient access to std::basic_stringbuf's Buffer </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0408r7.pdf" target="_top">
P0408R7 </a>
- </td><td align="center"> </td><td align="left"> </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ </td><td align="center"> 11 </td><td align="left"> </td></tr></tbody></table></div></div><br class="table-break" /><p>
Note 1: This feature is supported in older releases but the
<code class="code">__cpp_lib</code> macro is not defined to the right value
(or not defined at all) until the version shown in parentheses.
diff --git a/libstdc++-v3/doc/xml/manual/configure.xml b/libstdc++-v3/doc/xml/manual/configure.xml
index b84ac42..cc9c855 100644
--- a/libstdc++-v3/doc/xml/manual/configure.xml
+++ b/libstdc++-v3/doc/xml/manual/configure.xml
@@ -171,8 +171,7 @@
<function>sched_yield</function> functions, used in the
implementation of [thread.thread.this] of the 2011 ISO C++ standard.
The choice OPTION=yes checks for the availability of the facilities
- in libc and libposix4. In case it's needed the latter is also linked
- to libstdc++ as part of the build process. OPTION=rt also checks in
+ in libc. OPTION=rt also checks in
librt (and, if it's needed, links to it). Note that linking to librt
is not always desirable because for glibc it requires linking to
libpthread too, which causes all reference counting to use atomic
diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2020.xml b/libstdc++-v3/doc/xml/manual/status_cxx2020.xml
index e633365..b62a432 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2020.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2020.xml
@@ -357,24 +357,22 @@ or any notes about the implementation.
</row>
<row>
- <?dbhtml bgcolor="#C8B0B0" ?>
<entry> C++ Synchronized Buffered Ostream </entry>
<entry>
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0053r7.pdf">
P0053R7 </link>
</entry>
- <entry align="center"> </entry>
+ <entry align="center"> 11 </entry>
<entry> <code>__cpp_lib_syncbuf &gt;= 201711L</code> </entry>
</row>
<row>
- <?dbhtml bgcolor="#C8B0B0" ?>
<entry> Manipulators for C++ Synchronized Buffered Ostream </entry>
<entry>
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0753r2.pdf">
P0753R2 </link>
</entry>
- <entry align="center"> </entry>
+ <entry align="center"> 11 </entry>
<entry> <code>__cpp_lib_syncbuf &gt;= 201803L</code> </entry>
</row>
@@ -1024,13 +1022,12 @@ or any notes about the implementation.
</row>
<row>
- <?dbhtml bgcolor="#C8B0B0" ?>
<entry> Bit-casting object representations </entry>
<entry>
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0476r2.html">
P0476R2 </link>
</entry>
- <entry align="center"> </entry>
+ <entry align="center"> 11 </entry>
<entry> <code>__cpp_lib_bit_cast &gt;= 201806L</code> </entry>
</row>
@@ -1411,26 +1408,24 @@ or any notes about the implementation.
</row>
<row>
- <?dbhtml bgcolor="#C8B0B0" ?>
<entry> std::source_location </entry>
<entry>
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1208r6.pdf">
P1208R6 </link>
</entry>
- <entry align="center"> </entry>
+ <entry align="center"> 11 </entry>
<entry>
<code>__cpp_lib_source_location &gt;= 201907L</code>
</entry>
</row>
<row>
- <?dbhtml bgcolor="#C8B0B0" ?>
<entry> Efficient access to std::basic_stringbuf's Buffer </entry>
<entry>
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0408r7.pdf">
P0408R7 </link>
</entry>
- <entry align="center"> </entry>
+ <entry align="center"> 11 </entry>
<entry />
</row>
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 292d89d..9dbc7dc 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -52,6 +52,7 @@ std_headers = \
${std_srcdir}/iostream \
${std_srcdir}/istream \
${std_srcdir}/iterator \
+ ${std_srcdir}/latch \
${std_srcdir}/limits \
${std_srcdir}/list \
${std_srcdir}/locale \
@@ -69,8 +70,10 @@ std_headers = \
${std_srcdir}/ratio \
${std_srcdir}/regex \
${std_srcdir}/scoped_allocator \
+ ${std_srcdir}/semaphore \
${std_srcdir}/set \
${std_srcdir}/shared_mutex \
+ ${std_srcdir}/source_location \
${std_srcdir}/span \
${std_srcdir}/sstream \
${std_srcdir}/syncstream \
@@ -103,6 +106,8 @@ bits_headers = \
${bits_srcdir}/allocator.h \
${bits_srcdir}/atomic_base.h \
${bits_srcdir}/atomic_futex.h \
+ ${bits_srcdir}/atomic_timed_wait.h \
+ ${bits_srcdir}/atomic_wait.h \
${bits_srcdir}/basic_ios.h \
${bits_srcdir}/basic_ios.tcc \
${bits_srcdir}/basic_string.h \
@@ -178,6 +183,7 @@ bits_headers = \
${bits_srcdir}/regex_compiler.tcc \
${bits_srcdir}/regex_executor.h \
${bits_srcdir}/regex_executor.tcc \
+ ${bits_srcdir}/semaphore_base.h \
${bits_srcdir}/shared_ptr.h \
${bits_srcdir}/shared_ptr_atomic.h \
${bits_srcdir}/shared_ptr_base.h \
@@ -187,6 +193,7 @@ bits_headers = \
${bits_srcdir}/std_abs.h \
${bits_srcdir}/std_function.h \
${bits_srcdir}/std_mutex.h \
+ ${bits_srcdir}/std_thread.h \
${bits_srcdir}/stl_algo.h \
${bits_srcdir}/stl_algobase.h \
${bits_srcdir}/stl_bvector.h \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index fff444c..0cb0fdf 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -398,6 +398,7 @@ std_headers = \
${std_srcdir}/iostream \
${std_srcdir}/istream \
${std_srcdir}/iterator \
+ ${std_srcdir}/latch \
${std_srcdir}/limits \
${std_srcdir}/list \
${std_srcdir}/locale \
@@ -415,8 +416,10 @@ std_headers = \
${std_srcdir}/ratio \
${std_srcdir}/regex \
${std_srcdir}/scoped_allocator \
+ ${std_srcdir}/semaphore \
${std_srcdir}/set \
${std_srcdir}/shared_mutex \
+ ${std_srcdir}/source_location \
${std_srcdir}/span \
${std_srcdir}/sstream \
${std_srcdir}/syncstream \
@@ -449,6 +452,8 @@ bits_headers = \
${bits_srcdir}/allocator.h \
${bits_srcdir}/atomic_base.h \
${bits_srcdir}/atomic_futex.h \
+ ${bits_srcdir}/atomic_timed_wait.h \
+ ${bits_srcdir}/atomic_wait.h \
${bits_srcdir}/basic_ios.h \
${bits_srcdir}/basic_ios.tcc \
${bits_srcdir}/basic_string.h \
@@ -524,6 +529,7 @@ bits_headers = \
${bits_srcdir}/regex_compiler.tcc \
${bits_srcdir}/regex_executor.h \
${bits_srcdir}/regex_executor.tcc \
+ ${bits_srcdir}/semaphore_base.h \
${bits_srcdir}/shared_ptr.h \
${bits_srcdir}/shared_ptr_atomic.h \
${bits_srcdir}/shared_ptr_base.h \
@@ -533,6 +539,7 @@ bits_headers = \
${bits_srcdir}/std_abs.h \
${bits_srcdir}/std_function.h \
${bits_srcdir}/std_mutex.h \
+ ${bits_srcdir}/std_thread.h \
${bits_srcdir}/stl_algo.h \
${bits_srcdir}/stl_algobase.h \
${bits_srcdir}/stl_bvector.h \
diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h
index 86d8ed2..467311f 100644
--- a/libstdc++-v3/include/bits/alloc_traits.h
+++ b/libstdc++-v3/include/bits/alloc_traits.h
@@ -708,6 +708,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Alloc>
using _RequireNotAllocator
= typename enable_if<!__is_allocator<_Alloc>::value, _Alloc>::type;
+
+#if __cpp_concepts >= 201907L
+ template<typename _Alloc>
+ concept __allocator_like = requires (_Alloc& __a) {
+ typename _Alloc::value_type;
+ __a.deallocate(__a.allocate(1u), 1u);
+ };
+#endif
#endif // C++11
/**
diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h
index 2cdd2bd..89f66a2 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -37,6 +37,10 @@
#include <bits/atomic_lockfree_defines.h>
#include <bits/move.h>
+#if __cplusplus > 201703L
+#include <bits/atomic_wait.h>
+#endif
+
#ifndef _GLIBCXX_ALWAYS_INLINE
#define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
#endif
@@ -134,7 +138,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __ret;
}
-
// Base types for atomics.
template<typename _IntTp>
struct __atomic_base;
@@ -226,6 +229,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__atomic_load(&_M_i, &__v, int(__m));
return __v == __GCC_ATOMIC_TEST_AND_SET_TRUEVAL;
}
+
+#if __cpp_lib_atomic_wait
+ _GLIBCXX_ALWAYS_INLINE void
+ wait(bool __old,
+ memory_order __m = memory_order_seq_cst) const noexcept
+ {
+ std::__atomic_wait(&_M_i, static_cast<__atomic_flag_data_type>(__old),
+ [__m, this, __old]()
+ { return this->test(__m) != __old; });
+ }
+
+ // TODO add const volatile overload
+
+ _GLIBCXX_ALWAYS_INLINE void
+ notify_one() const noexcept
+ { std::__atomic_notify(&_M_i, false); }
+
+ // TODO add const volatile overload
+
+ _GLIBCXX_ALWAYS_INLINE void
+ notify_all() const noexcept
+ { std::__atomic_notify(&_M_i, true); }
+
+ // TODO add const volatile overload
+#endif // __cpp_lib_atomic_wait
#endif // C++20
_GLIBCXX_ALWAYS_INLINE void
@@ -576,6 +604,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__cmpexch_failure_order(__m));
}
+#if __cpp_lib_atomic_wait
+ _GLIBCXX_ALWAYS_INLINE void
+ wait(__int_type __old,
+ memory_order __m = memory_order_seq_cst) const noexcept
+ {
+ std::__atomic_wait(&_M_i, __old,
+ [__m, this, __old]
+ { return this->load(__m) != __old; });
+ }
+
+ // TODO add const volatile overload
+
+ _GLIBCXX_ALWAYS_INLINE void
+ notify_one() const noexcept
+ { std::__atomic_notify(&_M_i, false); }
+
+ // TODO add const volatile overload
+
+ _GLIBCXX_ALWAYS_INLINE void
+ notify_all() const noexcept
+ { std::__atomic_notify(&_M_i, true); }
+
+ // TODO add const volatile overload
+#endif // __cpp_lib_atomic_wait
+
_GLIBCXX_ALWAYS_INLINE __int_type
fetch_add(__int_type __i,
memory_order __m = memory_order_seq_cst) noexcept
@@ -845,6 +898,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
int(__m1), int(__m2));
}
+#if __cpp_lib_atomic_wait
+ _GLIBCXX_ALWAYS_INLINE void
+ wait(__pointer_type __old,
+ memory_order __m = memory_order_seq_cst) noexcept
+ {
+ std::__atomic_wait(&_M_p, __old,
+ [__m, this, __old]()
+ { return this->load(__m) != __old; });
+ }
+
+ // TODO add const volatile overload
+
+ _GLIBCXX_ALWAYS_INLINE void
+ notify_one() const noexcept
+ { std::__atomic_notify(&_M_p, false); }
+
+ // TODO add const volatile overload
+
+ _GLIBCXX_ALWAYS_INLINE void
+ notify_all() const noexcept
+ { std::__atomic_notify(&_M_p, true); }
+
+ // TODO add const volatile overload
+#endif // __cpp_lib_atomic_wait
+
_GLIBCXX_ALWAYS_INLINE __pointer_type
fetch_add(ptrdiff_t __d,
memory_order __m = memory_order_seq_cst) noexcept
@@ -933,6 +1011,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
int(__success), int(__failure));
}
+#if __cpp_lib_atomic_wait
+ template<typename _Tp>
+ _GLIBCXX_ALWAYS_INLINE void
+ wait(const _Tp* __ptr, _Val<_Tp> __old,
+ memory_order __m = memory_order_seq_cst) noexcept
+ {
+ std::__atomic_wait(__ptr, __old,
+ [=]() { return load(__ptr, __m) == __old; });
+ }
+
+ // TODO add const volatile overload
+
+ template<typename _Tp>
+ _GLIBCXX_ALWAYS_INLINE void
+ notify_one(const _Tp* __ptr) noexcept
+ { std::__atomic_notify(__ptr, false); }
+
+ // TODO add const volatile overload
+
+ template<typename _Tp>
+ _GLIBCXX_ALWAYS_INLINE void
+ notify_all(const _Tp* __ptr) noexcept
+ { std::__atomic_notify(__ptr, true); }
+
+ // TODO add const volatile overload
+#endif // __cpp_lib_atomic_wait
+
template<typename _Tp>
_GLIBCXX_ALWAYS_INLINE _Tp
fetch_add(_Tp* __ptr, _Diff<_Tp> __i, memory_order __m) noexcept
@@ -1186,6 +1291,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__cmpexch_failure_order(__order));
}
+#if __cpp_lib_atomic_wait
+ _GLIBCXX_ALWAYS_INLINE void
+ wait(_Fp __old, memory_order __m = memory_order_seq_cst) const noexcept
+ { __atomic_impl::wait(&_M_fp, __old, __m); }
+
+ // TODO add const volatile overload
+
+ _GLIBCXX_ALWAYS_INLINE void
+ notify_one() const noexcept
+ { __atomic_impl::notify_one(&_M_fp); }
+
+ // TODO add const volatile overload
+
+ _GLIBCXX_ALWAYS_INLINE void
+ notify_all() const noexcept
+ { __atomic_impl::notify_all(&_M_fp); }
+
+ // TODO add const volatile overload
+#endif // __cpp_lib_atomic_wait
+
value_type
fetch_add(value_type __i,
memory_order __m = memory_order_seq_cst) noexcept
@@ -1323,6 +1448,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__cmpexch_failure_order(__order));
}
+#if __cpp_lib_atomic_wait
+ _GLIBCXX_ALWAYS_INLINE void
+ wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
+ { __atomic_impl::wait(_M_ptr, __old, __m); }
+
+ // TODO add const volatile overload
+
+ _GLIBCXX_ALWAYS_INLINE void
+ notify_one() const noexcept
+ { __atomic_impl::notify_one(_M_ptr); }
+
+ // TODO add const volatile overload
+
+ _GLIBCXX_ALWAYS_INLINE void
+ notify_all() const noexcept
+ { __atomic_impl::notify_all(_M_ptr); }
+
+ // TODO add const volatile overload
+#endif // __cpp_lib_atomic_wait
+
private:
_Tp* _M_ptr;
};
@@ -1418,6 +1563,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__cmpexch_failure_order(__order));
}
+#if __cpp_lib_atomic_wait
+ _GLIBCXX_ALWAYS_INLINE void
+ wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
+ { __atomic_impl::wait(_M_ptr, __old, __m); }
+
+ // TODO add const volatile overload
+
+ _GLIBCXX_ALWAYS_INLINE void
+ notify_one() const noexcept
+ { __atomic_impl::notify_one(_M_ptr); }
+
+ // TODO add const volatile overload
+
+ _GLIBCXX_ALWAYS_INLINE void
+ notify_all() const noexcept
+ { __atomic_impl::notify_all(_M_ptr); }
+
+ // TODO add const volatile overload
+#endif // __cpp_lib_atomic_wait
+
value_type
fetch_add(value_type __i,
memory_order __m = memory_order_seq_cst) const noexcept
@@ -1573,6 +1738,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__cmpexch_failure_order(__order));
}
+#if __cpp_lib_atomic_wait
+ _GLIBCXX_ALWAYS_INLINE void
+ wait(_Fp __old, memory_order __m = memory_order_seq_cst) const noexcept
+ { __atomic_impl::wait(_M_ptr, __old, __m); }
+
+ // TODO add const volatile overload
+
+ _GLIBCXX_ALWAYS_INLINE void
+ notify_one() const noexcept
+ { __atomic_impl::notify_one(_M_ptr); }
+
+ // TODO add const volatile overload
+
+ _GLIBCXX_ALWAYS_INLINE void
+ notify_all() const noexcept
+ { __atomic_impl::notify_all(_M_ptr); }
+
+ // TODO add const volatile overload
+#endif // __cpp_lib_atomic_wait
+
value_type
fetch_add(value_type __i,
memory_order __m = memory_order_seq_cst) const noexcept
@@ -1682,6 +1867,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__cmpexch_failure_order(__order));
}
+#if __cpp_lib_atomic_wait
+ _GLIBCXX_ALWAYS_INLINE void
+ wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
+ { __atomic_impl::wait(_M_ptr, __old, __m); }
+
+ // TODO add const volatile overload
+
+ _GLIBCXX_ALWAYS_INLINE void
+ notify_one() const noexcept
+ { __atomic_impl::notify_one(_M_ptr); }
+
+ // TODO add const volatile overload
+
+ _GLIBCXX_ALWAYS_INLINE void
+ notify_all() const noexcept
+ { __atomic_impl::notify_all(_M_ptr); }
+
+ // TODO add const volatile overload
+#endif // __cpp_lib_atomic_wait
+
_GLIBCXX_ALWAYS_INLINE value_type
fetch_add(difference_type __d,
memory_order __m = memory_order_seq_cst) const noexcept
diff --git a/libstdc++-v3/include/bits/atomic_timed_wait.h b/libstdc++-v3/include/bits/atomic_timed_wait.h
new file mode 100644
index 0000000..83438ae
--- /dev/null
+++ b/libstdc++-v3/include/bits/atomic_timed_wait.h
@@ -0,0 +1,297 @@
+// -*- C++ -*- header.
+
+// Copyright (C) 2020 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 bits/atomic_timed_wait.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{atomic}
+ */
+
+#ifndef _GLIBCXX_ATOMIC_TIMED_WAIT_H
+#define _GLIBCXX_ATOMIC_TIMED_WAIT_H 1
+
+#pragma GCC system_header
+
+#include <bits/atomic_wait.h>
+
+#if __cpp_lib_atomic_wait
+#include <bits/functional_hash.h>
+
+#include <chrono>
+
+#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
+#include <exception> // std::terminate
+#include <sys/time.h>
+#endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ enum class __atomic_wait_status { no_timeout, timeout };
+
+ namespace __detail
+ {
+#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
+ using __platform_wait_clock_t = chrono::steady_clock;
+
+ template<typename _Duration>
+ __atomic_wait_status
+ __platform_wait_until_impl(__platform_wait_t* __addr,
+ __platform_wait_t __val,
+ const chrono::time_point<
+ __platform_wait_clock_t, _Duration>&
+ __atime) noexcept
+ {
+ auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
+ auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
+
+ struct timespec __rt =
+ {
+ static_cast<std::time_t>(__s.time_since_epoch().count()),
+ static_cast<long>(__ns.count())
+ };
+
+ auto __e = syscall (SYS_futex, __addr,
+ static_cast<int>(__futex_wait_flags::
+ __wait_bitset_private),
+ __val, &__rt, nullptr,
+ static_cast<int>(__futex_wait_flags::
+ __bitset_match_any));
+ if (__e && !(errno == EINTR || errno == EAGAIN || errno == ETIMEDOUT))
+ std::terminate();
+ return (__platform_wait_clock_t::now() < __atime)
+ ? __atomic_wait_status::no_timeout
+ : __atomic_wait_status::timeout;
+ }
+
+ template<typename _Clock, typename _Duration>
+ __atomic_wait_status
+ __platform_wait_until(__platform_wait_t* __addr, __platform_wait_t __val,
+ const chrono::time_point<_Clock, _Duration>&
+ __atime)
+ {
+ if constexpr (is_same_v<__platform_wait_clock_t, _Clock>)
+ {
+ return __detail::__platform_wait_until_impl(__addr, __val, __atime);
+ }
+ else
+ {
+ const typename _Clock::time_point __c_entry = _Clock::now();
+ const __platform_wait_clock_t::time_point __s_entry =
+ __platform_wait_clock_t::now();
+ const auto __delta = __atime - __c_entry;
+ const auto __s_atime = __s_entry + __delta;
+ if (__detail::__platform_wait_until_impl(__addr, __val, __s_atime)
+ == __atomic_wait_status::no_timeout)
+ return __atomic_wait_status::no_timeout;
+
+ // We got a timeout when measured against __clock_t but
+ // we need to check against the caller-supplied clock
+ // to tell whether we should return a timeout.
+ if (_Clock::now() < __atime)
+ return __atomic_wait_status::no_timeout;
+ return __atomic_wait_status::timeout;
+ }
+ }
+#else // ! FUTEX
+
+#ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
+ template<typename _Duration>
+ __atomic_wait_status
+ __cond_wait_until_impl(__condvar& __cv, mutex& __mx,
+ const chrono::time_point<chrono::steady_clock, _Duration>& __atime)
+ {
+ auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
+ auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
+
+ __gthread_time_t __ts =
+ {
+ static_cast<std::time_t>(__s.time_since_epoch().count()),
+ static_cast<long>(__ns.count())
+ };
+
+ __cv.wait_until(__mx, CLOCK_MONOTONIC, __ts);
+
+ return (chrono::steady_clock::now() < __atime)
+ ? __atomic_wait_status::no_timeout
+ : __atomic_wait_status::timeout;
+ }
+#endif
+
+ template<typename _Duration>
+ __atomic_wait_status
+ __cond_wait_until_impl(__condvar& __cv, mutex& __mx,
+ const chrono::time_point<chrono::system_clock, _Duration>& __atime)
+ {
+ auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
+ auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
+
+ __gthread_time_t __ts =
+ {
+ static_cast<std::time_t>(__s.time_since_epoch().count()),
+ static_cast<long>(__ns.count())
+ };
+
+ __cv.wait_until(__mx, __ts);
+
+ return (chrono::system_clock::now() < __atime)
+ ? __atomic_wait_status::no_timeout
+ : __atomic_wait_status::timeout;
+ }
+
+ // return true if timeout
+ template<typename _Clock, typename _Duration>
+ __atomic_wait_status
+ __cond_wait_until(__condvar& __cv, mutex& __mx,
+ const chrono::time_point<_Clock, _Duration>& __atime)
+ {
+#ifndef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
+ using __clock_t = chrono::system_clock;
+#else
+ using __clock_t = chrono::steady_clock;
+ if constexpr (is_same_v<_Clock, chrono::steady_clock>)
+ return __detail::__cond_wait_until_impl(__cv, __mx, __atime);
+ else
+#endif
+ if constexpr (is_same_v<_Clock, chrono::system_clock>)
+ return __detail::__cond_wait_until_impl(__cv, __mx, __atime);
+ else
+ {
+ const typename _Clock::time_point __c_entry = _Clock::now();
+ const __clock_t::time_point __s_entry = __clock_t::now();
+ const auto __delta = __atime - __c_entry;
+ const auto __s_atime = __s_entry + __delta;
+ if (__detail::__cond_wait_until_impl(__cv, __mx, __s_atime)
+ == __atomic_wait_status::no_timeout)
+ return __atomic_wait_status::no_timeout;
+ // We got a timeout when measured against __clock_t but
+ // we need to check against the caller-supplied clock
+ // to tell whether we should return a timeout.
+ if (_Clock::now() < __atime)
+ return __atomic_wait_status::no_timeout;
+ return __atomic_wait_status::timeout;
+ }
+ }
+#endif // FUTEX
+
+ struct __timed_waiters : __waiters
+ {
+ template<typename _Clock, typename _Duration>
+ __atomic_wait_status
+ _M_do_wait_until(__platform_wait_t __version,
+ const chrono::time_point<_Clock, _Duration>& __atime)
+ {
+#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
+ return __detail::__platform_wait_until(&_M_ver, __version, __atime);
+#else
+ __platform_wait_t __cur = 0;
+ __waiters::__lock_t __l(_M_mtx);
+ while (__cur <= __version)
+ {
+ if (__detail::__cond_wait_until(_M_cv, _M_mtx, __atime)
+ == __atomic_wait_status::timeout)
+ return __atomic_wait_status::timeout;
+
+ __platform_wait_t __last = __cur;
+ __atomic_load(&_M_ver, &__cur, __ATOMIC_ACQUIRE);
+ if (__cur < __last)
+ break; // break the loop if version overflows
+ }
+ return __atomic_wait_status::no_timeout;
+#endif
+ }
+
+ static __timed_waiters&
+ _S_timed_for(void* __t)
+ {
+ static_assert(sizeof(__timed_waiters) == sizeof(__waiters));
+ return static_cast<__timed_waiters&>(__waiters::_S_for(__t));
+ }
+ };
+ } // namespace __detail
+
+ template<typename _Tp, typename _Pred,
+ typename _Clock, typename _Duration>
+ bool
+ __atomic_wait_until(const _Tp* __addr, _Tp __old, _Pred __pred,
+ const chrono::time_point<_Clock, _Duration>&
+ __atime) noexcept
+ {
+ using namespace __detail;
+
+ if (std::__atomic_spin(__pred))
+ return true;
+
+ auto& __w = __timed_waiters::_S_timed_for((void*)__addr);
+ auto __version = __w._M_enter_wait();
+ do
+ {
+ __atomic_wait_status __res;
+#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
+ if constexpr (__platform_wait_uses_type<_Tp>)
+ {
+ __res = __detail::__platform_wait_until((__platform_wait_t*)(void*) __addr,
+ __old, __atime);
+ }
+ else
+#endif
+ {
+ __res = __w._M_do_wait_until(__version, __atime);
+ }
+ if (__res == __atomic_wait_status::timeout)
+ return false;
+ }
+ while (!__pred() && __atime < _Clock::now());
+ __w._M_leave_wait();
+
+ // if timed out, return false
+ return (_Clock::now() < __atime);
+ }
+
+ template<typename _Tp, typename _Pred,
+ typename _Rep, typename _Period>
+ bool
+ __atomic_wait_for(const _Tp* __addr, _Tp __old, _Pred __pred,
+ const chrono::duration<_Rep, _Period>& __rtime) noexcept
+ {
+ using namespace __detail;
+
+ if (std::__atomic_spin(__pred))
+ return true;
+
+ if (!__rtime.count())
+ return false; // no rtime supplied, and spin did not acquire
+
+ using __dur = chrono::steady_clock::duration;
+ auto __reltime = chrono::duration_cast<__dur>(__rtime);
+ if (__reltime < __rtime)
+ ++__reltime;
+
+ return __atomic_wait_until(__addr, __old, std::move(__pred),
+ chrono::steady_clock::now() + __reltime);
+ }
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+#endif // __cpp_lib_atomic_wait
+#endif // _GLIBCXX_ATOMIC_TIMED_WAIT_H
diff --git a/libstdc++-v3/include/bits/atomic_wait.h b/libstdc++-v3/include/bits/atomic_wait.h
new file mode 100644
index 0000000..5efd96d
--- /dev/null
+++ b/libstdc++-v3/include/bits/atomic_wait.h
@@ -0,0 +1,299 @@
+// -*- C++ -*- header.
+
+// Copyright (C) 2020 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 bits/atomic_wait.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{atomic}
+ */
+
+#ifndef _GLIBCXX_ATOMIC_WAIT_H
+#define _GLIBCXX_ATOMIC_WAIT_H 1
+
+#pragma GCC system_header
+
+#include <bits/c++config.h>
+#if defined _GLIBCXX_HAS_GTHREADS || defined _GLIBCXX_HAVE_LINUX_FUTEX
+#include <bits/functional_hash.h>
+#include <bits/gthr.h>
+#include <ext/numeric_traits.h>
+
+#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
+# include <cerrno>
+# include <climits>
+# include <unistd.h>
+# include <syscall.h>
+# include <bits/functexcept.h>
+// TODO get this from Autoconf
+# define _GLIBCXX_HAVE_LINUX_FUTEX_PRIVATE 1
+#else
+# include <bits/std_mutex.h> // std::mutex, std::__condvar
+#endif
+
+#define __cpp_lib_atomic_wait 201907L
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ namespace __detail
+ {
+ using __platform_wait_t = int;
+
+ constexpr auto __atomic_spin_count_1 = 16;
+ constexpr auto __atomic_spin_count_2 = 12;
+
+ template<typename _Tp>
+ inline constexpr bool __platform_wait_uses_type
+#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
+ = is_same_v<remove_cv_t<_Tp>, __platform_wait_t>;
+#else
+ = false;
+#endif
+
+#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
+ enum class __futex_wait_flags : int
+ {
+#ifdef _GLIBCXX_HAVE_LINUX_FUTEX_PRIVATE
+ __private_flag = 128,
+#else
+ __private_flag = 0,
+#endif
+ __wait = 0,
+ __wake = 1,
+ __wait_bitset = 9,
+ __wake_bitset = 10,
+ __wait_private = __wait | __private_flag,
+ __wake_private = __wake | __private_flag,
+ __wait_bitset_private = __wait_bitset | __private_flag,
+ __wake_bitset_private = __wake_bitset | __private_flag,
+ __bitset_match_any = -1
+ };
+
+ template<typename _Tp>
+ void
+ __platform_wait(const _Tp* __addr, __platform_wait_t __val) noexcept
+ {
+ for(;;)
+ {
+ auto __e = syscall (SYS_futex, static_cast<const void*>(__addr),
+ static_cast<int>(__futex_wait_flags::__wait_private),
+ __val, nullptr);
+ if (!__e || errno == EAGAIN)
+ break;
+ else if (errno != EINTR)
+ __throw_system_error(__e);
+ }
+ }
+
+ template<typename _Tp>
+ void
+ __platform_notify(const _Tp* __addr, bool __all) noexcept
+ {
+ syscall (SYS_futex, static_cast<const void*>(__addr),
+ static_cast<int>(__futex_wait_flags::__wake_private),
+ __all ? INT_MAX : 1);
+ }
+#endif
+
+ struct __waiters
+ {
+ alignas(64) __platform_wait_t _M_ver = 0;
+ alignas(64) __platform_wait_t _M_wait = 0;
+
+#ifndef _GLIBCXX_HAVE_LINUX_FUTEX
+ using __lock_t = lock_guard<mutex>;
+ mutex _M_mtx;
+ __condvar _M_cv;
+
+ __waiters() noexcept = default;
+#endif
+
+ __platform_wait_t
+ _M_enter_wait() noexcept
+ {
+ __platform_wait_t __res;
+ __atomic_load(&_M_ver, &__res, __ATOMIC_ACQUIRE);
+ __atomic_fetch_add(&_M_wait, 1, __ATOMIC_ACQ_REL);
+ return __res;
+ }
+
+ void
+ _M_leave_wait() noexcept
+ {
+ __atomic_fetch_sub(&_M_wait, 1, __ATOMIC_ACQ_REL);
+ }
+
+ void
+ _M_do_wait(__platform_wait_t __version) noexcept
+ {
+#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
+ __platform_wait(&_M_ver, __version);
+#else
+ __platform_wait_t __cur = 0;
+ while (__cur <= __version)
+ {
+ __waiters::__lock_t __l(_M_mtx);
+ _M_cv.wait(_M_mtx);
+ __platform_wait_t __last = __cur;
+ __atomic_load(&_M_ver, &__cur, __ATOMIC_ACQUIRE);
+ if (__cur < __last)
+ break; // break the loop if version overflows
+ }
+#endif
+ }
+
+ bool
+ _M_waiting() const noexcept
+ {
+ __platform_wait_t __res;
+ __atomic_load(&_M_wait, &__res, __ATOMIC_ACQUIRE);
+ return __res;
+ }
+
+ void
+ _M_notify(bool __all) noexcept
+ {
+ __atomic_fetch_add(&_M_ver, 1, __ATOMIC_ACQ_REL);
+#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
+ __platform_notify(&_M_ver, __all);
+#else
+ if (__all)
+ _M_cv.notify_all();
+ else
+ _M_cv.notify_one();
+#endif
+ }
+
+ static __waiters&
+ _S_for(const void* __t)
+ {
+ const unsigned char __mask = 0xf;
+ static __waiters __w[__mask + 1];
+
+ auto __key = _Hash_impl::hash(__t) & __mask;
+ return __w[__key];
+ }
+ };
+
+ struct __waiter
+ {
+ __waiters& _M_w;
+ __platform_wait_t _M_version;
+
+ template<typename _Tp>
+ __waiter(const _Tp* __addr) noexcept
+ : _M_w(__waiters::_S_for(static_cast<const void*>(__addr)))
+ , _M_version(_M_w._M_enter_wait())
+ { }
+
+ ~__waiter()
+ { _M_w._M_leave_wait(); }
+
+ void _M_do_wait() noexcept
+ { _M_w._M_do_wait(_M_version); }
+ };
+
+ inline void
+ __thread_relax() noexcept
+ {
+#if defined __i386__ || defined __x86_64__
+ __builtin_ia32_pause();
+#elif defined _GLIBCXX_USE_SCHED_YIELD
+ __gthread_yield();
+#endif
+ }
+
+ inline void
+ __thread_yield() noexcept
+ {
+#if defined _GLIBCXX_USE_SCHED_YIELD
+ __gthread_yield();
+#endif
+ }
+
+ } // namespace __detail
+
+ template<typename _Pred>
+ bool
+ __atomic_spin(_Pred& __pred) noexcept
+ {
+ for (auto __i = 0; __i < __detail::__atomic_spin_count_1; ++__i)
+ {
+ if (__pred())
+ return true;
+
+ if (__i < __detail::__atomic_spin_count_2)
+ __detail::__thread_relax();
+ else
+ __detail::__thread_yield();
+ }
+ return false;
+ }
+
+ template<typename _Tp, typename _Pred>
+ void
+ __atomic_wait(const _Tp* __addr, _Tp __old, _Pred __pred) noexcept
+ {
+ using namespace __detail;
+ if (std::__atomic_spin(__pred))
+ return;
+
+ __waiter __w(__addr);
+ while (!__pred())
+ {
+ if constexpr (__platform_wait_uses_type<_Tp>)
+ {
+ __platform_wait(__addr, __old);
+ }
+ else
+ {
+ // TODO support timed backoff when this can be moved into the lib
+ __w._M_do_wait();
+ }
+ }
+ }
+
+ template<typename _Tp>
+ void
+ __atomic_notify(const _Tp* __addr, bool __all) noexcept
+ {
+ using namespace __detail;
+ auto& __w = __waiters::_S_for((void*)__addr);
+ if (!__w._M_waiting())
+ return;
+
+#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
+ if constexpr (__platform_wait_uses_type<_Tp>)
+ {
+ __platform_notify((__platform_wait_t*)(void*) __addr, __all);
+ }
+ else
+#endif
+ {
+ __w._M_notify(__all);
+ }
+ }
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+#endif // GTHREADS || LINUX_FUTEX
+#endif // _GLIBCXX_ATOMIC_WAIT_H
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 2e6c880..27302ed 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -653,35 +653,36 @@ namespace std
#define _GLIBCXX_USE_FLOAT128
#endif
-#if __GNUC__ >= 7
-// Assume these are available if the compiler claims to be a recent GCC:
+#ifdef __has_builtin
+# ifdef __is_identifier
+// Intel and older Clang require !__is_identifier for some built-ins:
+# define _GLIBCXX_HAS_BUILTIN(B) __has_builtin(B) || ! __is_identifier(B)
+# else
+# define _GLIBCXX_HAS_BUILTIN(B) __has_builtin(B)
+# endif
+#endif
+
+#if _GLIBCXX_HAS_BUILTIN(__has_unique_object_representations)
# define _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP 1
+#endif
+
+#if _GLIBCXX_HAS_BUILTIN(__is_aggregate)
# define _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE 1
-# define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1
-# if __GNUC__ >= 9
-# define _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 1
-# endif
-# if __GNUC__ >= 11
-# define _GLIBCXX_HAVE_BUILTIN_IS_SAME 1
-# endif
-#elif defined(__is_identifier) && defined(__has_builtin)
-// For non-GNU compilers:
-# if ! __is_identifier(__has_unique_object_representations)
-# define _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP 1
-# endif
-# if ! __is_identifier(__is_aggregate)
-# define _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE 1
-# endif
-# if __has_builtin(__builtin_launder)
-# define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1
-# endif
-# if __has_builtin(__builtin_is_constant_evaluated)
+#endif
+
+#if _GLIBCXX_HAS_BUILTIN(__builtin_is_constant_evaluated)
# define _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 1
-# endif
-# if ! __is_identifier(__is_same)
+#endif
+
+#if _GLIBCXX_HAS_BUILTIN(__is_same)
# define _GLIBCXX_HAVE_BUILTIN_IS_SAME 1
-# endif
-#endif // GCC
+#endif
+
+#if _GLIBCXX_HAS_BUILTIN(__builtin_launder)
+# define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1
+#endif
+
+#undef _GLIBCXX_HAS_BUILTIN
#if _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
# define __glibcxx_assert_1(_Condition) \
diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h
index 8ff4f86..6668caa 100644
--- a/libstdc++-v3/include/bits/iterator_concepts.h
+++ b/libstdc++-v3/include/bits/iterator_concepts.h
@@ -357,6 +357,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Iter>
concept __iter_without_nested_types = !__iter_with_nested_types<_Iter>;
+
+ template<typename _Iter>
+ concept __iter_without_category
+ = !requires { typename _Iter::iterator_category; };
+
} // namespace __detail
template<typename _Iterator>
@@ -396,20 +401,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ using type = typename _Iter::iterator_category; };
template<typename _Iter>
- requires (!requires { typename _Iter::iterator_category; }
- && __detail::__cpp17_randacc_iterator<_Iter>)
+ requires __detail::__iter_without_category<_Iter>
+ && __detail::__cpp17_randacc_iterator<_Iter>
struct __cat<_Iter>
{ using type = random_access_iterator_tag; };
template<typename _Iter>
- requires (!requires { typename _Iter::iterator_category; }
- && __detail::__cpp17_bidi_iterator<_Iter>)
+ requires __detail::__iter_without_category<_Iter>
+ && __detail::__cpp17_bidi_iterator<_Iter>
struct __cat<_Iter>
{ using type = bidirectional_iterator_tag; };
template<typename _Iter>
- requires (!requires { typename _Iter::iterator_category; }
- && __detail::__cpp17_fwd_iterator<_Iter>)
+ requires __detail::__iter_without_category<_Iter>
+ && __detail::__cpp17_fwd_iterator<_Iter>
struct __cat<_Iter>
{ using type = forward_iterator_tag; };
diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h
index 5a4dbdc..b33c22a 100644
--- a/libstdc++-v3/include/bits/move.h
+++ b/libstdc++-v3/include/bits/move.h
@@ -158,9 +158,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @} group utilities
+#define _GLIBCXX_FWDREF(_Tp) _Tp&&
#define _GLIBCXX_MOVE(__val) std::move(__val)
#define _GLIBCXX_FORWARD(_Tp, __val) std::forward<_Tp>(__val)
#else
+#define _GLIBCXX_FWDREF(_Tp) const _Tp&
#define _GLIBCXX_MOVE(__val) (__val)
#define _GLIBCXX_FORWARD(_Tp, __val) (__val)
#endif
diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h
index f1a4cc2..3905fe4 100644
--- a/libstdc++-v3/include/bits/ranges_algo.h
+++ b/libstdc++-v3/include/bits/ranges_algo.h
@@ -579,7 +579,8 @@ namespace ranges
}
}
- if constexpr (sized_sentinel_for<_Sent, _Iter>)
+ if constexpr (sized_sentinel_for<_Sent, _Iter>
+ && random_access_iterator<_Iter>)
{
auto __tail_size = __last - __first;
auto __remainder = __count;
@@ -594,6 +595,7 @@ namespace ranges
if (--__remainder == 0)
return {__first - __count, __first};
}
+ __remainder = __count + 1 - (__first - __backtrack);
}
auto __i = __first + __tail_size;
return {__i, __i};
diff --git a/libstdc++-v3/include/bits/semaphore_base.h b/libstdc++-v3/include/bits/semaphore_base.h
new file mode 100644
index 0000000..e4e57de
--- /dev/null
+++ b/libstdc++-v3/include/bits/semaphore_base.h
@@ -0,0 +1,301 @@
+// -*- C++ -*- header.
+
+// Copyright (C) 2020 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 bits/semaphore_base.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{semaphore}
+ */
+
+#ifndef _GLIBCXX_SEMAPHORE_BASE_H
+#define _GLIBCXX_SEMAPHORE_BASE_H 1
+
+#pragma GCC system_header
+
+#include <bits/atomic_base.h>
+#if __cpp_lib_atomic_wait
+#include <bits/atomic_timed_wait.h>
+
+#include <ext/numeric_traits.h>
+
+#ifdef _GLIBCXX_HAVE_POSIX_SEMAPHORE
+# include <limits.h>
+# include <semaphore.h>
+#endif
+
+#include <chrono>
+#include <type_traits>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#ifdef _GLIBCXX_HAVE_POSIX_SEMAPHORE
+ struct __platform_semaphore
+ {
+ using __clock_t = chrono::system_clock;
+#ifdef SEM_VALUE_MAX
+ static constexpr ptrdiff_t _S_max = SEM_VALUE_MAX;
+#else
+ static constexpr ptrdiff_t _S_max = _POSIX_SEM_VALUE_MAX;
+#endif
+
+ explicit __platform_semaphore(ptrdiff_t __count) noexcept
+ {
+ sem_init(&_M_semaphore, 0, __count);
+ }
+
+ __platform_semaphore(const __platform_semaphore&) = delete;
+ __platform_semaphore& operator=(const __platform_semaphore&) = delete;
+
+ ~__platform_semaphore()
+ { sem_destroy(&_M_semaphore); }
+
+ _GLIBCXX_ALWAYS_INLINE void
+ _M_acquire() noexcept
+ {
+ for (;;)
+ {
+ auto __err = sem_wait(&_M_semaphore);
+ if (__err && (errno == EINTR))
+ continue;
+ else if (__err)
+ std::terminate();
+ else
+ break;
+ }
+ }
+
+ _GLIBCXX_ALWAYS_INLINE void
+ _M_release(std::ptrdiff_t __update) noexcept
+ {
+ for(; __update != 0; --__update)
+ {
+ auto __err = sem_post(&_M_semaphore);
+ if (__err)
+ std::terminate();
+ }
+ }
+
+ bool
+ _M_try_acquire_until_impl(const chrono::time_point<__clock_t>& __atime)
+ noexcept
+ {
+
+ auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
+ auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
+
+ struct timespec __ts =
+ {
+ static_cast<std::time_t>(__s.time_since_epoch().count()),
+ static_cast<long>(__ns.count())
+ };
+
+ for (;;)
+ {
+ if (auto __err = sem_timedwait(&_M_semaphore, &__ts))
+ {
+ if (errno == EINTR)
+ continue;
+ else if (errno == ETIMEDOUT || errno == EINVAL)
+ return false;
+ else
+ std::terminate();
+ }
+ else
+ break;
+ }
+ return true;
+ }
+
+ template<typename _Clock, typename _Duration>
+ bool
+ _M_try_acquire_until(const chrono::time_point<_Clock,
+ _Duration>& __atime) noexcept
+ {
+ if constexpr (std::is_same_v<__clock_t, _Clock>)
+ {
+ return _M_try_acquire_until_impl(__atime);
+ }
+ else
+ {
+ const typename _Clock::time_point __c_entry = _Clock::now();
+ const auto __s_entry = __clock_t::now();
+ const auto __delta = __atime - __c_entry;
+ const auto __s_atime = __s_entry + __delta;
+ if (_M_try_acquire_until_impl(__s_atime))
+ return true;
+
+ // We got a timeout when measured against __clock_t but
+ // we need to check against the caller-supplied clock
+ // to tell whether we should return a timeout.
+ return (_Clock::now() < __atime);
+ }
+ }
+
+ template<typename _Rep, typename _Period>
+ _GLIBCXX_ALWAYS_INLINE bool
+ _M_try_acquire_for(const chrono::duration<_Rep, _Period>& __rtime)
+ noexcept
+ { return _M_try_acquire_until(__clock_t::now() + __rtime); }
+
+ private:
+ sem_t _M_semaphore;
+ };
+#endif // _GLIBCXX_HAVE_POSIX_SEMAPHORE
+
+ template<typename _Tp>
+ struct __atomic_semaphore
+ {
+ static_assert(std::is_integral_v<_Tp>);
+ static_assert(__gnu_cxx::__int_traits<_Tp>::__max
+ <= __gnu_cxx::__int_traits<ptrdiff_t>::__max);
+ static constexpr ptrdiff_t _S_max = __gnu_cxx::__int_traits<_Tp>::__max;
+
+ explicit __atomic_semaphore(_Tp __count) noexcept
+ : _M_counter(__count)
+ {
+ __glibcxx_assert(__count >= 0 && __count <= _S_max);
+ }
+
+ __atomic_semaphore(const __atomic_semaphore&) = delete;
+ __atomic_semaphore& operator=(const __atomic_semaphore&) = delete;
+
+ _GLIBCXX_ALWAYS_INLINE void
+ _M_acquire() noexcept
+ {
+ auto const __pred = [this]
+ {
+ auto __old = __atomic_impl::load(&this->_M_counter,
+ memory_order::acquire);
+ if (__old == 0)
+ return false;
+ return __atomic_impl::compare_exchange_strong(&this->_M_counter,
+ __old, __old - 1,
+ memory_order::acquire,
+ memory_order::release);
+ };
+ auto __old = __atomic_impl::load(&_M_counter, memory_order_relaxed);
+ std::__atomic_wait(&_M_counter, __old, __pred);
+ }
+
+ bool
+ _M_try_acquire() noexcept
+ {
+ auto __old = __atomic_impl::load(&_M_counter, memory_order::acquire);
+ auto const __pred = [this, __old]
+ {
+ if (__old == 0)
+ return false;
+
+ auto __prev = __old;
+ return __atomic_impl::compare_exchange_weak(&this->_M_counter,
+ __prev, __prev - 1,
+ memory_order::acquire,
+ memory_order::release);
+ };
+ return std::__atomic_spin(__pred);
+ }
+
+ template<typename _Clock, typename _Duration>
+ _GLIBCXX_ALWAYS_INLINE bool
+ _M_try_acquire_until(const chrono::time_point<_Clock,
+ _Duration>& __atime) noexcept
+ {
+ auto const __pred = [this]
+ {
+ auto __old = __atomic_impl::load(&this->_M_counter,
+ memory_order::acquire);
+ if (__old == 0)
+ return false;
+ return __atomic_impl::compare_exchange_strong(&this->_M_counter,
+ __old, __old - 1,
+ memory_order::acquire,
+ memory_order::release);
+ };
+
+ auto __old = __atomic_impl::load(&_M_counter, memory_order_relaxed);
+ return __atomic_wait_until(&_M_counter, __old, __pred, __atime);
+ }
+
+ template<typename _Rep, typename _Period>
+ _GLIBCXX_ALWAYS_INLINE bool
+ _M_try_acquire_for(const chrono::duration<_Rep, _Period>& __rtime)
+ noexcept
+ {
+ auto const __pred = [this]
+ {
+ auto __old = __atomic_impl::load(&this->_M_counter,
+ memory_order::acquire);
+ if (__old == 0)
+ return false;
+ return __atomic_impl::compare_exchange_strong(&this->_M_counter,
+ __old, __old - 1,
+ memory_order::acquire,
+ memory_order::release);
+ };
+
+ auto __old = __atomic_impl::load(&_M_counter, memory_order_relaxed);
+ return __atomic_wait_for(&_M_counter, __old, __pred, __rtime);
+ }
+
+ _GLIBCXX_ALWAYS_INLINE void
+ _M_release(ptrdiff_t __update) noexcept
+ {
+ if (0 < __atomic_impl::fetch_add(&_M_counter, __update, memory_order_release))
+ return;
+ if (__update > 1)
+ __atomic_impl::notify_all(&_M_counter);
+ else
+ __atomic_impl::notify_one(&_M_counter);
+ }
+
+ private:
+ alignas(__alignof__(_Tp)) _Tp _M_counter;
+ };
+
+// Note: the _GLIBCXX_REQUIRE_POSIX_SEMAPHORE macro can be used to force the
+// use of Posix semaphores (sem_t). Doing so however, alters the ABI.
+#ifdef _GLIBCXX_HAVE_LINUX_FUTEX && !_GLIBCXX_REQUIRE_POSIX_SEMAPHORE
+ // Use futex if available and didn't force use of POSIX
+ using __fast_semaphore = __atomic_semaphore<__detail::__platform_wait_t>;
+#elif _GLIBCXX_HAVE_POSIX_SEMAPHORE
+ using __fast_semaphore = __platform_semaphore;
+#else
+ using __fast_semaphore = __atomic_semaphore<ptrdiff_t>;
+#endif
+
+template<ptrdiff_t __least_max_value>
+ using __semaphore_impl = conditional_t<
+ (__least_max_value > 1),
+ conditional_t<
+ (__least_max_value <= __fast_semaphore::_S_max),
+ __fast_semaphore,
+ __atomic_semaphore<ptrdiff_t>>,
+ __fast_semaphore>;
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // __cpp_lib_atomic_wait
+#endif // _GLIBCXX_SEMAPHORE_BASE_H
diff --git a/libstdc++-v3/include/bits/std_mutex.h b/libstdc++-v3/include/bits/std_mutex.h
index 56c853a..f308bf3 100644
--- a/libstdc++-v3/include/bits/std_mutex.h
+++ b/libstdc++-v3/include/bits/std_mutex.h
@@ -123,6 +123,76 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return &_M_mutex; }
};
+ // Implementation details for std::condition_variable
+ class __condvar
+ {
+ using timespec = __gthread_time_t;
+
+ public:
+ __condvar() noexcept
+ {
+#ifndef __GTHREAD_COND_INIT
+ __GTHREAD_COND_INIT_FUNCTION(&_M_cond);
+#endif
+ }
+
+ ~__condvar()
+ {
+ int __e __attribute__((__unused__)) = __gthread_cond_destroy(&_M_cond);
+ __glibcxx_assert(__e != EBUSY); // threads are still blocked
+ }
+
+ __condvar(const __condvar&) = delete;
+ __condvar& operator=(const __condvar&) = delete;
+
+ __gthread_cond_t* native_handle() noexcept { return &_M_cond; }
+
+ // Expects: Calling thread has locked __m.
+ void
+ wait(mutex& __m) noexcept
+ {
+ int __e __attribute__((__unused__))
+ = __gthread_cond_wait(&_M_cond, __m.native_handle());
+ __glibcxx_assert(__e == 0);
+ }
+
+ void
+ wait_until(mutex& __m, timespec& __abs_time) noexcept
+ {
+ __gthread_cond_timedwait(&_M_cond, __m.native_handle(), &__abs_time);
+ }
+
+#ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
+ void
+ wait_until(mutex& __m, clockid_t __clock, timespec& __abs_time) noexcept
+ {
+ pthread_cond_clockwait(&_M_cond, __m.native_handle(), __clock,
+ &__abs_time);
+ }
+#endif
+
+ void
+ notify_one() noexcept
+ {
+ int __e __attribute__((__unused__)) = __gthread_cond_signal(&_M_cond);
+ __glibcxx_assert(__e == 0);
+ }
+
+ void
+ notify_all() noexcept
+ {
+ int __e __attribute__((__unused__)) = __gthread_cond_broadcast(&_M_cond);
+ __glibcxx_assert(__e == 0);
+ }
+
+ protected:
+#ifdef __GTHREAD_COND_INIT
+ __gthread_cond_t _M_cond = __GTHREAD_COND_INIT;
+#else
+ __gthread_cond_t _M_cond;
+#endif
+ };
+
#endif // _GLIBCXX_HAS_GTHREADS
/// Do not acquire ownership of the mutex.
diff --git a/libstdc++-v3/include/bits/std_thread.h b/libstdc++-v3/include/bits/std_thread.h
new file mode 100644
index 0000000..24bd5fb
--- /dev/null
+++ b/libstdc++-v3/include/bits/std_thread.h
@@ -0,0 +1,323 @@
+// std::thread declarations -*- C++ -*-
+
+// Copyright (C) 2008-2020 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 bits/std_thread.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{thread}
+ */
+
+#ifndef _GLIBCXX_THREAD_H
+#define _GLIBCXX_THREAD_H 1
+
+#pragma GCC system_header
+
+#if __cplusplus >= 201103L
+#include <bits/c++config.h>
+
+#include <exception> // std::terminate
+#include <iosfwd> // std::basic_ostream
+#include <tuple> // std::tuple
+#include <bits/invoke.h> // std::__invoke
+#include <bits/refwrap.h> // not required, but helpful to users
+#include <bits/unique_ptr.h> // std::unique_ptr
+
+#ifdef _GLIBCXX_HAS_GTHREADS
+# include <bits/gthr.h>
+#else
+# include <errno.h>
+# include <bits/functexcept.h>
+#endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ /** @addtogroup threads
+ * @{
+ */
+
+ /// thread
+ class thread
+ {
+ public:
+#ifdef _GLIBCXX_HAS_GTHREADS
+ // Abstract base class for types that wrap arbitrary functors to be
+ // invoked in the new thread of execution.
+ struct _State
+ {
+ virtual ~_State();
+ virtual void _M_run() = 0;
+ };
+ using _State_ptr = unique_ptr<_State>;
+
+ using native_handle_type = __gthread_t;
+#else
+ using native_handle_type = int;
+#endif
+
+ /// thread::id
+ class id
+ {
+ native_handle_type _M_thread;
+
+ public:
+ id() noexcept : _M_thread() { }
+
+ explicit
+ id(native_handle_type __id) : _M_thread(__id) { }
+
+ private:
+ friend class thread;
+ friend struct hash<id>;
+
+ friend bool
+ operator==(id __x, id __y) noexcept;
+
+#if __cpp_lib_three_way_comparison
+ friend strong_ordering
+ operator<=>(id __x, id __y) noexcept;
+#else
+ friend bool
+ operator<(id __x, id __y) noexcept;
+#endif
+
+ template<class _CharT, class _Traits>
+ friend basic_ostream<_CharT, _Traits>&
+ operator<<(basic_ostream<_CharT, _Traits>& __out, id __id);
+ };
+
+ private:
+ id _M_id;
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2097. packaged_task constructors should be constrained
+ // 3039. Unnecessary decay in thread and packaged_task
+ template<typename _Tp>
+ using __not_same = __not_<is_same<__remove_cvref_t<_Tp>, thread>>;
+
+ public:
+ thread() noexcept = default;
+
+#ifdef _GLIBCXX_HAS_GTHREADS
+ template<typename _Callable, typename... _Args,
+ typename = _Require<__not_same<_Callable>>>
+ explicit
+ thread(_Callable&& __f, _Args&&... __args)
+ {
+ static_assert( __is_invocable<typename decay<_Callable>::type,
+ typename decay<_Args>::type...>::value,
+ "std::thread arguments must be invocable after conversion to rvalues"
+ );
+
+#ifdef GTHR_ACTIVE_PROXY
+ // Create a reference to pthread_create, not just the gthr weak symbol.
+ auto __depend = reinterpret_cast<void(*)()>(&pthread_create);
+#else
+ auto __depend = nullptr;
+#endif
+ using _Wrapper = _Call_wrapper<_Callable, _Args...>;
+ // Create a call wrapper with DECAY_COPY(__f) as its target object
+ // and DECAY_COPY(__args)... as its bound argument entities.
+ _M_start_thread(_State_ptr(new _State_impl<_Wrapper>(
+ std::forward<_Callable>(__f), std::forward<_Args>(__args)...)),
+ __depend);
+ }
+#endif // _GLIBCXX_HAS_GTHREADS
+
+ ~thread()
+ {
+ if (joinable())
+ std::terminate();
+ }
+
+ thread(const thread&) = delete;
+
+ thread(thread&& __t) noexcept
+ { swap(__t); }
+
+ thread& operator=(const thread&) = delete;
+
+ thread& operator=(thread&& __t) noexcept
+ {
+ if (joinable())
+ std::terminate();
+ swap(__t);
+ return *this;
+ }
+
+ void
+ swap(thread& __t) noexcept
+ { std::swap(_M_id, __t._M_id); }
+
+ bool
+ joinable() const noexcept
+ { return !(_M_id == id()); }
+
+ void
+ join();
+
+ void
+ detach();
+
+ id
+ get_id() const noexcept
+ { return _M_id; }
+
+ /** @pre thread is joinable
+ */
+ native_handle_type
+ native_handle()
+ { return _M_id._M_thread; }
+
+ // Returns a value that hints at the number of hardware thread contexts.
+ static unsigned int
+ hardware_concurrency() noexcept;
+
+#ifdef _GLIBCXX_HAS_GTHREADS
+ private:
+ template<typename _Callable>
+ struct _State_impl : public _State
+ {
+ _Callable _M_func;
+
+ template<typename... _Args>
+ _State_impl(_Args&&... __args)
+ : _M_func{{std::forward<_Args>(__args)...}}
+ { }
+
+ void
+ _M_run() { _M_func(); }
+ };
+
+ void
+ _M_start_thread(_State_ptr, void (*)());
+
+#if _GLIBCXX_THREAD_ABI_COMPAT
+ public:
+ struct _Impl_base;
+ typedef shared_ptr<_Impl_base> __shared_base_type;
+ struct _Impl_base
+ {
+ __shared_base_type _M_this_ptr;
+ virtual ~_Impl_base() = default;
+ virtual void _M_run() = 0;
+ };
+
+ private:
+ void
+ _M_start_thread(__shared_base_type, void (*)());
+
+ void
+ _M_start_thread(__shared_base_type);
+#endif
+
+ private:
+ // A call wrapper that does INVOKE(forwarded tuple elements...)
+ template<typename _Tuple>
+ struct _Invoker
+ {
+ _Tuple _M_t;
+
+ template<typename>
+ struct __result;
+ template<typename _Fn, typename... _Args>
+ struct __result<tuple<_Fn, _Args...>>
+ : __invoke_result<_Fn, _Args...>
+ { };
+
+ template<size_t... _Ind>
+ typename __result<_Tuple>::type
+ _M_invoke(_Index_tuple<_Ind...>)
+ { return std::__invoke(std::get<_Ind>(std::move(_M_t))...); }
+
+ typename __result<_Tuple>::type
+ operator()()
+ {
+ using _Indices
+ = typename _Build_index_tuple<tuple_size<_Tuple>::value>::__type;
+ return _M_invoke(_Indices());
+ }
+ };
+
+ public:
+ template<typename... _Tp>
+ using _Call_wrapper = _Invoker<tuple<typename decay<_Tp>::type...>>;
+#endif // _GLIBCXX_HAS_GTHREADS
+ };
+
+#ifndef _GLIBCXX_HAS_GTHREADS
+ inline void thread::join() { std::__throw_system_error(EINVAL); }
+ inline void thread::detach() { std::__throw_system_error(EINVAL); }
+ inline unsigned int thread::hardware_concurrency() { return 0; }
+#endif
+
+ inline void
+ swap(thread& __x, thread& __y) noexcept
+ { __x.swap(__y); }
+
+ inline bool
+ operator==(thread::id __x, thread::id __y) noexcept
+ {
+ // pthread_equal is undefined if either thread ID is not valid, so we
+ // can't safely use __gthread_equal on default-constructed values (nor
+ // the non-zero value returned by this_thread::get_id() for
+ // single-threaded programs using GNU libc). Assume EqualityComparable.
+ return __x._M_thread == __y._M_thread;
+ }
+
+ // N.B. other comparison operators are defined in <thread>
+
+ namespace this_thread
+ {
+ /// this_thread::get_id
+ inline thread::id
+ get_id() noexcept
+ {
+#ifndef _GLIBCXX_HAS_GTHREADS
+ return thread::id(1);
+#elif defined _GLIBCXX_NATIVE_THREAD_ID
+ return thread::id(_GLIBCXX_NATIVE_THREAD_ID);
+#else
+ return thread::id(__gthread_self());
+#endif
+ }
+
+ /// this_thread::yield
+ inline void
+ yield() noexcept
+ {
+#if defined _GLIBCXX_HAS_GTHREADS && defined _GLIBCXX_USE_SCHED_YIELD
+ __gthread_yield();
+#endif
+ }
+
+ } // namespace this_thread
+
+ /// @}
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+#endif // C++11
+
+#endif // _GLIBCXX_THREAD_H
diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h
index 6efc990..cb74841 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -2523,6 +2523,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_ValueType;
typedef typename iterator_traits<_BidirectionalIterator>::difference_type
_DistanceType;
+ typedef _Temporary_buffer<_BidirectionalIterator, _ValueType> _TmpBuf;
if (__first == __middle || __middle == __last)
return;
@@ -2530,8 +2531,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const _DistanceType __len1 = std::distance(__first, __middle);
const _DistanceType __len2 = std::distance(__middle, __last);
- typedef _Temporary_buffer<_BidirectionalIterator, _ValueType> _TmpBuf;
- _TmpBuf __buf(__first, __len1 + __len2);
+ // __merge_adaptive will use a buffer for the smaller of
+ // [first,middle) and [middle,last).
+ _TmpBuf __buf(__first, std::min(__len1, __len2));
if (__buf.begin() == 0)
std::__merge_without_buffer
@@ -2740,6 +2742,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::__merge_sort_with_buffer(__first, __middle, __buffer, __comp);
std::__merge_sort_with_buffer(__middle, __last, __buffer, __comp);
}
+
std::__merge_adaptive(__first, __middle, __last,
_Distance(__middle - __first),
_Distance(__last - __middle),
@@ -5005,9 +5008,14 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
_ValueType;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type
_DistanceType;
-
typedef _Temporary_buffer<_RandomAccessIterator, _ValueType> _TmpBuf;
- _TmpBuf __buf(__first, std::distance(__first, __last));
+
+ if (__first == __last)
+ return;
+
+ // __stable_sort_adaptive sorts the range in two halves,
+ // so the buffer only needs to fit half the range at once.
+ _TmpBuf __buf(__first, (__last - __first + 1) / 2);
if (__buf.begin() == 0)
std::__inplace_stable_sort(__first, __last, __comp);
diff --git a/libstdc++-v3/include/bits/stl_tempbuf.h b/libstdc++-v3/include/bits/stl_tempbuf.h
index f6f1796..d76ed7f 100644
--- a/libstdc++-v3/include/bits/stl_tempbuf.h
+++ b/libstdc++-v3/include/bits/stl_tempbuf.h
@@ -110,7 +110,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::nothrow));
if (__tmp != 0)
return std::pair<_Tp*, ptrdiff_t>(__tmp, __len);
- __len /= 2;
+ __len = __len == 1 ? 0 : ((__len + 1) / 2);
}
return std::pair<_Tp*, ptrdiff_t>(static_cast<_Tp*>(0), 0);
}
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index ec141ea..a51d6da 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -478,11 +478,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Arg>
_Link_type
-#if __cplusplus < 201103L
- operator()(const _Arg& __arg)
-#else
- operator()(_Arg&& __arg)
-#endif
+ operator()(_GLIBCXX_FWDREF(_Arg) __arg)
{
_Link_type __node = static_cast<_Link_type>(_M_extract());
if (__node)
@@ -544,11 +540,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Arg>
_Link_type
-#if __cplusplus < 201103L
- operator()(const _Arg& __arg) const
-#else
- operator()(_Arg&& __arg) const
-#endif
+ operator()(_GLIBCXX_FWDREF(_Arg) __arg) const
{ return _M_t._M_create_node(_GLIBCXX_FORWARD(_Arg, __arg)); }
private:
@@ -655,11 +647,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_put_node(__p);
}
- template<typename _NodeGen>
+ template<bool _MoveValue, typename _NodeGen>
_Link_type
- _M_clone_node(_Const_Link_type __x, _NodeGen& __node_gen)
+ _M_clone_node(_Link_type __x, _NodeGen& __node_gen)
{
- _Link_type __tmp = __node_gen(*__x->_M_valptr());
+#if __cplusplus >= 201103L
+ using _Vp = typename conditional<_MoveValue,
+ value_type&&,
+ const value_type&>::type;
+#endif
+ _Link_type __tmp
+ = __node_gen(_GLIBCXX_FORWARD(_Vp, *__x->_M_valptr()));
__tmp->_M_color = __x->_M_color;
__tmp->_M_left = 0;
__tmp->_M_right = 0;
@@ -748,9 +746,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return this->_M_impl._M_header._M_right; }
_Link_type
- _M_begin() _GLIBCXX_NOEXCEPT
+ _M_mbegin() const _GLIBCXX_NOEXCEPT
{ return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); }
+ _Link_type
+ _M_begin() _GLIBCXX_NOEXCEPT
+ { return _M_mbegin(); }
+
_Const_Link_type
_M_begin() const _GLIBCXX_NOEXCEPT
{
@@ -889,15 +891,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_insert_equal_lower(const value_type& __x);
#endif
- template<typename _NodeGen>
+ enum { __as_lvalue, __as_rvalue };
+
+ template<bool _MoveValues, typename _NodeGen>
_Link_type
- _M_copy(_Const_Link_type __x, _Base_ptr __p, _NodeGen&);
+ _M_copy(_Link_type, _Base_ptr, _NodeGen&);
- template<typename _NodeGen>
+ template<bool _MoveValues, typename _NodeGen>
_Link_type
_M_copy(const _Rb_tree& __x, _NodeGen& __gen)
{
- _Link_type __root = _M_copy(__x._M_begin(), _M_end(), __gen);
+ _Link_type __root =
+ _M_copy<_MoveValues>(__x._M_mbegin(), _M_end(), __gen);
_M_leftmost() = _S_minimum(__root);
_M_rightmost() = _S_maximum(__root);
_M_impl._M_node_count = __x._M_impl._M_node_count;
@@ -908,7 +913,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_copy(const _Rb_tree& __x)
{
_Alloc_node __an(*this);
- return _M_copy(__x, __an);
+ return _M_copy<__as_lvalue>(__x, __an);
}
void
@@ -1655,13 +1660,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
else
{
_Alloc_node __an(*this);
- auto __lbd =
- [&__an](const value_type& __cval)
- {
- auto& __val = const_cast<value_type&>(__cval);
- return __an(std::move_if_noexcept(__val));
- };
- _M_root() = _M_copy(__x, __lbd);
+ _M_root() =
+ _M_copy<!__move_if_noexcept_cond<value_type>::value>(__x, __an);
}
}
@@ -1693,13 +1693,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_impl._M_reset();
if (__x._M_root() != nullptr)
{
- auto __lbd =
- [&__roan](const value_type& __cval)
- {
- auto& __val = const_cast<value_type&>(__cval);
- return __roan(std::move(__val));
- };
- _M_root() = _M_copy(__x, __lbd);
+ _M_root() = _M_copy<__as_rvalue>(__x, __roan);
__x.clear();
}
}
@@ -1773,7 +1767,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_impl._M_reset();
_M_impl._M_key_compare = __x._M_impl._M_key_compare;
if (__x._M_root() != 0)
- _M_root() = _M_copy(__x, __roan);
+ _M_root() = _M_copy<__as_lvalue>(__x, __roan);
}
return *this;
@@ -1859,29 +1853,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Key, typename _Val, typename _KoV,
typename _Compare, typename _Alloc>
- template<typename _NodeGen>
+ template<bool _MoveValues, typename _NodeGen>
typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type
_Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::
- _M_copy(_Const_Link_type __x, _Base_ptr __p, _NodeGen& __node_gen)
+ _M_copy(_Link_type __x, _Base_ptr __p, _NodeGen& __node_gen)
{
// Structural copy. __x and __p must be non-null.
- _Link_type __top = _M_clone_node(__x, __node_gen);
+ _Link_type __top = _M_clone_node<_MoveValues>(__x, __node_gen);
__top->_M_parent = __p;
__try
{
if (__x->_M_right)
- __top->_M_right = _M_copy(_S_right(__x), __top, __node_gen);
+ __top->_M_right =
+ _M_copy<_MoveValues>(_S_right(__x), __top, __node_gen);
__p = __top;
__x = _S_left(__x);
while (__x != 0)
{
- _Link_type __y = _M_clone_node(__x, __node_gen);
+ _Link_type __y = _M_clone_node<_MoveValues>(__x, __node_gen);
__p->_M_left = __y;
__y->_M_parent = __p;
if (__x->_M_right)
- __y->_M_right = _M_copy(_S_right(__x), __y, __node_gen);
+ __y->_M_right = _M_copy<_MoveValues>(_S_right(__x),
+ __y, __node_gen);
__p = __y;
__x = _S_left(__x);
}
diff --git a/libstdc++-v3/include/ext/numeric_traits.h b/libstdc++-v3/include/ext/numeric_traits.h
index 585ecc0..2cac7f1 100644
--- a/libstdc++-v3/include/ext/numeric_traits.h
+++ b/libstdc++-v3/include/ext/numeric_traits.h
@@ -39,31 +39,23 @@ namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Compile time constants for builtin types.
- // In C++98 std::numeric_limits member functions cannot be used for this.
-#define __glibcxx_signed(_Tp) ((_Tp)(-1) < 0)
-#define __glibcxx_digits(_Tp) \
- (sizeof(_Tp) * __CHAR_BIT__ - __glibcxx_signed(_Tp))
-
-#define __glibcxx_min(_Tp) \
- (__glibcxx_signed(_Tp) ? -__glibcxx_max(_Tp) - 1 : (_Tp)0)
-
-#define __glibcxx_max(_Tp) \
- (__glibcxx_signed(_Tp) ? \
- (((((_Tp)1 << (__glibcxx_digits(_Tp) - 1)) - 1) << 1) + 1) : ~(_Tp)0)
-
+ // In C++98 std::numeric_limits member functions are not constant expressions
+ // (that changed in C++11 with the addition of 'constexpr').
+ // Even for C++11, this header is smaller than <limits> and can be used
+ // when only is_signed, digits, min, or max values are needed for integers,
+ // or is_signed, digits10, max_digits10, or max_exponent10 for floats.
+
+ // Unlike __is_integer (and std::is_integral) this trait is true for
+ // non-standard built-in integer types such as __int128 and __int20.
template<typename _Tp>
struct __is_integer_nonstrict
: public std::__is_integer<_Tp>
- { };
-
-#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
- // __is_integer<__int128> is false, but we still want to allow it here.
- template<> struct __is_integer_nonstrict<__int128>
- { enum { __value = 1 }; typedef std::__true_type __type; };
+ {
+ using std::__is_integer<_Tp>::__value;
- template<> struct __is_integer_nonstrict<unsigned __int128>
- { enum { __value = 1 }; typedef std::__true_type __type; };
-#endif
+ // The number of bits in the value representation.
+ enum { __width = __value ? sizeof(_Tp) * __CHAR_BIT__ : 0 };
+ };
template<typename _Value>
struct __numeric_traits_integer
@@ -73,14 +65,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
"invalid specialization");
#endif
- // Only integers for initialization of member constant.
- static const _Value __min = __glibcxx_min(_Value);
- static const _Value __max = __glibcxx_max(_Value);
-
- // NB: these two also available in std::numeric_limits as compile
- // time constants, but <limits> is big and we avoid including it.
- static const bool __is_signed = __glibcxx_signed(_Value);
- static const int __digits = __glibcxx_digits(_Value);
+ // NB: these two are also available in std::numeric_limits as compile
+ // time constants, but <limits> is big and we can avoid including it.
+ static const bool __is_signed = (_Value)(-1) < 0;
+ static const int __digits
+ = __is_integer_nonstrict<_Value>::__width - __is_signed;
+
+ // The initializers must be constants so that __max and __min are too.
+ static const _Value __max = __is_signed
+ ? (((((_Value)1 << (__digits - 1)) - 1) << 1) + 1)
+ : ~(_Value)0;
+ static const _Value __min = __is_signed ? -__max - 1 : (_Value)0;
};
template<typename _Value>
@@ -95,16 +90,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Value>
const int __numeric_traits_integer<_Value>::__digits;
+ // Enable __numeric_traits_integer for types where the __is_integer_nonstrict
+ // primary template doesn't give the right answer.
+#define _GLIBCXX_INT_N_TRAITS(T, WIDTH) \
+ template<> struct __is_integer_nonstrict<T> \
+ { \
+ enum { __value = 1 }; \
+ typedef std::__true_type __type; \
+ enum { __width = WIDTH }; \
+ }; \
+ template<> struct __is_integer_nonstrict<unsigned T> \
+ { \
+ enum { __value = 1 }; \
+ typedef std::__true_type __type; \
+ enum { __width = WIDTH }; \
+ };
+
+ // We need to specify the width for some __intNN types because they
+ // have padding bits, e.g. the object representation of __int20 has 32 bits,
+ // but its width (number of bits in the value representation) is only 20.
+#if defined __GLIBCXX_TYPE_INT_N_0 && __GLIBCXX_BITSIZE_INT_N_0 % __CHAR_BIT__
+ _GLIBCXX_INT_N_TRAITS(__GLIBCXX_TYPE_INT_N_0, __GLIBCXX_BITSIZE_INT_N_0)
+#endif
+#if defined __GLIBCXX_TYPE_INT_N_1 && __GLIBCXX_BITSIZE_INT_N_1 % __CHAR_BIT__
+ _GLIBCXX_INT_N_TRAITS(__GLIBCXX_TYPE_INT_N_1, __GLIBCXX_BITSIZE_INT_N_1)
+#endif
+#if defined __GLIBCXX_TYPE_INT_N_2 && __GLIBCXX_BITSIZE_INT_N_2 % __CHAR_BIT__
+ _GLIBCXX_INT_N_TRAITS(__GLIBCXX_TYPE_INT_N_2, __GLIBCXX_BITSIZE_INT_N_2)
+#endif
+#if defined __GLIBCXX_TYPE_INT_N_3 && __GLIBCXX_BITSIZE_INT_N_3 % __CHAR_BIT__
+ _GLIBCXX_INT_N_TRAITS(__GLIBCXX_TYPE_INT_N_3, __GLIBCXX_BITSIZE_INT_N_3)
+#endif
+
+#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
+ // In strict modes __is_integer<__int128> is false,
+ // but we still want to define __numeric_traits_integer<__int128>.
+ _GLIBCXX_INT_N_TRAITS(__int128, 128)
+#endif
+
+#undef _GLIBCXX_INT_N_TRAITS
+
#if __cplusplus >= 201103L
+ /// Convenience alias for __numeric_traits<integer-type>.
template<typename _Tp>
using __int_traits = __numeric_traits_integer<_Tp>;
#endif
-#undef __glibcxx_signed
-#undef __glibcxx_digits
-#undef __glibcxx_min
-#undef __glibcxx_max
-
#define __glibcxx_floating(_Tp, _Fval, _Dval, _LDval) \
(std::__are_same<_Tp, float>::__value ? _Fval \
: std::__are_same<_Tp, double>::__value ? _Dval : _LDval)
@@ -120,10 +151,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__glibcxx_floating(_Tp, __FLT_MAX_10_EXP__, __DBL_MAX_10_EXP__, \
__LDBL_MAX_10_EXP__)
+ // N.B. this only supports float, double and long double (no __float128 etc.)
template<typename _Value>
struct __numeric_traits_floating
{
- // Only floating point types. See N1822.
+ // Only floating point types. See N1822.
static const int __max_digits10 = __glibcxx_max_digits10(_Value);
// See above comment...
@@ -144,19 +176,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Value>
const int __numeric_traits_floating<_Value>::__max_exponent10;
+#undef __glibcxx_floating
+#undef __glibcxx_max_digits10
+#undef __glibcxx_digits10
+#undef __glibcxx_max_exponent10
+
template<typename _Value>
struct __numeric_traits
- : public __conditional_type<__is_integer_nonstrict<_Value>::__value,
- __numeric_traits_integer<_Value>,
- __numeric_traits_floating<_Value> >::__type
+ : public __numeric_traits_integer<_Value>
+ { };
+
+ template<>
+ struct __numeric_traits<float>
+ : public __numeric_traits_floating<float>
+ { };
+
+ template<>
+ struct __numeric_traits<double>
+ : public __numeric_traits_floating<double>
+ { };
+
+ template<>
+ struct __numeric_traits<long double>
+ : public __numeric_traits_floating<long double>
{ };
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
-#undef __glibcxx_floating
-#undef __glibcxx_max_digits10
-#undef __glibcxx_digits10
-#undef __glibcxx_max_exponent10
-
-#endif
+#endif
diff --git a/libstdc++-v3/include/ext/rope b/libstdc++-v3/include/ext/rope
index 08e510b..de6ecdd 100644
--- a/libstdc++-v3/include/ext/rope
+++ b/libstdc++-v3/include/ext/rope
@@ -675,7 +675,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static void _S_ref(_Rope_RopeRep*) { }
static void _S_free_if_unref(_Rope_RopeRep*) { }
# endif
-protected:
+ protected:
_Rope_RopeRep&
operator=(const _Rope_RopeRep&);
@@ -742,7 +742,7 @@ protected:
this->__STL_FREE_STRING(_M_data, this->_M_size, this->_M_get_allocator());
}
#endif
-protected:
+ protected:
_Rope_RopeLeaf&
operator=(const _Rope_RopeLeaf&);
@@ -778,7 +778,7 @@ protected:
_M_right->_M_unref_nonnil();
}
#endif
-protected:
+ protected:
_Rope_RopeConcatenation&
operator=(const _Rope_RopeConcatenation&);
@@ -1508,7 +1508,7 @@ protected:
__ROPE_DEFINE_ALLOCS(_Alloc)
#undef __ROPE_DEFINE_ALLOC
- protected:
+ protected:
_Rope_base&
operator=(const _Rope_base&);
@@ -1612,19 +1612,21 @@ protected:
static _RopeRep* _S_concat_char_iter(_RopeRep* __r,
const _CharT* __iter,
- size_type __slen);
- // Concatenate rope and char ptr, copying __s.
+ size_type __slen,
+ allocator_type& __a);
+ // Concatenate rope and char ptr, copying __iter.
// Should really take an arbitrary iterator.
// Result is counted in refcount.
static _RopeRep* _S_destr_concat_char_iter(_RopeRep* __r,
const _CharT* __iter,
- size_type __slen)
+ size_type __slen,
+ allocator_type& __a)
// As above, but one reference to __r is about to be
// destroyed. Thus the pieces may be recycled if all
// relevant reference counts are 1.
#ifdef __GC
// We can't really do anything since refcounts are unavailable.
- { return _S_concat_char_iter(__r, __iter, __slen); }
+ { return _S_concat_char_iter(__r, __iter, __slen, __a); }
#else
;
#endif
@@ -1913,9 +1915,10 @@ protected:
void
push_back(_CharT __x)
{
+ allocator_type __a = _M_get_allocator();
_RopeRep* __old = this->_M_tree_ptr;
this->_M_tree_ptr
- = _S_destr_concat_char_iter(this->_M_tree_ptr, &__x, 1);
+ = _S_destr_concat_char_iter(this->_M_tree_ptr, &__x, 1, __a);
_S_unref(__old);
}
@@ -2115,8 +2118,9 @@ protected:
rope&
append(const _CharT* __iter, size_type __n)
{
+ allocator_type __a = _M_get_allocator();
_RopeRep* __result =
- _S_destr_concat_char_iter(this->_M_tree_ptr, __iter, __n);
+ _S_destr_concat_char_iter(this->_M_tree_ptr, __iter, __n, __a);
_S_unref(this->_M_tree_ptr);
this->_M_tree_ptr = __result;
return *this;
@@ -2133,8 +2137,9 @@ protected:
rope&
append(const _CharT* __s, const _CharT* __e)
{
+ allocator_type __a = _M_get_allocator();
_RopeRep* __result =
- _S_destr_concat_char_iter(this->_M_tree_ptr, __s, __e - __s);
+ _S_destr_concat_char_iter(this->_M_tree_ptr, __s, __e - __s, __a);
_S_unref(this->_M_tree_ptr);
this->_M_tree_ptr = __result;
return *this;
@@ -2156,8 +2161,9 @@ protected:
rope&
append(_CharT __c)
{
+ allocator_type __a = _M_get_allocator();
_RopeRep* __result =
- _S_destr_concat_char_iter(this->_M_tree_ptr, &__c, 1);
+ _S_destr_concat_char_iter(this->_M_tree_ptr, &__c, 1, __a);
_S_unref(this->_M_tree_ptr);
this->_M_tree_ptr = __result;
return *this;
@@ -2239,7 +2245,8 @@ protected:
_Self_destruct_ptr __left(_S_substring(this->_M_tree_ptr, 0, __p));
_Self_destruct_ptr __right(_S_substring(this->_M_tree_ptr,
__p, size()));
- _Self_destruct_ptr __left_result(_S_concat_char_iter(__left, __i, __n));
+ _Self_destruct_ptr __left_result(_S_concat_char_iter(__left, __i, __n,
+ _M_get_allocator()));
// _S_ destr_concat_char_iter should be safe here.
// But as it stands it's probably not a win, since __left
// is likely to have additional references.
@@ -2843,8 +2850,9 @@ protected:
{
typedef rope<_CharT, _Alloc> rope_type;
std::size_t __rlen = rope_type::_S_char_ptr_len(__right);
+ _Alloc __a = __left.get_allocator();
return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr,
- __right, __rlen));
+ __right, __rlen, __a));
}
template <class _CharT, class _Alloc>
@@ -2861,8 +2869,9 @@ protected:
operator+(const rope<_CharT, _Alloc>& __left, _CharT __right)
{
typedef rope<_CharT, _Alloc> rope_type;
+ _Alloc __a = __left.get_allocator();
return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr,
- &__right, 1));
+ &__right, 1, __a));
}
template <class _CharT, class _Alloc>
diff --git a/libstdc++-v3/include/ext/ropeimpl.h b/libstdc++-v3/include/ext/ropeimpl.h
index c5d3a0c..e571847 100644
--- a/libstdc++-v3/include/ext/ropeimpl.h
+++ b/libstdc++-v3/include/ext/ropeimpl.h
@@ -524,7 +524,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template <class _CharT, class _Alloc>
typename rope<_CharT, _Alloc>::_RopeRep*
rope<_CharT, _Alloc>::
- _S_concat_char_iter(_RopeRep* __r, const _CharT*__s, std::size_t __slen)
+ _S_concat_char_iter(_RopeRep* __r, const _CharT*__s, std::size_t __slen,
+ allocator_type& __a)
{
using std::size_t;
_RopeRep* __result;
@@ -534,8 +535,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __r;
}
if (0 == __r)
- return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen,
- __r->_M_get_allocator());
+ return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __a);
if (__r->_M_tag == __detail::_S_leaf
&& __r->_M_size + __slen <= size_t(_S_copy_max))
{
@@ -564,8 +564,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __result;
}
}
- _RopeRep* __nright =
- __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->_M_get_allocator());
+ _RopeRep* __nright = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __a);
__try
{
__r->_M_ref_nonnil();
@@ -585,17 +584,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename rope<_CharT,_Alloc>::_RopeRep*
rope<_CharT,_Alloc>::
_S_destr_concat_char_iter(_RopeRep* __r, const _CharT* __s,
- std::size_t __slen)
+ std::size_t __slen, allocator_type& __a)
{
using std::size_t;
_RopeRep* __result;
if (0 == __r)
- return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen,
- __r->_M_get_allocator());
+ return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __a);
size_t __count = __r->_M_ref_count;
size_t __orig_size = __r->_M_size;
if (__count > 1)
- return _S_concat_char_iter(__r, __s, __slen);
+ return _S_concat_char_iter(__r, __s, __slen, __a);
if (0 == __slen)
{
__r->_M_ref_count = 2; // One more than before
@@ -632,8 +630,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __r;
}
}
- _RopeRep* __right =
- __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->_M_get_allocator());
+ _RopeRep* __right = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __a);
__r->_M_ref_nonnil();
__try
{ __result = _S_tree_concat(__r, __right); }
@@ -1500,9 +1497,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Self_destruct_ptr __left(_My_rope::_S_substring(__old, 0, _M_pos));
_Self_destruct_ptr __right(_My_rope::_S_substring(__old, _M_pos + 1,
__old->_M_size));
+ typename _RopeRep::allocator_type __a = _M_root->_M_get_allocator();
_Self_destruct_ptr __result_left(_My_rope::
_S_destr_concat_char_iter(__left,
- &__c, 1));
+ &__c, 1,
+ __a));
_RopeRep* __result = _My_rope::_S_concat(__result_left, __right);
#ifndef __GC
diff --git a/libstdc++-v3/include/precompiled/stdc++.h b/libstdc++-v3/include/precompiled/stdc++.h
index 8899c32..692fae7 100644
--- a/libstdc++-v3/include/precompiled/stdc++.h
+++ b/libstdc++-v3/include/precompiled/stdc++.h
@@ -137,10 +137,15 @@
#include <bit>
#include <compare>
#include <concepts>
+#if __cpp_impl_coroutine
+# include <coroutine>
+#endif
+#include <latch>
#include <numbers>
#include <ranges>
#include <span>
#include <stop_token>
+#include <semaphore>
#include <syncstream>
#include <version>
#endif
diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array
index 3c4c88a..8075099 100644
--- a/libstdc++-v3/include/std/array
+++ b/libstdc++-v3/include/std/array
@@ -192,7 +192,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr const_reference
operator[](size_type __n) const noexcept
{
+#if __cplusplus >= 201402L
__glibcxx_requires_subscript(__n);
+#endif
return _AT_Type::_S_ref(_M_elems, __n);
}
@@ -228,7 +230,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr const_reference
front() const noexcept
{
+#if __cplusplus >= 201402L
__glibcxx_requires_nonempty();
+#endif
return _AT_Type::_S_ref(_M_elems, 0);
}
@@ -242,7 +246,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr const_reference
back() const noexcept
{
+#if __cplusplus >= 201402L
__glibcxx_requires_nonempty();
+#endif
return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1)
: _AT_Type::_S_ref(_M_elems, 0);
}
diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 1a30426..4a9b001 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -163,6 +163,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
compare_exchange_strong(bool& __i1, bool __i2,
memory_order __m = memory_order_seq_cst) volatile noexcept
{ return _M_base.compare_exchange_strong(__i1, __i2, __m); }
+
+#if __cpp_lib_atomic_wait
+ void
+ wait(bool __old, memory_order __m = memory_order_seq_cst) const noexcept
+ { _M_base.wait(__old, __m); }
+
+ // TODO add const volatile overload
+
+ void
+ notify_one() const noexcept
+ { _M_base.notify_one(); }
+
+ void
+ notify_all() const noexcept
+ { _M_base.notify_all(); }
+#endif // __cpp_lib_atomic_wait
};
#if __cplusplus <= 201703L
@@ -363,6 +379,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
memory_order __m = memory_order_seq_cst) volatile noexcept
{ return compare_exchange_strong(__e, __i, __m,
__cmpexch_failure_order(__m)); }
+
+#if __cpp_lib_atomic_wait
+ void
+ wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
+ {
+ std::__atomic_wait(&_M_i, __old,
+ [__m, this, __old]
+ {
+ const auto __v = this->load(__m);
+ // TODO make this ignore padding bits when we
+ // can do that
+ return __builtin_memcmp(&__old, &__v,
+ sizeof(_Tp)) != 0;
+ });
+ }
+
+ // TODO add const volatile overload
+
+ void
+ notify_one() const noexcept
+ { std::__atomic_notify(&_M_i, false); }
+
+ void
+ notify_all() const noexcept
+ { std::__atomic_notify(&_M_i, true); }
+#endif // __cpp_lib_atomic_wait
+
};
#undef _GLIBCXX20_INIT
@@ -601,6 +644,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__cmpexch_failure_order(__m));
}
+#if __cpp_lib_atomic_wait
+ void
+ wait(__pointer_type __old, memory_order __m = memory_order_seq_cst) noexcept
+ { _M_b.wait(__old, __m); }
+
+ // TODO add const volatile overload
+
+ void
+ notify_one() const noexcept
+ { _M_b.notify_one(); }
+
+ void
+ notify_all() const noexcept
+ { _M_b.notify_all(); }
+#endif // __cpp_lib_atomic_wait
__pointer_type
fetch_add(ptrdiff_t __d,
memory_order __m = memory_order_seq_cst) noexcept
@@ -1353,6 +1411,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
memory_order_seq_cst);
}
+
+#if __cpp_lib_atomic_wait
+ template<typename _Tp>
+ inline void
+ atomic_wait(const atomic<_Tp>* __a,
+ typename std::atomic<_Tp>::value_type __old) noexcept
+ { __a->wait(__old); }
+
+ template<typename _Tp>
+ inline void
+ atomic_wait_explicit(const atomic<_Tp>* __a,
+ typename std::atomic<_Tp>::value_type __old,
+ std::memory_order __m) noexcept
+ { __a->wait(__old, __m); }
+
+ template<typename _Tp>
+ inline void
+ atomic_notify_one(atomic<_Tp>* __a) noexcept
+ { __a->notify_one(); }
+
+ template<typename _Tp>
+ inline void
+ atomic_notify_all(atomic<_Tp>* __a) noexcept
+ { __a->notify_all(); }
+#endif // __cpp_lib_atomic_wait
+
// Function templates for atomic_integral and atomic_pointer operations only.
// Some operations (and, or, xor) are only available for atomic integrals,
// which is implemented by taking a parameter of type __atomic_base<_ITp>*.
diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit
index 16f7eba..1d99c80 100644
--- a/libstdc++-v3/include/std/bit
+++ b/libstdc++-v3/include/std/bit
@@ -49,6 +49,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @{
*/
+#if __cplusplus > 201703l && __has_builtin(__builtin_bit_cast)
+#define __cpp_lib_bit_cast 201806L
+
+ /// Create a value of type `To` from the bits of `from`.
+ template<typename _To, typename _From>
+ constexpr _To
+ bit_cast(const _From& __from) noexcept
+ {
+ return __builtin_bit_cast(_To, __from);
+ }
+#endif
+
/// @cond undoc
template<typename _Tp>
diff --git a/libstdc++-v3/include/std/condition_variable b/libstdc++-v3/include/std/condition_variable
index 7406fde..5b7a9cb 100644
--- a/libstdc++-v3/include/std/condition_variable
+++ b/libstdc++-v3/include/std/condition_variable
@@ -74,16 +74,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#else
using __clock_t = system_clock;
#endif
- typedef __gthread_cond_t __native_type;
-#ifdef __GTHREAD_COND_INIT
- __native_type _M_cond = __GTHREAD_COND_INIT;
-#else
- __native_type _M_cond;
-#endif
+ __condvar _M_cond;
public:
- typedef __native_type* native_handle_type;
+ typedef __gthread_cond_t* native_handle_type;
condition_variable() noexcept;
~condition_variable() noexcept;
@@ -185,7 +180,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
native_handle_type
native_handle()
- { return &_M_cond; }
+ { return _M_cond.native_handle(); }
private:
#ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
@@ -203,9 +198,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static_cast<long>(__ns.count())
};
- pthread_cond_clockwait(&_M_cond, __lock.mutex()->native_handle(),
- CLOCK_MONOTONIC,
- &__ts);
+ _M_cond.wait_until(*__lock.mutex(), CLOCK_MONOTONIC, __ts);
return (steady_clock::now() < __atime
? cv_status::no_timeout : cv_status::timeout);
@@ -226,8 +219,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static_cast<long>(__ns.count())
};
- __gthread_cond_timedwait(&_M_cond, __lock.mutex()->native_handle(),
- &__ts);
+ _M_cond.wait_until(*__lock.mutex(), __ts);
return (system_clock::now() < __atime
? cv_status::no_timeout : cv_status::timeout);
diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future
index 5d94801..77b6f93 100644
--- a/libstdc++-v3/include/std/future
+++ b/libstdc++-v3/include/std/future
@@ -36,7 +36,6 @@
#else
#include <mutex> // call_once
-#include <thread>
#include <condition_variable> // __at_thread_exit_elt
#include <system_error>
#include <atomic>
@@ -46,6 +45,7 @@
#include <bits/unique_ptr.h>
#include <bits/shared_ptr.h>
#include <bits/std_function.h>
+#include <bits/std_thread.h>
#include <bits/uses_allocator.h>
#include <ext/aligned_buffer.h>
@@ -345,10 +345,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// to synchronize with the thread that made it ready.
if (_M_status._M_load(memory_order_acquire) == _Status::__ready)
return future_status::ready;
+
if (_M_is_deferred_future())
return future_status::deferred;
- if (_M_status._M_load_when_equal_for(_Status::__ready,
- memory_order_acquire, __rel))
+
+ // Don't wait unless the relative time is greater than zero.
+ if (__rel > __rel.zero()
+ && _M_status._M_load_when_equal_for(_Status::__ready,
+ memory_order_acquire,
+ __rel))
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2100. timed waiting functions must also join
@@ -377,10 +382,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// to synchronize with the thread that made it ready.
if (_M_status._M_load(memory_order_acquire) == _Status::__ready)
return future_status::ready;
+
if (_M_is_deferred_future())
return future_status::deferred;
+
if (_M_status._M_load_when_equal_until(_Status::__ready,
- memory_order_acquire, __abs))
+ memory_order_acquire,
+ __abs))
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2100. timed waiting functions must also join
diff --git a/libstdc++-v3/include/std/latch b/libstdc++-v3/include/std/latch
new file mode 100644
index 0000000..d4a00c4
--- /dev/null
+++ b/libstdc++-v3/include/std/latch
@@ -0,0 +1,94 @@
+// <latch> -*- C++ -*-
+
+// Copyright (C) 2020 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/latch
+ * This is a Standard C++ Library header.
+ */
+
+#ifndef _GLIBCXX_LATCH
+#define _GLIBCXX_LATCH 1
+
+#pragma GCC system_header
+
+#if __cplusplus > 201703L
+
+#include <bits/atomic_base.h>
+#include <ext/numeric_traits.h>
+
+#if __cpp_lib_atomic_wait
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#define __cpp_lib_latch 201907L
+
+ class latch
+ {
+ public:
+ static constexpr ptrdiff_t
+ max() noexcept
+ { return __gnu_cxx::__int_traits<ptrdiff_t>::__max; }
+
+ constexpr explicit latch(ptrdiff_t __expected) noexcept
+ : _M_a(__expected) { }
+
+ ~latch() = default;
+ latch(const latch&) = delete;
+ latch& operator=(const latch&) = delete;
+
+ _GLIBCXX_ALWAYS_INLINE void
+ count_down(ptrdiff_t __update = 1)
+ {
+ auto const __old = __atomic_impl::fetch_sub(&_M_a,
+ __update, memory_order::release);
+ if (__old == __update)
+ __atomic_impl::notify_all(&_M_a);
+ }
+
+ _GLIBCXX_ALWAYS_INLINE bool
+ try_wait() const noexcept
+ { return __atomic_impl::load(&_M_a, memory_order::acquire) == 0; }
+
+ _GLIBCXX_ALWAYS_INLINE void
+ wait() const noexcept
+ {
+ auto const __old = __atomic_impl::load(&_M_a, memory_order::acquire);
+ std::__atomic_wait(&_M_a, __old, [this] { return this->try_wait(); });
+ }
+
+ _GLIBCXX_ALWAYS_INLINE void
+ arrive_and_wait(ptrdiff_t __update = 1) noexcept
+ {
+ count_down(__update);
+ wait();
+ }
+
+ private:
+ alignas(__alignof__(ptrdiff_t)) ptrdiff_t _M_a;
+ };
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+#endif // __cpp_lib_atomic_wait
+#endif // __cplusplus > 201703L
+#endif // _GLIBCXX_LATCH
diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream
index 9a80adf..c203e31 100644
--- a/libstdc++-v3/include/std/ostream
+++ b/libstdc++-v3/include/std/ostream
@@ -776,6 +776,73 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__ret_os << __x;
return __ret_os;
}
+
+#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
+ template<typename _CharT, typename _Traits>
+ class __syncbuf_base : public basic_streambuf<_CharT, _Traits>
+ {
+ public:
+ static bool*
+ _S_get(basic_streambuf<_CharT, _Traits>* __buf) noexcept
+ {
+ if (auto __p = dynamic_cast<__syncbuf_base*>(__buf))
+ return &__p->_M_emit_on_sync;
+ return nullptr;
+ }
+
+ protected:
+ __syncbuf_base(basic_streambuf<_CharT, _Traits>* __w = nullptr)
+ : _M_wrapped(__w)
+ { }
+
+ basic_streambuf<_CharT, _Traits>* _M_wrapped = nullptr;
+ bool _M_emit_on_sync = false;
+ bool _M_needs_sync = false;
+ };
+
+ template<typename _CharT, typename _Traits>
+ inline basic_ostream<_CharT, _Traits>&
+ emit_on_flush(basic_ostream<_CharT, _Traits>& __os)
+ {
+ if (bool* __flag = __syncbuf_base<_CharT, _Traits>::_S_get(__os.rdbuf()))
+ *__flag = true;
+ return __os;
+ }
+
+ template<typename _CharT, typename _Traits>
+ inline basic_ostream<_CharT, _Traits>&
+ noemit_on_flush(basic_ostream<_CharT, _Traits>& __os)
+ {
+ if (bool* __flag = __syncbuf_base<_CharT, _Traits>::_S_get(__os.rdbuf()))
+ *__flag = false;
+ return __os;
+ }
+
+ template<typename _CharT, typename _Traits>
+ inline basic_ostream<_CharT, _Traits>&
+ flush_emit(basic_ostream<_CharT, _Traits>& __os)
+ {
+ struct _Restore
+ {
+ ~_Restore() { *_M_flag = _M_prev; }
+
+ bool _M_prev = false;
+ bool* _M_flag = &_M_prev;
+ } __restore;
+
+ if (bool* __flag = __syncbuf_base<_CharT, _Traits>::_S_get(__os.rdbuf()))
+ {
+ __restore._M_prev = *__flag;
+ __restore._M_flag = __flag;
+ *__flag = true;
+ }
+
+ __os.flush();
+ return __os;
+ }
+
+#endif // C++20
+
#endif // C++11
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 14d2a11..d38b199 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -2128,9 +2128,9 @@ namespace views
for (; _M_outer != ranges::end(_M_parent->_M_base); ++_M_outer)
{
- auto& inner = __update_inner(*_M_outer);
- _M_inner = ranges::begin(inner);
- if (_M_inner != ranges::end(inner))
+ auto& __inner = __update_inner(*_M_outer);
+ _M_inner = ranges::begin(__inner);
+ if (_M_inner != ranges::end(__inner))
return;
}
@@ -2211,10 +2211,12 @@ namespace views
operator*() const
{ return *_M_inner; }
- constexpr _Outer_iter
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 3500. join_view::iterator::operator->() is bogus
+ constexpr _Inner_iter
operator->() const
- requires __detail::__has_arrow<_Outer_iter>
- && copyable<_Outer_iter>
+ requires __detail::__has_arrow<_Inner_iter>
+ && copyable<_Inner_iter>
{ return _M_inner; }
constexpr _Iterator&
diff --git a/libstdc++-v3/include/std/regex b/libstdc++-v3/include/std/regex
index 43ee1ae..783f5f1 100644
--- a/libstdc++-v3/include/std/regex
+++ b/libstdc++-v3/include/std/regex
@@ -64,21 +64,25 @@
#include <bits/regex_executor.h>
#if __cplusplus >= 201703L && _GLIBCXX_USE_CXX11_ABI
-#include <memory_resource>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
- namespace pmr {
+ namespace pmr
+ {
template<typename _Tp> class polymorphic_allocator;
template<typename _BidirectionalIterator>
using match_results
= std::match_results<_BidirectionalIterator, polymorphic_allocator<
sub_match<_BidirectionalIterator>>>;
- using cmatch = match_results<const char*>;
- using smatch = match_results<string::const_iterator>;
+ using cmatch = match_results<const char*>;
+ // Use __normal_iterator directly, because pmr::string::const_iterator
+ // would require pmr::polymorphic_allocator to be complete.
+ using smatch
+ = match_results<__gnu_cxx::__normal_iterator<const char*, string>>;
#ifdef _GLIBCXX_USE_WCHAR_T
using wcmatch = match_results<const wchar_t*>;
- using wsmatch = match_results<wstring::const_iterator>;
+ using wsmatch
+ = match_results<__gnu_cxx::__normal_iterator<const wchar_t*, wstring>>;
#endif
} // namespace pmr
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/std/semaphore b/libstdc++-v3/include/std/semaphore
new file mode 100644
index 0000000..ff83a56
--- /dev/null
+++ b/libstdc++-v3/include/std/semaphore
@@ -0,0 +1,95 @@
+// <semaphore> -*- C++ -*-
+
+// Copyright (C) 2020 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/semaphore
+ * This is a Standard C++ Library header.
+ */
+
+#ifndef _GLIBCXX_SEMAPHORE
+#define _GLIBCXX_SEMAPHORE 1
+
+#pragma GCC system_header
+
+#if __cplusplus > 201703L
+#include <bits/semaphore_base.h>
+#if __cpp_lib_atomic_wait
+#include <ext/numeric_traits.h>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#define __cpp_lib_semaphore 201907L
+
+ template<ptrdiff_t __least_max_value =
+ __gnu_cxx::__int_traits<ptrdiff_t>::__max>
+ class counting_semaphore
+ {
+ static_assert(__least_max_value >= 0);
+
+ __semaphore_impl<__least_max_value> _M_sem;
+
+ public:
+ explicit counting_semaphore(ptrdiff_t __desired) noexcept
+ : _M_sem(__desired)
+ { }
+
+ ~counting_semaphore() = default;
+
+ counting_semaphore(const counting_semaphore&) = delete;
+ counting_semaphore& operator=(const counting_semaphore&) = delete;
+
+ static constexpr ptrdiff_t
+ max() noexcept
+ { return __least_max_value; }
+
+ void
+ release(ptrdiff_t __update = 1) noexcept(noexcept(_M_sem._M_release(1)))
+ { _M_sem._M_release(__update); }
+
+ void
+ acquire() noexcept(noexcept(_M_sem._M_acquire()))
+ { _M_sem._M_acquire(); }
+
+ bool
+ try_acquire() noexcept(noexcept(_M_sem._M_try_acquire()))
+ { return _M_sem._M_try_acquire(); }
+
+ template<typename _Rep, typename _Period>
+ bool
+ try_acquire_for(const std::chrono::duration<_Rep, _Period>& __rtime)
+ { return _M_sem._M_try_acquire_for(__rtime); }
+
+ template<typename _Clock, typename _Dur>
+ bool
+ try_acquire_until(const std::chrono::time_point<_Clock, _Dur>& __atime)
+ { return _M_sem._M_try_acquire_until(__atime); }
+ };
+
+ using binary_semaphore = std::counting_semaphore<1>;
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+#endif // __cpp_lib_atomic_wait
+#endif // C++20
+#endif // _GLIBCXX_SEMAPHORE
diff --git a/libstdc++-v3/include/std/source_location b/libstdc++-v3/include/std/source_location
new file mode 100644
index 0000000..13d4bd4
--- /dev/null
+++ b/libstdc++-v3/include/std/source_location
@@ -0,0 +1,92 @@
+// <source_location> -*- C++ -*-
+
+// Copyright (C) 2020 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/source_location
+ * This is a Standard C++ Library header.
+ */
+
+#ifndef _GLIBCXX_SRCLOC
+#define _GLIBCXX_SRCLOC 1
+
+#if __cplusplus > 201703L && __has_builtin(__builtin_source_location)
+#include <bits/c++config.h>
+
+namespace std
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#define __cpp_lib_source_location 201907L
+
+ /// A class that describes a location in source code.
+ struct source_location
+ {
+ private:
+ using uint_least32_t = __UINT_LEAST32_TYPE__;
+
+ public:
+
+ // [support.srcloc.cons], creation
+ static consteval source_location
+ current(const void* __p = __builtin_source_location()) noexcept
+ {
+ source_location __ret;
+ __ret._M_impl = static_cast <const __impl*>(__p);
+ return __ret;
+ }
+
+ constexpr source_location() noexcept { }
+
+ // [support.srcloc.obs], observers
+ constexpr uint_least32_t
+ line() const noexcept
+ { return _M_impl ? _M_impl->_M_line : 0u; }
+
+ constexpr uint_least32_t
+ column() const noexcept
+ { return _M_impl ? _M_impl->_M_column : 0u; }
+
+ constexpr const char*
+ file_name() const noexcept
+ { return _M_impl ? _M_impl->_M_file_name : ""; }
+
+ constexpr const char*
+ function_name() const noexcept
+ { return _M_impl ? _M_impl->_M_function_name : ""; }
+
+ private:
+ struct __impl
+ {
+ const char* _M_file_name;
+ const char* _M_function_name;
+ unsigned _M_line;
+ unsigned _M_column;
+ };
+
+ const __impl* _M_impl = nullptr;
+ };
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+#endif // C++20 && __builtin_source_location
+#endif // _GLIBCXX_SRCLOC
diff --git a/libstdc++-v3/include/std/sstream b/libstdc++-v3/include/std/sstream
index 437e2ba..d7200ab 100644
--- a/libstdc++-v3/include/std/sstream
+++ b/libstdc++-v3/include/std/sstream
@@ -37,6 +37,13 @@
#include <istream>
#include <ostream>
+#include <bits/alloc_traits.h> // allocator_traits, __allocator_like
+
+#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_LVAL_REF_QUAL &
+#else
+# define _GLIBCXX_LVAL_REF_QUAL
+#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
@@ -65,6 +72,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
{
struct __xfer_bufptrs;
+
+#if __cplusplus >= 201103L
+ using allocator_traits = std::allocator_traits<_Alloc>;
+ using _Noexcept_swap
+ = __or_<typename allocator_traits::propagate_on_container_swap,
+ typename allocator_traits::is_always_equal>;
+#endif
+
public:
// Types:
typedef _CharT char_type;
@@ -134,37 +149,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
: basic_stringbuf(std::move(__rhs), __xfer_bufptrs(__rhs, this))
{ __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); }
- // 27.8.2.2 Assign and swap:
-
- basic_stringbuf&
- operator=(const basic_stringbuf&) = delete;
-
- basic_stringbuf&
- operator=(basic_stringbuf&& __rhs)
- {
- __xfer_bufptrs __st{__rhs, this};
- const __streambuf_type& __base = __rhs;
- __streambuf_type::operator=(__base);
- this->pubimbue(__rhs.getloc());
- _M_mode = __rhs._M_mode;
- _M_string = std::move(__rhs._M_string);
- __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0);
- return *this;
- }
-
- void
- swap(basic_stringbuf& __rhs)
- {
- __xfer_bufptrs __l_st{*this, std::__addressof(__rhs)};
- __xfer_bufptrs __r_st{__rhs, this};
- __streambuf_type& __base = __rhs;
- __streambuf_type::swap(__base);
- __rhs.pubimbue(this->pubimbue(__rhs.getloc()));
- std::swap(_M_mode, __rhs._M_mode);
- std::swap(_M_string, __rhs._M_string);
- }
-#endif
-
#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
explicit
basic_stringbuf(const allocator_type& __a)
@@ -211,9 +195,41 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
allocator_type get_allocator() const noexcept
{ return _M_string.get_allocator(); }
-#endif
+#endif // C++20
+
+ // 27.8.2.2 Assign and swap:
+
+ basic_stringbuf&
+ operator=(const basic_stringbuf&) = delete;
+
+ basic_stringbuf&
+ operator=(basic_stringbuf&& __rhs)
+ {
+ __xfer_bufptrs __st{__rhs, this};
+ const __streambuf_type& __base = __rhs;
+ __streambuf_type::operator=(__base);
+ this->pubimbue(__rhs.getloc());
+ _M_mode = __rhs._M_mode;
+ _M_string = std::move(__rhs._M_string);
+ __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0);
+ return *this;
+ }
+
+ void
+ swap(basic_stringbuf& __rhs) noexcept(_Noexcept_swap::value)
+ {
+ __xfer_bufptrs __l_st{*this, std::__addressof(__rhs)};
+ __xfer_bufptrs __r_st{__rhs, this};
+ __streambuf_type& __base = __rhs;
+ __streambuf_type::swap(__base);
+ __rhs.pubimbue(this->pubimbue(__rhs.getloc()));
+ std::swap(_M_mode, __rhs._M_mode);
+ std::swap(_M_string, __rhs._M_string); // XXX not exception safe
+ }
+#endif // C++11
+
+ // Getters and setters:
- // Get and set:
/**
* @brief Copying out the string buffer.
* @return A copy of one of the underlying sequences.
@@ -223,23 +239,51 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* is equal to the output sequence.</em> [27.7.1.2]/1
*/
__string_type
- str() const
+ str() const _GLIBCXX_LVAL_REF_QUAL
{
__string_type __ret(_M_string.get_allocator());
- if (char_type* __pptr = this->pptr())
- {
- char_type* __egptr = this->egptr();
- // The current egptr() may not be the actual string end.
- if (!__egptr || __pptr > __egptr)
- __ret.assign(this->pbase(), __pptr);
- else
- __ret.assign(this->pbase(), __egptr);
- }
+ if (char_type* __hi = _M_high_mark())
+ __ret.assign(this->pbase(), __hi);
else
__ret = _M_string;
return __ret;
}
+#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
+#if __cpp_concepts
+ template<__allocator_like _SAlloc>
+ basic_string<_CharT, _Traits, _SAlloc>
+ str(const _SAlloc& __sa) const
+ {
+ auto __sv = view();
+ return { __sv.data(), __sv.size(), __sa };
+ }
+#endif
+
+ __string_type
+ str() &&
+ {
+ if (char_type* __hi = _M_high_mark())
+ {
+ // Set length to end of character sequence and add null terminator.
+ _M_string._M_set_length(_M_high_mark() - this->pbase());
+ }
+ auto __str = std::move(_M_string);
+ _M_string.clear();
+ _M_sync(_M_string.data(), 0, 0);
+ return __str;
+ }
+
+ basic_string_view<char_type, traits_type>
+ view() const noexcept
+ {
+ if (char_type* __hi = _M_high_mark())
+ return { this->pbase(), __hi };
+ else
+ return _M_string;
+ }
+#endif // C++20
+
/**
* @brief Setting a new buffer.
* @param __s The string to use as a new sequence.
@@ -257,21 +301,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
}
#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
- basic_string_view<char_type, traits_type>
- view() const noexcept
- {
- using __sv_type = basic_string_view<char_type, traits_type>;
+#if __cpp_concepts
+ template<__allocator_like _SAlloc>
+ requires (!is_same_v<_SAlloc, _Alloc>)
+ void
+ str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
+ {
+ _M_string.assign(__s.data(), __s.size());
+ _M_stringbuf_init(_M_mode);
+ }
+#endif
- if (this->pptr())
- {
- // The current egptr() may not be the actual string end.
- if (this->pptr() > this->egptr())
- return __sv_type(this->pbase(), this->pptr());
- else
- return __sv_type(this->pbase(), this->egptr());
- }
- else
- return static_cast<__sv_type>(_M_string);
+ void
+ str(__string_type&& __s)
+ {
+ _M_string = std::move(__s);
+ _M_stringbuf_init(_M_mode);
}
#endif
@@ -357,13 +402,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
void
_M_update_egptr()
{
- const bool __testin = _M_mode & ios_base::in;
- if (this->pptr() && this->pptr() > this->egptr())
+ if (char_type* __pptr = this->pptr())
{
- if (__testin)
- this->setg(this->eback(), this->gptr(), this->pptr());
- else
- this->setg(this->pptr(), this->pptr(), this->pptr());
+ char_type* __egptr = this->egptr();
+ if (!__egptr || __pptr > __egptr)
+ {
+ if (_M_mode & ios_base::in)
+ this->setg(this->eback(), this->gptr(), __pptr);
+ else
+ this->setg(__pptr, __pptr, __pptr);
+ }
}
}
@@ -373,6 +421,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
_M_pbump(char_type* __pbeg, char_type* __pend, off_type __off);
private:
+ // Return a pointer to the end of the underlying character sequence.
+ // This might not be the same character as _M_string.end() because
+ // basic_stringbuf::overflow might have written to unused capacity
+ // in _M_string without updating its length.
+ char_type*
+ _M_high_mark() const _GLIBCXX_NOEXCEPT
+ {
+ if (char_type* __pptr = this->pptr())
+ {
+ char_type* __egptr = this->egptr();
+ if (!__egptr || __pptr > __egptr)
+ return __pptr; // Underlying sequence is [pbase, pptr).
+ else
+ return __egptr; // Underlying sequence is [pbase, egptr).
+ }
+ return 0; // Underlying character sequence is just _M_string.
+ }
+
#if __cplusplus >= 201103L
#if _GLIBCXX_USE_CXX11_ABI
// This type captures the state of the gptr / pptr pointers as offsets
@@ -396,7 +462,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
_M_poff[0] = __from.pbase() - __str;
_M_poff[1] = __from.pptr() - __from.pbase();
_M_poff[2] = __from.epptr() - __str;
- if (__from.pptr() > __end)
+ if (!__end || __from.pptr() > __end)
__end = __from.pptr();
}
@@ -447,7 +513,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
_M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string), __a)
{ }
#endif
-#endif
+#endif // C++11
};
@@ -557,27 +623,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
_M_stringbuf(std::move(__rhs._M_stringbuf))
{ __istream_type::set_rdbuf(&_M_stringbuf); }
- // 27.8.3.2 Assign and swap:
-
- basic_istringstream&
- operator=(const basic_istringstream&) = delete;
-
- basic_istringstream&
- operator=(basic_istringstream&& __rhs)
- {
- __istream_type::operator=(std::move(__rhs));
- _M_stringbuf = std::move(__rhs._M_stringbuf);
- return *this;
- }
-
- void
- swap(basic_istringstream& __rhs)
- {
- __istream_type::swap(__rhs);
- _M_stringbuf.swap(__rhs._M_stringbuf);
- }
-#endif
-
#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
basic_istringstream(ios_base::openmode __mode, const allocator_type& __a)
: __istream_type(), _M_stringbuf(__mode | ios_base::in, __a)
@@ -608,7 +653,28 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
ios_base::openmode __mode = ios_base::in)
: basic_istringstream(__str, __mode, allocator_type())
{ }
-#endif
+#endif // C++20
+
+ // 27.8.3.2 Assign and swap:
+
+ basic_istringstream&
+ operator=(const basic_istringstream&) = delete;
+
+ basic_istringstream&
+ operator=(basic_istringstream&& __rhs)
+ {
+ __istream_type::operator=(std::move(__rhs));
+ _M_stringbuf = std::move(__rhs._M_stringbuf);
+ return *this;
+ }
+
+ void
+ swap(basic_istringstream& __rhs)
+ {
+ __istream_type::swap(__rhs);
+ _M_stringbuf.swap(__rhs._M_stringbuf);
+ }
+#endif // C++11
// Members:
/**
@@ -626,9 +692,26 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @return @c rdbuf()->str()
*/
__string_type
- str() const
+ str() const _GLIBCXX_LVAL_REF_QUAL
{ return _M_stringbuf.str(); }
+#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
+#if __cpp_concepts
+ template<__allocator_like _SAlloc>
+ basic_string<_CharT, _Traits, _SAlloc>
+ str(const _SAlloc& __sa) const
+ { return _M_stringbuf.str(__sa); }
+#endif
+
+ __string_type
+ str() &&
+ { return std::move(_M_stringbuf).str(); }
+
+ basic_string_view<char_type, traits_type>
+ view() const noexcept
+ { return _M_stringbuf.view(); }
+#endif
+
/**
* @brief Setting a new buffer.
* @param __s The string to use as a new sequence.
@@ -640,9 +723,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{ _M_stringbuf.str(__s); }
#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
- basic_string_view<char_type, traits_type>
- view() const noexcept
- { return _M_stringbuf.view(); }
+#if __cpp_concepts
+ template<__allocator_like _SAlloc>
+ requires (!is_same_v<_SAlloc, _Alloc>)
+ void
+ str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
+ { _M_stringbuf.str(__s); }
+#endif
+
+ void
+ str(__string_type&& __s)
+ { _M_stringbuf.str(std::move(__s)); }
#endif
};
@@ -753,27 +844,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
_M_stringbuf(std::move(__rhs._M_stringbuf))
{ __ostream_type::set_rdbuf(&_M_stringbuf); }
- // 27.8.3.2 Assign and swap:
-
- basic_ostringstream&
- operator=(const basic_ostringstream&) = delete;
-
- basic_ostringstream&
- operator=(basic_ostringstream&& __rhs)
- {
- __ostream_type::operator=(std::move(__rhs));
- _M_stringbuf = std::move(__rhs._M_stringbuf);
- return *this;
- }
-
- void
- swap(basic_ostringstream& __rhs)
- {
- __ostream_type::swap(__rhs);
- _M_stringbuf.swap(__rhs._M_stringbuf);
- }
-#endif
-
#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
basic_ostringstream(ios_base::openmode __mode, const allocator_type& __a)
: __ostream_type(), _M_stringbuf(__mode | ios_base::out, __a)
@@ -804,7 +874,28 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
ios_base::openmode __mode = ios_base::out)
: basic_ostringstream(__str, __mode, allocator_type())
{ }
-#endif
+#endif // C++20
+
+ // 27.8.3.2 Assign and swap:
+
+ basic_ostringstream&
+ operator=(const basic_ostringstream&) = delete;
+
+ basic_ostringstream&
+ operator=(basic_ostringstream&& __rhs)
+ {
+ __ostream_type::operator=(std::move(__rhs));
+ _M_stringbuf = std::move(__rhs._M_stringbuf);
+ return *this;
+ }
+
+ void
+ swap(basic_ostringstream& __rhs)
+ {
+ __ostream_type::swap(__rhs);
+ _M_stringbuf.swap(__rhs._M_stringbuf);
+ }
+#endif // C++11
// Members:
/**
@@ -822,9 +913,26 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @return @c rdbuf()->str()
*/
__string_type
- str() const
+ str() const _GLIBCXX_LVAL_REF_QUAL
{ return _M_stringbuf.str(); }
+#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
+#if __cpp_concepts
+ template<__allocator_like _SAlloc>
+ basic_string<_CharT, _Traits, _SAlloc>
+ str(const _SAlloc& __sa) const
+ { return _M_stringbuf.str(__sa); }
+#endif
+
+ __string_type
+ str() &&
+ { return std::move(_M_stringbuf).str(); }
+
+ basic_string_view<char_type, traits_type>
+ view() const noexcept
+ { return _M_stringbuf.view(); }
+#endif
+
/**
* @brief Setting a new buffer.
* @param __s The string to use as a new sequence.
@@ -836,9 +944,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{ _M_stringbuf.str(__s); }
#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
- basic_string_view<char_type, traits_type>
- view() const noexcept
- { return _M_stringbuf.view(); }
+#if __cpp_concepts
+ template<__allocator_like _SAlloc>
+ requires (!is_same_v<_SAlloc, _Alloc>)
+ void
+ str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
+ { _M_stringbuf.str(__s); }
+#endif
+
+ void
+ str(__string_type&& __s)
+ { _M_stringbuf.str(std::move(__s)); }
#endif
};
@@ -945,27 +1061,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
_M_stringbuf(std::move(__rhs._M_stringbuf))
{ __iostream_type::set_rdbuf(&_M_stringbuf); }
- // 27.8.3.2 Assign and swap:
-
- basic_stringstream&
- operator=(const basic_stringstream&) = delete;
-
- basic_stringstream&
- operator=(basic_stringstream&& __rhs)
- {
- __iostream_type::operator=(std::move(__rhs));
- _M_stringbuf = std::move(__rhs._M_stringbuf);
- return *this;
- }
-
- void
- swap(basic_stringstream& __rhs)
- {
- __iostream_type::swap(__rhs);
- _M_stringbuf.swap(__rhs._M_stringbuf);
- }
-#endif
-
#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
basic_stringstream(ios_base::openmode __mode, const allocator_type& __a)
: __iostream_type(), _M_stringbuf(__mode, __a)
@@ -998,7 +1093,28 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
| ios_base::out)
: basic_stringstream(__str, __mode, allocator_type())
{ }
-#endif
+#endif // C++20
+
+ // 27.8.3.2 Assign and swap:
+
+ basic_stringstream&
+ operator=(const basic_stringstream&) = delete;
+
+ basic_stringstream&
+ operator=(basic_stringstream&& __rhs)
+ {
+ __iostream_type::operator=(std::move(__rhs));
+ _M_stringbuf = std::move(__rhs._M_stringbuf);
+ return *this;
+ }
+
+ void
+ swap(basic_stringstream& __rhs)
+ {
+ __iostream_type::swap(__rhs);
+ _M_stringbuf.swap(__rhs._M_stringbuf);
+ }
+#endif // C++11
// Members:
/**
@@ -1016,9 +1132,26 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @return @c rdbuf()->str()
*/
__string_type
- str() const
+ str() const _GLIBCXX_LVAL_REF_QUAL
{ return _M_stringbuf.str(); }
+#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
+#if __cpp_concepts
+ template<__allocator_like _SAlloc>
+ basic_string<_CharT, _Traits, _SAlloc>
+ str(const _SAlloc& __sa) const
+ { return _M_stringbuf.str(__sa); }
+#endif
+
+ __string_type
+ str() &&
+ { return std::move(_M_stringbuf).str(); }
+
+ basic_string_view<char_type, traits_type>
+ view() const noexcept
+ { return _M_stringbuf.view(); }
+#endif
+
/**
* @brief Setting a new buffer.
* @param __s The string to use as a new sequence.
@@ -1030,9 +1163,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{ _M_stringbuf.str(__s); }
#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
- basic_string_view<char_type, traits_type>
- view() const noexcept
- { return _M_stringbuf.view(); }
+#if __cpp_concepts
+ template<__allocator_like _SAlloc>
+ requires (!is_same_v<_SAlloc, _Alloc>)
+ void
+ str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
+ { _M_stringbuf.str(__s); }
+#endif
+
+ void
+ str(__string_type&& __s)
+ { _M_stringbuf.str(std::move(__s)); }
#endif
};
@@ -1042,6 +1183,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
inline void
swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x,
basic_stringbuf<_CharT, _Traits, _Allocator>& __y)
+ noexcept(noexcept(__x.swap(__y)))
{ __x.swap(__y); }
/// Swap specialization for istringstreams.
@@ -1064,12 +1206,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x,
basic_stringstream<_CharT, _Traits, _Allocator>& __y)
{ __x.swap(__y); }
-#endif
+#endif // C++11
_GLIBCXX_END_NAMESPACE_CXX11
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
+#undef _GLIBCXX_LVAL_REF_QUAL
+
#include <bits/sstream.tcc>
#endif /* _GLIBCXX_SSTREAM */
diff --git a/libstdc++-v3/include/std/stop_token b/libstdc++-v3/include/std/stop_token
index ccec6fa..3163428 100644
--- a/libstdc++-v3/include/std/stop_token
+++ b/libstdc++-v3/include/std/stop_token
@@ -32,14 +32,11 @@
#if __cplusplus > 201703L
#include <atomic>
+#include <bits/std_thread.h>
-#ifdef _GLIBCXX_HAS_GTHREADS
-# define __cpp_lib_jthread 201911L
-# include <bits/gthr.h>
-# if __has_include(<semaphore>)
-# include <semaphore>
-# endif
-#endif
+#include <semaphore>
+
+#define __cpp_lib_jthread 201911L
namespace std _GLIBCXX_VISIBILITY(default)
{
@@ -105,9 +102,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
#if defined __i386__ || defined __x86_64__
__builtin_ia32_pause();
-#elif defined _GLIBCXX_HAS_GTHREADS && defined _GLIBCXX_USE_SCHED_YIELD
- __gthread_yield();
#endif
+ this_thread::yield();
}
#ifndef __cpp_lib_semaphore
@@ -162,9 +158,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::atomic<value_type> _M_owners{1};
std::atomic<value_type> _M_value{_S_ssrc_counter_inc};
_Stop_cb* _M_head = nullptr;
-#ifdef _GLIBCXX_HAS_GTHREADS
- __gthread_t _M_requester;
-#endif
+ std::thread::id _M_requester;
_Stop_state_t() = default;
@@ -237,9 +231,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
while (!_M_try_lock_and_stop(__old));
-#ifdef _GLIBCXX_HAS_GTHREADS
- _M_requester = __gthread_self();
-#endif
+ _M_requester = this_thread::get_id();
while (_M_head)
{
@@ -266,10 +258,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (!__destroyed)
{
__cb->_M_destroyed = nullptr;
-#ifdef _GLIBCXX_HAS_GTHREADS
+
// synchronize with destructor of stop_callback that owns *__cb
- __cb->_M_done.release();
-#endif
+ if (!__gnu_cxx::__is_single_threaded())
+ __cb->_M_done.release();
}
// Avoid relocking if we already know there are no more callbacks.
@@ -343,18 +335,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Callback is not in the list, so must have been removed by a call to
// _M_request_stop.
-#ifdef _GLIBCXX_HAS_GTHREADS
// Despite appearances there is no data race on _M_requester. The only
// write to it happens before the callback is removed from the list,
// and removing it from the list happens before this read.
- if (!__gthread_equal(_M_requester, __gthread_self()))
+ if (!(_M_requester == this_thread::get_id()))
{
// Synchronize with completion of callback.
__cb->_M_done.acquire();
// Safe for ~stop_callback to destroy *__cb now.
return;
}
-#endif
+
if (__cb->_M_destroyed)
*__cb->_M_destroyed = true;
}
diff --git a/libstdc++-v3/include/std/syncstream b/libstdc++-v3/include/std/syncstream
index 9d1db0c..07aab65 100644
--- a/libstdc++-v3/include/std/syncstream
+++ b/libstdc++-v3/include/std/syncstream
@@ -52,7 +52,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits = char_traits<_CharT>,
typename _Alloc = allocator<_CharT>>
- class basic_syncbuf : public basic_streambuf<_CharT, _Traits>
+ class basic_syncbuf : public __syncbuf_base<_CharT, _Traits>
{
public:
using char_type = _CharT;
@@ -69,22 +69,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
explicit
basic_syncbuf(streambuf_type* __obuf)
- : basic_syncbuf(__obuf, allocator_type{})
+ : basic_syncbuf(__obuf, allocator_type{})
{ }
basic_syncbuf(streambuf_type* __obuf, const allocator_type& __alloc)
- : _M_wrapped(__obuf)
- , _M_impl(__alloc)
- , _M_mtx(__obuf)
+ : __syncbuf_base<_CharT, _Traits>(__obuf)
+ , _M_impl(__alloc)
+ , _M_mtx(__obuf)
{ }
basic_syncbuf(basic_syncbuf&& __other)
- : _M_wrapped(__other._M_wrapped)
- , _M_impl(std::move(__other._M_impl))
- , _M_mtx(std::move(__other._M_mtx))
- , _M_emit_on_sync(__other._M_emit_on_sync)
- , _M_needs_sync(__other._M_needs_sync)
+ : __syncbuf_base<_CharT, _Traits>(__other._M_wrapped)
+ , _M_impl(std::move(__other._M_impl))
+ , _M_mtx(std::move(__other._M_mtx))
{
+ this->_M_emit_on_sync = __other._M_emit_on_sync;
+ this->_M_needs_sync = __other._M_needs_sync;
__other._M_wrapped = nullptr;
}
@@ -98,82 +98,93 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ }
}
- basic_syncbuf& operator=(basic_syncbuf&& __other)
+ basic_syncbuf&
+ operator=(basic_syncbuf&& __other)
{
- if (std::__addressof(__other) != this)
- {
- emit();
+ emit();
+
+ _M_impl = std::move(__other._M_impl);
+ this->_M_emit_on_sync = __other._M_emit_on_sync;
+ this->_M_needs_sync = __other._M_needs_sync;
+ this->_M_wrapped = __other._M_wrapped;
+ __other._M_wrapped = nullptr;
+ _M_mtx = std::move(__other._M_mtx);
- _M_impl = std::move(__other._M_impl);
- _M_wrapped = __other._M_wrapped; __other._M_wrapped = nullptr;
- _M_mtx = std::move(__other._M_mtx);
- _M_emit_on_sync = __other._M_emit_on_sync;
- _M_needs_sync = __other._M_needs_sync;
- }
return *this;
}
void
- swap(basic_syncbuf& __other)
+ swap(basic_syncbuf& __other) noexcept
{
- if (std::__addressof(__other) != this)
- {
- std::swap(_M_impl, __other._M_impl);
- std::swap(_M_wrapped, __other._M_wrapped);
- std::swap(_M_mtx, __other._M_mtx);
- std::swap(_M_emit_on_sync, __other._M_emit_on_sync);
- std::swap(_M_needs_sync, __other._M_needs_sync);
- }
+ using _ATr = allocator_traits<_Alloc>;
+ if constexpr (!_ATr::propagate_on_container_swap::value)
+ __glibcxx_assert(get_allocator() == __other.get_allocator());
+
+ std::swap(_M_impl, __other._M_impl);
+ std::swap(this->_M_emit_on_sync, __other._M_emit_on_sync);
+ std::swap(this->_M_needs_sync, __other._M_needs_sync);
+ std::swap(this->_M_wrapped, __other._M_wrapped);
+ std::swap(_M_mtx, __other._M_mtx);
}
bool
emit()
{
- if (!_M_wrapped)
+ if (!this->_M_wrapped)
return false;
- auto __s = _M_impl.view();
- if (__s.empty())
- return true;
+ auto __s = std::move(_M_impl).str();
const lock_guard<__mutex> __l(_M_mtx);
- if (_M_wrapped->sputn(__s.data(), __s.size()) != __s.size())
- return false;
+ if (auto __size = __s.size())
+ {
+ auto __n = this->_M_wrapped->sputn(__s.data(), __size);
+ if (__n != __size)
+ {
+ __s.erase(0, __n);
+ _M_impl.str(std::move(__s));
+ return false;
+ }
+ }
- if (_M_needs_sync)
+ if (this->_M_needs_sync)
{
- _M_needs_sync = false;
- if (_M_wrapped->pubsync() != 0)
+ this->_M_needs_sync = false;
+ if (this->_M_wrapped->pubsync() != 0)
return false;
}
-
- _M_impl.str("");
return true;
}
streambuf_type*
get_wrapped() const noexcept
- { return _M_wrapped; }
+ { return this->_M_wrapped; }
- allocator_type get_allocator() const noexcept
+ allocator_type
+ get_allocator() const noexcept
{ return _M_impl.get_allocator(); }
void
set_emit_on_sync(bool __b) noexcept
- { _M_emit_on_sync = __b; }
+ { this->_M_emit_on_sync = __b; }
protected:
int
sync() override
{
- auto __res = _M_impl.pubsync();
- if (__res == 0)
- {
- _M_needs_sync = true;
- if (_M_emit_on_sync)
- return emit() ? 0 : -1;
- }
- return __res;
+ this->_M_needs_sync = true;
+ if (this->_M_emit_on_sync && !emit())
+ return -1;
+ return 0;
+ }
+
+ int_type
+ overflow(int_type __c) override
+ {
+ int_type __eof = traits_type::eof();
+ if (__builtin_expect(!traits_type::eq_int_type(__c, __eof), true))
+ return _M_impl.sputc(__c);
+ return __eof;
}
streamsize
@@ -181,11 +192,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return _M_impl.sputn(__s, __n); }
private:
- streambuf_type* _M_wrapped;
-
- using __impl_type = basic_stringbuf<char_type, traits_type,
- allocator_type>;
- __impl_type _M_impl;
+ basic_stringbuf<char_type, traits_type, allocator_type> _M_impl;
struct __mutex
{
@@ -203,15 +210,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
lock()
{
- if (_M_mtx)
- _M_mtx->lock();
+ _M_mtx->lock();
}
void
unlock()
{
- if (_M_mtx)
- _M_mtx->unlock();
+ _M_mtx->unlock();
}
// FIXME: This should be put in the .so
@@ -225,31 +230,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __m[__key];
}
#else
- __mutex(void*)
- { }
-
- void
- swap(__mutex&&) noexcept
- { }
-
- void
- lock()
- { }
-
- void
- unlock()
- { }
+ __mutex(void*) { }
+ void swap(__mutex&&) noexcept { }
+ void lock() { }
+ void unlock() { }
#endif
- __mutex(const __mutex&) = delete;
- __mutex& operator=(const __mutex&) = delete;
-
__mutex(__mutex&&) = default;
__mutex& operator=(__mutex&&) = default;
};
__mutex _M_mtx;
-
- bool _M_emit_on_sync = false;
- bool _M_needs_sync = false;
};
template <typename _CharT, typename _Traits = char_traits<_CharT>,
diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread
index 887ee57..6ea8a51 100644
--- a/libstdc++-v3/include/std/thread
+++ b/libstdc++-v3/include/std/thread
@@ -37,26 +37,18 @@
#include <chrono> // std::chrono::*
-#ifdef _GLIBCXX_USE_NANOSLEEP
-# include <cerrno> // errno, EINTR
-# include <time.h> // nanosleep
-#endif
-
-#if defined(_GLIBCXX_HAS_GTHREADS)
-#include <bits/gthr.h>
-
-#include <memory> // std::unique_ptr
-#include <tuple> // std::tuple
-
#if __cplusplus > 201703L
# include <compare> // std::strong_ordering
# include <stop_token> // std::stop_source, std::stop_token, std::nostopstate
#endif
+#include <bits/std_thread.h> // std::thread, get_id, yield
#include <bits/functional_hash.h> // std::hash
-#include <bits/invoke.h> // std::__invoke
-#endif // _GLIBCXX_HAS_GTHREADS
+#ifdef _GLIBCXX_USE_NANOSLEEP
+# include <cerrno> // errno, EINTR
+# include <time.h> // nanosleep
+#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
@@ -70,221 +62,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @{
*/
-#if defined(_GLIBCXX_HAS_GTHREADS)
- /// thread
- class thread
- {
- public:
- // Abstract base class for types that wrap arbitrary functors to be
- // invoked in the new thread of execution.
- struct _State
- {
- virtual ~_State();
- virtual void _M_run() = 0;
- };
- using _State_ptr = unique_ptr<_State>;
-
- typedef __gthread_t native_handle_type;
-
- /// thread::id
- class id
- {
- native_handle_type _M_thread;
-
- public:
- id() noexcept : _M_thread() { }
-
- explicit
- id(native_handle_type __id) : _M_thread(__id) { }
-
- private:
- friend class thread;
- friend struct hash<id>;
-
- friend bool
- operator==(id __x, id __y) noexcept;
-
-#if __cpp_lib_three_way_comparison
- friend strong_ordering
- operator<=>(id __x, id __y) noexcept;
-#else
- friend bool
- operator<(id __x, id __y) noexcept;
-#endif
-
- template<class _CharT, class _Traits>
- friend basic_ostream<_CharT, _Traits>&
- operator<<(basic_ostream<_CharT, _Traits>& __out, id __id);
- };
-
- private:
- id _M_id;
-
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 2097. packaged_task constructors should be constrained
- // 3039. Unnecessary decay in thread and packaged_task
- template<typename _Tp>
- using __not_same = __not_<is_same<__remove_cvref_t<_Tp>, thread>>;
-
- public:
- thread() noexcept = default;
-
- template<typename _Callable, typename... _Args,
- typename = _Require<__not_same<_Callable>>>
- explicit
- thread(_Callable&& __f, _Args&&... __args)
- {
- static_assert( __is_invocable<typename decay<_Callable>::type,
- typename decay<_Args>::type...>::value,
- "std::thread arguments must be invocable after conversion to rvalues"
- );
-
-#ifdef GTHR_ACTIVE_PROXY
- // Create a reference to pthread_create, not just the gthr weak symbol.
- auto __depend = reinterpret_cast<void(*)()>(&pthread_create);
-#else
- auto __depend = nullptr;
-#endif
- using _Wrapper = _Call_wrapper<_Callable, _Args...>;
- // Create a call wrapper with DECAY_COPY(__f) as its target object
- // and DECAY_COPY(__args)... as its bound argument entities.
- _M_start_thread(_State_ptr(new _State_impl<_Wrapper>(
- std::forward<_Callable>(__f), std::forward<_Args>(__args)...)),
- __depend);
- }
-
- ~thread()
- {
- if (joinable())
- std::terminate();
- }
-
- thread(const thread&) = delete;
-
- thread(thread&& __t) noexcept
- { swap(__t); }
-
- thread& operator=(const thread&) = delete;
-
- thread& operator=(thread&& __t) noexcept
- {
- if (joinable())
- std::terminate();
- swap(__t);
- return *this;
- }
-
- void
- swap(thread& __t) noexcept
- { std::swap(_M_id, __t._M_id); }
-
- bool
- joinable() const noexcept
- { return !(_M_id == id()); }
-
- void
- join();
-
- void
- detach();
-
- id
- get_id() const noexcept
- { return _M_id; }
-
- /** @pre thread is joinable
- */
- native_handle_type
- native_handle()
- { return _M_id._M_thread; }
-
- // Returns a value that hints at the number of hardware thread contexts.
- static unsigned int
- hardware_concurrency() noexcept;
-
- private:
- template<typename _Callable>
- struct _State_impl : public _State
- {
- _Callable _M_func;
-
- template<typename... _Args>
- _State_impl(_Args&&... __args)
- : _M_func{{std::forward<_Args>(__args)...}}
- { }
-
- void
- _M_run() { _M_func(); }
- };
-
- void
- _M_start_thread(_State_ptr, void (*)());
-
-#if _GLIBCXX_THREAD_ABI_COMPAT
- public:
- struct _Impl_base;
- typedef shared_ptr<_Impl_base> __shared_base_type;
- struct _Impl_base
- {
- __shared_base_type _M_this_ptr;
- virtual ~_Impl_base() = default;
- virtual void _M_run() = 0;
- };
-
- private:
- void
- _M_start_thread(__shared_base_type, void (*)());
-
- void
- _M_start_thread(__shared_base_type);
-#endif
-
- private:
- // A call wrapper that does INVOKE(forwarded tuple elements...)
- template<typename _Tuple>
- struct _Invoker
- {
- _Tuple _M_t;
-
- template<typename>
- struct __result;
- template<typename _Fn, typename... _Args>
- struct __result<tuple<_Fn, _Args...>>
- : __invoke_result<_Fn, _Args...>
- { };
-
- template<size_t... _Ind>
- typename __result<_Tuple>::type
- _M_invoke(_Index_tuple<_Ind...>)
- { return std::__invoke(std::get<_Ind>(std::move(_M_t))...); }
-
- typename __result<_Tuple>::type
- operator()()
- {
- using _Indices
- = typename _Build_index_tuple<tuple_size<_Tuple>::value>::__type;
- return _M_invoke(_Indices());
- }
- };
-
- public:
- template<typename... _Tp>
- using _Call_wrapper = _Invoker<tuple<typename decay<_Tp>::type...>>;
- };
-
- inline void
- swap(thread& __x, thread& __y) noexcept
- { __x.swap(__y); }
-
- inline bool
- operator==(thread::id __x, thread::id __y) noexcept
- {
- // pthread_equal is undefined if either thread ID is not valid, so we
- // can't safely use __gthread_equal on default-constructed values (nor
- // the non-zero value returned by this_thread::get_id() for
- // single-threaded programs using GNU libc). Assume EqualityComparable.
- return __x._M_thread == __y._M_thread;
- }
+ // std::thread is defined in <bits/std_thread.h>
#if __cpp_lib_three_way_comparison
inline strong_ordering
@@ -336,7 +114,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
else
return __out << __id._M_thread;
}
-#endif // _GLIBCXX_HAS_GTHREADS
/** @namespace std::this_thread
* @brief ISO C++ 2011 namespace for interacting with the current thread
@@ -345,36 +122,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
namespace this_thread
{
-#if defined _GLIBCXX_HAS_GTHREADS
- /// get_id
- inline thread::id
- get_id() noexcept
- {
-#ifdef __GLIBC__
- // For the GNU C library pthread_self() is usable without linking to
- // libpthread.so but returns 0, so we cannot use it in single-threaded
- // programs, because this_thread::get_id() != thread::id{} must be true.
- // We know that pthread_t is an integral type in the GNU C library.
- if (!__gthread_active_p())
- return thread::id(1);
-#endif
- return thread::id(__gthread_self());
- }
-#endif // _GLIBCXX_HAS_GTHREADS
-
- /// yield
- inline void
- yield() noexcept
- {
-#if defined _GLIBCXX_HAS_GTHREADS && defined _GLIBCXX_USE_SCHED_YIELD
- __gthread_yield();
-#endif
- }
-
void
__sleep_for(chrono::seconds, chrono::nanoseconds);
- /// sleep_for
+ /// this_thread::sleep_for
template<typename _Rep, typename _Period>
inline void
sleep_for(const chrono::duration<_Rep, _Period>& __rtime)
@@ -396,7 +147,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
}
- /// sleep_until
+ /// this_thread::sleep_until
template<typename _Clock, typename _Duration>
inline void
sleep_until(const chrono::time_point<_Clock, _Duration>& __atime)
@@ -421,6 +172,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#ifdef __cpp_lib_jthread
+ /// A thread that can be requested to stop and automatically joined.
class jthread
{
public:
@@ -456,7 +208,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator=(const jthread&) = delete;
jthread&
- operator=(jthread&&) noexcept = default;
+ operator=(jthread&& __other) noexcept
+ {
+ std::jthread(std::move(__other)).swap(*this);
+ return *this;
+ }
void
swap(jthread& __other) noexcept
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index 7f51ef3..e4a8bed 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -197,7 +197,13 @@
#if _GLIBCXX_HOSTED
#define __cpp_lib_array_constexpr 201811L
#define __cpp_lib_assume_aligned 201811L
+#if defined _GLIBCXX_HAS_GTHREADS || defined _GLIBCXX_HAVE_LINUX_FUTEX
+# define __cpp_lib_atomic_wait 201907L
+#endif
#define __cpp_lib_bind_front 201907L
+#if __has_builtin(__builtin_bit_cast)
+# define __cpp_lib_bit_cast 201806L
+#endif
// FIXME: #define __cpp_lib_execution 201902L
#define __cpp_lib_integer_comparison_functions 202002L
#define __cpp_lib_constexpr_algorithms 201806L
@@ -216,6 +222,9 @@
#ifdef _GLIBCXX_HAS_GTHREADS
# define __cpp_lib_jthread 201911L
#endif
+#if __cpp_lib_atomic_wait
+# define __cpp_lib_latch 201907L
+#endif
#define __cpp_lib_list_remove_return_type 201806L
#if __cpp_lib_concepts
# define __cpp_lib_make_obj_using_allocator 201811L
@@ -225,8 +234,16 @@
#if __cpp_lib_concepts
# define __cpp_lib_ranges 201911L
#endif
+#if __cpp_lib_atomic_wait
+# define __cpp_lib_semaphore 201907L
+#endif
#define __cpp_lib_shift 201806L
-#define __cpp_lib_span 202002L
+#if __has_builtin(__builtin_source_location)
+# define __cpp_lib_source_location 201907L
+#endif
+#if __cpp_lib_concepts
+# define __cpp_lib_span 202002L
+#endif
#define __cpp_lib_ssize 201902L
#define __cpp_lib_starts_ends_with 201711L
# if _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index c0f061f..9c63937 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -479,7 +479,27 @@ class StdVectorIteratorPrinter:
return 'non-dereferenceable iterator for std::vector'
return str(self.val['_M_current'].dereference())
-# TODO add printer for vector<bool>'s _Bit_iterator and _Bit_const_iterator
+class StdBitIteratorPrinter:
+ "Print std::vector<bool>'s _Bit_iterator and _Bit_const_iterator"
+
+ def __init__(self, typename, val):
+ self.val = val
+
+ def to_string(self):
+ if not self.val['_M_p']:
+ return 'non-dereferenceable iterator for std::vector<bool>'
+ return bool(self.val['_M_p'].dereference() & (1 << self.val['_M_offset']))
+
+class StdBitReferencePrinter:
+ "Print std::_Bit_reference"
+
+ def __init__(self, typename, val):
+ self.val = val
+
+ def to_string(self):
+ if not self.val['_M_p']:
+ return 'invalid std::_Bit_reference'
+ return bool(self.val['_M_p'].dereference() & (self.val['_M_mask']))
class StdTuplePrinter:
"Print a std::tuple"
@@ -1106,6 +1126,29 @@ class SingleObjContainerPrinter(object):
return self.visualizer.display_hint ()
return self.hint
+def function_pointer_to_name(f):
+ "Find the name of the function referred to by the gdb.Value f, "
+ " which should contain a function pointer from the program."
+
+ # Turn the function pointer into an actual address.
+ # This is needed to unpack ppc64 function descriptors.
+ f = f.dereference().address
+
+ if sys.version_info[0] == 2:
+ # Older versions of GDB need to use long for Python 2,
+ # because int(f) on 64-bit big-endian values raises a
+ # gdb.error saying "Cannot convert value to int."
+ f = long(f)
+ else:
+ f = int(f)
+
+ try:
+ # If the function can't be found older versions of GDB raise a
+ # RuntimeError saying "Cannot locate object file for block."
+ return gdb.block_for_pc(f).function.name
+ except:
+ return None
+
class StdExpAnyPrinter(SingleObjContainerPrinter):
"Print a std::any or std::experimental::any"
@@ -1118,11 +1161,11 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
visualizer = None
mgr = self.val['_M_manager']
if mgr != 0:
- func = gdb.block_for_pc(int(mgr.cast(gdb.lookup_type('intptr_t'))))
+ func = function_pointer_to_name(mgr)
if not func:
- raise ValueError("Invalid function pointer in %s" % self.typename)
+ raise ValueError("Invalid function pointer in %s" % (self.typename))
rx = r"""({0}::_Manager_\w+<.*>)::_S_manage\((enum )?{0}::_Op, (const {0}|{0} const) ?\*, (union )?{0}::_Arg ?\*\)""".format(typename)
- m = re.match(rx, func.function.name)
+ m = re.match(rx, func)
if not m:
raise ValueError("Unknown manager function in %s" % self.typename)
@@ -1274,6 +1317,7 @@ class StdExpPathPrinter:
def __init__ (self, typename, val):
self.val = val
+ self.typename = typename
start = self.val['_M_cmpts']['_M_impl']['_M_start']
finish = self.val['_M_cmpts']['_M_impl']['_M_finish']
self.num_cmpts = int (finish - start)
@@ -1292,10 +1336,11 @@ class StdExpPathPrinter:
t = self._path_type()
if t:
path = '%s [%s]' % (path, t)
- return "filesystem::path %s" % path
+ return "experimental::filesystem::path %s" % path
class _iterator(Iterator):
- def __init__(self, cmpts):
+ def __init__(self, cmpts, pathtype):
+ self.pathtype = pathtype
self.item = cmpts['_M_impl']['_M_start']
self.finish = cmpts['_M_impl']['_M_finish']
self.count = 0
@@ -1311,13 +1356,13 @@ class StdExpPathPrinter:
self.count = self.count + 1
self.item = self.item + 1
path = item['_M_pathname']
- t = StdExpPathPrinter(item.type.name, item)._path_type()
+ t = StdExpPathPrinter(self.pathtype, item)._path_type()
if not t:
t = count
return ('[%s]' % t, path)
def children(self):
- return self._iterator(self.val['_M_cmpts'])
+ return self._iterator(self.val['_M_cmpts'], self.typename)
class StdPathPrinter:
"Print a std::filesystem::path"
@@ -1350,6 +1395,7 @@ class StdPathPrinter:
class _iterator(Iterator):
def __init__(self, impl, pathtype):
+ self.pathtype = pathtype
if impl:
# We can't access _Impl::_M_size because _Impl is incomplete
# so cast to int* to access the _M_size member at offset zero,
@@ -1382,7 +1428,7 @@ class StdPathPrinter:
self.count = self.count + 1
self.item = self.item + 1
path = item['_M_pathname']
- t = StdPathPrinter(item.type.name, item)._path_type()
+ t = StdPathPrinter(self.pathtype, item)._path_type()
if not t:
t = count
return ('[%s]' % t, path)
@@ -1965,6 +2011,12 @@ def build_libstdcxx_dictionary ():
StdDequeIteratorPrinter)
libstdcxx_printer.add_version('__gnu_cxx::', '__normal_iterator',
StdVectorIteratorPrinter)
+ libstdcxx_printer.add_version('std::', '_Bit_iterator',
+ StdBitIteratorPrinter)
+ libstdcxx_printer.add_version('std::', '_Bit_const_iterator',
+ StdBitIteratorPrinter)
+ libstdcxx_printer.add_version('std::', '_Bit_reference',
+ StdBitReferencePrinter)
libstdcxx_printer.add_version('__gnu_cxx::', '_Slist_iterator',
StdSlistIteratorPrinter)
libstdcxx_printer.add_container('std::', '_Fwd_list_iterator',
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index 1eda70e..21b6db7 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -269,8 +269,8 @@ libstdc++-symbols.ver-sun : libstdc++-symbols.ver \
perl $(toplevel_srcdir)/contrib/make_sunver.pl \
libstdc++-symbols.ver \
$(libstdc___la_OBJECTS:%.lo=.libs/%.o) \
- `echo $(libstdc___la_LIBADD) | \
- sed 's,/\([^/.]*\)\.la,/.libs/\1.a,g'` \
+ `echo ' $(libstdc___la_LIBADD) ' | \
+ sed -e 's,/\([^/.]*\)\.la,/.libs/\1.a,g' -e 's/ -l[^ ]* / /'` \
> $@ || (rm -f $@ ; exit 1)
endif
if ENABLE_SYMVERS_DARWIN
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index 7f55917..e7ccdae 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -1022,8 +1022,8 @@ compatibility-condvar.o: compatibility-condvar.cc
@ENABLE_SYMVERS_SUN_TRUE@@ENABLE_SYMVERS_TRUE@ perl $(toplevel_srcdir)/contrib/make_sunver.pl \
@ENABLE_SYMVERS_SUN_TRUE@@ENABLE_SYMVERS_TRUE@ libstdc++-symbols.ver \
@ENABLE_SYMVERS_SUN_TRUE@@ENABLE_SYMVERS_TRUE@ $(libstdc___la_OBJECTS:%.lo=.libs/%.o) \
-@ENABLE_SYMVERS_SUN_TRUE@@ENABLE_SYMVERS_TRUE@ `echo $(libstdc___la_LIBADD) | \
-@ENABLE_SYMVERS_SUN_TRUE@@ENABLE_SYMVERS_TRUE@ sed 's,/\([^/.]*\)\.la,/.libs/\1.a,g'` \
+@ENABLE_SYMVERS_SUN_TRUE@@ENABLE_SYMVERS_TRUE@ `echo ' $(libstdc___la_LIBADD) ' | \
+@ENABLE_SYMVERS_SUN_TRUE@@ENABLE_SYMVERS_TRUE@ sed -e 's,/\([^/.]*\)\.la,/.libs/\1.a,g' -e 's/ -l[^ ]* / /'` \
@ENABLE_SYMVERS_SUN_TRUE@@ENABLE_SYMVERS_TRUE@ > $@ || (rm -f $@ ; exit 1)
@ENABLE_SYMVERS_DARWIN_TRUE@@ENABLE_SYMVERS_TRUE@libstdc++-symbols.explist : libstdc++-symbols.ver \
@ENABLE_SYMVERS_DARWIN_TRUE@@ENABLE_SYMVERS_TRUE@ ${glibcxx_srcdir}/scripts/make_exports.pl \
diff --git a/libstdc++-v3/src/c++11/condition_variable.cc b/libstdc++-v3/src/c++11/condition_variable.cc
index 19b03da..92721bb 100644
--- a/libstdc++-v3/src/c++11/condition_variable.cc
+++ b/libstdc++-v3/src/c++11/condition_variable.cc
@@ -31,51 +31,26 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
-#ifdef __GTHREAD_COND_INIT
condition_variable::condition_variable() noexcept = default;
-#else
- condition_variable::condition_variable() noexcept
- {
- __GTHREAD_COND_INIT_FUNCTION(&_M_cond);
- }
-#endif
- condition_variable::~condition_variable() noexcept
- {
- // XXX no thread blocked
- /* int __e = */ __gthread_cond_destroy(&_M_cond);
- // if __e == EBUSY then blocked
- }
+ condition_variable::~condition_variable() noexcept = default;
void
condition_variable::wait(unique_lock<mutex>& __lock) noexcept
{
- int __e = __gthread_cond_wait(&_M_cond, __lock.mutex()->native_handle());
-
- if (__e)
- std::terminate();
+ _M_cond.wait(*__lock.mutex());
}
void
condition_variable::notify_one() noexcept
{
- int __e = __gthread_cond_signal(&_M_cond);
-
- // XXX not in spec
- // EINVAL
- if (__e)
- __throw_system_error(__e);
+ _M_cond.notify_one();
}
void
condition_variable::notify_all() noexcept
{
- int __e = __gthread_cond_broadcast(&_M_cond);
-
- // XXX not in spec
- // EINVAL
- if (__e)
- __throw_system_error(__e);
+ _M_cond.notify_all();
}
extern void
diff --git a/libstdc++-v3/src/c++11/futex.cc b/libstdc++-v3/src/c++11/futex.cc
index 0331bd6..290201a 100644
--- a/libstdc++-v3/src/c++11/futex.cc
+++ b/libstdc++-v3/src/c++11/futex.cc
@@ -31,6 +31,7 @@
#include <unistd.h>
#include <sys/time.h>
#include <errno.h>
+#include <ext/numeric_traits.h>
#include <debug/debug.h>
#ifdef _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL
@@ -46,20 +47,71 @@ const unsigned futex_clock_realtime_flag = 256;
const unsigned futex_bitset_match_any = ~0;
const unsigned futex_wake_op = 1;
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ using __gnu_cxx::__int_traits;
+
namespace
{
std::atomic<bool> futex_clock_realtime_unavailable;
std::atomic<bool> futex_clock_monotonic_unavailable;
-}
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
+#if defined(SYS_futex_time64) && SYS_futex_time64 != SYS_futex
+ // Userspace knows about the new time64 syscalls, so it's possible that
+ // userspace has also updated timespec to use a 64-bit tv_sec.
+ // The SYS_futex syscall still uses the old definition of timespec
+ // where tv_sec is 32 bits, so define a type that matches that.
+ struct syscall_timespec { long tv_sec; long tv_nsec; };
+ using syscall_time_t = long;
+#else
+ using syscall_timespec = ::timespec;
+ using syscall_time_t = time_t;
+#endif
+
+ // Return the relative duration from (now_s + now_ns) to (abs_s + abs_ns)
+ // as a timespec suitable for syscalls.
+ syscall_timespec
+ relative_timespec(chrono::seconds abs_s, chrono::nanoseconds abs_ns,
+ time_t now_s, long now_ns)
+ {
+ syscall_timespec rt;
+
+ // Did we already time out?
+ if (now_s > abs_s.count())
+ {
+ rt.tv_sec = -1;
+ return rt;
+ }
+
+ const auto rel_s = abs_s.count() - now_s;
+
+ // Convert the absolute timeout to a relative timeout, without overflow.
+ if (rel_s > __int_traits<syscall_time_t>::__max) [[unlikely]]
+ {
+ rt.tv_sec = __int_traits<syscall_time_t>::__max;
+ rt.tv_nsec = 999999999;
+ }
+ else
+ {
+ rt.tv_sec = rel_s;
+ rt.tv_nsec = abs_ns.count() - now_ns;
+ if (rt.tv_nsec < 0)
+ {
+ rt.tv_nsec += 1000000000;
+ --rt.tv_sec;
+ }
+ }
+
+ return rt;
+ }
+} // namespace
bool
- __atomic_futex_unsigned_base::_M_futex_wait_until(unsigned *__addr,
- unsigned __val,
- bool __has_timeout, chrono::seconds __s, chrono::nanoseconds __ns)
+ __atomic_futex_unsigned_base::
+ _M_futex_wait_until(unsigned *__addr, unsigned __val, bool __has_timeout,
+ chrono::seconds __s, chrono::nanoseconds __ns)
{
if (!__has_timeout)
{
@@ -75,9 +127,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
if (!futex_clock_realtime_unavailable.load(std::memory_order_relaxed))
{
- struct timespec rt;
- rt.tv_sec = __s.count();
+ // futex sets errno=EINVAL for absolute timeouts before the epoch.
+ if (__s.count() < 0)
+ return false;
+
+ syscall_timespec rt;
+ if (__s.count() > __int_traits<syscall_time_t>::__max) [[unlikely]]
+ rt.tv_sec = __int_traits<syscall_time_t>::__max;
+ else
+ rt.tv_sec = __s.count();
rt.tv_nsec = __ns.count();
+
if (syscall (SYS_futex, __addr,
futex_wait_bitset_op | futex_clock_realtime_flag,
__val, &rt, nullptr, futex_bitset_match_any) == -1)
@@ -104,15 +164,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// true or has just been set to true.
struct timeval tv;
gettimeofday (&tv, NULL);
+
// Convert the absolute timeout value to a relative timeout
- struct timespec rt;
- rt.tv_sec = __s.count() - tv.tv_sec;
- rt.tv_nsec = __ns.count() - tv.tv_usec * 1000;
- if (rt.tv_nsec < 0)
- {
- rt.tv_nsec += 1000000000;
- --rt.tv_sec;
- }
+ auto rt = relative_timespec(__s, __ns, tv.tv_sec, tv.tv_usec * 1000);
+
// Did we already time out?
if (rt.tv_sec < 0)
return false;
@@ -129,9 +184,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
bool
- __atomic_futex_unsigned_base::_M_futex_wait_until_steady(unsigned *__addr,
- unsigned __val,
- bool __has_timeout, chrono::seconds __s, chrono::nanoseconds __ns)
+ __atomic_futex_unsigned_base::
+ _M_futex_wait_until_steady(unsigned *__addr, unsigned __val,
+ bool __has_timeout,
+ chrono::seconds __s, chrono::nanoseconds __ns)
{
if (!__has_timeout)
{
@@ -147,8 +203,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
if (!futex_clock_monotonic_unavailable.load(std::memory_order_relaxed))
{
- struct timespec rt;
- rt.tv_sec = __s.count();
+ // futex sets errno=EINVAL for absolute timeouts before the epoch.
+ if (__s.count() < 0) [[unlikely]]
+ return false;
+
+ syscall_timespec rt;
+ if (__s.count() > __int_traits<syscall_time_t>::__max) [[unlikely]]
+ rt.tv_sec = __int_traits<syscall_time_t>::__max;
+ else
+ rt.tv_sec = __s.count();
rt.tv_nsec = __ns.count();
if (syscall (SYS_futex, __addr,
@@ -179,15 +242,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#else
clock_gettime(CLOCK_MONOTONIC, &ts);
#endif
+
// Convert the absolute timeout value to a relative timeout
- struct timespec rt;
- rt.tv_sec = __s.count() - ts.tv_sec;
- rt.tv_nsec = __ns.count() - ts.tv_nsec;
- if (rt.tv_nsec < 0)
- {
- rt.tv_nsec += 1000000000;
- --rt.tv_sec;
- }
+ auto rt = relative_timespec(__s, __ns, ts.tv_sec, ts.tv_nsec);
+
// Did we already time out?
if (rt.tv_sec < 0)
return false;
diff --git a/libstdc++-v3/src/c++11/thread.cc b/libstdc++-v3/src/c++11/thread.cc
index a4c87d8..a9c9280 100644
--- a/libstdc++-v3/src/c++11/thread.cc
+++ b/libstdc++-v3/src/c++11/thread.cc
@@ -24,6 +24,7 @@
#define _GLIBCXX_THREAD_ABI_COMPAT 1
+#include <memory> // include this first so <thread> can use shared_ptr
#include <thread>
#include <system_error>
#include <cerrno>
@@ -132,6 +133,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
thread::_M_start_thread(_State_ptr state, void (*)())
{
+ if (!__gthread_active_p())
+ {
+#if __cpp_exceptions
+ throw system_error(make_error_code(errc::operation_not_permitted),
+ "Enable multithreading to use std::thread");
+#else
+ __builtin_abort();
+#endif
+ }
+
const int err = __gthread_create(&_M_id._M_thread,
&execute_native_thread_routine,
state.get());
diff --git a/libstdc++-v3/src/c++20/sstream-inst.cc b/libstdc++-v3/src/c++20/sstream-inst.cc
index 7d275de..9e157d1 100644
--- a/libstdc++-v3/src/c++20/sstream-inst.cc
+++ b/libstdc++-v3/src/c++20/sstream-inst.cc
@@ -46,29 +46,53 @@ template basic_stringbuf<char>::basic_stringbuf(basic_stringbuf&&,
__xfer_bufptrs&&);
template basic_stringbuf<char>::allocator_type
basic_stringbuf<char>::get_allocator() const noexcept;
+template string
+basic_stringbuf<char>::str() const &;
+template string
+basic_stringbuf<char>::str() &&;
template string_view
basic_stringbuf<char>::view() const noexcept;
+template void
+basic_stringbuf<char>::str(string&&);
template basic_istringstream<char>::basic_istringstream(ios_base::openmode,
const allocator_type&);
template basic_istringstream<char>::basic_istringstream(__string_type&&,
ios_base::openmode);
+template string
+basic_istringstream<char>::str() const &;
+template string
+basic_istringstream<char>::str() &&;
template string_view
basic_istringstream<char>::view() const noexcept;
+template void
+basic_istringstream<char>::str(string&&);
template basic_ostringstream<char>::basic_ostringstream(ios_base::openmode,
const allocator_type&);
template basic_ostringstream<char>::basic_ostringstream(__string_type&&,
ios_base::openmode);
+template string
+basic_ostringstream<char>::str() const &;
+template string
+basic_ostringstream<char>::str() &&;
template string_view
basic_ostringstream<char>::view() const noexcept;
+template void
+basic_ostringstream<char>::str(string&&);
template basic_stringstream<char>::basic_stringstream(ios_base::openmode,
const allocator_type&);
template basic_stringstream<char>::basic_stringstream(__string_type&&,
ios_base::openmode);
+template string
+basic_stringstream<char>::str() const &;
+template string
+basic_stringstream<char>::str() &&;
template string_view
basic_stringstream<char>::view() const noexcept;
+template void
+basic_stringstream<char>::str(string&&);
#ifdef _GLIBCXX_USE_WCHAR_T
template basic_stringbuf<wchar_t>::basic_stringbuf(const allocator_type&);
@@ -84,29 +108,53 @@ template basic_stringbuf<wchar_t>::basic_stringbuf(basic_stringbuf&&,
template basic_stringbuf<wchar_t>::allocator_type
basic_stringbuf<wchar_t>::get_allocator() const noexcept;
+template wstring
+basic_stringbuf<wchar_t>::str() const &;
+template wstring
+basic_stringbuf<wchar_t>::str() &&;
template wstring_view
basic_stringbuf<wchar_t>::view() const noexcept;
+template void
+basic_stringbuf<wchar_t>::str(wstring&&);
template basic_istringstream<wchar_t>::basic_istringstream(ios_base::openmode,
const allocator_type&);
template basic_istringstream<wchar_t>::basic_istringstream(__string_type&&,
ios_base::openmode);
+template wstring
+basic_istringstream<wchar_t>::str() const &;
+template wstring
+basic_istringstream<wchar_t>::str() &&;
template wstring_view
basic_istringstream<wchar_t>::view() const noexcept;
+template void
+basic_istringstream<wchar_t>::str(wstring&&);
template basic_ostringstream<wchar_t>::basic_ostringstream(ios_base::openmode,
const allocator_type&);
template basic_ostringstream<wchar_t>::basic_ostringstream(__string_type&&,
ios_base::openmode);
+template wstring
+basic_ostringstream<wchar_t>::str() const &;
+template wstring
+basic_ostringstream<wchar_t>::str() &&;
template wstring_view
basic_ostringstream<wchar_t>::view() const noexcept;
+template void
+basic_ostringstream<wchar_t>::str(wstring&&);
template basic_stringstream<wchar_t>::basic_stringstream(ios_base::openmode,
const allocator_type&);
template basic_stringstream<wchar_t>::basic_stringstream(__string_type&&,
ios_base::openmode);
+template wstring
+basic_stringstream<wchar_t>::str() const &;
+template wstring
+basic_stringstream<wchar_t>::str() &&;
template wstring_view
basic_stringstream<wchar_t>::view() const noexcept;
+template void
+basic_stringstream<wchar_t>::str(wstring&&);
#endif
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/src/c++98/locale.cc b/libstdc++-v3/src/c++98/locale.cc
index 0642241..4c1612c 100644
--- a/libstdc++-v3/src/c++98/locale.cc
+++ b/libstdc++-v3/src/c++98/locale.cc
@@ -515,7 +515,7 @@ namespace {
#endif
#ifdef __GTHREADS
- if (__gthread_active_p())
+ if (!__gnu_cxx::__is_single_threaded())
{
if (__atomic_always_lock_free(sizeof(_M_index), &_M_index))
{
diff --git a/libstdc++-v3/testsuite/17_intro/names.cc b/libstdc++-v3/testsuite/17_intro/names.cc
index 5a61c97..2c8bfff 100644
--- a/libstdc++-v3/testsuite/17_intro/names.cc
+++ b/libstdc++-v3/testsuite/17_intro/names.cc
@@ -193,6 +193,8 @@
#undef r
#undef x
#undef y
+// <sys/var.h> defines vario::v
+#undef v
#endif
#ifdef __hpux__
diff --git a/libstdc++-v3/testsuite/18_support/96817.cc b/libstdc++-v3/testsuite/18_support/96817.cc
index 4591a72..7f35f03 100644
--- a/libstdc++-v3/testsuite/18_support/96817.cc
+++ b/libstdc++-v3/testsuite/18_support/96817.cc
@@ -15,19 +15,18 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// { dg-options "-pthread" }
-// { dg-do run { target *-*-linux-gnu } }
-// { dg-require-effective-target pthread }
+// { dg-do run }
+// { dg-additional-options "-pthread" { target pthread } }
+
+// Static init cannot detect recursion for gthreads targets without futexes
+// (and the futex case can only detect it if __libc_single_threaded==true).
+// { dg-skip-if "unsupported" { gthreads && { ! futex } } }
// PR libstdc++/96817
#include <exception>
#include <stdlib.h>
-#ifndef _GLIBCXX_HAVE_LINUX_FUTEX
-# error "This test requries futex support in the library"
-#endif
-
int init()
{
#if __has_include(<sys/single_threaded.h>)
diff --git a/libstdc++-v3/testsuite/18_support/source_location/1.cc b/libstdc++-v3/testsuite/18_support/source_location/1.cc
new file mode 100644
index 0000000..c945aaa
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/source_location/1.cc
@@ -0,0 +1,155 @@
+// Copyright (C) 2020 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/>.
+
+// Example from C++ Standard Working Draft N4842, November 2019 Mailing
+// Adapted for testing.
+
+// { dg-options "-std=gnu++2a -include string -include stdexcept" }
+// { dg-do run { target c++2a } }
+
+#include <source_location>
+
+#ifndef __cpp_lib_source_location
+# error "Feature-test macro for source_location missing in <source_location>"
+#elif __cpp_lib_source_location != 201907L
+# error "Feature-test macro for source_location has wrong value in <source_location>"
+#endif
+
+#include <string_view>
+#include <testsuite_hooks.h>
+#include "srcloc.h"
+
+
+struct s {
+ std::source_location member = std::source_location::current();
+ int other_member = 1;
+
+ s(std::source_location loc = std::source_location::current())
+ : member(loc) // values of member refer to calling function
+ { }
+
+ s(int blather) : // values of member refer to this location
+ other_member(blather)
+ { }
+};
+
+std::source_location
+f(std::source_location a = std::source_location::current());
+
+std::source_location
+f(std::source_location a)
+{ return a; }
+
+auto
+g()
+{
+ struct srcloc_and_line
+ {
+ std::source_location sl;
+ unsigned line;
+ };
+
+ std::source_location c = std::source_location::current();
+ return srcloc_and_line{ f(c), __LINE__ - 1 };
+}
+
+int main ()
+{
+ std::source_location main_sl = std::source_location::current();
+ unsigned main_sl_line = __LINE__ - 1;
+ std::source_location f_arg_sl = f(main_sl);
+ unsigned f_arg_sl_line = main_sl_line;
+ auto [g_sl, g_sl_line] = g();
+ std::source_location f_sl = f();
+ unsigned f_sl_line = __LINE__ - 1;
+ std::source_location h_sl = h(); // defined in ./srcloc.h
+ s member_main_sl(main_sl);
+ s member_defaulted_sl(1);
+ s member_sl = s{};
+ const unsigned member_sl_line = __LINE__ - 1;
+
+ using namespace std::string_view_literals;
+
+ std::string_view main_sl_fn_name(main_sl.function_name());
+ std::string_view main_sl_fi_name(main_sl.file_name());
+ VERIFY(main_sl.line() == main_sl_line);
+ // closing paren of call
+ VERIFY(main_sl.column() == 64);
+ VERIFY(main_sl_fn_name.ends_with("main"sv));
+ VERIFY(main_sl_fi_name.ends_with("1.cc"sv));
+
+ std::string_view f_arg_sl_fn_name(f_arg_sl.function_name());
+ std::string_view f_arg_sl_fi_name(f_arg_sl.file_name());
+ VERIFY(f_arg_sl.line() == f_arg_sl_line);
+ // closing paren of call
+ VERIFY(f_arg_sl.column() == 64);
+ VERIFY(f_arg_sl_fn_name.ends_with("main"sv));
+ VERIFY(f_arg_sl_fi_name.ends_with("1.cc"sv));
+
+ std::string_view g_sl_fn_name(g_sl.function_name());
+ std::string_view g_sl_fi_name(g_sl.file_name());
+ VERIFY(g_sl.line() == g_sl_line);
+ VERIFY(g_sl.column() == 58); // closing paren of call
+ VERIFY(g_sl_fn_name.ends_with("g"sv));
+ VERIFY(g_sl_fi_name.ends_with("1.cc"sv));
+
+ std::string_view h_sl_fn_name(h_sl.function_name());
+ std::string_view h_sl_fi_name(h_sl.file_name());
+ VERIFY(h_sl.line() == 23);
+ VERIFY(h_sl.column() == 58); // closing paren of call
+ VERIFY(h_sl_fn_name.ends_with("h"sv));
+ VERIFY(h_sl_fi_name.ends_with("srcloc.h"sv));
+
+ std::string_view member_main_sl_fn_name(member_main_sl.member.function_name());
+ std::string_view member_main_sl_fi_name(member_main_sl.member.file_name());
+ VERIFY(member_main_sl.member.line() == main_sl_line);
+ VERIFY(member_main_sl.member.column() == 64);
+ VERIFY(member_main_sl_fn_name.ends_with("main"sv));
+ VERIFY(member_main_sl_fi_name.ends_with("1.cc"sv));
+
+ std::string_view member_defaulted_sl_fi_name(
+ member_defaulted_sl.member.file_name());
+ std::string_view member_defaulted_sl_fn_name(
+ member_defaulted_sl.member.function_name());
+ VERIFY(member_defaulted_sl.member.line() == 46);
+ // closing paren of constructor declaration
+ VERIFY(member_defaulted_sl.member.column() == 25);
+#if 0
+ VERIFY(member_defaulted_sl_fn_name.starts_with("s::s(int)"sv));
+#endif
+ VERIFY(member_defaulted_sl_fi_name.ends_with("1.cc"sv));
+
+ std::string_view member_sl_fi_name(
+ member_sl.member.file_name());
+ std::string_view member_sl_fn_name(
+ member_sl.member.function_name());
+ VERIFY(member_sl.member.line() == member_sl_line);
+ // closing brace/paren of constructor
+ VERIFY(member_sl.member.column() == 19);
+ VERIFY(member_sl_fn_name.starts_with("main"sv));
+ VERIFY(member_sl_fi_name.ends_with("1.cc"sv));
+
+ std::string_view f_sl_fi_name(f_sl.file_name());
+ std::string_view f_sl_fn_name(f_sl.function_name());
+ VERIFY(f_sl.line() == f_sl_line);
+ // closing paren of call
+ VERIFY(f_sl.column() == 33);
+ VERIFY(f_sl_fn_name.ends_with("main"sv));
+ VERIFY(f_sl_fi_name.ends_with("1.cc"sv));
+
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/18_support/source_location/consteval.cc b/libstdc++-v3/testsuite/18_support/source_location/consteval.cc
new file mode 100644
index 0000000..9b137f8
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/source_location/consteval.cc
@@ -0,0 +1,149 @@
+// Copyright (C) 2020 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/>.
+
+// Example from C++ Standard Working Draft N4842, November 2019 Mailing
+// Adapted for testing.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <source_location>
+#include <string_view>
+
+struct s {
+ std::source_location member = std::source_location::current();
+ int other_member = 1;
+
+ constexpr s(std::source_location loc = std::source_location::current())
+ : member(loc) // values of member refer to calling function
+ { }
+
+ constexpr s(int blather) : // values of member refer to this location
+ other_member(blather)
+ { }
+};
+
+constexpr std::source_location
+f(std::source_location a = std::source_location::current())
+{ return a; }
+
+constexpr auto
+g()
+{
+ struct srcloc_and_line
+ {
+ std::source_location sl;
+ unsigned line;
+ };
+
+ std::source_location c = std::source_location::current();
+ return srcloc_and_line{ f(c), __LINE__ - 1 };
+}
+
+#include "srcloc.h"
+
+int main ()
+{
+ constexpr std::source_location main_sl = std::source_location::current();
+ constexpr unsigned main_sl_line = __LINE__ - 1;
+ constexpr std::source_location f_arg_sl = f(main_sl);
+ constexpr unsigned f_arg_sl_line = main_sl_line;
+ constexpr std::source_location g_sl = g().sl;
+ constexpr unsigned g_sl_line = g().line;
+ constexpr std::source_location f_sl = f();
+ constexpr unsigned f_sl_line = __LINE__ - 1;
+ constexpr std::source_location h_sl = h(); // defined in ./srcloc.h
+ constexpr s member_main_sl(main_sl);
+ constexpr s member_defaulted_sl(1);
+ constexpr s member_sl = s{};
+ constexpr unsigned member_sl_line = __LINE__ - 1;
+
+ using namespace std::string_view_literals;
+
+ static_assert (std::source_location::current ().line () == __LINE__);
+ static_assert (std::source_location::current ().column () == 49);
+
+
+ constexpr std::string_view main_sl_fn_name(main_sl.function_name());
+ constexpr std::string_view main_sl_fi_name(main_sl.file_name());
+ static_assert(main_sl.line() == main_sl_line);
+ // closing paren of call
+ static_assert(main_sl.column() == 74);
+ static_assert(main_sl_fn_name.ends_with("main"sv));
+ static_assert(main_sl_fi_name.ends_with("consteval.cc"sv));
+
+ constexpr std::string_view f_arg_sl_fn_name(f_arg_sl.function_name());
+ constexpr std::string_view f_arg_sl_fi_name(f_arg_sl.file_name());
+ static_assert(f_arg_sl.line() == f_arg_sl_line);
+ // closing paren of call
+ static_assert(f_arg_sl.column() == 74);
+ static_assert(f_arg_sl_fn_name.ends_with("main"sv));
+ static_assert(f_arg_sl_fi_name.ends_with("consteval.cc"sv));
+
+ constexpr std::string_view g_sl_fn_name(g_sl.function_name());
+ constexpr std::string_view g_sl_fi_name(g_sl.file_name());
+ static_assert(g_sl.line() == g_sl_line);
+ static_assert(g_sl.column() == 58); // closing paren of call
+ static_assert(g_sl_fn_name.ends_with("g"sv));
+ static_assert(g_sl_fi_name.ends_with("consteval.cc"sv));
+
+ constexpr std::string_view h_sl_fn_name(h_sl.function_name());
+ constexpr std::string_view h_sl_fi_name(h_sl.file_name());
+ static_assert(h_sl.line() == 23);
+ static_assert(h_sl.column() == 58); // closing paren of call
+ static_assert(h_sl_fn_name.ends_with("h"sv));
+ static_assert(h_sl_fi_name.ends_with("srcloc.h"sv));
+
+ constexpr std::string_view member_main_sl_fn_name(member_main_sl.member.function_name());
+ constexpr std::string_view member_main_sl_fi_name(member_main_sl.member.file_name());
+ static_assert(member_main_sl.member.line() == main_sl_line);
+ static_assert(member_main_sl.member.column() == 74);
+ static_assert(member_main_sl_fn_name.ends_with("main"sv));
+ static_assert(member_main_sl_fi_name.ends_with("consteval.cc"sv));
+
+ constexpr std::string_view member_defaulted_sl_fi_name(
+ member_defaulted_sl.member.file_name());
+ constexpr std::string_view member_defaulted_sl_fn_name(
+ member_defaulted_sl.member.function_name());
+ static_assert(member_defaulted_sl.member.line() == 36);
+ // closing paren of constructor declaration
+ static_assert(member_defaulted_sl.member.column() == 25);
+#if 0
+ static_assert(member_defaulted_sl_fn_name.ends_with("s::s(int)"sv));
+#endif
+ static_assert(member_defaulted_sl_fi_name.ends_with("consteval.cc"sv));
+
+ constexpr std::string_view member_sl_fi_name(
+ member_sl.member.file_name());
+ constexpr std::string_view member_sl_fn_name(
+ member_sl.member.function_name());
+ static_assert(member_sl.member.line() == member_sl_line);
+ // closing brace/paren of constructor
+ static_assert(member_sl.member.column() == 29);
+ static_assert(member_sl_fn_name.starts_with("main"sv));
+ static_assert(member_sl_fi_name.ends_with("consteval.cc"sv));
+
+ constexpr std::string_view f_sl_fi_name(f_sl.file_name());
+ constexpr std::string_view f_sl_fn_name(f_sl.function_name());
+ static_assert(f_sl.line() == f_sl_line);
+ // closing paren of call
+ static_assert(f_sl.column() == 43);
+ static_assert(f_sl_fn_name.ends_with("main"sv));
+ static_assert(f_sl_fi_name.ends_with("consteval.cc"sv));
+
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/18_support/source_location/srcloc.h b/libstdc++-v3/testsuite/18_support/source_location/srcloc.h
new file mode 100644
index 0000000..9b05458
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/source_location/srcloc.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2020 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 <source_location>
+
+constexpr std::source_location
+h()
+{
+ std::source_location a = std::source_location::current();
+ return a;
+}
diff --git a/libstdc++-v3/testsuite/18_support/source_location/version.cc b/libstdc++-v3/testsuite/18_support/source_location/version.cc
new file mode 100644
index 0000000..f2b3bf6
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/source_location/version.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2020 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 preprocess { target c++2a } }
+
+#include <version>
+
+#ifndef __cpp_lib_source_location
+# error "Feature-test macro for source_location missing in <version>"
+#elif __cpp_lib_source_location != 201907L
+# error "Feature-test macro for source_location has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/20_util/result_of/sfinae_friendly_1.cc b/libstdc++-v3/testsuite/20_util/result_of/sfinae_friendly_1.cc
index 4b44b79..cce4812 100644
--- a/libstdc++-v3/testsuite/20_util/result_of/sfinae_friendly_1.cc
+++ b/libstdc++-v3/testsuite/20_util/result_of/sfinae_friendly_1.cc
@@ -379,19 +379,19 @@ static_assert(is_type<std::result_of<ident_functor(const volatile Abstract&)>,
const volatile Abstract&>(), "Error!");
static_assert(!has_type<std::result_of<ident_functor(int(&&)[1])>>(), "Error!");
-static_assert(!has_type<std::result_of<ident_functor(Abstract&&)>>(), "Error!");
+static_assert(is_type<std::result_of<ident_functor(Abstract&&)>,Abstract>(), "Error!");
static_assert(!has_type<std::result_of<ident_functor(const int(&&)[1])>>(),
"Error!");
-static_assert(!has_type<std::result_of<ident_functor(const Abstract&&)>>(),
+static_assert(is_type<std::result_of<ident_functor(const Abstract&&)>,const Abstract>(),
"Error!");
static_assert(!has_type<std::result_of<ident_functor_noref(int(&)[1])>>(),
"Error!");
static_assert(!has_type<std::result_of<ident_functor_noref
(const int(&)[1])>>(), "Error!");
-static_assert(!has_type<std::result_of<ident_functor_noref(Abstract&)>>(),
+static_assert(is_type<std::result_of<ident_functor_noref(Abstract&)>,Abstract>(),
"Error!");
-static_assert(!has_type<std::result_of
- <ident_functor_noref(const Abstract&)>>(), "Error!");
+static_assert(is_type<std::result_of
+ <ident_functor_noref(const Abstract&)>,const Abstract>(), "Error!");
static_assert(!has_type<std::result_of<ident_functor_noref(void(&)())>>(),
"Error!");
static_assert(!has_type<std::result_of<ident_functor_noref(void(&&)())>>(),
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_construct.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_construct.cc
index 4f1911e..a6dbe69 100644
--- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_construct.cc
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_construct.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- uninitialized_construct.pass.cpp ----------------------------------===//
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_copy_move.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_copy_move.cc
index 2ecfde2..48b6a6a 100644
--- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_copy_move.cc
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_copy_move.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- uninitialized_copy_move.pass.cpp ----------------------------------===//
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_fill_destroy.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_fill_destroy.cc
index 31ea484..16a6ef2 100644
--- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_fill_destroy.cc
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_fill_destroy.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- uninitialized_fill_destroy.pass.cpp -------------------------------===//
diff --git a/libstdc++-v3/testsuite/23_containers/array/debug/constexpr_c++11.cc b/libstdc++-v3/testsuite/23_containers/array/debug/constexpr_c++11.cc
new file mode 100644
index 0000000..c8b3599
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/array/debug/constexpr_c++11.cc
@@ -0,0 +1,32 @@
+// { dg-options "-std=gnu++11 -D_GLIBCXX_DEBUG" }
+// { dg-do compile { target c++11 } }
+
+// Copyright (C) 2011-2020 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()
+{
+ // array
+ constexpr std::array<std::size_t, 6> a = { { 0, 55, 66, 99, 4115, 2 } };
+ constexpr auto v1 = a[1];
+ constexpr auto v2 = a.at(2);
+ constexpr auto v3 = a.front();
+ constexpr auto v4 = a.back();
+ static_assert( (v1 + v2 + v3 + v4) == (55 + 66 + 0 + 2), "" );
+}
diff --git a/libstdc++-v3/testsuite/23_containers/array/element_access/constexpr_element_access.cc b/libstdc++-v3/testsuite/23_containers/array/element_access/constexpr_element_access.cc
index c1dd905..037f6ea 100644
--- a/libstdc++-v3/testsuite/23_containers/array/element_access/constexpr_element_access.cc
+++ b/libstdc++-v3/testsuite/23_containers/array/element_access/constexpr_element_access.cc
@@ -19,14 +19,13 @@
#include <array>
-int main()
+void test01()
{
// array
- typedef std::array<std::size_t, 6> array_type;
- constexpr array_type a = { { 0, 55, 66, 99, 4115, 2 } };
- constexpr auto v1 __attribute__((unused)) = a[1];
- constexpr auto v2 __attribute__((unused)) = a.at(2);
- constexpr auto v3 __attribute__((unused)) = a.front();
- constexpr auto v4 __attribute__((unused)) = a.back();
- return 0;
+ constexpr std::array<std::size_t, 6> a = { { 0, 55, 66, 99, 4115, 2 } };
+ constexpr auto v1 = a[1];
+ constexpr auto v2 = a.at(2);
+ constexpr auto v3 = a.front();
+ constexpr auto v4 = a.back();
+ static_assert( (v1 + v2 + v3 + v4) == (55 + 66 + 0 + 2), "" );
}
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 88416cc..e287eef 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
@@ -26,6 +26,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 *-*-* } 357 }
-// { dg-error "static assertion failed" "" { target *-*-* } 365 }
-// { dg-error "static assertion failed" "" { target *-*-* } 373 }
+// { dg-error "static assertion failed" "" { target *-*-* } 363 }
+// { dg-error "static assertion failed" "" { target *-*-* } 371 }
+// { dg-error "static assertion failed" "" { target *-*-* } 379 }
diff --git a/libstdc++-v3/testsuite/23_containers/map/allocator/move_cons.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/move_cons.cc
new file mode 100644
index 0000000..08a14a4
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/allocator/move_cons.cc
@@ -0,0 +1,53 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <map>
+#include <string>
+
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using Cmp = std::less<int>;
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+ typedef uneq_allocator<std::pair<const int, std::string>> alloc_type;
+ typedef std::map<int, std::string, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ const char* str = "A long enough string to require dynamic allocation";
+ v1 = { { 1, str } };
+
+ alloc_type a2(2);
+ test_type v2(std::move(v1), a2);
+
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+
+ VERIFY( v1[1].empty() );
+ VERIFY( v2[1] == str );
+}
+
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/allocator/move_cons.cc b/libstdc++-v3/testsuite/23_containers/multimap/allocator/move_cons.cc
new file mode 100644
index 0000000..4fbd85d
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/allocator/move_cons.cc
@@ -0,0 +1,53 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <map>
+#include <string>
+
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using Cmp = std::less<int>;
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+ typedef uneq_allocator<std::pair<const int, std::string>> alloc_type;
+ typedef std::multimap<int, std::string, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ const char* str = "A long enough string to require dynamic allocation";
+ v1 = { { 1, str } };
+
+ alloc_type a2(2);
+ test_type v2(std::move(v1), a2);
+
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+
+ VERIFY( v1.begin()->second.empty() );
+ VERIFY( v2.begin()->second == str );
+}
+
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/allocator/move_cons.cc b/libstdc++-v3/testsuite/23_containers/multiset/allocator/move_cons.cc
new file mode 100644
index 0000000..bc7356b
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/allocator/move_cons.cc
@@ -0,0 +1,53 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <set>
+#include <string>
+
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using Cmp = std::less<std::string>;
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+ typedef uneq_allocator<std::string> alloc_type;
+ typedef std::multiset<std::string, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ const char* str = "A long enough string to require dynamic allocation";
+ v1 = { str };
+
+ alloc_type a2(2);
+ test_type v2(std::move(v1), a2);
+
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+
+ VERIFY( v1.count(str) == 0 );
+ VERIFY( v2.count(str) == 1 );
+}
+
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/allocator/move_cons.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/move_cons.cc
new file mode 100644
index 0000000..137d50d
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/allocator/move_cons.cc
@@ -0,0 +1,53 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <set>
+#include <string>
+
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using Cmp = std::less<std::string>;
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+ typedef uneq_allocator<std::string> alloc_type;
+ typedef std::set<std::string, Cmp, alloc_type> test_type;
+ test_type v1(alloc_type(1));
+ const char* str = "A long enough string to require dynamic allocation";
+ v1 = { str };
+
+ alloc_type a2(2);
+ test_type v2(std::move(v1), a2);
+
+ VERIFY(1 == v1.get_allocator().get_personality());
+ VERIFY(2 == v2.get_allocator().get_personality());
+
+ VERIFY( v1.count(str) == 0 );
+ VERIFY( v2.count(str) == 1 );
+}
+
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/24_iterators/associated_types/iterator.traits.cc b/libstdc++-v3/testsuite/24_iterators/associated_types/iterator.traits.cc
new file mode 100644
index 0000000..c3549fe
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/associated_types/iterator.traits.cc
@@ -0,0 +1,56 @@
+// Copyright (C) 2020 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 <iterator>
+
+struct bidi_iterator
+{
+ // No nested reference and pointer types.
+ // No iterator_category.
+
+ // cpp17-iterator requirements:
+ int& operator*() const;
+ bidi_iterator& operator++();
+ bidi_iterator operator++(int);
+
+ // cpp17-input-iterator requirements:
+ friend bool operator==(const bidi_iterator&, const bidi_iterator&);
+ using difference_type = long long;
+ using value_type = int;
+
+ // cpp17-forward-iterator requirements:
+ bidi_iterator();
+
+ // cpp17-bidirectional-iterator requirements:
+ bidi_iterator& operator--();
+ bidi_iterator operator--(int);
+};
+
+void
+test01()
+{
+ // PR libstdc++/97935
+ // Missing subsumption in iterator category detection
+ using namespace std;
+ static_assert(__detail::__cpp17_bidi_iterator<bidi_iterator>);
+ static_assert(same_as<iterator_traits<bidi_iterator>::iterator_category,
+ bidirectional_iterator_tag>,
+ "PR libstdc++/97935");
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/inplace_merge/1.cc b/libstdc++-v3/testsuite/25_algorithms/inplace_merge/1.cc
index 5859f03..bfdff77 100644
--- a/libstdc++-v3/testsuite/25_algorithms/inplace_merge/1.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/inplace_merge/1.cc
@@ -28,7 +28,7 @@ using std::inplace_merge;
typedef test_container<int, bidirectional_iterator_wrapper> container;
-void
+void
test1()
{
int array[] = { 1 };
@@ -39,7 +39,7 @@ test1()
inplace_merge(con2.begin(), con2.begin(), con2.end());
}
-void
+void
test2()
{
int array[] = { 0, 2, 4, 1, 3, 5 };
@@ -86,6 +86,36 @@ test3()
VERIFY( s[0].b == 0 && s[1].b == 4 && s[2].b == 1 && s[3].b == 5 );
}
+void
+test4()
+{
+ S s[8];
+ for (int pivot_idx = 0; pivot_idx < 8; ++pivot_idx)
+ {
+ int bval = 0;
+ for (int i = 0; i != pivot_idx; ++i)
+ {
+ s[i].a = i;
+ s[i].b = bval++;
+ }
+
+ for (int i = pivot_idx; i != 8; ++i)
+ {
+ s[i].a = i - pivot_idx;
+ s[i].b = bval++;
+ }
+
+ inplace_merge(s, s + pivot_idx, s + 8);
+
+ for (int i = 1; i < 8; ++i)
+ {
+ VERIFY( !(s[i] < s[i - 1]) );
+ if (s[i - 1].a == s[i].a)
+ VERIFY( s[i - 1].b < s[i].b );
+ }
+ }
+}
+
int
main()
{
@@ -95,12 +125,15 @@ main()
__gnu_test::set_new_limit(sizeof(S) * 4);
test3();
+ test4();
__gnu_test::set_new_limit(sizeof(S));
test3();
+ test4();
__gnu_test::set_new_limit(0);
test3();
+ test4();
return 0;
}
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_merge/inplace_merge.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_merge/inplace_merge.cc
index a20bdf9..74af960 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_merge/inplace_merge.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_merge/inplace_merge.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- inplace_merge.pass.cpp --------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_merge/merge.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_merge/merge.cc
index 3d450b9..d6dea08 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_merge/merge.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_merge/merge.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- merge.pass.cpp ----------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_if.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_if.cc
index fa4104a..ac5d643 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_if.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_if.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- copy_if.pass.cpp --------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_move.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_move.cc
index f711b90..8adca5b 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_move.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_move.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- copy_move.pass.cpp ------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/fill.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/fill.cc
index fd29a61..4e67d87 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/fill.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/fill.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- fill.pass.cpp -----------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/generate.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/generate.cc
index ebd922d..d732b5b 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/generate.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/generate.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- generate.pass.cpp -------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/is_partitioned.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/is_partitioned.cc
index 86c0341..055ec38 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/is_partitioned.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/is_partitioned.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- is_partitioned.pass.cpp -------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/partition.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/partition.cc
index beff2b9..dbda3d8 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/partition.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/partition.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- partition.pass.cpp ------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/partition_copy.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/partition_copy.cc
index b10fa64..0f0606d 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/partition_copy.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/partition_copy.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- partition_copy.pass.cpp -------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/remove.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/remove.cc
index c99e40c..3411a2d0 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/remove.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/remove.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- remove.pass.cpp ---------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/remove_copy.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/remove_copy.cc
index c5883c6..fc5aca4 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/remove_copy.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/remove_copy.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- remove_copy.pass.cpp ----------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/replace.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/replace.cc
index 4d68591..18e990b 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/replace.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/replace.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- replace.pass.cpp --------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/replace_copy.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/replace_copy.cc
index b36ce9a..7f7cfe1 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/replace_copy.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/replace_copy.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- replace_copy.pass.cpp ---------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate.cc
index 228293f..37fda26 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- rotate.pass.cpp ---------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate_copy.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate_copy.cc
index 802b7cb..b3275ea 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate_copy.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate_copy.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- rotate_copy.pass.cpp ----------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/swap_ranges.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/swap_ranges.cc
index 3a19f36..a6d4fa4 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/swap_ranges.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/swap_ranges.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- swap_ranges.pass.cpp ----------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_binary.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_binary.cc
index 37b2d12..518647a 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_binary.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_binary.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- transform_binary.pass.cpp -----------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_unary.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_unary.cc
index 2224c0a..ffb5a5c 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_unary.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_unary.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- transform_unary.pass.cpp ------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/unique.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/unique.cc
index 0c35179..c7a6458 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/unique.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/unique.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- unique.pass.cpp ---------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/unique_copy_equal.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/unique_copy_equal.cc
index 2bbd104..6102a32 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/unique_copy_equal.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/unique_copy_equal.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- unique_copy_equal.pass.cpp ----------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/adjacent_find.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/adjacent_find.cc
index 1ec6690..5cb8302 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/adjacent_find.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/adjacent_find.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- adjacent_find.pass.cpp --------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/all_of.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/all_of.cc
index c9cd76c..b7e7fd9 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/all_of.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/all_of.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- all_of.pass.cpp ---------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/any_of.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/any_of.cc
index dba6641..31585c6 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/any_of.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/any_of.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- any_of.pass.cpp ---------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/count.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/count.cc
index 6f39168..42e57f4 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/count.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/count.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- count.pass.cpp ----------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/equal.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/equal.cc
index e4dece2..fb8b302 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/equal.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/equal.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- equal.pass.cpp ----------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find.cc
index 1aad79f..7bf6980 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- find.pass.cpp -----------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_end.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_end.cc
index 0959b96..08daa10 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_end.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_end.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- find_end.pass.cpp -------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_first_of.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_first_of.cc
index e0b1344..59e37ca 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_first_of.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_first_of.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- find_first_of.pass.cpp --------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_if.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_if.cc
index b4ecdb0..39cc135 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_if.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_if.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- find_if.pass.cpp --------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/for_each.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/for_each.cc
index dc9e146..fc4ab3a 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/for_each.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/for_each.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- for_each.pass.cpp -------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/mismatch.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/mismatch.cc
index 50a6120..f792b51 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/mismatch.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/mismatch.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- mismatch.pass.cpp -------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/none_of.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/none_of.cc
index 9d34da8..2883385e 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/none_of.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/none_of.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- none_of.pass.cpp --------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/nth_element.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/nth_element.cc
index 54fd817..65b192f 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/nth_element.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/nth_element.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- nth_element.pass.cpp ----------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse.cc
index ec41df3..dd4de34 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- reverse.pass.cpp --------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse_copy.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse_copy.cc
index efd16a9..2563cef 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse_copy.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse_copy.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- reverse_copy.pass.cpp ---------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/search_n.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/search_n.cc
index f587bba..0720c37 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/search_n.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/search_n.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- search_n.pass.cpp -------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/includes.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/includes.cc
index 2e7dc8f..0a61e4f 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/includes.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/includes.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- includes.pass.cpp -------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/is_heap.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/is_heap.cc
index 76c1081..d9d7771 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/is_heap.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/is_heap.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- is_heap.pass.cpp --------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/is_sorted.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/is_sorted.cc
index 11fa230..daa1601 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/is_sorted.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/is_sorted.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- is_sorted.pass.cpp ------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/lexicographical_compare.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/lexicographical_compare.cc
index 5fce08b..fd758ba 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/lexicographical_compare.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/lexicographical_compare.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- lexicographical_compare.pass.cpp ----------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/minmax_element.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/minmax_element.cc
index e194a1d..52306ec 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/minmax_element.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/minmax_element.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- minmax_element.pass.cpp -------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/partial_sort.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/partial_sort.cc
index e99f593..63f2a1c 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/partial_sort.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/partial_sort.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- partial_sort.pass.cpp ---------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/partial_sort_copy.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/partial_sort_copy.cc
index fde44d5..e4da0b3 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/partial_sort_copy.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/partial_sort_copy.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- partial_sort_copy.pass.cpp ----------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/set.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/set.cc
index 4b9e7aa..286a528 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/set.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/set.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- set.pass.cpp ------------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/sort.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/sort.cc
index e0c55df..f5cb00e 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/sort.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/sort.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- sort.pass.cpp -----------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/25_algorithms/search_n/97828.cc b/libstdc++-v3/testsuite/25_algorithms/search_n/97828.cc
new file mode 100644
index 0000000..f692369
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/search_n/97828.cc
@@ -0,0 +1,58 @@
+// Copyright (C) 2020 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 } }
+
+// PR libstdc++/97828
+
+#include <algorithm>
+#include <testsuite_hooks.h>
+#include <testsuite_iterators.h>
+
+using __gnu_test::test_sized_range;
+using __gnu_test::forward_iterator_wrapper;
+using __gnu_test::random_access_iterator_wrapper;
+
+template<template<typename> typename Wrapper>
+void
+test01()
+{
+ int x[] = {0,42,42,0,42,42,42};
+ test_sized_range<int, Wrapper> rx(x);
+ auto res = std::ranges::search_n(rx, 3, 42);
+ VERIFY( res.begin().ptr == x+4 && res.end().ptr == x+7 );
+}
+
+template<template<typename> typename Wrapper>
+void
+test02()
+{
+ int x[] = {0,42,42,0,42};
+ test_sized_range<int, Wrapper> rx(x);
+ auto res = std::ranges::search_n(rx, 3, 42);
+ VERIFY( res.begin().ptr == x+5 && res.end().ptr == x+5 );
+}
+
+int
+main()
+{
+ test01<forward_iterator_wrapper>();
+ test01<random_access_iterator_wrapper>();
+ test02<forward_iterator_wrapper>();
+ test02<random_access_iterator_wrapper>();
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.cast/bit_cast.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.cast/bit_cast.cc
new file mode 100644
index 0000000..138ceb1
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.cast/bit_cast.cc
@@ -0,0 +1,81 @@
+// Copyright (C) 2020 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_bit_cast
+# error "Feature-test macro for bit_cast missing in <bit>"
+#elif __cpp_lib_bit_cast != 201806L
+# error "Feature-test macro for bit_cast has wrong value in <bit>"
+#endif
+
+#include <cstdint>
+#include <cstring>
+#include <testsuite_hooks.h>
+
+template<typename To, typename From>
+constexpr bool
+check(const From& from)
+{
+ return std::bit_cast<From>(std::bit_cast<To>(from)) == from;
+}
+
+void
+test01()
+{
+ static_assert( std::bit_cast<int>(123) == 123 );
+ static_assert( std::bit_cast<int>(123u) == 123 );
+ static_assert( std::bit_cast<int>(~0u) == ~0 );
+
+ if constexpr (sizeof(int) == sizeof(float))
+ static_assert( check<int>(12.34f) );
+ if constexpr (sizeof(unsigned long long) == sizeof(double))
+ static_assert( check<unsigned long long>(123.456) );
+ if constexpr (sizeof(std::intptr_t) == sizeof(void(*)()))
+ VERIFY( check<std::intptr_t>(&test01) );
+}
+
+void
+test02()
+{
+ struct S
+ {
+ int i;
+
+ bool operator==(const char* s) const
+ { return std::memcmp(&i, s, sizeof(i)) == 0; }
+ };
+
+ char arr[sizeof(int)];
+ char arr2[sizeof(int)];
+ for (int i = 0; i < sizeof(int); ++i)
+ {
+ arr[i] = i + 1;
+ arr2[i] = (i + 1) * -(i % 2);
+ }
+ VERIFY( std::bit_cast<S>(arr) == arr );
+ VERIFY( std::bit_cast<S>(arr2) == arr2 );
+}
+
+int main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.cast/version.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.cast/version.cc
new file mode 100644
index 0000000..82e9754
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.cast/version.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2020 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_bit_cast
+# error "Feature-test macro for bit_cast missing in <version>"
+#elif __cpp_lib_bit_cast != 201806L
+# error "Feature-test macro for bit_cast has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/adjacent_difference.cc b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/adjacent_difference.cc
index 14246d8..26dc280 100644
--- a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/adjacent_difference.cc
+++ b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/adjacent_difference.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- adjacent_difference.pass.cpp --------------------------------------===//
diff --git a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/reduce.cc b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/reduce.cc
index 266af3a..b31cdcc 100644
--- a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/reduce.cc
+++ b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/reduce.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- reduce.pass.cpp ---------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/scan.cc b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/scan.cc
index c47eb23..41b92cb 100644
--- a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/scan.cc
+++ b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/scan.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- scan.pass.cpp -----------------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/transform_reduce.cc b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/transform_reduce.cc
index 41c6457..a083d9c 100644
--- a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/transform_reduce.cc
+++ b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/transform_reduce.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- transform_reduce.pass.cpp -----------------------------------------===//
diff --git a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/transform_scan.cc b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/transform_scan.cc
index eb2694e..babe84e 100644
--- a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/transform_scan.cc
+++ b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/transform_scan.cc
@@ -1,6 +1,7 @@
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
+// { dg-timeout-factor 3 }
// { dg-require-effective-target tbb-backend }
//===-- transform_scan.pass.cpp -------------------------------------------===//
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/get/char/lwg3464.cc b/libstdc++-v3/testsuite/27_io/basic_istream/get/char/lwg3464.cc
index 6123ca5..85d7fc0 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istream/get/char/lwg3464.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/get/char/lwg3464.cc
@@ -16,6 +16,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do run { target { ! lp64 } } }
+// { dg-timeout-factor 2 }
#include <istream>
#include <streambuf>
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/get/wchar_t/lwg3464.cc b/libstdc++-v3/testsuite/27_io/basic_istream/get/wchar_t/lwg3464.cc
index 6df244c..1d8411c 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istream/get/wchar_t/lwg3464.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/get/wchar_t/lwg3464.cc
@@ -16,6 +16,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do run { target { ! lp64 } } }
+// { dg-timeout-factor 2 }
#include <istream>
#include <streambuf>
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/94749.cc b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/94749.cc
index 21097c2..63b652d 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/94749.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/94749.cc
@@ -17,6 +17,7 @@
// { dg-do run }
// { dg-options "-DSIMULATOR_TEST" { target simulator } }
+// { dg-timeout-factor 2 { target ilp32 } }
// PR libstdc++/94749
// basic_istream::ignore(n, c) discards n+1 if next character is equal to c.
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/ignore/wchar_t/94749.cc b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/wchar_t/94749.cc
index 2473588..dcf0fee 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istream/ignore/wchar_t/94749.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/wchar_t/94749.cc
@@ -17,6 +17,7 @@
// { dg-do run }
// { dg-options "-DSIMULATOR_TEST" { target simulator } }
+// { dg-timeout-factor 2 { target ilp32 } }
// PR libstdc++/94749
// basic_istream::ignore(n, c) discards n+1 if next character is equal to c.
diff --git a/libstdc++-v3/testsuite/27_io/basic_istringstream/str/char/2.cc b/libstdc++-v3/testsuite/27_io/basic_istringstream/str/char/2.cc
new file mode 100644
index 0000000..58ee1d2
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_istringstream/str/char/2.cc
@@ -0,0 +1,94 @@
+// Copyright (C) 2020 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/>.
+
+// 29.8.3.4 basic_istringstream member functions [istringstream.members]
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target cxx11-abi }
+
+#include <sstream>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+void test01()
+{
+ const std::string s0 = "this is not a short string";
+ std::istringstream ss;
+ ss.str(s0);
+ VERIFY( ss.str() == s0 );
+ VERIFY( ss.str() == s0 );
+
+ using Alloc = __gnu_test::uneq_allocator<char>;
+ const Alloc a1(1);
+ std::basic_string<char, std::char_traits<char>, Alloc> s1 = ss.str(a1);
+ VERIFY( s1.get_allocator() == a1 );
+ VERIFY( ss.str(a1).get_allocator() == a1 );
+ VERIFY( ss.str(a1) == s1 );
+ VERIFY( std::move(ss).str(a1) == s1 );
+ VERIFY( std::move(ss).str(a1) == s1 );
+
+ const Alloc a2(2);
+ VERIFY( ss.str(a2).get_allocator() == a2 );
+ VERIFY( ss.str(a2) == s1 );
+
+ VERIFY( std::move(ss).str() == s0 );
+ VERIFY( std::move(ss).str().empty() );
+ VERIFY( ss.str().empty() );
+ VERIFY( ss.str(a1).empty() );
+}
+
+void test02()
+{
+ std::istringstream ss("123");
+ std::string str = "ABCDEF";
+ ss.str(str);
+ VERIFY( ss.str() == str );
+ VERIFY( std::move(ss).str() == str );
+ VERIFY( std::move(ss).str().empty() );
+}
+
+void test03()
+{
+ std::istringstream ss;
+ using Alloc = __gnu_test::tracker_allocator<char>;
+ using Str = std::basic_string<char, std::char_traits<char>, Alloc>;
+ Str s1 = "string that is not short, quite long even";
+ auto count1 = __gnu_test::tracker_allocator_counter::get_allocation_count();
+ ss.str(s1);
+ auto count2 = __gnu_test::tracker_allocator_counter::get_allocation_count();
+ VERIFY( count1 == count2 );
+ VERIFY( ss.str() == s1.c_str() );
+}
+
+void test04()
+{
+ std::istringstream ss;
+ const std::string str = "Another quite long string, not at all short";
+ std::string str2 = str;
+ ss.str(std::move(str2));
+ VERIFY( str2.empty() );
+ VERIFY( ss.str() == str );
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_istringstream/str/wchar_t/2.cc b/libstdc++-v3/testsuite/27_io/basic_istringstream/str/wchar_t/2.cc
new file mode 100644
index 0000000..5958527
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_istringstream/str/wchar_t/2.cc
@@ -0,0 +1,94 @@
+// Copyright (C) 2020 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/>.
+
+// 29.8.3.4 basic_istringstream member functions [istringstream.members]
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target cxx11-abi }
+
+#include <sstream>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+void test01()
+{
+ const std::wstring s0 = L"this is not a short string";
+ std::wistringstream ss;
+ ss.str(s0);
+ VERIFY( ss.str() == s0 );
+ VERIFY( ss.str() == s0 );
+
+ using Alloc = __gnu_test::uneq_allocator<wchar_t>;
+ const Alloc a1(1);
+ std::basic_string<wchar_t, std::char_traits<wchar_t>, Alloc> s1 = ss.str(a1);
+ VERIFY( s1.get_allocator() == a1 );
+ VERIFY( ss.str(a1).get_allocator() == a1 );
+ VERIFY( ss.str(a1) == s1 );
+ VERIFY( std::move(ss).str(a1) == s1 );
+ VERIFY( std::move(ss).str(a1) == s1 );
+
+ const Alloc a2(2);
+ VERIFY( ss.str(a2).get_allocator() == a2 );
+ VERIFY( ss.str(a2) == s1 );
+
+ VERIFY( std::move(ss).str() == s0 );
+ VERIFY( std::move(ss).str().empty() );
+ VERIFY( ss.str().empty() );
+ VERIFY( ss.str(a1).empty() );
+}
+
+void test02()
+{
+ std::wistringstream ss(L"123");
+ std::wstring str = L"ABCDEF";
+ ss.str(str);
+ VERIFY( ss.str() == str );
+ VERIFY( std::move(ss).str() == str );
+ VERIFY( std::move(ss).str().empty() );
+}
+
+void test03()
+{
+ std::wistringstream ss;
+ using Alloc = __gnu_test::tracker_allocator<wchar_t>;
+ using Str = std::basic_string<wchar_t, std::char_traits<wchar_t>, Alloc>;
+ Str s1 = L"string that is not short, quite long even";
+ auto count1 = __gnu_test::tracker_allocator_counter::get_allocation_count();
+ ss.str(s1);
+ auto count2 = __gnu_test::tracker_allocator_counter::get_allocation_count();
+ VERIFY( count1 == count2 );
+ VERIFY( ss.str() == s1.c_str() );
+}
+
+void test04()
+{
+ std::wistringstream ss;
+ const std::wstring str = L"Another quite long string, not at all short";
+ std::wstring str2 = str;
+ ss.str(std::move(str2));
+ VERIFY( str2.empty() );
+ VERIFY( ss.str() == str );
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_istringstream/view/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_istringstream/view/char/1.cc
index 091de5f..c455070 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istringstream/view/char/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istringstream/view/char/1.cc
@@ -15,7 +15,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 27.7.1.1 basic_stringbuf constructors [lib.stringbuf.cons]
+// 29.8.3.4 basic_istringstream member functions [istringstream.members]
// { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } }
@@ -31,5 +31,17 @@ main()
std::string s("This is a test");
std::istringstream stm(s);
VERIFY( stm.view() == s );
- return 0;
+ VERIFY( stm.view() == const_cast<const std::istringstream&>(stm).view() );
+
+ s = "This is another test with a longer string";
+ stm.str(s);
+ VERIFY( stm.view() == s );
+
+ s = "This is a shorter string";
+ stm.str(s);
+ VERIFY( stm.view() == s );
+
+ std::string s2;
+ stm >> s2;
+ VERIFY( stm.view() == s );
}
diff --git a/libstdc++-v3/testsuite/27_io/basic_istringstream/view/wchar_t/1.cc b/libstdc++-v3/testsuite/27_io/basic_istringstream/view/wchar_t/1.cc
index f659964..8efba06 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istringstream/view/wchar_t/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istringstream/view/wchar_t/1.cc
@@ -31,5 +31,17 @@ main()
std::wstring s(L"This is a test");
std::wistringstream stm(s);
VERIFY( stm.view() == s );
- return 0;
+ VERIFY( stm.view() == const_cast<const std::wistringstream&>(stm).view() );
+
+ s = L"This is another test with a longer string";
+ stm.str(s);
+ VERIFY( stm.view() == s );
+
+ s = L"This is a shorter string";
+ stm.str(s);
+ VERIFY( stm.view() == s );
+
+ std::wstring s2;
+ stm >> s2;
+ VERIFY( stm.view() == s );
}
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/emit/1.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/emit/1.cc
new file mode 100644
index 0000000..c50648a
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/emit/1.cc
@@ -0,0 +1,44 @@
+// Copyright (C) 2020 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-additional-options "-pthread" { target pthread } }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target cxx11-abi }
+
+#include <syncstream>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ std::stringbuf sb;
+ std::osyncstream s(&sb);
+ s << "abc" << std::emit_on_flush << "def" << std::flush << "ghi"
+ << std::emit_on_flush << std::noemit_on_flush << std::endl;
+ VERIFY( sb.view() == "abcdef" );
+ s << "jkl" << std::flush_emit << "mno" << std::flush;
+ VERIFY( sb.view() == "abcdefghi\njkl" );
+ s.emit();
+ VERIFY( sb.view() == "abcdefghi\njklmno" );
+}
+
+int
+main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostringstream/str/char/3.cc b/libstdc++-v3/testsuite/27_io/basic_ostringstream/str/char/3.cc
new file mode 100644
index 0000000..23e961e
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_ostringstream/str/char/3.cc
@@ -0,0 +1,94 @@
+// Copyright (C) 2020 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/>.
+
+// 29.8.4.4 basic_ostringstream member functions [ostringstream.members]
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target cxx11-abi }
+
+#include <sstream>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+void test01()
+{
+ const std::string s0 = "this is not a short string";
+ std::ostringstream ss;
+ ss.str(s0);
+ VERIFY( ss.str() == s0 );
+ VERIFY( ss.str() == s0 );
+
+ using Alloc = __gnu_test::uneq_allocator<char>;
+ const Alloc a1(1);
+ std::basic_string<char, std::char_traits<char>, Alloc> s1 = ss.str(a1);
+ VERIFY( s1.get_allocator() == a1 );
+ VERIFY( ss.str(a1).get_allocator() == a1 );
+ VERIFY( ss.str(a1) == s1 );
+ VERIFY( std::move(ss).str(a1) == s1 );
+ VERIFY( std::move(ss).str(a1) == s1 );
+
+ const Alloc a2(2);
+ VERIFY( ss.str(a2).get_allocator() == a2 );
+ VERIFY( ss.str(a2) == s1 );
+
+ VERIFY( std::move(ss).str() == s0 );
+ VERIFY( std::move(ss).str().empty() );
+ VERIFY( ss.str().empty() );
+ VERIFY( ss.str(a1).empty() );
+}
+
+void test02()
+{
+ std::ostringstream ss("123");
+ std::string str = "ABCDEF";
+ ss << str;
+ VERIFY( ss.str() == str );
+ VERIFY( std::move(ss).str() == str );
+ VERIFY( std::move(ss).str().empty() );
+}
+
+void test03()
+{
+ std::ostringstream ss;
+ using Alloc = __gnu_test::tracker_allocator<char>;
+ using Str = std::basic_string<char, std::char_traits<char>, Alloc>;
+ Str s1 = "string that is not short, quite long even";
+ auto count1 = __gnu_test::tracker_allocator_counter::get_allocation_count();
+ ss.str(s1);
+ auto count2 = __gnu_test::tracker_allocator_counter::get_allocation_count();
+ VERIFY( count1 == count2 );
+ VERIFY( ss.str() == s1.c_str() );
+}
+
+void test04()
+{
+ std::ostringstream ss;
+ const std::string str = "Another quite long string, not at all short";
+ std::string str2 = str;
+ ss.str(std::move(str2));
+ VERIFY( str2.empty() );
+ VERIFY( ss.str() == str );
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostringstream/str/wchar_t/3.cc b/libstdc++-v3/testsuite/27_io/basic_ostringstream/str/wchar_t/3.cc
new file mode 100644
index 0000000..7c354cb
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_ostringstream/str/wchar_t/3.cc
@@ -0,0 +1,94 @@
+// Copyright (C) 2020 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/>.
+
+// 29.8.4.4 basic_ostringstream member functions [ostringstream.members]
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target cxx11-abi }
+
+#include <sstream>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+void test01()
+{
+ const std::wstring s0 = L"this is not a short string";
+ std::wostringstream ss;
+ ss.str(s0);
+ VERIFY( ss.str() == s0 );
+ VERIFY( ss.str() == s0 );
+
+ using Alloc = __gnu_test::uneq_allocator<wchar_t>;
+ const Alloc a1(1);
+ std::basic_string<wchar_t, std::char_traits<wchar_t>, Alloc> s1 = ss.str(a1);
+ VERIFY( s1.get_allocator() == a1 );
+ VERIFY( ss.str(a1).get_allocator() == a1 );
+ VERIFY( ss.str(a1) == s1 );
+ VERIFY( std::move(ss).str(a1) == s1 );
+ VERIFY( std::move(ss).str(a1) == s1 );
+
+ const Alloc a2(2);
+ VERIFY( ss.str(a2).get_allocator() == a2 );
+ VERIFY( ss.str(a2) == s1 );
+
+ VERIFY( std::move(ss).str() == s0 );
+ VERIFY( std::move(ss).str().empty() );
+ VERIFY( ss.str().empty() );
+ VERIFY( ss.str(a1).empty() );
+}
+
+void test02()
+{
+ std::wostringstream ss(L"123");
+ std::wstring str = L"ABCDEF";
+ ss << str;
+ VERIFY( ss.str() == str );
+ VERIFY( std::move(ss).str() == str );
+ VERIFY( std::move(ss).str().empty() );
+}
+
+void test03()
+{
+ std::wostringstream ss;
+ using Alloc = __gnu_test::tracker_allocator<wchar_t>;
+ using Str = std::basic_string<wchar_t, std::char_traits<wchar_t>, Alloc>;
+ Str s1 = L"string that is not short, quite long even";
+ auto count1 = __gnu_test::tracker_allocator_counter::get_allocation_count();
+ ss.str(s1);
+ auto count2 = __gnu_test::tracker_allocator_counter::get_allocation_count();
+ VERIFY( count1 == count2 );
+ VERIFY( ss.str() == s1.c_str() );
+}
+
+void test04()
+{
+ std::wostringstream ss;
+ const std::wstring str = L"Another quite long string, not at all short";
+ std::wstring str2 = str;
+ ss.str(std::move(str2));
+ VERIFY( str2.empty() );
+ VERIFY( ss.str() == str );
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostringstream/view/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_ostringstream/view/char/1.cc
index a366363..f072c16 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ostringstream/view/char/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ostringstream/view/char/1.cc
@@ -15,7 +15,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 27.7.1.1 basic_stringbuf constructors [lib.stringbuf.cons]
+// 29.8.4.4 basic_ostringstream member functions [ostringstream.members]
// { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } }
@@ -31,5 +31,13 @@ main()
std::string s("This is a test");
std::ostringstream stm(s);
VERIFY( stm.view() == s );
- return 0;
+ VERIFY( stm.view() == const_cast<const std::ostringstream&>(stm).view() );
+
+ s += " with a longer string";
+ stm << s;
+ VERIFY( stm.view() == s );
+
+ s = "This is a shorter string";
+ stm.str(s);
+ VERIFY( stm.view() == s );
}
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostringstream/view/wchar_t/1.cc b/libstdc++-v3/testsuite/27_io/basic_ostringstream/view/wchar_t/1.cc
index 1ebf7c5..3fa2604 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ostringstream/view/wchar_t/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ostringstream/view/wchar_t/1.cc
@@ -15,7 +15,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 27.7.1.1 basic_stringbuf constructors [lib.stringbuf.cons]
+// 29.8.4.4 basic_ostringstream member functions [ostringstream.members]
// { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } }
@@ -31,5 +31,13 @@ main()
std::wstring s(L"This is a test");
std::wostringstream stm(s);
VERIFY( stm.view() == s );
- return 0;
+ VERIFY( stm.view() == const_cast<const std::wostringstream&>(stm).view() );
+
+ s += L" with a longer string";
+ stm << s;
+ VERIFY( stm.view() == s );
+
+ s = L"This is a shorter string";
+ stm.str(s);
+ VERIFY( stm.view() == s );
}
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/char/4.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/char/4.cc
new file mode 100644
index 0000000..3a4b0c7
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/char/4.cc
@@ -0,0 +1,94 @@
+// Copyright (C) 2020 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/>.
+
+// 29.8.2.4 basic_stringbuf member functions [stringbuf.members]
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target cxx11-abi }
+
+#include <sstream>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+void test01()
+{
+ const std::string s0 = "this is not a short string";
+ std::stringbuf sb;
+ sb.str(s0);
+ VERIFY( sb.str() == s0 );
+ VERIFY( sb.str() == s0 );
+
+ using Alloc = __gnu_test::uneq_allocator<char>;
+ const Alloc a1(1);
+ std::basic_string<char, std::char_traits<char>, Alloc> s1 = sb.str(a1);
+ VERIFY( s1.get_allocator() == a1 );
+ VERIFY( sb.str(a1).get_allocator() == a1 );
+ VERIFY( sb.str(a1) == s1 );
+ VERIFY( std::move(sb).str(a1) == s1 );
+ VERIFY( std::move(sb).str(a1) == s1 );
+
+ const Alloc a2(2);
+ VERIFY( sb.str(a2).get_allocator() == a2 );
+ VERIFY( sb.str(a2) == s1 );
+
+ VERIFY( std::move(sb).str() == s0 );
+ VERIFY( std::move(sb).str().empty() );
+ VERIFY( sb.str().empty() );
+ VERIFY( sb.str(a1).empty() );
+}
+
+void test02()
+{
+ std::stringbuf sb("123");
+ std::string str = "ABCDEF";
+ sb.sputn(str.c_str(), str.size());
+ VERIFY( sb.str() == str );
+ VERIFY( std::move(sb).str() == str );
+ VERIFY( std::move(sb).str().empty() );
+}
+
+void test03()
+{
+ std::stringbuf sb;
+ using Alloc = __gnu_test::tracker_allocator<char>;
+ using Str = std::basic_string<char, std::char_traits<char>, Alloc>;
+ Str s1("string that is not short, quite long even");
+ auto count1 = __gnu_test::tracker_allocator_counter::get_allocation_count();
+ sb.str(s1);
+ auto count2 = __gnu_test::tracker_allocator_counter::get_allocation_count();
+ VERIFY( count1 == count2 );
+ VERIFY( sb.str() == s1.c_str() );
+}
+
+void test04()
+{
+ std::stringbuf sb;
+ const std::string str = "Another quite long string, not at all short";
+ std::string str2 = str;
+ sb.str(std::move(str2));
+ VERIFY( str2.empty() );
+ VERIFY( sb.str() == str );
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/wchar_t/4.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/wchar_t/4.cc
new file mode 100644
index 0000000..5d5187f
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/wchar_t/4.cc
@@ -0,0 +1,94 @@
+// Copyright (C) 2020 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/>.
+
+// 29.8.2.4 basic_stringbuf member functions [stringbuf.members]
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target cxx11-abi }
+
+#include <sstream>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+void test01()
+{
+ const std::wstring s0 = L"this is not a short string";
+ std::wstringbuf sb;
+ sb.str(s0);
+ VERIFY( sb.str() == s0 );
+ VERIFY( sb.str() == s0 );
+
+ using Alloc = __gnu_test::uneq_allocator<wchar_t>;
+ const Alloc a1(1);
+ std::basic_string<wchar_t, std::char_traits<wchar_t>, Alloc> s1 = sb.str(a1);
+ VERIFY( s1.get_allocator() == a1 );
+ VERIFY( sb.str(a1).get_allocator() == a1 );
+ VERIFY( sb.str(a1) == s1 );
+ VERIFY( std::move(sb).str(a1) == s1 );
+ VERIFY( std::move(sb).str(a1) == s1 );
+
+ const Alloc a2(2);
+ VERIFY( sb.str(a2).get_allocator() == a2 );
+ VERIFY( sb.str(a2) == s1 );
+
+ VERIFY( std::move(sb).str() == s0 );
+ VERIFY( std::move(sb).str().empty() );
+ VERIFY( sb.str().empty() );
+ VERIFY( sb.str(a1).empty() );
+}
+
+void test02()
+{
+ std::wstringbuf sb(L"123");
+ std::wstring str = L"ABCDEF";
+ sb.sputn(str.c_str(), str.size());
+ VERIFY( sb.str() == str );
+ VERIFY( std::move(sb).str() == str );
+ VERIFY( std::move(sb).str().empty() );
+}
+
+void test03()
+{
+ std::wstringbuf sb;
+ using Alloc = __gnu_test::tracker_allocator<wchar_t>;
+ using Str = std::basic_string<wchar_t, std::char_traits<wchar_t>, Alloc>;
+ Str s1 = L"string that is not short, quite long even";
+ auto count1 = __gnu_test::tracker_allocator_counter::get_allocation_count();
+ sb.str(s1);
+ auto count2 = __gnu_test::tracker_allocator_counter::get_allocation_count();
+ VERIFY( count1 == count2 );
+ VERIFY( sb.str() == s1.c_str() );
+}
+
+void test04()
+{
+ std::wstringbuf sb;
+ const std::wstring str = L"Another quite long string, not at all short";
+ std::wstring str2 = str;
+ sb.str(std::move(str2));
+ VERIFY( str2.empty() );
+ VERIFY( sb.str() == str );
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringstream/str/char/5.cc b/libstdc++-v3/testsuite/27_io/basic_stringstream/str/char/5.cc
new file mode 100644
index 0000000..917bd21
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_stringstream/str/char/5.cc
@@ -0,0 +1,94 @@
+// Copyright (C) 2020 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/>.
+
+// 29.8.5.4 basic_stringstream member functions [stringstream.members]
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target cxx11-abi }
+
+#include <sstream>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+void test01()
+{
+ const std::string s0 = "this is not a short string";
+ std::stringstream ss;
+ ss.str(s0);
+ VERIFY( ss.str() == s0 );
+ VERIFY( ss.str() == s0 );
+
+ using Alloc = __gnu_test::uneq_allocator<char>;
+ const Alloc a1(1);
+ std::basic_string<char, std::char_traits<char>, Alloc> s1 = ss.str(a1);
+ VERIFY( s1.get_allocator() == a1 );
+ VERIFY( ss.str(a1).get_allocator() == a1 );
+ VERIFY( ss.str(a1) == s1 );
+ VERIFY( std::move(ss).str(a1) == s1 );
+ VERIFY( std::move(ss).str(a1) == s1 );
+
+ const Alloc a2(2);
+ VERIFY( ss.str(a2).get_allocator() == a2 );
+ VERIFY( ss.str(a2) == s1 );
+
+ VERIFY( std::move(ss).str() == s0 );
+ VERIFY( std::move(ss).str().empty() );
+ VERIFY( ss.str().empty() );
+ VERIFY( ss.str(a1).empty() );
+}
+
+void test02()
+{
+ std::stringstream ss("123");
+ std::string str = "ABCDEF";
+ ss << str;
+ VERIFY( ss.str() == str );
+ VERIFY( std::move(ss).str() == str );
+ VERIFY( std::move(ss).str().empty() );
+}
+
+void test03()
+{
+ std::stringstream ss;
+ using Alloc = __gnu_test::tracker_allocator<char>;
+ using Str = std::basic_string<char, std::char_traits<char>, Alloc>;
+ Str s1 = "string that is not short, quite long even";
+ auto count1 = __gnu_test::tracker_allocator_counter::get_allocation_count();
+ ss.str(s1);
+ auto count2 = __gnu_test::tracker_allocator_counter::get_allocation_count();
+ VERIFY( count1 == count2 );
+ VERIFY( ss.str() == s1.c_str() );
+}
+
+void test04()
+{
+ std::stringstream ss;
+ const std::string str = "Another quite long string, not at all short";
+ std::string str2 = str;
+ ss.str(std::move(str2));
+ VERIFY( str2.empty() );
+ VERIFY( ss.str() == str );
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringstream/str/wchar_t/5.cc.cc b/libstdc++-v3/testsuite/27_io/basic_stringstream/str/wchar_t/5.cc.cc
new file mode 100644
index 0000000..3a2a26c
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_stringstream/str/wchar_t/5.cc.cc
@@ -0,0 +1,94 @@
+// Copyright (C) 2020 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/>.
+
+// 29.8.5.4 basic_stringstream member functions [stringstream.members]
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target cxx11-abi }
+
+#include <sstream>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+void test01()
+{
+ const std::wstring s0 = L"this is not a short string";
+ std::wstringstream ss;
+ ss.str(s0);
+ VERIFY( ss.str() == s0 );
+ VERIFY( ss.str() == s0 );
+
+ using Alloc = __gnu_test::uneq_allocator<wchar_t>;
+ const Alloc a1(1);
+ std::basic_string<wchar_t, std::char_traits<wchar_t>, Alloc> s1 = ss.str(a1);
+ VERIFY( s1.get_allocator() == a1 );
+ VERIFY( ss.str(a1).get_allocator() == a1 );
+ VERIFY( ss.str(a1) == s1 );
+ VERIFY( std::move(ss).str(a1) == s1 );
+ VERIFY( std::move(ss).str(a1) == s1 );
+
+ const Alloc a2(2);
+ VERIFY( ss.str(a2).get_allocator() == a2 );
+ VERIFY( ss.str(a2) == s1 );
+
+ VERIFY( std::move(ss).str() == s0 );
+ VERIFY( std::move(ss).str().empty() );
+ VERIFY( ss.str().empty() );
+ VERIFY( ss.str(a1).empty() );
+}
+
+void test02()
+{
+ std::wstringstream ss(L"123");
+ std::wstring str = L"ABCDEF";
+ ss << str;
+ VERIFY( ss.str() == str );
+ VERIFY( std::move(ss).str() == str );
+ VERIFY( std::move(ss).str().empty() );
+}
+
+void test03()
+{
+ std::wstringstream ss;
+ using Alloc = __gnu_test::tracker_allocator<wchar_t>;
+ using Str = std::basic_string<wchar_t, std::char_traits<wchar_t>, Alloc>;
+ Str s1 = L"string that is not short, quite long even";
+ auto count1 = __gnu_test::tracker_allocator_counter::get_allocation_count();
+ ss.str(s1);
+ auto count2 = __gnu_test::tracker_allocator_counter::get_allocation_count();
+ VERIFY( count1 == count2 );
+ VERIFY( ss.str() == s1.c_str() );
+}
+
+void test04()
+{
+ std::wstringstream ss;
+ const std::wstring str = L"Another quite long string, not at all short";
+ std::wstring str2 = str;
+ ss.str(std::move(str2));
+ VERIFY( str2.empty() );
+ VERIFY( ss.str() == str );
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringstream/view/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_stringstream/view/char/1.cc
index f47035c..942db75 100644
--- a/libstdc++-v3/testsuite/27_io/basic_stringstream/view/char/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_stringstream/view/char/1.cc
@@ -15,7 +15,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 27.7.1.1 basic_stringbuf constructors [lib.stringbuf.cons]
+// 29.8.5.4 basic_stringstream member functions [stringstream.members]
// { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } }
@@ -31,5 +31,17 @@ main()
std::string s("This is a test");
std::stringstream stm(s);
VERIFY( stm.view() == s );
- return 0;
+ VERIFY( stm.view() == const_cast<const std::stringstream&>(stm).view() );
+
+ s += " with a longer string";
+ stm << s;
+ VERIFY( stm.view() == s );
+
+ s = "This is a shorter string";
+ stm.str(s);
+ VERIFY( stm.view() == s );
+
+ std::string s2;
+ stm >> s2;
+ VERIFY( stm.view() == s );
}
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringstream/view/wchar_t/1.cc b/libstdc++-v3/testsuite/27_io/basic_stringstream/view/wchar_t/1.cc
index d707cfe..7c35299 100644
--- a/libstdc++-v3/testsuite/27_io/basic_stringstream/view/wchar_t/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_stringstream/view/wchar_t/1.cc
@@ -31,5 +31,17 @@ main()
std::wstring s(L"This is a test");
std::wstringstream stm(s);
VERIFY( stm.view() == s );
- return 0;
+ VERIFY( stm.view() == const_cast<const std::wstringstream&>(stm).view() );
+
+ s += L" with a longer string";
+ stm << s;
+ VERIFY( stm.view() == s );
+
+ s = L"This is a shorter string";
+ stm.str(s);
+ VERIFY( stm.view() == s );
+
+ std::wstring s2;
+ stm >> s2;
+ VERIFY( stm.view() == s );
}
diff --git a/libstdc++-v3/testsuite/27_io/basic_syncbuf/sync_ops/1.cc b/libstdc++-v3/testsuite/27_io/basic_syncbuf/sync_ops/1.cc
index 90d20f1..a224e0c 100644
--- a/libstdc++-v3/testsuite/27_io/basic_syncbuf/sync_ops/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_syncbuf/sync_ops/1.cc
@@ -15,11 +15,12 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// { dg-options "-std=gnu++2a -pthread" }
+// { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } }
-// { dg-require-effective-target pthread }
// { dg-require-effective-target cxx11-abi }
// { dg-require-gthreads "" }
+// { dg-add-options libatomic }
+// { dg-additional-options "-pthread" { target pthread } }
#include <algorithm>
#include <atomic>
diff --git a/libstdc++-v3/testsuite/27_io/basic_syncstream/basic_ops/1.cc b/libstdc++-v3/testsuite/27_io/basic_syncstream/basic_ops/1.cc
index ef46399..3ca97aa 100644
--- a/libstdc++-v3/testsuite/27_io/basic_syncstream/basic_ops/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_syncstream/basic_ops/1.cc
@@ -123,12 +123,41 @@ test04() // emitting
s.emit();
VERIFY( b.str() == txt );
}
+
+ {
+ std::stringbuf b;
+ std::osyncstream s(&b);
+
+ s.put('a');
+ s.put('b');
+ s.put('c');
+
+ s.emit();
+ VERIFY( b.str() == "abc" );
+ }
+
+ {
+ std::stringbuf b;
+ std::osyncstream s(&b);
+
+ s << "abc";
+ s.put(' ');
+ s << "def";
+ s.emit();
+ VERIFY( b.str() == "abc def" );
+
+ s << "ghi";
+ s.put(' ');
+ s << "jkl";
+ s.emit();
+ VERIFY( b.str() == "abc defghi jkl" );
+ }
}
+
int main()
{
test01();
test02();
test03();
test04();
- return 0;
}
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/absolute.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/absolute.cc
index 96ccd77..712d131 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/absolute.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/absolute.cc
@@ -30,7 +30,7 @@ using std::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
std::error_code ec;
path abs = absolute(p, ec);
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/append/source.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/append/source.cc
index dc73319..4468a24 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/append/source.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/append/source.cc
@@ -92,8 +92,8 @@ test02()
void
test03()
{
- for (const path& p : __gnu_test::test_paths)
- for (const path& q : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
+ for (const path q : __gnu_test::test_paths)
{
test(p, q.c_str());
if constexpr (!std::is_same_v<path::value_type, char>)
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/assign/copy.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/assign/copy.cc
index 0f912a5..c0fd2aa 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/assign/copy.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/assign/copy.cc
@@ -28,7 +28,7 @@ using __gnu_test::compare_paths;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path copy;
copy = p;
@@ -39,7 +39,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path copy = p;
path move;
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/compare/path.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/compare/path.cc
index 6f4166b..fd310fb 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/compare/path.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/compare/path.cc
@@ -30,7 +30,7 @@ void
test01()
{
const path p0 = "/a/a/b/b";
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.compare(p) == 0 );
int cmp = p.compare(p0);
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/construct/copy.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/construct/copy.cc
index 54b3510..a61c7c4 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/construct/copy.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/construct/copy.cc
@@ -28,7 +28,7 @@ using std::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path copy = p;
__gnu_test::compare_paths(p, copy);
@@ -38,7 +38,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path copy = p;
path move = std::move(copy);
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/extension.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/extension.cc
index 032af98..9498970 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/extension.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/extension.cc
@@ -51,7 +51,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
auto stem = p.stem();
auto ext = p.extension();
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/filename.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/filename.cc
index 52dc3899..2ab6014 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/filename.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/filename.cc
@@ -46,7 +46,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path f = p.filename();
if (p.empty())
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/parent_path.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/parent_path.cc
index cf37240..f198a4c 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/parent_path.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/parent_path.cc
@@ -46,7 +46,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
if (p.begin() == p.end())
continue;
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/relative_path.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/relative_path.cc
index 3d14829..d514951 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/relative_path.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/relative_path.cc
@@ -42,7 +42,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
bool after_root = false;
const path prel = p.relative_path();
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/root_directory.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/root_directory.cc
index b89dd47..6e24cc8 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/root_directory.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/root_directory.cc
@@ -46,7 +46,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path rootdir = p.root_directory();
VERIFY( !rootdir.has_relative_path() );
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/root_path.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/root_path.cc
index 10ed314..aa0516f 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/root_path.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/root_path.cc
@@ -38,7 +38,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path rootp = p.root_path();
path rootn = p.root_name();
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/itr/traversal.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/itr/traversal.cc
index 43cb43b..b65f997 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/itr/traversal.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/itr/traversal.cc
@@ -108,7 +108,7 @@ test02()
using reverse_iterator = std::reverse_iterator<path::iterator>;
std::vector<path> fwd, rev;
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
const auto begin = p.begin(), end = p.end();
fwd.assign(begin, end);
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/remove_filename.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/remove_filename.cc
index f47227a..7848abd 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/remove_filename.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/remove_filename.cc
@@ -40,7 +40,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path p2(p);
p2.remove_filename();
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/replace_extension.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/replace_extension.cc
index a7b61f0..6cb2300 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/replace_extension.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/replace_extension.cc
@@ -47,7 +47,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path p2 = p;
compare_paths( p2.replace_extension(p2.extension()), p );
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/replace_filename.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/replace_filename.cc
index 48572ac..c8e39e2 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/replace_filename.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/replace_filename.cc
@@ -38,7 +38,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path p2(p);
p2.replace_filename(p.filename());
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/append.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/append.cc
index 03da11f..b05f5f2 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/append.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/append.cc
@@ -69,8 +69,8 @@ test02()
void
test03()
{
- for (const path& p : __gnu_test::test_paths)
- for (const path& q : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
+ for (const path q : __gnu_test::test_paths)
test(p, q);
}
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/cmp.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/cmp.cc
index d9adfad..ff3741c 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/cmp.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/cmp.cc
@@ -47,7 +47,7 @@ void
test02()
{
const path p0 = "/a/a/b/b";
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.compare(p) == 0 );
int cmp = p.compare(p0);
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/cmp_c++20.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/cmp_c++20.cc
index 34e8bf8..786634d 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/cmp_c++20.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/cmp_c++20.cc
@@ -53,7 +53,7 @@ void
test02()
{
const path p0 = "/a/a/b/b";
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( std::is_eq(p <=> p) );
VERIFY( (p <=> p0) == (p.compare(p0) <=> 0) );
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/hash_value.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/hash_value.cc
index d665bcb..0164fa1 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/hash_value.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/nonmember/hash_value.cc
@@ -36,7 +36,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path pp = p.native();
VERIFY( hash_value(p) == hash_value(pp) );
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_extension.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_extension.cc
index 707e7ac..201406f 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_extension.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_extension.cc
@@ -29,7 +29,7 @@ using std::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.has_extension() == !p.extension().empty() );
}
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_filename.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_filename.cc
index b1848d7..f6287cb 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_filename.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_filename.cc
@@ -29,7 +29,7 @@ using std::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.has_filename() == !p.filename().empty() );
}
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_parent_path.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_parent_path.cc
index 7f34be2..3013dbf 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_parent_path.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_parent_path.cc
@@ -29,7 +29,7 @@ using std::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.has_parent_path() == !p.parent_path().empty() );
}
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_relative_path.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_relative_path.cc
index ef606b3..3d44874 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_relative_path.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_relative_path.cc
@@ -29,7 +29,7 @@ using std::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.has_relative_path() == !p.relative_path().empty() );
}
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_root_directory.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_root_directory.cc
index 5a35ded..741b409 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_root_directory.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_root_directory.cc
@@ -29,7 +29,7 @@ using std::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.has_root_directory() == !p.root_directory().empty() );
}
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_root_name.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_root_name.cc
index 0459873..079f9c9 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_root_name.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_root_name.cc
@@ -29,7 +29,7 @@ using std::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.has_root_name() == !p.root_name().empty() );
}
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_root_path.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_root_path.cc
index 99c6951..19f1c8f 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_root_path.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_root_path.cc
@@ -29,7 +29,7 @@ using std::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.has_root_path() == !p.root_path().empty() );
}
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_stem.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_stem.cc
index c531899..7893baf 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_stem.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/query/has_stem.cc
@@ -29,7 +29,7 @@ using std::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.has_stem() == !p.stem().empty() );
}
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/query/is_relative.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/query/is_relative.cc
index ba6fe3c..0ee4d94 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/query/is_relative.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/query/is_relative.cc
@@ -29,7 +29,7 @@ using std::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.is_relative() == !p.is_absolute() );
}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/awk/cstring_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/awk/cstring_01.cc
index 6bd08dc..4c71179 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/awk/cstring_01.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/awk/cstring_01.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-08-26 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/empty_range.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/empty_range.cc
index 45071a6..da5814d 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/empty_range.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/empty_range.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-08-26 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_01.cc
index 317c768..0ccb06a 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_01.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_01.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-11 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_00_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_00_03.cc
index 4982d2a..d985830 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_00_03.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_00_03.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_01_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_01_03.cc
index f787f57..0809716 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_01_03.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_01_03.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca>
@@ -55,7 +56,7 @@ test01()
int
main()
-{
+{
test01();
return 0;
}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc
index 313a385..b527f7f 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/cstring_bracket_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/cstring_bracket_01.cc
index fe076c7..6bf6a77 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/cstring_bracket_01.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/cstring_bracket_01.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-08-01 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/dr2329_neg.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/dr2329_neg.cc
index 9c1c9b3..e8284da 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/dr2329_neg.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/dr2329_neg.cc
@@ -16,6 +16,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
#include <regex>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/53622.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/53622.cc
index 4c392c8..f2e957b 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/53622.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/53622.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-07-23 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/57173.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/57173.cc
index b6cd770..4398ed7 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/57173.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/57173.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-07-23 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/58576.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/58576.cc
index 991385a..4cf8c23 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/58576.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/58576.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-10-01 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/61601.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/61601.cc
index 50997aa..0d300aa 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/61601.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/61601.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// Copyright (C) 2013-2020 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/68863.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/68863.cc
index e5f1a98..6c20148 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/68863.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/68863.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// Copyright (C) 2015-2020 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/anymatcher.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/anymatcher.cc
index 4095dce..0e799a3 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/anymatcher.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/anymatcher.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-09-02 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/backref.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/backref.cc
index ac08a7d..8fb320f 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/backref.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/backref.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-09-02 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/empty_range.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/empty_range.cc
index 7453632..b824c14 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/empty_range.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/empty_range.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-09-02 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/emptygroup.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/emptygroup.cc
index dde9270..f5a8427 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/emptygroup.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/emptygroup.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-09-02 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/hex.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/hex.cc
index 626a347..047c6b8 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/hex.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/hex.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-09-02 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc
index 4f63501..c1e51a6 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-09-05 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/ungreedy.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/ungreedy.cc
index 0e18fc7..566b3cd 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/ungreedy.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/ungreedy.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-10-24 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/63199.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/63199.cc
index 1ea076e..e2b906d 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/63199.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/63199.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 3 }
//
// Copyright (C) 2014-2020 Free Software Foundation, Inc.
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/anymatcher.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/anymatcher.cc
index 590a5d3..49444c4 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/anymatcher.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/anymatcher.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 3 }
//
// 2013-09-02 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/cjk_match.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/cjk_match.cc
index 81ee616..58fdd6e 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/cjk_match.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/cjk_match.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 3 }
//
// 2013-10-18 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/hex.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/hex.cc
index 765bfff..b8e94ef 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/hex.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/hex.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-09-02 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc
index 8c5ee3d..8d5e150 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-21 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc
index 4356509..e1bc770 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-21 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc
index 134202a..9f2242f 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-09-05 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_any.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_any.cc
index 53fb3ee..a3962a1 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_any.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_any.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-11 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc
index 323c198..ae0ee23 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_01_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_01_03.cc
index e687cf1..7f68f94 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_01_03.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_01_03.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc
index b5d5df8..293ea37b 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc
index 483a4a6..33867e5 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc
@@ -1,5 +1,6 @@
// { dg-do run { target c++11 } }
// { dg-require-namedlocale "de_DE.UTF-8" }
+// { dg-timeout-factor 3 }
//
// 2013-08-29 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/51711.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/51711.cc
index bd77feb..8768827 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/51711.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/51711.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// Copyright (C) 2011-2020 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/basic_replace.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/basic_replace.cc
index f7bb9eb..a4475a9 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/basic_replace.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/basic_replace.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-09-24 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/dr2213.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/dr2213.cc
index b9eb926..c9a516c 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/dr2213.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/dr2213.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// Copyright (C) 2014-2020 Free Software Foundation, Inc.
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/pr83601.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/pr83601.cc
index c5f3f00..181e365 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/pr83601.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/pr83601.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// Copyright (C) 2018-2020 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/wchar_t/51711.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/wchar_t/51711.cc
index 5165027..7fe2327 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/wchar_t/51711.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/wchar_t/51711.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// Copyright (C) 2011-2020 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/wchar_t/pr83601.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/wchar_t/pr83601.cc
index 50a98bc..5a7e08f 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/wchar_t/pr83601.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/wchar_t/pr83601.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// Copyright (C) 2018-2020 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/61424.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/61424.cc
index f15baea..823c0e5 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/61424.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/61424.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// Copyright (C) 2014-2020 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/61720.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/61720.cc
index f4126fe..169527b 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/61720.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/61720.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// Copyright (C) 2014-2020 Free Software Foundation, Inc.
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/basic/string_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/basic/string_01.cc
index 79a2944..bae76cc 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/basic/string_01.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/basic/string_01.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-07-17 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/dr2332_neg.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/dr2332_neg.cc
index daa2d90..a5f59ab 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/dr2332_neg.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/dr2332_neg.cc
@@ -16,6 +16,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
#include <regex>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc
index ab80804..bf4207e 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-09-14 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/flags.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/flags.cc
index 8adb468..a781ceb 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/flags.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/flags.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-09-18 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/greedy.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/greedy.cc
index 7b6b412..15aab2d 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/greedy.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/greedy.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-09-14 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc
index 456b876..f69e6a6 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-08-26 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/85098.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/85098.cc
index cfb282f..a16b7f9 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/85098.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/85098.cc
@@ -17,6 +17,7 @@
// { dg-options "-O0" }
// { dg-do link { target c++11 } }
+// { dg-timeout-factor 2 }
#include <regex>
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/cstring.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/cstring.cc
index b97f7ab..630f02c 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/cstring.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/cstring.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// 2009-06-05 Stephen M. Webb <stephen.webb@bregmasoft.ca>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/cstring_op.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/cstring_op.cc
index 3cd4581..ccc6dc3 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/cstring_op.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/cstring_op.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/lwg3296.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/lwg3296.cc
index 3cac594..5ffcc6f 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/lwg3296.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/lwg3296.cc
@@ -16,6 +16,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
#include <regex>
#include <testsuite_hooks.h>
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/moveable.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/moveable.cc
index 45d575d..488f0f7 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/moveable.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/moveable.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// 2010-07-07 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/pstring.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/pstring.cc
index 0e0d2c3..7a2d147 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/pstring.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/pstring.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/range.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/range.cc
index dfb816a1..85acfbd 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/range.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/range.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/string.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/string.cc
index f416474..425e6f9 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/string.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/string.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/string_op.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/string_op.cc
index c675423..27eb1d1 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/string_op.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/string_op.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/cstring.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/cstring.cc
index d15c7f4..5711b26 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/cstring.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/cstring.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/cstring_op.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/cstring_op.cc
index 2c1aeee..f27401e 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/cstring_op.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/cstring_op.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/lwg3296.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/lwg3296.cc
index 4a863c8..eaf253c 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/lwg3296.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/lwg3296.cc
@@ -16,6 +16,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
#include <regex>
#include <testsuite_hooks.h>
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/pstring.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/pstring.cc
index a6d1a58..a106728 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/pstring.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/pstring.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/range.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/range.cc
index 18d36ec..87aec0c 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/range.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/range.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/string.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/string.cc
index f2ee0f3..f945538 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/string.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/string.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/string_op.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/string_op.cc
index 10de7b2..c61a4af 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/string_op.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/string_op.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/47724.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/47724.cc
index 66dec60..f1af1db 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/47724.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/47724.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// Copyright (C) 2011-2020 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/83598.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/83598.cc
index 79e7d9e..fb50817 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/83598.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/83598.cc
@@ -16,6 +16,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
#include <regex>
#include <testsuite_hooks.h>
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/cstring.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/cstring.cc
index 47c9f39..d8a77f6 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/cstring.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/cstring.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/default.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/default.cc
index 3389f67..dbc713a 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/default.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/default.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/iter.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/iter.cc
index 1c40fd2..4cd6ee3 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/iter.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/iter.cc
@@ -16,6 +16,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
#include <regex>
#include <testsuite_iterators.h>
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/pstring_char.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/pstring_char.cc
index 36941ed..103c48e 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/pstring_char.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/pstring_char.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/pstring_wchar_t.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/pstring_wchar_t.cc
index cf75613..9603f3b 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/pstring_wchar_t.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/pstring_wchar_t.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/raw_string.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/raw_string.cc
index f7e1041..a0f7523 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/raw_string.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/raw_string.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// 2012-08-20 Benjamin Kosnik <bkoz@redhat.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/string_range_01_02_03.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/string_range_01_02_03.cc
index f3f8006..5232d1a 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/string_range_01_02_03.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/string_range_01_02_03.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring.cc
index ff049b0..e0cdf67 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_awk.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_awk.cc
index 90993bf..e95aeab 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_awk.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_awk.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_ecma.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_ecma.cc
index 7aa7f2b..920a3da 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_ecma.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_ecma.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_egrep.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_egrep.cc
index 595b576..6ddb206 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_egrep.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_egrep.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_grep.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_grep.cc
index a178e03..0953fb0 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_grep.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring_grep.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/default.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/default.cc
index c84d893..71993e4 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/default.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/default.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/range.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/range.cc
index 80ffbb6..396754a 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/range.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/range.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/copy_char.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/copy_char.cc
index 3004759..8253850 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/copy_char.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/copy_char.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// 2010-07-07 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/deduction.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/deduction.cc
index 6fab70c..88112af 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/deduction.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/deduction.cc
@@ -17,6 +17,7 @@
// { dg-options "-std=gnu++17" }
// { dg-do compile { target c++17 } }
+// { dg-timeout-factor 3 }
#include <regex>
#include <testsuite_iterators.h>
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/extended/cstring.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/extended/cstring.cc
index cafd94f..d6fd8b4 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/extended/cstring.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/extended/cstring.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/extended/string_range_01_02_03.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/extended/string_range_01_02_03.cc
index 5af5689..2b49c75 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/extended/string_range_01_02_03.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/extended/string_range_01_02_03.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/move_char.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/move_char.cc
index 252d202..7b84ced 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/move_char.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/move_char.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// 2010-07-07 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/string_char.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/string_char.cc
index 7ded161..29c9ea0 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/string_char.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/string_char.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/string_wchar_t.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/string_wchar_t.cc
index cdf851a..99965cc 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/string_wchar_t.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/string_wchar_t.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/cstring.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/cstring.cc
index 2a452f8..2df3cd5 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/cstring.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/cstring.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/default.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/default.cc
index 6b69124..818bd19 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/default.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/default.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/range.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/range.cc
index c10f260..8049de0 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/range.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/range.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/imbue/string.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/imbue/string.cc
index 0e1464b..6a00bee 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/imbue/string.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/imbue/string.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// Copyright (C) 2015-2020 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/multiple_quantifiers.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/multiple_quantifiers.cc
index 5836cc1..2b16fd45 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/multiple_quantifiers.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/multiple_quantifiers.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// Copyright (C) 2014-2020 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/requirements/constexpr_data.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/requirements/constexpr_data.cc
index 72a8a4f..9960b6e 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/requirements/constexpr_data.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/requirements/constexpr_data.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// Copyright (C) 2010-2020 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/28_regex/constants/constexpr.cc b/libstdc++-v3/testsuite/28_regex/constants/constexpr.cc
index 26a36e6..ba69b0b 100644
--- a/libstdc++-v3/testsuite/28_regex/constants/constexpr.cc
+++ b/libstdc++-v3/testsuite/28_regex/constants/constexpr.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
//
// Copyright (C) 2015-2020 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/28_regex/constants/error_type.cc b/libstdc++-v3/testsuite/28_regex/constants/error_type.cc
index e4f23fb..dd77694 100644
--- a/libstdc++-v3/testsuite/28_regex/constants/error_type.cc
+++ b/libstdc++-v3/testsuite/28_regex/constants/error_type.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2009-06-17 Stephen M. Webb <stephen.webb@xandros.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/constants/match_flag_type.cc b/libstdc++-v3/testsuite/28_regex/constants/match_flag_type.cc
index 99c4e39..98b821e 100644
--- a/libstdc++-v3/testsuite/28_regex/constants/match_flag_type.cc
+++ b/libstdc++-v3/testsuite/28_regex/constants/match_flag_type.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2009-06-17 Stephen M. Webb <stephen.webb@xandros.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/constants/syntax_option_type.cc b/libstdc++-v3/testsuite/28_regex/constants/syntax_option_type.cc
index 4cb0028..5e97ac6 100644
--- a/libstdc++-v3/testsuite/28_regex/constants/syntax_option_type.cc
+++ b/libstdc++-v3/testsuite/28_regex/constants/syntax_option_type.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2009-06-17 Stephen M. Webb <stephen.webb@xandros.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/headers/regex/std_c++0x_neg.cc b/libstdc++-v3/testsuite/28_regex/headers/regex/std_c++0x_neg.cc
index f07e438..0be20c8 100644
--- a/libstdc++-v3/testsuite/28_regex/headers/regex/std_c++0x_neg.cc
+++ b/libstdc++-v3/testsuite/28_regex/headers/regex/std_c++0x_neg.cc
@@ -1,5 +1,6 @@
// { dg-options "-std=gnu++98" }
// { dg-do compile { target c++98_only } }
+// { dg-timeout-factor 2 }
// Copyright (C) 2007-2020 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/28_regex/init-list.cc b/libstdc++-v3/testsuite/28_regex/init-list.cc
index f51453f..dfc6c86 100644
--- a/libstdc++-v3/testsuite/28_regex/init-list.cc
+++ b/libstdc++-v3/testsuite/28_regex/init-list.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// Copyright (C) 2008-2020 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/64140.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/64140.cc
index 186837e..9304d60 100644
--- a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/64140.cc
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/64140.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// Copyright (C) 2014-2020 Free Software Foundation, Inc.
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_01.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_01.cc
index 2c10d4a..4a41847 100644
--- a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_01.cc
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_01.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-07-20 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_position_01.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_position_01.cc
index 5b2c13e..aba6d30 100644
--- a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_position_01.cc
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_position_01.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-07-25 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/ctors/char/default.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/ctors/char/default.cc
index 4bce84c..bde4e20 100644
--- a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/ctors/char/default.cc
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/ctors/char/default.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-10 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/ctors/char/dr2332_neg.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/ctors/char/dr2332_neg.cc
index cef42d2..4f59f82 100644
--- a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/ctors/char/dr2332_neg.cc
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/ctors/char/dr2332_neg.cc
@@ -16,6 +16,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
#include <regex>
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/ctors/wchar_t/default.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/ctors/wchar_t/default.cc
index b56840f..3e5d791 100644
--- a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/ctors/wchar_t/default.cc
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/ctors/wchar_t/default.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-10 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/typedefs.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/typedefs.cc
index b31c674..8a3e9c7 100644
--- a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/typedefs.cc
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/typedefs.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-10 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_01.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_01.cc
index 78cd1c7..0f19118 100644
--- a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_01.cc
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_01.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-07-20 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_02.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_02.cc
index aab4fdb..5f4696a 100644
--- a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_02.cc
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_02.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// { dg-require-namedlocale "en_US.UTF-8" }
//
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/64303.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/64303.cc
index 2d7036d..95d39a7 100644
--- a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/64303.cc
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/64303.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// Copyright (C) 2014-2020 Free Software Foundation, Inc.
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/char/string_01.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/char/string_01.cc
index 2cdb7a9..dbf4386 100644
--- a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/char/string_01.cc
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/char/string_01.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-07-20 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/ctors/char/default.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/ctors/char/default.cc
index fe01d47..fbeb35b 100644
--- a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/ctors/char/default.cc
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/ctors/char/default.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-10 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/ctors/char/dr2332_neg.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/ctors/char/dr2332_neg.cc
index f2898bd..9233bfb 100644
--- a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/ctors/char/dr2332_neg.cc
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/ctors/char/dr2332_neg.cc
@@ -16,6 +16,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
#include <regex>
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/ctors/wchar_t/default.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/ctors/wchar_t/default.cc
index 7d7481f..836e632 100644
--- a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/ctors/wchar_t/default.cc
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/ctors/wchar_t/default.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-10 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/typedefs.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/typedefs.cc
index fbb1c7a..adb2691 100644
--- a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/typedefs.cc
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/typedefs.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-10 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/wchar_t/string_01.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/wchar_t/string_01.cc
index 4474a3f..794640f 100644
--- a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/wchar_t/string_01.cc
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/wchar_t/string_01.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-07-20 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/wchar_t/wstring_02.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/wchar_t/wstring_02.cc
index 9bb4536..778da57 100644
--- a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/wchar_t/wstring_02.cc
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/wchar_t/wstring_02.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// { dg-require-namedlocale "en_US.UTF-8" }
//
diff --git a/libstdc++-v3/testsuite/28_regex/match_results/94627.cc b/libstdc++-v3/testsuite/28_regex/match_results/94627.cc
index dc4883c..9226929 100644
--- a/libstdc++-v3/testsuite/28_regex/match_results/94627.cc
+++ b/libstdc++-v3/testsuite/28_regex/match_results/94627.cc
@@ -16,6 +16,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
#include <regex>
#include <testsuite_hooks.h>
diff --git a/libstdc++-v3/testsuite/28_regex/match_results/ctors/char/default.cc b/libstdc++-v3/testsuite/28_regex/match_results/ctors/char/default.cc
index ad644ff..72e321f 100644
--- a/libstdc++-v3/testsuite/28_regex/match_results/ctors/char/default.cc
+++ b/libstdc++-v3/testsuite/28_regex/match_results/ctors/char/default.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// 2009-06-10 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/match_results/ctors/wchar_t/default.cc b/libstdc++-v3/testsuite/28_regex/match_results/ctors/wchar_t/default.cc
index cf53264..ba63be9 100644
--- a/libstdc++-v3/testsuite/28_regex/match_results/ctors/wchar_t/default.cc
+++ b/libstdc++-v3/testsuite/28_regex/match_results/ctors/wchar_t/default.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// 2009-06-05 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/match_results/format.cc b/libstdc++-v3/testsuite/28_regex/match_results/format.cc
index 28c2396..df4e6bb 100644
--- a/libstdc++-v3/testsuite/28_regex/match_results/format.cc
+++ b/libstdc++-v3/testsuite/28_regex/match_results/format.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2013-09-24 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/match_results/out_of_range_submatches.cc b/libstdc++-v3/testsuite/28_regex/match_results/out_of_range_submatches.cc
index 43374e6..f7cf6d8 100644
--- a/libstdc++-v3/testsuite/28_regex/match_results/out_of_range_submatches.cc
+++ b/libstdc++-v3/testsuite/28_regex/match_results/out_of_range_submatches.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// Copyright (C) 2015-2020 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/28_regex/match_results/pmr_typedefs.cc b/libstdc++-v3/testsuite/28_regex/match_results/pmr_typedefs.cc
index 5df85fd..97df14d 100644
--- a/libstdc++-v3/testsuite/28_regex/match_results/pmr_typedefs.cc
+++ b/libstdc++-v3/testsuite/28_regex/match_results/pmr_typedefs.cc
@@ -17,6 +17,7 @@
// { dg-options "-std=gnu++17" }
// { dg-do compile { target c++17 } }
+// { dg-timeout-factor 2 }
// { dg-require-effective-target cxx11-abi }
#include <regex>
diff --git a/libstdc++-v3/testsuite/28_regex/match_results/swap.cc b/libstdc++-v3/testsuite/28_regex/match_results/swap.cc
index 8f9c3be..ff173a2 100644
--- a/libstdc++-v3/testsuite/28_regex/match_results/swap.cc
+++ b/libstdc++-v3/testsuite/28_regex/match_results/swap.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// Copyright (C) 2015-2020 Free Software Foundation, Inc.
diff --git a/libstdc++-v3/testsuite/28_regex/match_results/typedefs.cc b/libstdc++-v3/testsuite/28_regex/match_results/typedefs.cc
index 81a9e56..9af92d2 100644
--- a/libstdc++-v3/testsuite/28_regex/match_results/typedefs.cc
+++ b/libstdc++-v3/testsuite/28_regex/match_results/typedefs.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-10 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/range_access.cc b/libstdc++-v3/testsuite/28_regex/range_access.cc
index 07a5309..cda4936 100644
--- a/libstdc++-v3/testsuite/28_regex/range_access.cc
+++ b/libstdc++-v3/testsuite/28_regex/range_access.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
// Copyright (C) 2010-2020 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/28_regex/regex_error/base.cc b/libstdc++-v3/testsuite/28_regex/regex_error/base.cc
index dc98607..e42080a 100644
--- a/libstdc++-v3/testsuite/28_regex/regex_error/base.cc
+++ b/libstdc++-v3/testsuite/28_regex/regex_error/base.cc
@@ -18,6 +18,7 @@
// 28.6 [re.badexp]
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
#include <regex>
diff --git a/libstdc++-v3/testsuite/28_regex/regex_error/regex_error.cc b/libstdc++-v3/testsuite/28_regex/regex_error/regex_error.cc
index 3ec4194..1e9c884 100644
--- a/libstdc++-v3/testsuite/28_regex/regex_error/regex_error.cc
+++ b/libstdc++-v3/testsuite/28_regex/regex_error/regex_error.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2009-06-17 Stephen M. Webb <stephen.webb@xandros.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/regression.cc b/libstdc++-v3/testsuite/28_regex/regression.cc
index 754c3da..a479601 100644
--- a/libstdc++-v3/testsuite/28_regex/regression.cc
+++ b/libstdc++-v3/testsuite/28_regex/regression.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// Copyright (C) 2015-2020 Free Software Foundation, Inc.
diff --git a/libstdc++-v3/testsuite/28_regex/requirements/typedefs.cc b/libstdc++-v3/testsuite/28_regex/requirements/typedefs.cc
index 93ccc63..acd8821 100644
--- a/libstdc++-v3/testsuite/28_regex/requirements/typedefs.cc
+++ b/libstdc++-v3/testsuite/28_regex/requirements/typedefs.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-02-17 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/simple_c++11.cc b/libstdc++-v3/testsuite/28_regex/simple_c++11.cc
index 8b3fda5..3ad9a46 100644
--- a/libstdc++-v3/testsuite/28_regex/simple_c++11.cc
+++ b/libstdc++-v3/testsuite/28_regex/simple_c++11.cc
@@ -17,6 +17,7 @@
// { dg-options "-std=gnu++11" }
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
#include <regex>
diff --git a/libstdc++-v3/testsuite/28_regex/sub_match/cast_char.cc b/libstdc++-v3/testsuite/28_regex/sub_match/cast_char.cc
index 292e53d..3969438 100644
--- a/libstdc++-v3/testsuite/28_regex/sub_match/cast_char.cc
+++ b/libstdc++-v3/testsuite/28_regex/sub_match/cast_char.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-09 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/sub_match/cast_wchar_t.cc b/libstdc++-v3/testsuite/28_regex/sub_match/cast_wchar_t.cc
index 30a3aa6..5c32fdb 100644
--- a/libstdc++-v3/testsuite/28_regex/sub_match/cast_wchar_t.cc
+++ b/libstdc++-v3/testsuite/28_regex/sub_match/cast_wchar_t.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-09 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/sub_match/compare.cc b/libstdc++-v3/testsuite/28_regex/sub_match/compare.cc
index babb576..86c147f 100644
--- a/libstdc++-v3/testsuite/28_regex/sub_match/compare.cc
+++ b/libstdc++-v3/testsuite/28_regex/sub_match/compare.cc
@@ -16,6 +16,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
#include <regex>
#include <testsuite_hooks.h>
diff --git a/libstdc++-v3/testsuite/28_regex/sub_match/compare_c++20.cc b/libstdc++-v3/testsuite/28_regex/sub_match/compare_c++20.cc
index d632d00..a746173 100644
--- a/libstdc++-v3/testsuite/28_regex/sub_match/compare_c++20.cc
+++ b/libstdc++-v3/testsuite/28_regex/sub_match/compare_c++20.cc
@@ -17,6 +17,7 @@
// { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } }
+// { dg-timeout-factor 2 }
#include <regex>
#include <testsuite_hooks.h>
diff --git a/libstdc++-v3/testsuite/28_regex/sub_match/embedded_zeros_cmp.cc b/libstdc++-v3/testsuite/28_regex/sub_match/embedded_zeros_cmp.cc
index 0c336b5..c948514 100644
--- a/libstdc++-v3/testsuite/28_regex/sub_match/embedded_zeros_cmp.cc
+++ b/libstdc++-v3/testsuite/28_regex/sub_match/embedded_zeros_cmp.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2014-11-13 Daniel Kruegler <daniel.kruegler@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/sub_match/length.cc b/libstdc++-v3/testsuite/28_regex/sub_match/length.cc
index fb6fdf7e..edd2178 100644
--- a/libstdc++-v3/testsuite/28_regex/sub_match/length.cc
+++ b/libstdc++-v3/testsuite/28_regex/sub_match/length.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-09 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/sub_match/typedefs.cc b/libstdc++-v3/testsuite/28_regex/sub_match/typedefs.cc
index bac764e..ce9f4f6 100644
--- a/libstdc++-v3/testsuite/28_regex/sub_match/typedefs.cc
+++ b/libstdc++-v3/testsuite/28_regex/sub_match/typedefs.cc
@@ -1,4 +1,5 @@
// { dg-do compile { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-07 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/ctor.cc b/libstdc++-v3/testsuite/28_regex/traits/char/ctor.cc
index 8b8459e..6938772 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/char/ctor.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/char/ctor.cc
@@ -1,4 +1,5 @@
// { dg-do link { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/icase.cc b/libstdc++-v3/testsuite/28_regex/traits/char/icase.cc
index d42ce61..f083188 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/char/icase.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/char/icase.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// Copyright (C) 2016-2020 Free Software Foundation, Inc.
diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/isctype.cc b/libstdc++-v3/testsuite/28_regex/traits/char/isctype.cc
index b40f06d..a8f06c2 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/char/isctype.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/char/isctype.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// { dg-additional-options "-DNEWLINE_IN_CLASS_BLANK" { target newlib } }
//
diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/length.cc b/libstdc++-v3/testsuite/28_regex/traits/char/length.cc
index 3c05535..6180e01 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/char/length.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/char/length.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-02-17 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/lookup_classname.cc b/libstdc++-v3/testsuite/28_regex/traits/char/lookup_classname.cc
index 9f0314e..0718a49 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/char/lookup_classname.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/char/lookup_classname.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-23 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/lookup_collatename.cc b/libstdc++-v3/testsuite/28_regex/traits/char/lookup_collatename.cc
index 3897f25..44cc19e 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/char/lookup_collatename.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/char/lookup_collatename.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-06-23 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/transform.cc b/libstdc++-v3/testsuite/28_regex/traits/char/transform.cc
index e838dcd..9ea9a09 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/char/transform.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/char/transform.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-02-17 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/transform_primary.cc b/libstdc++-v3/testsuite/28_regex/traits/char/transform_primary.cc
index 5497a16..a18fd05 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/char/transform_primary.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/char/transform_primary.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-02-17 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/translate.cc b/libstdc++-v3/testsuite/28_regex/traits/char/translate.cc
index e857fb1..63a0ff7 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/char/translate.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/char/translate.cc
@@ -1,5 +1,6 @@
// { dg_do run }
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-02-17 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/translate_nocase.cc b/libstdc++-v3/testsuite/28_regex/traits/char/translate_nocase.cc
index 4caa954..9bbfef5 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/char/translate_nocase.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/char/translate_nocase.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/user_defined.cc b/libstdc++-v3/testsuite/28_regex/traits/char/user_defined.cc
index d3241e2..782d418 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/char/user_defined.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/char/user_defined.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2014-01-07 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/value.cc b/libstdc++-v3/testsuite/28_regex/traits/char/value.cc
index 444c0ad..f26fa4b 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/char/value.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/char/value.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// 2008-08-11 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/ctor.cc b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/ctor.cc
index 8c48116..a376cd6 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/ctor.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/ctor.cc
@@ -1,4 +1,5 @@
// { dg-do link { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/isctype.cc b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/isctype.cc
index 0a27f01..92d1614 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/isctype.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/isctype.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// { dg-additional-options "-DNEWLINE_IN_CLASS_BLANK" { target newlib } }
// Copyright (C) 2010-2020 Free Software Foundation, Inc.
diff --git a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/length.cc b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/length.cc
index 458311c..99686cc 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/length.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/length.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-02-17 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_classname.cc b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_classname.cc
index b168950..c7ec260 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_classname.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_classname.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// Copyright (C) 2010-2020 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_collatename.cc b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_collatename.cc
index 4fea3b1..9399fe1 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_collatename.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_collatename.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// Copyright (C) 2010-2020 Free Software Foundation, Inc.
diff --git a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/transform.cc b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/transform.cc
index 9eeb3b2..33d3117 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/transform.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/transform.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-02-17 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/transform_primary.cc b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/transform_primary.cc
index 7fa93ca..41642b8 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/transform_primary.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/transform_primary.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// Copyright (C) 2010-2020 Free Software Foundation, Inc.
diff --git a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/translate.cc b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/translate.cc
index 6bb4d9f..170bd43 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/translate.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/translate.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2010-02-17 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/translate_nocase.cc b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/translate_nocase.cc
index 6636bf7..aebce49 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/translate_nocase.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/translate_nocase.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/user_defined.cc b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/user_defined.cc
index 8bbfba4..fe34697 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/user_defined.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/user_defined.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
//
// 2014-01-07 Tim Shen <timshen91@gmail.com>
diff --git a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/value.cc b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/value.cc
index 86b0c88..e1d47ca 100644
--- a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/value.cc
+++ b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/value.cc
@@ -1,4 +1,5 @@
// { dg-do run { target c++11 } }
+// { dg-timeout-factor 2 }
// 2008-08-11 Stephen M. Webb <stephen.webb@bregmasoft.com>
//
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/1.cc b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/1.cc
new file mode 100644
index 0000000..7b183b2
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/1.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2020 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 } }
+// { dg-require-effective-target gthreads }
+
+#include <atomic>
+
+#ifndef __cpp_lib_atomic_wait
+# error "Feature-test macro for atomic wait missing in <atomic>"
+#elif __cpp_lib_atomic_wait != 201907L
+# error "Feature-test macro for atomic wait has wrong value in <atomic>"
+#endif
+
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/2.cc b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/2.cc
new file mode 100644
index 0000000..249bf2d
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/2.cc
@@ -0,0 +1,30 @@
+// Copyright (C) 2020 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 } }
+// { dg-require-effective-target gthreads }
+
+#include <version>
+
+#ifndef __cpp_lib_atomic_wait
+# error "Feature-test macro for atomic wait missing in <version>"
+#elif __cpp_lib_atomic_wait != 201907L
+# error "Feature-test macro for atomic wait has wrong value in <version>"
+#endif
+
+
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/bool.cc b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/bool.cc
new file mode 100644
index 0000000..1fc0149
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/bool.cc
@@ -0,0 +1,63 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-require-gthreads "" }
+// { dg-additional-options "-pthread" { target pthread } }
+
+// Copyright (C) 2020 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 <atomic>
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include <type_traits>
+#include <chrono>
+
+#include <testsuite_hooks.h>
+
+int
+main ()
+{
+ using namespace std::literals::chrono_literals;
+
+ std::mutex m;
+ std::condition_variable cv;
+ std::unique_lock<std::mutex> l(m);
+
+ std::atomic<bool> a(false);
+ std::atomic<bool> b(false);
+ std::thread t([&]
+ {
+ {
+ // This ensures we block until cv.wait(l) starts.
+ std::lock_guard<std::mutex> ll(m);
+ }
+ cv.notify_one();
+ a.wait(false);
+ if (a.load())
+ {
+ b.store(true);
+ }
+ });
+ cv.wait(l);
+ std::this_thread::sleep_for(100ms);
+ a.store(true);
+ a.notify_one();
+ t.join();
+ VERIFY( b.load() );
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/generic.cc b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/generic.cc
new file mode 100644
index 0000000..988fe7b
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/generic.cc
@@ -0,0 +1,31 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-require-gthreads "" }
+// { dg-additional-options "-pthread" { target pthread } }
+
+// Copyright (C) 2020 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 "atomic/wait_notify_util.h"
+
+int
+main ()
+{
+ struct S{ int i; };
+ check<S> check_s{S{0},S{42}};
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/pointers.cc b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/pointers.cc
new file mode 100644
index 0000000..3b699e9
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/pointers.cc
@@ -0,0 +1,63 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2020 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 <atomic>
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include <type_traits>
+#include <chrono>
+
+#include <testsuite_hooks.h>
+
+int
+main ()
+{
+ using namespace std::literals::chrono_literals;
+
+ std::mutex m;
+ std::condition_variable cv;
+ std::unique_lock<std::mutex> l(m);
+
+ long aa;
+ long bb;
+
+ std::atomic<long*> a(nullptr);
+ std::thread t([&]
+ {
+ {
+ // This ensures we block until cv.wait(l) starts.
+ std::lock_guard<std::mutex> ll(m);
+ }
+ cv.notify_one();
+ a.wait(nullptr);
+ if (a.load() == &aa)
+ a.store(&bb);
+ });
+ cv.wait(l);
+ std::this_thread::sleep_for(100ms);
+ a.store(&aa);
+ a.notify_one();
+ t.join();
+ VERIFY( a.load() == &bb);
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc b/libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc
new file mode 100644
index 0000000..5d5e06d
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc
@@ -0,0 +1,65 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-require-gthreads "" }
+// { dg-additional-options "-pthread" { target pthread } }
+
+// Copyright (C) 2020 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 <atomic>
+#include <chrono>
+#include <condition_variable>
+#include <concepts>
+#include <mutex>
+#include <thread>
+
+#include <testsuite_hooks.h>
+
+int
+main()
+{
+ using namespace std::literals::chrono_literals;
+
+ std::mutex m;
+ std::condition_variable cv;
+ std::unique_lock<std::mutex> l(m);
+
+ std::atomic_flag a;
+ std::atomic_flag b;
+ std::thread t([&]
+ {
+ {
+ // This ensures we block until cv.wait(l) starts.
+ std::lock_guard<std::mutex> ll(m);
+ }
+ cv.notify_one();
+ a.wait(false);
+ b.test_and_set();
+ b.notify_one();
+ });
+
+ cv.wait(l);
+ std::this_thread::sleep_for(100ms);
+ a.test_and_set();
+ a.notify_one();
+ b.wait(false);
+ t.join();
+
+ VERIFY( a.test() );
+ VERIFY( b.test() );
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_float/wait_notify.cc b/libstdc++-v3/testsuite/29_atomics/atomic_float/wait_notify.cc
new file mode 100644
index 0000000..134eff3
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_float/wait_notify.cc
@@ -0,0 +1,32 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-require-gthreads "" }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-add-options libatomic }
+
+// Copyright (C) 2020 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 "atomic/wait_notify_util.h"
+
+int
+main ()
+{
+ check<float> f;
+ check<double> d;
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_integral/wait_notify.cc b/libstdc++-v3/testsuite/29_atomics/atomic_integral/wait_notify.cc
new file mode 100644
index 0000000..c65379c
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_integral/wait_notify.cc
@@ -0,0 +1,66 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-require-gthreads "" }
+// { dg-add-options libatomic }
+// { dg-additional-options "-pthread" { target pthread } }
+
+// Copyright (C) 2020 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 "atomic/wait_notify_util.h"
+
+void
+test01()
+{
+ struct S{ int i; };
+ std::atomic<S> s;
+
+ s.wait(S{42});
+}
+
+int
+main ()
+{
+ // check<bool> bb;
+ check<char> ch;
+ check<signed char> sch;
+ check<unsigned char> uch;
+ check<short> s;
+ check<unsigned short> us;
+ check<int> i;
+ check<unsigned int> ui;
+ check<long> l;
+ check<unsigned long> ul;
+ check<long long> ll;
+ check<unsigned long long> ull;
+
+ check<wchar_t> wch;
+ check<char8_t> ch8;
+ check<char16_t> ch16;
+ check<char32_t> ch32;
+
+ check<int8_t> i8;
+ check<int16_t> i16;
+ check<int32_t> i32;
+ check<int64_t> i64;
+
+ check<uint8_t> u8;
+ check<uint16_t> u16;
+ check<uint32_t> u32;
+ check<uint64_t> u64;
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc b/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc
new file mode 100644
index 0000000..bc5a7d0
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc
@@ -0,0 +1,95 @@
+// { dg-options "-std=gnu++2a -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+// { dg-add-options libatomic }
+
+// Copyright (C) 2020 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 <atomic>
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include <chrono>
+#include <type_traits>
+
+#include <testsuite_hooks.h>
+
+template<typename Tp>
+Tp check_wait_notify(Tp val1, Tp val2)
+{
+ using namespace std::literals::chrono_literals;
+
+ std::mutex m;
+ std::condition_variable cv;
+ std::unique_lock<std::mutex> l(m);
+
+ Tp aa = val1;
+ std::atomic_ref<Tp> a(aa);
+ std::thread t([&]
+ {
+ {
+ // This ensures we block until cv.wait(l) starts.
+ std::lock_guard<std::mutex> ll(m);
+ }
+ cv.notify_one();
+ a.wait(val1);
+ if (a.load() != val2)
+ a = val1;
+ });
+ cv.wait(l);
+ std::this_thread::sleep_for(100ms);
+ a.store(val2);
+ a.notify_one();
+ t.join();
+ return a.load();
+}
+
+template<typename Tp,
+ bool = std::is_integral_v<Tp>
+ || std::is_floating_point_v<Tp>>
+struct check;
+
+template<typename Tp>
+struct check<Tp, true>
+{
+ check()
+ {
+ Tp a = 0;
+ Tp b = 42;
+ VERIFY(check_wait_notify(a, b) == b);
+ }
+};
+
+template<typename Tp>
+struct check<Tp, false>
+{
+ check(Tp b)
+ {
+ Tp a;
+ VERIFY(check_wait_notify(a, b) == b);
+ }
+};
+
+int
+main ()
+{
+ check<long>();
+ check<double>();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/async/async.cc b/libstdc++-v3/testsuite/30_threads/async/async.cc
index 1c779bf..b06c255 100644
--- a/libstdc++-v3/testsuite/30_threads/async/async.cc
+++ b/libstdc++-v3/testsuite/30_threads/async/async.cc
@@ -22,6 +22,7 @@
#include <future>
+#include <thread>
#include <testsuite_hooks.h>
using namespace std;
diff --git a/libstdc++-v3/testsuite/30_threads/call_once/66146.cc b/libstdc++-v3/testsuite/30_threads/call_once/66146.cc
index b1ca0eb..a9c9948 100644
--- a/libstdc++-v3/testsuite/30_threads/call_once/66146.cc
+++ b/libstdc++-v3/testsuite/30_threads/call_once/66146.cc
@@ -16,9 +16,11 @@
// <http://www.gnu.org/licenses/>.
// { dg-do run { target c++11 } }
-// { dg-skip-if "" { pthread && { ! *-*-*linux* } } }
// { dg-additional-options "-pthread" { target pthread } }
+// Currently std::call_once is broken for gthreads targets without futexes:
+// { dg-skip-if "see PR 66146" { gthreads && { ! futex } } }
+
#include <mutex>
#include <cstdlib>
#include <testsuite_hooks.h>
diff --git a/libstdc++-v3/testsuite/30_threads/future/members/93456.cc b/libstdc++-v3/testsuite/30_threads/future/members/93456.cc
new file mode 100644
index 0000000..9d1cbce
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/future/members/93456.cc
@@ -0,0 +1,49 @@
+// { dg-do run }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-require-effective-target c++11 }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2020 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 <future>
+#include <thread>
+#include <chrono>
+#include <climits>
+#include <testsuite_hooks.h>
+
+namespace chrono = std::chrono;
+
+void test01()
+{
+ std::future<void> fut = std::async(std::launch::async, [] {
+ std::this_thread::sleep_for(chrono::seconds(4));
+ });
+
+ // A time in the distant future, but which overflows 32-bit time_t:
+ auto then = chrono::system_clock::now() + chrono::seconds(UINT_MAX + 2LL);
+ auto status = fut.wait_until(then);
+ // The wait_until call should have waited for the result to be ready.
+ // If converting the time_point to time_t overflows, it will timeout.
+ VERIFY(status == std::future_status::ready);
+}
+
+int main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/30_threads/future/members/poll.cc b/libstdc++-v3/testsuite/30_threads/future/members/poll.cc
new file mode 100644
index 0000000..fff9bea
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/future/members/poll.cc
@@ -0,0 +1,105 @@
+// Copyright (C) 2020 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 "-O3" }
+// { dg-do run { target c++11 } }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-require-gthreads "" }
+
+#include <future>
+#include <chrono>
+#include <iostream>
+#include <testsuite_hooks.h>
+
+const int iterations = 200;
+
+using namespace std;
+
+template<typename Duration>
+double
+print(const char* desc, Duration dur)
+{
+ auto ns = chrono::duration_cast<chrono::nanoseconds>(dur).count();
+ double d = double(ns) / iterations;
+ cout << desc << ": " << ns << "ns for " << iterations
+ << " calls, avg " << d << "ns per call\n";
+ return d;
+}
+
+int main()
+{
+ promise<int> p;
+ future<int> f = p.get_future();
+
+ auto start = chrono::high_resolution_clock::now();
+ for(int i = 0; i < iterations; i++)
+ f.wait_for(chrono::seconds(0));
+ auto stop = chrono::high_resolution_clock::now();
+ double wait_for_0 = print("wait_for(0s)", stop - start);
+
+ start = chrono::high_resolution_clock::now();
+ for(int i = 0; i < iterations; i++)
+ f.wait_until(chrono::system_clock::time_point::min());
+ stop = chrono::high_resolution_clock::now();
+ double wait_until_sys_min __attribute__((unused))
+ = print("wait_until(system_clock minimum)", stop - start);
+
+ start = chrono::high_resolution_clock::now();
+ for(int i = 0; i < iterations; i++)
+ f.wait_until(chrono::steady_clock::time_point::min());
+ stop = chrono::high_resolution_clock::now();
+ double wait_until_steady_min __attribute__((unused))
+ = print("wait_until(steady_clock minimum)", stop - start);
+
+ start = chrono::high_resolution_clock::now();
+ for(int i = 0; i < iterations; i++)
+ f.wait_until(chrono::system_clock::time_point());
+ stop = chrono::high_resolution_clock::now();
+ double wait_until_sys_epoch __attribute__((unused))
+ = print("wait_until(system_clock epoch)", stop - start);
+
+ start = chrono::high_resolution_clock::now();
+ for(int i = 0; i < iterations; i++)
+ f.wait_until(chrono::steady_clock::time_point());
+ stop = chrono::high_resolution_clock::now();
+ double wait_until_steady_epoch __attribute__((unused))
+ = print("wait_until(steady_clock epoch", stop - start);
+
+ p.set_value(1);
+
+ start = chrono::high_resolution_clock::now();
+ for(int i = 0; i < iterations; i++)
+ f.wait_for(chrono::seconds(0));
+ stop = chrono::high_resolution_clock::now();
+ double ready = print("wait_for when ready", stop - start);
+
+ // Polling before ready with wait_for(0s) should be almost as fast as
+ // after the result is ready.
+ VERIFY( wait_for_0 < (ready * 30) );
+
+ // Polling before ready using wait_until(min) should not be terribly slow.
+ VERIFY( wait_until_sys_min < (ready * 100) );
+ VERIFY( wait_until_steady_min < (ready * 100) );
+
+ // The following two tests fail with GCC 11, see
+ // https://gcc.gnu.org/pipermail/libstdc++/2020-November/051422.html
+#if 0
+ // Polling before ready using wait_until(epoch) should not be terribly slow.
+ VERIFY( wait_until_sys_epoch < (ready * 100) );
+ VERIFY( wait_until_steady_epoch < (ready * 100) );
+#endif
+}
diff --git a/libstdc++-v3/testsuite/30_threads/jthread/95989.cc b/libstdc++-v3/testsuite/30_threads/jthread/95989.cc
new file mode 100644
index 0000000..a179eab
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/jthread/95989.cc
@@ -0,0 +1,56 @@
+// Copyright (C) 2020 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 } }
+// { dg-require-gthreads {} }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-additional-options "-static" { target static } }
+// { dg-skip-if "broken" { *-*-* } }
+
+#include <thread>
+
+// PR libstdc++/95989
+// Segfault compiling with static libraries and using jthread::request_stop
+
+void
+test01()
+{
+ std::jthread t{ [] () {} };
+}
+
+void
+test02()
+{
+ std::jthread t{ [] () {} };
+ t.request_stop();
+}
+
+void
+test03()
+{
+ std::jthread t{ [] {} };
+ std::stop_callback cb(t.get_stop_token(), [] () {});
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/30_threads/jthread/jthread.cc b/libstdc++-v3/testsuite/30_threads/jthread/jthread.cc
index 746ff43..b8ba62f 100644
--- a/libstdc++-v3/testsuite/30_threads/jthread/jthread.cc
+++ b/libstdc++-v3/testsuite/30_threads/jthread/jthread.cc
@@ -187,6 +187,25 @@ void test_detach()
VERIFY(t1FinallyInterrupted.load());
}
+//------------------------------------------------------
+
+void test_move_assignment()
+{
+ std::jthread thread1([]{});
+ std::jthread thread2([]{});
+
+ const auto id2 = thread2.get_id();
+ const auto ssource2 = thread2.get_stop_source();
+
+ thread1 = std::move(thread2);
+
+ VERIFY(thread1.get_id() == id2);
+ VERIFY(thread2.get_id() == std::jthread::id());
+
+ VERIFY(thread1.get_stop_source() == ssource2);
+ VERIFY(!thread2.get_stop_source().stop_possible());
+}
+
int main()
{
std::set_terminate([](){
@@ -197,4 +216,5 @@ int main()
test_stop_token();
test_join();
test_detach();
+ test_move_assignment();
}
diff --git a/libstdc++-v3/testsuite/30_threads/latch/1.cc b/libstdc++-v3/testsuite/30_threads/latch/1.cc
new file mode 100644
index 0000000..aa203cd
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/latch/1.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2020 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 <latch>
+
+#ifndef __cpp_lib_latch
+# error "Feature-test macro for latch missing in <latch>"
+#elif __cpp_lib_latch!= 201907L
+# error "Feature-test macro for latch has wrong value in <latch>"
+#endif
diff --git a/libstdc++-v3/testsuite/30_threads/latch/2.cc b/libstdc++-v3/testsuite/30_threads/latch/2.cc
new file mode 100644
index 0000000..318a859
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/latch/2.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2020 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_latch
+# error "Feature-test macro for latch missing in <version>"
+#elif __cpp_lib_latch != 201907L
+# error "Feature-test macro for latch has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/30_threads/latch/3.cc b/libstdc++-v3/testsuite/30_threads/latch/3.cc
new file mode 100644
index 0000000..70f2d18
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/latch/3.cc
@@ -0,0 +1,69 @@
+// Copyright (C) 2020 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 } }
+// { dg-require-gthreads "" }
+// { dg-additional-options "-pthread" { target pthread } }
+
+#include <latch>
+#include <atomic>
+#include <thread>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ std::latch l(3);
+
+ VERIFY( !l.try_wait() );
+
+ auto fn = [&]
+ {
+ l.count_down();
+ };
+
+ std::thread t0(fn);
+ std::thread t1(fn);
+
+ l.arrive_and_wait();
+ t0.join();
+ t1.join();
+
+ VERIFY( l.try_wait() );
+}
+
+void
+test02()
+{
+ std::latch l(3);
+ std::thread t([&]
+ {
+ l.count_down();
+ });
+
+ l.arrive_and_wait(2);
+ t.join();
+ VERIFY( l.try_wait() );
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/1.cc b/libstdc++-v3/testsuite/30_threads/semaphore/1.cc
new file mode 100644
index 0000000..1bbca68
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/1.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2020 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 <semaphore>
+
+#ifndef __cpp_lib_semaphore
+# error "Feature-test macro for semaphore missing in <semaphore>"
+#elif __cpp_lib_semaphore != 201907L
+# error "Feature-test macro for semaphore has wrong value in <semaphore>"
+#endif
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/2.cc b/libstdc++-v3/testsuite/30_threads/semaphore/2.cc
new file mode 100644
index 0000000..98743f5
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/2.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2020 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_semaphore
+# error "Feature-test macro for semaphore missing in <version>"
+#elif __cpp_lib_semaphore != 201907L
+# error "Feature-test macro for semaphore has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/least_max_value_neg.cc b/libstdc++-v3/testsuite/30_threads/semaphore/least_max_value_neg.cc
new file mode 100644
index 0000000..d74cfad
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/least_max_value_neg.cc
@@ -0,0 +1,30 @@
+// Copyright (C) 2020 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 } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+
+#include <semaphore>
+
+int main()
+{
+ std::counting_semaphore<-1> sem(2);
+ return 0;
+}
+// { dg-error "static assertion failed" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire.cc b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire.cc
new file mode 100644
index 0000000..2528044
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire.cc
@@ -0,0 +1,55 @@
+// Copyright (C) 2020 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 -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+
+#include <semaphore>
+#include <limits>
+#include <cstddef>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ std::counting_semaphore<10> s(3);
+
+ s.acquire();
+ VERIFY( s.try_acquire() );
+ VERIFY( s.try_acquire() );
+ VERIFY( !s.try_acquire() );
+ s.release();
+ VERIFY( s.try_acquire() );
+}
+
+void test02()
+{
+ std::binary_semaphore s(1);
+
+ s.acquire();
+ VERIFY( !s.try_acquire() );
+ s.release();
+ VERIFY( s.try_acquire() );
+}
+
+
+int main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_for.cc b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_for.cc
new file mode 100644
index 0000000..3f450e7
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_for.cc
@@ -0,0 +1,85 @@
+// Copyright (C) 2020 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 -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+
+#include <semaphore>
+#include <chrono>
+#include <thread>
+#include <atomic>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ using namespace std::chrono_literals;
+ std::counting_semaphore<10> s(2);
+ s.acquire();
+
+ auto const dur = 250ms;
+ {
+ auto const t0 = std::chrono::steady_clock::now();
+ VERIFY( s.try_acquire_for(dur) );
+ auto const diff = std::chrono::steady_clock::now() - t0;
+ VERIFY( diff < dur );
+ }
+
+ {
+ auto const t0 = std::chrono::steady_clock::now();
+ VERIFY( !s.try_acquire_for(dur) );
+ auto const diff = std::chrono::steady_clock::now() - t0;
+ VERIFY( diff >= dur );
+ }
+}
+
+void test02()
+{
+ using namespace std::chrono_literals;
+ std::binary_semaphore s(1);
+ std::atomic<int> a(0), b(0);
+ std::thread t([&] {
+ a.wait(0);
+ auto const dur = 250ms;
+ VERIFY( !s.try_acquire_for(dur) );
+ b++;
+ b.notify_one();
+
+ a.wait(1);
+ VERIFY( s.try_acquire_for(dur) );
+ b++;
+ b.notify_one();
+ });
+ t.detach();
+
+ s.acquire();
+ a++;
+ a.notify_one();
+ b.wait(0);
+ s.release();
+ a++;
+ a.notify_one();
+
+ b.wait(1);
+}
+
+int main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_posix.cc b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_posix.cc
new file mode 100644
index 0000000..13bd748
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_posix.cc
@@ -0,0 +1,153 @@
+// Copyright (C) 2020 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 -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+
+#include <semaphore>
+#ifdef _GLIBCXX_HAVE_POSIX_SEMAPHORE
+#include <chrono>
+#include <thread>
+#include <atomic>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ using namespace std::chrono_literals;
+ std::__platform_semaphore s(2);
+ s._M_acquire();
+
+ auto const dur = 250ms;
+ {
+ auto const t0 = std::chrono::steady_clock::now();
+ VERIFY( s._M_try_acquire_for(dur) );
+ auto const diff = std::chrono::steady_clock::now() - t0;
+ VERIFY( diff < dur );
+ }
+
+ {
+ auto const t0 = std::chrono::steady_clock::now();
+ VERIFY( !s._M_try_acquire_for(dur) );
+ auto const diff = std::chrono::steady_clock::now() - t0;
+ VERIFY( diff >= dur );
+ }
+}
+
+void test02()
+{
+ using namespace std::chrono_literals;
+ std::__platform_semaphore s(1);
+ std::atomic<int> a(0), b(0);
+ std::thread t([&] {
+ a.wait(0);
+ auto const dur = 250ms;
+ VERIFY( !s._M_try_acquire_for(dur) );
+ b++;
+ b.notify_one();
+
+ a.wait(1);
+ VERIFY( s._M_try_acquire_for(dur) );
+ b++;
+ b.notify_one();
+ });
+ t.detach();
+
+ s._M_acquire();
+ a++;
+ a.notify_one();
+ b.wait(0);
+ s._M_release(1);
+ a++;
+ a.notify_one();
+
+ b.wait(1);
+}
+
+void test03()
+{
+ using namespace std::chrono_literals;
+ std::__platform_semaphore s(2);
+ s._M_acquire();
+
+ auto const dur = 250ms;
+ {
+ auto const at = std::chrono::system_clock::now() + dur;
+ auto const t0 = std::chrono::steady_clock::now();
+ VERIFY( s._M_try_acquire_until(at) );
+ auto const diff = std::chrono::steady_clock::now() - t0;
+ VERIFY( diff < dur );
+ }
+
+ {
+ auto const at = std::chrono::system_clock::now() + dur;
+ auto const t0 = std::chrono::steady_clock::now();
+ VERIFY( !s._M_try_acquire_until(at) );
+ auto const diff = std::chrono::steady_clock::now() - t0;
+ VERIFY( diff >= dur );
+ }
+}
+
+void test04()
+{
+ using namespace std::chrono_literals;
+ std::__platform_semaphore s(1);
+ std::atomic<int> a(0), b(0);
+ std::thread t([&] {
+ a.wait(0);
+ auto const dur = 250ms;
+ {
+ auto const at = std::chrono::system_clock::now() + dur;
+ VERIFY( !s._M_try_acquire_until(at) );
+
+ b++;
+ b.notify_one();
+ }
+
+ a.wait(1);
+ {
+ auto const at = std::chrono::system_clock::now() + dur;
+ VERIFY( s._M_try_acquire_until(at) );
+ }
+ b++;
+ b.notify_one();
+ });
+ t.detach();
+
+ s._M_acquire();
+ a++;
+ a.notify_one();
+ b.wait(0);
+ s._M_release(1);
+ a++;
+ a.notify_one();
+
+ b.wait(1);
+}
+#endif
+
+int main()
+{
+#ifdef _GLIBCXX_HAVE_POSIX_SEMAPHORE
+ test01();
+ test02();
+ test03();
+ test04();
+#endif
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc
new file mode 100644
index 0000000..58f68ce
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc
@@ -0,0 +1,94 @@
+// Copyright (C) 2020 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 } }
+// { dg-require-gthreads "" }
+// { dg-additional-options "-pthread" { target pthread } }
+
+#include <semaphore>
+#include <chrono>
+#include <thread>
+#include <atomic>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ using namespace std::chrono_literals;
+ std::counting_semaphore<10> s(2);
+ s.acquire();
+
+ auto const dur = 250ms;
+ {
+ auto const at = std::chrono::system_clock::now() + dur;
+ auto const t0 = std::chrono::steady_clock::now();
+ VERIFY( s.try_acquire_until(at) );
+ auto const diff = std::chrono::steady_clock::now() - t0;
+ VERIFY( diff < dur );
+ }
+
+ {
+ auto const at = std::chrono::system_clock::now() + dur;
+ auto const t0 = std::chrono::steady_clock::now();
+ VERIFY( !s.try_acquire_until(at) );
+ auto const diff = std::chrono::steady_clock::now() - t0;
+ VERIFY( diff >= dur );
+ }
+}
+
+void test02()
+{
+ using namespace std::chrono_literals;
+ std::binary_semaphore s(1);
+ std::atomic<int> a(0), b(0);
+ std::thread t([&] {
+ a.wait(0);
+ auto const dur = 250ms;
+ {
+ auto const at = std::chrono::system_clock::now() + dur;
+ VERIFY( !s.try_acquire_until(at) );
+
+ b++;
+ b.notify_one();
+ }
+
+ a.wait(1);
+ {
+ auto const at = std::chrono::system_clock::now() + dur;
+ VERIFY( s.try_acquire_until(at) );
+ }
+ b++;
+ b.notify_one();
+ });
+ t.detach();
+
+ s.acquire();
+ a++;
+ a.notify_one();
+ b.wait(0);
+ s.release();
+ a++;
+ a.notify_one();
+
+ b.wait(1);
+}
+
+int main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/30_threads/this_thread/95989.cc b/libstdc++-v3/testsuite/30_threads/this_thread/95989.cc
new file mode 100644
index 0000000..16535af
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/this_thread/95989.cc
@@ -0,0 +1,51 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+// { dg-require-gthreads {} }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-additional-options "-static" { target static } }
+
+#include <thread>
+#include <testsuite_hooks.h>
+
+__attribute__((noinline,noipa))
+void
+join(std::thread& t)
+{
+ if (!t.joinable())
+ return;
+
+ // Using thread::join() creates a dependency on libpthread symbols
+ // so that __gthread_active_p is true, and we use pthread_self.
+ t.join();
+}
+
+void
+test01()
+{
+ std::thread t;
+ // PR libstdc++/95989
+ auto id = std::this_thread::get_id();
+ VERIFY (t.get_id() != id );
+}
+
+int
+main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/operations/absolute.cc b/libstdc++-v3/testsuite/experimental/filesystem/operations/absolute.cc
index 5c9627f..8b9fb73 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/operations/absolute.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/operations/absolute.cc
@@ -30,7 +30,7 @@ using std::experimental::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
#if defined(__MINGW32__) || defined(__MINGW64__)
if (p.empty())
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/assign/copy.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/assign/copy.cc
index 2f79360..09e2fd6 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/assign/copy.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/assign/copy.cc
@@ -28,7 +28,7 @@ using __gnu_test::compare_paths;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path copy;
copy = p;
@@ -39,7 +39,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path copy = p;
path move;
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/compare/path.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/compare/path.cc
index 5228d0a..66606f7 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/compare/path.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/compare/path.cc
@@ -31,7 +31,7 @@ void
test01()
{
const path p0 = "/a/a/b/b";
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.compare(p) == 0 );
int cmp = p.compare(p0);
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/construct/copy.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/construct/copy.cc
index f075ba6..50a00c5 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/construct/copy.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/construct/copy.cc
@@ -29,7 +29,7 @@ using std::experimental::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path copy = p;
__gnu_test::compare_paths(p, copy);
@@ -39,7 +39,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path copy = p;
path move = std::move(copy);
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/extension.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/extension.cc
index 2d0b088..0c5b5f4 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/extension.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/extension.cc
@@ -44,7 +44,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
auto stem = p.stem();
auto ext = p.extension();
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/filename.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/filename.cc
index 066d7dc..a6a7b8d 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/filename.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/filename.cc
@@ -39,7 +39,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path f = p.filename();
if (p.empty())
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/parent_path.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/parent_path.cc
index 3f12fad..bd3961a 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/parent_path.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/parent_path.cc
@@ -43,7 +43,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
if (p.begin() == p.end())
continue;
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/relative_path.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/relative_path.cc
index 43b5091..14221de 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/relative_path.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/relative_path.cc
@@ -41,7 +41,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
bool after_root = false;
const path prel = p.relative_path();
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/root_directory.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/root_directory.cc
index bbb5009..ffc4839 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/root_directory.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/root_directory.cc
@@ -43,7 +43,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path rootdir = p.root_directory();
// If root-directory is composed of 'slash name',
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/root_path.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/root_path.cc
index dfd2cb0..7ffd526 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/root_path.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/decompose/root_path.cc
@@ -39,7 +39,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path rootp = p.root_path();
path rootn = p.root_name();
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/itr/traversal.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/itr/traversal.cc
index 83ee78b..c148177 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/itr/traversal.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/itr/traversal.cc
@@ -69,7 +69,7 @@ test02()
using reverse_iterator = std::reverse_iterator<path::iterator>;
std::vector<path> fwd, rev;
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
const auto begin = p.begin(), end = p.end();
fwd.assign(begin, end);
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/modifiers/remove_filename.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/modifiers/remove_filename.cc
index 0537bf4..5186c3d 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/modifiers/remove_filename.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/modifiers/remove_filename.cc
@@ -37,7 +37,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path p2(p);
p2.remove_filename();
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/modifiers/replace_extension.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/modifiers/replace_extension.cc
index 5053c72..b098454 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/modifiers/replace_extension.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/modifiers/replace_extension.cc
@@ -38,7 +38,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path p2 = p;
VERIFY(p2.replace_extension(p2.extension()) == p);
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/modifiers/replace_filename.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/modifiers/replace_filename.cc
index 1d063b6..858ecd9 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/modifiers/replace_filename.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/modifiers/replace_filename.cc
@@ -37,7 +37,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path p2(p);
p2.replace_filename(p.filename());
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/nonmember/hash_value.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/nonmember/hash_value.cc
index 6853491..931727f 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/nonmember/hash_value.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/nonmember/hash_value.cc
@@ -37,7 +37,7 @@ test01()
void
test02()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
path pp = p.native();
VERIFY( hash_value(p) == hash_value(pp) );
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_extension.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_extension.cc
index 3041e10..031bc82 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_extension.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_extension.cc
@@ -30,7 +30,7 @@ using std::experimental::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.has_extension() == !p.extension().empty() );
}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_filename.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_filename.cc
index 5fa4c6e..5ad1e3d 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_filename.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_filename.cc
@@ -30,7 +30,7 @@ using std::experimental::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.has_filename() == !p.filename().empty() );
}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_parent_path.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_parent_path.cc
index 5a16cf2..99d0b77 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_parent_path.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_parent_path.cc
@@ -30,7 +30,7 @@ using std::experimental::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.has_parent_path() == !p.parent_path().empty() );
}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_relative_path.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_relative_path.cc
index 8674bda..fa58a81 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_relative_path.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_relative_path.cc
@@ -30,7 +30,7 @@ using std::experimental::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.has_relative_path() == !p.relative_path().empty() );
}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_root_directory.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_root_directory.cc
index 262d7a4..930c9cb 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_root_directory.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_root_directory.cc
@@ -30,7 +30,7 @@ using std::experimental::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.has_root_directory() == !p.root_directory().empty() );
}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_root_name.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_root_name.cc
index 05cc306..951a746 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_root_name.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_root_name.cc
@@ -30,7 +30,7 @@ using std::experimental::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.has_root_name() == !p.root_name().empty() );
}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_root_path.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_root_path.cc
index bd77193..501fc82 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_root_path.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_root_path.cc
@@ -30,7 +30,7 @@ using std::experimental::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.has_root_path() == !p.root_path().empty() );
}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_stem.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_stem.cc
index acb70d9..103aff0 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_stem.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/query/has_stem.cc
@@ -30,7 +30,7 @@ using std::experimental::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.has_stem() == !p.stem().empty() );
}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/query/is_relative.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/query/is_relative.cc
index 6071400..86a60c6 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/query/is_relative.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/query/is_relative.cc
@@ -30,7 +30,7 @@ using std::experimental::filesystem::path;
void
test01()
{
- for (const path& p : __gnu_test::test_paths)
+ for (const path p : __gnu_test::test_paths)
{
VERIFY( p.is_relative() == !p.is_absolute() );
}
diff --git a/libstdc++-v3/testsuite/ext/stdio_filebuf/char/79820.cc b/libstdc++-v3/testsuite/ext/stdio_filebuf/char/79820.cc
index c9842d6..aaa398c 100644
--- a/libstdc++-v3/testsuite/ext/stdio_filebuf/char/79820.cc
+++ b/libstdc++-v3/testsuite/ext/stdio_filebuf/char/79820.cc
@@ -26,10 +26,11 @@ void
test01()
{
FILE* f = std::fopen("79820.txt", "w");
- std::fclose(f);
errno = 127;
__gnu_cxx::stdio_filebuf<char> b(f, std::ios::out, BUFSIZ);
VERIFY(errno == 127); // PR libstdc++/79820
+ b.close();
+ std::fclose(f);
}
int
diff --git a/libstdc++-v3/testsuite/lib/dg-options.exp b/libstdc++-v3/testsuite/lib/dg-options.exp
index d3f61cb..0102acf 100644
--- a/libstdc++-v3/testsuite/lib/dg-options.exp
+++ b/libstdc++-v3/testsuite/lib/dg-options.exp
@@ -257,13 +257,14 @@ proc add_options_for_net_ts { flags } {
return $flags
}
-# Add to FLAGS all the target-specific flags to link to libatomic, if required.
+# Add to FLAGS all the target-specific flags to link to libatomic,
+# if required for atomics on pointers and 64-bit types.
proc add_options_for_libatomic { flags } {
if { [istarget hppa*-*-hpux*]
- || [istarget powerpc-ibm-aix*]
- || [istarget powerpc*-*-darwin*]
- || [istarget riscv*-*-*] } {
+ || ([istarget powerpc*-*-*] && [check_effective_target_ilp32])
+ || [istarget riscv*-*-*]
+ } {
return "$flags -L../../libatomic/.libs -latomic"
}
return $flags
diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
index fc1e8f2..35817a8 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -246,7 +246,10 @@ proc libstdc++_init { testfile } {
}
# Set the default timeout for v3 tests.
- set tool_timeout 600
+ # You can override this in ~/.dejagnurc or a .exp file named by $DEJAGNU.
+ if {![info exists tool_timeout]} {
+ set tool_timeout 360
+ }
# Default settings.
set cxx [transform "g++"]
@@ -942,85 +945,97 @@ proc check_v3_target_namedlocale { args } {
}]
}
-proc check_v3_target_debug_mode { } {
- return [check_v3_target_prop_cached et_debug_mode {
- global tool
- # Set up and preprocess a C++ test program that depends
- # on debug mode activated.
- set src debug_mode[pid].cc
+# Returns 1 if the tokens in CODE can be preprocessed successfully using FLAGS,
+# returns 0 otherwise.
+proc v3_try_preprocess { name code flags } {
+ global tool
+ global cxxflags
- set f [open $src "w"]
- puts $f "#ifndef _GLIBCXX_DEBUG"
- puts $f "# error No debug mode"
- puts $f "#endif"
- close $f
+ # Set up and preprocess a C++ translation unit.
+ set src $name[pid].cc
- set lines [v3_target_compile $src /dev/null preprocess ""]
- file delete $src
+ set f [open $src "w"]
+ puts $f $code
+ close $f
- if [string match "" $lines] {
- # No error message, preprocessing succeeded.
- return 1
- }
- return 0
- }]
+ set cxxflags_saved $cxxflags
+ set cxxflags "$flags"
+
+ set lines [v3_target_compile $src /dev/null preprocess ""]
+ set cxxflags $cxxflags_saved
+ file delete $src
+
+ if [string match "" $lines] {
+ verbose "v3_try_preprocess $name: preprocessing passed" 3
+ # No error message, preprocessing succeeded.
+ return 1
+ }
+ verbose "v3_try_preprocess $name: preprocessing failed" 2
+ return 0
}
-proc check_v3_target_normal_mode { } {
- return [check_v3_target_prop_cached et_normal_mode {
- global tool
- # Set up and compile a C++ test program that depends
- # on normal mode activated.
- set src normal_mode[pid].cc
+# Return 1 if COND evaluates to true in the preprocessor, 0 otherwise.
+# The <bits/c++config.h> config header is included.
+proc v3_check_preprocessor_condition { name cond } {
+ global cxxflags
+ global DEFAULT_CXXFLAGS
- set f [open $src "w"]
- puts $f "#include <bits/c++config.h>"
- puts $f "#if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL)"
- puts $f "# error No normal mode"
- puts $f "#endif"
- close $f
+ set code "
+ #include <bits/c++config.h>
+ #if ! ($cond)
+ #error '$cond' is false
+ #endif
+ "
+ set flags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
- set lines [v3_target_compile $src /dev/null preprocess ""]
- file delete $src
+ return [v3_try_preprocess name $code $flags]
+}
- if [string match "" $lines] {
- # No error message, compilation succeeded.
- return 1
- }
- return 0
+# Return 1 if Debug Mode is active, 0 otherwise.
+proc check_v3_target_debug_mode { } {
+ global cxxflags
+ return [check_v3_target_prop_cached et_debug_mode {
+ set code "
+ #if ! defined _GLIBCXX_DEBUG
+ # error no debug mode
+ #endif
+ "
+ return [v3_try_preprocess debug_mode $code $cxxflags]
}]
}
+# Return 1 if normal mode is active, 0 otherwise.
+# i.e. neither Debug Mode nor Parallel Mode is active.
+proc check_v3_target_normal_mode { } {
+ global cxxflags
+ return [check_v3_target_prop_cached et_normal_mode {
+ set code "
+ #if defined _GLIBCXX_DEBUG
+ # error debug mode
+ #endif
+ #if defined _GLIBCXX_PARALLEL
+ # error parallel mode
+ #endif
+ "
+ return [v3_try_preprocess normal_mode $code $cxxflags]
+ }]
+}
+
+# Return 1 if unversioned namespace is in use, 0 otherwise.
+# i.e. the library uses namespace std:: not std::__8:: or similar.
proc check_v3_target_normal_namespace { } {
return [check_v3_target_prop_cached et_normal_namespace {
- global tool
- # Set up and compile a C++ test program that depends
- # on normal std namespace.
- set src normal_namespace[pid].cc
-
- set f [open $src "w"]
- puts $f "#include <bits/c++config.h>"
- puts $f "#if _GLIBCXX_INLINE_VERSION"
- puts $f "# error No normal namespace"
- puts $f "#endif"
- close $f
-
- set lines [v3_target_compile $src /dev/null preprocess ""]
- file delete $src
-
- if [string match "" $lines] {
- # No error message, compilation succeeded.
- return 1
- }
- return 0
+ set cond "!_GLIBCXX_INLINE_VERSION"
+ return [v3_check_preprocessor_condition normal_namespace $cond]
}]
}
+# Return 1 if the libgomp is being used, 0 otherwise.
proc check_v3_target_parallel_mode { } {
return [check_v3_target_prop_cached et_parallel_mode {
global cxxflags
global v3-libgomp
- # If 'make check-parallel' is running the test succeeds.
+ # If 'make check-parallel' is running then the test succeeds.
if { ${v3-libgomp} == 1 && [regexp "libgomp" $cxxflags] } {
return 1
}
@@ -1028,67 +1043,19 @@ proc check_v3_target_parallel_mode { } {
}]
}
+# Return 1 if the C99 stdint facilities are available, 0 otherwise.
proc check_v3_target_cstdint { } {
return [check_v3_target_prop_cached et_cstdint {
- global DEFAULT_CXXFLAGS
- global cxxflags
- # Set up and preprocess a C++0x test program that depends
- # on the C99 stdint facilities to be available.
- set src cstdint[pid].cc
-
- set f [open $src "w"]
- puts $f "#include <tr1/cstdint>"
- puts $f "#ifndef _GLIBCXX_USE_C99_STDINT_TR1"
- puts $f "# error No C99 stdint"
- puts $f "#endif"
- close $f
-
- set cxxflags_saved $cxxflags
- set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
-
- set lines [v3_target_compile $src /dev/null preprocess ""]
- set cxxflags $cxxflags_saved
- file delete $src
-
- if [string match "" $lines] {
- # No error message, preprocess succeeded.
- return 1
- } else {
- verbose "check_v3_target_cstdint: compilation failed" 2
- return 0
- }
+ set cond "defined _GLIBCXX_USE_C99_STDINT_TR1"
+ return [v3_check_preprocessor_condition cstdint $cond]
}]
}
+# Return 1 if the C99 math facilities are available, 0 otherwise.
proc check_v3_target_cmath { } {
return [check_v3_target_prop_cached et_c99_math {
- global cxxflags
- global DEFAULT_CXXFLAGS
- # Set up and preprocess a C++0x test program that depends
- # on the C99 math facilities to be available.
- set src c99_math[pid].cc
-
- set f [open $src "w"]
- puts $f "#include <tr1/cmath>"
- puts $f "#ifndef _GLIBCXX_USE_C99_MATH_TR1"
- puts $f "# error No C99 math"
- puts $f "#endif"
- close $f
-
- set cxxflags_saved $cxxflags
- set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
-
- set lines [v3_target_compile $src /dev/null preprocess ""]
- set cxxflags $cxxflags_saved
- file delete $src
-
- if [string match "" $lines] {
- # No error message, preprocess succeeded.
- return 1
- } else {
- verbose "check_v3_target_c99_math: compilation failed" 2
- return 0
- }
+ set cond "defined _GLIBCXX_USE_C99_MATH_TR1"
+ return [v3_check_preprocessor_condition cmath $cond]
}]
}
@@ -1097,15 +1064,16 @@ proc check_v3_target_thread_fence { } {
global cxxflags
global DEFAULT_CXXFLAGS
- # Set up and preprocess a C++11 test program that depends
+ # Set up and link a C++11 test program that depends
# on the thread fence to be available.
set src thread_fence[pid].cc
set f [open $src "w"]
- puts $f "int main() {"
- puts $f "__atomic_thread_fence (__ATOMIC_SEQ_CST);"
- puts $f "return 0;"
- puts $f "}"
+ puts $f "
+ int main() {
+ __atomic_thread_fence (__ATOMIC_SEQ_CST);
+ return 0;
+ }"
close $f
set cxxflags_saved $cxxflags
@@ -1125,309 +1093,106 @@ proc check_v3_target_thread_fence { } {
}]
}
+# Return 1 if atomics_bool and atomic_int are always lock-free, 0 otherwise.
proc check_v3_target_atomic_builtins { } {
return [check_v3_target_prop_cached et_atomic_builtins {
- global cxxflags
- global DEFAULT_CXXFLAGS
-
- # Set up and preprocess a C++11 test program that depends
- # on the atomic builtin facilities to be available.
- set src atomic_builtins[pid].cc
-
- set f [open $src "w"]
- puts $f "#if __GCC_ATOMIC_BOOL_LOCK_FREE < 2"
- puts $f "# error No atomic bool"
- puts $f "#endif"
- puts $f "#if __GCC_ATOMIC_INT_LOCK_FREE < 2"
- puts $f "# error No atomic int"
- puts $f "#endif"
- close $f
-
- set cxxflags_saved $cxxflags
- set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror -std=gnu++11"
-
- set lines [v3_target_compile $src /dev/null preprocess ""]
- set cxxflags $cxxflags_saved
- file delete $src
-
- if [string match "" $lines] {
- # No error message, preprocess succeeded.
- return 1
- } else {
- verbose "check_v3_target_atomic_builtins: compilation failed" 2
- return 0
- }
+ set cond "__GCC_ATOMIC_BOOL_LOCK_FREE > 1 && __GCC_ATOMIC_INT_LOCK_FREE > 1"
+ return [v3_check_preprocessor_condition atomic_builtins $cond]
}]
}
+# Define "atomic-builtins" as an effective-target keyword.
+proc check_effective_target_atomic-builtins { } {
+ return [check_v3_target_atomic_builtins]
+}
+
+# Return 1 if C++11 [threads] facilities are available via gthreads,
+# 0 otherwise.
proc check_v3_target_gthreads { } {
return [check_v3_target_prop_cached et_gthreads {
- global cxxflags
- global DEFAULT_CXXFLAGS
-
- # Set up and preprocess a C++0x test program that depends
- # on the gthreads facilities to be available.
- set src gthreads[pid].cc
-
- set f [open $src "w"]
- puts $f "#include <bits/c++config.h>"
- puts $f "#ifndef _GLIBCXX_HAS_GTHREADS"
- puts $f "# error No gthread"
- puts $f "#endif"
- close $f
-
- set cxxflags_saved $cxxflags
- set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
-
- set lines [v3_target_compile $src /dev/null preprocess ""]
- set cxxflags $cxxflags_saved
- file delete $src
-
- if [string match "" $lines] {
- # No error message, preprocessing succeeded.
- return 1
- } else {
- verbose "check_v3_target_gthreads: compilation failed" 2
- return 0
- }
+ set cond "defined _GLIBCXX_HAS_GTHREADS"
+ return [v3_check_preprocessor_condition gthreads $cond]
}]
}
+# Define "gthreads" as an effective-target keyword.
+proc check_effective_target_gthreads { } {
+ return [check_v3_target_gthreads]
+}
+
+# Return 1 if C++11 timed mutexes are available via gthreads, 0 otherwise.
proc check_v3_target_gthreads_timed { } {
return [check_v3_target_prop_cached et_gthreads_timed {
- global cxxflags
- global DEFAULT_CXXFLAGS
- # Set up and preprocess a C++0x test program that depends
- # on the gthreads timed mutex facilities to be available.
- set src gthreads_timed[pid].cc
-
- set f [open $src "w"]
- puts $f "#include <bits/c++config.h>"
- puts $f "#ifndef _GLIBCXX_HAS_GTHREADS"
- puts $f "# error No gthread"
- puts $f "#endif"
- puts $f "#if !_GTHREAD_USE_MUTEX_TIMEDLOCK"
- puts $f "# error No gthread timed mutexes"
- puts $f "#endif"
- close $f
-
- set cxxflags_saved $cxxflags
- set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
-
- set lines [v3_target_compile $src /dev/null preprocess ""]
- set cxxflags $cxxflags_saved
- file delete $src
-
- if [string match "" $lines] {
- # No error message, preprocessing succeeded.
- return 1
+ if [check_v3_target_gthreads] {
+ set cond "defined _GTHREAD_USE_MUTEX_TIMEDLOCK"
+ return [v3_check_preprocessor_condition gthreads_timed $cond]
} else {
- verbose "check_v3_target_gthreads_timed: compilation failed" 2
return 0
}
}]
}
+# Define "gthreads-timed" as an effective-target keyword.
+proc check_effective_target_gthreads-timed { } {
+ return [check_v3_target_gthreads_timed]
+}
+
+# Return 1 if either nanosleep or sleep is available, 0 otherwise.
proc check_v3_target_sleep { } {
return [check_v3_target_prop_cached et_sleep {
- global cxxflags
- global DEFAULT_CXXFLAGS
- # Set up and preprocess a C++11 test program that depends
- # on the sleep facilities to be available.
- set src sleep[pid].cc
-
- set f [open $src "w"]
- puts $f "#include <bits/c++config.h>"
- puts $f "#ifndef _GLIBCXX_USE_NANOSLEEP"
- puts $f "# ifndef _GLIBCXX_HAVE_SLEEP"
- puts $f "# error No nanosleep or sleep"
- puts $f "# endif"
- puts $f "#endif"
- close $f
-
- set cxxflags_saved $cxxflags
- set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
-
- set lines [v3_target_compile $src /dev/null preprocess ""]
- set cxxflags $cxxflags_saved
- file delete $src
-
- if [string match "" $lines] {
- # No error message, preprocessing succeeded.
- return 1
- } else {
- verbose "check_v3_target_sleep: compilation failed" 2
- return 0
- }
+ set cond "defined _GLIBCXX_USE_NANOSLEEP || defined _GLIBCXX_HAVE_SLEEP"
+ return [v3_check_preprocessor_condition sleep $cond]
}]
}
+# Return 1 if __gthread_yield is available, 0 otherwise.
proc check_v3_target_sched_yield { } {
return [check_v3_target_prop_cached et_sched_yield {
- global cxxflags
- global DEFAULT_CXXFLAGS
-
- # Set up and preprocess a C++0x test program that depends
- # on the sched_yield facility to be available.
- set src sched_yield[pid].cc
-
- set f [open $src "w"]
- puts $f "#include <bits/c++config.h>"
- puts $f "#ifndef _GLIBCXX_USE_SCHED_YIELD"
- puts $f "# error No sched yield"
- puts $f "#endif"
- close $f
-
- set cxxflags_saved $cxxflags
- set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
-
- set lines [v3_target_compile $src /dev/null preprocess ""]
- set cxxflags $cxxflags_saved
- file delete $src
-
- if [string match "" $lines] {
- # No error message, preprocessing succeeded.
- return 1
- } else {
- verbose "check_v3_target_sched_yield: compilation failed" 2
- return 0
- }
+ set cond "defined _GLIBCXX_USE_SCHED_YIELD"
+ return [v3_check_preprocessor_condition sched_yield $cond]
}]
}
+# Return 1 if the [string.conversions] facilities are available, 0 otherwise.
proc check_v3_target_string_conversions { } {
return [check_v3_target_prop_cached et_string_conversions {
- global cxxflags
- global DEFAULT_CXXFLAGS
- # Set up and preprocess a C++0x test program that depends
- # on the string_conversions facilities to be available.
- set src string_conversions[pid].cc
-
- set f [open $src "w"]
- puts $f "#include <bits/c++config.h>"
- puts $f "#if !(_GLIBCXX_USE_C99_STDIO && _GLIBCXX_USE_C99_STDLIB && _GLIBCXX_USE_C99_WCHAR) || defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)"
- puts $f "# error No string conversions"
- puts $f "#endif"
- close $f
-
- set cxxflags_saved $cxxflags
- set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
-
- set lines [v3_target_compile $src /dev/null preprocess ""]
- set cxxflags $cxxflags_saved
- file delete $src
-
- if [string match "" $lines] {
- # No error message, preprocessing succeeded.
- return 1
- } else {
- verbose "check_v3_target_string_conversions: compilation failed" 2
- return 0
- }
+ set cond "_GLIBCXX_USE_C99_STDIO && _GLIBCXX_USE_C99_STDLIB"
+ set cond "$cond && _GLIBCXX_USE_C99_WCHAR"
+ set cond "$cond && !defined _GLIBCXX_HAVE_BROKEN_VSWPRINTF"
+ return [v3_check_preprocessor_condition string_conversions $cond]
}]
}
+# Return 1 if a standard-conforming swprintf is available, 0 otherwise.
proc check_v3_target_swprintf { } {
return [check_v3_target_prop_cached et_swprintf {
- global cxxflags
- global DEFAULT_CXXFLAGS
- # Set up and preprocess a C++0x test program that depends
- # on a standard swprintf function to be available.
- set src swprintf[pid].cc
-
- set f [open $src "w"]
- puts $f "#include <bits/c++config.h>"
- puts $f "#if defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)"
- puts $f "# error No swprintf"
- puts $f "#endif"
- close $f
-
- set cxxflags_saved $cxxflags
- set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
-
- set lines [v3_target_compile $src /dev/null preprocess ""]
- set cxxflags $cxxflags_saved
- file delete $src
-
- if [string match "" $lines] {
- # No error message, preprocessing succeeded.
- return 1
- } else {
- verbose "check_v3_target_swprintf: compilation failed" 2
- return 0
- }
+ set cond "! defined _GLIBCXX_HAVE_BROKEN_VSWPRINTF"
+ return [v3_check_preprocessor_condition swprintf $cond]
}]
}
+# Return 1 if text and binary I/O are the same, 0 otherwise.
proc check_v3_target_binary_io { } {
return [check_v3_target_prop_cached et_binary_io {
- global cxxflags
- global DEFAULT_CXXFLAGS
- # Set up and preprocess a C++0x test program that depends
- # on text and binary I/O being the same.
- set src binary_io[pid].cc
-
- set f [open $src "w"]
- puts $f "#include <bits/c++config.h>"
- puts $f "#if defined(_GLIBCXX_HAVE_DOS_BASED_FILESYSTEM)"
- puts $f "# error No binary io"
- puts $f "#endif"
- close $f
-
- set cxxflags_saved $cxxflags
- set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
-
- set lines [v3_target_compile $src /dev/null preprocess ""]
- set cxxflags $cxxflags_saved
- file delete $src
-
- if [string match "" $lines] {
- # No error message, preprocessing succeeded.
- return 1
- } else {
- verbose "check_v3_target_binary_io: compilation failed" 2
- return 0
- }
+ set cond "! defined _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM"
+ return [v3_check_preprocessor_condition binary_io $cond]
}]
}
+# Return 1 if get_nprocs or pthreads_num_processors_np or a suitable sysconf
+# is available, 0 otherwise.
proc check_v3_target_nprocs { } {
return [check_v3_target_prop_cached et_nprocs {
- global cxxflags
- global DEFAULT_CXXFLAGS
- # Set up and preprocess a C++0x test program that depends
- # on either get_nprocs or sysconf to be available.
- set src nprocs[pid].cc
-
- set f [open $src "w"]
- puts $f "#include <bits/c++config.h>"
- puts $f "#if defined(_GLIBCXX_USE_GET_NPROCS)"
- puts $f "#elif defined(_GLIBCXX_USE_PTHREADS_NUM_PROCESSORS_NP)"
- puts $f "#elif defined(_GLIBCXX_USE_SYSCTL_HW_NCPU)"
- puts $f "#elif defined(_GLIBCXX_USE_SC_NPROCESSORS_ONLN)"
- puts $f "#elif defined(_GLIBCXX_USE_SC_NPROC_ONLN)"
- puts $f "#else"
- puts $f "# error hardware_concurrency not implemented"
- puts $f "#endif"
- close $f
-
- set cxxflags_saved $cxxflags
- set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
-
- set lines [v3_target_compile $src /dev/null preprocess ""]
- set cxxflags $cxxflags_saved
- file delete $src
-
- if [string match "" $lines] {
- # No error message, preprocess succeeded.
- return 1
- } else {
- verbose "check_v3_target_nprocs: compilation failed" 2
- return 0
- }
+ set cond "defined _GLIBCXX_USE_GET_NPROCS"
+ set cond "$cond || defined _GLIBCXX_USE_PTHREADS_NUM_PROCESSORS_NP"
+ set cond "$cond || defined _GLIBCXX_USE_SYSCTL_HW_NCPU"
+ set cond "$cond || defined _GLIBCXX_USE_SC_NPROCESSORS_ONLN"
+ set cond "$cond || defined _GLIBCXX_USE_SC_NPROC_ONLN"
+ return [v3_check_preprocessor_condition nprocs $cond]
}]
}
+# Return 1 if linking with -static-libstdc++ works, 0 otherwise.
proc check_v3_target_static_libstdcxx { } {
return [check_v3_target_prop_cached et_static_libstdcxx {
global cxxflags
@@ -1463,32 +1228,7 @@ proc check_v3_target_static_libstdcxx { } {
}
proc check_v3_target_little_endian { } {
- return [check_v3_target_prop_cached et_little_endian {
- global cxxflags
- global DEFAULT_CXXFLAGS
- set src little_endian[pid].cc
-
- set f [open $src "w"]
- puts $f "#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__"
- puts $f "# error Not little endian"
- puts $f "#endif"
- close $f
-
- set cxxflags_saved $cxxflags
- set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
-
- set lines [v3_target_compile $src /dev/null preprocess ""]
- set cxxflags $cxxflags_saved
- file delete $src
-
- if [string match "" $lines] {
- # No error message, preprocessing succeeded.
- return 1
- } else {
- verbose "check_v3_target_little_endian: compilation failed" 2
- return 0
- }
- }]
+ return [check_effective_target_le]
}
# Return 1 if the Filesystem TS is supported, 0 otherwise.
@@ -1527,61 +1267,18 @@ proc check_v3_target_filesystem_ts { } {
# Any flags provided by RUNTESTFLAGS or a target board will be used here.
# Flags added in the test by dg-options or dg-add-options will not be used.
proc check_effective_target_cxx11-abi { } {
- global cxxflags
-
- # Set up and preprocess a C++ test program that depends
- # on the new ABI being enabled.
- set src cxx11_abi[pid].cc
-
- set f [open $src "w"]
- puts $f "#include <bits/c++config.h>"
- puts $f "#if ! _GLIBCXX_USE_CXX11_ABI"
- puts $f "# error old ABI in use"
- puts $f "#endif"
- close $f
-
- set lines [v3_target_compile $src /dev/null preprocess ""]
- file delete $src
-
- if [string match "" $lines] {
- # No error message, preprocessing succeeded.
- verbose "check_v3_cxx11_abi: `1'" 2
- return 1
- }
-
- verbose "check_v3_cxx11_abi: `0'" 2
- return 0
+ set cond "_GLIBCXX_USE_CXX11_ABI"
+ return [v3_check_preprocessor_condition cxx11_abi $cond]
}
-# Return 1 if std::random_device should be usable using the current flags, 0 otherwise.
+# Return 1 if std::random_device should be usable using the current flags,
+# 0 otherwise.
proc check_effective_target_random_device { } {
- global cxxflags
-
- # Set up and preprocess a C++ test program that depends
- # on std::random_device being usable.
- set src random_device[pid].cc
-
- set f [open $src "w"]
- puts $f "#include <bits/c++config.h>"
- puts $f "#if ! _GLIBCXX_USE_RANDOM_TR1"
- puts $f "# error No working std::random_device available"
- puts $f "#endif"
- close $f
-
- set lines [v3_target_compile $src /dev/null preprocess ""]
- file delete $src
-
- if [string match "" $lines] {
- # No error message, preprocessing succeeded.
- verbose "check_v3_random_device: `1'" 2
- return 1
- }
-
- verbose "check_v3_random_device: `0'" 2
- return 0
+ set cond "_GLIBCXX_USE_RANDOM_TR1"
+ return [v3_check_preprocessor_condition random_device $cond]
}
-# Return 1 if tbb parallel backend is available
+# Return 1 if tbb parallel backend is available, 0 otherwise.
proc check_effective_target_tbb-backend { } {
return [check_v3_target_prop_cached et_tbb {
# Set up and compile a C++ test program that depends on tbb
@@ -1613,6 +1310,14 @@ proc check_effective_target_tbb-backend { } {
}]
}
+# Return 1 if futex syscall is available
+proc check_effective_target_futex { } {
+ return [check_v3_target_prop_cached et_futex {
+ set cond "_GLIBCXX_HAVE_LINUX_FUTEX"
+ return [v3_check_preprocessor_condition futex $cond]
+ }]
+}
+
set additional_prunes ""
if { [info exists env(GCC_RUNTEST_PARALLELIZE_DIR)] \
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc
new file mode 100644
index 0000000..692d79f
--- /dev/null
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc
@@ -0,0 +1,39 @@
+// { dg-options "-g -O0 -lstdc++fs" }
+// { dg-do run { target c++11 } }
+// { dg-require-filesystem-ts "" }
+
+// Copyright (C) 2020 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 <experimental/filesystem>
+#include <iostream>
+
+int
+main()
+{
+ std::experimental::filesystem::path path0;
+// { dg-final { note-test path0 {experimental::filesystem::path ""} } }
+ std::experimental::filesystem::path path1("filename");
+// { dg-final { note-test path1 {experimental::filesystem::path "filename"} } }
+ std::experimental::filesystem::path path2("/dir/.");
+// { dg-final { note-test path2 {experimental::filesystem::path "/dir/." = {[root-directory] = "/", [1] = "dir", [2] = "."}} } }
+
+ std::cout << "\n";
+ return 0; // Mark SPOT
+}
+
+// { dg-final { gdb-test SPOT } }
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
index 4b44be5..9821d18 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
@@ -127,6 +127,37 @@ main()
vb.erase(vb.begin());
// { dg-final { regexp-test vb {std::(__debug::)?vector<bool> of length 5, capacity 128 = \\{true, true, false, false, true\\}} } }
+ std::vector<bool>::iterator vbIt = vb.begin();
+// { dg-final { note-test vbIt {true} } }
+ std::vector<bool>::iterator vbIt2 = ++vbIt;
+// { dg-final { note-test vbIt2 {true} } }
+ std::vector<bool>::iterator vbIt3 = ++vbIt;
+// { dg-final { note-test vbIt3 {false} } }
+ std::vector<bool>::iterator vbIt4 = ++vbIt;
+// { dg-final { note-test vbIt4 {false} } }
+ std::vector<bool>::iterator vbIt5 = ++vbIt;
+// { dg-final { note-test vbIt5 {true} } }
+
+ std::vector<bool>::const_iterator vbcIt = vb.begin();
+// { dg-final { note-test vbcIt {true} } }
+
+ std::vector<bool>::iterator vbIt0;
+// { dg-final { note-test vbIt0 {non-dereferenceable iterator for std::vector<bool>} } }
+
+ std::_Bit_reference br = *vb.begin();
+// { dg-final { note-test br {true} } }
+ std::_Bit_reference br2 = *vbIt2;
+// { dg-final { note-test br2 {true} } }
+ std::_Bit_reference br3 = *vbIt3;
+// { dg-final { note-test br3 {false} } }
+ std::_Bit_reference br4 = *vbIt4;
+// { dg-final { note-test br4 {false} } }
+ std::_Bit_reference br5 = *vbIt5;
+// { dg-final { note-test br5 {true} } }
+
+ std::_Bit_reference br0;
+// { dg-final { note-test br0 {invalid std::_Bit_reference} } }
+
__gnu_cxx::slist<int> sll;
sll.push_front(23);
sll.push_front(47);
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
index 0ebd80a..5195656 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
@@ -120,6 +120,37 @@ main()
vb.erase(vb.begin());
// { dg-final { regexp-test vb {std::(__debug::)?vector<bool> of length 5, capacity 128 = \\{true, true, false, false, true\\}} } }
+ std::vector<bool>::iterator vbIt = vb.begin();
+// { dg-final { note-test vbIt {true} } }
+ std::vector<bool>::iterator vbIt2 = ++vbIt;
+// { dg-final { note-test vbIt2 {true} } }
+ std::vector<bool>::iterator vbIt3 = ++vbIt;
+// { dg-final { note-test vbIt3 {false} } }
+ std::vector<bool>::iterator vbIt4 = ++vbIt;
+// { dg-final { note-test vbIt4 {false} } }
+ std::vector<bool>::iterator vbIt5 = ++vbIt;
+// { dg-final { note-test vbIt5 {true} } }
+
+ std::vector<bool>::const_iterator vbcIt = vb.cbegin();
+// { dg-final { note-test vbcIt {true} } }
+
+ std::vector<bool>::iterator vbIt0;
+// { dg-final { note-test vbIt0 {non-dereferenceable iterator for std::vector<bool>} } }
+
+ std::_Bit_reference br = *vb.begin();
+// { dg-final { note-test br {true} } }
+ std::_Bit_reference br2 = *vbIt2;
+// { dg-final { note-test br2 {true} } }
+ std::_Bit_reference br3 = *vbIt3;
+// { dg-final { note-test br3 {false} } }
+ std::_Bit_reference br4 = *vbIt4;
+// { dg-final { note-test br4 {false} } }
+ std::_Bit_reference br5 = *vbIt5;
+// { dg-final { note-test br5 {true} } }
+
+ std::_Bit_reference br0;
+// { dg-final { note-test br0 {invalid std::_Bit_reference} } }
+
__gnu_cxx::slist<int> sll;
sll.push_front(23);
sll.push_front(47);
diff --git a/libstdc++-v3/testsuite/performance/25_algorithms/inplace_merge.cc b/libstdc++-v3/testsuite/performance/25_algorithms/inplace_merge.cc
new file mode 100644
index 0000000..780c219
--- /dev/null
+++ b/libstdc++-v3/testsuite/performance/25_algorithms/inplace_merge.cc
@@ -0,0 +1,290 @@
+// Copyright (C) 2020 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 <vector>
+#include <algorithm>
+#include <cmath>
+
+#include <testsuite_new_operators.h>
+#include <testsuite_performance.h>
+
+const int max_size = 10000000;
+const int small_size = 200000;
+const int front_pivot_idx = 10000;
+int middle_pivot_idx = max_size / 2;
+int back_pivot_idx = max_size - front_pivot_idx;
+
+void bench(int mem_threshold, int pivot_index,
+ std::vector<int> revv,
+ std::vector<int> fwdv,
+ std::vector<int> wstv,
+ std::vector<int> rndv)
+{
+ using namespace __gnu_test;
+
+ time_counter time;
+ resource_counter resource;
+
+ set_new_limit(mem_threshold);
+
+ start_counters(time, resource);
+ std::inplace_merge(revv.begin(), revv.begin() + pivot_index, revv.end());
+ stop_counters(time, resource);
+
+ set_new_limit(~size_t(0));
+
+ report_performance(__FILE__, "reverse", time, resource);
+ clear_counters(time, resource);
+
+ set_new_limit(mem_threshold);
+
+ start_counters(time, resource);
+ std::inplace_merge(fwdv.begin(), fwdv.begin() + pivot_index, fwdv.end());
+ stop_counters(time, resource);
+
+ set_new_limit(~size_t(0));
+
+ report_performance(__FILE__, "forward", time, resource);
+ clear_counters(time, resource);
+
+ set_new_limit(mem_threshold);
+
+ start_counters(time, resource);
+ std::inplace_merge(wstv.begin(), wstv.begin() + pivot_index, wstv.end());
+ stop_counters(time, resource);
+
+ set_new_limit(~size_t(0));
+
+ report_performance(__FILE__, "worst", time, resource);
+ clear_counters(time, resource);
+
+ set_new_limit(mem_threshold);
+
+ start_counters(time, resource);
+ std::inplace_merge(rndv.begin(), rndv.begin() + pivot_index, rndv.end());
+ stop_counters(time, resource);
+
+ set_new_limit(~size_t(0));
+ report_performance(__FILE__, "random", time, resource);
+}
+
+void mem_bench(double mem_ratio,
+ const std::vector<int>& front_revv,
+ const std::vector<int>& middle_revv,
+ const std::vector<int>& back_revv,
+ const std::vector<int>& fwdv,
+ const std::vector<int>& front_wstv,
+ const std::vector<int>& middle_wstv,
+ const std::vector<int>& back_wstv,
+ const std::vector<int>& front_rndv,
+ const std::vector<int>& middle_rndv,
+ const std::vector<int>& back_rndv)
+{
+ using namespace __gnu_test;
+
+ time_counter time;
+ resource_counter resource;
+
+ int max_mem = (int)std::ceil(front_pivot_idx * mem_ratio) * sizeof(int);
+ start_counters(time, resource);
+ bench(max_mem, front_pivot_idx, front_revv, fwdv, front_wstv, front_rndv);
+ stop_counters(time, resource);
+ report_performance(__FILE__, "front pivot", time, resource);
+ clear_counters(time, resource);
+
+ max_mem = (int)std::ceil(middle_pivot_idx * mem_ratio) * sizeof(int);
+ start_counters(time, resource);
+ bench(max_mem, middle_pivot_idx, middle_revv, fwdv, middle_wstv, middle_rndv);
+ stop_counters(time, resource);
+ report_performance(__FILE__, "middle pivot", time, resource);
+ clear_counters(time, resource);
+
+ max_mem = (int)std::ceil(front_pivot_idx * mem_ratio) * sizeof(int);
+ start_counters(time, resource);
+ bench(max_mem, back_pivot_idx, back_revv, fwdv, back_wstv, back_rndv);
+ stop_counters(time, resource);
+ report_performance(__FILE__, "back pivot", time, resource);
+}
+
+void init_reverse(std::vector<int>& v, size_t pivot_index)
+{
+ int val = 0;
+ for (size_t i = pivot_index; i != v.size(); ++i)
+ v[i] = val++;
+ for (size_t i = 0; i != pivot_index; ++i)
+ v[i] = val++;
+}
+
+void init_forward(std::vector<int>& v)
+{
+ int val = 0;
+ for (size_t i = 0; i != v.size(); ++i)
+ v[i] = val++;
+}
+
+void init_worst(std::vector<int>& v, size_t pivot_index)
+{
+ int val = 0;
+ if (pivot_index + 1 > v.size() / 2)
+ {
+ for (size_t i = 0; i != pivot_index; val += 2, ++i)
+ v[i] = val;
+ val = 1;
+ }
+ else
+ {
+ for (size_t i = pivot_index; i != v.size(); val += 2, ++i)
+ v[i] = val;
+ val -= pivot_index * 2 + 1;
+ }
+
+ if (pivot_index + 1 > v.size() / 2)
+ for (size_t i = pivot_index; i != v.size(); val += 2, ++i)
+ v[i] = val;
+ else
+ for (size_t i = 0; i != pivot_index; val += 2, ++i)
+ v[i] = val;
+}
+
+void init_random(std::vector<int>& v)
+{
+ // a simple pseudo-random series which does not rely on rand() and friends
+ v[0] = 0;
+ for (size_t i = 1; i != v.size(); ++i)
+ v[i] = (v[i-1] + 110211473) * 745988807;
+}
+
+void reduce_size(std::vector<int>& front_v,
+ std::vector<int>& middle_v,
+ std::vector<int>& back_v)
+{
+ front_v.erase(front_v.begin() + front_pivot_idx,
+ front_v.end() - back_pivot_idx);
+ middle_v.erase(middle_v.begin() + small_size / 2,
+ middle_v.end() - small_size / 2);
+ back_v.erase(back_v.begin() + back_pivot_idx,
+ back_v.end() - front_pivot_idx);
+}
+
+int main()
+{
+ using namespace __gnu_test;
+
+ // No constraint to build vectors.
+ set_new_limit(~size_t(0));
+
+ std::vector<int> front_revv(max_size);
+ init_reverse(front_revv, front_pivot_idx);
+
+ std::vector<int> middle_revv(max_size);
+ init_reverse(middle_revv, middle_pivot_idx);
+
+ std::vector<int> back_revv(max_size);
+ init_reverse(back_revv, back_pivot_idx);
+
+ std::vector<int> fwdv(max_size);
+ init_forward(fwdv);
+
+ std::vector<int> front_wstv(max_size);
+ init_worst(front_wstv, front_pivot_idx);
+
+ std::vector<int> middle_wstv(max_size);
+ init_worst(middle_wstv, middle_pivot_idx);
+
+ std::vector<int> back_wstv(max_size);
+ init_worst(back_wstv, back_pivot_idx);
+
+ std::vector<int> front_rndv(max_size);
+ init_random(front_rndv);
+ std::vector<int> middle_rndv(front_rndv);
+ std::vector<int> back_rndv(front_rndv);
+
+ sort(front_rndv.begin(), front_rndv.begin() + front_pivot_idx);
+ sort(front_rndv.begin() + front_pivot_idx, front_rndv.end());
+
+ sort(middle_rndv.begin(), middle_rndv.begin() + middle_pivot_idx);
+ sort(middle_rndv.begin() + middle_pivot_idx, middle_rndv.end());
+
+ sort(back_rndv.begin(), back_rndv.begin() + back_pivot_idx);
+ sort(back_rndv.begin() + back_pivot_idx, back_rndv.end());
+
+ time_counter time;
+ resource_counter resource;
+
+ start_counters(time, resource);
+
+ // No limit.
+ mem_bench(1.0,
+ front_revv, middle_revv, back_revv,
+ fwdv,
+ front_wstv, middle_wstv, back_wstv,
+ front_rndv, middle_rndv, back_rndv);
+
+ stop_counters(time, resource);
+
+ report_performance(__FILE__, "bench 1 / 1 memory", time, resource);
+ clear_counters(time, resource);
+
+ start_counters(time, resource);
+
+ // Limit to the fourth.
+ mem_bench(1.0 / 4,
+ front_revv, middle_revv, back_revv,
+ fwdv,
+ front_wstv, middle_wstv, back_wstv,
+ front_rndv, middle_rndv, back_rndv);
+
+ stop_counters(time, resource);
+
+ report_performance(__FILE__, "bench 1 / 4 memory", time, resource);
+ clear_counters(time, resource);
+
+ start_counters(time, resource);
+
+ // Really limit allocation.
+ mem_bench(1.0 / 64,
+ front_revv, middle_revv, back_revv,
+ fwdv,
+ front_wstv, middle_wstv, back_wstv,
+ front_rndv, middle_rndv, back_rndv);
+
+ stop_counters(time, resource);
+
+ report_performance(__FILE__, "bench 1 /64 memory", time, resource);
+ clear_counters(time, resource);
+
+ middle_pivot_idx = small_size / 2;
+ back_pivot_idx = small_size - front_pivot_idx;
+ reduce_size(front_revv, middle_revv, back_revv);
+ fwdv.resize(small_size);
+ reduce_size(front_wstv, middle_wstv, back_wstv);
+ reduce_size(front_rndv, middle_rndv, back_rndv);
+
+ start_counters(time, resource);
+
+ // No memory.
+ mem_bench(0.0,
+ front_revv, middle_revv, back_revv,
+ fwdv,
+ front_wstv, middle_wstv, back_wstv,
+ front_rndv, middle_rndv, back_rndv);
+
+ stop_counters(time, resource);
+
+ report_performance(__FILE__, "bench 0 / 1 memory", time, resource);
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/performance/25_algorithms/stable_sort.cc b/libstdc++-v3/testsuite/performance/25_algorithms/stable_sort.cc
index 02b869d..fe52663 100644
--- a/libstdc++-v3/testsuite/performance/25_algorithms/stable_sort.cc
+++ b/libstdc++-v3/testsuite/performance/25_algorithms/stable_sort.cc
@@ -17,49 +17,107 @@
#include <vector>
#include <algorithm>
+
+#include <testsuite_new_operators.h>
#include <testsuite_performance.h>
-int main()
+const int max_size = 10000000;
+const int small_size = 200000;
+
+void bench(size_t mem_threshold,
+ std::vector<int> revv,
+ std::vector<int> fwdv,
+ std::vector<int> rndv)
{
using namespace __gnu_test;
time_counter time;
resource_counter resource;
- const int max_size = 10000000;
-
- std::vector<int> v(max_size);
-
- for (int i = 0; i < max_size; ++i)
- v[i] = -i;
+ set_new_limit(mem_threshold);
start_counters(time, resource);
- std::stable_sort(v.begin(), v.end());
+ std::stable_sort(revv.begin(), revv.end());
stop_counters(time, resource);
+ set_new_limit(~size_t(0));
report_performance(__FILE__, "reverse", time, resource);
clear_counters(time, resource);
- for (int i = 0; i < max_size; ++i)
- v[i] = i;
+ set_new_limit(mem_threshold);
start_counters(time, resource);
- std::stable_sort(v.begin(), v.end());
+ std::stable_sort(fwdv.begin(), fwdv.end());
stop_counters(time, resource);
+ set_new_limit(~size_t(0));
report_performance(__FILE__, "forwards", time, resource);
clear_counters(time, resource);
- // a simple psuedo-random series which does not rely on rand() and friends
- v[0] = 0;
+ start_counters(time, resource);
+ std::stable_sort(rndv.begin(), rndv.end());
+ stop_counters(time, resource);
+
+ set_new_limit(~size_t(0));
+ report_performance(__FILE__, "random", time, resource);
+}
+
+int main()
+{
+ using namespace __gnu_test;
+
+ // No memory constraint.
+ set_new_limit(~size_t(0));
+
+ std::vector<int> revv(max_size);
+ for (int i = 0; i < max_size; ++i)
+ revv[i] = -i;
+
+ std::vector<int> fwdv(max_size);
+ for (int i = 0; i < max_size; ++i)
+ fwdv[i] = i;
+
+ // a simple pseudo-random series which does not rely on rand() and friends
+ std::vector<int> rndv(max_size);
+ rndv[0] = 0;
for (int i = 1; i < max_size; ++i)
- v[i] = (v[i-1] + 110211473) * 745988807;
+ rndv[i] = (rndv[i-1] + 110211473) * 745988807;
+
+ time_counter time;
+ resource_counter resource;
start_counters(time, resource);
- std::stable_sort(v.begin(), v.end());
+ bench(~size_t(0), revv, fwdv, rndv);
stop_counters(time, resource);
- report_performance(__FILE__, "random", time, resource);
+ report_performance(__FILE__, "bench 1 / 1 memory", time, resource);
+ clear_counters(time, resource);
+
+ start_counters(time, resource);
+ // Limit to fourth the expected size of the sorted array.
+ bench(max_size * sizeof(int) / 4, revv, fwdv, rndv);
+ stop_counters(time, resource);
+
+ report_performance(__FILE__, "bench 1 / 4 memory", time, resource);
+ clear_counters(time, resource);
+
+ start_counters(time, resource);
+ // Limit to 1/64 of range size.
+ bench(max_size * sizeof(int) / 64, revv, fwdv, rndv);
+ stop_counters(time, resource);
+
+ report_performance(__FILE__, "bench 1 /64 memory", time, resource);
+ clear_counters(time, resource);
+
+ revv.resize(small_size);
+ fwdv.resize(small_size);
+ rndv.resize(small_size);
+
+ start_counters(time, resource);
+ // Forbid any allocation.
+ bench(0, revv, fwdv, rndv);
+ stop_counters(time, resource);
+ report_performance(__FILE__, "bench 0 / 1 memory", time, resource);
return 0;
}
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc
index e21e705..8bbea9a 100644
--- a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc
@@ -138,6 +138,17 @@ test07()
static_assert( std::same_as<std::ranges::range_value_t<V>, int> );
}
+void
+test08()
+{
+ // LWG 3500. join_view::iterator::operator->() is bogus
+ struct X { int a; };
+ ranges::single_view<ranges::single_view<X>> s{std::in_place, std::in_place, 5};
+ auto v = s | views::join;
+ auto i = v.begin();
+ VERIFY( i->a == 5 );
+}
+
int
main()
{
@@ -148,4 +159,5 @@ main()
test05();
test06();
test07();
+ test08();
}
diff --git a/libstdc++-v3/testsuite/util/atomic/wait_notify_util.h b/libstdc++-v3/testsuite/util/atomic/wait_notify_util.h
new file mode 100644
index 0000000..f5fff4a
--- /dev/null
+++ b/libstdc++-v3/testsuite/util/atomic/wait_notify_util.h
@@ -0,0 +1,176 @@
+// Copyright (C) 2020 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 <atomic>
+#include <chrono>
+#include <condition_variable>
+#include <concepts>
+#include <mutex>
+#include <thread>
+
+#include <testsuite_hooks.h>
+
+#include <iostream>
+
+template<typename Tp>
+Tp check_wait_notify(Tp val1, Tp val2)
+ requires std::equality_comparable<Tp>
+{
+ using namespace std::literals::chrono_literals;
+
+ std::mutex m;
+ std::condition_variable cv;
+ std::unique_lock<std::mutex> l(m);
+
+ std::atomic<Tp> a(val1);
+ std::thread t([&]
+ {
+ {
+ // This ensures we block until cv.wait(l) starts.
+ std::lock_guard<std::mutex> ll(m);
+ }
+ cv.notify_one();
+ a.wait(val1);
+ if (a.load() != val2)
+ a = val1;
+ });
+ cv.wait(l);
+ std::this_thread::sleep_for(100ms);
+ a.store(val2);
+ a.notify_one();
+ t.join();
+ return a.load();
+}
+
+template<typename Tp>
+Tp check_wait_notify(Tp val1, Tp val2)
+{
+ using namespace std::literals::chrono_literals;
+
+ std::mutex m;
+ std::condition_variable cv;
+ std::unique_lock<std::mutex> l(m);
+
+ std::atomic<Tp> a(val1);
+ std::thread t([&]
+ {
+ {
+ // This ensures we block until cv.wait(l) starts.
+ std::lock_guard<std::mutex> ll(m);
+ }
+ cv.notify_one();
+ a.wait(val1);
+ auto v = a.load();
+ // TODO this needs to zero padding bits when we can do that
+ if (__builtin_memcmp(&v, &val2, sizeof(Tp)) != 0)
+ a = val1;
+ });
+ cv.wait(l);
+ std::this_thread::sleep_for(100ms);
+ a.store(val2);
+ a.notify_one();
+ t.join();
+ return a.load();
+}
+
+template<typename Tp>
+Tp check_atomic_wait_notify(Tp val1, Tp val2)
+ requires std::equality_comparable<Tp>
+{
+ using namespace std::literals::chrono_literals;
+
+ std::mutex m;
+ std::condition_variable cv;
+ std::unique_lock<std::mutex> l(m);
+
+ std::atomic<Tp> a(val1);
+ std::thread t([&]
+ {
+ {
+ // This ensures we block until cv.wait(l) starts.
+ std::lock_guard<std::mutex> ll(m);
+ }
+ cv.notify_one();
+ std::atomic_wait(&a, val1);
+ if (a.load() != val2)
+ a = val1;
+ });
+ cv.wait(l);
+ std::this_thread::sleep_for(100ms);
+ a.store(val2);
+ std::atomic_notify_one(&a);
+ t.join();
+ return a.load();
+}
+
+template<typename Tp>
+Tp check_atomic_wait_notify(Tp val1, Tp val2)
+{
+ using namespace std::literals::chrono_literals;
+
+ std::mutex m;
+ std::condition_variable cv;
+ std::unique_lock<std::mutex> l(m);
+
+ std::atomic<Tp> a(val1);
+ std::thread t([&]
+ {
+ {
+ // This ensures we block until cv.wait(l) starts.
+ std::lock_guard<std::mutex> ll(m);
+ }
+ cv.notify_one();
+ std::atomic_wait(&a, val1);
+ auto v = a.load();
+ // TODO this needs to zero padding bits when we can do that
+ if (__builtin_memcmp(&v, &val2, sizeof(Tp)) != 0)
+ a = val1;
+ });
+ cv.wait(l);
+ std::this_thread::sleep_for(100ms);
+ a.store(val2);
+ std::atomic_notify_one(&a);
+ t.join();
+ return a.load();
+}
+
+template<typename Tp>
+struct check
+{
+ check(Tp a = 0, Tp b = 42)
+ {
+ if constexpr (std::equality_comparable<Tp>)
+ {
+ VERIFY( check_wait_notify(a, b) == b);
+ VERIFY( check_atomic_wait_notify(a, b) == b);
+ }
+ else
+ {
+ {
+ // TODO this needs to zero padding bits when we can do that
+ auto v = check_wait_notify(a, b);
+ VERIFY( __builtin_memcmp(&v, &b, sizeof(Tp)) == 0 );
+ }
+
+ {
+ // TODO this needs to zero padding bits when we can do that
+ auto v = check_atomic_wait_notify(a, b);
+ VERIFY( __builtin_memcmp(&v, &b, sizeof(Tp)) == 0);
+ }
+ }
+ }
+};
diff --git a/libtool.m4 b/libtool.m4
index e194e89..9dc7b0f 100644
--- a/libtool.m4
+++ b/libtool.m4
@@ -4878,7 +4878,7 @@ _LT_EOF
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -4890,7 +4890,7 @@ _LT_EOF
else
case $host_cpu in
hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -5867,7 +5867,7 @@ if test "$_lt_caught_CXX_error" != yes; then
aCC*)
case $host_cpu in
hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
@@ -5891,7 +5891,7 @@ if test "$_lt_caught_CXX_error" != yes; then
if test $with_gnu_ld = no; then
case $host_cpu in
hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
diff --git a/libvtv/ChangeLog b/libvtv/ChangeLog
index 8e7b951..f26e02f 100644
--- a/libvtv/ChangeLog
+++ b/libvtv/ChangeLog
@@ -1,3 +1,7 @@
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ * configure: Regenerate.
+
2020-05-29 H.J. Lu <hjl.tools@gmail.com>
PR bootstrap/95413
diff --git a/libvtv/configure b/libvtv/configure
index b796e01..c60ad8e 100755
--- a/libvtv/configure
+++ b/libvtv/configure
@@ -10546,7 +10546,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -10558,7 +10558,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -13390,7 +13390,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
aCC*)
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
@@ -13414,7 +13414,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test $with_gnu_ld = no; then
case $host_cpu in
hppa*64*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
diff --git a/lto-plugin/ChangeLog b/lto-plugin/ChangeLog
index 4f285ce..bc50cc2 100644
--- a/lto-plugin/ChangeLog
+++ b/lto-plugin/ChangeLog
@@ -1,3 +1,12 @@
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ * configure: Regenerate.
+
+2020-11-25 Matthew Malcomson <matthew.malcomson@arm.com>
+
+ * Makefile.am: Avoid using sanitizer.
+ * Makefile.in: Regenerate.
+
2020-09-10 Jonathan Yong <10walls@gmail.com>
* Makefile.am: drop versioning from libtool completely.
diff --git a/lto-plugin/Makefile.am b/lto-plugin/Makefile.am
index 204b25f..8b20e1d 100644
--- a/lto-plugin/Makefile.am
+++ b/lto-plugin/Makefile.am
@@ -11,8 +11,8 @@ AM_CPPFLAGS = -I$(top_srcdir)/../include $(DEFS)
AM_CFLAGS = @ac_lto_plugin_warn_cflags@ $(CET_HOST_FLAGS)
AM_LDFLAGS = @ac_lto_plugin_ldflags@
AM_LIBTOOLFLAGS = --tag=disable-static
-override CFLAGS := $(filter-out -fsanitize=address,$(CFLAGS))
-override LDFLAGS := $(filter-out -fsanitize=address,$(LDFLAGS))
+override CFLAGS := $(filter-out -fsanitize=address -fsanitize=hwaddress,$(CFLAGS))
+override LDFLAGS := $(filter-out -fsanitize=address -fsanitize=hwaddress,$(LDFLAGS))
libexecsub_LTLIBRARIES = liblto_plugin.la
gcc_build_dir = @gcc_build_dir@
diff --git a/lto-plugin/Makefile.in b/lto-plugin/Makefile.in
index 834699b..20611c6 100644
--- a/lto-plugin/Makefile.in
+++ b/lto-plugin/Makefile.in
@@ -675,8 +675,8 @@ uninstall-am: uninstall-libexecsubLTLIBRARIES
.PRECIOUS: Makefile
-override CFLAGS := $(filter-out -fsanitize=address,$(CFLAGS))
-override LDFLAGS := $(filter-out -fsanitize=address,$(LDFLAGS))
+override CFLAGS := $(filter-out -fsanitize=address -fsanitize=hwaddress,$(CFLAGS))
+override LDFLAGS := $(filter-out -fsanitize=address -fsanitize=hwaddress,$(LDFLAGS))
all-local: $(in_gcc_libs)
diff --git a/lto-plugin/configure b/lto-plugin/configure
index c1dd0cd..9209d33 100755
--- a/lto-plugin/configure
+++ b/lto-plugin/configure
@@ -10244,7 +10244,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -10256,7 +10256,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
diff --git a/zlib/ChangeLog b/zlib/ChangeLog
index 09e2778..2e48299 100644
--- a/zlib/ChangeLog
+++ b/zlib/ChangeLog
@@ -1,3 +1,7 @@
+2020-11-29 John David Anglin <danglin@gcc.gnu.org>
+
+ * configure: Regenerate.
+
2020-05-29 H.J. Lu <hjl.tools@gmail.com>
PR bootstrap/95413
diff --git a/zlib/configure b/zlib/configure
index f9a2689..75d4766 100755
--- a/zlib/configure
+++ b/zlib/configure
@@ -9006,7 +9006,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
if test "$GCC" = yes && test "$with_gnu_ld" = no; then
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
@@ -9018,7 +9018,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
else
case $host_cpu in
hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'